Changeset 2944

Show
Ignore:
Timestamp:
06/01/05 10:32:08 (4 years ago)
Author:
morris
Message:

Same handler for RSS/Atom, use a constant instead

Special handling for flickr.com

Share HTML parser with feed/html handlers

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • Footagehead/trunk/FHFeedHandler.h

    r2935 r2944  
    2929#import "FHURLHandler.h" 
    3030 
     31enum FHFeedFormat { 
     32        FHFeedUnknown = 0, 
     33        FHFeedRSS, 
     34        FHFeedAtom, 
     35}; 
     36typedef enum FHFeedFormat                       FHFeedFormat; 
     37 
     38 
    3139@interface FHFeedHandler : FHURLHandler { 
    3240        CFXMLTreeRef                            _feed; 
     41        CFXMLTreeRef                            _contentTree; 
     42         
     43        FHFeedFormat                            _format; 
    3344 
    3445        NSMutableDictionary                     *_header; 
     
    3748 
    3849 
    39 + (Class)handlerForFeed:(CFXMLTreeRef)feed; 
    40 + (NSString *)itemDividerKey; 
    41 + (NSString *)itemContentKey; 
     50+ (Class)handlerForURL:(ZAURL *)url; 
    4251 
    4352- (id)initHandlerWithURL:(ZAURL *)url feed:(CFXMLTreeRef)feed; 
     53- (id)initHandlerWithURL:(ZAURL *)url feed:(CFXMLTreeRef)feed format:(FHFeedFormat)format; 
    4454 
     55- (NSString *)itemDividerKey; 
     56- (NSString *)itemContentKey; 
    4557- (CFXMLTreeRef)contentTree; 
    4658- (CFXMLTreeRef)treeWithName:(NSString *)name inTree:(CFXMLTreeRef)tree; 
  • Footagehead/trunk/FHFeedHandler.m

    r2935 r2944  
    2828 
    2929#import "FHFeedHandler.h" 
     30#import "FHFlickrHandler.h" 
    3031#import "FHFile.h" 
    31 #import "FHAtomHandler.h" 
    32 #import "FHRSSHandler.h" 
     32#import "FHHTMLParser.h" 
    3333 
    3434@interface FHFeedHandler(Private) 
    3535 
    36 enum FHFeedHandlerParseMode { 
    37         FHFeedHandlerParseHeader, 
    38         FHFeedHandlerParseItems, 
     36enum FHFeedParseMode { 
     37        FHFeedParseHeader, 
     38        FHFeedParseItems, 
    3939}; 
    40 typedef enum FHFeedHandlerParseMode            FHFeedHandlerParseMode; 
     40typedef enum FHFeedParseMode           FHFeedParseMode; 
    4141 
    4242 
     
    4949@implementation FHFeedHandler 
    5050 
    51 + (Class)handlerForFeed:(CFXMLTreeRef)feed { 
     51+ (Class)handlerForURL:(ZAURL *)url { 
     52        NSString        *host; 
     53         
     54        host = [url host]; 
     55         
     56        if([host hasSuffix:@"flickr.com"]) 
     57                return [FHFlickrHandler class]; 
     58         
     59        return self; 
     60
     61 
     62 
     63 
     64#pragma mark - 
     65 
     66- (id)initHandlerWithURL:(ZAURL *)url feed:(CFXMLTreeRef)feed { 
    5267        CFXMLNodeRef    node; 
    5368        NSString                *name; 
     69        FHFeedFormat    format; 
     70         
     71        format = FHFeedUnknown; 
    5472         
    5573        if(CFTreeGetChildCount(feed) >= 2) { 
     
    5876         
    5977                if([name isEqualToString:@"rss"]) 
    60                         return [FHRSSHandler class]
     78                        format = FHFeedRSS
    6179                else if([name isEqualToString:@"feed"]) 
    62                         return [FHAtomHandler class]; 
    63         } 
    64          
    65         return NULL; 
    66 
    67  
    68  
    69  
    70 + (NSString *)itemDividerKey { 
    71         return NULL; 
    72 
    73  
    74  
    75  
    76 + (NSString *)itemContentKey { 
    77         return NULL; 
    78 
    79  
    80  
    81  
    82 #pragma mark - 
    83  
    84 - (id)initHandlerWithURL:(ZAURL *)url feed:(CFXMLTreeRef)feed { 
     80                        format = FHFeedAtom; 
     81        } 
     82 
     83        return [self initHandlerWithURL:url feed:feed format:format]; 
     84
     85 
     86 
     87 
     88- (id)initHandlerWithURL:(ZAURL *)url feed:(CFXMLTreeRef)feed format:(FHFeedFormat)format { 
     89        CFXMLTreeRef    rssTree; 
     90         
    8591        self = [super initHandlerWithURL:url]; 
    8692         
    8793        _feed = (CFXMLTreeRef) CFRetain(feed); 
    88          
     94        _format = format; 
     95 
     96        if(_format == FHFeedRSS) { 
     97                rssTree = [self treeWithName:@"rss" inTree:_feed]; 
     98                 
     99                if(!rssTree) 
     100                        rssTree = [self treeWithName:@"rdf:RDF" inTree:_feed]; 
     101                 
     102                if(!rssTree) { 
     103                        [self release]; 
     104                         
     105                        return NULL; 
     106                } 
     107                 
     108                _contentTree = [self treeWithName:@"channel" inTree:rssTree]; 
     109                 
     110                if(!_contentTree) 
     111                        _contentTree = [self treeWithName:@"rss:channel" inTree:rssTree]; 
     112                 
     113                if(!_contentTree) { 
     114                        [self release]; 
     115                         
     116                        return NULL; 
     117                } 
     118        } 
     119         
     120        [self parse]; 
     121                 
    89122        return self; 
    90123} 
     
    101134 
    102135#pragma mark - 
    103  
    104136- (void)parse { 
    105137        NSMutableDictionary             *items; 
     
    107139        CFXMLTreeRef                    contentTree, tree, itemTree; 
    108140        CFXMLNodeRef                    node, itemNode; 
    109         FHFeedHandlerParseMode        mode; 
     141        FHFeedParseMode                       mode; 
    110142        unsigned int                    i, count, j, itemCount; 
    111143         
    112144        contentTree = [self contentTree]; 
    113         dividerKey = [[self class] itemDividerKey]; 
     145        dividerKey = [self itemDividerKey]; 
    114146        count = CFTreeGetChildCount(contentTree); 
    115         mode = FHFeedHandlerParseHeader; 
     147        mode = FHFeedParseHeader; 
    116148 
    117149        _header = [[NSMutableDictionary alloc] initWithCapacity:10]; 
     
    124156                 
    125157                if([name isEqualToString:dividerKey]) 
    126                         mode = FHFeedHandlerParseItems; 
    127                  
    128                 if(mode == FHFeedHandlerParseHeader) { 
     158                        mode = FHFeedParseItems; 
     159                 
     160                if(mode == FHFeedParseHeader) { 
    129161                        if([name isEqualTo:@"image"]) 
    130162                                [self parseImageHeaderInTree:tree]; 
     
    132164                        [_header setObject:[self valueOfTree:tree] forKey:name]; 
    133165                } 
    134                 else if(mode == FHFeedHandlerParseItems) { 
     166                else if(mode == FHFeedParseItems) { 
    135167                        itemCount = CFTreeGetChildCount(tree); 
    136168                        items = [[NSMutableDictionary alloc] initWithCapacity:itemCount]; 
     
    173205#pragma mark - 
    174206 
     207 
     208- (NSString *)itemDividerKey { 
     209        switch(_format) { 
     210                case FHFeedUnknown: 
     211                        return NULL; 
     212                        break; 
     213 
     214                case FHFeedRSS: 
     215                        return @"item"; 
     216                        break; 
     217 
     218                case FHFeedAtom: 
     219                        return @"entry"; 
     220                        break; 
     221        } 
     222} 
     223 
     224 
     225 
     226- (NSString *)itemContentKey { 
     227        switch(_format) { 
     228                case FHFeedUnknown: 
     229                        return NULL; 
     230                        break; 
     231 
     232                case FHFeedRSS: 
     233                        return @"description"; 
     234                        break; 
     235 
     236                case FHFeedAtom: 
     237                        return @"content"; 
     238                        break; 
     239        } 
     240} 
     241 
     242 
     243 
    175244- (CFXMLTreeRef)contentTree { 
    176         return _feed
     245        return _contentTree
    177246} 
    178247 
     
    237306#pragma mark - 
    238307 
    239  
    240308- (NSArray *)files { 
    241309        NSDictionary    *item; 
    242         NSMutableString *address; 
    243         NSString                *name, *content, *string; 
    244         NSScanner               *scanner; 
     310        NSArray                 *links; 
     311        NSString                *content; 
    245312        FHFile                  *file; 
    246         NSRange                 range; 
    247         unsigned int    i, count; 
     313        unsigned int    i, index, count, j, linkCount; 
    248314         
    249315        if(!_files) { 
    250                 [self parse]; 
    251                  
    252316                count = [_items count]; 
    253317                _files = [[NSMutableArray alloc] initWithCapacity:count]; 
    254318                 
    255                 for(i = 0; i < count; i++) { 
     319                for(i = index = 0; i < count; i++) { 
    256320                        item = [_items objectAtIndex:i]; 
    257                         name = [item objectForKey:@"title"]; 
    258                         content = [item objectForKey:[[self class] itemContentKey]]; 
    259                          
    260                         scanner = [[NSScanner alloc] initWithString:content]; 
    261                         [scanner setCaseSensitive:NO]; 
    262  
    263                         if(![scanner scanUpToString:@"img src=\"" intoString:NULL]) 
    264                                 continue; 
    265                          
    266                         if(![scanner scanString:@"img src=\"" intoString:NULL]) 
    267                                 continue; 
    268                          
    269                         if(![scanner scanUpToString:@"\"" intoString:&string]) 
    270                                 continue; 
    271                          
    272                         [scanner release]; 
    273                          
    274                         address = [string mutableCopy]; 
    275                         range = [address rangeOfString:@"_m"]; 
    276                          
    277                         if(range.location != NSNotFound) 
    278                                 [address deleteCharactersInRange:range]; 
    279                          
    280                         file = [[FHFile alloc] initWithURL:[ZAURL URLWithString:address] name:name isDirectory:NO index:i]; 
    281                         [_files addObject:file]; 
    282                         [file release]; 
    283                          
    284                         _numberOfFiles++; 
    285                         _numberOfImages++; 
    286                          
    287                         [address release]; 
     321                        content = [item objectForKey:[self itemContentKey]]; 
     322                        links = [FHHTMLParser imageLinksInHTML:content baseURL:[self URL]]; 
     323                         
     324                        for(j = 0, linkCount = [links count]; j < linkCount; j++) { 
     325                                file = [[FHFile alloc] initWithURL:[links objectAtIndex:j] isDirectory:NO index:index++]; 
     326                                [_files addObject:file]; 
     327                                [file release]; 
     328                                 
     329                                _numberOfFiles++; 
     330                                _numberOfImages++; 
     331                        } 
    288332                } 
    289333        } 
  • Footagehead/trunk/FHHTMLHandler.m

    r2934 r2944  
    3030#import "FHFile.h" 
    3131#import "FHHTMLHandler.h" 
     32#import "FHHTMLParser.h" 
    3233 
    3334@implementation FHHTMLHandler 
     
    5455 
    5556- (NSArray *)files { 
    56         NSCharacterSet  *skipSet; 
    57         NSMutableArray  *links; 
    58         NSMutableSet    *set; 
     57        NSArray                 *links; 
    5958        NSArray                 *types; 
    60         NSString                *token, *link, *path; 
    61         NSScanner               *scanner; 
    6259        FHFile                  *file; 
    63         ZAURL                   *url; 
    64         unsigned int    i, index, count, length; 
     60        unsigned int    i, index, count; 
    6561         
    6662        if(!_files) { 
    67                 _files = [[NSMutableArray alloc] initWithCapacity:50]; 
     63                types = [NSImage FHImageFileTypes]; 
     64                links = [FHHTMLParser imageLinksInHTML:_html baseURL:[self URL]]; 
     65                count = [links count]; 
    6866                 
    69                 types = [NSImage FHImageFileTypes]; 
    70                 links = [NSMutableArray array]; 
    71                 set = [NSMutableSet set]; 
    72                 skipSet = [NSCharacterSet characterSetWithCharactersInString:@" =\r\n\t\"\'<>"]; 
    73                 length = [_html length]; 
     67                _files = [[NSMutableArray alloc] initWithCapacity:count]; 
    7468                 
    75                 for(i = 0, token = @"SRC"; i < 2; i++, token = @"HREF") { 
    76                         scanner = [[NSScanner alloc] initWithString:_html]; 
    77                         [scanner setCaseSensitive:NO]; 
    78                         [scanner setCharactersToBeSkipped:skipSet]; 
    79                          
    80                         while([scanner scanLocation] < length) { 
    81                                 if([scanner scanUpToString:token intoString:NULL]) { 
    82                                         if([scanner scanString:token intoString:NULL]) { 
    83                                                 if([scanner scanUpToCharactersFromSet:skipSet intoString:&link]) { 
    84                                                         if(![set containsObject:link]) { 
    85                                                                 [links addObject:link]; 
    86                                                                 [set addObject:link]; 
    87                                                         } 
    88                                                 } 
    89                                         } 
    90                                 } 
    91                         } 
    92                          
    93                         [scanner release]; 
    94                 } 
    95                          
    96                 for(i = index = 0, count = [links count]; i < count; i++) { 
    97                         link = [links objectAtIndex:i]; 
    98                          
    99                         if(![types containsObject:[link pathExtension]])  
    100                                 continue; 
    101                          
    102                         link = [link stringByReplacingURLPercentEscapes]; 
    103                          
    104                         if([link containsSubstring:@"://"]) { 
    105                                 url = [ZAURL URLWithString:link]; 
    106                         } else { 
    107                                 url = [[[self URL] copy] autorelease]; 
    108                                  
    109                                 if([link hasPrefix:@"/"]) { 
    110                                         [url setPath:link]; 
    111                                 } else { 
    112                                         path = [url path]; 
    113                                          
    114                                         if(![path hasSuffix:@"/"]) 
    115                                                 path = [path stringByDeletingLastPathComponent]; 
    116                                          
    117                                         [url setPath:[path stringByAppendingPathComponent:link]]; 
    118                                 } 
    119                         } 
    120                          
    121                         if([[url path] isEqualToString:@"/"]) 
    122                                 continue; 
    123                          
    124                         file = [[FHFile alloc] initWithURL:url isDirectory:NO index:index++]; 
     69                for(i = index = 0; i < count; i++) { 
     70                        file = [[FHFile alloc] initWithURL:[links objectAtIndex:i] isDirectory:NO index:index++]; 
    12571                        [_files addObject:file]; 
    12672                        [file release]; 
  • Footagehead/trunk/FHURLHandler.m

    r2938 r2944  
    2828 
    2929#import "FHURLHandler.h" 
     30#import "FHFeedHandler.h" 
    3031#import "FHHTMLHandler.h" 
    3132#import "FHImageHandler.h" 
    32 #import "FHRSSHandler.h" 
    3333 
    3434@implementation FHURLHandler 
     
    104104        else if([mime containsSubstring:@"xml"]) { 
    105105                CFXMLTreeRef    feed; 
     106                Class                   class; 
    106107                 
    107108                feed = CFXMLTreeCreateFromData(kCFAllocatorDefault, (CFDataRef) data, 
     
    110111 
    111112                if(feed) { 
     113                        class = [FHFeedHandler handlerForURL:url]; 
     114                         
    112115                        if([mime isEqualToString:@"text/xml"]) 
    113                                 return [[[FHFeedHandler handlerForFeed:feed] allocWithZone:zone] initHandlerWithURL:url feed:feed]; 
     116                                return [[class allocWithZone:zone] initHandlerWithURL:url feed:feed]; 
    114117                        else if([mime isEqualToString:@"application/rss+xml"]) 
    115                                 return [[FHRSSHandler allocWithZone:zone] initHandlerWithURL:url feed:feed]; 
     118                                return [[class allocWithZone:zone] initHandlerWithURL:url feed:feed format:FHFeedRSS]; 
    116119                } 
    117120        } 
  • Footagehead/trunk/Footagehead.xcode/project.pbxproj

    r2940 r2944  
    14641464                        sourceTree = "<group>"; 
    14651465                }; 
     1466                77EABF0E084C61FF006C9F69 = { 
     1467                        fileEncoding = 4; 
     1468                        isa = PBXFileReference; 
     1469                        lastKnownFileType = sourcecode.c.h; 
     1470                        path = FHHTMLParser.h; 
     1471                        refType = 4; 
     1472                        sourceTree = "<group>"; 
     1473                }; 
     1474                77EABF0F084C61FF006C9F69 = { 
     1475                        fileEncoding = 4; 
     1476                        isa = PBXFileReference; 
     1477                        lastKnownFileType = sourcecode.c.objc; 
     1478                        path = FHHTMLParser.m; 
     1479                        refType = 4; 
     1480                        sourceTree = "<group>"; 
     1481                }; 
     1482                77EABF11084C61FF006C9F69 = { 
     1483                        fileRef = 77EABF0F084C61FF006C9F69; 
     1484                        isa = PBXBuildFile; 
     1485                        settings = { 
     1486                        }; 
     1487                }; 
     1488                77EAC0D2084C6D1F006C9F69 = { 
     1489                        fileEncoding = 4; 
     1490                        isa = PBXFileReference; 
     1491                        lastKnownFileType = sourcecode.c.h; 
     1492                        path = FHFlickrHandler.h; 
     1493                        refType = 4; 
     1494                        sourceTree = "<group>"; 
     1495                }; 
     1496                77EAC0D3084C6D1F006C9F69 = { 
     1497                        fileEncoding = 4; 
     1498                        isa = PBXFileReference; 
     1499                        lastKnownFileType = sourcecode.c.objc; 
     1500                        path = FHFlickrHandler.m; 
     1501                        refType = 4; 
     1502                        sourceTree = "<group>"; 
     1503                }; 
     1504                77EAC0D4084C6D1F006C9F69 = { 
     1505                        fileRef = 77EAC0D2084C6D1F006C9F69; 
     1506                        isa = PBXBuildFile; 
     1507                        settings = { 
     1508                        }; 
     1509                }; 
     1510                77EAC0D5084C6D1F006C9F69 = { 
     1511                        fileRef = 77EAC0D3084C6D1F006C9F69; 
     1512                        isa = PBXBuildFile; 
     1513                        settings = { 
     1514                        }; 
     1515                }; 
    14661516//770 
    14671517//771 
     
    15571607                                770EBFC5083C94CE0094BD6C, 
    15581608                                775BA4F2075F70ED00F0941E, 
    1559                                 A519AA6A084BAC2800EFF2EA, 
    15601609                                A5B1FB9F067CB90400111D0A, 
    15611610                                A587DF83055AA418005D2097, 
     
    15661615                                A5B1F611067B3AA100111D0A, 
    15671616                                A5B1F9AC067BCF0200111D0A, 
    1568                                 77EAADDA084B546D006C9F69, 
     1617                                77EABF11084C61FF006C9F69, 
    15691618                                A5B1FBC6067D01C200111D0A, 
    15701619                                77CDB023083B6B85003BE654, 
    15711620                                A54BD5420566834700E3ACBC, 
    15721621                                A5B1F9C1067BDF2300111D0A, 
    1573                                 A519AA0A084BA8C900EFF2EA, 
    15741622                                A587DF85055AA418005D2097, 
    15751623                                A5092F57083E7812006646D1, 
    15761624                                77BD99520760B7380007D034, 
     1625                                77EAADDA084B546D006C9F69, 
     1626                                77EAC0D5084C6D1F006C9F69, 
    15771627                        ); 
    15781628                        isa = PBXSourcesBuildPhase; 
     
    16991749                        shellScript = "#!/bin/sh\n\nPATH=\"/usr/local/bin:$PATH\" perl version.pl\n\nexit 0"; 
    17001750                }; 
    1701                 A519AA07084BA8C900EFF2EA = { 
    1702                         fileEncoding = 5; 
    1703                         isa = PBXFileReference; 
    1704                         lastKnownFileType = sourcecode.c.h; 
    1705                         path = FHRSSHandler.h; 
    1706                         refType = 4; 
    1707                         sourceTree = "<group>"; 
    1708                 }; 
    1709                 A519AA08084BA8C900EFF2EA = { 
    1710                         fileEncoding = 5; 
    1711                         isa = PBXFileReference; 
    1712                         lastKnownFileType = sourcecode.c.objc; 
    1713                         path = FHRSSHandler.m; 
    1714                         refType = 4; 
    1715                         sourceTree = "<group>"; 
    1716                 }; 
    1717                 A519AA0A084BA8C900EFF2EA = { 
    1718                         fileRef = A519AA08084BA8C900EFF2EA; 
    1719                         isa = PBXBuildFile; 
    1720                         settings = { 
    1721                         }; 
    1722                 }; 
    17231751                A519AA10084BA8FB00EFF2EA = { 
    17241752                        children = ( 
    17251753                                A519AA32084BA91B00EFF2EA, 
    17261754                                A519AA33084BA91B00EFF2EA, 
    1727                                 A519AA68084BAC2800EFF2EA, 
    1728                                 A519AA69084BAC2800EFF2EA, 
    1729                                 A519AA08084BA8C900EFF2EA, 
    1730                                 A519AA07084BA8C900EFF2EA, 
     1755                                77EAC0D3084C6D1F006C9F69, 
     1756                                77EAC0D2084C6D1F006C9F69, 
    17311757                        ); 
    17321758                        isa = PBXGroup; 
     
    17531779                A519AA34084BA91B00EFF2EA = { 
    17541780                        fileRef = A519AA32084BA91B00EFF2EA; 
    1755                         isa = PBXBuildFile; 
    1756                         settings = { 
    1757                         }; 
    1758                 }; 
    1759                 A519AA68084BAC2800EFF2EA = { 
    1760                         fileEncoding = 5; 
    1761                         isa = PBXFileReference; 
    1762                         lastKnownFileType = sourcecode.c.objc; 
    1763                         path = FHAtomHandler.m; 
    1764                         refType = 4; 
    1765                         sourceTree = "<group>"; 
    1766                 }; 
    1767                 A519AA69084BAC2800EFF2EA = { 
    1768                         fileEncoding = 5; 
    1769                         isa = PBXFileReference; 
    1770                         lastKnownFileType = sourcecode.c.h; 
    1771                         path = FHAtomHandler.h; 
    1772                         refType = 4; 
    1773                         sourceTree = "<group>"; 
    1774                 }; 
    1775                 A519AA6A084BAC2800EFF2EA = { 
    1776                         fileRef = A519AA68084BAC2800EFF2EA; 
    17771781                        isa = PBXBuildFile; 
    17781782                        settings = { 
     
    20222026                        files = ( 
    20232027                                A54D42DD07663AA300227EBE, 
     2028                                77EAC0D4084C6D1F006C9F69, 
    20242029                        ); 
    20252030                        isa = PBXCopyFilesBuildPhase; 
     
    21152120                                A5B1F7BA067B440E00111D0A, 
    21162121                                A5B1F7BB067B440E00111D0A, 
     2122                                77EABF0F084C61FF006C9F69, 
     2123                                77EABF0E084C61FF006C9F69, 
    21172124                                A587DF7B055AA418005D2097, 
    21182125                                A587DF76055AA418005D2097,