2 // AdiumApplescriptRunner.m
5 // Created by Evan Schoenberg on 4/29/06.
8 #import "AdiumApplescriptRunner.h"
10 @implementation AdiumApplescriptRunner
13 if ((self = [super init])) {
14 NSDistributedNotificationCenter *distributedNotificationCenter = [NSDistributedNotificationCenter defaultCenter];
15 [distributedNotificationCenter addObserver:self
16 selector:@selector(applescriptRunnerIsReady:)
17 name:@"AdiumApplescriptRunner_IsReady"
19 [distributedNotificationCenter addObserver:self
20 selector:@selector(applescriptRunnerDidQuit:)
21 name:@"AdiumApplescriptRunner_DidQuit"
24 [distributedNotificationCenter addObserver:self
25 selector:@selector(applescriptDidRun:)
26 name:@"AdiumApplescript_DidRun"
29 //Check for an existing AdiumApplescriptRunner; if there is one, it will respond with AdiumApplescriptRunner_IsReady
30 [distributedNotificationCenter postNotificationName:@"AdiumApplescriptRunner_RespondIfReady"
33 deliverImmediately:NO];
41 [[NSDistributedNotificationCenter defaultCenter] removeObserver:self];
43 [[NSDistributedNotificationCenter defaultCenter] postNotificationName:@"AdiumApplescriptRunner_Quit"
46 deliverImmediately:NO];
51 - (void)_executeApplescriptWithDict:(NSDictionary *)executionDict
53 [[NSDistributedNotificationCenter defaultCenter] postNotificationName:@"AdiumApplescriptRunner_ExecuteScript"
55 userInfo:executionDict
56 deliverImmediately:NO];
59 - (void)launchApplescriptRunner
61 NSString *applescriptRunnerPath = [[NSBundle mainBundle] pathForResource:@"AdiumApplescriptRunner"
65 //Houston, we are go for launch.
66 if (applescriptRunnerPath) {
67 LSLaunchFSRefSpec spec;
69 OSStatus err = FSPathMakeRef((UInt8 *)[applescriptRunnerPath fileSystemRepresentation], &appRef, NULL);
71 spec.appRef = &appRef;
74 spec.passThruParams = NULL;
75 spec.launchFlags = kLSLaunchDontAddToRecents | kLSLaunchDontSwitch | kLSLaunchNoParams | kLSLaunchAsync;
76 spec.asyncRefCon = NULL;
77 err = LSOpenFromRefSpec(&spec, NULL);
80 NSLog(@"Could not launch %@",applescriptRunnerPath);
84 NSLog(@"Could not find AdiumApplescriptRunner...");
89 * @brief Run an applescript, optinally calling a function with arguments, and notify a target/selector with its output when it is done
91 - (void)runApplescriptAtPath:(NSString *)path function:(NSString *)function arguments:(NSArray *)arguments notifyingTarget:(id)target selector:(SEL)selector userInfo:(id)userInfo
93 NSString *uniqueID = [[NSProcessInfo processInfo] globallyUniqueString];
95 if (!runningApplescriptsDict) runningApplescriptsDict = [[NSMutableDictionary alloc] init];
97 if (target && selector) {
98 [runningApplescriptsDict setObject:[NSDictionary dictionaryWithObjectsAndKeys:
100 NSStringFromSelector(selector), @"selector",
101 userInfo, @"userInfo", nil]
105 NSDictionary *executionDict = [NSDictionary dictionaryWithObjectsAndKeys:
107 (function ? function : @""), @"function",
108 (arguments ? arguments : [NSArray array]), @"arguments",
109 uniqueID, @"uniqueID",
112 if (applescriptRunnerIsReady) {
113 [self _executeApplescriptWithDict:executionDict];
116 if (!pendingApplescriptsArray) pendingApplescriptsArray = [[NSMutableArray alloc] init];
118 [pendingApplescriptsArray addObject:executionDict];
120 [self launchApplescriptRunner];
124 - (void)applescriptRunnerIsReady:(NSNotification *)inNotification
126 NSEnumerator *enumerator;
127 NSDictionary *executionDict;
129 applescriptRunnerIsReady = YES;
131 enumerator = [pendingApplescriptsArray objectEnumerator];
132 while ((executionDict = [enumerator nextObject])) {
133 [self _executeApplescriptWithDict:executionDict];
136 [pendingApplescriptsArray release]; pendingApplescriptsArray = nil;
139 - (void)applescriptRunnerDidQuit:(NSNotification *)inNotification
141 applescriptRunnerIsReady = NO;
144 - (void)applescriptDidRun:(NSNotification *)inNotification
146 NSDictionary *userInfo = [inNotification userInfo];
147 NSString *uniqueID = [userInfo objectForKey:@"uniqueID"];
149 NSDictionary *targetDict = [runningApplescriptsDict objectForKey:uniqueID];
151 id target = [targetDict objectForKey:@"target"];
152 //Selector will be of the form applescriptDidRun:resultString:
153 SEL selector = NSSelectorFromString([targetDict objectForKey:@"selector"]);
156 [target performSelector:selector
157 withObject:[targetDict objectForKey:@"userInfo"]
158 withObject:[userInfo objectForKey:@"resultString"]];
160 //No further need for this dictionary entry
161 [runningApplescriptsDict removeObjectForKey:uniqueID];
163 if (![runningApplescriptsDict count]) {
164 [runningApplescriptsDict release]; runningApplescriptsDict = nil;