Parse Atom enclosures. However, I couldn’t find any in the wild, so there are no tests yet.

This commit is contained in:
Brent Simmons 2017-12-19 10:17:09 -08:00
parent 5bb9081fd2
commit 7ccb531f0c
5 changed files with 63 additions and 16 deletions

View File

@ -14,6 +14,7 @@
#import <RSParser/NSString+RSParser.h> #import <RSParser/NSString+RSParser.h>
#import <RSParser/RSDateParser.h> #import <RSParser/RSDateParser.h>
#import <RSParser/ParserData.h> #import <RSParser/ParserData.h>
#import <RSParser/RSParsedEnclosure.h>
@interface RSAtomParser () <RSSAXParserDelegate> @interface RSAtomParser () <RSSAXParserDelegate>
@ -94,11 +95,14 @@ static NSString *kXMLBaseKey = @"xml:base";
static NSString *kXMLLangKey = @"xml:lang"; static NSString *kXMLLangKey = @"xml:lang";
static NSString *kTextHTMLValue = @"text/html"; static NSString *kTextHTMLValue = @"text/html";
static NSString *kRelatedValue = @"related"; static NSString *kRelatedValue = @"related";
static NSString *kEnclosureValue = @"enclosure";
static NSString *kShortURLValue = @"shorturl"; static NSString *kShortURLValue = @"shorturl";
static NSString *kHTMLValue = @"html"; static NSString *kHTMLValue = @"html";
static NSString *kEnValue = @"en"; static NSString *kEnValue = @"en";
static NSString *kTextValue = @"text"; static NSString *kTextValue = @"text";
static NSString *kSelfValue = @"self"; static NSString *kSelfValue = @"self";
static NSString *kLengthKey = @"length";
static NSString *kTitleKey = @"title";
static const char *kID = "id"; static const char *kID = "id";
static const NSInteger kIDLength = 3; static const NSInteger kIDLength = 3;
@ -175,6 +179,11 @@ static const NSInteger kTextLength = 5;
static const char *kSelf = "self"; static const char *kSelf = "self";
static const NSInteger kSelfLength = 5; static const NSInteger kSelfLength = 5;
static const char *kEnclosure = "enclosure";
static const NSInteger kEnclosureLength = 10;
static const char *kLength = "length";
static const NSInteger kLengthLength = 7;
#pragma mark - Parsing #pragma mark - Parsing
@ -241,28 +250,46 @@ static const NSInteger kSelfLength = 5;
- (void)addLink { - (void)addLink {
NSString *urlString = self.currentAttributes[kHrefKey]; NSDictionary *attributes = self.currentAttributes;
NSString *urlString = attributes[kHrefKey];
if (urlString.length < 1) { if (urlString.length < 1) {
return; return;
} }
NSString *rel = self.currentAttributes[kRelKey]; RSParsedArticle *article = self.currentArticle;
NSString *rel = attributes[kRelKey];
if (rel.length < 1) { if (rel.length < 1) {
rel = kAlternateValue; rel = kAlternateValue;
} }
if (rel == kAlternateValue) { if (rel == kAlternateValue) {
if (!self.currentArticle.link) { if (!article.link) {
self.currentArticle.link = urlString; article.link = urlString;
} }
} }
else if (rel == kRelatedValue) { else if (rel == kRelatedValue) {
if (!self.currentArticle.permalink) { if (!article.permalink) {
self.currentArticle.permalink = urlString; article.permalink = urlString;
} }
} }
else if (rel == kEnclosureValue) {
RSParsedEnclosure *enclosure = [self enclosureWithURLString:urlString attributes:attributes];
[article addEnclosure:enclosure];
}
} }
- (RSParsedEnclosure *)enclosureWithURLString:(NSString *)urlString attributes:(NSDictionary *)attributes {
RSParsedEnclosure *enclosure = [[RSParsedEnclosure alloc] init];
enclosure.url = urlString;
enclosure.title = attributes[kTitleKey];
enclosure.mimeType = attributes[kTypeKey];
enclosure.length = [attributes[kLengthKey] integerValue];
return enclosure;
}
- (void)addContent { - (void)addContent {
@ -502,6 +529,14 @@ static const NSInteger kSelfLength = 5;
return kAlternateValue; return kAlternateValue;
} }
if (RSSAXEqualTags(name, kLength, kLengthLength)) {
return kLengthKey;
}
if (RSSAXEqualTags(name, kTitle, kTitleLength)) {
return kTitleKey;
}
return nil; return nil;
} }
@ -522,11 +557,16 @@ static BOOL equalBytes(const void *bytes1, const void *bytes2, NSUInteger length
static const NSUInteger enLength = kEnLength - 1; static const NSUInteger enLength = kEnLength - 1;
static const NSUInteger textLength = kTextLength - 1; static const NSUInteger textLength = kTextLength - 1;
static const NSUInteger selfLength = kSelfLength - 1; static const NSUInteger selfLength = kSelfLength - 1;
static const NSUInteger enclosureLength = kEnclosureLength - 1;
if (length == alternateLength && equalBytes(bytes, kAlternate, alternateLength)) { if (length == alternateLength && equalBytes(bytes, kAlternate, alternateLength)) {
return kAlternateValue; return kAlternateValue;
} }
if (length == enclosureLength && equalBytes(bytes, kEnclosure, enclosureLength)) {
return kEnclosureValue;
}
if (length == textHTMLLength && equalBytes(bytes, kTextHTML, textHTMLLength)) { if (length == textHTMLLength && equalBytes(bytes, kTextHTML, textHTMLLength)) {
return kTextHTMLValue; return kTextHTMLValue;
} }

View File

@ -28,6 +28,8 @@
@property (nonatomic, nullable) NSDate *dateModified; @property (nonatomic, nullable) NSDate *dateModified;
@property (nonatomic, nonnull) NSDate *dateParsed; @property (nonatomic, nonnull) NSDate *dateParsed;
- (void)addEnclosure:(RSParsedEnclosure *_Nonnull)enclosure;
- (void)calculateArticleID; // Optimization. Call after all properties have been set. Call on a background thread. - (void)calculateArticleID; // Optimization. Call after all properties have been set. Call on a background thread.
@end @end

View File

@ -32,6 +32,18 @@
} }
#pragma mark - Enclosures
- (void)addEnclosure:(RSParsedEnclosure *)enclosure {
if (self.enclosures) {
self.enclosures = [self.enclosures setByAddingObject:enclosure];
}
else {
self.enclosures = [NSSet setWithObject:enclosure];
}
}
#pragma mark - Accessors #pragma mark - Accessors
- (NSString *)articleID { - (NSString *)articleID {

View File

@ -15,6 +15,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic) NSString *url; @property (nonatomic) NSString *url;
@property (nonatomic) NSInteger length; @property (nonatomic) NSInteger length;
@property (nonatomic, nullable) NSString *mimeType; @property (nonatomic, nullable) NSString *mimeType;
@property (nonatomic, nullable) NSString *title;
@end @end

View File

@ -244,18 +244,10 @@ static const NSInteger kEnclosureLength = 10;
RSParsedEnclosure *enclosure = [[RSParsedEnclosure alloc] init]; RSParsedEnclosure *enclosure = [[RSParsedEnclosure alloc] init];
enclosure.url = url; enclosure.url = url;
enclosure.length = [attributes[kLengthKey] integerValue];
NSString *lengthString = attributes[kLengthKey];
if (lengthString) {
enclosure.length = lengthString.integerValue;
}
enclosure.mimeType = attributes[kTypeKey]; enclosure.mimeType = attributes[kTypeKey];
// The RSS spec specifies zero or one enclosures. [self.currentArticle addEnclosure:enclosure];
// However, the Media RSS namespace allows for more than one.
// We could add support for multiple enclosures at some time in the future.
self.currentArticle.enclosures = [NSSet setWithObject:enclosure];
} }
- (NSString *)urlString:(NSString *)s { - (NSString *)urlString:(NSString *)s {