winamp/Src/Plugins/Library/ml_wire/RSSParse.cpp
2024-09-24 14:54:57 +02:00

181 lines
4.9 KiB
C++

#include "Main.h"
#include "RSSParse.h"
#include "RFCDate.h"
#include "../xml/XMLNode.h"
#include "Feeds.h"
#include "Defaults.h"
#include "ChannelSync.h"
#include "ParseUtil.h"
#include <strsafe.h>
static void ReadWinampSpecificItem(const XMLNode *item, RSS::Item &newItem)
{
newItem.listened = PropertyIsTrue(item, L"winamp:listened");
newItem.downloaded = PropertyIsTrue(item, L"winamp:downloaded");
}
static void ReadRSSItem(XMLNode *item, Channel &channel, bool doWinampSpecificTags)
{
RSS::MutableItem newItem;
if (doWinampSpecificTags)
ReadWinampSpecificItem(item, newItem);
const wchar_t *pubdate = GetContent(item, L"pubDate");
if (pubdate && pubdate[0])
{
newItem.publishDate = MakeRFCDate(pubdate);
if (newItem.publishDate <= 0)
{
newItem.publishDate = _time64(0);
newItem.generatedDate = true;
}
else
newItem.generatedDate = false;
}
else
{
newItem.publishDate = _time64(0);
newItem.generatedDate = true;
}
const wchar_t *itemName = GetContent(item, L"title");
if (itemName && itemName[0])
newItem.SetItemName(itemName);
else
{
wchar_t date_str[128] = {0};
MakeRFCDateString(newItem.publishDate, date_str, 128);
newItem.SetItemName(date_str);
}
newItem.SetLink(GetContent(item, L"link"));
newItem.SetURL(GetProperty(item, L"enclosure", L"url"));
const wchar_t* src = GetProperty(item, L"source", L"src");
if (!src || !src[0])
{
newItem.SetSourceURL(GetProperty(item, L"source", L"url"));
}
else
{
newItem.SetSourceURL(src/*GetProperty(item, L"source", L"src")*/);
}
newItem.SetSize(GetProperty(item, L"enclosure", L"length"));
const wchar_t *guid = GetContent(item, L"guid");
if (!guid || !guid[0])
guid = GetProperty(item, L"enclosure", L"url");
if (guid && guid[0])
{
newItem.SetGUID(guid);
}
else
{
wchar_t generated_guid[160] = {0};
StringCbPrintf(generated_guid, sizeof(generated_guid), L"%s%s", channel.title, newItem.itemName);
newItem.SetGUID(generated_guid);
}
const wchar_t *description = GetContent(item, L"description");
if (!description || !description[0])
description = GetContent(item, L"content:encoded");
newItem.SetDescription(description);
const wchar_t *duration = GetContent(item, L"itunes:duration");
if (duration && duration[0])
newItem.SetDuration(duration);
if (newItem.itemName && newItem.itemName[0])
{
channel.items.push_back(newItem);
}
}
void ReadWinampSpecificChannel(const XMLNode *node, Channel &newChannel)
{
const XMLNode *curNode = 0;
const wchar_t *lastupdate = node->GetProperty(L"winamp:lastupdate");
if (lastupdate && lastupdate[0])
newChannel.lastUpdate = MakeRFCDate(lastupdate);
const wchar_t *winamp_url = GetContent(node, L"winamp:url");
newChannel.SetURL(winamp_url);
// set to preference value first
newChannel.updateTime = updateTime;
newChannel.autoUpdate = autoUpdate;
newChannel.autoDownload = autoDownload;
newChannel.autoDownloadEpisodes = autoDownloadEpisodes;
curNode = node->Get(L"winamp:update");
if (curNode)
{
newChannel.useDefaultUpdate = PropertyIsTrue(curNode, L"usedefaultupdate");
newChannel.needsRefresh = PropertyIsTrue(curNode, L"needsrefresh");
if (!newChannel.useDefaultUpdate)
{
newChannel.updateTime = _wtoi64(curNode->GetProperty(L"updatetime"));
newChannel.autoUpdate = PropertyIsTrue(curNode, L"autoupdate");
}
}
curNode = node->Get(L"winamp:download");
if (curNode)
{
newChannel.autoDownload = PropertyIsTrue(curNode, L"autodownload");
if (newChannel.autoDownload)
{
const wchar_t *prop = curNode->GetProperty(L"autoDownloadEpisodes");
if (prop)
newChannel.autoDownloadEpisodes = _wtoi(prop);
}
}
}
static void ReadRSSChannel(const XMLNode *node, Channel &newChannel, bool doWinampSpecificTags)
{
XMLNode::NodeList::const_iterator itemItr;
if (doWinampSpecificTags)
ReadWinampSpecificChannel(node, newChannel);
const wchar_t *title = GetContent(node, L"title");
newChannel.SetTitle(title);
const wchar_t *link = GetContent(node, L"link");
newChannel.SetLink(link);
const wchar_t *description = GetContent(node, L"description");
newChannel.SetDescription(description);
const wchar_t *ttl = GetContent(node, L"ttl");
if (ttl)
newChannel.ttl = _wtoi(ttl);
const XMLNode::NodeList *items = node->GetList(L"item");
if (items)
{
for (itemItr = items->begin(); itemItr != items->end(); itemItr++)
ReadRSSItem(*itemItr, newChannel, doWinampSpecificTags);
}
}
void ReadRSS(const XMLNode *rss, ChannelSync *sync, bool doWinampSpecificTags, const wchar_t *url)
{
XMLNode::NodeList::const_iterator itr;
sync->BeginChannelSync();
const XMLNode::NodeList *channelList = rss->GetList(L"channel");
if (channelList)
{
for (itr = channelList->begin(); itr != channelList->end(); itr ++)
{
Channel newChannel;
ReadRSSChannel(*itr, newChannel, doWinampSpecificTags);
if (!newChannel.url || !newChannel.url[0])
newChannel.SetURL(url);
sync->NewChannel(newChannel);
}
}
sync->EndChannelSync();
}