Notifications once per sync

This commit is contained in:
Jaidyn Ann 2021-03-01 19:13:22 -06:00
parent 2834ed4227
commit bbdc2c2865
8 changed files with 160 additions and 117 deletions

View File

@ -1,7 +1,4 @@
Important Features:
* Show in desktray
* Make archivable
* Get menu working
* Default column layouts for ~/feeds and ~/config/settings/Pogger/Subscriptions
* Localization
@ -14,6 +11,7 @@ Important improvements:
and updates every 30 minutes, it got to about 200MB after a week or
so.
* _Huge_ problem, but I haven't had luck figuring it out yet…
* Move from BLists to BObjectLists where possible
* No hardcoded paths
* General input sanitization
* File error-handling
@ -31,6 +29,7 @@ Nice Improvements:
* Main window
* Subscription-edit window
* Proper scripting support
* Show in desktray
* Store feeds in kEnqueueFeeds/etc messages as paths? hmm
* This way, if the user edits the feed after it is enqueued but before
processing, the changes will be applied.

View File

@ -54,22 +54,16 @@ App::MessageReceived(BMessage* msg)
{
switch (msg->what)
{
case kDownloadComplete:
fMainWindow->PostMessage(msg);
case kEnqueueFeed:
case kUpdateSubscribed:
case kControllerCheck:
{
fFeedController->MessageReceived(msg);
break;
}
case kDownloadComplete:
fMainWindow->PostMessage(msg);
case kEnqueueFeed:
{
fNotifier->MessageReceived(msg);
fFeedController->MessageReceived(msg);
break;
}
case kFeedsEdited:
case kProgress:
case kDownloadStart:
{
fMainWindow->PostMessage(msg);
@ -77,8 +71,10 @@ App::MessageReceived(BMessage* msg)
}
case kClearQueue:
{
fFeedController->MessageReceived(msg);
break;
}
case kProgress:
case kParseComplete:
case kParseFail:
case kDownloadFail:

View File

@ -20,11 +20,13 @@
FeedController::FeedController()
:
fEnqueuedTotal(0),
fMainThread(find_thread(NULL)),
fDownloadThread(0),
fParseThread(0),
fDownloadQueue(new BList()),
fMessageRunner(new BMessageRunner(be_app, BMessage(kControllerCheck), 50000, -1))
{
fDownloadThread = spawn_thread(_DownloadLoop, "here, eat this",
B_NORMAL_PRIORITY, &fMainThread);
@ -58,6 +60,7 @@ FeedController::MessageReceived(BMessage* msg)
_EnqueueFeed((Feed*)data);
i++;
}
_SendProgress();
break;
}
case kUpdateSubscribed:
@ -66,21 +69,18 @@ FeedController::MessageReceived(BMessage* msg)
for (int i = 0; i < subFeeds.CountItems(); i++) {
_EnqueueFeed((Feed*)subFeeds.ItemAt(i));
}
_SendProgress();
break;
}
case kClearQueue:
{
fDownloadQueue->MakeEmpty();
break;
}
case kControllerCheck:
{
_ProcessQueueItem();
_CheckStatus();
break;
}
default:
{
// BWindow::MessageReceived(msg);
_ReceiveStatus();
break;
}
}
@ -100,6 +100,24 @@ FeedController::SubscribedFeeds()
}
void
FeedController::_SendProgress()
{
int32 dqCount = fDownloadQueue->CountItems();
if (fEnqueuedTotal < dqCount)
fEnqueuedTotal = dqCount;
BMessage progress(kProgress);
progress.AddInt32("total", fEnqueuedTotal);
progress.AddInt32("current", fEnqueuedTotal - dqCount);
be_app->MessageReceived(&progress);
if (dqCount == 0)
fEnqueuedTotal = 0;
}
void
FeedController::_EnqueueFeed(Feed* feed)
{
@ -116,15 +134,15 @@ FeedController::_ProcessQueueItem()
send_data(fDownloadThread, 0, (void*)buffer, sizeof(Feed));
BMessage downloadInit = BMessage(kDownloadStart);
downloadInit.AddString("feed_url", buffer->GetXmlUrl().UrlString());
downloadInit.AddString("feed_name", buffer->GetTitle());
downloadInit.AddString("feed_url", buffer->GetXmlUrl().UrlString());
((App*)be_app)->MessageReceived(&downloadInit);
}
}
void
FeedController::_CheckStatus()
FeedController::_ReceiveStatus()
{
thread_id sender;
@ -137,6 +155,7 @@ FeedController::_CheckStatus()
case kDownloadComplete:
{
BMessage complete = BMessage(kDownloadComplete);
complete.AddString("feed_name", feedBuffer->GetTitle());
complete.AddString("feed_url",
feedBuffer->GetXmlUrl().UrlString());
((App*)be_app)->MessageReceived(&complete);
@ -147,26 +166,31 @@ FeedController::_CheckStatus()
case kDownloadFail:
{
BMessage failure = BMessage(kDownloadFail);
failure.AddString("feed_name", feedBuffer->GetTitle());
failure.AddString("feed_url",
feedBuffer->GetXmlUrl().UrlString());
((App*)be_app)->MessageReceived(&failure);
break;
}
case kParseComplete:
{
BMessage complete = BMessage(kParseComplete);
complete.AddString("feed_url", feedBuffer->GetXmlUrl().UrlString());
complete.AddInt32("entry_count", feedBuffer->GetNewEntries().CountItems());
((App*)be_app)->MessageReceived(&complete);
_SendProgress();
break;
}
case kParseFail:
{
BMessage failure = BMessage(kParseFail);
failure.AddString("feed_name", feedBuffer->GetTitle());
failure.AddString("feed_url", feedBuffer->GetXmlUrl().UrlString());
((App*)be_app)->MessageReceived(&failure);
_SendProgress();
break;
}
// If parse was successful, the code is the amount of new entries
default:
BMessage complete = BMessage(kParseComplete);
complete.AddString("feed_name", feedBuffer->GetTitle());
complete.AddString("feed_url", feedBuffer->GetXmlUrl().UrlString());
complete.AddInt32("entry_count", code);
((App*)be_app)->MessageReceived(&complete);
_SendProgress();
break;
}
}
}
@ -209,6 +233,7 @@ FeedController::_ParseLoop(void* data)
int32 code = receive_data(&sender, (void*)feedBuffer, sizeof(Feed));
BList entries;
int32 entriesCount;
BString feedTitle;
BUrl feedUrl = feedBuffer->GetXmlUrl();
BDirectory outDir = BDirectory(((App*)be_app)->fPreferences->EntryDir());
@ -218,9 +243,10 @@ FeedController::_ParseLoop(void* data)
feed = new AtomFeed(feedBuffer);
feed->Parse();
entries = feed->GetNewEntries();
entriesCount = entries.CountItems();
feedTitle = feed->GetTitle();
for (int i = 0; i < entries.CountItems(); i++)
for (int i = 0; i < entriesCount; i++)
((Entry*)entries.ItemAt(i))->Filetize(outDir);
delete feed;
}
@ -229,19 +255,20 @@ FeedController::_ParseLoop(void* data)
feed = new RssFeed(feedBuffer);
feed->Parse();
entries = feed->GetNewEntries();
entriesCount = entries.CountItems();
feedTitle = feed->GetTitle();
for (int i = 0; i < entries.CountItems(); i++)
for (int i = 0; i < entriesCount; i++)
((Entry*)entries.ItemAt(i))->Filetize(outDir);
delete feed;
}
if (feedBuffer->IsAtom() || feedBuffer->IsRss()) {
send_data(main, kParseComplete, (void*)feedBuffer, sizeof(Feed));
send_data(main, entriesCount, (void*)feedBuffer, sizeof(Feed));
}
else {
send_data(main, kParseFail, (void*)feedBuffer, sizeof(Feed));
send_data(main, entriesCount, (void*)feedBuffer, sizeof(Feed));
}
}

