Using pithos icon for the status bar.
[pithos-macos] / pithos-macos / pithos_macosAppDelegate.m
index e9282a1..bd68cf8 100644 (file)
 
 #import "pithos_macosAppDelegate.h"
 #import "PithosBrowserController.h"
+#import "PithosPreferencesController.h"
+#import "PithosSyncDaemon.h"
+#import "ASIPithosRequest.h"
+#import "ASIDownloadCache.h"
 
 @implementation pithos_macosAppDelegate
-@synthesize pithosBrowserController;
+@synthesize storageURLPrefix, publicURLPrefix, loginURLPrefix, aboutURL;
+@synthesize syncContainerName, syncTimeInterval, pithosBrowserController, pithosSyncDaemon, alwaysNo;
 
 - (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
-    [pithosBrowserController showWindow:self];
+    NSURL *testURL;
+    storageURLPrefix = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"PithosStorageURLPrefix"];
+    if (!storageURLPrefix) {
+        storageURLPrefix = [NSString stringWithString:@"https://pithos.dev.grnet.gr/v1"];
+    } else {
+        testURL = [NSURL URLWithString:storageURLPrefix];
+        if (!testURL || !testURL.scheme || !testURL.host)
+            storageURLPrefix = [NSString stringWithString:@"https://pithos.dev.grnet.gr/v1"];
+    }
+    [storageURLPrefix retain];
+    
+    publicURLPrefix = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"PithosPublicURLPrefix"];
+    if (!publicURLPrefix) {
+        publicURLPrefix = [NSString stringWithString:@"https://pithos.dev.grnet.gr"];
+    } else {
+        testURL = [NSURL URLWithString:publicURLPrefix];
+        if (!testURL || !testURL.scheme || !testURL.host)
+            publicURLPrefix = [NSString stringWithString:@"https://pithos.dev.grnet.gr"];
+    }
+    [publicURLPrefix retain];
+    
+    loginURLPrefix = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"PithosLoginURLPrefix"];
+    if (!loginURLPrefix) {
+        loginURLPrefix = [NSString stringWithString:@"https://pithos.dev.grnet.gr/login"];
+    } else {
+        testURL = [NSURL URLWithString:loginURLPrefix];
+        if (!testURL || !testURL.scheme || !testURL.host)
+            loginURLPrefix = [NSString stringWithString:@"https://pithos.dev.grnet.gr/login"];
+    }
+    [loginURLPrefix retain];
+
+    aboutURL = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"PithosAboutURL"];
+    if (!aboutURL) {
+        aboutURL = [NSString stringWithString:@"https://pithos.dev.grnet.gr/docs"];
+    } else {
+        testURL = [NSURL URLWithString:aboutURL];
+        if (!testURL || !testURL.scheme || !testURL.host)
+            aboutURL = [NSString stringWithString:@"https://pithos.dev.grnet.gr/docs"];
+    }
+    [aboutURL retain];
+    
+    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+    NSString *syncDirectoryPath = [userDefaults stringForKey:@"pithosSyncDirectoryPath"];
+    if (!syncDirectoryPath || ![syncDirectoryPath length]) {
+        syncDirectoryPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:@"Pithos"];
+    } else {
+        NSFileManager *fileManager = [NSFileManager defaultManager];
+        BOOL isDirectory;
+        BOOL fileExists = [fileManager fileExistsAtPath:syncDirectoryPath isDirectory:&isDirectory];
+        NSError *error = nil;
+        if ((fileExists && !isDirectory) || 
+            (!fileExists && (![fileManager createDirectoryAtPath:syncDirectoryPath withIntermediateDirectories:YES attributes:nil error:&error] || error))) {
+            syncDirectoryPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:@"Pithos"];
+        }   
+    }
+    [userDefaults setObject:syncDirectoryPath forKey:@"pithosSyncDirectoryPath"];
+    [userDefaults synchronize];
+    
+    syncContainerName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"PithosSyncContainerName"];
+    if (!syncContainerName || ![syncContainerName length] || [syncContainerName isEqualToString:@"trash"]) {
+        syncContainerName = [NSString stringWithString:@"pithos"];
+    }
+    [syncContainerName retain];
+
+    syncTimeInterval = [[[[NSBundle mainBundle] infoDictionary] objectForKey:@"PithosSyncTimeInterval"] doubleValue];
+    if (syncTimeInterval <= 0) {
+        syncTimeInterval = 180.0;
+    }
+    
+    [[NSAppleEventManager sharedAppleEventManager] setEventHandler:self 
+                                                       andSelector:@selector(handleAppleEvent:withReplyEvent:) 
+                                                     forEventClass:kInternetEventClass 
+                                                        andEventID:kAEGetURL];
+    [self showPithosBrowser:self];
+    
+    [self authenticate];
+}
+
+// Based on: http://cocoatutorial.grapewave.com/2010/01/creating-a-status-bar-application/
+// and: http://www.cocoadev.com/index.pl?ThumbnailImages
+- (void)awakeFromNib {
+    NSImage *sourceImage = [NSImage imageNamed:@"pithos-large.png"];
+    
+    NSImage *smallImage = [[[NSImage alloc] initWithSize:NSMakeSize(18, 18)] autorelease];
+    [smallImage lockFocus];
+    [[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];
+    [sourceImage setSize:NSMakeSize(18, 18)];
+    [sourceImage compositeToPoint:NSZeroPoint operation:NSCompositeCopy];
+    [smallImage unlockFocus];
+    
+    statusItem = [[[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength] retain];
+    [statusItem setMenu:statusMenu];
+    [statusItem setImage:sourceImage];
+    [statusItem setHighlightMode:YES];
+    
+    self.alwaysNo = NO;
+}
+
+- (void)handleAppleEvent:(NSAppleEventDescriptor *)event withReplyEvent: (NSAppleEventDescriptor *)replyEvent {
+    NSURL *url = [NSURL URLWithString:[[event paramDescriptorForKeyword:keyDirectObject] stringValue]];
+    NSString *host = [url host];
+       NSString *query = [url query];
+    NSLog(@"host : '%@', query: '%@'", host, query);
+    NSProcessInfo *processInfo = [NSProcessInfo processInfo];
+    if ([host isEqualToString:[NSString stringWithFormat:@"%@_%d", [processInfo processName], [processInfo processIdentifier]]] && query) {
+        // user=
+        NSString *authUser;
+        NSRange userRange = [query rangeOfString:@"user=" options:NSCaseInsensitiveSearch];
+        if (userRange.length == 0)
+            // XXX maybe show an error message?
+            return;
+        NSUInteger authUserStartLocation = userRange.location + userRange.length;
+        NSRange userEndRange = [query rangeOfString:@"&" options:NSCaseInsensitiveSearch 
+                                              range:NSMakeRange(authUserStartLocation, [query length] - authUserStartLocation)];
+        if (userEndRange.length) {
+            authUser = [[query substringWithRange:NSMakeRange(authUserStartLocation, userEndRange.location - authUserStartLocation)]
+                        stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
+        } else {
+            authUser = [[query substringFromIndex:authUserStartLocation]
+                        stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
+        }
+        // token=
+        NSString *authToken;
+        NSRange tokenRange = [query rangeOfString:@"token=" options:NSCaseInsensitiveSearch];
+        if (tokenRange.length == 0)
+            // XXX maybe show an error message?
+            return;
+        NSUInteger authTokenStartLocation = tokenRange.location + tokenRange.length;
+        NSRange tokenEndRange = [query rangeOfString:@"&" options:NSCaseInsensitiveSearch 
+                                              range:NSMakeRange(authTokenStartLocation, [query length] - authTokenStartLocation)];
+        if (tokenEndRange.length) {
+            authToken = [[query substringWithRange:NSMakeRange(authTokenStartLocation, tokenEndRange.location - authTokenStartLocation)]
+                         stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
+        } else {
+            authToken = [[query substringFromIndex:authTokenStartLocation]
+                         stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
+        }
+        
+        NSLog(@"query authUser: '%@', authToken: '%@'", authUser, authToken);
+        if ([authUser length] && [authToken length]) {
+            NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+            [userDefaults setObject:authUser forKey:@"authUser"];
+            [userDefaults setObject:authToken forKey:@"authToken"];
+            [userDefaults synchronize];
+
+            [self authenticate];
+        }
+        // XXX else maybe show an error message?
+    }
+    // XXX else maybe show an error message?
+}
+
+#pragma mark -
+#pragma Actions
+
+- (IBAction)showPithosBrowser:(id)sender {
+    [pithosBrowserController showWindow:sender];
+    [[pithosBrowserController window] makeKeyAndOrderFront:sender];
+    [NSApp activateIgnoringOtherApps:YES];
+}
+
+- (IBAction)showPithosPreferences:(id)sender {
+    [pithosPreferencesController showWindow:sender];
+    [[pithosPreferencesController window] makeKeyAndOrderFront:sender];
+    [NSApp activateIgnoringOtherApps:YES];
+}
+
+- (IBAction)aboutPithos:(id)sender {
+    [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:self.aboutURL]];
+}
+
+- (IBAction)syncNow:(id)sender {
+    [pithosSyncDaemon sync];
+}
+
+#pragma mark -
+#pragma Authentication
+
+- (void)authenticate {
+    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+    NSString *authUser = [userDefaults stringForKey:@"authUser"];
+    NSString *authToken = [userDefaults stringForKey:@"authToken"];
+    NSString *syncDirectoryPath = [userDefaults stringForKey:@"pithosSyncDirectoryPath"];
+    NSLog(@"Authentication - storageURLPrefix:%@, authUser:%@, authToken:%@", storageURLPrefix, authUser, authToken);
+    if (([authUser length] == 0) || ([authToken length] == 0)) {
+        [self showPithosPreferences:self];
+    } else if ([authUser length] && [authToken length] && 
+               (![[ASIPithosRequest authUser] isEqualToString:authUser] || ![[ASIPithosRequest authToken] isEqualToString:authToken])) {
+        [[ASIDownloadCache sharedCache] clearCachedResponsesForStoragePolicy:ASICacheForSessionDurationCacheStoragePolicy];
+        [[ASIPithosRequest sharedQueue] cancelAllOperations];
+        
+        [ASIPithosRequest setAuthURL:storageURLPrefix];
+        [ASIPithosRequest setStorageURLPrefix:storageURLPrefix];
+        [ASIPithosRequest setAuthUser:authUser];
+        [ASIPithosRequest setAuthToken:authToken];
+        [ASIPithosRequest setPublicURLPrefix:publicURLPrefix];
+        
+        self.pithosSyncDaemon = [[[PithosSyncDaemon alloc] initWithDirectoryPath:syncDirectoryPath 
+                                                                   containerName:syncContainerName 
+                                                                    timeInterval:syncTimeInterval 
+                                                                 resetLocalState:NO] autorelease];
+        
+        [[NSNotificationCenter defaultCenter] postNotificationName:@"PithosAuthenticationCredentialsUpdated" object:self];
+    } else if (![pithosSyncDaemon.directoryPath isEqualToString:syncDirectoryPath]) {
+        self.pithosSyncDaemon = [[[PithosSyncDaemon alloc] initWithDirectoryPath:syncDirectoryPath 
+                                                                   containerName:syncContainerName 
+                                                                    timeInterval:syncTimeInterval 
+                                                                 resetLocalState:YES] autorelease];
+    }
 }
 
 @end