root/Footagehead/trunk/FHFeedHandler.m

Revision 4726, 7.5 kB (checked in by morris, 1 year ago)

Random stuff

  • Property svn:keywords set to Id Rev
Line 
1 /* $Id$ */
2
3 /*
4  *  Copyright (c) 2003-2007 Axel Andersson
5  *  All rights reserved.
6  *
7  *  Redistribution and use in source and binary forms, with or without
8  *  modification, are permitted provided that the following conditions
9  *  are met:
10  *  1. Redistributions of source code must retain the above copyright
11  *     notice, this list of conditions and the following disclaimer.
12  *  2. Redistributions in binary form must reproduce the above copyright
13  *     notice, this list of conditions and the following disclaimer in the
14  *     documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
20  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
25  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #import "FHFeedHandler.h"
30 #import "FHFlickrHandler.h"
31 #import "FHFile.h"
32 #import "FHHTMLParser.h"
33
34 enum FHFeedParseMode {
35         FHFeedParseHeader,
36         FHFeedParseItems,
37 };
38 typedef enum FHFeedParseMode            FHFeedParseMode;
39
40
41 @interface FHFeedHandler(Private)
42
43 - (void)_parse;
44 - (void)_parseImageHeaderInTree:(CFXMLTreeRef)imageTree;
45
46 @end
47
48
49 @implementation FHFeedHandler(Private)
50
51 - (void)_parse {
52         NSMutableDictionary             *items;
53         NSString                                *dividerKey, *name, *itemName;
54         CFXMLTreeRef                    contentTree, tree, itemTree;
55         CFXMLNodeRef                    node, itemNode;
56         FHFeedParseMode                 mode;
57         NSUInteger                              i, count, j, itemCount;
58        
59         contentTree = [self contentTree];
60         dividerKey = [self itemDividerKey];
61         count = CFTreeGetChildCount(contentTree);
62         mode = FHFeedParseHeader;
63
64         _header = [[NSMutableDictionary alloc] initWithCapacity:10];
65         _items = [[NSMutableArray alloc] initWithCapacity:count];
66
67         for(i = 0; i < count; i++) {
68                 tree = CFTreeGetChildAtIndex(contentTree, i);
69                 node = CFXMLTreeGetNode(tree);
70                 name = (NSString *) CFXMLNodeGetString(node);
71                
72                 if([name isEqualToString:dividerKey])
73                         mode = FHFeedParseItems;
74                
75                 if(mode == FHFeedParseHeader) {
76                         if([name isEqualTo:@"image"])
77                                 [self _parseImageHeaderInTree:tree];
78                        
79                         [_header setObject:[self valueOfTree:tree] forKey:name];
80                 }
81                 else if(mode == FHFeedParseItems) {
82                         itemCount = CFTreeGetChildCount(tree);
83                         items = [[NSMutableDictionary alloc] initWithCapacity:itemCount];
84                        
85                         for(j = 0; j < itemCount; j++) {
86                                 itemTree = CFTreeGetChildAtIndex(tree, j);
87                                 itemNode = CFXMLTreeGetNode(itemTree);
88                                 itemName = (NSString *) CFXMLNodeGetString(itemNode);
89                                
90                                 [items setObject:[self valueOfTree:itemTree] forKey:itemName];
91                         }
92                        
93                         [_items addObject:items];
94                         [items release];
95                 }
96         }
97 }
98
99
100
101 - (void)_parseImageHeaderInTree:(CFXMLTreeRef)imageTree {
102         NSString                *name;
103         CFXMLTreeRef    tree;
104         CFXMLNodeRef    node;
105         NSUInteger              i, count;
106        
107         count = CFTreeGetChildCount(imageTree);
108                
109         for(i = 0; i < count; i++) {
110                 tree = CFTreeGetChildAtIndex(imageTree, i);
111                 node = CFXMLTreeGetNode(tree);
112                 name = (NSString *) CFXMLNodeGetString(node);
113                
114                 [_header setObject:[self valueOfTree:tree] forKey:[@"image" stringByAppendingString:name]];
115         }
116 }
117
118 @end
119
120
121 @implementation FHFeedHandler
122
123 + (Class)handlerForURL:(WIURL *)url {
124         NSString        *host;
125        
126         host = [url host];
127        
128         if([host hasSuffix:@"flickr.com"])
129                 return [FHFlickrHandler class];
130        
131         return self;
132 }
133
134
135
136 #pragma mark -
137
138 - (id)initHandlerWithURL:(WIURL *)url feed:(CFXMLTreeRef)feed {
139         CFXMLNodeRef    node;
140         NSString                *name;
141         FHFeedFormat    format;
142        
143         format = FHFeedUnknown;
144        
145         if(CFTreeGetChildCount(feed) >= 2) {
146                 node = CFXMLTreeGetNode(CFTreeGetChildAtIndex(feed, 1));
147                 name = (NSString *) CFXMLNodeGetString(node);
148        
149                 if([name isEqualToString:@"rss"])
150                         format = FHFeedRSS;
151                 else if([name isEqualToString:@"feed"])
152                         format = FHFeedAtom;
153         }
154
155         return [self initHandlerWithURL:url feed:feed format:format];
156 }
157
158
159
160 - (id)initHandlerWithURL:(WIURL *)url feed:(CFXMLTreeRef)feed format:(FHFeedFormat)format {
161         CFXMLTreeRef    rssTree;
162        
163         self = [super initHandlerWithURL:url];
164        
165         _feed = (CFXMLTreeRef) CFRetain(feed);
166         _format = format;
167
168         if(_format == FHFeedRSS) {
169                 rssTree = [self treeWithName:@"rss" inTree:_feed];
170                
171                 if(!rssTree)
172                         rssTree = [self treeWithName:@"rdf:RDF" inTree:_feed];
173                
174                 if(!rssTree) {
175                         [self release];
176                        
177                         return NULL;
178                 }
179                
180                 _contentTree = [self treeWithName:@"channel" inTree:rssTree];
181                
182                 if(!_contentTree)
183                         _contentTree = [self treeWithName:@"rss:channel" inTree:rssTree];
184                
185                 if(!_contentTree) {
186                         [self release];
187                        
188                         return NULL;
189                 }
190         }
191        
192         [self _parse];
193                
194         return self;
195 }
196
197
198
199 - (void)dealloc {
200         CFRelease(_feed);
201        
202         [super dealloc];
203 }
204
205
206
207 #pragma mark -
208
209 - (NSString *)itemDividerKey {
210         switch(_format) {
211                 case FHFeedUnknown:
212                         return NULL;
213                         break;
214
215                 case FHFeedRSS:
216                         return @"item";
217                         break;
218
219                 case FHFeedAtom:
220                         return @"entry";
221                         break;
222         }
223        
224         return NULL;
225 }
226
227
228
229 - (NSString *)itemContentKey {
230         switch(_format) {
231                 case FHFeedUnknown:
232                         return NULL;
233                         break;
234
235                 case FHFeedRSS:
236                         return @"description";
237                         break;
238
239                 case FHFeedAtom:
240                         return @"content";
241                         break;
242         }
243        
244         return NULL;
245 }
246
247
248
249 - (CFXMLTreeRef)contentTree {
250         return _contentTree;
251 }
252
253
254
255 - (CFXMLTreeRef)treeWithName:(NSString *)name inTree:(CFXMLTreeRef)tree {
256         NSString                *itemName;
257         CFXMLTreeRef    itemTree;
258         CFXMLNodeRef    node;
259         NSUInteger              i, count;
260        
261         count = CFTreeGetChildCount(tree);
262        
263         for(i = 0; i < count; i++) {
264                 itemTree        = CFTreeGetChildAtIndex(tree, i);
265                 node            = CFXMLTreeGetNode(itemTree);
266                 itemName        = (NSString *) CFXMLNodeGetString(node);
267                
268                 if([itemName isEqualToString:name])
269                         return itemTree;
270         }
271        
272         return NULL;
273 }
274
275
276
277 - (NSString *)valueOfTree:(CFXMLTreeRef)tree {
278         NSMutableString         *value;
279         NSString                        *name;
280         CFXMLNodeRef            node;
281         NSUInteger                      i, count;
282        
283         value = [NSMutableString string];
284         count = CFTreeGetChildCount(tree);
285        
286         for(i = 0; i < count; i++) {
287                 node = CFXMLTreeGetNode(CFTreeGetChildAtIndex(tree, i));
288                 name = (NSString *) CFXMLNodeGetString(node);
289                
290                 if(name) {
291                         if(CFXMLNodeGetTypeCode(node) == kCFXMLNodeTypeEntityReference) {
292                                 if([name isEqualToString:@"lt"])
293                                         name = @"<";
294                                 else if([name isEqualToString:@"gt"])
295                                         name = @">";
296                                 else if([name isEqualToString:@"quot"])
297                                         name = @"\"";
298                                 else if([name isEqualToString:@"amp"])
299                                         name = @"&";
300                         }
301                                                
302                         [value appendString:name];
303                 }
304         }
305        
306         return value;
307 }
308
309
310
311 #pragma mark -
312
313 - (NSArray *)files {
314         NSDictionary    *item;
315         NSArray                 *links;
316         NSString                *content;
317         NSUInteger              i, index, count, j, linkCount;
318        
319         if(!_files) {
320                 count = [_items count];
321                 _files = [[NSMutableArray alloc] initWithCapacity:count];
322                
323                 for(i = index = 0; i < count; i++) {
324                         item = [_items objectAtIndex:i];
325                         content = [item objectForKey:[self itemContentKey]];
326                         links = [FHHTMLParser imageLinksInHTML:content baseURL:[self URL]];
327                        
328                         for(j = 0, linkCount = [links count]; j < linkCount; j++) {
329                                 [_files addObject:[FHFile fileWithURL:[links objectAtIndex:j] isDirectory:NO]];
330                                
331                                 _numberOfFiles++;
332                                 _numberOfImages++;
333                         }
334                 }
335         }
336        
337         return _files;
338 }
339
340
341
342 - (BOOL)hasParent {
343         return NO;
344 }
345
346
347
348 - (NSArray *)stringComponents {
349         return [NSArray arrayWithObject:[_header objectForKey:@"title"]];
350 }
351
352
353
354 - (NSArray *)URLComponents {
355         return [NSArray arrayWithObject:[self URL]];
356 }
357
358 @end
Note: See TracBrowser for help on using the browser.