Skip to content

Commit edd6a7f

Browse files
committed
change Simplenote sync from using app engine api2 to Simperium api
Fixes an issue where NV would revert a note's contents after the first sync. Provides proper support for merging of content if a note has been edited elsewhere inbetween syncs. Much faster syncing. Best effort has been made to preserve existing semantics and reuse existing data structures (syncMD) wherever possible so users should not be affected when they upgrade. Most changes are related to index fetching as Simperium only provides item id and version in its' index whereas SN API2 provided metadata like a note's deleted status. Since deleted is no longer available, we must fetch each note to determine it's deleted status, therefore additional code to detect deleted status has been added to all the entry collectors. This update also supports Simperium's changes api to fetch only the diffs for notes since a certain mark (provided in changes and in index). A full sync (index pull) is performed when app is first opened, subsequently only changes will be fetched.
1 parent 17d288e commit edd6a7f

11 files changed

+445
-171
lines changed

NotationPrefsViewController.m

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -448,17 +448,18 @@ - (void)cancelLoginVerifier {
448448

449449
- (void)startLoginVerifier {
450450
if (!loginVerifier && [[syncAccountField stringValue] length] && [[syncPasswordField stringValue] length]) {
451-
NSURL *loginURL = [SimplenoteSession servletURLWithPath:@"/api/login" parameters:nil];
452-
loginVerifier = [[SyncResponseFetcher alloc] initWithURL:loginURL bodyStringAsUTF8B64:
453-
[[NSDictionary dictionaryWithObjectsAndKeys: [syncAccountField stringValue], @"email", [syncPasswordField stringValue], @"password", nil]
454-
URLEncodedString] delegate:self];
451+
NSURL *loginURL = [SimplenoteSession servletURLWithPath:@"/api2/login" parameters:nil];
452+
loginVerifier = [[SyncResponseFetcher alloc] initWithURL:loginURL POSTData:
453+
[[[NSDictionary dictionaryWithObjectsAndKeys:
454+
[syncAccountField stringValue], @"email", [syncPasswordField stringValue], @"password", @"1", @"api", nil] URLEncodedString]
455+
dataUsingEncoding:NSUTF8StringEncoding] delegate:self];
455456
[loginVerifier start];
456457
[self setVerificationStatus:VERIFY_IN_PROGRESS withString:@""];
457458
}
458459
}
459460

460461
- (void)syncResponseFetcher:(SyncResponseFetcher*)fetcher receivedData:(NSData*)data returningError:(NSString*)errString {
461-
BOOL authFailed = errString && [fetcher statusCode] == 400;
462+
BOOL authFailed = errString && [fetcher statusCode] >= 400;
462463

463464
[self setVerificationStatus:errString ? VERIFY_FAILED : VERIFY_SUCCESS withString:
464465
authFailed ? NSLocalizedString(@"Incorrect login and password", @"sync status menu msg") : errString];
@@ -483,7 +484,7 @@ - (IBAction)changePassphrase:(id)sender {
483484
}
484485

485486
- (IBAction)visitSimplenoteSite:(id)sender {
486-
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"http://simplenoteapp.com/"]];
487+
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"http://simplenote.com/"]];
487488
}
488489

