jens@0: // jens@0: // IChatUtils.m jens@0: // MYUtilities jens@0: // jens@0: // Created by Jens Alfke on 3/3/08. jens@0: // Copyright 2008 Jens Alfke. All rights reserved. jens@0: // jens@0: jens@0: #import "IChatUtils.h" jens@0: #import "iChatBridge.h" jens@11: #import jens@0: jens@0: @implementation IChatUtils jens@0: jens@0: jens@0: static iChatApplication *sIChatApp; jens@0: jens@0: + (void) initialize jens@0: { jens@0: if( ! sIChatApp ) { jens@0: sIChatApp = [SBApplication applicationWithBundleIdentifier: @"com.apple.iChat"]; jens@0: sIChatApp.timeout = 5*60; // in ticks jens@0: } jens@0: } jens@0: jens@0: jens@0: + (SBApplication*) app {return sIChatApp;} jens@0: + (BOOL) isRunning {return sIChatApp.isRunning;} jens@0: + (void) activate {[sIChatApp activate];} jens@0: jens@0: jens@0: + (iChatTextChat*) activeChat jens@0: { jens@0: if( ! [sIChatApp isRunning] ) jens@0: return nil; jens@0: SBElementArray *chats = sIChatApp.textChats; jens@0: if( chats.count==0 ) jens@0: return nil; jens@0: iChatTextChat *chat = [chats objectAtIndex: 0]; jens@4: /*if( ! chat.active ) // somehow this returns NO for Bonjour chats jens@4: return nil;*/ jens@0: return chat; jens@0: } jens@0: jens@0: + (NSString*) activeChatPartner jens@0: { jens@0: iChatTextChat *chat = [self activeChat]; jens@4: Log(@"Active chat = %@",chat); jens@0: if( ! chat ) jens@0: return nil; jens@0: NSMutableArray *names = $marray(); jens@0: for( iChatBuddy *b in [chat participants] ) jens@0: [names addObject: (b.fullName ?: b.name)]; jens@4: Log(@"Particpants = %@",names); jens@0: return [names componentsJoinedByString: @", "]; jens@0: } jens@0: jens@0: + (BOOL) sendMessage: (NSString*)msg jens@0: { jens@0: iChatTextChat *chat = [self activeChat]; jens@0: if( ! chat ) jens@0: return NO; jens@0: [sIChatApp send: msg to: chat]; jens@0: return YES; jens@0: } jens@0: jens@11: + (NSDictionary*) iChatInfoForOnlinePerson: (ABPerson*)abPerson jens@11: { jens@11: if( ! abPerson ) jens@11: return nil; jens@11: IMPersonStatus bestStatus = IMPersonStatusOffline; jens@11: NSDictionary *bestInfo = nil; jens@11: for( IMService *service in [IMService allServices] ) { jens@11: for( NSString *name in [service screenNamesForPerson: abPerson] ) { jens@11: NSDictionary *info = [service infoForScreenName: name]; jens@11: if( [[info objectForKey: IMPersonCapabilitiesKey] containsObject: IMCapabilityText] ) { jens@11: IMPersonStatus status = [[info objectForKey: IMPersonStatusKey] intValue]; jens@11: if( IMComparePersonStatus(status,bestStatus) < 0 ) { // yes, it returns the wrong sign jens@11: bestInfo = info; jens@11: bestStatus = status; jens@11: } jens@11: } jens@11: } jens@11: } jens@11: return bestInfo; jens@11: } jens@11: jens@11: + (BOOL) isPersonOnline: (ABPerson*)abPerson jens@11: { jens@11: return [self iChatInfoForOnlinePerson: abPerson] != nil; jens@11: } jens@11: jens@17: + (iChatBuddy*) buddyWithScreenName: (NSString*)screenName jens@11: { jens@17: NSPredicate *pred = [NSPredicate predicateWithFormat: @"handle==%@", screenName]; jens@11: @try{ jens@11: return [[[[sIChatApp buddies] filteredArrayUsingPredicate: pred] objectAtIndex: 0] get]; jens@11: } @catch( NSException *x ) { jens@17: Log(@"buddyWithScreenName got exception: %@",x); jens@11: } jens@11: return nil; jens@11: } jens@11: jens@17: + (iChatBuddy*) buddyWithInfo: (NSDictionary*)info jens@17: { jens@17: return [self buddyWithScreenName: [info objectForKey: IMPersonScreenNameKey]]; jens@17: } jens@17: jens@11: + (BOOL) sendMessage: (NSString*)msg toPerson: (ABPerson*)abPerson jens@11: { jens@11: NSDictionary *info = [self iChatInfoForOnlinePerson: abPerson]; jens@11: if( info ) { jens@11: iChatBuddy *buddy = [self buddyWithInfo: info]; jens@11: if( buddy ) { jens@11: [sIChatApp send: msg to: buddy]; jens@11: return YES; jens@11: } jens@11: } jens@11: return NO; jens@11: } jens@11: jens@0: jens@17: + (BOOL) sendMessage: (NSString*)msg toBuddyWithScreenName: (NSString*)screenName jens@17: { jens@17: iChatBuddy *buddy = [self buddyWithScreenName: screenName]; jens@17: if( buddy ) { jens@17: @try{ jens@17: [sIChatApp send: msg to: buddy]; jens@17: return YES; jens@17: } @catch( NSException *x ) { jens@17: Log(@"sendMessage:toBuddyWithScreenName: got exception: %@",x); jens@17: } jens@17: } jens@17: return NO; jens@17: } jens@17: jens@17: jens@0: @end jens@11: jens@11: jens@11: /* jens@11: Copyright (c) 2008, Jens Alfke . All rights reserved. jens@11: jens@11: Redistribution and use in source and binary forms, with or without modification, are permitted jens@11: provided that the following conditions are met: jens@11: jens@11: * Redistributions of source code must retain the above copyright notice, this list of conditions jens@11: and the following disclaimer. jens@11: * Redistributions in binary form must reproduce the above copyright notice, this list of conditions jens@11: and the following disclaimer in the documentation and/or other materials provided with the jens@11: distribution. jens@11: jens@11: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR jens@11: IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND jens@11: FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRI- jens@11: BUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES jens@11: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR jens@11: PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN jens@11: CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF jens@11: THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. jens@11: */