View File

@ -16,6 +16,7 @@ class Feed;
enum
{
kProgress = 'npro',
kEnqueueFeed = 'fenq',
kClearQueue = 'frmq',
kDownloadStart = 'fdst',
@ -38,12 +39,17 @@ public:
static BList SubscribedFeeds();
private:
void _SendProgress();
void _EnqueueFeed(Feed* feed);
void _ProcessQueueItem();
void _ReceiveStatus();
static int32 _DownloadLoop(void* data);
static int32 _ParseLoop(void* data);
void _EnqueueFeed(Feed* feed);
void _ProcessQueueItem();
void _CheckStatus();
int32 fEnqueuedTotal;
thread_id fMainThread;
thread_id fDownloadThread;

View File

@ -60,13 +60,12 @@ MainWindow::MessageReceived(BMessage *msg)
case kProgress:
{
fFeedsView->MessageReceived(msg);
int32 max = 0;
int32 current = 0;
int32 total,current = 0;
if (msg->FindInt32("max", &max) == B_OK
if (msg->FindInt32("total", &total) == B_OK
&& msg->FindInt32("current", &current) == B_OK)
{
_UpdateProgress(max, current);
_UpdateProgress(total, current);
}
break;
}
@ -120,12 +119,12 @@ MainWindow::_InitInterface()
void
MainWindow::_UpdateProgress(int32 max, int32 current)
MainWindow::_UpdateProgress(int32 total, int32 current)
{
int32 prog = max - current;
fStatusBar->SetMaxValue(max);
fStatusBar->SetTo(prog);
if (current < fStatusBar->CurrentValue())
fStatusBar->Reset();
fStatusBar->SetMaxValue(total);
fStatusBar->SetTo(current);
}

View File

@ -22,7 +22,7 @@ public:
private:
void _InitInterface();
void _UpdateProgress(int32 max, int32 current);
void _UpdateProgress(int32 total, int32 current);
BGroupView* fBaseView;
BTabView* fTabView;

View File

@ -5,6 +5,7 @@
#include "Notifier.h"
#include <List.h>
#include <Message.h>
#include <Notification.h>
@ -14,8 +15,9 @@
Notifier::Notifier()
:
fEnqueuedFeeds(0),
fFeedsInProgress(0)
fFailedFeeds(new BList()),
fUpdatedFeeds(new BList()),
fTotalEntries(0)
{
}
@ -25,45 +27,44 @@ Notifier::MessageReceived(BMessage* msg)
{
switch (msg->what)
{
case kEnqueueFeed:
case kProgress:
{
fEnqueuedFeeds++;
fFeedsInProgress++;
_UpdateProgress();
int32 total, current = 0;
if (msg->FindInt32("total", &total) == B_OK
&& msg->FindInt32("current", &current) == B_OK
&& total == current)
{
_SendNotifications();
}
break;
}
case kParseComplete:
{
BString feedName;
BString feedUrl;
int32 entryCount;
if (msg->FindString("feed_name", &feedName) == B_OK
if ((msg->FindString("feed_name", &feedName) == B_OK
|| msg->FindString("feed_url", &feedUrl) == B_OK)
&& msg->FindInt32("entry_count", &entryCount) == B_OK)
{
if (entryCount > 0)
_NewEntryNotification(feedName, entryCount);
_SaveUpdated(feedName, feedUrl, entryCount);
}
fFeedsInProgress--;
_UpdateProgress();
break;
}
case kParseFail:
{
BString feedUrl = msg->GetString("feed_url", "");
_ParseFailNotification(feedUrl);
fFeedsInProgress--;
_UpdateProgress();
break;
}
case kDownloadFail:
case kParseFail:
{
BString feedUrl = msg->GetString("feed_url", "");
_DownloadFailNotification(feedUrl);
BString feedName;
BString feedUrl;
fFeedsInProgress--;
_UpdateProgress();
if (msg->FindString("feed_name", &feedName) == B_OK
|| msg->FindString("feed_url", &feedUrl) == B_OK)
{
_SaveFailed(feedName, feedUrl);
}
break;
}
}
@ -71,19 +72,40 @@ Notifier::MessageReceived(BMessage* msg)
void
Notifier::_NewEntryNotification(BString feedName, int32 entryCount)
Notifier::_SendNotifications()
{
if (((App*)be_app)->fPreferences->fNewNotify == false)
_SendUpdatedNotification();
_SendFailedNotification();
fFailedFeeds->MakeEmpty();
fUpdatedFeeds->MakeEmpty();
fTotalEntries = 0;
}
void
Notifier::_SendUpdatedNotification()
{
if (((App*)be_app)->fPreferences->fNewNotify == false
|| fTotalEntries == 0) {
return;
}
BNotification notifyNew(B_INFORMATION_NOTIFICATION);
BString notifyLabel("New Feed Entries");
BString notifyLabel("Feed Updates");
BString notifyText("%n% new entries from %source%");
BString numStr("");
numStr << entryCount;
notifyText.ReplaceAll("%source%", feedName);
notifyText.ReplaceAll("%n%", numStr);
if (fUpdatedFeeds->CountItems() > 1)
notifyText = "%n% new entries from %source% and %m% others";
BString entryNum,feedNum = "";
entryNum << fTotalEntries;
feedNum << fUpdatedFeeds->CountItems();
notifyText.ReplaceAll("%n%", entryNum);
notifyText.ReplaceAll("%m%", feedNum);
notifyText.ReplaceAll("%source%",
((BString*)fUpdatedFeeds->ItemAt(0))->String());
notifyNew.SetTitle(notifyLabel);
notifyNew.SetContent(notifyText);
@ -92,56 +114,53 @@ Notifier::_NewEntryNotification(BString feedName, int32 entryCount)
void
Notifier::_ParseFailNotification(BString feedUrl)
Notifier::_SendFailedNotification()
{
if (((App*)be_app)->fPreferences->fFailureNotify == false)
if (((App*)be_app)->fPreferences->fFailureNotify == false
|| fFailedFeeds->CountItems() == 0) {
return;
}
BNotification notifyError(B_ERROR_NOTIFICATION);
BString notifyText("Failed to parse feed from %url%");
BString notifyLabel("Update Failure");
BString notifyText("Failed to update %source%");
if (feedUrl.IsEmpty())
notifyText = "Failed to parse a feed";
if (fFailedFeeds->CountItems() > 1)
notifyText = "Failed to update %source% and %m% others";
notifyText.ReplaceAll("%url%", feedUrl);
BString feedNum = "";
feedNum << fFailedFeeds->CountItems();
notifyError.SetTitle("Parse Failure");
notifyText.ReplaceAll("%m%", feedNum);
notifyText.ReplaceAll("%source%",
((BString*)fFailedFeeds->ItemAt(0))->String());
notifyError.SetTitle(notifyLabel);
notifyError.SetContent(notifyText);
notifyError.Send();
}
void
Notifier::_DownloadFailNotification(BString feedUrl)
Notifier::_SaveUpdated(BString feedName, BString feedUrl, int32 entryCount)
{
if (((App*)be_app)->fPreferences->fFailureNotify == false)
return;
BString name = feedName;
if (feedName.IsEmpty())
name = 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();
fTotalEntries += entryCount;
fUpdatedFeeds->AddItem(new BString(feedName));
}
void
Notifier::_UpdateProgress()
Notifier::_SaveFailed(BString feedName, BString feedUrl)
{
BMessage progress = BMessage(kProgress);
progress.AddInt32("max", fEnqueuedFeeds);
progress.AddInt32("current", fFeedsInProgress);
BString name = feedName;
if (feedName.IsEmpty())
name = feedUrl;
((App*)be_app)->MessageReceived(&progress);
if (fFeedsInProgress == 0)
fEnqueuedFeeds = 0;
fFailedFeeds->AddItem(new BString(feedName));
}

View File

@ -7,16 +7,11 @@
#include <SupportDefs.h>
class BList;
class BString;
class BMessage;
enum
{
kProgress = 'npro'
};
class Notifier {
public:
Notifier();
@ -24,14 +19,16 @@ public:
void MessageReceived(BMessage* msg);
private:
void _NewEntryNotification(BString feedName, int32 feedCount);
void _ParseFailNotification(BString feedUrl);
void _DownloadFailNotification(BString feedUrl);
void _SendNotifications();
void _SendUpdatedNotification();
void _SendFailedNotification();
void _UpdateProgress();
void _SaveUpdated(BString feedName, BString feedUrl, int32 feedCount);
void _SaveFailed(BString feedName, BString feedUrl);
int32 fEnqueuedFeeds;
int32 fFeedsInProgress;
BList* fFailedFeeds;
BList* fUpdatedFeeds;
int32 fTotalEntries;
};