From 17d45ae9ec6c47ff29f3d68767547afabc2f1600 Mon Sep 17 00:00:00 2001 From: Jaidyn Ann Date: Tue, 12 Jan 2021 15:30:21 -0600 Subject: [PATCH] Add subscription Feed files --- src/App.cpp | 7 ++++++- src/AtomFeed.cpp | 7 ++----- src/Feed.cpp | 44 ++++++++++++++++++++++++++++++++++++------ src/Feed.h | 3 +++ src/FeedController.cpp | 23 +++++++++++++++++++++- src/FeedController.h | 3 ++- src/MainWindow.cpp | 5 +++-- src/Mimetypes.cpp | 38 +++++++++++++++++++++++++++++++----- src/Mimetypes.h | 2 ++ src/RssFeed.cpp | 5 ++--- 10 files changed, 113 insertions(+), 24 deletions(-) diff --git a/src/App.cpp b/src/App.cpp index 8b66fd8..660f564 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -25,7 +25,7 @@ int main(int argc, char** argv) { App* app = new App(); - feedMimeType(); + installMimeTypes(); app->cfg = new Config; app->cfg->Load(); @@ -57,6 +57,11 @@ App::MessageReceived(BMessage* msg) fFeedController->MessageReceived(msg); break; } + case kUpdateSubscribed: + { + fFeedController->MessageReceived(msg); + break; + } case kClearQueue: { break; diff --git a/src/AtomFeed.cpp b/src/AtomFeed.cpp index 83b8cac..db3f6c9 100644 --- a/src/AtomFeed.cpp +++ b/src/AtomFeed.cpp @@ -16,7 +16,6 @@ AtomFeed::AtomFeed() { title = BString("Untitled Feed"); - xmlUrl = BString(""); cachePath = BString(""); } @@ -24,6 +23,7 @@ AtomFeed::AtomFeed() AtomFeed::AtomFeed(Feed* feed) : AtomFeed::AtomFeed() { + SetXmlUrl(feed->GetXmlUrl()); SetCachePath(feed->GetCachePath()); } @@ -42,10 +42,7 @@ AtomFeed::Parse () RootParse(xfeed); ParseEntries(xfeed); - BFile* feedFile = new BFile(cachePath, B_READ_WRITE); - time_t tt_date = date.Time_t(); - feedFile->WriteAttr("LastDate", B_TIME_TYPE, 0, &tt_date, - sizeof(time_t)); + _PostParse(); } diff --git a/src/Feed.cpp b/src/Feed.cpp index 3543e08..70a61e7 100644 --- a/src/Feed.cpp +++ b/src/Feed.cpp @@ -16,21 +16,35 @@ Feed::Feed(BUrl xml, BString path) : Feed() { - xmlUrl = xml; - cachePath = path; + SetXmlUrl(xml); + SetCachePath(path); } Feed::Feed(BUrl xml) : Feed() { - xmlUrl = xml; + SetXmlUrl(xml); BString cache("/boot/home/config/cache/Pogger/"); cache.Append(urlToFilename(xmlUrl)); 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() { @@ -53,23 +67,41 @@ Feed::Parse() BFile feedFile = BFile(cachePath, B_READ_ONLY); 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) 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. BString Feed::Fetch() { BFile cacheFile = BFile(cachePath, B_READ_WRITE | B_CREATE_FILE); - cacheFile.ReadAttrString("LastHash", &lastHash); + cacheFile.ReadAttrString("Feed:hash", &lastHash); fetch(xmlUrl, &cacheFile, &hash, 30); - cacheFile.WriteAttrString("LastHash", &hash); + cacheFile.WriteAttrString("Feed:hash", &hash); if (hash == lastHash) updated = false; diff --git a/src/Feed.h b/src/Feed.h index eba3952..9dfe2b9 100644 --- a/src/Feed.h +++ b/src/Feed.h @@ -12,6 +12,7 @@ class BDateTime; +class BEntry; class BString; class BList; class BUrl; @@ -21,6 +22,7 @@ class Feed { public: Feed(BUrl); Feed(BUrl, BString); + Feed(BEntry); Feed(Feed*); Feed(); @@ -52,6 +54,7 @@ protected: bool AddEntry(Entry*); + void _PostParse(); int xmlCountSiblings(tinyxml2::XMLElement*, const char*); BString title; diff --git a/src/FeedController.cpp b/src/FeedController.cpp index eda2782..2dadd1c 100644 --- a/src/FeedController.cpp +++ b/src/FeedController.cpp @@ -54,6 +54,19 @@ FeedController::MessageReceived(BMessage* msg) } 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: { break; @@ -88,7 +101,9 @@ FeedController::_DownloadLoop(void* ignored) Feed* feedBuffer = new Feed(); 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(); BMessage* downloaded = new BMessage(kDownloadComplete); @@ -113,6 +128,9 @@ FeedController::_ParseLoop(void* ignored) BDirectory outDir = BDirectory(((App*)be_app)->cfg->outDir); if (feedBuffer->IsAtom()) { + printf("Parsing Atom feed from %s...\n", + feedBuffer->GetXmlUrl().UrlString().String()); + AtomFeed* feed = (AtomFeed*)malloc(sizeof(AtomFeed)); feed = new AtomFeed(feedBuffer); feed->Parse(); @@ -120,6 +138,9 @@ FeedController::_ParseLoop(void* ignored) delete(feed); } else if (feedBuffer->IsRss()) { + printf("Parsing RSS feed from %s...\n", + feedBuffer->GetXmlUrl().UrlString().String()); + RssFeed* feed = (RssFeed*)malloc(sizeof(RssFeed)); feed = new RssFeed(feedBuffer); feed->Parse(); diff --git a/src/FeedController.h b/src/FeedController.h index 24e5877..f7e5286 100644 --- a/src/FeedController.h +++ b/src/FeedController.h @@ -16,7 +16,8 @@ enum kEnqueueFeed = 'fenq', kClearQueue = 'frmq', kDownloadComplete = 'fdpr', - kQueueProgress = 'fqpr' + kQueueProgress = 'fqpr', + kUpdateSubscribed = 'fups' }; diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 55abc40..9a4a22b 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -16,6 +16,7 @@ #include "App.h" #include "EntriesView.h" +#include "FeedController.h" #include "FeedsView.h" #include "UpdatesView.h" @@ -63,8 +64,8 @@ MainWindow::_InitInterface() fBaseView->AddChild(fTabView); fUpdateNowButton = new BButton("updateNow", "Update Now", - new BMessage('iiii')); - fUpdateNowButton->SetTarget(this); + new BMessage(kUpdateSubscribed)); + fUpdateNowButton->SetTarget((App*)be_app); fUpdateNowButton->SetExplicitAlignment( BAlignment(B_ALIGN_RIGHT, B_ALIGN_MIDDLE)); diff --git a/src/Mimetypes.cpp b/src/Mimetypes.cpp index be4811c..9be3aaa 100644 --- a/src/Mimetypes.cpp +++ b/src/Mimetypes.cpp @@ -11,9 +11,37 @@ #include -// install the Feed Entry mimetype, if need be +bool installMimeTypes() +{ + return (feedMimeType() && feedEntryMimeType()); +} + + bool 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; BMimeType mime("text/x-feed-entry"); @@ -25,11 +53,11 @@ feedMimeType() mime.SetShortDescription("Feed Entry"); mime.SetLongDescription("Atom/RSS Feed Entry"); - addAttribute(info, "FEED:name", "Name"); - addAttribute(info, "FEED:description", "Description"); + addAttribute(info, "Feed:name", "Name"); + addAttribute(info, "Feed:description", "Description"); addAttribute(info, "META:url", "URL"); - addAttribute(info, "FEED:source", "Source"); - addAttribute(info, "FEED:when", "When", B_TIME_TYPE, 150); + addAttribute(info, "Feed:source", "Source"); + addAttribute(info, "Feed:when", "When", B_TIME_TYPE, 150); return mime.SetAttrInfo(&info); } diff --git a/src/Mimetypes.h b/src/Mimetypes.h index 9b8ff05..7620e7c 100644 --- a/src/Mimetypes.h +++ b/src/Mimetypes.h @@ -12,7 +12,9 @@ class BMessage; +bool installMimeTypes(); bool feedMimeType(); +bool feedEntryMimeType(); static void addAttribute(BMessage&, const char*, const char*, int32 type = B_STRING_TYPE, int32 width = 200); diff --git a/src/RssFeed.cpp b/src/RssFeed.cpp index e06fbb2..1004cd7 100644 --- a/src/RssFeed.cpp +++ b/src/RssFeed.cpp @@ -21,6 +21,7 @@ RssFeed::RssFeed() RssFeed::RssFeed(Feed* feed) : RssFeed::RssFeed() { + SetXmlUrl(feed->GetXmlUrl()); SetCachePath(feed->GetCachePath()); } @@ -39,9 +40,7 @@ RssFeed::Parse() RootParse(xchan); ParseEntries(xchan); - time_t tt_date = date.Time_t(); - BFile* feedFile = new BFile(cachePath, B_READ_ONLY); - feedFile->WriteAttr("LastDate", B_TIME_TYPE, 0, &tt_date, sizeof(time_t)); + _PostParse(); }