-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
140 lines (118 loc) · 3.1 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
var app = require('express')();
var http = require('http');
var server = http.createServer(app);
var WebSocket = require('ws');
var wss = new WebSocket.Server({ server });
const low = require('lowdb');
const FileSync = require('lowdb/adapters/FileSync');
const db = low(new FileSync('db.json'));
const RssFeedEmitter = require('rss-feed-emitter');
const feeder = new RssFeedEmitter({ skipFirstLoad: true });
const request = require('request');
const crypto = require('crypto');
const he = require('he');
const config = require('./config.json');
// Globals
let connectMessage = JSON.stringify([{
title: "Server ist gerade beschäftigt, bitte Seite neu laden",
date: new Date().toISOString(),
link: ""
}]);
let cacheTimeout;
let feedsHash;
function updateFeeds () {
// Fetch endpoint .json
request({
url: config.endpoint
},
function (error, response, body) {
const md5 = crypto.createHash('md5').update(body).digest('hex');
if (md5 !== feedsHash) {
feedsHash = md5;
// Clear db
db.unset('log')
.write()
// Set some defaults
db.defaults({ log: [] })
.write();
// Remove all feeds
feeder.destroy();
// Add all feeds
feeder.add({
url: JSON.parse(body)
});
}
}
);
// Update feeds every hour
setTimeout(() => {
updateFeeds();
}, 60 * 60 * 1000);
}
function updateCache () {
const entries = db.get('log')
.sortBy('date')
.takeRight(25)
.value();
connectMessage = JSON.stringify(entries);
}
function removeTags (string) {
return string ? string.replace(/<(?:.|\n)*?>/gm, '').trim() : '';
}
feeder.on('new-item', item => {
// Skip empty titles
if (!item.title) {
return;
}
// Skip already existing links
const link = db.get('log')
.find({ link: item.link })
.value()
if (link) {
return;
}
// Stop current timeout
clearTimeout(cacheTimeout);
// Create item
const newItem = {
title: item.title,
date: item.date || new Date().toISOString(),
link: item.link,
summary: he.decode(removeTags(item.summary))
}
// Send to all connected clients immediately
// via WebSocket
wss.clients.forEach(function(client) {
if (client.readyState === WebSocket.OPEN ) {
client.send(JSON.stringify([newItem]));
}
});
// Push to db
db.get('log')
.push(newItem)
.write()
// Update cache after 10s if no new item comes in
cacheTimeout = setTimeout(() => {
updateCache();
}, 10000);
});
feeder.on('error', console.error);
wss.on('connection', function(socket) {
console.log('a user connected');
if (socket.readyState === WebSocket.OPEN) {
socket.send(connectMessage);
}
socket.on('message', function(message) {
if (message === 'ping' && socket.readyState === WebSocket.OPEN) {
socket.send('pong');
}
});
socket.on('close', function() {
console.log('user disconnected');
});
});
server.listen(config.port, function() {
console.log(`listening on *:${config.port}`);
});
// Kickstart
updateFeeds();