From 0b9e50ee8589a4517743e214d5dc8d6815f399a2 Mon Sep 17 00:00:00 2001 From: Dave Winer Date: Thu, 16 Jul 2015 09:08:12 -0400 Subject: [PATCH] v0.65 --- README.md | 8 ++++ lib/opml.js | 103 ++++++++++++++++++++++++++++------------------- lib/utils.js | 28 ++++++++----- pagepark.js | 63 ++++++++++++++++------------- prefs/error.html | 8 ++++ 5 files changed, 132 insertions(+), 78 deletions(-) create mode 100644 prefs/error.html diff --git a/README.md b/README.md index eb07f8b..e817e04 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,14 @@ There will always be more work to do here. ;-) #### Updates +##### v0.65 7/16/15 by DW + +In prefs.json a new value, error404File, defaults to prefs/error.html + +When there's an error, we read that file and send it back as the text of the 404 response. + +The default value is more or less exactly the same text earlier versions of PagePark returned. It's actually in HTML, that's the difference. As opposed to being plain text. + ##### v0.64 7/7/15 by DW I wanted to do a site redirect that was more than just a domain name change. diff --git a/lib/opml.js b/lib/opml.js index ab9d478..3a9b439 100644 --- a/lib/opml.js +++ b/lib/opml.js @@ -10,7 +10,7 @@ var opmlParser = require ("opmlparser"); //6/23/15 by DW var opmlData = { flUseOutlineCache: false, - outlineCache: new Object () + outlineCache: new Object (), } function getBoolean (val) { //12/5/13 by DW @@ -72,10 +72,6 @@ function getNameAtt (theNode) { } return (nameatt); } -function typeIsDoc (theNode) { - var type = getNodeType (theNode); - return ((type !== undefined) && (type != "include") && (type != "link") && (type != "tweet")); - } function getNodeType (theNode) { if (theNode.type == "include") { return (theNode.includetype); //this allows include nodes to have types @@ -96,20 +92,29 @@ function copyScalars (source, dest) { //8/31/14 by DW } } } -function readInclude (theIncludeNode, callback) { - console.log ("readInclude: url == " + theIncludeNode.url); - readOpmlUrl (theIncludeNode.url, function (theOutline) { - if (theOutline === undefined) { - callback (undefined); +function outlineVisiter (theOutline, inlevelcallback, outlevelcallback, nodecallback, visitcompletecallback, flStopAtDocs) { + function readInclude (theIncludeNode, callback) { + console.log ("readInclude: url == " + theIncludeNode.url); + readOpmlUrl (theIncludeNode.url, function (theOutline) { + if (theOutline === undefined) { + callback (undefined); + } + else { + expandIncludes (theOutline, function (expandedOutline) { + callback (expandedOutline); + }, flStopAtDocs); + } + }); + } + function typeIsDoc (theNode) { + if (flStopAtDocs) { + var type = getNodeType (theNode); + return ((type !== undefined) && (type != "include") && (type != "link") && (type != "tweet")); } else { - expandIncludes (theOutline, function (expandedOutline) { - callback (expandedOutline); - }); + return (false); } - }); - } -function outlineVisiter (theOutline, inlevelcallback, outlevelcallback, nodecallback, visitcompletecallback) { + } function doLevel (head, path, levelcompletecallback) { function doOneSub (head, ixsub) { if ((head.subs !== undefined) && (ixsub < head.subs.length)) { @@ -171,12 +176,17 @@ function outlineVisiter (theOutline, inlevelcallback, outlevelcallback, nodecall doOneSub (head, 0); } } + + if (flStopAtDocs === undefined) { //7/15/15 by DW -- see note at top of routine + flStopAtDocs = true; + } + doLevel (theOutline, "", function () { outlevelcallback (); visitcompletecallback (); }); } -function expandIncludes (theOutline, callback) { +function expandIncludes (theOutline, callback, flStopAtDocs) { var theNewOutline = new Object (), lastNewNode = theNewOutline, stack = new Array (), currentOutline; function inlevelcallback () { stack [stack.length] = currentOutline; @@ -195,11 +205,16 @@ function expandIncludes (theOutline, callback) { currentOutline = stack [stack.length - 1]; stack.length--; //pop the stack } + + if (flStopAtDocs === undefined) { //7/15/15 by DW + flStopAtDocs = true; + } + outlineVisiter (theOutline, inlevelcallback, outlevelcallback, nodecallback, function () { callback (theNewOutline); - }); + }, flStopAtDocs); } -function readOpmlString (s, callback) { +function readOpmlString (s, callback, flExpandIncludes) { var opmlparser = new opmlParser (); var outlineArray = new Array (); var metadata = undefined; @@ -265,14 +280,24 @@ function readOpmlString (s, callback) { delete obj ["#parentid"]; } } - expandIncludes (theOutline, function (expandedOutline) { + + if (flExpandIncludes === undefined) { //7/15/15 by DW + flExpandIncludes = true; + } + if (flExpandIncludes) { + expandIncludes (theOutline, function (expandedOutline) { + if (callback != undefined) { + callback (expandedOutline, undefined); + } + }, false); + } + else { if (callback != undefined) { - callback (expandedOutline, undefined); + callback (theOutline, undefined); } - }); + } }); } - function readOpmlFile (f, callback) { //6/25/15 by DW fs.readFile (f, function (err, data) { if (err) { @@ -284,28 +309,24 @@ function readOpmlFile (f, callback) { //6/25/15 by DW } }); } - -function readOpmlUrl (urlOutline, callback) { - if (urlOutline === undefined) { //6/28/15 by DW - console.log ("readOpmlUrl: urlOutline is undefined.") - callback (undefined); +function readOpmlUrl (urlOutline, callback, flExpandIncludes) { + if (flExpandIncludes === undefined) { + flExpandIncludes = true; } - else { - request (urlOutline, function (err, response, body) { - if (err !== null) { - console.log ("readOpmlUrl: error reading file " + urlOutline + " == " + err.message) + request (urlOutline, function (err, response, body) { + if (err !== null) { + console.log ("readOpmlUrl: error reading file " + urlOutline + " == " + err.message) + callback (undefined); + } + else { + if (response.statusCode != 200) { + console.log ("readOpmlUrl: error reading file, statusCode == " + response.statusCode + ", urlOutline == " + urlOutline) callback (undefined); } else { - if (response.statusCode != 200) { - console.log ("readOpmlUrl: error reading file, statusCode == " + response.statusCode + ", urlOutline == " + urlOutline) - callback (undefined); - } - else { - readOpmlString (body.toString (), callback); - } + readOpmlString (body.toString (), callback, flExpandIncludes); } - }); - } + } + }); } diff --git a/lib/utils.js b/lib/utils.js index 85b4d24..61bd789 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -20,6 +20,13 @@ exports.replaceAll = replaceAll; //2/17/15 by DW exports.kilobyteString = kilobyteString; exports.megabyteString = megabyteString; exports.gigabyteString = gigabyteString; +exports.stringLower = stringLower; +exports.filledString = filledString; +exports.innerCaseName = innerCaseName; +exports.copyScalars = copyScalars; +exports.stripMarkup = stripMarkup; +exports.replaceAll = replaceAll; +exports.hotUpText = hotUpText; function sameDay (d1, d2) { //returns true if the two dates are on the same day @@ -138,6 +145,9 @@ function stringContains (s, whatItMightContain, flUnicase) { //11/9/14 by DW return (s.indexOf (whatItMightContain) != -1); } function beginsWith (s, possibleBeginning, flUnicase) { + if (s === undefined) { //7/15/15 by DW + return (false); + } if (s.length == 0) { //1/1/14 by DW return (false); } @@ -485,16 +495,16 @@ function hotUpText (s, url) { //7/18/14 by DW s = leftpart + linktext + rightpart; return (s); } +function getDomainFromUrl (url) { //7/11/15 by DW + if ((url != null ) && (url != "")) { + url = url.replace("www.","").replace("www2.", "").replace("feedproxy.", "").replace("feeds.", ""); + var root = url.split('?')[0]; // cleans urls of form http://domain.com?a=1&b=2 + url = root.split('/')[2]; + } + return (url); + }; function getFavicon (url) { //7/18/14 by DW - function getDomain (url) { - if ((url != null ) && (url != "")) { - url = url.replace("www.","").replace("www2.", "").replace("feedproxy.", "").replace("feeds.", ""); - var root = url.split('?')[0]; // cleans urls of form http://domain.com?a=1&b=2 - var url = root.split('/')[2]; - } - return (url); - }; - var domain = getDomain (url); + var domain = getDomainFromUrl (url); return ("http://www.google.com/s2/favicons?domain=" + domain); }; function getURLParameter (name) { //7/21/14 by DW diff --git a/pagepark.js b/pagepark.js index 35ce5dd..e93f084 100644 --- a/pagepark.js +++ b/pagepark.js @@ -1,29 +1,29 @@ -var myVersion = "0.63a", myProductName = "PagePark"; - - //The MIT License (MIT) - - //Copyright (c) 2014 Dave Winer - - //Permission is hereby granted, free of charge, to any person obtaining a copy - //of this software and associated documentation files (the "Software"), to deal - //in the Software without restriction, including without limitation the rights - //to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - //copies of the Software, and to permit persons to whom the Software is - //furnished to do so, subject to the following conditions: +var myVersion = "0.65a", myProductName = "PagePark"; + +/* The MIT License (MIT) + Copyright (c) 2014-2015 Dave Winer - //The above copyright notice and this permission notice shall be included in all - //copies or substantial portions of the Software. + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: - //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - //SOFTWARE. + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. - //structured listing: http://scripting.com/listings/pagepark.html + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + structured listing: http://scripting.com/listings/pagepark.html + */ + var fs = require ("fs"); var request = require ("request"); var urlpack = require ("url"); @@ -41,7 +41,8 @@ var pageparkPrefs = { indexFilename: "index", flProcessScriptFiles: true, extScriptFiles: "js", //5/5/15 by DW flProcessMarkdownFiles: true, extMarkdownFiles: "md", //5/5/15 by DW - flProcessOpmlFiles: true, extOpmlFiles: "opml" //6/23/15 by DW + flProcessOpmlFiles: true, extOpmlFiles: "opml", //6/23/15 by DW + error404File: "prefs/error.html" //7/16/15 by DW }; var fnamePrefs = "prefs/prefs.json"; @@ -63,6 +64,9 @@ var urlDefaultMarkdownTemplate = "http://fargo.io/code/pagepark/defaultmarkdownt var opmlTemplatePath = "prefs/opmlTemplate.txt"; var urlDefaultOpmlTemplate = "http://fargo.io/code/pagepark/defaultopmltemplate.txt"; +var urlDefaultErrorPage = "http://fargo.io/code/pagepark/prefs/error.html"; //7/16/15 by DW + + function fsSureFilePath (path, callback) { var splits = path.split ("/"); path = ""; //1/8/15 by DW @@ -239,15 +243,18 @@ function handleHttpRequest (httpRequest, httpResponse) { }); } function return404 () { - httpResponse.writeHead (404, {"Content-Type": "text/plain"}); - httpResponse.end ("The file was not found."); + getTemplate (pageparkPrefs.error404File, urlDefaultErrorPage, function (htmtext) { + httpResponse.writeHead (404, {"Content-Type": "text/html"}); + httpResponse.end (htmtext); + }); } - function findIndexFile (folder, callback) { + function findSpecificFile (folder, specificFname, callback) { + specificFname = specificFname.toLowerCase (); //7/16/15 by DW fs.readdir (folder, function (err, list) { for (var i = 0; i < list.length; i++) { var fname = list [i]; if (utils.stringCountFields (fname, ".") == 2) { //something like xxx.yyy - if (utils.stringNthField (fname, ".", 1).toLowerCase () == pageparkPrefs.indexFilename) { //something like index.wtf + if (utils.stringNthField (fname, ".", 1).toLowerCase () == specificFname) { //something like index.wtf callback (folder + fname); return; } @@ -497,7 +504,7 @@ function handleHttpRequest (httpRequest, httpResponse) { if (!utils.endsWith (f, "/")) { f += "/"; } - findIndexFile (f, function (findex) { + findSpecificFile (f, pageparkPrefs.indexFilename, function (findex) { serveFile (findex, config); }); } diff --git a/prefs/error.html b/prefs/error.html new file mode 100644 index 0000000..c3d068d --- /dev/null +++ b/prefs/error.html @@ -0,0 +1,8 @@ + + + File not found + + + The file was not found. + +