Permalink
Browse files

TwitterFon version 1.4.4 (rev 1726)

 LC_ALL=C svn info
Path: .
URL: http://naan.net/svn/trunk/TwitterFon
Repository Root: http://naan.net/svn
Repository UUID: 542e9493-1a22-0410-9183-c10453d2b9ee
Revision: 1730
Node Kind: directory
Schedule: normal
Last Changed Author: kaz
Last Changed Rev: 1726
Last Changed Date: 2009-03-14 00:53:24 +0100 (Sat, 14 Mar 2009)
  • Loading branch information...
drodriguez committed May 6, 2009
1 parent 58905d4 commit 39fa661da27ce9e26907f8394ede85b2d10a9df2
Showing with 1,701 additions and 203 deletions.
  1. +1 −0 Classes/Controllers/FavoritesViewController.h
  2. +31 −5 Classes/Controllers/FavoritesViewController.m
  3. +7 −1 Classes/Controllers/FriendsTimelineController.m
  4. +1 −1 Classes/Controllers/FriendsViewController.m
  5. +1 −0 Classes/Controllers/ProfileViewController.m
  6. +1 −0 Classes/Controllers/Timeline.h
  7. +5 −0 Classes/Controllers/Timeline.m
  8. +1 −0 Classes/Controllers/UserTimelineController.m
  9. +1 −2 Classes/Models/DBConnection.h
  10. +40 −89 Classes/Models/DBConnection.m
  11. +32 −0 Classes/Models/Followee.m
  12. +1 −0 Classes/Models/Statement.h
  13. +21 −3 Classes/Models/Statement.m
  14. +40 −14 Classes/Models/Status.m
  15. +4 −2 Classes/Models/User.h
  16. +63 −8 Classes/Models/User.m
  17. +367 −0 Classes/Network/TwitterClient.m.orig
  18. +19 −0 Classes/Network/TwitterClient.m.rej
  19. +9 −0 Classes/OtherSources/RGConfig.h
  20. +99 −0 Classes/OtherSources/RGReverseGeocoder.h
  21. +530 −0 Classes/OtherSources/RGReverseGeocoder.m
  22. +1 −0 Classes/OtherSources/TimeUtils.h
  23. +10 −5 Classes/OtherSources/TimeUtils.m
  24. +4 −0 Classes/OtherSources/TwitterFonAppDelegate.h
  25. +35 −38 Classes/OtherSources/TwitterFonAppDelegate.m
  26. +1 −1 Info.plist
  27. +132 −3 Interfaces/MainWindow.xib
  28. +19 −21 Interfaces/SettingsView.xib
  29. +23 −10 TwitterFon.xcodeproj/project.pbxproj
  30. +65 −0 db/create.sql
  31. BIN db/db1.4.sql
  32. +66 −0 db/update_v12_to_v13.sql
  33. +2 −0 db/update_v13_to_v14.sql
  34. BIN etc/dSYM/1.4.1/TwitterFon
  35. BIN etc/dSYM/1.4.2/TwitterFon
  36. +23 −0 etc/dSYM/1.4.2/TwitterFon.app.dSYM/Contents/Info.plist
  37. BIN etc/dSYM/1.4.2/TwitterFon.app.dSYM/Contents/Resources/DWARF/TwitterFon
  38. BIN etc/dSYM/1.4.3/TwitterFon
  39. +23 −0 etc/dSYM/1.4.3/TwitterFon.app.dSYM/Contents/Info.plist
  40. BIN etc/dSYM/1.4.3/TwitterFon.app.dSYM/Contents/Resources/DWARF/TwitterFon
  41. BIN etc/dSYM/1.4.4/TwitterFon
  42. +23 −0 etc/dSYM/1.4.4/TwitterFon.app.dSYM/Contents/Info.plist
  43. BIN etc/dSYM/1.4.4/TwitterFon.app.dSYM/Contents/Resources/DWARF/TwitterFon
  44. 0 etc/{ → test}/error.json
  45. 0 etc/{ → test}/friends_timeline.json
  46. BIN etc/{ → test}/naan_db1.2.sql
  47. BIN etc/{ → test}/naantest_db1.2.sql
  48. 0 etc/{ → test}/null_friends_timelne.json
  49. 0 etc/{ → test}/replies.json
