2 * Adium is the legal property of its developers, whose names are listed in the copyright file included
3 * with this source distribution.
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.
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.
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.
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"
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
39 importServiceAccountPair = [newSAPair copy];
45 [importServiceAccountPair release];
49 -(BOOL)createNewLogForPath:(NSString *)fullPath
51 AIHTMLDecoder *xhtmlDecoder = [[AIHTMLDecoder alloc] initWithHeaders:NO
59 onlyIncludeOutgoingImages:NO
62 allowJavascriptURLs:YES];
63 [xhtmlDecoder setGeneratesStrictXHTML:YES];
64 [xhtmlDecoder setUsesAttachmentTextEquivalents:YES];
66 // read the raw file into an array for working against, two different formats have been employed by iChat, based on available classes
67 NSArray *rawChat = ([[fullPath pathExtension] isEqual:@"ichat"] ?
68 [NSKeyedUnarchiver unarchiveObjectWithFile:fullPath] :
69 [NSUnarchiver unarchiveObjectWithFile:fullPath]);
71 NSString *preceedingPath = nil;
74 preceedingPath = [[[[adium loginController] userDirectory] stringByAppendingPathComponent:PATH_LOGS] stringByExpandingTildeInPath];
76 preceedingPath = TEST_LOGGING_LOCATION;
80 [rawChat objectAtIndex:0],
81 TEST_ACCOUNT, // this has to be matched somehow, I can't see a way offhand through as iChat stores the originating party
83 NSString *parentPath = [preceedingPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@/%@",
84 importServiceAccountPair, // see commented code above for a brittle methodology
85 [[[rawChat objectAtIndex:3] objectAtIndex:0] senderID] // this is improperly brittle and imprecise
88 // create a new xml parser for logs
89 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]]];
90 AIXMLAppender *appender = [AIXMLAppender documentWithPath:documentPath];
91 [appender setFullSyncAfterEachAppend:NO];
93 // set up the initial layout of the xml log
94 [appender initializeDocumentWithRootElementName:@"chat"
95 attributeKeys:[NSArray arrayWithObjects:@"xmlns", @"account", @"service", nil]
96 attributeValues:[NSArray arrayWithObjects:
97 XML_LOGGING_NAMESPACE,
98 [[[rawChat objectAtIndex:3] objectAtIndex:0] senderID],
99 [rawChat objectAtIndex:0],
100 // [[chat account] UID], // pulled from iChat transcript
101 // [[chat account] serviceID], // pulled from iChat transcript
104 // sequentially add the messages from the iChat transcript sans attributed text features
105 for(int i = 0; i < [[rawChat objectAtIndex:2] count]; i++)
107 NSMutableArray *attributeKeys = [NSMutableArray arrayWithObjects:@"sender", @"time", nil];
108 NSMutableArray *attributeValues = [NSMutableArray arrayWithObjects:
109 ([[(InstantMessage *)[[rawChat objectAtIndex:2] objectAtIndex:i] sender] senderID] != nil ? [[(InstantMessage *)[[rawChat objectAtIndex:2] objectAtIndex:i] sender] senderID] : @""),
110 [[[(InstantMessage *)[[rawChat objectAtIndex:2] objectAtIndex:i] date] dateWithCalendarFormat:nil timeZone:nil] ISO8601DateString],
113 NSMutableString *chatContents = [[[xhtmlDecoder encodeHTML:[[[rawChat objectAtIndex:2] objectAtIndex:i] text] imagesPath:nil] mutableCopy] autorelease];
115 [appender addElementWithName:(![[[(InstantMessage *)[[rawChat objectAtIndex:2] objectAtIndex:i] sender] senderID] isEqual:@""] ? @"message" : @"event")
116 escapedContent:chatContents
117 attributeKeys:([attributeValues count] == 2 ? attributeKeys : nil)
118 attributeValues:([attributeValues count] == 2 ? attributeValues : nil)];
121 //Force this log to disk immediately
122 [appender performFullSync];
124 if ([[NSFileManager defaultManager] fileExistsAtPath:documentPath]) {
125 [(AILoggerPlugin *)[[adium componentLoader] pluginWithClassName:@"AILoggerPlugin"] markLogDirtyAtPath:documentPath];