diff options
Diffstat (limited to 'Providers/QSDeliciousAPIProvider.m')
| -rw-r--r-- | Providers/QSDeliciousAPIProvider.m | 360 |
1 files changed, 211 insertions, 149 deletions
diff --git a/Providers/QSDeliciousAPIProvider.m b/Providers/QSDeliciousAPIProvider.m index 0c37a43..03991c1 100644 --- a/Providers/QSDeliciousAPIProvider.m +++ b/Providers/QSDeliciousAPIProvider.m @@ -4,202 +4,264 @@ // #import "QSDeliciousAPIProvider.h" -#import "SocialSite.h" #import "Constants.h" +#import "SocialSite.h" #import <QSCore/QSCore.h> @implementation QSDeliciousAPIProvider -- (BOOL)canHandleSite:(SocialSite)site username:(NSString *)username password:(NSString *)password host:(NSString *)host { - return ( - site == SocialSiteDelicious || - site == SocialSiteMagnolia || - site == SocialSitePinboard || - site == SocialSiteSelfHostedDeliciousCompatible - ) && - username.length > 0 && - password.length > 0 && - (site != SocialSiteSelfHostedDeliciousCompatible || host.length > 0); +- (BOOL)canHandleSite:(SocialSite)site + username:(NSString *)username + password:(NSString *)password + host:(NSString *)host { + return (site == SocialSiteDelicious || site == SocialSiteMagnolia || + site == SocialSitePinboard || + site == SocialSiteSelfHostedDeliciousCompatible) && + username.length > 0 && password.length > 0 && + (site != SocialSiteSelfHostedDeliciousCompatible || host.length > 0); } - (NSString *)apiURLForSite:(SocialSite)site andHost:(NSString *)host { - switch (site) { - case SocialSiteDelicious: - return @"api.del.icio.us/v1"; - case SocialSiteMagnolia: - return @"ma.gnolia.com/api/mirrord/v1"; - case SocialSitePinboard: - return @"https://api.pinboard.in/v1"; - case SocialSiteSelfHostedDeliciousCompatible: - return [NSString stringWithFormat:@"%@/v1", host]; - default: - return nil; - } + switch (site) { + case SocialSiteDelicious: + return @"api.del.icio.us/v1"; + case SocialSiteMagnolia: + return @"ma.gnolia.com/api/mirrord/v1"; + case SocialSitePinboard: + return @"https://api.pinboard.in/v1"; + case SocialSiteSelfHostedDeliciousCompatible: + return [NSString stringWithFormat:@"%@/v1", host]; + default: + return nil; + } } - (BOOL)usesAuthToken:(SocialSite)site { - switch (site) { - case SocialSitePinboard: - case SocialSiteSelfHostedDeliciousCompatible: - return YES; - default: - return NO; - } + switch (site) { + case SocialSitePinboard: + case SocialSiteSelfHostedDeliciousCompatible: + return YES; + default: + return NO; + } } -- (NSURL *)requestURLForSite:(SocialSite)site username:(NSString *)username password:(NSString *)password host:(NSString *)host { - NSString *apiURL = [self apiURLForSite:site andHost: host]; - if (!apiURL) return nil; - +- (NSURL *)requestURLForSite:(SocialSite)site + username:(NSString *)username + password:(NSString *)password + host:(NSString *)host { + NSString *apiURL = [self apiURLForSite:site andHost:host]; + if (!apiURL) + return nil; + NSString *urlString; if ([self usesAuthToken:site]) { // Pinboard and pinboard compatible sites require an // auth token rather than a password. - urlString = [NSString stringWithFormat:@"%@/posts/all?auth_token=%@", apiURL, password]; + urlString = [NSString + stringWithFormat:@"%@/posts/all?auth_token=%@", apiURL, password]; } else { - urlString = [NSString stringWithFormat:@"https://%@:%@@%@/posts/all?", username, password, apiURL]; + urlString = [NSString stringWithFormat:@"https://%@:%@@%@/posts/all?", + username, password, apiURL]; } - return [NSURL URLWithString:urlString]; + return [NSURL URLWithString:urlString]; } -# pragma mark - Cache +#pragma mark - Cache + +- (NSString *)cachePathForSite:(SocialSite)site + username:(NSString *)username + host:(NSString *)host + create:(BOOL)create { -- (NSString *)cachePathForSite:(SocialSite)site username:(NSString *)username host:(NSString *)host create:(BOOL) create { - NSString *siteURL = [SocialSiteHelper cacheKeyForSite:site]; - NSString *safeHost = [[host componentsSeparatedByCharactersInSet:[[NSCharacterSet alphanumericCharacterSet] invertedSet]] componentsJoinedByString:@"-"]; - return [QSApplicationSupportSubPath([NSString stringWithFormat:@"Caches/%@/", siteURL], create) stringByAppendingPathComponent:[NSString stringWithFormat:@"%@-%@.xml", safeHost, username]]; + NSString *safeHost = + [[host componentsSeparatedByCharactersInSet:[[NSCharacterSet + alphanumericCharacterSet] + invertedSet]] + componentsJoinedByString:@"-"]; + return [QSApplicationSupportSubPath( + [NSString stringWithFormat:@"Caches/%@/", siteURL], create) + stringByAppendingPathComponent:[NSString stringWithFormat:@"%@-%@.xml", + safeHost, + username]]; } - -- (NSData *)cachedBookmarkDataForSite:(SocialSite)site username:(NSString *)username host:(NSString *)host { - NSString *cachePath = [self cachePathForSite: site username: username host: host create: NO]; +- (NSData *)cachedBookmarkDataForSite:(SocialSite)site + username:(NSString *)username + host:(NSString *)host { + NSString *cachePath = [self cachePathForSite:site + username:username + host:host + create:NO]; return [NSData dataWithContentsOfFile:cachePath]; } -- (void)cacheBookmarkData:(NSData *)data forSite:(SocialSite)site username:(NSString *)username host:(NSString *)host { - NSString *cachePath = [self cachePathForSite: site username: username host: host create: YES]; - [data writeToFile:cachePath atomically:NO]; +- (void)cacheBookmarkData:(NSData *)data + forSite:(SocialSite)site + username:(NSString *)username + host:(NSString *)host { + NSString *cachePath = [self cachePathForSite:site + username:username + host:host + create:YES]; + [data writeToFile:cachePath atomically:NO]; } -- (NSArray *)fetchBookmarksForSite:(SocialSite)site username:(NSString *)username password:(NSString *)password identifier:(NSString *)identifier host:(NSString *)host includeTags:(BOOL)includeTags { - - // Try cached data first - NSData *data = [self cachedBookmarkDataForSite:site username:username host:host]; +- (NSArray *)fetchBookmarksForSite:(SocialSite)site + username:(NSString *)username + password:(NSString *)password + identifier:(NSString *)identifier + host:(NSString *)host + includeTags:(BOOL)includeTags { - // If no cached data, fetch from API - if (![data length]) { - NSURL *requestURL = [self requestURLForSite:site username:username password:password host:host]; - if (!requestURL) return @[]; - - NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:requestURL - cachePolicy:NSURLRequestUseProtocolCachePolicy - timeoutInterval:60.0]; - [theRequest setHTTPMethod:@"GET"]; - [theRequest setValue:@"text/xml" forHTTPHeaderField:@"Content-type"]; - [theRequest setValue:@"Quicksilver (Blacktree,MacOSX)" forHTTPHeaderField:@"User-Agent"]; - - NSError *error = nil; - data = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:nil error:&error]; - - if (error) { - NSLog(@"Error fetching bookmarks: %@", error.localizedDescription); - return @[]; - } - - // Cache the data - [self cacheBookmarkData:data forSite:site username:username host:host]; + // Try cached data first + NSData *data = [self cachedBookmarkDataForSite:site + username:username + host:host]; + + // If no cached data, fetch from API + if (![data length]) { + NSURL *requestURL = [self requestURLForSite:site + username:username + password:password + host:host]; + if (!requestURL) + return @[]; + + NSMutableURLRequest *theRequest = + [NSMutableURLRequest requestWithURL:requestURL + cachePolicy:NSURLRequestUseProtocolCachePolicy + timeoutInterval:60.0]; + [theRequest setHTTPMethod:@"GET"]; + [theRequest setValue:@"text/xml" forHTTPHeaderField:@"Content-type"]; + [theRequest setValue:@"Quicksilver (Blacktree,MacOSX)" + forHTTPHeaderField:@"User-Agent"]; + + NSError *error = nil; + data = [NSURLConnection sendSynchronousRequest:theRequest + returningResponse:nil + error:&error]; + + if (error) { + NSLog(@"Error fetching bookmarks: %@", error.localizedDescription); + return @[]; } - - // Parse XML data - NSXMLParser *postParser = [[NSXMLParser alloc] initWithData:data]; - [postParser setDelegate:self]; - - self.posts = [NSMutableArray arrayWithCapacity:1]; - [postParser parse]; - - NSMutableArray *objects = [NSMutableArray arrayWithCapacity:1]; - NSMutableSet *tagSet = [NSMutableSet set]; - - // Create bookmark objects - for (NSDictionary *post in self.posts) { - QSObject *newObject = [self objectForPost:post]; - if (newObject) { - [objects addObject:newObject]; - - // Collect tags if requested - if (includeTags) { - NSString *tagString = [post objectForKey:@"tag"]; - if (tagString.length > 0) { - [tagSet addObjectsFromArray:[tagString componentsSeparatedByString:@" "]]; - } - } + + // Cache the data + [self cacheBookmarkData:data forSite:site username:username host:host]; + } + + // Parse XML data + NSXMLParser *postParser = [[NSXMLParser alloc] initWithData:data]; + [postParser setDelegate:self]; + + self.posts = [NSMutableArray arrayWithCapacity:1]; + [postParser parse]; + + NSMutableArray *objects = [NSMutableArray arrayWithCapacity:1]; + NSMutableSet *tagSet = [NSMutableSet set]; + + // Create bookmark objects + for (NSDictionary *post in self.posts) { + QSObject *newObject = [self objectForPost:post]; + if (newObject) { + [objects addObject:newObject]; + + // Collect tags if requested + if (includeTags) { + NSString *tagString = [post objectForKey:@"tag"]; + if (tagString.length > 0) { + [tagSet + addObjectsFromArray:[tagString componentsSeparatedByString:@" "]]; } + } } - - // Create tag objects if requested - if (includeTags) { - for (NSString *tag in tagSet) { - if (tag.length > 0) { - QSObject *tagObject = [QSObject makeObjectWithIdentifier:[NSString stringWithFormat:@"[%@ tag]:%@", [SocialSiteHelper displayNameForSite:site], tag]]; + } - [tagObject setObject:tag forType:kTagType]; - [tagObject setObject:@(site) forMeta:kTagSiteField]; - [tagObject setObject:username forMeta:kTagUsernameField]; - [tagObject setObject:host forMeta:kTagHostField]; - [tagObject setObject:identifier forMeta:kTagIdentifierField]; - [tagObject setName:tag]; - [tagObject setPrimaryType:kTagType]; - [objects addObject:tagObject]; - } - } + // Create tag objects if requested + if (includeTags) { + for (NSString *tag in tagSet) { + if (tag.length > 0) { + QSObject *tagObject = [QSObject + makeObjectWithIdentifier: + [NSString + stringWithFormat:@"[%@ tag]:%@", + [SocialSiteHelper displayNameForSite:site], + tag]]; + + [tagObject setObject:tag forType:kTagType]; + [tagObject setObject:@(site) forMeta:kTagSiteField]; + [tagObject setObject:username forMeta:kTagUsernameField]; + [tagObject setObject:host forMeta:kTagHostField]; + [tagObject setObject:identifier forMeta:kTagIdentifierField]; + [tagObject setName:tag]; + [tagObject setPrimaryType:kTagType]; + [objects addObject:tagObject]; + } } - - return objects; + } + + return objects; } -- (NSArray *)fetchBookmarksForTag:(NSString *)tag site:(SocialSite)site username:(NSString *)username password:(NSString *)password host:(NSString *)host { - NSData *data = [self cachedBookmarkDataForSite:site username:username host:host]; - if (!data) return @[]; - - NSXMLParser *postParser = [[NSXMLParser alloc] initWithData:data]; - [postParser setDelegate:self]; - self.posts = [NSMutableArray arrayWithCapacity:1]; - [postParser parse]; - - NSMutableArray *objects = [NSMutableArray arrayWithCapacity:1]; - - for (NSDictionary *post in self.posts) { - NSString *postTags = [post objectForKey:@"tag"]; - if ([postTags rangeOfString:tag].location != NSNotFound) { - QSObject *newObject = [self objectForPost:post]; - if (newObject) { - [objects addObject:newObject]; - } - } +- (NSArray *)fetchBookmarksForTag:(NSString *)tag + site:(SocialSite)site + username:(NSString *)username + password:(NSString *)password + host:(NSString *)host { + NSData *data = [self cachedBookmarkDataForSite:site + username:username + host:host]; + if (!data) + return @[]; + + NSXMLParser *postParser = [[NSXMLParser alloc] initWithData:data]; + [postParser setDelegate:self]; + self.posts = [NSMutableArray arrayWithCapacity:1]; + [postParser parse]; + + NSMutableArray *objects = [NSMutableArray arrayWithCapacity:1]; + + for (NSDictionary *post in self.posts) { + NSString *postTags = [post objectForKey:@"tag"]; + if ([postTags rangeOfString:tag].location != NSNotFound) { + QSObject *newObject = [self objectForPost:post]; + if (newObject) { + [objects addObject:newObject]; + } } - - return objects; + } + + return objects; } - (QSObject *)objectForPost:(NSDictionary *)post { - QSObject *newObject = [QSObject makeObjectWithIdentifier:[post objectForKey:@"hash"]]; - [newObject setObject:[post objectForKey:@"href"] forType:QSURLType]; - [newObject setName:[post objectForKey:@"description"]]; - [newObject setDetails:[post objectForKey:@"extended"]]; - [newObject setPrimaryType:QSURLType]; - return newObject; + QSObject *newObject = + [QSObject makeObjectWithIdentifier:[post objectForKey:@"hash"]]; + [newObject setObject:[post objectForKey:@"href"] forType:QSURLType]; + [newObject setName:[post objectForKey:@"description"]]; + [newObject setDetails:[post objectForKey:@"extended"]]; + [newObject setPrimaryType:QSURLType]; + return newObject; } #pragma mark - NSXMLParserDelegate -- (void)parser:(NSXMLParser*)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict { - if ([elementName isEqualToString:@"post"] && attributeDict) { - [self.posts addObject:attributeDict]; - } +- (void)parser:(NSXMLParser *)parser + didStartElement:(NSString *)elementName + namespaceURI:(NSString *)namespaceURI + qualifiedName:(NSString *)qName + attributes:(NSDictionary *)attributeDict { + if ([elementName isEqualToString:@"post"] && attributeDict) { + [self.posts addObject:attributeDict]; + } } -- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { - // Implementation if needed +- (void)parser:(NSXMLParser *)parser + didEndElement:(NSString *)elementName + namespaceURI:(NSString *)namespaceURI + qualifiedName:(NSString *)qName { + // Implementation if needed } @end |