From 08d5a73f899b60b38f3e3ccbc6b1bf6e2e1c607b Mon Sep 17 00:00:00 2001 From: Jaidyn Ann Date: Mon, 11 Jan 2021 11:41:46 -0600 Subject: [PATCH] Download timeout; better argv handling --- src/App.cpp | 80 ++++++-------------------- src/App.h | 7 +-- src/Feed.cpp | 17 +++--- src/FeedController.cpp | 4 +- src/Invocation.cpp | 126 ----------------------------------------- src/Invocation.h | 17 ------ src/Util.cpp | 22 ++++--- src/Util.h | 3 +- 8 files changed, 42 insertions(+), 234 deletions(-) delete mode 100644 src/Invocation.cpp delete mode 100644 src/Invocation.h diff --git a/src/App.cpp b/src/App.cpp index dff069a..fa8470b 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -15,7 +15,6 @@ #include "Entry.h" #include "Feed.h" #include "FeedController.h" -#include "Invocation.h" #include "MainWindow.h" #include "Mimetypes.h" #include "RssFeed.h" @@ -26,17 +25,12 @@ int main(int argc, char** argv) { App* app = new App(); - usageMsg.ReplaceAll("%app%", "Pogger"); feedMimeType(); app->cfg = new Config; app->cfg->Load(); - if (argc == 1) - app->Run(); - else - cliStart(argc, argv); - + app->Run(); if ( app->cfg->will_save == true ) app->cfg->Save(); @@ -45,23 +39,6 @@ main(int argc, char** argv) } -void -cliStart(int argc, char** argv) -{ - invocation(argc, argv); - BList targetFeeds = ((App*)be_app)->cfg->targetFeeds; - - for (int i = 0; i < targetFeeds.CountItems(); i++) { - Feed* newFeed = new Feed(((BString*)targetFeeds.ItemAt(i))->String()); - BMessage* enqueue = new BMessage(kEnqueueFeed); - - enqueue->AddData("feeds", B_RAW_TYPE, newFeed, sizeof(Feed)); - - ((App*)be_app)->MessageReceived(enqueue); - } -} - - App::App() : BApplication("application/x-vnd.Pogger") { fMainWindow = new MainWindow(); @@ -101,43 +78,20 @@ App::MessageReceived(BMessage* msg) } +void +App::ArgvReceived(int32 argc, char** argv) +{ + for (int i = 1; i < argc; i++) { + Feed* newFeed = new Feed(argv[i]); + + BMessage* enqueue = new BMessage(kEnqueueFeed); + enqueue->AddData("feeds", B_RAW_TYPE, (void*)newFeed, sizeof(Feed)); + + MessageReceived(enqueue); + } +} + + const char* configPath = "/boot/home/config/settings/Pogger/"; -BString usageMsg = - "Usage: %app% [-hvDus] [-tT datetime] [-cCO path] \n" - " %app% [-hvs] [-tTcCO] ( | | )\n" - "\n" - "%app%, a RSS and Atom feed parser/daemon.\n" - "\n" - "Options:\n" - " -h, --help - Print this usage info.\n" - " -v, --verbose - Print verbose (debug) info.\n" - " -O, --output - Output dir for item files. (Default: ~/feeds/)\n" - " -t, --before - Only return items published before this datetime.\n" - " -T, --after - Only return items published after this datetime.\n" - " -c, --config - Path to config dir. (Default: ~/config/settings/Pogger/)\n" - " -C, --cache - Path to cache. (Default: ~/config/cache/Pogger/)\n" - " -s, --save - Save the args of `-m`, `-C`, and `-O` to config.\n" - " -u, --update - Update all feeds, but don't start daemon.\n" - " -D, --foreground - Run in the foreground, do not daemonize.\n" - " `-u` and `-D` only apply when running without file/url arg.\n" - "\n" - "When invoked without a file or URL, will search for any new feed items\n" - "published since last check by by any 'feed file' placed in the config\n" - "directory (default: ~/config/settings/Rifen/feeds/) and create their\n" - "corresponding files.\n" - "\n" - "When invoked with a file or URL, will create files from items contained\n" - "within the given file or URL.\n" - "\n" - "'Feed files' are files with a 'META:url' attribute containing the\n" - "corresponding URL to the feed's XML.\n" - "\n" - "Both -t and -T use the ISO 8601 format for specifying datetimes:\n" - " YYYY-MM-DDTHH:MM:SS - 2020-01-01T07:07:07\n" - "\n" - "NOTE: This message doesn't reflect reality. This is more of a spec of\n" - " what I hope this program will be. As of now, running %app%\n" - " without a file/url free-argument is invalid, as the daemon\n" - " isn't implemented at all. As such, -D -u and -C are non-functional.\n" - " But it sure can turn an XML feed into files! Lol.\n" -; + + diff --git a/src/App.h b/src/App.h index eacb2cf..af25957 100644 --- a/src/App.h +++ b/src/App.h @@ -21,6 +21,8 @@ class App : public BApplication public: App(void); void MessageReceived(BMessage* msg); + void ArgvReceived(int32 argc, char** argv); + Config* cfg; MainWindow* fMainWindow; @@ -29,14 +31,9 @@ private: FeedController* fFeedController; }; - int main ( int, char** ); -void cliStart ( int, char** ); - - extern const char* configPath; -extern BString usageMsg; #endif // APP_H diff --git a/src/Feed.cpp b/src/Feed.cpp index e3de764..26815dc 100644 --- a/src/Feed.cpp +++ b/src/Feed.cpp @@ -66,22 +66,23 @@ Feed::FetchRemoteFeed() BUrl givenUrl = BUrl(inputPath); time_t tt_lastDate = 0; BDateTime* lastDate = new BDateTime(); - BString* newHash = new BString(); - char oldHash[41]; + BString newHash; + BString oldHash; BFile* cacheFile = new BFile(GetCachePath(), B_READ_WRITE | B_CREATE_FILE); - cacheFile->ReadAttr("LastHash", B_STRING_TYPE, 0, oldHash, 41); +// cacheFile->ReadAttr("LastHash", B_STRING_TYPE, 0, oldHash, 41); + cacheFile->ReadAttrString("LastHash", &oldHash); if (((App*)be_app)->cfg->verbose) printf("Saving %s...\n", inputPath.String()); - webFetch(BUrl(inputPath), cacheFile, newHash); + fetch(BUrl(inputPath), cacheFile, &newHash, 30); + cacheFile->WriteAttrString("LastHash", &newHash); +// cacheFile->WriteAttr("LastHash", B_STRING_TYPE, 0, +// newHash.String(), newHash.CountChars()); - cacheFile->WriteAttr("LastHash", B_STRING_TYPE, 0, - newHash->String(), newHash->CountChars()); - - if (*(newHash) == BString(oldHash)) + if (newHash == oldHash) updated = false; fetched = true; diff --git a/src/FeedController.cpp b/src/FeedController.cpp index b9c4d29..299ded4 100644 --- a/src/FeedController.cpp +++ b/src/FeedController.cpp @@ -88,12 +88,12 @@ FeedController::_DownloadLoop(void* ignored) Feed* feedBuffer = new Feed(); while (receive_data(&sender, (void*)feedBuffer, sizeof(Feed)) != 0) { + printf( "%s\n\n", feedBuffer->GetCachePath().String()); feedBuffer->FetchRemoteFeed(); BMessage* downloaded = new BMessage(kDownloadComplete); downloaded->AddData("feeds", B_RAW_TYPE, feedBuffer, sizeof(Feed)); - ((App*)be_app)->MessageReceived(downloaded); } @@ -133,3 +133,5 @@ FeedController::_ParseLoop(void* ignored) delete (feedBuffer); return 0; } + + diff --git a/src/Invocation.cpp b/src/Invocation.cpp deleted file mode 100644 index a287286..0000000 --- a/src/Invocation.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2020, Jaidyn Levesque - * All rights reserved. Distributed under the terms of the MIT license. - */ - -#include "Invocation.h" - -#include -#include - -#include - -#include "App.h" -#include "AtomFeed.h" -#include "Config.h" -#include "Entry.h" -#include "Feed.h" -#include "Mimetypes.h" -#include "RssFeed.h" -#include "Util.h" - - -int -usage() -{ - fprintf(stderr, "%s", usageMsg.String()); - return 2; -} - - -int -invocation(int argc, char** argv) -{ - Config* cfg = ((App*)be_app)->cfg; - BDateTime maxDate; - BDateTime minDate; - - static struct option sLongOptions[] = { - { "help", no_argument, 0, 'h' }, - { "verbose", no_argument, 0, 'v' }, - { "config", required_argument, 0, 'c' }, - { "cache", required_argument, 0, 'C' }, - { "before", required_argument, 0, 't' }, - { "after", required_argument, 0, 'T' }, - { "output", required_argument, 0, 'O' }, - { "foreground", no_argument, 0, 'D' }, - { "update", no_argument, 0, 'u' }, - { 0, 0, 0, 0 } - }; - - while (true) { - opterr = 0; - int c = getopt_long(argc, argv, "+hsuvDm:O:T:t:c:C:", sLongOptions, NULL); - - switch (c) { - case -1: - freeargInvocation(argc, argv, optind); - return 0; - case 'h': - return usage(); - case 'c': - cfg->configDir = BString(optarg); - break; - case 'C': - cfg->cacheDir = BString(optarg); - break; - case 's': - cfg->will_save = true; - case 't': - minDate = dateRfc3339ToBDate(optarg); - if (minDate != NULL) - cfg->minDate = minDate; - else { - fprintf(stderr, "Invalid date format for `-%c'.\n", optopt); - return 2; - } - break; - case 'T': - maxDate = dateRfc3339ToBDate(optarg); - if (maxDate != NULL) - cfg->maxDate = maxDate; - else { - fprintf(stderr, "Invalid date format for `-%c'.\n", optopt); - return 2; - } - break; - case 'O': - cfg->outDir = BString(optarg); - break; - case 'u': - cfg->updateFeeds = true; - break; - case 'v': - cfg->verbose = true; - break; - case 'D': - cfg->daemon = false; - break; - case '?': - if (optopt == 'O' || optopt == 'm') - fprintf(stderr, "Option `-%c` requires an argument.\n", - optopt); - else - fprintf(stderr, "Unknown option `-%c`.\n", optopt); - return 2; - } - } -} - - -void -freeargInvocation(int argc, char** argv, int optind) -{ - Config* cfg = ((App*)be_app)->cfg; - if (optind < argc) { - int freeargc = argc - optind; - cfg->targetFeeds = BList(freeargc); - - for (int i = 0; i < freeargc; i++) { - BString* newFeed = new BString(argv[optind + i]); - cfg->targetFeeds.AddItem(newFeed); - } - } -} - - diff --git a/src/Invocation.h b/src/Invocation.h deleted file mode 100644 index 403c518..0000000 --- a/src/Invocation.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2020, Jaidyn Levesque - * All rights reserved. Distributed under the terms of the MIT license. - */ -#ifndef INVOCATION_H -#define INVOCATION_H - - -int usage ( ); -int invocation ( int, char** ); -void freeargInvocation ( int, char**, int ); -bool processItem ( void* ); -bool processFeed ( void* ); - - -#endif - diff --git a/src/Util.cpp b/src/Util.cpp index 9ef169f..ab8d834 100644 --- a/src/Util.cpp +++ b/src/Util.cpp @@ -5,6 +5,7 @@ #include "Util.h" +#include #include #include #include @@ -95,15 +96,7 @@ isRemotePath(BString path) { int32 -webFetch(BUrl url, BDataIO* reply) -{ - BString* ignored = new BString(); - return webFetch(url, reply, ignored); -} - - -int32 -webFetch(BUrl url, BDataIO* reply, BString* hash) +fetch(BUrl url, BDataIO* reply, BString* hash, int timeout) { ProtocolListener listener(true); boost::uuids::detail::sha1 sha1; @@ -113,13 +106,18 @@ webFetch(BUrl url, BDataIO* reply, BString* hash) listener.SetDownloadIO(reply); listener.SetSha1(&sha1); + time_t startTime = time(0); thread_id thread = request->Run(); - wait_for_thread(thread, NULL); + thread_info t_info; + + while (time(0) - startTime < timeout + && get_thread_info(thread, &t_info) == B_OK) + snooze(100000); + + kill_thread(thread); *(hash) = listener.GetHash(); - return request->Status(); - return 200; } diff --git a/src/Util.h b/src/Util.h index a3f17c5..4b73aef 100644 --- a/src/Util.h +++ b/src/Util.h @@ -23,8 +23,7 @@ bool withinDateRange(BDateTime, BDateTime, BDateTime); bool isRemotePath(BString); -int32 webFetch(BUrl, BDataIO*, BString*); -int32 webFetch(BUrl, BDataIO*); +int32 fetch(BUrl url, BDataIO* reply, BString* hash, int timeout); #endif