Adium plugin to pipe events/messages to an external program
1#import "PipeEventPlugin.h"
2#import "PipeEventDetailPane.h"
3#import <AIUtilities/AIImageAdditions.h>
4#import <Adium/AIContentObject.h>
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
12
13- (void)installPlugin
14{
15 [adium.contactAlertsController registerActionID:PIPE_EVENT_IDENTIFIER withHandler:self];
16}
17
18/* text for the "Action:" drop down */
19- (NSString *)shortDescriptionForActionID:(NSString *)actionID
20{
21 return PIPE_EVENT_SHORT;
22}
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
37{
38 return [NSImage imageNamed:@"TerminalIcon" forClass:[self class]];
39}
40
41- (AIModularPane *)detailsPaneForActionID:(NSString *)actionID
42{
43 return [PipeEventDetailPane actionDetailsPane];
44}
45
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
66 if ([adium.contactAlertsController isMessageEvent:eventID] &&
67 [userInfo respondsToSelector:@selector(objectForKey:)] &&
68 [userInfo objectForKey:@"AIContentObject"]) {
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
80 listObject = [(AIListContact *)listObject parentContact];
81 sender = [listObject longDisplayName];
82 } else
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]];
94 [task setStandardInput:[NSPipe pipe]];
95
96 // go go gadget nstask
97 [task launch];
98
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
112- (BOOL)allowMultipleActionsWithID:(NSString *)actionID
113{
114 /* we can be setup with different commands for different things, so, yeah */
115 return YES;
116}
117
118- (NSString *)pluginAuthor
119{
120 return @"joshua stein";
121}
122
123- (NSString *)pluginVersion
124{
125 return @"1.1";
126}
127
128- (NSString *)pluginDescription
129{
130 return @"This plugin pipes events to an external command."; // with gusto!
131}
132
133- (NSString *)pluginURL
134{
135 return @"http://jcs.org/";
136}
137
138@end