diff --git a/source/app.d b/source/app.d index 9235eb9..9e2cb22 100644 --- a/source/app.d +++ b/source/app.d @@ -5,8 +5,10 @@ import cartastraccia.endpoint; import vibe.core.log; +import vibe.core.file; import vibe.http.server; import vibe.http.router; +import vibe.http.fileserver; import vibe.inet.url; import vibe.http.client; import vibe.web.web; @@ -22,6 +24,7 @@ import std.algorithm : each; import std.getopt; import std.conv : to; +import std.process; immutable string info = "============================================= CARTASTRACCIA is a news reader for RSS feeds. @@ -32,11 +35,8 @@ 1. Start the daemon: > cartastraccia --daemon --endpoint=cli --endpoint=html --feeds=feeds.conf --------------------------------------------- -2a. Connect to daemon using CLI endpoint: -> cartastraccia ---------------------------------------------- -2b. Connect to daemon using HTML endpoint: -> elinks \"http://localhost:8080\" +2. Connect to daemon using HTML endpoint +> cartastraccia --browser=/path/to/browser ---------------------------------------------"; void runWebServer(ref URLRouter router, immutable string bindAddress, immutable ushort bindPort) @@ -49,7 +49,7 @@ runEventLoop(); } -void runDaemon(EndpointType[] endpoints, immutable string feedsFile, immutable +void runDaemon(immutable string feedsFile, immutable string bindAddress, immutable ushort bindPort) { // parse feed list @@ -68,27 +68,41 @@ }); }); - // initialize a new service to serve endpoints + // initialize a new service to serve requests auto router = new URLRouter; router.registerWebInterface(new EndpointService(feeds, tasks)); + router.get("*", serveStaticFiles("public/")); // start the webserver in main thread runWebServer(router, bindAddress, bindPort); } -void runClient(immutable string bindAddress, immutable ushort bindPort) +void runClient(EndpointType endpoint, immutable string browser, immutable string bindAddress, immutable ushort bindPort) { - URL url = URL("http://"~bindAddress~":"~bindPort.to!string~"/cli"); - try { - requestHTTP(url, - (scope HTTPClientRequest req) { - req.method = HTTPMethod.GET; - }, - (scope HTTPClientResponse res) { - writeln(res.bodyReader.readAllUTF8()); - }); - } catch (Exception e) { - logWarn("ERROR from daemon: "~e.msg~"\nCheck daemon logs for details (is it running?)"); + if(endpoint == EndpointType.cli) { + URL url = URL("http://"~bindAddress~":"~bindPort.to!string~"/cli"); + try { + requestHTTP(url, + (scope HTTPClientRequest req) { + req.method = HTTPMethod.GET; + }, + (scope HTTPClientResponse res) { + writeln(res.bodyReader.readAllUTF8()); + }); + } catch (Exception e) { + logWarn("ERROR from daemon: "~e.msg~"\nCheck daemon logs for details (is it running?)"); + } + } else if(endpoint == EndpointType.html) { + + if(!existsFile(browser)) { + logWarn("Could not find browser: "~browser); + logWarn("Try running: cartastraccia --browser=[/path/to/browser]"); + return; + } + + immutable address = "http://"~bindAddress~":"~bindPort.to!string; + auto pid = spawnShell(browser ~" "~address); + wait(pid); } } @@ -96,18 +110,20 @@ { // CLI arguments bool daemon = false; - EndpointType[] endpoints = [EndpointType.cli]; + EndpointType endpoint = EndpointType.html; string feedsFile = "feeds.conf"; string bindAddress = "localhost"; ushort bindPort = 8080; + string browser = "/usr/bin/elinks"; auto helpInformation = getopt( args, "daemon|d", "Start daemon", &daemon, - "endpoint|e", "Endpoints to register [cli]", &endpoints, + "endpoint|e", "Endpoints to register [cli]", &endpoint, "feeds|f", "File containing feeds to pull [feeds.conf]", &feedsFile, "host|l", "Bind to this address [localhost]", &bindAddress, - "port|p", "Bind to this port [8080]", &bindPort + "port|p", "Bind to this port [8080]", &bindPort, + "browser|b", "Absolute path to browser for HTML rendering [/usr/bin/elinks]", &browser ); if(helpInformation.helpWanted) { @@ -115,6 +131,6 @@ return; } - if(daemon) runDaemon(endpoints, feedsFile, bindAddress, bindPort); - else runClient(bindAddress, bindPort); + if(daemon) runDaemon(feedsFile, bindAddress, bindPort); + else runClient(endpoint, browser, bindAddress, bindPort); } diff --git a/source/cartastraccia/actor.d b/source/cartastraccia/actor.d index e6eaadc..d07f03a 100644 --- a/source/cartastraccia/actor.d +++ b/source/cartastraccia/actor.d @@ -1,6 +1,7 @@ module cartastraccia.actor; import cartastraccia.rss; +import cartastraccia.renderer; import vibe.core.log; import vibe.inet.url; @@ -48,6 +49,8 @@ busyListen(rss); }, (ref ValidRSS vr) { + immutable fileName = "public/channels/"~feedName~".html"; + createHTMLPage(vr, feedName, fileName); busyListen(rss); }); } @@ -94,7 +97,6 @@ } else if(r == FeedActorRequest.DATA_HTML) { logInfo("Received HTML request from task: "~webTask.getDebugID()); - webTask.dispatchHTML(vr.channels); } else if(r == FeedActorRequest.QUIT){ logDebug("Task exiting due to quit request."); @@ -122,19 +124,3 @@ b = (b+chunkSize > len) ? len : b + chunkSize; } } - -void dispatchHTML(scope Task task, RSSChannel[string] channels) -{ - ulong len = channels.length; - task.send(len); - - foreach(string cname, RSSChannel ch; channels) { - task.send(cname); - ulong ilen = ch.items.length; - task.send(ilen); - foreach(string iname, RSSItem item; ch.items) { - task.send(item); - } - } -} - diff --git a/source/cartastraccia/endpoint.d b/source/cartastraccia/endpoint.d index cccd0b2..0f6f8bf 100644 --- a/source/cartastraccia/endpoint.d +++ b/source/cartastraccia/endpoint.d @@ -34,23 +34,16 @@ @path("/") void getHTMLEndpoint(scope HTTPServerRequest req, scope HTTPServerResponse res) { - struct ChannelItems { - string cname; - string fname; - RSSItem[] items; - } - - ChannelItems[] channelItems; - + RSSFeed[] validFeeds; feedList.match!( (InvalidFeeds i) {}, (RSSFeed[] fl) { - ChannelItems[] tmpCh; fl.each!( (RSSFeed f) { // send task for response from server tasks[f.name].send(Task.getThis()); + // validate feeds auto resp = receiveOnly!FeedActorResponse; if(resp == FeedActorResponse.INVALID) { tasks.remove(f.name); @@ -60,26 +53,9 @@ // send data request tasks[f.name].send(FeedActorRequest.DATA_HTML); - // receive data length - auto nch = receiveOnly!RequestDataLength; - RequestDataLength chRecv = 0; - - while(chRecv < nch) { - ChannelItems chit; - chit.fname = f.name; - chit.cname = receiveOnly!string; - - RequestDataLength nit = receiveOnly!RequestDataLength; - RequestDataLength iRecv = 0; - while(iRecv < nit) { - chit.items ~= receiveOnly!RSSItem; - iRecv++; - } - channelItems ~= chit; - chRecv++; - } + validFeeds ~= f; }); - res.render!("index.dt", req, channelItems, fl); + res.render!("index.dt", req, validFeeds); }); } diff --git a/views/index.dt b/views/index.dt index bfa7e41..73de1d0 100644 --- a/views/index.dt +++ b/views/index.dt @@ -4,24 +4,14 @@ title CartaStraccia - RSS Feed Reader body h1 Cartastraccia RSS Channels - p Click channel name to read, click Source link for remote source + p Click channel name to read, click Source for remote source ul#index - uint cnt = 0; - - foreach(feed; fl) + - foreach(feed; validFeeds) - cnt++; li Feed #{cnt}: - a(href="#"~feed.name) #{feed.name} + a(href="channels/"~feed.name~".html") #{feed.name} p a(href=feed.path) View source - - foreach(chit; channelItems) - h1(id=chit.fname) #{chit.cname} - - uint icnt = 0; - - foreach(item; chit.items) - - icnt++; - b #{icnt}. #{item.title} - p - a(href=item.link) View source - p!= item.description -