reallysimple 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +23 -0
- package/readme.md +58 -0
- package/readme.opml +54 -0
- package/reallysimple.js +179 -0
package/package.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "reallysimple",
|
|
3
|
+
"description": "Reads an RSS-like feed and calls back with a JavaScript structure, hiding all the history. It really is simple. ;-)",
|
|
4
|
+
"author": "Dave Winer <dave@scripting.com>",
|
|
5
|
+
"files": [
|
|
6
|
+
"feedread2.js"
|
|
7
|
+
],
|
|
8
|
+
"main": "reallysimple.js",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "https://github.com/scripting/feedread2.git"
|
|
12
|
+
},
|
|
13
|
+
"license": "MIT",
|
|
14
|
+
"engines": {
|
|
15
|
+
"node": "*"
|
|
16
|
+
},
|
|
17
|
+
"version": "0.4.0",
|
|
18
|
+
"dependencies" : {
|
|
19
|
+
"opml": "*",
|
|
20
|
+
"daveutils": "*",
|
|
21
|
+
"davefeedread": "*"
|
|
22
|
+
}
|
|
23
|
+
}
|
package/readme.md
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# reallysimple
|
|
2
|
+
|
|
3
|
+
Reads an RSS-like feed and calls back with a JavaScript structure, hiding all the history.
|
|
4
|
+
|
|
5
|
+
#### Why?
|
|
6
|
+
|
|
7
|
+
If it's easier to use RSS, more people will use it. If programmers can quickly put together an app that uses RSS, people will try out more ideas, add RSS support to more apps. I see this as a good thing.
|
|
8
|
+
|
|
9
|
+
I also want to include RSS verbs in a scripting language I'm working on. For scripting, simplicity is everything.
|
|
10
|
+
|
|
11
|
+
There probably is a small tradeoff in performance, you can probably write faster code by going straight to the feedparser level. And that's fine for applications that require the maximum performance, perhaps where you're reading a thousand feeds per sectond.
|
|
12
|
+
|
|
13
|
+
#### An example
|
|
14
|
+
|
|
15
|
+
#### A coding example
|
|
16
|
+
|
|
17
|
+
Here's how you call the package.
|
|
18
|
+
|
|
19
|
+
const reallysimple = require ("reallysimple");
|
|
20
|
+
|
|
21
|
+
const url = "http://scripting.com/rss.xml";
|
|
22
|
+
|
|
23
|
+
reallysimple.readFeed (url, function (err, theFeed) {
|
|
24
|
+
|
|
25
|
+
if (!err) {
|
|
26
|
+
|
|
27
|
+
console.log ("theFeed == " + JSON.stringify (theFeed));
|
|
28
|
+
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
}):
|
|
32
|
+
|
|
33
|
+
Here's what shows up in the console when you run that code.
|
|
34
|
+
|
|
35
|
+
#### What we build on
|
|
36
|
+
|
|
37
|
+
Thanks to Dan MacTough for the feedparser package which we build on.
|
|
38
|
+
|
|
39
|
+
It also builds on the davefeedread package, which simplifies the programming interface to feedparser, and returns the same complicated structure returned by feedparser.
|
|
40
|
+
|
|
41
|
+
#### Work notes
|
|
42
|
+
|
|
43
|
+
3/7/22; 10:27:47 AM by DW
|
|
44
|
+
|
|
45
|
+
Start the reallysimple repo. Publish the NPM package.
|
|
46
|
+
|
|
47
|
+
3/6/22; 11:27:52 AM by DW
|
|
48
|
+
|
|
49
|
+
It now understands various elements from the source namespace, including source:account, source:localtime and source:outline.
|
|
50
|
+
|
|
51
|
+
Started a new private GitHub repo for the project and saved the files.
|
|
52
|
+
|
|
53
|
+
Added it to my NPM sub-menu, this is going to be a supported project.
|
|
54
|
+
|
|
55
|
+
#### Comments, questions?
|
|
56
|
+
|
|
57
|
+
Please post your comments and questions in the <a href="https://github.com/scripting/reallysimple/issues/new">issues section</a> of this repo.
|
|
58
|
+
|
package/readme.opml
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="ISO-8859-1"?>
|
|
2
|
+
<opml version="2.0">
|
|
3
|
+
<head>
|
|
4
|
+
<title>readme.md</title>
|
|
5
|
+
<dateModified><%dateModified%></dateModified>
|
|
6
|
+
<expansionState></expansionState>
|
|
7
|
+
<vertScrollState>1</vertScrollState>
|
|
8
|
+
<windowTop>300</windowTop>
|
|
9
|
+
<windowLeft>700</windowLeft>
|
|
10
|
+
<windowBottom>900</windowBottom>
|
|
11
|
+
<windowRight>1500</windowRight>
|
|
12
|
+
</head>
|
|
13
|
+
<body created="Sat, 05 Mar 2022 16:54:13 GMT" text="readme.md">
|
|
14
|
+
<outline created="Sat, 05 Mar 2022 16:54:15 GMT" text="# reallysimple">
|
|
15
|
+
<outline created="Mon, 07 Mar 2022 15:05:45 GMT" text="Reads an RSS-like feed and calls back with a JavaScript structure, hiding all the history."></outline>
|
|
16
|
+
</outline>
|
|
17
|
+
<outline text="#### Why?">
|
|
18
|
+
<outline created="Mon, 07 Mar 2022 15:16:54 GMT" text="If it's easier to use RSS, more people will use it. If programmers can quickly put together an app that uses RSS, people will try out more ideas, add RSS support to more apps. I see this as a good thing."></outline>
|
|
19
|
+
<outline created="Mon, 07 Mar 2022 15:17:44 GMT" text="I also want to include RSS verbs in a scripting language I'm working on. For scripting, simplicity is everything. "></outline>
|
|
20
|
+
<outline created="Mon, 07 Mar 2022 15:18:12 GMT" text="There probably is a small tradeoff in performance, you can probably write faster code by going straight to the feedparser level. And that's fine for applications that require the maximum performance, perhaps where you're reading a thousand feeds per sectond. "></outline>
|
|
21
|
+
</outline>
|
|
22
|
+
<outline created="Mon, 07 Mar 2022 15:10:25 GMT" text="#### An example"></outline>
|
|
23
|
+
<outline created="Mon, 07 Mar 2022 15:11:02 GMT" text="#### A coding example">
|
|
24
|
+
<outline created="Mon, 07 Mar 2022 15:11:09 GMT" text="Here's how you call the package."></outline>
|
|
25
|
+
<outline created="Mon, 07 Mar 2022 15:12:02 GMT" text="const reallysimple = require ("reallysimple");"></outline>
|
|
26
|
+
<outline created="Mon, 07 Mar 2022 15:12:17 GMT" text="const url = "http://scripting.com/rss.xml";"></outline>
|
|
27
|
+
<outline created="Mon, 07 Mar 2022 15:11:18 GMT" text="reallysimple.readFeed (url, function (err, theFeed) {">
|
|
28
|
+
<outline created="Mon, 07 Mar 2022 15:12:40 GMT" text="if (!err) {">
|
|
29
|
+
<outline created="Mon, 07 Mar 2022 15:12:44 GMT" text="console.log ("theFeed == " + JSON.stringify (theFeed));"></outline>
|
|
30
|
+
<outline created="Mon, 07 Mar 2022 15:13:04 GMT" text="}"></outline>
|
|
31
|
+
</outline>
|
|
32
|
+
<outline created="Mon, 07 Mar 2022 15:11:54 GMT" text="}):"></outline>
|
|
33
|
+
</outline>
|
|
34
|
+
<outline created="Mon, 07 Mar 2022 15:10:30 GMT" text="Here's what shows up in the console when you run that code. "></outline>
|
|
35
|
+
</outline>
|
|
36
|
+
<outline created="Mon, 07 Mar 2022 15:25:06 GMT" text="#### What we build on">
|
|
37
|
+
<outline created="Mon, 07 Mar 2022 15:25:07 GMT" text="Thanks to Dan MacTough for the feedparser package which we build on."></outline>
|
|
38
|
+
<outline created="Mon, 07 Mar 2022 15:25:33 GMT" text="It also builds on the davefeedread package, which simplifies the programming interface to feedparser, and returns the same complicated structure returned by feedparser. "></outline>
|
|
39
|
+
</outline>
|
|
40
|
+
<outline created="Sat, 05 Mar 2022 17:30:26 GMT" text="#### Work notes">
|
|
41
|
+
<outline created="Mon, 07 Mar 2022 15:27:46 GMT" text="3/7/22; 10:27:47 AM by DW">
|
|
42
|
+
<outline created="Mon, 07 Mar 2022 15:27:47 GMT" text="Start the reallysimple repo. Publish the NPM package. "></outline>
|
|
43
|
+
</outline>
|
|
44
|
+
<outline created="Sun, 06 Mar 2022 16:27:50 GMT" text="3/6/22; 11:27:52 AM by DW">
|
|
45
|
+
<outline created="Sun, 06 Mar 2022 16:27:53 GMT" text="It now understands various elements from the source namespace, including source:account, source:localtime and source:outline."></outline>
|
|
46
|
+
<outline created="Sun, 06 Mar 2022 16:28:33 GMT" text="Started a new private GitHub repo for the project and saved the files. "></outline>
|
|
47
|
+
<outline created="Sun, 06 Mar 2022 16:29:01 GMT" text="Added it to my NPM sub-menu, this is going to be a supported project."></outline>
|
|
48
|
+
</outline>
|
|
49
|
+
</outline>
|
|
50
|
+
<outline created="Mon, 07 Mar 2022 15:26:41 GMT" text="#### Comments, questions?">
|
|
51
|
+
<outline created="Mon, 07 Mar 2022 15:26:47 GMT" text="Please post your comments and questions in the <a href="https://github.com/scripting/reallysimple/issues/new">issues section</a> of this repo."></outline>
|
|
52
|
+
</outline>
|
|
53
|
+
</body>
|
|
54
|
+
</opml>
|
package/reallysimple.js
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
var myProductName = "reallysimple"; myVersion = "0.4.0";
|
|
2
|
+
|
|
3
|
+
exports.readFeed = readFeed;
|
|
4
|
+
exports.convertFeedToOpml = convertFeedToOpml;
|
|
5
|
+
|
|
6
|
+
const utils = require ("daveutils");
|
|
7
|
+
const request = require ("request");
|
|
8
|
+
const feedRead1 = require ("davefeedread");
|
|
9
|
+
|
|
10
|
+
const allowedHeadNames = [
|
|
11
|
+
"title", "link", "description", "language", "copyright", "managingEditor", "webMaster", "lastBuildDate", "pubDate", "category",
|
|
12
|
+
"generator", "docs", "cloud", "ttl", "image", "rating", "textInput", "skipHours", "skipDays", "source:account", "source:localtime"
|
|
13
|
+
];
|
|
14
|
+
const allowedItemNames = [
|
|
15
|
+
"title", "link", "description", "author", "category", "comments", "enclosure", "guid", "pubDate", "source", "source:outline", "source:likes"
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
var config = {
|
|
19
|
+
timeOutSecs: 3
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function isEmptyObject (obj) {
|
|
23
|
+
return (Object.keys (obj).length === 0);
|
|
24
|
+
}
|
|
25
|
+
function getItemPermalink (item) {
|
|
26
|
+
var rssguid = item ["rss:guid"], returnedval = undefined;
|
|
27
|
+
if (rssguid !== undefined) {
|
|
28
|
+
var atts = rssguid ["@"];
|
|
29
|
+
if (atts.ispermalink === undefined) {
|
|
30
|
+
returnedval = rssguid ["#"];
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
if (utils.getBoolean (atts.ispermalink)) {
|
|
34
|
+
returnedval = rssguid ["#"];
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
if (returnedval !== undefined) {
|
|
39
|
+
if (utils.beginsWith (returnedval, "http")) {
|
|
40
|
+
return (returnedval);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return (undefined);
|
|
44
|
+
}
|
|
45
|
+
function convertFeedToOpml (theFeed) {
|
|
46
|
+
var theOutline = {
|
|
47
|
+
opml: {
|
|
48
|
+
head: {
|
|
49
|
+
title: theFeed.title
|
|
50
|
+
},
|
|
51
|
+
body: {
|
|
52
|
+
subs: new Array ()
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
theFeed.items.forEach (function (item) {
|
|
57
|
+
var linetext, subtext;
|
|
58
|
+
if (item.title === undefined) {
|
|
59
|
+
linetext = item.description;
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
linetext = item.title;
|
|
63
|
+
subtext = item.description;
|
|
64
|
+
}
|
|
65
|
+
theOutline.opml.body.subs.push ({
|
|
66
|
+
text: linetext,
|
|
67
|
+
type: "link",
|
|
68
|
+
url: item.link
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
return (opml.stringify (theOutline));
|
|
72
|
+
}
|
|
73
|
+
function convertFeed (oldFeed) {
|
|
74
|
+
|
|
75
|
+
var newFeed = new Object ();
|
|
76
|
+
|
|
77
|
+
function convertOutline (jstruct) {
|
|
78
|
+
var theNewOutline = {};
|
|
79
|
+
if (jstruct ["@"] !== undefined) {
|
|
80
|
+
utils.copyScalars (jstruct ["@"], theNewOutline);
|
|
81
|
+
}
|
|
82
|
+
if (jstruct ["source:outline"] !== undefined) {
|
|
83
|
+
if (jstruct ["source:outline"] instanceof Array) {
|
|
84
|
+
var theArray = jstruct ["source:outline"];
|
|
85
|
+
theNewOutline.subs = [];
|
|
86
|
+
theArray.forEach (function (item) {
|
|
87
|
+
theNewOutline.subs.push (convertOutline (item));
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
theNewOutline.subs = [
|
|
92
|
+
convertOutline (jstruct ["source:outline"])
|
|
93
|
+
];
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return (theNewOutline);
|
|
97
|
+
}
|
|
98
|
+
function getHeadValuesFromFirstItem () { //3/6/22 by DW
|
|
99
|
+
if (oldFeed.items.length > 0) {
|
|
100
|
+
var item = oldFeed.items [0];
|
|
101
|
+
if (item.meta !== undefined) {
|
|
102
|
+
if (item.meta ["source:account"] !== undefined) {
|
|
103
|
+
var account = item.meta ["source:account"];
|
|
104
|
+
newFeed.accounts = new Object ();
|
|
105
|
+
if (Array.isArray (account)) {
|
|
106
|
+
account.forEach (function (item) {
|
|
107
|
+
var service = item ["@"].service
|
|
108
|
+
var name = item ["#"];
|
|
109
|
+
newFeed.accounts [service] = name;
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
var service = account ["@"].service; //something like twitter
|
|
114
|
+
var name = account ["#"];
|
|
115
|
+
newFeed.accounts [service] = name;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (item.meta ["source:localtime"] !== undefined) {
|
|
119
|
+
var localtime = item.meta ["source:localtime"];
|
|
120
|
+
newFeed.localtime = localtime ["#"];
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
for (var x in oldFeed.head) {
|
|
127
|
+
let val = oldFeed.head [x];
|
|
128
|
+
if (val != null) {
|
|
129
|
+
allowedHeadNames.forEach (function (name) {
|
|
130
|
+
if (x == name) {
|
|
131
|
+
newFeed [x] = val;
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
getHeadValuesFromFirstItem (); //3/6/22 by DW
|
|
138
|
+
|
|
139
|
+
if (isEmptyObject (newFeed.image)) {
|
|
140
|
+
delete newFeed.image;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
newFeed.items = new Array ();
|
|
144
|
+
oldFeed.items.forEach (function (item) {
|
|
145
|
+
var newItem = new Object ();
|
|
146
|
+
for (var x in item) {
|
|
147
|
+
val = item [x];
|
|
148
|
+
if (val != null) {
|
|
149
|
+
allowedItemNames.forEach (function (name) {
|
|
150
|
+
if (x == name) {
|
|
151
|
+
if (x == "source:outline") {
|
|
152
|
+
val = convertOutline (item ["source:outline"]);
|
|
153
|
+
}
|
|
154
|
+
newItem [x] = val;
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
newItem.guid = getItemPermalink (item);
|
|
160
|
+
if (isEmptyObject (newItem.source)) {
|
|
161
|
+
delete newItem.source;
|
|
162
|
+
}
|
|
163
|
+
newFeed.items.push (newItem);
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
return (newFeed);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function readFeed (url, callback) {
|
|
170
|
+
feedRead1.parseUrl (url, config.timeOutSecs, function (err, theFeed) {
|
|
171
|
+
if (err) {
|
|
172
|
+
callback (err);
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
callback (undefined, convertFeed (theFeed));
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
|