diff --git a/Frameworks/RSParser/HTML/RSHTMLMetadata.h b/Frameworks/RSParser/HTML/RSHTMLMetadata.h index f110292d8..7ccbc9645 100755 --- a/Frameworks/RSParser/HTML/RSHTMLMetadata.h +++ b/Frameworks/RSParser/HTML/RSHTMLMetadata.h @@ -13,6 +13,7 @@ @class RSHTMLOpenGraphProperties; @class RSHTMLOpenGraphImage; @class RSHTMLTag; +@class RSHTMLTwitterProperties; @interface RSHTMLMetadata : NSObject @@ -26,6 +27,8 @@ @property (nonatomic, readonly) NSArray *feedLinks; @property (nonatomic, readonly) RSHTMLOpenGraphProperties *openGraphProperties; +@property (nonatomic, readonly) RSHTMLTwitterProperties *twitterProperties; + @end @@ -67,3 +70,14 @@ @property (nonatomic, readonly) NSString *altText; @end + +@interface RSHTMLTwitterProperties : NSObject + +// TODO: the rest. At this writing (Nov. 26, 2017) I just care about twitter:image:src. + +- (instancetype)initWithURLString:(NSString *)urlString tags:(NSArray *)tags; + +@property (nonatomic, readonly) NSString *imageURL; // twitter:image:src + +@end + diff --git a/Frameworks/RSParser/HTML/RSHTMLMetadata.m b/Frameworks/RSParser/HTML/RSHTMLMetadata.m index 52c329d80..b68dbd06e 100755 --- a/Frameworks/RSParser/HTML/RSHTMLMetadata.m +++ b/Frameworks/RSParser/HTML/RSHTMLMetadata.m @@ -71,7 +71,8 @@ static NSString *kTypeKey = @"type"; _feedLinks = objectsOfClassWithTags([RSHTMLMetadataFeedLink class], feedLinkTags, urlString); _openGraphProperties = [[RSHTMLOpenGraphProperties alloc] initWithURLString:urlString tags:tags]; - + _twitterProperties = [[RSHTMLTwitterProperties alloc] initWithURLString:urlString tags:tags]; + return self; } @@ -382,4 +383,38 @@ static NSString *ogContentKey = @"content"; @end +@implementation RSHTMLTwitterProperties + +static NSString *twitterNameKey = @"name"; +static NSString *twitterContentKey = @"content"; +static NSString *twitterImageSrc = @"twitter:image:src"; + +- (instancetype)initWithURLString:(NSString *)urlString tags:(NSArray *)tags { + + self = [super init]; + if (!self) { + return nil; + } + + for (RSHTMLTag *tag in tags) { + + if (tag.type != RSHTMLTagTypeMeta) { + continue; + } + NSString *name = tag.attributes[twitterNameKey]; + if (!name || ![name isEqualToString:twitterImageSrc]) { + continue; + } + NSString *content = tag.attributes[twitterContentKey]; + if (!content || content.length < 1) { + continue; + } + _imageURL = content; + break; + } + + return self; +} + +@end diff --git a/Frameworks/RSParser/RSParserTests/HTMLMetadataTests.swift b/Frameworks/RSParser/RSParserTests/HTMLMetadataTests.swift index 8eff9fb81..a03f8bcc6 100644 --- a/Frameworks/RSParser/RSParserTests/HTMLMetadataTests.swift +++ b/Frameworks/RSParser/RSParserTests/HTMLMetadataTests.swift @@ -83,6 +83,15 @@ class HTMLMetadataTests: XCTestCase { } } + func testCocoPerformance() { + + // 0.004 sec on my 2012 iMac + let d = parserData("coco", "html", "https://www.theatlantic.com/entertainment/archive/2017/11/coco-is-among-pixars-best-movies-in-years/546695/") + self.measure { + let _ = RSHTMLMetadataParser.htmlMetadata(with: d) + } + } + func testSixColors() { let d = parserData("sixcolors", "html", "http://sixcolors.com/") @@ -120,4 +129,13 @@ class HTMLMetadataTests: XCTestCase { let image = openGraphData.images.first! XCTAssert(image.url == "https://cdn.theatlantic.com/assets/media/img/mt/2017/11/1033101_first_full_length_trailer_arrives_pixars_coco/facebook.jpg?1511382177") } + + func testCocoTwitterImage() { + + let d = parserData("coco", "html", "https://www.theatlantic.com/entertainment/archive/2017/11/coco-is-among-pixars-best-movies-in-years/546695/") + let metadata = RSHTMLMetadataParser.htmlMetadata(with: d) + let twitterData = metadata.twitterProperties! + let imageURL = twitterData.imageURL! + XCTAssert(imageURL == "https://cdn.theatlantic.com/assets/media/img/mt/2017/11/1033101_first_full_length_trailer_arrives_pixars_coco/facebook.jpg?1511382177") + } }