Error notifications and dedicated Notifier object
This commit is contained in:
parent
543292c825
commit
4383c4b906
1
Makefile
1
Makefile
|
@ -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, \
|
||||||
|
|
15
src/App.cpp
15
src/App.cpp
|
@ -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:
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
|
|
12
src/Feed.cpp
12
src/Feed.cpp
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Ŝarĝante…
Reference in New Issue