@@ -20,6 +20,7 @@
TwitterClient* twitterClient;
NSString* screenName;
BOOL isRestored;
+ int page;
}
- (void)loadTimeline:(NSString*)screenName;
@@ -25,6 +25,7 @@ - (void)awakeFromNib
- (void)viewDidLoad
{
+ page = 1;
if (timeline == nil) {
timeline = [[Timeline alloc] init];
}
@@ -97,8 +98,12 @@ - (int)restore:(BOOL)all
int count = 0;
while ([stmt step] == SQLITE_ROW) {
Status* sts = [Status initWithStatement:stmt type:TWEET_TYPE_FAVORITES];
- [timeline appendStatus:sts];
- ++count;
+ if (sts) {
+ if ([timeline indexOfObject:sts] == -1) {
+ [timeline appendStatus:sts];
+ ++count;
+ }
+ }
}
isRestored = all;
return count;
@@ -185,7 +190,7 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath
if (twitterClient) return;
[loadCell.spinner startAnimating];
twitterClient = [[TwitterClient alloc] initWithTarget:self action:@selector(favoritesDidReceive:obj:)];
- int page = ([timeline countStatuses] / 20) + 1;
+ ++page;
[twitterClient favorites:screenName page:page];
}
else {
@@ -242,9 +247,21 @@ - (void)favoritesDidReceive:(TwitterClient*)sender obj:(NSObject*)obj
else {
return;
}
+
+ int received = [ary count];
+ NSLog(@"Received %d favorites", received);
+ if (screenName == nil) {
+ int count = [timeline countStatuses];
+ if (count > received) {
+ NSRange r;
+ r.location = received;
+ r.length = [timeline countStatuses] - received;
+ [timeline removeStatusesInRange:r];
+ }
+ }
// Add messages to the timeline
- for (int i = 0; i < [ary count]; ++i) {
+ for (int i = 0; i < received; ++i) {
NSDictionary *dic = (NSDictionary*)[ary objectAtIndex:i];
if (![dic isKindOfClass:[NSDictionary class]]) {
continue;
@@ -266,13 +283,22 @@ - (void)favoritesDidReceive:(TwitterClient*)sender obj:(NSObject*)obj
[sts updateFavoriteState];
}
else {
- Status* sts = [Status statusWithJsonDictionary:[ary objectAtIndex:i] type:TWEET_TYPE_FAVORITES];
+ sts = [Status statusWithJsonDictionary:[ary objectAtIndex:i] type:TWEET_TYPE_FAVORITES];
sts.unread = false;
[sts insertDB];
}
+ [timeline removeStatus:sts];
}
}
+
if (screenName == nil) {
+ for (int i = 0; i < [timeline countStatuses]; ++i) {
+ Status *sts = [timeline statusAtIndex:i];
+ NSLog(@"Remove favorite:%lld:%@:%@", sts.statusId, sts.user.screenName, sts.text);
+ sts.favorited = false;
+ [sts updateFavoriteState];
+ }
+
[timeline removeAllStatuses];
[self restore:isRestored];
}
@@ -102,7 +102,10 @@ - (void)restoreAndLoadTimeline:(BOOL)load
timelineDataSource = [[FriendsTimelineDataSource alloc] initWithController:self tweetType:tab];
self.tableView.dataSource = timelineDataSource;
self.tableView.delegate = timelineDataSource;
- if (load) [self loadTimeline];
+ if (load) {
+ [self performSelector:@selector(loadTimeline) withObject:nil afterDelay:0.01];
+ }
+ [self.tableView reloadData];
}
- (IBAction) reload:(id) sender
@@ -170,6 +173,9 @@ - (void)scrollToFirstUnread
BOOL flag = [[NSUserDefaults standardUserDefaults] boolForKey:@"autoScrollToFirstUnread"];
if (flag == false) return;
+ CGPoint offset = [self.tableView contentOffset];
+ if (offset.y != 0) return;
+
if (unread) {
if (unread < [timelineDataSource.timeline countStatuses]) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:unread inSection:0];
@@ -148,7 +148,7 @@ - (void)friendsDidReceive:(TwitterClient*)client obj:(NSObject*)obj
if (![dic isKindOfClass:[NSDictionary class]]) {
continue;
}
- User *user = [[User alloc] initWithJsonDictionary:dic];
+ User *user = [User userWithJsonDictionary:dic];
if (ownFriendsList) {
[Followee insertDB:user];
}
@@ -227,6 +227,7 @@ - (void)userDidReceive:(TwitterClient*)sender obj:(NSObject*)obj
dic = (NSDictionary*)obj;
[user updateWithJSonDictionary:dic];
+ [user updateDB];
[userView setUser:user];
detailLoaded = true;
#ifndef USE_FRIENDSHIP_EXISTS_METHOD
@@ -26,6 +26,7 @@
- (void)removeStatus:(Status*)status;
- (void)removeStatusAtIndex:(int)index;
+- (void)removeStatusesInRange:(NSRange)r;
- (void)removeLastStatus;
- (void)removeAllStatuses;
@@ -68,6 +68,11 @@ - (void)removeStatusAtIndex:(int)index
[statuses removeObjectAtIndex:index];
}
+- (void)removeStatusesInRange:(NSRange)r
+{
+ [statuses removeObjectsInRange:r];
+}
+
- (void)removeAllStatuses
{
[statuses removeAllObjects];
@@ -253,6 +253,7 @@ - (void)userTimelineDidReceive:(TwitterClient*)sender obj:(NSObject*)obj
for (int i = 0; i < [ary count]; ++i) {
Status* sts = [Status statusWithJsonDictionary:[ary objectAtIndex:i] type:TWEET_TYPE_FRIENDS];
sts.cellType = TWEET_CELL_TYPE_USER;
+ [sts insertDBIfFollowing];
[sts updateAttribute];
[timeline appendStatus:sts];
}
@@ -9,8 +9,7 @@
}
+ (void)createEditableCopyOfDatabaseIfNeeded:(BOOL)force;
-+ (void)deleteMessageCache;
-+ (void)deleteImageCache;
++ (void)migrate:(NSString*)dbname to:(NSString*)newdbname queries:(NSString*)query_file;
+ (sqlite3*)getSharedDatabase;
+ (void)closeDatabase;
@@ -1,10 +1,11 @@
#import "DBConnection.h"
#import "Statement.h"
+#import "TimeUtils.h"
#import "TwitterFonAppDelegate.h"
static sqlite3* theDatabase = nil;
-#define MAIN_DATABASE_NAME @"db1.3.sql"
+#define MAIN_DATABASE_NAME @"db1.4.sql"
//#define TEST_DELETE_TWEET
@@ -32,23 +33,27 @@ + (sqlite3*)openDatabase:(NSString*)dbFilename
// Open the database. The database was prepared outside the application.
if (sqlite3_open([path UTF8String], &instance) != SQLITE_OK) {
// Even though the open failed, call close to properly clean up resources.
+ NSString *msg = [NSString stringWithUTF8String:sqlite3_errmsg(instance)];
+ [[TwitterFonAppDelegate getAppDelegate] alert:@"Failed to open database" message:msg];
+ NSLog(@"Failed to open database. (%@)", msg);
sqlite3_close(instance);
- NSLog(@"Failed to open database. (%s)", sqlite3_errmsg(instance));
- return nil;
- }
+ instance = nil;
+ }
+
return instance;
}
+ (sqlite3*)getSharedDatabase
{
if (theDatabase == nil) {
+
theDatabase = [self openDatabase:MAIN_DATABASE_NAME];
if (theDatabase == nil) {
[DBConnection createEditableCopyOfDatabaseIfNeeded:true];
[[TwitterFonAppDelegate getAppDelegate] alert:@"Local cache error"
message:@"Local cache database has been corrupted. Re-created new database."];
}
-
+
#ifdef TEST_DELETE_TWEET
char *errmsg;
if (sqlite3_exec(theDatabase, delete_tweets, NULL, NULL, &errmsg) != SQLITE_OK) {
@@ -59,110 +64,54 @@ + (sqlite3*)getSharedDatabase
return theDatabase;
}
-//
-// delete caches
-//
-const char *delete_message_cache_sql =
-"BEGIN;"
-"DELETE FROM statuses;"
-"DELETE FROM direct_messages;"
-"DELETE FROM users;"
-"DELETE FROM followees;"
-"COMMIT;"
-"VACUUM;";
-
-+ (void)deleteMessageCache
-{
- char *errmsg;
- [self getSharedDatabase];
-
- if (sqlite3_exec(theDatabase, delete_message_cache_sql, NULL, NULL, &errmsg) != SQLITE_OK) {
- // ignore error
- NSLog(@"Error: failed to cleanup chache (%s)", errmsg);
- }
-}
-
-+ (void)deleteImageCache
-{
- char *errmsg;
- [self getSharedDatabase];
-
- if (sqlite3_exec(theDatabase, "DELETE FROM images; VACUUM;", NULL, NULL, &errmsg) != SQLITE_OK) {
- // ignore error
- NSLog(@"Error: failed to cleanup chache (%s)", errmsg);
- }
-}
-
-//
-// cleanup and optimize
-//
-const char *cleanup_sql =
-"BEGIN;"
-"DELETE FROM images WHERE updated_at <= (SELECT updated_at FROM images order by updated_at LIMIT 1 OFFSET 5000);"
-"DELETE FROM statuses WHERE type = 0 and id <= (SELECT id FROM statuses WHERE type = 0 ORDER BY id DESC LIMIT 1 OFFSET 4000);"
-"DELETE FROM statuses WHERE type = 1 and id <= (SELECT id FROM statuses WHERE type = 1 ORDER BY id DESC LIMIT 1 OFFSET 1000);"
-"COMMIT";
-
-
-const char *optimize_sql = "VACUUM; ANALYZE";
-
+ (void)closeDatabase
{
- char *errmsg;
- if (theDatabase) {
- if (sqlite3_exec(theDatabase, cleanup_sql, NULL, NULL, &errmsg) != SQLITE_OK) {
- // ignore error
- NSLog(@"Error: failed to cleanup chache (%s)", errmsg);
- }
-
- int launchCount = [[NSUserDefaults standardUserDefaults] integerForKey:@"launchCount"];
- NSLog(@"launchCount %d", launchCount);
- if (launchCount-- <= 0) {
- NSLog(@"Optimize database...");
- if (sqlite3_exec(theDatabase, optimize_sql, NULL, NULL, &errmsg) != SQLITE_OK) {
- NSLog(@"Error: failed to cleanup chache (%s)", errmsg);
- }
- launchCount = 50;
- }
- [[NSUserDefaults standardUserDefaults] setInteger:launchCount forKey:@"launchCount"];
- [[NSUserDefaults standardUserDefaults] synchronize];
+ if (theDatabase) {
sqlite3_close(theDatabase);
}
}
-// Creates a writable copy of the bundled default database in the application Documents directory.
-+ (void)createEditableCopyOfDatabaseIfNeeded:(BOOL)force
++ (void)migrate:(NSString*)dbname to:(NSString*)newdbname queries:(NSString*)query_file
{
- // First, test for existence.
- BOOL success;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
- NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:MAIN_DATABASE_NAME];
- //
- // migration
- //
- // Update from version 1.2.*
- //
- NSString *oldDBPath = [documentsDirectory stringByAppendingPathComponent:@"db1.2.sql"];
- success = [fileManager fileExistsAtPath:oldDBPath];
+ NSString *oldDBPath = [documentsDirectory stringByAppendingPathComponent:dbname];
+ NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:newdbname];
+
+ BOOL success = [fileManager fileExistsAtPath:oldDBPath];
if (success) {
- sqlite3 *db12 = [DBConnection openDatabase:@"db1.2.sql"];
+ sqlite3 *oldDB = [DBConnection openDatabase:dbname];
char *errmsg;
- NSString *migrateSQL = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"update_v12_to_v13.sql"];
+ NSString *migrateSQL = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:query_file];
NSData *sqldata = [fileManager contentsAtPath:migrateSQL];
NSString *sql = [[[NSString alloc] initWithData:sqldata encoding:NSUTF8StringEncoding] autorelease];
- if (sqlite3_exec(db12, [sql UTF8String], NULL, NULL, &errmsg) == SQLITE_OK) {
+ if (sqlite3_exec(oldDB, [sql UTF8String], NULL, NULL, &errmsg) == SQLITE_OK) {
// succeeded to update.
[fileManager moveItemAtPath:oldDBPath toPath:writableDBPath error:&error];
- NSLog(@"Updated database from version 1.2 to 1.3.");
+ NSLog(@"Updated database (%@)", query_file);
return;
}
- NSLog(@"Failed to update database (Reason: %s). Discard version 1.2 data...", errmsg);
+ NSLog(@"Failed to update database (Reason: %s). Discard %@ data...", errmsg, dbname);
[fileManager removeItemAtPath:oldDBPath error:&error];
- }
+ }
+}
+
+// Creates a writable copy of the bundled default database in the application Documents directory.
++ (void)createEditableCopyOfDatabaseIfNeeded:(BOOL)force
+{
+ // First, test for existence.
+ BOOL success;
+ NSFileManager *fileManager = [NSFileManager defaultManager];
+ NSError *error;
+ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
+ NSString *documentsDirectory = [paths objectAtIndex:0];
+ NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:MAIN_DATABASE_NAME];
+
+ [DBConnection migrate:@"db1.2.sql" to:@"db1.3.sql" queries:@"update_v12_to_v13.sql"];
+ [DBConnection migrate:@"db1.3.sql" to:@"db1.4.sql" queries:@"update_v13_to_v14.sql"];
if (force) {
[fileManager removeItemAtPath:writableDBPath error:&error];
@@ -188,8 +137,10 @@ + (void)beginTransaction
+ (void)commitTransaction
{
- char *errmsg;
+ char *errmsg;
+ Stopwatch *sw = [Stopwatch stopwatch];
sqlite3_exec(theDatabase, "COMMIT", NULL, NULL, &errmsg);
+ [sw lap:@"COMMIT"];
}
+ (Statement*)statementWithQuery:(const char *)sql
Oops, something went wrong.

0 comments on commit 39fa661

Please sign in to comment.