Pogger/src/Feed.cpp

324 lines
4.7 KiB
C++
Raw Normal View History

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>
2021-04-20 20:00:37 -05:00
#include <FindDirectory.h>
2021-01-24 23:20:11 -06:00
#include <tinyxml2.h>
2020-12-30 22:07:54 -06: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()
{
2021-01-12 15:30:21 -06:00
SetXmlUrl(xml);
BPath cache;
find_directory(B_USER_CACHE_DIRECTORY, &cache);
cache.Append("Pogger");
2021-03-20 18:45:37 -05:00
cache.Append(urlToFilename(fXmlUrl));
SetCachePath(cache.Path());
}
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-03-23 10:39:31 -05:00
BString name, url;
2021-01-12 15:30:21 -06:00
file.ReadAttrString("META:url", &url);
2021-01-13 20:23:21 -06:00
file.ReadAttrString("Feed:name", &name);
2021-03-23 10:39:31 -05:00
file.ReadAttrString("Feed:hash", &fLastHash);
2021-01-13 20:23:21 -06:00
if (!url.IsEmpty())
SetXmlUrl(BUrl(url));
if (!name.IsEmpty())
SetTitle(name);
}
2021-03-06 12:36:33 -06:00
Feed::Feed(const char* pathStr)
: Feed(BEntry(pathStr))
{
}
2021-01-13 20:23:21 -06:00
// 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-03-20 18:45:37 -05:00
SetTitle(feed->Title());
SetXmlUrl(feed->XmlUrl());
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
:
2021-03-21 14:21:14 -05:00
fTitle(BString(""))
{
2021-03-20 18:45:37 -05:00
fLastDate = BDateTime::CurrentDateTime(B_LOCAL_TIME);
}
Feed::~Feed()
{
}
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-03-20 18:45:37 -05:00
BFile feedFile = BFile(fCachePath, 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)
2021-03-20 18:45:37 -05:00
fLastDate.SetTime_t(tt_lastDate);
2020-08-14 14:00:07 -05:00
}
2021-01-15 22:22:33 -06:00
// Download a remote feed's XML to the cache path.
bool
Feed::Fetch()
{
2021-03-20 18:45:37 -05:00
BFile cacheFile = BFile(fCachePath, B_READ_WRITE | B_CREATE_FILE);
2021-01-15 22:22:33 -06:00
2021-03-20 18:45:37 -05:00
int32 result = fetch(fXmlUrl, &cacheFile, &fHash, 30);
cacheFile.WriteAttrString("Feed:hash", &fHash);
2021-01-15 22:22:33 -06:00
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-03-20 18:45:37 -05:00
BFile feedFile(fCachePath, B_WRITE_ONLY | B_CREATE_FILE);
time_t tt_date = fDate.Time_t();
BString url = fXmlUrl.UrlString();
BString name = Title();
2021-01-12 15:30:21 -06:00
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()
{
2021-03-20 18:45:37 -05:00
BEntry entry(CachePath().String());
2021-01-15 22:22:33 -06:00
entry.Remove();
}
2020-12-30 22:07:54 -06:00
bool
2021-01-11 18:08:15 -06:00
Feed::IsRss()
{
tinyxml2::XMLDocument xml;
2021-03-20 18:45:37 -05:00
xml.LoadFile(fCachePath.String());
2020-12-30 22:07:54 -06:00
if (xml.FirstChildElement("rss"))
return true;
return false;
}
2020-12-30 22:07:54 -06:00
bool
2021-01-11 18:08:15 -06:00
Feed::IsAtom()
{
tinyxml2::XMLDocument xml;
2021-03-20 18:45:37 -05:00
xml.LoadFile(fCachePath.String());
2020-12-30 22:07:54 -06:00
if (xml.FirstChildElement("feed"))
return true;
return false;
}
2021-01-11 18:08:15 -06:00
bool
Feed::IsUpdated()
{
2021-03-20 18:45:37 -05:00
return fLastHash != fHash;
}
2021-01-09 16:53:39 -06:00
// Count the amount of siblings to an element of given type name
int
2021-03-20 18:45:37 -05:00
Feed::_XmlCountSiblings (tinyxml2::XMLElement* xsibling, const char* sibling_name)
{
int count = 0;
2020-12-30 22:07:54 -06:00
while (xsibling) {
count++;
xsibling = xsibling->NextSiblingElement(sibling_name);
}
return count;
}
2020-08-14 01:59:15 -05:00
bool
2021-03-20 18:45:37 -05:00
Feed::_AddEntry (Entry* newEntry)
2020-08-14 01:59:15 -05:00
{
2021-03-20 18:45:37 -05:00
fEntries.AddItem(newEntry);
2020-08-14 01:59:15 -05:00
return true;
}
2020-12-30 22:07:54 -06:00
2021-03-04 18:31:47 -06:00
BObjectList<Entry>
2021-03-20 18:45:37 -05:00
Feed::Entries()
2020-12-30 22:07:54 -06:00
{
2021-03-20 18:45:37 -05:00
return fEntries;
2020-12-30 22:07:54 -06:00
}
2021-03-04 18:31:47 -06:00
BObjectList<Entry>
2021-03-20 18:45:37 -05:00
Feed::NewEntries()
2021-01-11 18:08:15 -06:00
{
2021-03-04 18:31:47 -06:00
BObjectList<Entry> newEntries;
2021-03-20 18:45:37 -05:00
for (int i = 0; i < fEntries.CountItems(); i++) {
Entry* entry = fEntries.ItemAt(i);
if (entry->Date() > fLastDate)
2021-01-11 18:08:15 -06:00
newEntries.AddItem(entry);
}
return newEntries;
}
2020-12-30 22:07:54 -06:00
bool
Feed::SetTitle(const char* titleStr)
{
if (titleStr != NULL)
2021-03-20 18:45:37 -05:00
fTitle = BString(titleStr);
else return false;
return true;
}
2020-12-30 22:07:54 -06:00
bool
2021-03-20 18:45:37 -05:00
Feed::_SetTitle(tinyxml2::XMLElement* elem)
2020-12-30 22:07:54 -06:00
{
2021-03-21 14:21:14 -05:00
if (elem != NULL && fTitle.IsEmpty() == true)
2020-12-30 22:07:54 -06:00
return SetTitle(elem->GetText());
else return false;
}
2020-12-30 22:07:54 -06:00
BString
2021-03-20 18:45:37 -05:00
Feed::Title()
2020-12-30 22:07:54 -06:00
{
2021-03-20 18:45:37 -05:00
return fTitle;
2020-12-30 22:07:54 -06:00
}
bool
2021-01-11 18:08:15 -06:00
Feed::SetXmlUrl(BUrl newUrl)
2020-12-30 22:07:54 -06:00
{
2021-03-20 18:45:37 -05:00
fXmlUrl = newUrl;
return true;
}
2020-12-30 22:07:54 -06:00
2021-01-11 18:08:15 -06:00
BUrl
2021-03-20 18:45:37 -05:00
Feed::XmlUrl()
2020-12-30 22:07:54 -06:00
{
2021-03-20 18:45:37 -05:00
return fXmlUrl;
2020-12-30 22:07:54 -06: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-03-20 18:45:37 -05:00
fCachePath = path;
return true;
}
2020-12-30 22:07:54 -06:00
BString
2021-03-20 18:45:37 -05:00
Feed::CachePath()
2020-12-30 22:07:54 -06:00
{
2021-03-20 18:45:37 -05:00
return fCachePath;
2020-12-30 22:07:54 -06:00
}
2021-01-11 18:08:15 -06:00
// Set the latest date given by feed (from entry or from root)
bool
2021-03-20 18:45:37 -05:00
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;
2021-03-20 18:45:37 -05:00
fDate = newDate;
2021-01-11 18:08:15 -06:00
return true;
2021-01-09 16:53:39 -06:00
}
2020-12-30 22:07:54 -06:00
bool
2021-03-20 18:45:37 -05:00
Feed::_SetDate(const char* dateCStr)
2020-12-30 22:07:54 -06:00
{
if (dateCStr == NULL)
return false;
2021-03-20 18:45:37 -05:00
_SetDate(feedDateToBDate(dateCStr));
return true;
}
2020-12-30 22:07:54 -06:00
bool
2021-03-20 18:45:37 -05:00
Feed::_SetDate(tinyxml2::XMLElement* elem)
2020-12-30 22:07:54 -06:00
{
if (elem != NULL)
2021-03-20 18:45:37 -05:00
return _SetDate(elem->GetText());
else return false;
}
2020-12-30 22:07:54 -06:00
BDateTime
2021-03-20 18:45:37 -05:00
Feed::Date()
2020-12-30 22:07:54 -06:00
{
2021-03-20 18:45:37 -05:00
return fDate;
2020-12-30 22:07:54 -06:00
}