Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

to handle TheOldReader #266

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion 3rdparty/ASIHTTPRequest/ASIDataCompressor.m
Expand Up @@ -212,7 +212,7 @@ + (BOOL)compressDataFromFile:(NSString *)sourcePath toFile:(NSString *)destinati

+ (NSError *)deflateErrorWithCode:(int)code
{
return [NSError errorWithDomain:NetworkRequestErrorDomain code:ASICompressionError userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"Compression of data failed with code %hi",code],NSLocalizedDescriptionKey,nil]];
return [NSError errorWithDomain:NetworkRequestErrorDomain code:ASICompressionError userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"Compression of data failed with code %i",code],NSLocalizedDescriptionKey,nil]];
}

@synthesize streamReady;
Expand Down
2 changes: 1 addition & 1 deletion 3rdparty/ASIHTTPRequest/ASIDataDecompressor.m
Expand Up @@ -211,7 +211,7 @@ + (BOOL)uncompressDataFromFile:(NSString *)sourcePath toFile:(NSString *)destina

+ (NSError *)inflateErrorWithCode:(int)code
{
return [NSError errorWithDomain:NetworkRequestErrorDomain code:ASICompressionError userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"Decompression of data failed with code %hi",code],NSLocalizedDescriptionKey,nil]];
return [NSError errorWithDomain:NetworkRequestErrorDomain code:ASICompressionError userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"Decompression of data failed with code %i",code],NSLocalizedDescriptionKey,nil]];
}

@synthesize streamReady;
Expand Down
3 changes: 2 additions & 1 deletion 3rdparty/ASIHTTPRequest/ASIHTTPRequest.m
Expand Up @@ -4866,7 +4866,8 @@ + (NSDate *)expiryDateForRequest:(ASIHTTPRequest *)request maxAge:(NSTimeInterva

// RFC 2612 says max-age must override any Expires header
if (maxAge) {
return [[NSDate date] addTimeInterval:maxAge];
// return [[NSDate date] addTimeInterval:maxAge];
return [[NSDate date] dateByAddingTimeInterval:maxAge];
} else {
NSString *expires = [responseHeaders objectForKey:@"Expires"];
if (expires) {
Expand Down
3 changes: 3 additions & 0 deletions Vienna.xcodeproj/project.pbxproj
Expand Up @@ -8662,6 +8662,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.9;
};
name = StaticAnalyzer;
};
Expand Down Expand Up @@ -8767,6 +8768,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.9;
};
name = Development;
};
Expand All @@ -8786,6 +8788,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.9;
};
name = Deployment;
};
Expand Down
13 changes: 10 additions & 3 deletions lproj/en.lproj/KnownSyncServers.plist
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BazQux</key>
<dict>
<key>Address</key>
<string>www.bazqux.com</string>
<key>Hint</key>
<string>Enter the info you set in BazQux's 'Mobile login' settings</string>
<string>Enter the info you set in BazQux&apos;s &apos;Mobile login&apos; settings</string>
</dict>
<key>FeedHQ</key>
<dict>
Expand All @@ -28,7 +28,14 @@
<key>Address</key>
<string></string>
<key>Hint</key>
<string>Enter server's address and your credentials for this server</string>
<string>Enter server&apos;s address and your credentials for this server</string>
</dict>
<key>TheOldReader</key>
<dict>
<key>Address</key>
<string>theoldreader.com</string>
<key>Hist</key>
<string>Enter server&apos;s address and your credentials for this server</string>
</dict>
</dict>
</plist>
12 changes: 2 additions & 10 deletions src/Folder.m
Expand Up @@ -361,11 +361,7 @@ -(NSImage *)image
if ([self feedURL])
{
NSString * homePageSiteRoot;
if (IsRSSFolder(self)) {
homePageSiteRoot = [[[self homePage] host] convertStringToValidPath];
} else {
homePageSiteRoot = [[[self feedURL] host] convertStringToValidPath];
}
homePageSiteRoot = [[[self homePage] host] convertStringToValidPath];
imagePtr = [[FolderImageCache defaultCache] retrieveImage:homePageSiteRoot];
}
NSImage *altIcon;
Expand Down Expand Up @@ -418,11 +414,7 @@ -(void)setImage:(NSImage *)iconImage
if ([self feedURL] != nil && iconImage != nil)
{
NSString * homePageSiteRoot;
if (IsRSSFolder(self)) {
homePageSiteRoot = [[[self homePage] host] convertStringToValidPath];
} else { //GoogleReader
homePageSiteRoot = [[[self feedURL] host] convertStringToValidPath];
}
homePageSiteRoot = [[[self homePage] host] convertStringToValidPath];
[[FolderImageCache defaultCache] addImage:iconImage forURL:homePageSiteRoot];
}
}
Expand Down
1 change: 1 addition & 0 deletions src/GoogleReader.h
Expand Up @@ -39,6 +39,7 @@
-(void)clearAuthentication;
-(void)resetAuthentication;


