FSParseRssPodcastFeedRequest.m 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. /*
  2. * This file is part of the FreeStreamer project,
  3. * (C)Copyright 2011-2018 Matias Muhonen <mmu@iki.fi> 穆马帝
  4. * See the file ''LICENSE'' for using the code.
  5. *
  6. * https://github.com/muhku/FreeStreamer
  7. */
  8. #import <libxml/parser.h>
  9. #import <libxml/xpath.h>
  10. #import "FSParseRssPodcastFeedRequest.h"
  11. #import "FSPlaylistItem.h"
  12. static NSString *const kXPathQueryItems = @"/rss/channel/item";
  13. @interface FSParseRssPodcastFeedRequest ()
  14. - (NSURL *)parseLocalFileUrl:(NSString *)fileUrl;
  15. - (void)parseItems:(xmlNodePtr)node;
  16. @end
  17. @implementation FSParseRssPodcastFeedRequest
  18. - (NSURL *)parseLocalFileUrl:(NSString *)fileUrl
  19. {
  20. // Resolve the local bundle URL
  21. NSString *path = [fileUrl substringFromIndex:7];
  22. NSRange range = [path rangeOfString:@"." options:NSBackwardsSearch];
  23. NSString *fileName = [path substringWithRange:NSMakeRange(0, range.location)];
  24. NSString *suffix = [path substringWithRange:NSMakeRange(range.location + 1, [path length] - [fileName length] - 1)];
  25. return [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:fileName ofType:suffix]];
  26. }
  27. - (void)parseItems:(xmlNodePtr)node
  28. {
  29. FSPlaylistItem *item = [[FSPlaylistItem alloc] init];
  30. for (xmlNodePtr n = node->children; n != NULL; n = n->next) {
  31. NSString *nodeName = @((const char *)n->name);
  32. if ([nodeName isEqualToString:@"title"]) {
  33. item.title = [self contentForNode:n];
  34. } else if ([nodeName isEqualToString:@"enclosure"]) {
  35. NSString *url = [self contentForNodeAttribute:n attribute:"url"];
  36. if ([url hasPrefix:@"file://"]) {
  37. item.url = [self parseLocalFileUrl:url];
  38. } else {
  39. item.url = [NSURL URLWithString:url];
  40. }
  41. } else if ([nodeName isEqualToString:@"link"]) {
  42. NSString *url = [self contentForNode:n];
  43. if ([url hasPrefix:@"file://"]) {
  44. item.originatingUrl = [self parseLocalFileUrl:url];
  45. } else {
  46. item.originatingUrl = [NSURL URLWithString:url];
  47. }
  48. }
  49. }
  50. if (nil == item.url &&
  51. nil == item.originatingUrl) {
  52. // Not a valid item, as there is no URL. Skip.
  53. return;
  54. }
  55. [_playlistItems addObject:item];
  56. }
  57. - (void)parseResponseData
  58. {
  59. if (!_playlistItems) {
  60. _playlistItems = [[NSMutableArray alloc] init];
  61. }
  62. [_playlistItems removeAllObjects];
  63. // RSS feed publication date format:
  64. // Sun, 22 Jul 2012 17:35:05 GMT
  65. [_dateFormatter setDateFormat:@"EEE, dd MMMM yyyy HH:mm:ss V"];
  66. [_dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_GB"]];
  67. [self performXPathQuery:kXPathQueryItems];
  68. }
  69. - (void)parseXMLNode:(xmlNodePtr)node xPathQuery:(NSString *)xPathQuery
  70. {
  71. if ([xPathQuery isEqualToString:kXPathQueryItems]) {
  72. [self parseItems:node];
  73. }
  74. }
  75. - (NSArray *)playlistItems
  76. {
  77. return _playlistItems;
  78. }
  79. @end