Add subscription Feed files

This commit is contained in:
Jaidyn Ann 2021-01-12 15:30:21 -06:00
parent 7ab7cb35fd
commit 17d45ae9ec
10 changed files with 113 additions and 24 deletions

View File

@ -25,7 +25,7 @@ int
main(int argc, char** argv) main(int argc, char** argv)
{ {
App* app = new App(); App* app = new App();
feedMimeType(); installMimeTypes();
app->cfg = new Config; app->cfg = new Config;
app->cfg->Load(); app->cfg->Load();
@ -57,6 +57,11 @@ App::MessageReceived(BMessage* msg)
fFeedController->MessageReceived(msg); fFeedController->MessageReceived(msg);
break; break;
} }
case kUpdateSubscribed:
{
fFeedController->MessageReceived(msg);
break;
}
case kClearQueue: case kClearQueue:
{ {
break; break;

View File

@ -16,7 +16,6 @@
AtomFeed::AtomFeed() AtomFeed::AtomFeed()
{ {
title = BString("Untitled Feed"); title = BString("Untitled Feed");
xmlUrl = BString("");
cachePath = BString(""); cachePath = BString("");
} }
@ -24,6 +23,7 @@ AtomFeed::AtomFeed()
AtomFeed::AtomFeed(Feed* feed) AtomFeed::AtomFeed(Feed* feed)
: AtomFeed::AtomFeed() : AtomFeed::AtomFeed()
{ {
SetXmlUrl(feed->GetXmlUrl());
SetCachePath(feed->GetCachePath()); SetCachePath(feed->GetCachePath());
} }
@ -42,10 +42,7 @@ AtomFeed::Parse ()
RootParse(xfeed); RootParse(xfeed);
ParseEntries(xfeed); ParseEntries(xfeed);
BFile* feedFile = new BFile(cachePath, B_READ_WRITE); _PostParse();
time_t tt_date = date.Time_t();
feedFile->WriteAttr("LastDate", B_TIME_TYPE, 0, &tt_date,
sizeof(time_t));
} }

View File

