Added a debug log to investigate #8685, as it worksforme. Refs #8685
[adiumx.git] / Source / GBFireImporter.m
blobec2fc38a68a834a9c3d98f9fc0b1226acd5cceec
1 /* 
2  * Adium is the legal property of its developers, whose names are listed in the copyright file included
3  * with this source distribution.
4  * 
5  * This program is free software; you can redistribute it and/or modify it under the terms of the GNU
6  * General Public License as published by the Free Software Foundation; either version 2 of the License,
7  * or (at your option) any later version.
8  * 
9  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
10  * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
11  * Public License for more details.
12  * 
13  * You should have received a copy of the GNU General Public License along with this program; if not,
14  * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
15  */
17 #import "GBFireImporter.h"
18 #import <Adium/AIContactControllerProtocol.h>
19 #import <Adium/AIPreferenceControllerProtocol.h>
20 #import <Adium/AIAccountControllerProtocol.h>
22 #import <AIUtilities/AIFileManagerAdditions.h>
23 #import "AIAccount.h"
24 #import <Adium/AIStatus.h>
25 #import "AIHTMLDecoder.h"
26 #import "AIStatusController.h"
28 #import "AIListGroup.h"
29 #import <Adium/AIListContact.h>
30 #import "AIMetaContact.h"
31 #import "GBFireLogImporter.h"
33 #define FIRECONFIGURATION2              @"FireConfiguration2.plist"
34 #define FIRECONFIGURATION               @"FireConfiguration.plist"
35 #define ACCOUNTS2                               @"Accounts2.plist"
36 #define ACCOUNTS                                @"Accounts.plist"
38 @interface GBFireImportedBuddy : AIObject{
39         AIListContact *contact;
41         AIAccount *account;
42         NSString *groupName;
43         NSString *screenname;
44         NSString *displayName;
45         BOOL blocked;
48 - (id)initScreenname:(NSString *)screen forAccount:(AIAccount *)acct;
49 - (AIAccount *)account;
50 - (void)setGroup:(NSString *)group;
51 - (void)setBlocked:(BOOL)block;
52 - (void)setDisplayName:(NSString *)alias;
53 - (AIListContact *)createContact;
54 - (AIListContact *)contact;
55 @end
57 @implementation GBFireImportedBuddy
58 - (id)initScreenname:(NSString *)screen forAccount:(AIAccount *)acct
60         self = [super init];
61         if(!self)
62                 return nil;
63         
64         screenname = [screen retain];
65         account = [acct retain];
66         groupName = nil;
67         displayName = nil;
68         blocked = NO;
69         
70         return self;
73 - (void)dealloc
75         [screenname release];
76         [account release];
77         [groupName release];
78         [displayName release];
79         [super dealloc];
82 - (AIAccount *)account
84         return account;
87 - (void)setGroup:(NSString *)group
89         [groupName release];
90         groupName = [group retain];
93 - (void)setBlocked:(BOOL)block
95         blocked = block;
98 - (void)setDisplayName:(NSString *)alias
100         [displayName release];
101         displayName = [alias retain];
104 - (AIListContact *)createContact
106         if(contact != nil)
107                 return contact;
108         
109         id <AIContactController> contactController = [adium contactController];
111         contact = [contactController contactWithService:[account service] account:account UID:screenname];
112         if(displayName != nil)
113                 [contact setDisplayName:displayName];
114         if(blocked)
115                 [contact setIsBlocked:YES updateList:YES];
116         if(groupName)
117                 [contact setRemoteGroupName:groupName];
118         
119         return contact;
122 - (AIListContact *)contact
124         return contact;
126 @end
128 @interface GBFireImporter (private)
129 - (BOOL)importFireConfiguration;
130 - (BOOL)import2:(NSString *)fireDir;
131 - (BOOL)import1:(NSString *)fireDir;
132 @end
135  * @class GBFireImporter
136  * @brief Importer for Fire's configuration
138  * This class attempts to import Fire's configuration.  This includes status messages, accounts,
139  * groups, buddies, and meta-contacts.
140  */
142 @implementation GBFireImporter
144 - (id)init
146         self = [super init];
147         if(!self)
148                 return nil;
149         
150         accountUIDtoAccount = [[NSMutableDictionary alloc] init];
151         aliasToContacts = [[NSMutableDictionary alloc] init];
152         buddiesToContact = [[NSMutableDictionary alloc] init];
153         personLists = [[NSMutableArray alloc] init];
155         NSEnumerator *serviceEnum = [[[adium accountController] services] objectEnumerator];
156         AIService *service = nil;
157         serviceDict = [[NSMutableDictionary alloc] init];
158         while ((service = [serviceEnum nextObject]) != nil)
159         {
160                 [serviceDict setObject:service forKey:[service serviceID]];
161         }
162         [serviceDict setObject:[serviceDict objectForKey:@"Bonjour"] forKey:@"Rendezvous"];
163         [serviceDict setObject:[serviceDict objectForKey:@"GTalk"] forKey:@"GoogleTalk"];
164         [serviceDict setObject:[serviceDict objectForKey:@"Yahoo!"] forKey:@"Yahoo"];
165         
166         return self;
169 - (void)dealloc
171         [accountUIDtoAccount release];
172         [aliasToContacts release];
173         [buddiesToContact release];
174         [personLists release];
175         [serviceDict release];
176         [super dealloc];
179 - (void)accountConnected:(NSNotification *)notification
181         id <AIContactController> contactController = [adium contactController];
182         AIAccount *acct = [notification object];
183         
184         NSEnumerator *personEnum = [[NSArray arrayWithArray:personLists] objectEnumerator];
185         NSArray *personContacts = nil;
186         while((personContacts = [personEnum nextObject]) != nil)
187         {
188                 BOOL aBuddyNotCreated = NO;
189                 BOOL aBuddyCreated = NO;
190                 NSEnumerator *contactEnum = [personContacts objectEnumerator];
191                 GBFireImportedBuddy *buddy = nil;
192                 NSMutableArray *thisMetaContact = [[NSMutableArray alloc] init];
193                 while((buddy = [contactEnum nextObject]) != nil)
194                 {
195                         AIListContact *contact = [buddy contact];
196                         if(contact != nil)
197                         {
198                                 [thisMetaContact addObject:contact];
199                                 continue;
200                         }
201                         if([buddy account] == acct)
202                         {
203                                 contact = [buddy createContact];
204                                 [thisMetaContact addObject:contact];
205                                 aBuddyCreated = YES;
206                         }
207                         else
208                         {
209                                 aBuddyNotCreated = YES;
210                         }
211                 }
212                 if(aBuddyCreated && [thisMetaContact count] > 1)
213                         [contactController groupListContacts:thisMetaContact];
214                 if(!aBuddyNotCreated)
215                         [personLists removeObject:personContacts];
216                 [thisMetaContact release];
217         }
218         [[adium notificationCenter] removeObserver:self name:ACCOUNT_CONNECTED object:acct];
219         [self autorelease];
223  * @brief Attempt to import Fire's config.  Returns YES if successful
224  */
226 + (BOOL)importFireConfiguration
228         GBFireImporter *importer = [[GBFireImporter alloc] init];
229         BOOL ret = [importer importFireConfiguration];
230         
231         [importer release];
232         return ret;
235 - (BOOL)importFireConfiguration
237         NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
238         NSString *fireDir = [[[NSFileManager defaultManager] userApplicationSupportFolder] stringByAppendingPathComponent:@"Fire"];
239         BOOL version2Succeeded = NO;
240         BOOL version1Succeeded = NO;
241         BOOL ret = YES;
242         
243         version2Succeeded = [self import2:fireDir];
244         
245         if(!version2Succeeded)
246                 //try version 1
247                 version1Succeeded = [self import1:fireDir];
248         
249         if(!version2Succeeded && !version1Succeeded)
250                 //throw some error
251                 ret = NO;
252         
253         [pool release];
254         [GBFireLogImporter importLogs];
255         return ret;
258 - (AIService *)translateServiceName:(NSString *)serviceName screenName:(NSString *)screenName;
260         if([serviceName isEqualTo:@"Jabber"] && [screenName hasSuffix:@"@gmail.com"])
261                 serviceName = @"GoogleTalk";
262         
263         return [serviceDict objectForKey:serviceName];
266 - (int)checkPort:(int)port forService:(AIService *)service
268         if(port == 0)
269                 return 0;
270         if([[service serviceID] isEqualTo:@"AIM"] && port == 9898)
271                 return 0;
272         if([[service serviceID] isEqualTo:@"GTalk"] && port == 5223)
273                 return 0;
274         return port;
277 - (NSString *)checkHost:(NSString *)host forService:(AIService *)service
279         if(host == nil)
280                 return nil;
281         if([[service serviceID] isEqualTo:@"AIM"] && [host hasPrefix:@"toc"])
282                 return nil;
283         return host;
286 - (void)importAccounts2:(NSArray *)accountsDict
288         NSEnumerator *accountEnum = [accountsDict objectEnumerator];
289         NSDictionary *account = nil;
290         while((account = [accountEnum nextObject]) != nil)
291         {
292                 NSString *serviceName = [account objectForKey:@"ServiceName"];
293                 NSString *accountName = [account objectForKey:@"Username"];
294                 if(![serviceName length] || ![accountName length])
295                         continue;
296                 AIService *service = [self translateServiceName:serviceName screenName:accountName];
297                 if(service == nil)
298                         //Like irc service
299                         continue;
300                 AIAccount *newAcct = [[adium accountController] createAccountWithService:service
301                                                                                                                                                          UID:accountName];
302                 if(newAcct == nil)
303                         continue;
304                 
305                 [newAcct setPreference:[account objectForKey:@"AutoLogin"]
306                                                 forKey:@"Online"
307                                                  group:GROUP_ACCOUNT_STATUS];
308                 
309                 NSDictionary *properties = [account objectForKey:@"Properties"];
310                 NSString *connectHost = [properties objectForKey:@"server"];
311                 if([self checkHost:connectHost forService:service])
312                         [newAcct setPreference:connectHost
313                                                         forKey:KEY_CONNECT_HOST
314                                                          group:GROUP_ACCOUNT_STATUS];   
315                 
316                 int port = [[properties objectForKey:@"port"] intValue];
317                 if([self checkPort:port forService:service])
318                         [newAcct setPreference:[NSNumber numberWithInt:port]
319                                                         forKey:KEY_CONNECT_PORT
320                                                          group:GROUP_ACCOUNT_STATUS];
321                 
322                 [accountUIDtoAccount setObject:newAcct forKey:[account objectForKey:@"UniqueID"]];
323                 [[adium accountController] addAccount:newAcct];
324                 [[adium notificationCenter] addObserver:self
325                                                                            selector:@selector(accountConnected:)
326                                                                                    name:ACCOUNT_CONNECTED
327                                                                                  object:newAcct];
328                 //Retain for each account
329                 [self retain];
330                 [newAcct setShouldBeOnline:YES];
331         }
334 - (void)importAways2:(NSArray *)awayList
336         NSEnumerator *awayEnum = [awayList objectEnumerator];
337         NSDictionary *away = nil;
338         while((away = [awayEnum nextObject]) != nil)
339         {
340                 NSString *title = [away objectForKey:@"Title"];
341                 BOOL isDefault = [[away objectForKey:@"isIdleMessage"] boolValue];
342                 BOOL goIdle = [[away objectForKey:@"idleMessage"] boolValue];
343                 NSString *attrMessage = [away objectForKey:@"message"];
344                 int fireType = [[away objectForKey:@"messageType"] intValue];
345                 AIStatusType adiumType = 0;
346                 
347                 switch(fireType)
348                 {
349                         case 0:
350                         case 1:
351                                 adiumType = AIAvailableStatusType;
352                                 break;
353                         case 4:
354                                 adiumType = AIInvisibleStatusType;
355                         case 3:
356                         case 2:
357                         default:
358                                 adiumType = AIAwayStatusType;
359                 }
360                 
361                 AIStatus *newStatus = [AIStatus statusOfType:adiumType];
362                 [newStatus setTitle:title];
363                 [newStatus setStatusMessage:[AIHTMLDecoder decodeHTML:attrMessage]];
364                 [newStatus setAutoReplyIsStatusMessage:YES];
365                 [newStatus setShouldForceInitialIdleTime:goIdle];
366                 if(isDefault)
367                         [[adium preferenceController] setPreference:[newStatus uniqueStatusID]
368                                                                                                  forKey:KEY_STATUS_AUTO_AWAY_STATUS_STATE_ID
369                                                                                                   group:PREF_GROUP_STATUS_PREFERENCES];
370                 [[adium statusController] addStatusState:newStatus];
371         }       
374 NSComparisonResult groupSort(id left, id right, void *context)
376         NSNumber *leftNum = [left objectForKey:@"position"];
377         NSNumber *rightNum = [right objectForKey:@"position"];
378         NSComparisonResult ret = NSOrderedSame;
379         
380         if(leftNum == nil)
381         {
382                 if(rightNum != nil)
383                         ret = NSOrderedAscending;
384         }
385         else if (rightNum == nil)
386                 ret = NSOrderedDescending;
387         else
388                 ret = [leftNum compare:rightNum];
389         
390         return ret;
393 - (void)importGroups2:(NSDictionary *)groupList
395         id <AIContactController> contactController = [adium contactController];
397         //First itterate through the groups and create an array we can sort
398         NSEnumerator *groupEnum = [groupList keyEnumerator];
399         NSString *groupName = nil;
400         NSMutableArray *groupArray = [NSMutableArray array];
401         while((groupName = [groupEnum nextObject]) != nil)
402         {
403                 NSMutableDictionary *groupDict = [[groupList objectForKey:groupName] mutableCopy];
404                 [groupDict setObject:groupName forKey:@"Name"];
405                 [groupArray addObject:groupDict];
406                 [groupDict release];
407         }
408         [groupArray sortUsingFunction:groupSort context:NULL];
409         groupEnum = [groupArray objectEnumerator];
410         NSDictionary *group = nil;
411         while((group = [groupEnum nextObject]) != nil)
412         {
413                 AIListGroup *newGroup = [contactController groupWithUID:[group objectForKey:@"Name"]];
414                 NSNumber *expanded = [group objectForKey:@"groupexpanded"];
415                 if(expanded != nil)
416                         [newGroup setExpanded:[expanded boolValue]];
417         }       
420 - (void)importBuddies2:(NSArray *)buddyArray
422         NSEnumerator *buddyEnum = [buddyArray objectEnumerator];
423         NSDictionary *buddy = nil;
424         while((buddy = [buddyEnum nextObject]) != nil)
425         {
426                 NSNumber *inList = [buddy objectForKey:@"BuddyInList"];
427                 if(inList == nil || [inList boolValue] == NO)
428                         continue;
429                 
430                 NSNumber *accountNumber = [buddy objectForKey:@"account"];
431                 AIAccount *account = [accountUIDtoAccount objectForKey:accountNumber];
432                 if(account == nil)
433                         continue;
434                 
435                 NSString *buddyName = [buddy objectForKey:@"buddyname"];
436                 if([buddyName length] == 0)
437                         continue;
438                 
439                 GBFireImportedBuddy *newContact = [[GBFireImportedBuddy alloc] initScreenname:buddyName forAccount:account];
440                 
441                 NSMutableDictionary *accountBuddyList = [buddiesToContact objectForKey:accountNumber];
442                 if(accountBuddyList == nil)
443                 {
444                         accountBuddyList = [NSMutableDictionary dictionary];
445                         [buddiesToContact setObject:accountBuddyList forKey:accountNumber];
446                 }
447                 [accountBuddyList setObject:newContact forKey:buddyName];
448                 
449                 NSString *alias = [buddy objectForKey:@"displayname"];
450                 if([alias length] != 0)
451                 {
452                         [newContact setDisplayName:alias];
453                         NSMutableArray *contactArray = [aliasToContacts objectForKey:alias];
454                         if(contactArray == nil)
455                         {
456                                 contactArray = [NSMutableArray array];
457                                 [aliasToContacts setObject:contactArray forKey:alias];
458                         }
459                         [contactArray addObject:newContact];
460                 }
461                 
462                 BOOL blocked = [[buddy objectForKey:@"BuddyBlocked"] boolValue];
463                 if(blocked)
464                         [newContact setBlocked:YES];
465                 
466                 //Adium can only support a single group per buddy (boo!!!) so use the first
467                 NSString *groupName = ([[buddy objectForKey:@"Groups"] count] ? [[buddy objectForKey:@"Groups"] objectAtIndex:0] : nil);
468                 if([groupName length] != 0)
469                         [newContact setGroup:groupName];
470                 [newContact release];
471         }       
474 - (void)importPersons2:(NSArray *)personArray
476         NSEnumerator *personEnum = [personArray objectEnumerator];
477         NSDictionary *person = nil;
478         while((person = [personEnum nextObject]) != nil)
479         {
480                 NSString *personName = [person objectForKey:@"Name"];
481                 if([personName length] == 0)
482                         continue;
483                 
484                 if([personName hasPrefix:@"Screenname:"])
485                         continue;
486                 
487                 NSArray *buddyArray = [person objectForKey:@"Buddies"];
488                 if([buddyArray count] == 0)
489                         //Empty meta-contact; don't bother
490                         continue;
492                 NSEnumerator *buddyEnum = [buddyArray objectEnumerator];
493                 NSDictionary *buddyInfo = nil;
494                 NSMutableArray *buddies = [NSMutableArray array];
495                 while ((buddyInfo = [buddyEnum nextObject]) != nil)
496                 {
497                         NSNumber *buddyAccount = [buddyInfo objectForKey:@"BuddyAccount"];
498                         NSString *buddySN = [buddyInfo objectForKey:@"BuddyName"];
499                         
500                         if(buddyAccount == nil || buddySN == nil)
501                                 continue;
502                         
503                         GBFireImportedBuddy *contact = [[buddiesToContact objectForKey:buddyAccount] objectForKey:buddySN];
504                         if(contact == nil)
505                                 //Contact lookup failed
506                                 continue;
507                         
508                         [buddies addObject:contact];
509                 }
510                 [personLists addObject:buddies];
511         }
514 - (void)createMetaContacts
516         NSEnumerator *metaContantEnum = [aliasToContacts objectEnumerator];
517         NSArray *contacts = nil;
518         while ((contacts = [metaContantEnum nextObject]) != nil)
519                 [personLists addObject:contacts];
522 - (BOOL)import2:(NSString *)fireDir
524         NSString *configPath = [fireDir stringByAppendingPathComponent:FIRECONFIGURATION2];
525         NSString *accountPath = [fireDir stringByAppendingPathComponent:ACCOUNTS2];
526         NSDictionary *configDict = [NSDictionary dictionaryWithContentsOfFile:configPath];
527         NSDictionary *accountDict = [NSDictionary dictionaryWithContentsOfFile:accountPath];
528         
529         if(configDict == nil || accountDict == nil)
530                 //no dictionary or no account, can't import
531                 return NO;
532         
533         //Start with accounts
534         [self importAccounts2:[accountDict objectForKey:@"Accounts"]];
535         
536         //Away Messages
537         [self importAways2:[configDict objectForKey:@"awayMessages"]];
539         //Now for the groups
540         [self importGroups2:[configDict objectForKey:@"groups"]];
541         
542         //Buddies
543         [self importBuddies2:[configDict objectForKey:@"buddies"]];
545         //Persons
546         NSArray *personArray = [configDict objectForKey:@"persons"];
547         if([personArray count] > 0)
548                 [self importPersons2:personArray];
549         else
550                 [self createMetaContacts];
551         
552         return YES;
555 - (void)importAccounts1:(NSDictionary *)accountsDict
557         NSEnumerator *serviceNameEnum = [accountsDict keyEnumerator];
558         NSString *serviceName = nil;
559         while ((serviceName = [serviceNameEnum nextObject]) != nil)
560         {
561                 if(![serviceName length])
562                         continue;
563                 
564                 NSEnumerator *accountEnum = [[accountsDict objectForKey:serviceName] objectEnumerator];
565                 NSDictionary *account = nil;
566                 
567                 while((account = [accountEnum nextObject]) != nil)
568                 {
569                         NSString *accountName = [account objectForKey:@"userName"];
570                         if(![accountName length])
571                                 continue;
572                         AIService *service = [self translateServiceName:serviceName screenName:accountName];
573                         AIAccount *newAcct = [[adium accountController] createAccountWithService:service
574                                                                                                                                                                  UID:accountName];
575                         if(newAcct == nil)
576                                 continue;
577                         
578                         [newAcct setPreference:[account objectForKey:@"autoLogin"]
579                                                         forKey:@"Online"
580                                                          group:GROUP_ACCOUNT_STATUS];
581                         
582                         NSString *connectHost = [account objectForKey:@"server"];
583                         if([self checkHost:connectHost forService:service])
584                                 [newAcct setPreference:connectHost
585                                                                 forKey:KEY_CONNECT_HOST
586                                                                  group:GROUP_ACCOUNT_STATUS];   
587                         
588                         int port = [[account objectForKey:@"port"] intValue];
589                         if([self checkPort:port forService:service])
590                                 [newAcct setPreference:[NSNumber numberWithInt:port]
591                                                                 forKey:KEY_CONNECT_PORT
592                                                                  group:GROUP_ACCOUNT_STATUS];
593                         
594                         [accountUIDtoAccount setObject:newAcct forKey:[NSString stringWithFormat:@"%@-%@@%@", serviceName, accountName, connectHost]];
595                         [[adium accountController] addAccount:newAcct];
596                         [[adium notificationCenter] addObserver:self
597                                                                                    selector:@selector(accountConnected:)
598                                                                                            name:ACCOUNT_CONNECTED
599                                                                                          object:newAcct];
600                         //Retain for each account
601                         [self retain];
602                         [newAcct setShouldBeOnline:YES];
603                 }
604         }
607 - (void)importAways1:(NSArray *)awayList
609         NSEnumerator *awayEnum = [awayList objectEnumerator];
610         NSDictionary *away = nil;
611         while((away = [awayEnum nextObject]) != nil)
612         {
613                 NSString *title = [away objectForKey:@"Title"];
614                 BOOL isDefault = [[away objectForKey:@"isIdleMessage"] boolValue];
615                 BOOL goIdle = [[away objectForKey:@"idleMessage"] boolValue];
616                 NSString *message = [away objectForKey:@"message"];
617                 int fireType = [[away objectForKey:@"messageType"] intValue];
618                 AIStatusType adiumType = 0;
619                 
620                 switch(fireType)
621                 {
622                         case 0:
623                         case 1:
624                                 adiumType = AIAvailableStatusType;
625                                 break;
626                         case 4:
627                                 adiumType = AIInvisibleStatusType;
628                         case 3:
629                         case 2:
630                         default:
631                                 adiumType = AIAwayStatusType;
632                 }
633                 
634                 AIStatus *newStatus = [AIStatus statusOfType:adiumType];
635                 [newStatus setTitle:title];
636                 [newStatus setStatusMessage:[[[NSAttributedString alloc] initWithString:message] autorelease]];
637                 [newStatus setAutoReplyIsStatusMessage:YES];
638                 [newStatus setShouldForceInitialIdleTime:goIdle];
639                 if(isDefault)
640                         [[adium preferenceController] setPreference:[newStatus uniqueStatusID]
641                                                                                                  forKey:KEY_STATUS_AUTO_AWAY_STATUS_STATE_ID
642                                                                                                   group:PREF_GROUP_STATUS_PREFERENCES];
643                 [[adium statusController] addStatusState:newStatus];
644         }       
647 - (void)importBuddies1:(NSArray *)buddyArray
648                            toGroup:(NSString *)groupName
650         NSEnumerator *buddyEnum = [buddyArray objectEnumerator];
651         NSDictionary *buddy = nil;
652         while((buddy = [buddyEnum nextObject]) != nil)
653         {
654                 NSString *buddyName = [buddy objectForKey:@"buddyname"];
655                 if([buddyName length] == 0)
656                         continue;
657                 
658                 NSDictionary *permissionsDict = [buddy objectForKey:@"BuddyPermissions"];
659                 NSMutableArray *accounts = [NSMutableArray array];
660                 if(permissionsDict != nil)
661                 {
662                         NSEnumerator *permissionsEnum = [permissionsDict keyEnumerator];
663                         NSString *accountKey = nil;
664                         while ((accountKey = [permissionsEnum nextObject]) != nil)
665                         {
666                                 AIAccount *acct = [accountUIDtoAccount objectForKey:accountKey];
667                                 if(acct != nil && [[[permissionsDict objectForKey:accountKey] objectForKey:@"BuddyinList"] boolValue])
668                                         [accounts addObject:acct];
669                         }
670                 }
671                 else
672                 {
673                         NSEnumerator *acctEnum = [accountUIDtoAccount objectEnumerator];
674                         AIAccount *acct = nil;
675                         while ((acct = [acctEnum nextObject]) != nil)
676                         {
677                                 if([[acct serviceClass] isEqualToString:[buddy objectForKey:@"service"]])
678                                         [accounts addObject:acct];
679                         }
680                 }
681                 
682                 NSEnumerator *accountEnum = [accounts objectEnumerator];
683                 AIAccount *account = nil;
684                 while ((account = [accountEnum nextObject]) != nil)
685                 {
686                         GBFireImportedBuddy *newContact = [[GBFireImportedBuddy alloc] initScreenname:buddyName forAccount:account];
687                         if(newContact == nil)
688                                 continue;
689                         
690                         NSString *alias = [buddy objectForKey:@"displayname"];
691                         if([alias length] != 0)
692                         {
693                                 [newContact setDisplayName:alias];
694                                 NSMutableArray *contactArray = [aliasToContacts objectForKey:alias];
695                                 if(contactArray == nil)
696                                 {
697                                         contactArray = [NSMutableArray array];
698                                         [aliasToContacts setObject:contactArray forKey:alias];
699                                 }
700                                 [contactArray addObject:newContact];
701                         }
702                         
703                         if([groupName length] != 0)
704                                 [newContact setGroup:groupName];
705                         [newContact release];
706                 }
707         }       
710 - (void)importGroups1:(NSDictionary *)groupList
712         id <AIContactController> contactController = [adium contactController];
713         
714         //First itterate through the groups and create an array we can sort
715         NSEnumerator *groupEnum = [groupList keyEnumerator];
716         NSString *groupName = nil;
717         NSMutableArray *groupArray = [NSMutableArray array];
718         while((groupName = [groupEnum nextObject]) != nil)
719         {
720                 NSMutableDictionary *groupDict = [[groupList objectForKey:groupName] mutableCopy];
721                 [groupDict setObject:groupName forKey:@"Name"];
722                 [groupArray addObject:groupDict];
723                 [groupDict release];
724         }
725         [groupArray sortUsingFunction:groupSort context:NULL];
726         groupEnum = [groupArray objectEnumerator];
727         NSDictionary *group = nil;
728         while((group = [groupEnum nextObject]) != nil)
729         {
730                 NSString *groupName = [group objectForKey:@"Name"];
731                 AIListGroup *newGroup = [contactController groupWithUID:groupName];
732                 NSNumber *expanded = [group objectForKey:@"groupexpanded"];
733                 if(expanded != nil)
734                         [newGroup setExpanded:[expanded boolValue]];
735                 [self importBuddies1:[group objectForKey:@"buddies"]
736                                          toGroup:groupName];
737         }
740 - (BOOL)import1:(NSString *)fireDir
742         NSString *configPath = [fireDir stringByAppendingPathComponent:FIRECONFIGURATION];
743         NSString *accountPath = [fireDir stringByAppendingPathComponent:ACCOUNTS];
744         NSDictionary *configDict = [NSDictionary dictionaryWithContentsOfFile:configPath];
745         NSDictionary *accountDict = [NSDictionary dictionaryWithContentsOfFile:accountPath];
746         
747         if(configDict == nil || accountDict == nil)
748                 //no dictionary or no account, can't import
749                 return NO;
750         
751         //Start with accounts
752         [self importAccounts1:accountDict];
753         
754         //Away Messages
755         [self importAways1:[configDict objectForKey:@"awayMessages"]];
756         
757         //Now for the groups
758         [self importGroups1:[configDict objectForKey:@"groups"]];
759         
760         //Persons
761         [self createMetaContacts];
762         
763         return YES;
766 @end