Error notifications and dedicated Notifier object

This commit is contained in:
Jaidyn Ann 2021-01-13 17:28:07 -06:00
parent 543292c825
commit 4383c4b906
9 changed files with 174 additions and 38 deletions

View File

@ -39,6 +39,7 @@ SRCS = \
src/FeedsView.cpp, \ src/FeedsView.cpp, \
src/MainWindow.cpp, \ src/MainWindow.cpp, \
src/Mimetypes.cpp, \ src/Mimetypes.cpp, \
src/Notifier.cpp, \
src/ProtocolListener.cpp, \ src/ProtocolListener.cpp, \
src/RssFeed.cpp, \ src/RssFeed.cpp, \
src/UpdatesView.cpp, \ src/UpdatesView.cpp, \

View File

@ -18,6 +18,7 @@
#include "FeedController.h" #include "FeedController.h"
#include "MainWindow.h" #include "MainWindow.h"
#include "Mimetypes.h" #include "Mimetypes.h"
#include "Notifier.h"
#include "RssFeed.h" #include "RssFeed.h"
#include "Util.h" #include "Util.h"
@ -40,6 +41,7 @@ App::App() : BApplication("application/x-vnd.Pogger")
cfg->Load(); cfg->Load();
fMainWindow = new MainWindow(); fMainWindow = new MainWindow();
fNotifier = new Notifier();
fFeedController = new FeedController(); fFeedController = new FeedController();
fMainWindow->Show(); fMainWindow->Show();
@ -69,13 +71,22 @@ App::MessageReceived(BMessage* msg)
{ {
break; break;
} }
case kQueueProgress: case kParseFail:
{ {
fMainWindow->MessageReceived(msg); fNotifier->MessageReceived(msg);
fFeedController->MessageReceived(msg);
break;
}
case kDownloadFail:
{
fNotifier->MessageReceived(msg);
fFeedController->MessageReceived(msg);
break;
} }
case kDownloadComplete: case kDownloadComplete:
{ {
fFeedController->MessageReceived(msg); fFeedController->MessageReceived(msg);
break;
} }
default: default:
{ {

View File

@ -15,6 +15,7 @@ class BMessageRunner;
class Config; class Config;
class FeedController; class FeedController;
class MainWindow; class MainWindow;
class Notifier;
class App : public BApplication class App : public BApplication
@ -28,6 +29,7 @@ public:
Config* cfg; Config* cfg;
MainWindow* fMainWindow; MainWindow* fMainWindow;
BMessageRunner* fUpdateRunner; BMessageRunner* fUpdateRunner;
Notifier* fNotifier;
private: private:
FeedController* fFeedController; FeedController* fFeedController;

View File

@ -93,21 +93,19 @@ Feed::_PostParse()
// Download a remote feed's XML to the cache path. // Download a remote feed's XML to the cache path.
BString bool
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("Feed:hash", &lastHash); cacheFile.ReadAttrString("Feed:hash", &lastHash);
fetch(xmlUrl, &cacheFile, &hash, 30); int32 result = fetch(xmlUrl, &cacheFile, &hash, 30);
cacheFile.WriteAttrString("Feed:hash", &hash); cacheFile.WriteAttrString("Feed:hash", &hash);
if (hash == lastHash) if (result == 0)
updated = false; return true;
return false;
fetched = true;
return cachePath;
} }

View File

@ -31,7 +31,7 @@ public:
BList GetEntries(); BList GetEntries();
BList GetNewEntries(); BList GetNewEntries();
BString Fetch(); bool Fetch();
bool IsRss(); bool IsRss();
bool IsAtom(); bool IsAtom();

View File