@ -16,21 +16,35 @@
Feed::Feed(BUrl xml, BString path) Feed::Feed(BUrl xml, BString path)
: Feed() : Feed()
{ {
xmlUrl = xml; SetXmlUrl(xml);
cachePath = path; SetCachePath(path);
} }
Feed::Feed(BUrl xml) Feed::Feed(BUrl xml)
: Feed() : Feed()
{ {
xmlUrl = xml; SetXmlUrl(xml);
BString cache("/boot/home/config/cache/Pogger/"); BString cache("/boot/home/config/cache/Pogger/");
cache.Append(urlToFilename(xmlUrl)); cache.Append(urlToFilename(xmlUrl));
SetCachePath(cache); SetCachePath(cache);
} }
Feed::Feed(BEntry entry)
: Feed()
{
BFile file(&entry, B_READ_ONLY);
BPath path;
entry.GetPath(&path);
SetCachePath(BString(path.Path()));
BString url;
file.ReadAttrString("META:url", &url);
xmlUrl = BUrl(url);
}
Feed::Feed(Feed* feed) Feed::Feed(Feed* feed)
: Feed() : Feed()
{ {
@ -53,23 +67,41 @@ Feed::Parse()
BFile feedFile = BFile(cachePath, B_READ_ONLY); BFile feedFile = BFile(cachePath, B_READ_ONLY);
time_t tt_lastDate = 0; time_t tt_lastDate = 0;
feedFile.ReadAttr("LastDate", B_TIME_TYPE, 0, &tt_lastDate, sizeof(time_t)); feedFile.ReadAttr("Feed:when", B_TIME_TYPE, 0, &tt_lastDate, sizeof(time_t));
if (tt_lastDate > 0) if (tt_lastDate > 0)
lastDate.SetTime_t(tt_lastDate); lastDate.SetTime_t(tt_lastDate);
} }
void
Feed::_PostParse()
{
BFile feedFile(cachePath, B_WRITE_ONLY);
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);
}
// Download a remote feed's XML to the cache path. // Download a remote feed's XML to the cache path.
BString BString
Feed::Fetch() Feed::Fetch()
{ {
BFile cacheFile = BFile(cachePath, B_READ_WRITE | B_CREATE_FILE); BFile cacheFile = BFile(cachePath, B_READ_WRITE | B_CREATE_FILE);
cacheFile.ReadAttrString("LastHash", &lastHash); cacheFile.ReadAttrString("Feed:hash", &lastHash);
fetch(xmlUrl, &cacheFile, &hash, 30); fetch(xmlUrl, &cacheFile, &hash, 30);
cacheFile.WriteAttrString("LastHash", &hash); cacheFile.WriteAttrString("Feed:hash", &hash);
if (hash == lastHash) if (hash == lastHash)
updated = false; updated = false;

View File

@ -12,6 +12,7 @@
class BDateTime; class BDateTime;
class BEntry;
class BString; class BString;
class BList; class BList;
class BUrl; class BUrl;
@ -21,6 +22,7 @@ class Feed {
public: public:
Feed(BUrl); Feed(BUrl);
Feed(BUrl, BString); Feed(BUrl, BString);
Feed(BEntry);
Feed(Feed*); Feed(Feed*);
Feed(); Feed();
@ -52,6 +54,7 @@ protected:
bool AddEntry(Entry*); bool AddEntry(Entry*);
void _PostParse();
int xmlCountSiblings(tinyxml2::XMLElement*, const char*); int xmlCountSiblings(tinyxml2::XMLElement*, const char*);
BString title; BString title;

View File

@ -54,6 +54,19 @@ FeedController::MessageReceived(BMessage* msg)
} }
break; break;
} }
case kUpdateSubscribed:
{
BDirectory subDir("/boot/home/config/settings/Pogger/Subscriptions");
BEntry feedEntry;
Feed* feed;
while (subDir.GetNextEntry(&feedEntry) == B_OK) {
feed = new Feed(feedEntry);
BMessage* getFeed = new BMessage(kEnqueueFeed);
getFeed->AddData("feeds", B_RAW_TYPE, feed, sizeof(Feed));
((App*)be_app)->MessageReceived(getFeed);
}
}
case kClearQueue: case kClearQueue:
{ {
break; break;
@ -88,7 +101,9 @@ FeedController::_DownloadLoop(void* ignored)
Feed* feedBuffer = new Feed(); Feed* feedBuffer = new Feed();
while (receive_data(&sender, (void*)feedBuffer, sizeof(Feed)) != 0) { while (receive_data(&sender, (void*)feedBuffer, sizeof(Feed)) != 0) {
printf( "%s\n\n", feedBuffer->GetCachePath().String()); printf( "Downloading feed from %s...\n",
feedBuffer->GetXmlUrl().UrlString().String());
feedBuffer->Fetch(); feedBuffer->Fetch();
BMessage* downloaded = new BMessage(kDownloadComplete); BMessage* downloaded = new BMessage(kDownloadComplete);
@ -113,6 +128,9 @@ FeedController::_ParseLoop(void* ignored)
BDirectory outDir = BDirectory(((App*)be_app)->cfg->outDir); BDirectory outDir = BDirectory(((App*)be_app)->cfg->outDir);
if (feedBuffer->IsAtom()) { if (feedBuffer->IsAtom()) {
printf("Parsing Atom feed from %s...\n",
feedBuffer->GetXmlUrl().UrlString().String());
AtomFeed* feed = (AtomFeed*)malloc(sizeof(AtomFeed)); AtomFeed* feed = (AtomFeed*)malloc(sizeof(AtomFeed));
feed = new AtomFeed(feedBuffer); feed = new AtomFeed(feedBuffer);
feed->Parse(); feed->Parse();
@ -120,6 +138,9 @@ FeedController::_ParseLoop(void* ignored)
delete(feed); delete(feed);
} }
else if (feedBuffer->IsRss()) { else if (feedBuffer->IsRss()) {
printf("Parsing RSS feed from %s...\n",
feedBuffer->GetXmlUrl().UrlString().String());
RssFeed* feed = (RssFeed*)malloc(sizeof(RssFeed)); RssFeed* feed = (RssFeed*)malloc(sizeof(RssFeed));
feed = new RssFeed(feedBuffer); feed = new RssFeed(feedBuffer);
feed->Parse(); feed->Parse();

View File

@ -16,7 +16,8 @@ enum
kEnqueueFeed = 'fenq', kEnqueueFeed = 'fenq',
kClearQueue = 'frmq', kClearQueue = 'frmq',
kDownloadComplete = 'fdpr', kDownloadComplete = 'fdpr',
kQueueProgress = 'fqpr' kQueueProgress = 'fqpr',
kUpdateSubscribed = 'fups'
}; };

View File

@ -16,6 +16,7 @@
#include "App.h" #include "App.h"
#include "EntriesView.h" #include "EntriesView.h"
#include "FeedController.h"
#include "FeedsView.h" #include "FeedsView.h"
#include "UpdatesView.h" #include "UpdatesView.h"
@ -63,8 +64,8 @@ MainWindow::_InitInterface()
fBaseView->AddChild(fTabView); fBaseView->AddChild(fTabView);
fUpdateNowButton = new BButton("updateNow", "Update Now", fUpdateNowButton = new BButton("updateNow", "Update Now",
new BMessage('iiii')); new BMessage(kUpdateSubscribed));
fUpdateNowButton->SetTarget(this); fUpdateNowButton->SetTarget((App*)be_app);
fUpdateNowButton->SetExplicitAlignment( fUpdateNowButton->SetExplicitAlignment(
BAlignment(B_ALIGN_RIGHT, B_ALIGN_MIDDLE)); BAlignment(B_ALIGN_RIGHT, B_ALIGN_MIDDLE));

View File

@ -11,9 +11,37 @@
#include <MimeType.h> #include <MimeType.h>
// install the Feed Entry mimetype, if need be bool installMimeTypes()
{
return (feedMimeType() && feedEntryMimeType());
}
bool bool
feedMimeType() feedMimeType()
{
BMessage info;
BMimeType mime("application/x-feed-source");
if (mime.IsInstalled())
return true;
mime.GetAttrInfo(&info);
mime.SetShortDescription("Feed");
mime.SetLongDescription("Atom/RSS Feed");
addAttribute(info, "Feed:name", "Name");
addAttribute(info, "Feed:description", "Description");
addAttribute(info, "META:url", "URL");
addAttribute(info, "Feed:when", "Updated", B_TIME_TYPE, 150);
addAttribute(info, "Feed:hash", "Hash");
return mime.SetAttrInfo(&info);
}
bool
feedEntryMimeType()
{ {
BMessage info; BMessage info;
BMimeType mime("text/x-feed-entry"); BMimeType mime("text/x-feed-entry");
@ -25,11 +53,11 @@ feedMimeType()
mime.SetShortDescription("Feed Entry"); mime.SetShortDescription("Feed Entry");
mime.SetLongDescription("Atom/RSS Feed Entry"); mime.SetLongDescription("Atom/RSS Feed Entry");
addAttribute(info, "FEED:name", "Name"); addAttribute(info, "Feed:name", "Name");
addAttribute(info, "FEED:description", "Description"); addAttribute(info, "Feed:description", "Description");
addAttribute(info, "META:url", "URL"); addAttribute(info, "META:url", "URL");
addAttribute(info, "FEED:source", "Source"); addAttribute(info, "Feed:source", "Source");
addAttribute(info, "FEED:when", "When", B_TIME_TYPE, 150); addAttribute(info, "Feed:when", "When", B_TIME_TYPE, 150);
return mime.SetAttrInfo(&info); return mime.SetAttrInfo(&info);
} }

View File

@ -12,7 +12,9 @@
class BMessage; class BMessage;
bool installMimeTypes();
bool feedMimeType(); bool feedMimeType();
bool feedEntryMimeType();
static void addAttribute(BMessage&, const char*, const char*, static void addAttribute(BMessage&, const char*, const char*,
int32 type = B_STRING_TYPE, int32 width = 200); int32 type = B_STRING_TYPE, int32 width = 200);

View File

@ -21,6 +21,7 @@ RssFeed::RssFeed()
RssFeed::RssFeed(Feed* feed) RssFeed::RssFeed(Feed* feed)
: RssFeed::RssFeed() : RssFeed::RssFeed()
{ {
SetXmlUrl(feed->GetXmlUrl());
SetCachePath(feed->GetCachePath()); SetCachePath(feed->GetCachePath());
} }
@ -39,9 +40,7 @@ RssFeed::Parse()
RootParse(xchan); RootParse(xchan);
ParseEntries(xchan); ParseEntries(xchan);
time_t tt_date = date.Time_t(); _PostParse();
BFile* feedFile = new BFile(cachePath, B_READ_ONLY);
feedFile->WriteAttr("LastDate", B_TIME_TYPE, 0, &tt_date, sizeof(time_t));
} }