2020-12-30 22:07:54 -06:00
|
|
|
/*
|
|
|
|
* Copyright 2020, Jaidyn Levesque <jadedctrl@teknik.io>
|
|
|
|
* All rights reserved. Distributed under the terms of the MIT license.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "Feed.h"
|
|
|
|
|
2021-01-24 23:20:11 -06:00
|
|
|
#include <File.h>
|
|
|
|
|
2020-07-08 03:20:03 -05:00
|
|
|
#include <tinyxml2.h>
|
2020-12-30 22:07:54 -06:00
|
|
|
|
2020-11-16 20:32:58 -06:00
|
|
|
#include "App.h"
|
2020-07-08 03:20:03 -05:00
|
|
|
#include "Entry.h"
|
|
|
|
#include "Util.h"
|
|
|
|
|
2020-12-30 22:07:54 -06:00
|
|
|
|
2021-01-11 18:08:15 -06:00
|
|
|
Feed::Feed(BUrl xml, BString path)
|
|
|
|
: Feed()
|
|
|
|
{
|
2021-01-12 15:30:21 -06:00
|
|
|
SetXmlUrl(xml);
|
|
|
|
SetCachePath(path);
|
2021-01-11 18:08:15 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Feed::Feed(BUrl xml)
|
|
|
|
: Feed()
|
2020-07-08 03:20:03 -05:00
|
|
|
{
|
2021-01-12 15:30:21 -06:00
|
|
|
SetXmlUrl(xml);
|
2021-01-11 18:08:15 -06:00
|
|
|
BString cache("/boot/home/config/cache/Pogger/");
|
|
|
|
cache.Append(urlToFilename(xmlUrl));
|
|
|
|
SetCachePath(cache);
|
2020-07-08 03:20:03 -05:00
|
|
|
}
|
|
|
|
|
2020-12-30 22:07:54 -06:00
|
|
|
|
2021-01-13 20:23:21 -06:00
|
|
|
// For pre-existing feed
|
2021-01-12 15:30:21 -06:00
|
|
|
Feed::Feed(BEntry entry)
|
|
|
|
: Feed()
|
|
|
|
{
|
|
|
|
BFile file(&entry, B_READ_ONLY);
|
|
|
|
BPath path;
|
|
|
|
entry.GetPath(&path);
|
|
|
|
SetCachePath(BString(path.Path()));
|
|
|
|
|
2021-01-13 20:23:21 -06:00
|
|
|
BString name;
|
2021-01-12 15:30:21 -06:00
|
|
|
BString url;
|
|
|
|
file.ReadAttrString("META:url", &url);
|
2021-01-13 20:23:21 -06:00
|
|
|
file.ReadAttrString("Feed:name", &name);
|
|
|
|
|
|
|
|
if (!url.IsEmpty())
|
|
|
|
SetXmlUrl(BUrl(url));
|
|
|
|
if (!name.IsEmpty())
|
|
|
|
SetTitle(name);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// For new feed
|
|
|
|
Feed::Feed(BUrl xml, BEntry entry)
|
|
|
|
: Feed()
|
|
|
|
{
|
|
|
|
BPath path;
|
|
|
|
BString pathString;
|
|
|
|
entry.GetPath(&path);
|
|
|
|
pathString = path.Path();
|
|
|
|
|
|
|
|
if (entry.IsDirectory())
|
|
|
|
pathString += BString(urlToFilename(xml));
|
|
|
|
|
|
|
|
SetCachePath(pathString);
|
|
|
|
SetXmlUrl(xml);
|
2021-01-12 15:30:21 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-01-09 16:53:39 -06:00
|
|
|
Feed::Feed(Feed* feed)
|
|
|
|
: Feed()
|
|
|
|
{
|
2021-01-11 18:08:15 -06:00
|
|
|
SetTitle(feed->GetTitle());
|
|
|
|
SetXmlUrl(feed->GetXmlUrl());
|
2021-01-09 16:53:39 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-12-30 22:07:54 -06:00
|
|
|
Feed::Feed()
|
2021-01-11 18:08:15 -06:00
|
|
|
:
|
|
|
|
title(BString("Untitled Feed"))
|
2020-08-11 13:29:49 -05:00
|
|
|
{
|
2021-01-11 18:08:15 -06:00
|
|
|
lastDate = BDateTime::CurrentDateTime(B_LOCAL_TIME);
|
2020-07-08 04:43:35 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-02-21 13:16:35 -06:00
|
|
|
Feed::~Feed()
|
|
|
|
{
|
|
|
|
for (int i = entries.CountItems(); i >= 0; i--)
|
|
|
|
delete ((Entry*)entries.RemoveItem(i));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-08-14 14:00:07 -05:00
|
|
|
void
|
2020-12-30 22:07:54 -06:00
|
|
|
Feed::Parse()
|
2020-08-14 14:00:07 -05:00
|
|
|
{
|
2021-01-11 18:08:15 -06:00
|
|
|
BFile feedFile = BFile(cachePath, B_READ_ONLY);
|
2020-12-30 22:07:54 -06:00
|
|
|
time_t tt_lastDate = 0;
|
2020-08-14 14:00:07 -05:00
|
|
|
|
2021-01-12 15:30:21 -06:00
|
|
|
feedFile.ReadAttr("Feed:when", B_TIME_TYPE, 0, &tt_lastDate, sizeof(time_t));
|
2020-12-30 22:07:54 -06:00
|
|
|
|
2021-01-11 18:08:15 -06:00
|
|
|
if (tt_lastDate > 0)
|
|
|
|
lastDate.SetTime_t(tt_lastDate);
|
2020-08-14 14:00:07 -05:00
|
|
|
}
|
|
|
|
|
2020-08-02 02:05:20 -05:00
|
|
|
|
2021-01-15 22:22:33 -06:00
|
|
|
// Download a remote feed's XML to the cache path.
|
|
|
|
bool
|
|
|
|
Feed::Fetch()
|
|
|
|
{
|
|
|
|
BFile cacheFile = BFile(cachePath, B_READ_WRITE | B_CREATE_FILE);
|
|
|
|
|
|
|
|
cacheFile.ReadAttrString("Feed:hash", &lastHash);
|
|
|
|
|
|
|
|
int32 result = fetch(xmlUrl, &cacheFile, &hash, 30);
|
|
|
|
cacheFile.WriteAttrString("Feed:hash", &hash);
|
|
|
|
|
|
|
|
if (result == 0)
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-01-12 15:30:21 -06:00
|
|
|
void
|
2021-01-15 22:22:33 -06:00
|
|
|
Feed::Filetize()
|
2021-01-12 15:30:21 -06:00
|
|
|
{
|
2021-01-15 22:22:33 -06:00
|
|
|
BFile feedFile(cachePath, B_WRITE_ONLY | B_CREATE_FILE);
|
2021-01-12 15:30:21 -06:00
|
|
|
time_t tt_date = date.Time_t();
|
|
|
|
BString url = xmlUrl.UrlString();
|
|
|
|
BString name = GetTitle();
|
|
|
|
BString type("application/x-feed-source");
|
|
|
|
|
|
|
|
feedFile.WriteAttrString("Feed:name", &name);
|
|
|
|
feedFile.WriteAttrString("META:url", &url);
|
|
|
|
feedFile.WriteAttrString("BEOS:TYPE", &type);
|
|
|
|
feedFile.WriteAttr("Feed:when", B_TIME_TYPE, 0, &tt_date, sizeof(time_t));
|
|
|
|
feedFile.WriteAttr("BEOS:TYPE", B_MIME_STRING_TYPE, 0, type.String(),
|
|
|
|
type.CountChars() + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-01-15 22:22:33 -06:00
|
|
|
void
|
|
|
|
Feed::Unfiletize()
|
2020-08-02 02:05:20 -05:00
|
|
|
{
|
2021-01-15 22:22:33 -06:00
|
|
|
BEntry entry(GetCachePath().String());
|
|
|
|
entry.Remove();
|
2020-11-16 21:32:06 -06:00
|
|
|
}
|
|
|
|
|
2020-12-30 22:07:54 -06:00
|
|
|
|
2020-07-08 04:43:35 -05:00
|
|
|
bool
|
2021-01-11 18:08:15 -06:00
|
|
|
Feed::IsRss()
|
2020-07-08 04:43:35 -05:00
|
|
|
{
|
|
|
|
tinyxml2::XMLDocument xml;
|
2021-01-11 18:08:15 -06:00
|
|
|
xml.LoadFile(cachePath.String());
|
2020-07-08 04:43:35 -05:00
|
|
|
|
2020-12-30 22:07:54 -06:00
|
|
|
if (xml.FirstChildElement("rss"))
|
2020-07-08 04:43:35 -05:00
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-12-30 22:07:54 -06:00
|
|
|
|
2020-07-08 04:43:35 -05:00
|
|
|
bool
|
2021-01-11 18:08:15 -06:00
|
|
|
Feed::IsAtom()
|
2020-07-08 04:43:35 -05:00
|
|
|
{
|
|
|
|
tinyxml2::XMLDocument xml;
|
2021-01-11 18:08:15 -06:00
|
|
|
xml.LoadFile(cachePath.String());
|
2020-07-08 04:43:35 -05:00
|
|
|
|
2020-12-30 22:07:54 -06:00
|
|
|
if (xml.FirstChildElement("feed"))
|
2020-07-08 04:43:35 -05:00
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-01-11 18:08:15 -06:00
|
|
|
bool
|
|
|
|
Feed::IsUpdated()
|
2020-11-16 21:32:06 -06:00
|
|
|
{
|
2021-01-11 18:08:15 -06:00
|
|
|
return lastHash != hash;
|
2020-11-16 21:32:06 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-01-09 16:53:39 -06:00
|
|
|
// Count the amount of siblings to an element of given type name
|
2020-07-08 04:43:35 -05:00
|
|
|
int
|
2020-12-30 22:07:54 -06:00
|
|
|
Feed::xmlCountSiblings (tinyxml2::XMLElement* xsibling, const char* sibling_name)
|
2020-07-08 03:20:03 -05:00
|
|
|
{
|
2020-07-08 04:43:35 -05:00
|
|
|
int count = 0;
|
2020-12-30 22:07:54 -06:00
|
|
|
while (xsibling) {
|
2020-07-08 04:43:35 -05:00
|
|
|
count++;
|
|
|
|
xsibling = xsibling->NextSiblingElement(sibling_name);
|
|
|
|
}
|
|
|
|
return count;
|
2020-07-08 03:20:03 -05:00
|
|
|
}
|
|
|
|
|
2020-07-08 04:43:35 -05:00
|
|
|
|
2020-08-14 01:59:15 -05:00
|
|
|
bool
|
2020-12-30 22:07:54 -06:00
|
|
|
Feed::AddEntry (Entry* newEntry)
|
2020-08-14 01:59:15 -05:00
|
|
|
{
|
2020-12-30 22:07:54 -06:00
|
|
|
entries.AddItem(newEntry);
|
2020-08-14 01:59:15 -05:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-12-30 22:07:54 -06:00
|
|
|
|
|
|
|
BList
|
|
|
|
Feed::GetEntries()
|
|
|
|
{
|
|
|
|
return entries;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-01-11 18:08:15 -06:00
|
|
|
BList
|
|
|
|
Feed::GetNewEntries()
|
|
|
|
{
|
|
|
|
BList newEntries;
|
|
|
|
for (int i = 0; i < entries.CountItems(); i++) {
|
|
|
|
Entry* entry = ((Entry*)entries.ItemAt(i));
|
|
|
|
if (entry->GetDate() > lastDate)
|
|
|
|
newEntries.AddItem(entry);
|
|
|
|
}
|
|
|
|
|
|
|
|
return newEntries;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-12-30 22:07:54 -06:00
|
|
|
bool
|
|
|
|
Feed::SetTitle(const char* titleStr)
|
|
|
|
{
|
|
|
|
if (titleStr != NULL)
|
|
|
|
title = BString(titleStr);
|
2020-07-08 03:20:03 -05:00
|
|
|
else return false;
|
|
|
|
return true;
|
|
|
|
}
|
2020-12-30 22:07:54 -06:00
|
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
Feed::SetTitle(tinyxml2::XMLElement* elem)
|
|
|
|
{
|
|
|
|
if (elem != NULL)
|
|
|
|
return SetTitle(elem->GetText());
|
2020-07-08 03:20:03 -05:00
|
|
|
else return false;
|
|
|
|
}
|
|
|
|
|
2020-12-30 22:07:54 -06:00
|
|
|
|
|
|
|
BString
|
|
|
|
Feed::GetTitle()
|
|
|
|
{
|
|
|
|
return title;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool
|
2021-01-11 18:08:15 -06:00
|
|
|
Feed::SetXmlUrl(BUrl newUrl)
|
2020-12-30 22:07:54 -06:00
|
|
|
{
|
2021-01-11 18:08:15 -06:00
|
|
|
xmlUrl = newUrl;
|
2020-07-08 03:20:03 -05:00
|
|
|
return true;
|
|
|
|
}
|
2020-12-30 22:07:54 -06:00
|
|
|
|
|
|
|
|
2021-01-11 18:08:15 -06:00
|
|
|
BUrl
|
|
|
|
Feed::GetXmlUrl()
|
2020-12-30 22:07:54 -06:00
|
|
|
{
|
2021-01-11 18:08:15 -06:00
|
|
|
return xmlUrl;
|
2020-12-30 22:07:54 -06:00
|
|
|
}
|
|
|
|
|
2020-07-08 03:20:03 -05:00
|
|
|
|
2020-12-30 22:07:54 -06:00
|
|
|
bool
|
2021-01-11 18:08:15 -06:00
|
|
|
Feed::SetCachePath(BString path)
|
2020-12-30 22:07:54 -06:00
|
|
|
{
|
2021-01-11 18:08:15 -06:00
|
|
|
cachePath = path;
|
2020-07-08 03:20:03 -05:00
|
|
|
return true;
|
|
|
|
}
|
2020-12-30 22:07:54 -06:00
|
|
|
|
|
|
|
|
|
|
|
BString
|
2021-01-11 18:08:15 -06:00
|
|
|
Feed::GetCachePath()
|
2020-12-30 22:07:54 -06:00
|
|
|
{
|
2021-01-11 18:08:15 -06:00
|
|
|
return cachePath;
|
2020-12-30 22:07:54 -06:00
|
|
|
}
|
|
|
|
|
2020-07-08 03:20:03 -05:00
|
|
|
|
2021-01-11 18:08:15 -06:00
|
|
|
// Set the latest date given by feed (from entry or from root)
|
|
|
|
bool
|
|
|
|
Feed::SetDate(BDateTime newDate)
|
2021-01-09 16:53:39 -06:00
|
|
|
{
|
2021-01-11 18:08:15 -06:00
|
|
|
if (newDate == NULL)
|
|
|
|
return false;
|
|
|
|
date = newDate;
|
|
|
|
return true;
|
2021-01-09 16:53:39 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-12-30 22:07:54 -06:00
|
|
|
bool
|
|
|
|
Feed::SetDate(const char* dateCStr)
|
|
|
|
{
|
|
|
|
if (dateCStr == NULL)
|
2020-07-08 03:20:03 -05:00
|
|
|
return false;
|
2021-01-11 18:08:15 -06:00
|
|
|
SetDate(feedDateToBDate(dateCStr));
|
2020-07-08 03:20:03 -05:00
|
|
|
return true;
|
|
|
|
}
|
2020-12-30 22:07:54 -06:00
|
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
Feed::SetDate(tinyxml2::XMLElement* elem)
|
|
|
|
{
|
|
|
|
if (elem != NULL)
|
|
|
|
return SetDate(elem->GetText());
|
2020-07-08 03:20:03 -05:00
|
|
|
else return false;
|
|
|
|
}
|
2020-12-30 22:07:54 -06:00
|
|
|
|
|
|
|
|
|
|
|
BDateTime
|
|
|
|
Feed::GetDate()
|
|
|
|
{
|
|
|
|
return date;
|
|
|
|
}
|
|
|
|
|
2020-07-08 04:43:35 -05:00
|
|
|
|