Skip to content

Commit

Permalink
Upgraded project to XCode 2.2, added new DCAPICache class, added post…
Browse files Browse the repository at this point in the history
…-to-XML serialization to DCAPIPost.
  • Loading branch information
ldandersen committed Nov 15, 2005
1 parent bd71b65 commit 1d2576b
Show file tree
Hide file tree
Showing 11 changed files with 445 additions and 55 deletions.
46 changes: 46 additions & 0 deletions DCAPI/DCAPICache.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//
// DCAPICache.h
// Delicious Client
//
// Created by Buzz Andersen on 10/22/05.
// Copyright 2005 __MyCompanyName__. All rights reserved.
//

#import <Cocoa/Cocoa.h>
#import "DCAPIPost.h"
#import "DCAPIClient.h"
#import "NSFileManager+ESBExtensions.h"
#import "DCTypes.h"


@interface DCAPICache : NSObject {
NSMutableDictionary *memoryCache;
NSString *username;
DCAPIClient *client;
}

+ (DCAPICache *) DCAPICacheForUsername: (NSString *) username client: (DCAPIClient *) client;
- initWithUsername: (NSString *) newUsername client: (DCAPIClient *) newClient;

- (void) setUsername: (NSString *) newUsername;
- (NSString *) username;
- (void) setClient: (DCAPIClient *) newClient;
- (DCAPIClient *) client;
- (void) setMemoryCache: (NSDictionary *) newMemoryCache;
- (NSMutableDictionary *) memoryCache;

- (void) refreshMemoryCacheWithPolicy: (DCAPICachePolicy) policy error: (NSError **) error;

- (void) addPosts: (NSArray *) posts;
- (void) removePostsWithURLs: (NSArray *) postURLs;

+ (NSDictionary *) readPostsFromDiskCache: (NSString *) cachePath;
+ (void) addPosts: (NSArray *) posts toDiskCache: (NSString *) cachePath;
+ (void) removePostsWithURLs: (NSArray *) urls fromDiskCache: (NSString *) cachePath;

+ (NSString *) diskCachePathForUsername: (NSString *) username;
+ (NSString *) lastRefreshFilePathForUsername: (NSString *) username;
+ (NSString *) userSupportFilesPathForUsername: (NSString *) username;


@end
234 changes: 234 additions & 0 deletions DCAPI/DCAPICache.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
//
// DCAPICache.m
// Delicious Client
//
// Created by Buzz Andersen on 10/22/05.
// Copyright 2005 Sci-Fi Hi-Fi. All rights reserved.
//

#import "DCAPICache.h"


@implementation DCAPICache

+ (DCAPICache *) DCAPICacheForUsername: (NSString *) username client: (DCAPIClient *) client {
DCAPICache *cache = [[DCAPICache alloc] initWithUsername: username client: client];
return [cache autorelease];
}

- initWithUsername: (NSString *) newUsername client: (DCAPIClient *) newClient {
if (self = [super init]) {
[self setUsername: newUsername];
[self setClient: newClient];

return self;
}

return nil;
}

- (void) refreshMemoryCacheWithPolicy: (DCAPICachePolicy) policy error: (NSError **) error {
NSString *theUsername = [self username];
NSString *diskCachePath = [DCAPICache diskCachePathForUsername: theUsername];
BOOL diskCacheExists = [[NSFileManager defaultManager] fileExistsAtPath: diskCachePath];
NSString *lastRefreshFilePath = [DCAPICache lastRefreshFilePathForUsername: theUsername];
BOOL lastRefreshFileExists = [[NSFileManager defaultManager] fileExistsAtPath: lastRefreshFilePath];

BOOL serverHasUpdates = NO;

if (client && lastRefreshFileExists && policy == DCAPICacheUseProtocolCachePolicy) {
/* Must find out from del.icio.us whether there is an update */
NSDate *serverUpdateTime = [[self client] requestLastUpdateTime: error];

if (serverUpdateTime && !*error) {
#warning stringWithContentsOfFile: is deprecated in 10.4
NSString *lastRefreshTimeString = [NSString stringWithContentsOfFile: lastRefreshFilePath];
NSCalendarDate *lastRefreshDate = [NSCalendarDate dateWithString: lastRefreshTimeString calendarFormat: kDEFAULT_DATE_TIME_FORMAT];

if (lastRefreshDate && [lastRefreshDate compare: serverUpdateTime] == NSOrderedAscending) {
serverHasUpdates = YES;
}
}
}

if (client && (!diskCacheExists && DCAPICacheReturnCacheDataElseLoad) || policy == DCAPICacheReloadIgnoringCacheData || serverHasUpdates) {
/* Must reload from del.icio.us */
NSArray *posts = [[self client] requestPostsFilteredByTag: nil count: nil];
[self addPosts: posts];

/* Note that we refreshed the posts now */
[[NSFileManager defaultManager] createPathToFile: lastRefreshFilePath attributes: nil];
NSString *lastRefreshTimeString = [[NSDate date] descriptionWithCalendarFormat: kDEFAULT_DATE_TIME_FORMAT timeZone: [NSTimeZone timeZoneWithName: kDEFAULT_TIME_ZONE_NAME] locale: nil];
[lastRefreshTimeString writeToFile: lastRefreshFilePath atomically: YES];
}
else if (diskCacheExists) {
/* Must reload from disk */
NSDictionary *posts = [DCAPICache readPostsFromDiskCache: diskCachePath];
[self setMemoryCache: posts];
}
else {
[self setMemoryCache: [NSMutableDictionary dictionaryWithCapacity: 0]];
}
}

