-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
executable file
·141 lines (127 loc) · 5.17 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
141
const express = require('express');
const bodyParser = require('body-parser');
const GithubNews = require('./lib/githubnews');
const DockerNews = require('./lib/dockernews');
const Notifier = require('./lib/notifier');
class Main {
async createOrUpdateFeed(feed) {
return this.datastore.createOrUpdate(feed);
}
async read(owner) {
return this.datastore.readSingle(owner);
}
async readMultiple() {
return this.datastore.readMultiple();
}
async write(feed) {
return this.datastore.write(feed);
}
process(feed) {
return Promise.all(feed.repositories
.map((repository) => {
if (repository.type === 'github')
return this.ghn.inquireRepo(repository);
if (repository.type === 'docker')
return this.dockern.inquireRepo(repository);
}))
.then(async result => {
let results = [];
let news = [];
for (let i = 0; i < result.length; i++) {
let repository = result[i];
if (!repository._current || repository._current != repository.latest) {
await this.notifier.notify(feed.notifications, repository)
repository._current = repository.latest;
news.push(repository);
}
results.push(repository);
}
feed.repositories = results;
return Promise.resolve({feed:feed, news: news});
});
}
async run(owner, persist) {
let feeds = [];
feeds = owner ? [await this.read(owner)] : await this.readMultiple();
if (owner && (feeds.length == 0 || !feeds[0]))
return Promise.reject({message: 'profile not found'});
return Promise.all(feeds.map(feed => {
return this.process(feed)
.then((result) => {
if (persist !== 'false')
this.write(result.feed);
return { owner: result.feed.owner, news:result.news };
})
}
));
}
constructor(){
this.ghn = new GithubNews();
this.dockern = new DockerNews();
let Datastore = null;
if (process.env.DATASTORE == 'file')
Datastore = require('./lib/FileDataStore');
else
Datastore = require('./lib/GoogleDataStore');
this.datastore = new Datastore();
this.notifier = new Notifier();
}
}
const app = express();
app.use(bodyParser.json());
const main = new Main();
// health request
app.get('/health', (req, res) => {
res.status(200).send('UP');
});
// create or update feed
async function createOrUpdateFeed(req,res) {
if (!req.headers.apikey || req.headers.apikey !== process.env.APIKEY)
return res.status(401).json({"success": false, "cause": "no or wrong apikey"});
const contentType = req.headers["content-type"] || req.headers["Content-Type"];
if (contentType !== 'application/json')
return res.status(400).json({"success": false, "cause": "content-type not application/json"});
const feed = req.body;
feed.owner = req.params.owner;
let retval = await main.createOrUpdateFeed(feed);
res.status(200).send(retval);
}
app.post('/feeds/:owner', async (req, res) => createOrUpdateFeed(req, res));
app.put('/feeds/:owner', async (req, res) => createOrUpdateFeed(req, res));
// get feed
async function getFeed(req, res) {
if (!req.headers.apikey || req.headers.apikey !== process.env.APIKEY)
return res.status(401).json({"success": false, "cause": "no or wrong apikey"});
const data = await main.read(req.params.owner);
if (data) return res.json(data);
res.status(404).send('Not found');
}
app.get('/feeds/:owner', async (req, res) => getFeed(req, res));
// fetch news for feed - either for just one owner or for all users using cron
async function fetchNews(req, res) {
main.run(req.params && req.params.owner, req.query.persist)
.then(news => {
console.log('Sync successful', JSON.stringify(news));
res.status(200).json({"status":"success", "news": news});
})
.catch(error => {
console.error(`Sync failed ${error.message}`, error);
res.status(200).json({"status":"failed", "cause": error.message});
});
}
app.get('/feeds/:owner/update', (req, res) => {
if (!req.headers.apikey || req.headers.apikey !== process.env.APIKEY)
return res.status(401).json({"success": false, "cause": "no or wrong apikey"});
return fetchNews(req, res);
});
app.get('/github-news/cron/update', (req, res) => {
if (process.env.CRON
&& req.headers['x-appengine-cron'] !== "true"
&& req.headers['x-appengine-queuename'] !== "__cron")
return res.status(403).json({"status":"failed", "cause": "not cron"});
return fetchNews(req, res);
});
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
console.log(`Listening on port ${PORT}!`);
});