489490
- (IBAction)makeDefaultExtension:(id)sender {

NotationSyncServiceManager.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
- (NoteObject*)noteForKey:(NSString*)key ofServiceClass:(Class<SyncServiceSession>)serviceClass;
3030

31+
- (void)processPartialNotesList:(NSArray*)entries withRemovedList:(NSArray*)removedEntries fromSyncSession:(id <SyncServiceSession>)syncSession;
3132
- (void)makeNotesMatchList:(NSArray*)MDEntries fromSyncSession:(id <SyncServiceSession>)syncSession;
3233

3334
- (void)schedulePushToAllSyncServicesForNote:(id <SynchronizedNote>)aNote;

NotationSyncServiceManager.m

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,12 @@ - (void)syncSession:(id <SyncServiceSession>)syncSession receivedFullNoteList:(N
9292
[self makeNotesMatchList:allEntries fromSyncSession:syncSession];
9393
}
9494

95+
- (void)syncSession:(id <SyncServiceSession>)syncSession receivedPartialNoteList:(NSArray*)entries withRemovedList:(NSArray*)removed {
96+
97+
[self processPartialNotesList:entries withRemovedList:removed fromSyncSession:syncSession];
98+
}
99+
100+
95101
- (void)syncSession:(id <SyncServiceSession>)syncSession receivedAddedNotes:(NSArray*)addedNotes {
96102
//insert these notes into the list
97103
//no need to "reveal" them to the user
@@ -120,6 +126,64 @@ - (void)syncSessionDidFinishRemoteModifications:(id <SyncServiceSession>)syncSes
120126
[self _purgeAlreadyDistributedDeletedNotes];
121127
}
122128

129+
- (void)processPartialNotesList:(NSArray*)entries withRemovedList:(NSArray*)removedEntries fromSyncSession:(id <SyncServiceSession>)syncSession {
130+
NSString *keyName = [[syncSession class] nameOfKeyElement];
131+
NSString *serviceName = [[syncSession class] serviceName];
132+
NSUInteger i = 0;
133+
NSMutableArray *notesToDelete = [NSMutableArray array];
134+
NSMutableArray *changedNotes = [NSMutableArray array];
135+
NSMutableArray *checkEntries = [NSMutableArray array];
136+
NSDictionary *localNotesDict = [self invertedDictionaryOfNotes:allNotes forSession:syncSession];
137+
138+
//we only have a partial remote list, plus possibly a list of permanently deleted notes.
139+
//since we only have some remotes, we can't perform full sync operations like comparing
140+
//full sets of notes to find out what local ones need to be removed. we rely on the partial
141+
//list updates to keep us up to date.
142+
for (i=0; i<[entries count]; i++) {
143+
NSDictionary *remoteEntry = [entries objectAtIndex:i];
144+
NSString *remoteKey = [remoteEntry objectForKey:keyName];
145+
id <SynchronizedNote>note = [localNotesDict objectForKey:remoteKey];
146+
NSDictionary *thisServiceInfo = [[note syncServicesMD] objectForKey:serviceName];
147+
if ([localNotesDict objectForKey:remoteKey]) {
148+
if ([syncSession remoteEntryWasMarkedDeleted:remoteEntry]) {
149+
[notesToDelete addObject:note];
150+
} else {
151+
NSComparisonResult changeDiff = [syncSession localEntry:thisServiceInfo compareToRemoteEntry:remoteEntry];
152+
if (changeDiff == NSOrderedAscending) {
153+
[changedNotes addObject:note];
154+
} else {
155+
//NSLog(@"remote note not newer, not asking for changes");
156+
}
157+
}
158+
} else {
159+
// If we don't have the note and it is marked deleted, we don't care
160+
// Otherwise, we should add it to checkEntries which will add it to our collection
161+
if (![syncSession remoteEntryWasMarkedDeleted:remoteEntry]) {
162+
[checkEntries addObject:remoteEntry];
163+
}
164+
}
165+
}
166+
for (i=0; i<[removedEntries count]; i++) {
167+
NSDictionary *remoteEntry = [removedEntries objectAtIndex:i];
168+
NSString *remoteKey = [remoteEntry objectForKey:keyName];
169+
if ([localNotesDict objectForKey:remoteKey]) {
170+
[notesToDelete addObject:[localNotesDict objectForKey:remoteKey]];
171+
}
172+
}
173+
if ([checkEntries count]) {
174+
[syncSession startCollectingAddedNotesWithEntries:checkEntries mergingWithNotes:nil];
175+
}
176+
if ([changedNotes count]) {
177+
[syncSession startCollectingChangedNotesWithEntries:changedNotes];
178+
}
179+
if ([notesToDelete count]) {
180+
NSLog(@"removing %u notes", [notesToDelete count]);
181+
[syncSession suppressPushingForNotes:notesToDelete];
182+
[self removeNotes:notesToDelete];
183+
[syncSession stopSuppressingPushingForNotes:notesToDelete];
184+
}
185+
}
186+
123187
- (void)makeNotesMatchList:(NSArray*)MDEntries fromSyncSession:(id <SyncServiceSession>)syncSession {
124188
NSString *keyName = [[syncSession class] nameOfKeyElement];
125189
NSString *serviceName = [[syncSession class] serviceName];

NoteObject.m

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,10 @@ - (id)initWithCatalogEntry:(NoteCatalogEntry*)entry delegate:(id)aDelegate {
595595

596596
//assume any changes have been synchronized with undomanager
597597
- (void)setContentString:(NSAttributedString*)attributedString {
598+
[self setContentString:attributedString updateTime:YES];
599+
}
600+
601+
- (void)setContentString:(NSAttributedString*)attributedString updateTime:(BOOL)updateTime {
598602
if (attributedString) {
599603
[contentString setAttributedString:attributedString];
600604

@@ -604,7 +608,7 @@ - (void)setContentString:(NSAttributedString*)attributedString {
604608

605609
[delegate note:self attributeChanged:NotePreviewString];
606610

607-
[self makeNoteDirtyUpdateTime:YES updateFile:YES];
611+
[self makeNoteDirtyUpdateTime:updateTime updateFile:YES];
608612
}
609613
}
610614
- (NSAttributedString*)contentString {
@@ -1538,7 +1542,7 @@ - (void)updateWithSyncBody:(NSString*)newBody andTitle:(NSString*)newTitle {
15381542
[attributedBodyString addStrikethroughNearDoneTagsForRange:NSMakeRange(0, [attributedBodyString length])];
15391543

15401544
//should eventually sync changes back to disk:
1541-
[self setContentString:[attributedBodyString autorelease]];
1545+
[self setContentString:[attributedBodyString autorelease] updateTime:NO];
15421546

15431547
//actions that user-editing via AppDelegate would have handled for us:
15441548
[self updateContentCacheCStringIfNecessary];

SimplenoteEntryCollector.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
NSArray *entriesToCollect;
2929
NSMutableArray *entriesCollected, *entriesInError;
3030
NSUInteger entryFinishedCount;
31-
NSString *authToken, *email;
31+
NSString *simperiumToken;
3232
SEL entriesFinishedCallback;
3333
id collectionDelegate;
3434
BOOL stopped;
@@ -37,7 +37,7 @@
3737
id representedObject;
3838
}
3939

40-
- (id)initWithEntriesToCollect:(NSArray*)wantedEntries authToken:(NSString*)anAuthToken email:(NSString*)anEmail;
40+
- (id)initWithEntriesToCollect:(NSArray*)wantedEntries simperiumToken:(NSString*)aSimperiumToken;
4141

4242
- (NSArray*)entriesToCollect;
4343
- (NSArray*)entriesCollected;
@@ -66,7 +66,7 @@
6666
}
6767

6868

69-
- (id)initWithEntries:(NSArray*)wantedEntries operation:(SEL)opSEL authToken:(NSString*)anAuthToken email:(NSString*)anEmail;
69+
- (id)initWithEntries:(NSArray*)wantedEntries operation:(SEL)opSEL simperiumToken:(NSString*)aSimperiumToken;
7070

7171
- (SyncResponseFetcher*)_fetcherForNote:(NoteObject*)aNote creator:(BOOL)doesCreate;
7272
- (SyncResponseFetcher*)fetcherForCreatingNote:(NoteObject*)aNote;

0 commit comments

Comments
 (0)