-
Notifications
You must be signed in to change notification settings - Fork 4
/
GrowlNotifyioPathway.m
200 lines (136 loc) · 5.51 KB
/
GrowlNotifyioPathway.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
//
// GrowlNotifyioPathway.m
// Growl
//
// Created by awixted on 10/27/09.
// Copyright 2009 __MyCompanyName__. All rights reserved.
//
#import "GrowlNotifyioPathway.h"
#import "CJSONDeserializer.h"
#import "GrowlDefines.h"
#import "GrowlApplicationBridge.h"
@interface GrowlNotifyioPathway (PRIVATE)
- (void)initRemoteHost;
@end
@implementation GrowlNotifyioPathway
@synthesize messageData;
- (void) dealloc
{
[notifyConn release], notifyConn = nil;
[iconConn release], iconConn = nil;
[messageData release], messageData = nil;
[super dealloc];
}
- (BOOL) setEnabled:(BOOL)flag {
NSLog(@"GrowlNotifyioPathway>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
[self initRemoteHost];
// Register for notifications about clicks so we can open links
[[NSDistributedNotificationCenter defaultCenter] addObserver:self
selector:@selector(growlNotificationWasClicked:)
name:@"GrowlGrowlClicked!"
object:nil];
return [super setEnabled:flag];
}
- (void)initRemoteHost
{
NSString *filepath = [NSString stringWithFormat:@"%@/.growlURL", NSHomeDirectory()];
NSError *error;
NSString *stringFromFileAtPath = [[NSString alloc]
initWithContentsOfFile:filepath
encoding:NSASCIIStringEncoding
error:&error];
NSLog(@"contents of file: %@", stringFromFileAtPath);
if([stringFromFileAtPath length] == 0)
{
NSLog(@"the file at path %@ is empty", filepath);
return;
}
NSString *urlString = [stringFromFileAtPath stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSURL *url = [NSURL URLWithString:urlString];
[stringFromFileAtPath release];
// Timeout after 100 minutes. It'll reconnect after that in connection:didFailWithError:
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:(60*100)];
notifyConn = [[NSURLConnection alloc] initWithRequest:urlRequest delegate:self startImmediately:YES];
NSLog(@"notifyConn: %@", notifyConn);
}
#pragma mark NSDistributedNotificationCenter callback method
- (void)growlNotificationWasClicked:(id)context
{
NSLog(@"context! %@", context);
if(![context isKindOfClass:[NSNotification class]])
{
NSLog(@"the parameter isn't a NSNotification");
return;
}
NSNotification *notification = (NSNotification *)context;
NSDictionary *userInfo = [notification userInfo];
NSString *urlString = [userInfo objectForKey:@"ClickedContext"];
// open the url
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:urlString]];
}
#pragma mark NSURLConnectionDelegate
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(@"did fail with error: %@ on connection: %@", error, connection);
// Try reconnecting.
[connection release], connection = nil;
[self initRemoteHost];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSLog(@"received response: %@ for connection %@", response, connection);
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSLog(@"connection did receive data");
if([connection isEqualTo:notifyConn])
{
NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"data: %@", jsonString);
// Parse the json
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF32BigEndianStringEncoding];
[jsonString release], jsonString = nil;
NSError *error = nil;
NSDictionary *messageDict = [[CJSONDeserializer deserializer] deserializeAsDictionary:jsonData error:&error];
// Change the keys in this dict into ones growl understands
self.messageData = [[NSMutableDictionary alloc] initWithCapacity:3];
[messageData setObject:@"Growl" forKey:GROWL_APP_NAME];
[messageData setObject:@"Notifyio message received" forKey:GROWL_NOTIFICATION_NAME];
id piece;
if(piece = [messageDict objectForKey:@"title"])
[messageData setObject:piece forKey:GROWL_NOTIFICATION_TITLE];
if(piece = [messageDict objectForKey:@"text"])
[messageData setObject:piece forKey:GROWL_NOTIFICATION_DESCRIPTION];
if(piece = [messageDict objectForKey:@"link"])
[messageData setObject:piece forKey:GROWL_NOTIFICATION_CLICK_CONTEXT];
// TODO: handle sticky and link
// Keep the data in case we need it to stick around because we won't be posting the growl notif
// until we get the icon
// Get the icon from the json data
NSString *iconURLStr = [messageDict objectForKey:@"icon"];
if(!iconURLStr)
{
[self postNotificationWithDictionary:self.messageData];
self.messageData = nil;
}
else {
// Get the icon from the url
NSURL *url = [NSURL URLWithString:iconURLStr];
NSMutableURLRequest *urlRequest = [[NSMutableURLRequest alloc] initWithURL:url];
iconConn = [[NSURLConnection alloc] initWithRequest:urlRequest delegate:self startImmediately:YES];
}
}
else if([connection isEqualTo:iconConn])
{
// Make an image out of the received data
NSImage *image = [[NSImage alloc] initWithData:data];
// add the image data to the dictionary we're going to pass
//[messageData setObject:[image TIFFRepresentation] forKey:GROWL_NOTIFICATION_ICON];
[messageData setObject:image forKey:GROWL_NOTIFICATION_ICON];
[self postNotificationWithDictionary:self.messageData];
//TODO: release image here?
[iconConn release], iconConn = nil;
self.messageData = nil;
}
}
@end