- (void) addPosts: (NSArray *) posts {
if (!memoryCache) {
[self setMemoryCache: [NSMutableDictionary dictionaryWithCapacity: [posts count]]];
}

NSEnumerator *postEnumerator = [posts objectEnumerator];
DCAPIPost *currentPost;

while ((currentPost = (DCAPIPost *) [postEnumerator nextObject]) != nil) {
[memoryCache setObject: currentPost forKey: [[currentPost URL] absoluteString]];
}

NSString *diskCachePath = [DCAPICache diskCachePathForUsername: [self username]];
[DCAPICache addPosts: posts toDiskCache: diskCachePath];
}

- (void) removePostsWithURLs: (NSArray *) postURLs {
if (!memoryCache) {
return;
}

NSEnumerator *urlEnumerator = [postURLs objectEnumerator];
NSURL *currentURL;

while ((currentURL = [urlEnumerator nextObject]) != nil) {
[[self memoryCache] removeObjectForKey: [currentURL absoluteString]];
}

NSString *diskCachePath = [DCAPICache diskCachePathForUsername: [self username]];
[DCAPICache removePostsWithURLs: postURLs fromDiskCache: diskCachePath];
}

- (DCAPIPost *) postForURL: (NSURL *) url {
if (!url) {
return nil;
}

return [memoryCache objectForKey: [url absoluteString]];
}

- (void) setUsername: (NSString *) newUsername {
if (username != newUsername) {
[username release];
username = [newUsername copy];
}
}

- (NSString *) username {
return [[username retain] autorelease];
}

- (void) setClient: (DCAPIClient *) newClient {
if (client != newClient) {
[client release];
client = [newClient retain];
}
}

- (DCAPIClient *) client {
return [[client retain] autorelease];
}

- (void) setMemoryCache: (NSDictionary *) newMemoryCache {
if (newMemoryCache != memoryCache) {
[memoryCache release];
memoryCache = [newMemoryCache mutableCopy];
}
}

- (NSMutableDictionary *) memoryCache {
return [[memoryCache retain] autorelease];
}

+ (NSString *) diskCachePathForUsername: (NSString *) username {
return [[DCAPICache userSupportFilesPathForUsername: username] stringByAppendingPathComponent: kPOST_CACHE_FILE_NAME];
}

+ (NSString *) lastRefreshFilePathForUsername: (NSString *) username {
return [[DCAPICache userSupportFilesPathForUsername: username] stringByAppendingPathComponent: kLAST_REFRESH_FILE_NAME];
}

+ (NSString *) userSupportFilesPathForUsername: (NSString *) username {
return [[[NSFileManager defaultManager] getApplicationSupportFolder] stringByAppendingPathComponent: username];
}

+ (NSDictionary *) readPostsFromDiskCache: (NSString *) cachePath {
NSDictionary *cache = [NSDictionary dictionaryWithContentsOfFile: cachePath];

if (!cache) {
return nil;
}

NSEnumerator *keys = [[cache allKeys] objectEnumerator];
NSString *currentPostURLString;
NSMutableDictionary *postList = [NSMutableDictionary dictionaryWithCapacity: 1];

while ((currentPostURLString = (NSString *) [keys nextObject]) != nil) {
NSDictionary *currentPostDictionary = [cache objectForKey: currentPostURLString];
DCAPIPost *currentPost = [DCAPIPost postWithDictionary: currentPostDictionary URL: [NSURL URLWithString: currentPostURLString]];

if (currentPost) {
[postList setObject: currentPost forKey: currentPostURLString];
}
}

return postList;
}

+ (void) addPosts: (NSArray *) posts toDiskCache: (NSString *) cachePath {
NSMutableDictionary *cache;

if ([[NSFileManager defaultManager] fileExistsAtPath: cachePath]) {
cache = [NSMutableDictionary dictionaryWithContentsOfFile: cachePath];
}

if (!cache) {
cache = [NSMutableDictionary dictionaryWithCapacity: [posts count]];
}

NSEnumerator *postEnumerator = [posts objectEnumerator];
DCAPIPost *currentPost;

while ((currentPost = (DCAPIPost *) [postEnumerator nextObject]) != nil) {
NSDictionary *postDictionary = [currentPost dictionaryRepresentation];
[cache setObject: postDictionary forKey: [[currentPost URL] absoluteString]];
}

[[NSFileManager defaultManager] createPathToFile: cachePath attributes: nil];

if (![cache writeToFile: cachePath atomically: YES]) {
NSLog(@"Can't write cache!");
}
}