-(void)subscribeToFeed:(NSString *)feedURL;
-(void)unsubscribeFromFeed:(NSString *)feedURL;
-(void)markRead:(NSString *)itemGuid readFlag:(BOOL)flag;
Expand Down
67 changes: 53 additions & 14 deletions src/GoogleReader.m
Expand Up @@ -38,6 +38,7 @@

static NSString * LoginBaseURL = @"https://%@/accounts/ClientLogin?accountType=GOOGLE&service=reader";
static NSString * ClientName = @"ViennaRSS";
static NSString * TheOldReaderCom = @"theoldreader.com";

NSString * openReaderHost;
NSString * username;
Expand Down Expand Up @@ -129,14 +130,16 @@ - (void)requestFinished:(ASIHTTPRequest *)request
}

-(ASIHTTPRequest*)refreshFeed:(Folder*)thisFolder withLog:(ActivityItem *)aItem shouldIgnoreArticleLimit:(BOOL)ignoreLimit
{
{

ignoreLimit = TRUE;

//This is a workaround throw a BAD folderupdate value on DB
NSString *folderLastUpdateString = ignoreLimit ? @"0" : [thisFolder lastUpdateString];
if ([folderLastUpdateString isEqualToString:@""] || [folderLastUpdateString isEqualToString:@"(null)"]) folderLastUpdateString=@"0";

NSString *itemsLimitation;
if (ignoreLimit)
if (ignoreLimit)
itemsLimitation = @"&n=10000"; //just stay reasonable…
else
//Note : we don't set "r" (sorting order) here.
Expand All @@ -147,8 +150,15 @@ -(ASIHTTPRequest*)refreshFeed:(Folder*)thisFolder withLog:(ActivityItem *)aItem

if (![self isReady])
[self authenticate];

NSString* tmpfeedURL = [thisFolder feedURL];
if( [openReaderHost isEqualToString:TheOldReaderCom] )
{
tmpfeedURL = [[thisFolder feedURL] lastPathComponent];
}

NSURL *refreshFeedUrl = [NSURL URLWithString:[NSString stringWithFormat:@"%@stream/contents/feed/%@?client=%@&comments=false&likes=false%@&ck=%@",APIBaseURL,percentEscape([thisFolder feedURL]),ClientName,itemsLimitation,TIMESTAMP]];
NSURL *refreshFeedUrl = [NSURL URLWithString:[NSString stringWithFormat:@"%@stream/contents/feed/%@?client=%@&comments=false&likes=false%@&ck=%@&output=json",APIBaseURL,
percentEscape(tmpfeedURL),ClientName,itemsLimitation,TIMESTAMP]];

ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:refreshFeedUrl];
[request setDelegate:self];
Expand Down Expand Up @@ -323,8 +333,15 @@ - (void)feedRequestDone:(ASIHTTPRequest *)request

[dict release];

NSString* tmpfeedURL = [refreshedFolder feedURL];
if( [openReaderHost isEqualToString:TheOldReaderCom] )
{
tmpfeedURL = [[refreshedFolder feedURL] lastURLComponent];
}

// Request id's of unread items
NSString * args = [NSString stringWithFormat:@"?ck=%@&client=%@&s=feed/%@&xt=user/-/state/com.google/read&n=1000&output=json", TIMESTAMP, ClientName, percentEscape([refreshedFolder feedURL])];
NSString * args = [NSString stringWithFormat:@"?ck=%@&client=%@&s=feed/%@&xt=user/-/state/com.google/read&n=1000&output=json", TIMESTAMP, ClientName,
percentEscape(tmpfeedURL)];
NSURL * url = [NSURL URLWithString:[NSString stringWithFormat:@"%@%@%@", APIBaseURL, @"stream/items/ids", args]];
ASIHTTPRequest *request2 = [ASIHTTPRequest requestWithURL:url];
[request2 setUserInfo:[NSDictionary dictionaryWithObjectsAndKeys:refreshedFolder, @"folder", nil]];
Expand All @@ -336,7 +353,12 @@ - (void)feedRequestDone:(ASIHTTPRequest *)request
[[RefreshManager sharedManager] addConnection:request2];

// Request id's of starred items
args = [NSString stringWithFormat:@"?ck=%@&client=%@&s=feed/%@&it=user/-/state/com.google/starred&n=1000&output=json", TIMESTAMP, ClientName, percentEscape([refreshedFolder feedURL])];
// Note: Inoreader requires syntax "it=user/-/state/...", while TheOldReader ignores it and requires "s=user/-/state/..."
if( [openReaderHost isEqualToString:TheOldReaderCom] ) {
args = [NSString stringWithFormat:@"?ck=%@&client=%@&s=feed/%@&s=user/-/state/com.google/starred&n=1000&output=json", TIMESTAMP, ClientName, percentEscape(tmpfeedURL)];
} else {
args = [NSString stringWithFormat:@"?ck=%@&client=%@&s=feed/%@&it=user/-/state/com.google/starred&n=1000&output=json", TIMESTAMP, ClientName, percentEscape(tmpfeedURL)];
}
url = [NSURL URLWithString:[NSString stringWithFormat:@"%@%@%@", APIBaseURL, @"stream/items/ids", args]];
ASIHTTPRequest *request3 = [ASIHTTPRequest requestWithURL:url];
[request3 setUserInfo:[NSDictionary dictionaryWithObjectsAndKeys:refreshedFolder, @"folder", nil]];
Expand Down Expand Up @@ -376,11 +398,20 @@ - (void)readRequestDone:(ASIHTTPRequest *)request
NSMutableArray * guidArray = [NSMutableArray arrayWithCapacity:[dict count]];
for (NSDictionary *itemRef in dict)
{
// as described in http://code.google.com/p/google-reader-api/wiki/ItemId
// the short version of id is a base 10 signed integer ; the long version includes a 16 characters base 16 representation
NSInteger shortId = [[itemRef objectForKey:@"id"] integerValue];
NSString * guid = [NSString stringWithFormat:@"tag:google.com,2005:reader/item/%016qx",(long long)shortId];
[guidArray addObject:guid];
NSString * guid;
if( [openReaderHost isEqualToString:TheOldReaderCom] )
{
guid = [NSString stringWithFormat:@"tag:google.com,2005:reader/item/%@",[itemRef objectForKey:@"id"]];
}
else
{
// as described in http://code.google.com/p/google-reader-api/wiki/ItemId
// the short version of id is a base 10 signed integer ; the long version includes a 16 characters base 16 representation
NSInteger shortId = [[itemRef objectForKey:@"id"] integerValue];
guid = [NSString stringWithFormat:@"tag:google.com,2005:reader/item/%016qx",(long long)shortId];
}

[guidArray addObject:guid];
}
LLog(@"%ld unread items for %@", [guidArray count], [request url]);
[[Database sharedDatabase] markUnreadArticlesFromFolder:refreshedFolder guidArray:guidArray];
Expand All @@ -397,10 +428,18 @@ - (void)starredRequestDone:(ASIHTTPRequest *)request
NSMutableArray * guidArray = [NSMutableArray arrayWithCapacity:[dict count]];
for (NSDictionary *itemRef in dict)
{
// as described in http://code.google.com/p/google-reader-api/wiki/ItemId
// the short version of id is a base 10 signed integer ; the long version includes a 16 characters base 16 representation
NSInteger shortId = [[itemRef objectForKey:@"id"] integerValue];
NSString * guid = [NSString stringWithFormat:@"tag:google.com,2005:reader/item/%016qx",(long long)shortId];
NSString * guid;
if( [openReaderHost isEqualToString:TheOldReaderCom] )
{
guid = [NSString stringWithFormat:@"tag:google.com,2005:reader/item/%@",[itemRef objectForKey:@"id"]];
}
else
{
// as described in http://code.google.com/p/google-reader-api/wiki/ItemId
// the short version of id is a base 10 signed integer ; the long version includes a 16 characters base 16 representation
NSInteger shortId = [[itemRef objectForKey:@"id"] integerValue];
guid = [NSString stringWithFormat:@"tag:google.com,2005:reader/item/%016qx",(long long)shortId];
}
[guidArray addObject:guid];
}
LLog(@"%ld starred items for %@", [guidArray count], [request url]);
Expand Down
29 changes: 12 additions & 17 deletions src/RefreshManager.m
Expand Up @@ -526,6 +526,7 @@ -(void)pumpFolderIconRefresh:(Folder *)folder
ASIHTTPRequest *myRequest = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:favIconPath]];
[myRequest setDelegate:self];
[myRequest setDidFinishSelector:@selector(iconRequestDone:)];
[myRequest setDidFailSelector:@selector(iconRequestFailed:)];
[myRequest setUserInfo:[NSDictionary dictionaryWithObjectsAndKeys:folder, @"folder", aItem, @"log", [NSNumber numberWithInt:MA_Refresh_FavIcon], @"type", nil]];
[self addConnection:myRequest];

