2 // pithos_macosAppDelegate.m
5 // Copyright 2011 GRNET S.A. All rights reserved.
7 // Redistribution and use in source and binary forms, with or
8 // without modification, are permitted provided that the following
11 // 1. Redistributions of source code must retain the above
12 // copyright notice, this list of conditions and the following
15 // 2. Redistributions in binary form must reproduce the above
16 // copyright notice, this list of conditions and the following
17 // disclaimer in the documentation and/or other materials
18 // provided with the distribution.
20 // THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
21 // OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
24 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
27 // USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28 // AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 // POSSIBILITY OF SUCH DAMAGE.
33 // The views and conclusions contained in the software and
34 // documentation are those of the authors and should not be
35 // interpreted as representing official policies, either expressed
36 // or implied, of GRNET S.A.
38 #import "pithos_macosAppDelegate.h"
39 #import "PithosBrowserController.h"
40 #import "PithosPreferencesController.h"
41 #import "ASIPithosRequest.h"
42 #import "ASIDownloadCache.h"
44 @implementation pithos_macosAppDelegate
45 @synthesize storageURLPrefix, publicURLPrefix, loginURLPrefix, aboutURL;
47 - (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
49 storageURLPrefix = [[NSUserDefaults standardUserDefaults] stringForKey:@"PithosStorageURLPrefix"];
50 if (!storageURLPrefix) {
51 storageURLPrefix = [NSString stringWithString:@"https://pithos.dev.grnet.gr/v1"];
53 testURL = [NSURL URLWithString:storageURLPrefix];
54 if (!testURL || !testURL.scheme || !testURL.host)
55 storageURLPrefix = [NSString stringWithString:@"https://pithos.dev.grnet.gr/v1"];
57 [storageURLPrefix retain];
59 publicURLPrefix = [[NSUserDefaults standardUserDefaults] stringForKey:@"PithosPublicURLPrefix"];
60 if (!publicURLPrefix) {
61 publicURLPrefix = [NSString stringWithString:@"https://pithos.dev.grnet.gr"];
63 testURL = [NSURL URLWithString:publicURLPrefix];
64 if (!testURL || !testURL.scheme || !testURL.host)
65 publicURLPrefix = [NSString stringWithString:@"https://pithos.dev.grnet.gr"];
67 [publicURLPrefix retain];
69 loginURLPrefix = [[NSUserDefaults standardUserDefaults] stringForKey:@"PithosLoginURLPrefix"];
70 if (!loginURLPrefix) {
71 loginURLPrefix = [NSString stringWithString:@"https://pithos.dev.grnet.gr/login"];
73 testURL = [NSURL URLWithString:loginURLPrefix];
74 if (!testURL || !testURL.scheme || !testURL.host)
75 loginURLPrefix = [NSString stringWithString:@"https://pithos.dev.grnet.gr/login"];
77 [loginURLPrefix retain];
79 aboutURL = [[NSUserDefaults standardUserDefaults] stringForKey:@"PithosAboutURL"];
81 aboutURL = [NSString stringWithString:@"https://pithos.dev.grnet.gr/docs"];
83 testURL = [NSURL URLWithString:aboutURL];
84 if (!testURL || !testURL.scheme || !testURL.host)
85 aboutURL = [NSString stringWithString:@"https://pithos.dev.grnet.gr/docs"];
89 [[NSAppleEventManager sharedAppleEventManager] setEventHandler:self
90 andSelector:@selector(handleAppleEvent:withReplyEvent:)
91 forEventClass:kInternetEventClass
92 andEventID:kAEGetURL];
93 [self showPithosBrowser:self];
95 [self authenticateWithAuthUser:[[userDefaultsController values] valueForKey:@"authUser"]
96 authToken:[[userDefaultsController values] valueForKey:@"authToken"]];
99 // Based on: http://cocoatutorial.grapewave.com/2010/01/creating-a-status-bar-application/
100 // and: http://www.cocoadev.com/index.pl?ThumbnailImages
101 - (void)awakeFromNib {
102 NSImage *sourceImage = [NSImage imageNamed:NSImageNameFolder];
104 NSImage *smallImage = [[[NSImage alloc] initWithSize:NSMakeSize(18, 18)] autorelease];
105 [smallImage lockFocus];
106 [[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];
107 [sourceImage setSize:NSMakeSize(18, 18)];
108 [sourceImage compositeToPoint:NSZeroPoint operation:NSCompositeCopy];
109 [smallImage unlockFocus];
111 statusItem = [[[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength] retain];
112 [statusItem setMenu:statusMenu];
113 [statusItem setImage:sourceImage];
114 [statusItem setHighlightMode:YES];
117 - (void)handleAppleEvent:(NSAppleEventDescriptor *)event withReplyEvent: (NSAppleEventDescriptor *)replyEvent {
118 NSURL *url = [NSURL URLWithString:[[event paramDescriptorForKeyword:keyDirectObject] stringValue]];
119 NSString *host = [url host];
120 NSString *query = [url query];
121 NSLog(@"host : '%@', query: '%@'", host, query);
122 NSProcessInfo *processInfo = [NSProcessInfo processInfo];
123 if ([host isEqualToString:[NSString stringWithFormat:@"%@_%d", [processInfo processName], [processInfo processIdentifier]]] && query) {
126 NSRange userRange = [query rangeOfString:@"user=" options:NSCaseInsensitiveSearch];
127 if (userRange.length == 0)
128 // XXX maybe show an error message?
130 NSUInteger authUserStartLocation = userRange.location + userRange.length;
131 NSRange userEndRange = [query rangeOfString:@"&" options:NSCaseInsensitiveSearch
132 range:NSMakeRange(authUserStartLocation, [query length] - authUserStartLocation)];
133 if (userEndRange.length) {
134 authUser = [[query substringWithRange:NSMakeRange(authUserStartLocation, userEndRange.location - authUserStartLocation)]
135 stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
137 authUser = [[query substringFromIndex:authUserStartLocation]
138 stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
142 NSRange tokenRange = [query rangeOfString:@"token=" options:NSCaseInsensitiveSearch];
143 if (tokenRange.length == 0)
144 // XXX maybe show an error message?
146 NSUInteger authTokenStartLocation = tokenRange.location + tokenRange.length;
147 NSRange tokenEndRange = [query rangeOfString:@"&" options:NSCaseInsensitiveSearch
148 range:NSMakeRange(authTokenStartLocation, [query length] - authTokenStartLocation)];
149 if (tokenEndRange.length) {
150 authToken = [[query substringWithRange:NSMakeRange(authTokenStartLocation, tokenEndRange.location - authTokenStartLocation)]
151 stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
153 authToken = [[query substringFromIndex:authTokenStartLocation]
154 stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
157 NSLog(@"query authUser: '%@', authToken: '%@'", authUser, authToken);
158 if ([authUser length] && [authToken length]) {
159 [[userDefaultsController values] setValue:authUser forKey:@"authUser"];
160 [[userDefaultsController values] setValue:authToken forKey:@"authToken"];
162 [self authenticateWithAuthUser:authUser authToken:authToken];
164 // XXX else maybe show an error message?
166 // XXX else maybe show an error message?
172 - (IBAction)showPithosBrowser:(id)sender {
173 [pithosBrowserController showWindow:sender];
174 [[pithosBrowserController window] makeKeyAndOrderFront:sender];
175 [NSApp activateIgnoringOtherApps:YES];
178 - (IBAction)showPithosPreferences:(id)sender {
179 [pithosPreferencesController showWindow:sender];
180 [[pithosPreferencesController window] makeKeyAndOrderFront:sender];
181 [NSApp activateIgnoringOtherApps:YES];
184 - (IBAction)aboutPithos:(id)sender {
185 [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:self.aboutURL]];
189 #pragma Authentication
191 - (void)authenticateWithAuthUser:(NSString *)authUser authToken:(NSString *)authToken {
192 NSLog(@"Authentication - storageURLPrefix:%@, authUser:%@, authToken:%@", storageURLPrefix, authUser, authToken);
193 if ([authUser length] && [authToken length]) {
194 [[ASIDownloadCache sharedCache] clearCachedResponsesForStoragePolicy:ASICacheForSessionDurationCacheStoragePolicy];
195 [[ASIPithosRequest sharedQueue] cancelAllOperations];
196 [ASIPithosRequest setAuthURL:storageURLPrefix];
197 [ASIPithosRequest setStorageURLPrefix:storageURLPrefix];
198 [ASIPithosRequest setAuthUser:authUser];
199 [ASIPithosRequest setAuthToken:authToken];
200 [ASIPithosRequest setPublicURLPrefix:publicURLPrefix];
202 [[NSNotificationCenter defaultCenter] postNotificationName:@"PithosAuthenticationCredentialsUpdated" object:self];