Adium plugin to pipe events/messages to an external program

xcode's editor is sloppy

set tabs to 8

+23 -24
+1 -1
PipeEventPlugin.h
··· 3 #import <Adium/AISharedAdium.h> 4 #import <Adium/AIContactAlertsControllerProtocol.h> 5 6 - #define KEY_COMMAND @"PipeEvent" 7 8 @protocol AIContentFilter; 9
··· 3 #import <Adium/AISharedAdium.h> 4 #import <Adium/AIContactAlertsControllerProtocol.h> 5 6 + #define KEY_COMMAND @"PipeEvent" 7 8 @protocol AIContentFilter; 9
+22 -23
PipeEventPlugin.m
··· 5 #import <Adium/AIListContact.h> 6 7 #define PIPE_EVENT_IDENTIFIER @"PipeEvent" 8 - #define PIPE_EVENT_SHORT @"Pipe event to command" 9 #define PIPE_EVENT_LONG @"Pipe event to \"%@\"" 10 11 @implementation PipeEventPlugin ··· 23 24 /* subtext for the "When you receive any message" line, and the text in the full events list */ 25 - (NSString *)longDescriptionForActionID:(NSString *)actionID 26 - withDetails:(NSDictionary *)details 27 { 28 - NSString *command = [details objectForKey:KEY_COMMAND]; 29 30 - if (command && [command length]) { 31 - return [NSString stringWithFormat:PIPE_EVENT_LONG, [command lastPathComponent]]; 32 - } else { 33 - return PIPE_EVENT_SHORT; 34 - } 35 } 36 37 - (NSImage *)imageForActionID:(NSString *)actionID ··· 47 /* the actual event handler */ 48 - (BOOL)performActionID:(NSString *)actionID 49 forListObject:(AIListObject *)listObject 50 - withDetails:(NSDictionary *)details 51 - triggeringEventID:(NSString *)eventID 52 - userInfo:(id)userInfo 53 { 54 NSString *command = [details objectForKey:KEY_COMMAND]; 55 NSString *message = [adium.contactAlertsController naturalLanguageDescriptionForEventID:eventID 56 - listObject:listObject 57 - userInfo:userInfo 58 - includeSubject:NO]; 59 NSString *sender; 60 AIChat *chat = nil; 61 - 62 NSTask *task = [[NSTask alloc] init]; 63 - 64 [task setLaunchPath:command]; 65 66 // for a message event, listObject should become whoever sent the message ··· 70 AIContentObject *contentObject = [userInfo objectForKey:@"AIContentObject"]; 71 AIListObject *source = [contentObject source]; 72 chat = [userInfo objectForKey:@"AIChat"]; 73 - 74 if (source) 75 listObject = source; 76 } 77 - 78 if (listObject) { 79 if ([listObject isKindOfClass:[AIListContact class]]) { 80 // use the parent ··· 84 sender = listObject.displayName; 85 } else if (chat) 86 sender = chat.displayName; 87 - 88 // pass the sender (or whatever the event sends) as the first arg 89 if (sender) 90 [task setArguments:[NSArray arrayWithObjects:sender, nil]]; 91 - 92 // stdout and stderr will be closed right away 93 [task setStandardOutput:[NSPipe pipe]]; 94 [task setStandardError:[NSPipe pipe]]; ··· 100 // close command's stdout and stderr 101 [[[task standardOutput] fileHandleForReading] closeFile]; 102 [[[task standardError] fileHandleForReading] closeFile]; 103 - 104 // send the message contents (with newline) and then close the filehandle 105 [[[task standardInput] fileHandleForWriting] writeData:[[NSString stringWithFormat:@"%@\n", message] dataUsingEncoding:NSASCIIStringEncoding]]; 106 [[[task standardInput] fileHandleForWriting] closeFile]; 107 108 // uh, i guess magic happens here and everything is cleaned up for us 109 - 110 return YES; // WE CAN 111 } 112 ··· 136 return @"http://jcs.org/"; 137 } 138 139 - @end
··· 5 #import <Adium/AIListContact.h> 6 7 #define PIPE_EVENT_IDENTIFIER @"PipeEvent" 8 + #define PIPE_EVENT_SHORT @"Pipe event to command" 9 #define PIPE_EVENT_LONG @"Pipe event to \"%@\"" 10 11 @implementation PipeEventPlugin ··· 23 24 /* subtext for the "When you receive any message" line, and the text in the full events list */ 25 - (NSString *)longDescriptionForActionID:(NSString *)actionID 26 + withDetails:(NSDictionary *)details 27 { 28 + NSString *command = [details objectForKey:KEY_COMMAND]; 29 30 + if (command && [command length]) 31 + return [NSString stringWithFormat:PIPE_EVENT_LONG, [command lastPathComponent]]; 32 + else 33 + return PIPE_EVENT_SHORT; 34 } 35 36 - (NSImage *)imageForActionID:(NSString *)actionID ··· 46 /* the actual event handler */ 47 - (BOOL)performActionID:(NSString *)actionID 48 forListObject:(AIListObject *)listObject 49 + withDetails:(NSDictionary *)details 50 + triggeringEventID:(NSString *)eventID 51 + userInfo:(id)userInfo 52 { 53 NSString *command = [details objectForKey:KEY_COMMAND]; 54 NSString *message = [adium.contactAlertsController naturalLanguageDescriptionForEventID:eventID 55 + listObject:listObject 56 + userInfo:userInfo 57 + includeSubject:NO]; 58 NSString *sender; 59 AIChat *chat = nil; 60 + 61 NSTask *task = [[NSTask alloc] init]; 62 + 63 [task setLaunchPath:command]; 64 65 // for a message event, listObject should become whoever sent the message ··· 69 AIContentObject *contentObject = [userInfo objectForKey:@"AIContentObject"]; 70 AIListObject *source = [contentObject source]; 71 chat = [userInfo objectForKey:@"AIChat"]; 72 + 73 if (source) 74 listObject = source; 75 } 76 + 77 if (listObject) { 78 if ([listObject isKindOfClass:[AIListContact class]]) { 79 // use the parent ··· 83 sender = listObject.displayName; 84 } else if (chat) 85 sender = chat.displayName; 86 + 87 // pass the sender (or whatever the event sends) as the first arg 88 if (sender) 89 [task setArguments:[NSArray arrayWithObjects:sender, nil]]; 90 + 91 // stdout and stderr will be closed right away 92 [task setStandardOutput:[NSPipe pipe]]; 93 [task setStandardError:[NSPipe pipe]]; ··· 99 // close command's stdout and stderr 100 [[[task standardOutput] fileHandleForReading] closeFile]; 101 [[[task standardError] fileHandleForReading] closeFile]; 102 + 103 // send the message contents (with newline) and then close the filehandle 104 [[[task standardInput] fileHandleForWriting] writeData:[[NSString stringWithFormat:@"%@\n", message] dataUsingEncoding:NSASCIIStringEncoding]]; 105 [[[task standardInput] fileHandleForWriting] closeFile]; 106 107 // uh, i guess magic happens here and everything is cleaned up for us 108 + 109 return YES; // WE CAN 110 } 111 ··· 135 return @"http://jcs.org/"; 136 } 137 138 + @end