Notifications once per sync
This commit is contained in:
parent
2834ed4227
commit
bbdc2c2865
5
TODO.txt
5
TODO.txt
|
@ -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.
|
||||
|
|
14
src/App.cpp
14
src/App.cpp
|
@ -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:
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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", ¤t) == 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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ public:
|
|||
private:
|
||||
void _InitInterface();
|
||||
|
||||
void _UpdateProgress(int32 max, int32 current);
|
||||
void _UpdateProgress(int32 total, int32 current);
|
||||
|
||||
BGroupView* fBaseView;
|
||||
BTabView* fTabView;
|
||||
|
|
139
src/Notifier.cpp
139
src/Notifier.cpp
|
@ -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", ¤t) == 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));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
Ŝarĝante…
Reference in New Issue