Expand All @@ -539,10 +540,6 @@ - (void)iconRequestDone:(ASIHTTPRequest *)request
[self setFolderUpdatingFlag:folder flag:NO];
if ([request responseStatusCode] == 404) {
[aItem appendDetail:NSLocalizedString(@"RSS Icon not found!", nil)];
Database *db = [Database sharedDatabase];
@synchronized(db) {
[db clearFolderFlag:[folder itemId] flagToClear:MA_FFlag_CheckForImage];
}
} else if ([request responseStatusCode] == 200) {

NSImage * iconImage = [[NSImage alloc] initWithData:[request responseData]];
Expand All @@ -558,23 +555,16 @@ - (void)iconRequestDone:(ASIHTTPRequest *)request
// Log additional details about this.
[aItem appendDetail:[NSString stringWithFormat:NSLocalizedString(@"Folder image retrieved from %@", nil), [request url]]];
[aItem appendDetail:[NSString stringWithFormat:NSLocalizedString(@"%ld bytes received", nil), [[request responseData] length]]];

Database *db = [Database sharedDatabase];
@synchronized(db) {
[db clearFolderFlag:[folder itemId] flagToClear:MA_FFlag_CheckForImage];
}

} else {
// many servers send null data instead of a favicon
Database *db = [Database sharedDatabase];
@synchronized(db) {
[db clearFolderFlag:[folder itemId] flagToClear:MA_FFlag_CheckForImage];
};
}
[iconImage release];
} else {
ALog(@"Unhandled error code: %d",[request responseStatusCode]);
[aItem appendDetail:[NSString stringWithFormat:NSLocalizedString(@"HTTP code %d reported from server", nil), [request responseStatusCode]]];
}