@ -105,14 +105,17 @@ FeedController::_DownloadLoop(void* ignored)
printf( "Downloading feed from %s...\n", printf( "Downloading feed from %s...\n",
feedBuffer->GetXmlUrl().UrlString().String()); feedBuffer->GetXmlUrl().UrlString().String());
feedBuffer->Fetch(); if (feedBuffer->Fetch()) {
BMessage* downloaded = new BMessage(kDownloadComplete); BMessage* downloaded = new BMessage(kDownloadComplete);
downloaded->AddData("feeds", B_RAW_TYPE, feedBuffer, sizeof(Feed)); downloaded->AddData("feeds", B_RAW_TYPE, feedBuffer, sizeof(Feed));
((App*)be_app)->MessageReceived(downloaded); ((App*)be_app)->MessageReceived(downloaded);
} }
else {
BMessage* failure = new BMessage(kDownloadFail);
failure->AddString("feed_url", feedBuffer->GetXmlUrl().UrlString());
((App*)be_app)->MessageReceived(failure);
}
}
delete(feedBuffer); delete(feedBuffer);
return 0; return 0;
} }
@ -126,7 +129,8 @@ FeedController::_ParseLoop(void* ignored)
while (receive_data(&sender, (void*)feedBuffer, sizeof(Feed)) != 0) { while (receive_data(&sender, (void*)feedBuffer, sizeof(Feed)) != 0) {
BList entries; BList entries;
BString title; BString feedTitle;
BUrl feedUrl = feedBuffer->GetXmlUrl();
BDirectory outDir = BDirectory(((App*)be_app)->cfg->outDir); BDirectory outDir = BDirectory(((App*)be_app)->cfg->outDir);
if (feedBuffer->IsAtom()) { if (feedBuffer->IsAtom()) {
@ -134,7 +138,7 @@ FeedController::_ParseLoop(void* ignored)
feed = new AtomFeed(feedBuffer); feed = new AtomFeed(feedBuffer);
feed->Parse(); feed->Parse();
entries = feed->GetNewEntries(); entries = feed->GetNewEntries();
title = feed->GetTitle(); feedTitle = feed->GetTitle();
delete(feed); delete(feed);
} }
else if (feedBuffer->IsRss()) { else if (feedBuffer->IsRss()) {
@ -142,29 +146,24 @@ FeedController::_ParseLoop(void* ignored)
feed = new RssFeed(feedBuffer); feed = new RssFeed(feedBuffer);
feed->Parse(); feed->Parse();
entries = feed->GetNewEntries(); entries = feed->GetNewEntries();
title = feed->GetTitle(); feedTitle = feed->GetTitle();
delete(feed); delete(feed);
} }
if ((feedBuffer->IsAtom() || feedBuffer->IsRss())
&& entries.CountItems() > 0) if (feedBuffer->IsAtom() || feedBuffer->IsRss()) {
{
for (int i = 0; i < entries.CountItems(); i++) for (int i = 0; i < entries.CountItems(); i++)
((Entry*)entries.ItemAt(i))->Filetize(outDir); ((Entry*)entries.ItemAt(i))->Filetize(outDir);
BNotification notifyNew = (B_INFORMATION_NOTIFICATION); BMessage* complete = new BMessage(kParseComplete);
BString notifyLabel("New Feed Entries"); complete->AddString("feed_name", feedTitle);
BString notifyText("%n% new entries from %source%"); complete->AddInt32("entry_count", entries.CountItems());
((App*)be_app)->MessageReceived(complete);
BString numStr(""); }
numStr << entries.CountItems(); else {
notifyText.ReplaceAll("%source%", title); BMessage* failure = new BMessage(kParseFail);
notifyText.ReplaceAll("%n%", numStr); failure->AddString("feed_url", feedUrl.UrlString());
((App*)be_app)->MessageReceived(failure);
notifyNew.SetTitle(notifyLabel);
notifyNew.SetContent(notifyText);
notifyNew.Send();
} }
} }

View File

@ -15,8 +15,10 @@ enum
{ {
kEnqueueFeed = 'fenq', kEnqueueFeed = 'fenq',
kClearQueue = 'frmq', kClearQueue = 'frmq',
kDownloadComplete = 'fdpr', kDownloadComplete = 'fdlc',
kQueueProgress = 'fqpr', kDownloadFail = 'fdlf',
kParseComplete = 'fpec',
kParseFail = 'fpef',
kUpdateSubscribed = 'fups' kUpdateSubscribed = 'fups'
}; };

97
src/Notifier.cpp Normal file
View File

@ -0,0 +1,97 @@
/*
* Copyright 2020, Jaidyn Levesque <jadedctrl@teknik.io>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#include <Message.h>
#include <Notification.h>
#include "FeedController.h"
#include "Notifier.h"
void
Notifier::MessageReceived(BMessage* msg)
{
switch (msg->what)
{
case kParseComplete:
{
BString feedName;
int32 entryCount;
if (msg->FindString("feed_name", &feedName) == B_OK
&& msg->FindInt32("entry_count", &entryCount) == B_OK)
{
_NewEntryNotification(feedName, entryCount);
}
break;
}
case kParseFail:
{
BString feedUrl = msg->GetString("feed_url", "");
_ParseFailNotification(feedUrl);
break;
}
case kDownloadFail:
{
BString feedUrl = msg->GetString("feed_url", "");
_DownloadFailNotification(feedUrl);
}
}
}
void
Notifier::_NewEntryNotification(BString feedName, int32 entryCount)
{
BNotification notifyNew(B_INFORMATION_NOTIFICATION);
BString notifyLabel("New Feed Entries");
BString notifyText("%n% new entries from %source%");
BString numStr("");
numStr << entryCount;
notifyText.ReplaceAll("%source%", feedName);
notifyText.ReplaceAll("%n%", numStr);
notifyNew.SetTitle(notifyLabel);
notifyNew.SetContent(notifyText);
notifyNew.Send();
}
void
Notifier::_ParseFailNotification(BString feedUrl)
{
BNotification notifyError(B_ERROR_NOTIFICATION);
BString notifyText("Failed to parse feed from %url%");
if (feedUrl.IsEmpty())
notifyText = "Failed to parse a feed";
notifyText.ReplaceAll("%url%", feedUrl);
notifyError.SetTitle("Parse Failure");
notifyError.SetContent(notifyText);
notifyError.Send();
}
void
Notifier::_DownloadFailNotification(BString feedUrl)
{
BNotification notifyError(B_ERROR_NOTIFICATION);
BString notifyText("Failed to download feed from %url%");
if (feedUrl.IsEmpty())
notifyText = "Failed to download a feed";
notifyText.ReplaceAll("%url%", feedUrl);
notifyError.SetTitle("Download Failure");
notifyError.SetContent(notifyText);
notifyError.Send();
}

26
src/Notifier.h Normal file
View File

@ -0,0 +1,26 @@
/*
* Copyright 2020, Jaidyn Levesque <jadedctrl@teknik.io>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#ifndef NOTIFIER_H
#define NOTIFIER_H
#include <SupportDefs.h>
class BString;
class Notifier {
public:
void MessageReceived(BMessage* msg);
private:
void _NewEntryNotification(BString feedName, int32 feedCount);
void _ParseFailNotification(BString feedUrl);
void _DownloadFailNotification(BString feedUrl);
};
#endif // NOTIFIER_H