Use initialize, not load, wherever possible.
[adiumx.git] / Source / BGICLogImportController.m
blobf992424f7528868d6dd305617c70b598decb8a05
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 "BGICLogImportController.h"
18 #import "AIXMLAppender.h"
19 #import "AILoggerPlugin.h"
20 #import "AICoreComponentLoader.h"
21 #import <Adium/AIHTMLDecoder.h>
22 #import <Adium/AILoginControllerProtocol.h>
23 #import <AIUtilities/NSCalendarDate+ISO8601Unparsing.h>
25 // InstantMessage and other iChat transcript classes are from Spiny Software's Logorrhea, used with permission.
26 #import "InstantMessage.h"
27 #import "Presentity.h"
29 //#define LOG_TO_TEST
30 #define TEST_LOGGING_LOCATION [@"~/Desktop/testLog" stringByExpandingTildeInPath]
32 @implementation BGICLogImportController
34 /* an iChat log importer needs to be set up with a destination pair, specified as @"service.account" to match current representation(s) in PATH_LOGS */
35 -(id)initWithDestination:(NSString *)newSAPair
37         self = [super init];
38         if(self)
39                 importServiceAccountPair = [newSAPair copy];
40         return self;
43 -(void)dealloc
45         [importServiceAccountPair release];
46         [super dealloc];
49 -(BOOL)createNewLogForPath:(NSString *)fullPath 
51         AIHTMLDecoder *xhtmlDecoder = [[AIHTMLDecoder alloc] initWithHeaders:NO
52                                                                                                                                 fontTags:YES
53                                                                                                                    closeFontTags:YES
54                                                                                                                            colorTags:YES
55                                                                                                                            styleTags:YES
56                                                                                                                   encodeNonASCII:YES
57                                                                                                                         encodeSpaces:NO
58                                                                                                            attachmentsAsText:YES
59                                                                                            onlyIncludeOutgoingImages:NO
60                                                                                                                   simpleTagsOnly:NO
61                                                                                                                   bodyBackground:NO];
62         [xhtmlDecoder setGeneratesStrictXHTML:YES];
63         [xhtmlDecoder setUsesAttachmentTextEquivalents:YES];
64         
65         // read the raw file into an array for working against, two different formats have been employed by iChat, based on available classes
66         NSArray *rawChat =  ([[fullPath pathExtension] isEqual:@"ichat"] ?
67                                                  [NSKeyedUnarchiver unarchiveObjectWithFile:fullPath] :
68                                                  [NSUnarchiver unarchiveObjectWithFile:fullPath]);
69         
70         NSString *preceedingPath = nil;
71         
72 #ifndef LOG_TO_TEST
73         preceedingPath = [[[[adium loginController] userDirectory] stringByAppendingPathComponent:PATH_LOGS] stringByExpandingTildeInPath];
74 #else
75         preceedingPath = TEST_LOGGING_LOCATION;
76 #endif
77         
78         /*
79         [rawChat objectAtIndex:0],
80                 TEST_ACCOUNT, // this has to be matched somehow, I can't see a way offhand through as iChat stores the originating party 
81         */
82         NSString *parentPath = [preceedingPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@/%@", 
83                 importServiceAccountPair, // see commented code above for a brittle methodology
84                 [[[rawChat objectAtIndex:3] objectAtIndex:0] senderID] // this is improperly brittle and imprecise
85                 ]];
86         
87         // create a new xml parser for logs
88         NSString *documentPath = [parentPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@ (%@).chatlog", [[[rawChat objectAtIndex:3] objectAtIndex:0] senderID], [[[[rawChat objectAtIndex:2] objectAtIndex:0] date] dateWithCalendarFormat:@"%Y-%m-%dT%H.%M.%S%z" timeZone:nil]]];
89         AIXMLAppender *appender = [AIXMLAppender documentWithPath:documentPath];
90         [appender setFullSyncAfterEachAppend:NO];
92         // set up the initial layout of the xml log
93         [appender initializeDocumentWithRootElementName:@"chat"
94                                                                           attributeKeys:[NSArray arrayWithObjects:@"xmlns", @"account", @"service", nil]
95                                                                         attributeValues:[NSArray arrayWithObjects:
96                                                                                 XML_LOGGING_NAMESPACE,
97                                                                                 [[[rawChat objectAtIndex:3] objectAtIndex:0] senderID],
98                                                                                 [rawChat objectAtIndex:0],
99                                                                                 //                                                                              [[chat account] UID], // pulled from iChat transcript
100                                                                                 //                                                                              [[chat account] serviceID], // pulled from iChat transcript
101                                                                                 nil]];  
102         
103         // sequentially add the messages from the iChat transcript sans attributed text features
104         for(int i = 0; i < [[rawChat objectAtIndex:2] count]; i++)
105         {
106                 NSMutableArray *attributeKeys = [NSMutableArray arrayWithObjects:@"sender", @"time", nil];
107                 NSMutableArray *attributeValues = [NSMutableArray arrayWithObjects:
108                         ([[(InstantMessage *)[[rawChat objectAtIndex:2] objectAtIndex:i] sender] senderID] != nil ? [[(InstantMessage *)[[rawChat objectAtIndex:2] objectAtIndex:i] sender] senderID] : @""), 
109                         [[[(InstantMessage *)[[rawChat objectAtIndex:2] objectAtIndex:i] date] dateWithCalendarFormat:nil timeZone:nil] ISO8601DateString], 
110                         nil];
111                 
112                 NSMutableString *chatContents = [[[xhtmlDecoder encodeHTML:[[[rawChat objectAtIndex:2] objectAtIndex:i] text] imagesPath:nil] mutableCopy] autorelease];
113                 
114                 [appender addElementWithName:(![[[(InstantMessage *)[[rawChat objectAtIndex:2] objectAtIndex:i] sender] senderID] isEqual:@""] ? @"message" : @"event")
115                                           escapedContent:chatContents
116                                            attributeKeys:([attributeValues count] == 2 ? attributeKeys : nil)
117                                          attributeValues:([attributeValues count] == 2 ? attributeValues : nil)];
118         }
119         
120         //Force this log to disk immediately
121         [appender performFullSync];
122         
123         if ([[NSFileManager defaultManager] fileExistsAtPath:documentPath]) {
124                 [(AILoggerPlugin *)[[adium componentLoader] pluginWithClassName:@"AILoggerPlugin"] markLogDirtyAtPath:documentPath];
125                 return YES;
127         } else {
128                 return NO;
129         }
132 @end