Database *db = [Database sharedDatabase];
@synchronized(db) {
[db clearFolderFlag:[folder itemId] flagToClear:MA_FFlag_CheckForImage];
}
}

// failure callback
Expand All @@ -583,6 +573,11 @@ - (void)iconRequestFailed:(ASIHTTPRequest *)request
Folder * folder = (Folder *)[[request userInfo] objectForKey:@"folder"];
ActivityItem * aItem = [[ActivityLog defaultLog] itemByName:[folder name]];
[aItem appendDetail:[NSString stringWithFormat:@"%@ %@",NSLocalizedString(@"Error retrieving RSS Icon:", nil),[[request error] localizedDescription ]]];

Database *db = [Database sharedDatabase];
@synchronized(db) {
[db clearFolderFlag:[folder itemId] flagToClear:MA_FFlag_CheckForImage];
}
}

- (void)syncFinishedForFolder:(Folder *)folder
Expand Down
1 change: 1 addition & 0 deletions src/StringExtensions.h
Expand Up @@ -39,6 +39,7 @@
-(NSString *)stringByEscapingExtendedCharacters;
-(NSString *)stringByUnescapingExtendedCharacters;
-(NSString *)stringByDeletingLastURLComponent;
-(NSString *)lastURLComponent;
-(NSString *)stringByAppendingURLComponent:(NSString *)newComponent;
-(BOOL)hasCharacter:(char)ch;
-(NSString *)firstWord;
Expand Down
15 changes: 15 additions & 0 deletions src/StringExtensions.m
Expand Up @@ -435,6 +435,20 @@ -(NSString *)stringByDeletingLastURLComponent
return [self substringWithRange:NSMakeRange(0, index)];
}

/* lastURLComponent
* Returns a string with the last URL component.
*/
-(NSString *)lastURLComponent
{
int index = [self length] - 1;

while (index >= 0 && [self characterAtIndex:index] != '/')
--index;
if (index <= 0)
return self;
return [self substringWithRange:NSMakeRange(index+1, [self length] -1-index)];
}

/* stringByAppendingURLComponent
* Appends the specified component to the end of our URL. It is similar to stringByAppendingPathComponent
* but it doesn't attempt to interpret the current string as a file path and 'fixup' slashes.
Expand Down Expand Up @@ -691,6 +705,7 @@ -(BOOL)isBlank
-(NSString *)convertStringToValidPath
{
NSMutableString * baseURLString = [NSMutableString stringWithString:self];
[baseURLString replaceOccurrencesOfString:@":" withString:@"_" options:NSLiteralSearch range:NSMakeRange(0, [baseURLString length])];
[baseURLString replaceOccurrencesOfString:@"." withString:@"_" options:NSLiteralSearch range:NSMakeRange(0, [baseURLString length])];
[baseURLString replaceOccurrencesOfString:@"/" withString:@"_" options:NSLiteralSearch range:NSMakeRange(0, [baseURLString length])];
[baseURLString replaceOccurrencesOfString:@"?" withString:@"_" options:NSLiteralSearch range:NSMakeRange(0, [baseURLString length])];
Expand Down