root/trunk/Importer/GetMetadataForFile.m

Revision 3418, 7.0 kB (checked in by timothy, 2 years ago)

Turing on more warnings and fixing more of them.

Line 
1 #import <CoreServices/CoreServices.h>
2 #import <Foundation/Foundation.h>
3 #import <libxml/tree.h>
4 #import <libxml/xmlerror.h>
5
6 /* Sample transcript:
7 <log began="2005-07-11 12:19:09 -0400" source="irc://irc.freenode.net/%23barcamp">
8  <event id="H5OI9GYEXB" name="memberJoined" occurred="2005-08-20 22:13:28 -0400">
9   <message><span class="member">vdwal</span> joined the chat room.</message>
10   <who hostmask="n=vanderwa@dsl092-170-254.wdc2.dsl.speakeasy.net">vdwal</who>
11  </event>
12  <envelope>
13   <sender hostmask="i=urgy@c-67-188-71-51.hsd1.ca.comcast.net">urgen</sender>
14   <message id="H7DJHOYEXB" received="2005-08-20 22:13:36 -0400">hi</message>
15  </envelope>
16  <envelope>
17   <sender hostmask="n=vanderwa@dsl092-170-254.wdc2.dsl.speakeasy.net">vdwal</sender>
18   <message id="XVQ44ZYEXB" received="2005-08-20 22:13:47 -0400">where did everybody go?</message>
19   <message id="GD3YCAZEXB" received="2005-08-20 22:13:58 -0400">hi</message>
20   <message id="D0TAANZEXB" received="2005-08-20 22:14:11 -0400">i lost my nickname and my legs</message>
21   <message id="H5CJHSZEXB" received="2005-08-20 22:14:16 -0400">stuck again</message>
22  </envelope>
23 </log>
24 */
25
26 @interface JVChatTranscriptMetadataExtractor : NSObject {
27         BOOL inEnvelope;
28         BOOL inMessage;
29         NSString *lastElement;
30         NSDate *dateStarted;
31         NSString *lastEventDate;
32         NSString *source;
33         NSMutableString *content;
34         NSMutableSet *participants;
35         NSCharacterSet *lineBreaks;
36 }
37 - (id) initWithCapacity:(unsigned) capacity;
38 - (NSDictionary *) metadataAttributes;
39 @end
40
41 @implementation JVChatTranscriptMetadataExtractor
42 - (id) initWithCapacity:(unsigned) capacity {
43         if( ( self = [super init] ) ) {
44                 content = [[NSMutableString alloc] initWithCapacity:capacity];
45                 participants = [[NSMutableSet alloc] initWithCapacity:400];
46                 lineBreaks = [[NSCharacterSet characterSetWithCharactersInString:@"\n\r"] retain];
47         }
48
49         return self;
50 }
51
52 - (void) dealloc {
53         [lastElement release];
54         [content release];
55         [participants release];
56         [dateStarted release];
57         [lastEventDate release];
58         [source release];
59         [lineBreaks release];
60
61         lastElement = nil;
62         content = nil;
63         participants = nil;
64         dateStarted = nil;
65         lastEventDate = nil;
66         source = nil;
67         lineBreaks = nil;
68
69         [super dealloc];
70 }
71
72 - (NSDictionary *) metadataAttributes {
73         NSMutableDictionary *ret = [NSMutableDictionary dictionary];
74         [ret setObject:content forKey:(NSString *) kMDItemTextContent];
75
76         if( dateStarted ) [ret setObject:dateStarted forKey:(NSString *) kMDItemContentCreationDate];
77         if( [lastEventDate length] ) {
78                 NSDate *lastDate = [NSDate dateWithString:lastEventDate];
79                 if( lastDate ) {
80                         [ret setObject:lastDate forKey:(NSString *) kMDItemContentModificationDate];
81                         [ret setObject:lastDate forKey:(NSString *) kMDItemLastUsedDate];
82
83                         if( dateStarted ) {
84                                 // Set Duration
85                                 NSTimeInterval logDuration = [lastDate timeIntervalSinceDate:dateStarted];
86                                 [ret setObject:[NSNumber numberWithInt:logDuration] forKey:(NSString *) kMDItemDurationSeconds];
87
88                                 // Set Coverage
89                                 NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
90                                 [formatter setFormatterBehavior:NSDateFormatterBehavior10_4];
91                                 [formatter setDateStyle:NSDateFormatterShortStyle];
92                                 [formatter setTimeStyle:NSDateFormatterShortStyle];
93
94                                 NSString *coverageWording = [NSString stringWithFormat:@"%@ - %@", [formatter stringFromDate:dateStarted], [formatter stringFromDate:lastDate]];
95                                 [ret setObject:coverageWording forKey:(NSString *) kMDItemCoverage];
96                                 [formatter release];
97                         }                       
98                 }
99         }
100
101         if( [participants count] ) [ret setObject:[participants allObjects] forKey:(NSString *) kMDItemContributors];
102         if( [source length] ) [ret setObject:source forKey:(NSString *) kMDItemWhereFroms];
103
104         [ret setObject:[NSArray arrayWithObject:@"transcript"] forKey:(NSString *) kMDItemKind];
105         [ret setObject:[NSArray arrayWithObject:@"Colloquy"] forKey:(NSString *) kMDItemCreator];
106
107         return ret;
108 }
109
110 - (void) parser:(NSXMLParser *) parser didStartElement:(NSString *) elementName namespaceURI:(NSString *) namespaceURI qualifiedName:(NSString *) qName attributes:(NSDictionary *) attributes {
111         [lastElement release];
112         lastElement = [elementName retain];
113
114         if( [elementName isEqualToString:@"envelope"] ) inEnvelope = YES;
115         else if( inEnvelope && [elementName isEqualToString:@"message"] ) {
116                 inMessage = YES;
117                 NSString *date = [attributes objectForKey:@"received"];
118                 if( date ) {
119                         [lastEventDate release];
120                         lastEventDate = [date retain];
121                         if( ! dateStarted ) dateStarted = [[NSDate alloc] initWithString:date];
122                 }
123         } else if( ! inEnvelope && [elementName isEqualToString:@"event"] ) {
124                 NSString *date = [attributes objectForKey:@"occurred"];
125                 if( date ) {
126                         [lastEventDate release];
127                         lastEventDate = [date retain];
128                         if( ! dateStarted ) dateStarted = [[NSDate alloc] initWithString:date];
129                 }
130         } else if( ! inEnvelope && [elementName isEqualToString:@"log"] ) {
131                 NSString *date = [attributes objectForKey:@"began"];
132                 if( date && ! dateStarted ) dateStarted = [[NSDate alloc] initWithString:date];
133                 if( ! source ) source = [[attributes objectForKey:@"source"] retain];
134         }
135 }
136
137 - (void) parser:(NSXMLParser *) parser didEndElement:(NSString *) elementName namespaceURI:(NSString *) namespaceURI qualifiedName:(NSString *) qName {
138         if( inEnvelope && [elementName isEqualToString:@"envelope"] ) inEnvelope = NO;
139         else if( inEnvelope && inMessage && [elementName isEqualToString:@"message"] ) {
140                 inMessage = NO;
141                 [content appendString:@"\n"]; // append a newline after messages
142         }
143
144         [lastElement release];
145         lastElement = nil;
146 }
147
148 - (void) parser:(NSXMLParser *) parser foundCharacters:(NSString *) string {
149         if( inEnvelope && inMessage ) {
150                 NSString *newString = [string stringByTrimmingCharactersInSet:lineBreaks];
151                 if( [newString length] ) [content appendString:newString];
152         } else if( inEnvelope && [lastElement isEqualToString:@"sender"] ) {
153                 if( [string length] ) [participants addObject:string];
154         }
155 }
156 @end
157
158 Boolean GetMetadataForFile( void *thisInterface, CFMutableDictionaryRef attributes, CFStringRef contentTypeUTI, CFStringRef pathToFile );
159
160 Boolean GetMetadataForFile( void *thisInterface, CFMutableDictionaryRef attributes, CFStringRef contentTypeUTI, CFStringRef pathToFile ) {
161         NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
162
163         NSFileManager *fm = [NSFileManager defaultManager];
164
165         if( ! [fm fileExistsAtPath:(NSString *) pathToFile] ) goto end;
166         if( ! [fm isReadableFileAtPath:(NSString *) pathToFile] ) goto end;
167
168         NSURL *file = [NSURL fileURLWithPath:(NSString *) pathToFile];
169         NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:file];
170
171         unsigned long long fileSize = [[fm fileAttributesAtPath:(NSString *) pathToFile traverseLink:YES] fileSize];
172         unsigned capacity = ( fileSize ? fileSize / 3 : 5000 ); // the message content takes up about a third of the XML file's size
173
174         JVChatTranscriptMetadataExtractor *extractor = [[JVChatTranscriptMetadataExtractor alloc] initWithCapacity:capacity];
175
176         [parser setDelegate:extractor];
177         [parser parse];
178
179         [(NSMutableDictionary *) attributes addEntriesFromDictionary:[extractor metadataAttributes]];
180
181         [parser release];
182         [extractor release];
183
184         xmlSetStructuredErrorFunc( NULL, NULL );
185
186 end:
187         [pool release];
188     return TRUE;
189 }
Note: See TracBrowser for help on using the browser.