RSSParse.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. #include "Main.h"
  2. #include "RSSParse.h"
  3. #include "RFCDate.h"
  4. #include "../xml/XMLNode.h"
  5. #include "Feeds.h"
  6. #include "Defaults.h"
  7. #include "ChannelSync.h"
  8. #include "ParseUtil.h"
  9. #include <strsafe.h>
  10. static void ReadWinampSpecificItem(const XMLNode *item, RSS::Item &newItem)
  11. {
  12. newItem.listened = PropertyIsTrue(item, L"winamp:listened");
  13. newItem.downloaded = PropertyIsTrue(item, L"winamp:downloaded");
  14. }
  15. static void ReadRSSItem(XMLNode *item, Channel &channel, bool doWinampSpecificTags)
  16. {
  17. RSS::MutableItem newItem;
  18. if (doWinampSpecificTags)
  19. ReadWinampSpecificItem(item, newItem);
  20. const wchar_t *pubdate = GetContent(item, L"pubDate");
  21. if (pubdate && pubdate[0])
  22. {
  23. newItem.publishDate = MakeRFCDate(pubdate);
  24. if (newItem.publishDate <= 0)
  25. {
  26. newItem.publishDate = _time64(0);
  27. newItem.generatedDate = true;
  28. }
  29. else
  30. newItem.generatedDate = false;
  31. }
  32. else
  33. {
  34. newItem.publishDate = _time64(0);
  35. newItem.generatedDate = true;
  36. }
  37. const wchar_t *itemName = GetContent(item, L"title");
  38. if (itemName && itemName[0])
  39. newItem.SetItemName(itemName);
  40. else
  41. {
  42. wchar_t date_str[128] = {0};
  43. MakeRFCDateString(newItem.publishDate, date_str, 128);
  44. newItem.SetItemName(date_str);
  45. }
  46. newItem.SetLink(GetContent(item, L"link"));
  47. newItem.SetURL(GetProperty(item, L"enclosure", L"url"));
  48. const wchar_t* src = GetProperty(item, L"source", L"src");
  49. if (!src || !src[0])
  50. {
  51. newItem.SetSourceURL(GetProperty(item, L"source", L"url"));
  52. }
  53. else
  54. {
  55. newItem.SetSourceURL(src/*GetProperty(item, L"source", L"src")*/);
  56. }
  57. newItem.SetSize(GetProperty(item, L"enclosure", L"length"));
  58. const wchar_t *guid = GetContent(item, L"guid");
  59. if (!guid || !guid[0])
  60. guid = GetProperty(item, L"enclosure", L"url");
  61. if (guid && guid[0])
  62. {
  63. newItem.SetGUID(guid);
  64. }
  65. else
  66. {
  67. wchar_t generated_guid[160] = {0};
  68. StringCbPrintf(generated_guid, sizeof(generated_guid), L"%s%s", channel.title, newItem.itemName);
  69. newItem.SetGUID(generated_guid);
  70. }
  71. const wchar_t *description = GetContent(item, L"description");
  72. if (!description || !description[0])
  73. description = GetContent(item, L"content:encoded");
  74. newItem.SetDescription(description);
  75. const wchar_t *duration = GetContent(item, L"itunes:duration");
  76. if (duration && duration[0])
  77. newItem.SetDuration(duration);
  78. if (newItem.itemName && newItem.itemName[0])
  79. {
  80. channel.items.push_back(newItem);
  81. }
  82. }
  83. void ReadWinampSpecificChannel(const XMLNode *node, Channel &newChannel)
  84. {
  85. const XMLNode *curNode = 0;
  86. const wchar_t *lastupdate = node->GetProperty(L"winamp:lastupdate");
  87. if (lastupdate && lastupdate[0])
  88. newChannel.lastUpdate = MakeRFCDate(lastupdate);
  89. const wchar_t *winamp_url = GetContent(node, L"winamp:url");
  90. newChannel.SetURL(winamp_url);
  91. // set to preference value first
  92. newChannel.updateTime = updateTime;
  93. newChannel.autoUpdate = autoUpdate;
  94. newChannel.autoDownload = autoDownload;
  95. newChannel.autoDownloadEpisodes = autoDownloadEpisodes;
  96. curNode = node->Get(L"winamp:update");
  97. if (curNode)
  98. {
  99. newChannel.useDefaultUpdate = PropertyIsTrue(curNode, L"usedefaultupdate");
  100. newChannel.needsRefresh = PropertyIsTrue(curNode, L"needsrefresh");
  101. if (!newChannel.useDefaultUpdate)
  102. {
  103. newChannel.updateTime = _wtoi64(curNode->GetProperty(L"updatetime"));
  104. newChannel.autoUpdate = PropertyIsTrue(curNode, L"autoupdate");
  105. }
  106. }
  107. curNode = node->Get(L"winamp:download");
  108. if (curNode)
  109. {
  110. newChannel.autoDownload = PropertyIsTrue(curNode, L"autodownload");
  111. if (newChannel.autoDownload)
  112. {
  113. const wchar_t *prop = curNode->GetProperty(L"autoDownloadEpisodes");
  114. if (prop)
  115. newChannel.autoDownloadEpisodes = _wtoi(prop);
  116. }
  117. }
  118. }
  119. static void ReadRSSChannel(const XMLNode *node, Channel &newChannel, bool doWinampSpecificTags)
  120. {
  121. XMLNode::NodeList::const_iterator itemItr;
  122. if (doWinampSpecificTags)
  123. ReadWinampSpecificChannel(node, newChannel);
  124. const wchar_t *title = GetContent(node, L"title");
  125. newChannel.SetTitle(title);
  126. const wchar_t *link = GetContent(node, L"link");
  127. newChannel.SetLink(link);
  128. const wchar_t *description = GetContent(node, L"description");
  129. newChannel.SetDescription(description);
  130. const wchar_t *ttl = GetContent(node, L"ttl");
  131. if (ttl)
  132. newChannel.ttl = _wtoi(ttl);
  133. const XMLNode::NodeList *items = node->GetList(L"item");
  134. if (items)
  135. {
  136. for (itemItr = items->begin(); itemItr != items->end(); itemItr++)
  137. ReadRSSItem(*itemItr, newChannel, doWinampSpecificTags);
  138. }
  139. }
  140. void ReadRSS(const XMLNode *rss, ChannelSync *sync, bool doWinampSpecificTags, const wchar_t *url)
  141. {
  142. XMLNode::NodeList::const_iterator itr;
  143. sync->BeginChannelSync();
  144. const XMLNode::NodeList *channelList = rss->GetList(L"channel");
  145. if (channelList)
  146. {
  147. for (itr = channelList->begin(); itr != channelList->end(); itr ++)
  148. {
  149. Channel newChannel;
  150. ReadRSSChannel(*itr, newChannel, doWinampSpecificTags);
  151. if (!newChannel.url || !newChannel.url[0])
  152. newChannel.SetURL(url);
  153. sync->NewChannel(newChannel);
  154. }
  155. }
  156. sync->EndChannelSync();
  157. }