+ (void) removePostsWithURLs: (NSArray *) urls fromDiskCache: (NSString *) cachePath {
if (![[NSFileManager defaultManager] fileExistsAtPath: cachePath]) {
return;
}

NSMutableDictionary *cache = [NSMutableDictionary dictionaryWithContentsOfFile: cachePath];

NSEnumerator *urlEnumerator = [urls objectEnumerator];
NSURL *currentURL;

while ((currentURL = [urlEnumerator nextObject]) != nil) {
[cache removeObjectForKey: [currentURL absoluteString]];
}

if (![cache writeToFile: cachePath atomically: YES]) {
NSLog(@"Can't write cache!");
}
}

- (void) dealloc {
[username release];
[memoryCache release];
[client release];
[super dealloc];
}

@end
5 changes: 4 additions & 1 deletion DCAPI/DCAPIPost.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
- (NSString *) tagsAsString;
- (void) setTags: (NSArray *) newTags;
- (void) addTagsFromRating: (NSNumber *) rating;
- (NSArray *) tags;
- (NSMutableArray *) tags;
- (void) addTagNamed: (NSString *) newTagName;
- (void) removeTagNamed: (NSString *) removeTagName;
- (void) renameTag: (NSString *) oldTagName to: (NSString *) newTagName;
Expand All @@ -55,4 +55,7 @@
- (id) initWithCoder:(NSCoder *) coder;
- (void) encodeWithCoder:(NSCoder *) coder;

+ (DCAPIPost *) postWithDictionary: (NSDictionary *) postDictionary URL: (NSURL *) URL;
- (NSDictionary *) dictionaryRepresentation;

@end
57 changes: 56 additions & 1 deletion DCAPI/DCAPIPost.m
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
#import "DCAPIPost.h"

static NSString *kSEARCH_SEPARATOR_STRING = @" ";
static NSString *kPOST_DICTIONARY_DESCRIPTION_KEY = @"description";
static NSString *kPOST_DICTIONARY_EXTENDED_KEY = @"extended";
static NSString *kPOST_DICTIONARY_TAGS_KEY = @"tags";
static NSString *kPOST_DICTIONARY_DATE_KEY = @"post-date";

@implementation DCAPIPost

Expand Down Expand Up @@ -174,7 +178,7 @@ - (int) findIndexOfNextRatingTagAfterIndex: (int) index {
return -1;
}

- (NSArray *) tags {
- (NSMutableArray *) tags {
return [[tags retain] autorelease];
}

Expand Down Expand Up @@ -233,6 +237,10 @@ - (void) setVisitCount: (NSNumber *) newVisitCount {
}

- (NSNumber *) visitCount {
if (!visitCount) {
return [NSNumber numberWithInt: 0];
}

return [[visitCount retain] autorelease];
}

Expand Down Expand Up @@ -385,4 +393,51 @@ - (BOOL)isEqual: (id)anObject
}
}

+ (DCAPIPost *) postWithDictionary: (NSDictionary *) postDictionary URL: (NSURL *) URL {
NSString *postDateString = [postDictionary objectForKey: kPOST_DICTIONARY_DATE_KEY];
NSDate *postDate = [NSCalendarDate dateWithString: postDateString calendarFormat: kDEFAULT_DATE_TIME_FORMAT];
DCAPIPost *post = [[DCAPIPost alloc] initWithURL: URL description: (NSString *) [postDictionary objectForKey: kPOST_DICTIONARY_DESCRIPTION_KEY] extended: (NSString *) [postDictionary objectForKey: kPOST_DICTIONARY_EXTENDED_KEY] date: postDate tags: (NSArray *) [postDictionary objectForKey: kPOST_DICTIONARY_TAGS_KEY] urlHash: nil];

return [post autorelease];
}

- (NSDictionary *) dictionaryRepresentation {
NSMutableDictionary *postDictionary = [NSMutableDictionary dictionaryWithCapacity: 1];

NSString *theDescription = [self description];

if (!theDescription) {
theDescription = [NSString string];
}

[postDictionary setObject: theDescription forKey: kPOST_DICTIONARY_DESCRIPTION_KEY];

NSString *theExtended = [self extended];

if (!theExtended) {
theExtended = [NSString string];
}

[postDictionary setObject: theExtended forKey: kPOST_DICTIONARY_EXTENDED_KEY];

NSArray *theTags = [self tags];

if (!theTags) {
theTags = [NSMutableArray arrayWithCapacity: 0];
}

[postDictionary setObject: theTags forKey: kPOST_DICTIONARY_TAGS_KEY];

NSDate *theDate = [self date];

if (!theDate) {
theDate = [NSDate date];
}

NSString *dateString = [theDate descriptionWithCalendarFormat: kDEFAULT_DATE_TIME_FORMAT timeZone: [NSTimeZone timeZoneWithName: kDEFAULT_TIME_ZONE_NAME] locale: nil];
[postDictionary setObject: dateString forKey: kPOST_DICTIONARY_DATE_KEY];

return postDictionary;
}

@end
Loading

0 comments on commit 1d2576b

Please sign in to comment.