Skip to content

Commit 35a4946

Browse files
author
Oliver Schneider
committed
Initial commit
0 parents  commit 35a4946

File tree

9 files changed

+2707
-0
lines changed

9 files changed

+2707
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules
2+
/cache/

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Pimatic Updater Server API
2+
3+
Install
4+
5+
```
6+
npm install
7+
```
8+
9+
Make sure coffeescript is installed.
10+
11+
```
12+
npm install coffeescript -g
13+
```
14+
15+
Run
16+
17+
```
18+
coffee server.coffee
19+
```

app.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
/**
3+
* Application configuration section
4+
* http://pm2.keymetrics.io/docs/usage/application-declaration/
5+
*/
6+
"apps" : [
7+
{
8+
"name" : "update-server",
9+
"script" : "server.coffee",
10+
"env_production" : {
11+
"NODE_ENV": "production"
12+
},
13+
"log_date_format" : "YYYY-MM-DD HH:mm Z",
14+
"out_file": "update-server.log",
15+
"error_file": "update-server.log"
16+
},
17+
],
18+
}

cache/.gitkeep

Whitespace-only changes.

monitor.coffee

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
Promise = require 'bluebird'
2+
npmregistry = require('./npmregistry')
3+
events = require('events')
4+
5+
onError = (error) -> console.error error.stack
6+
7+
class PluginMonitor extends events.EventEmitter
8+
9+
pluginsList: null
10+
packageInfos: null
11+
12+
constructor: ->
13+
super()
14+
@pluginsList = npmregistry.getPluginListCached().then( (plugins) =>
15+
@packageInfos = Promise.map(@pluginsList, (name) =>
16+
return npmregistry.getInfoCached(name)
17+
).catch( (error) =>
18+
onError(error)
19+
@packageInfos = null
20+
)
21+
return plugins
22+
)
23+
24+
updatePluginList: =>
25+
oldPluginsList = @pluginsList or Promise.resolve([])
26+
pending = npmregistry.getPluginList()
27+
.then( (plugins) =>
28+
return oldPluginsList.then( (oldPlugins) =>
29+
if plugins.length is 0
30+
# something went wrong
31+
plugins = oldPlugins
32+
@pluginsList = Promise.resolve(plugins)
33+
for p in plugins
34+
unless p in oldPlugins
35+
@emit 'new', p
36+
return @pluginsList
37+
)
38+
).catch(onError)
39+
unless @pluginsList?
40+
@pluginsList = pending
41+
# reschedule next hour to update
42+
setTimeout(@updatePluginList, 60*60*1000)
43+
44+
updateNpmInfos: =>
45+
oldPackageInfos = @packageInfos or Promise.resolve([])
46+
pending = oldPackageInfos.then( (oldPackageInfos) =>
47+
return @pluginsList.map( (name) =>
48+
return npmregistry.getInfo(name).then( (info) =>
49+
@_checkForUpdate(oldPackageInfos, info)
50+
return info
51+
).catch( (error) =>
52+
onError(error)
53+
return Promise.resolve()
54+
)
55+
).filter( (p) => p? ).then( (infos) =>
56+
return @packageInfos = Promise.resolve(infos)
57+
)
58+
).catch(onError)
59+
unless @packageInfos?
60+
@packageInfos = pending
61+
# reschedule next 5min
62+
setTimeout(@updateNpmInfos, 5*60*1000)
63+
64+
start: ->
65+
@updatePluginList()
66+
@updateNpmInfos()
67+
68+
_checkForUpdate: (oldPackageInfos, info) ->
69+
for op in oldPackageInfos
70+
if op.name is info.name
71+
if op.version isnt info.version
72+
@emit 'update', info
73+
return
74+
@emit 'update', info
75+
return
76+
77+
getPluginList: -> @pluginsList
78+
getNpmInfos: -> @packageInfos
79+
80+
module.exports = {PluginMonitor}

npmregistry.coffee

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
Promise = require 'bluebird'
2+
prequest = require 'request-promise'
3+
request = require 'request'
4+
exec = require('child_process').exec
5+
6+
JSONStream = require('JSONStream')
7+
es = require('event-stream')
8+
9+
fs = require('fs')
10+
Promise.promisifyAll(fs)
11+
12+
module.exports = {
13+
14+
getInfo: (name) ->
15+
prequest("https://registry.npmjs.org/#{name}").then( (res) ->
16+
info = JSON.parse(res)
17+
if info.error?
18+
throw new Error("getting info about #{name} failed: #{info.reason}")
19+
return fs.writeFileAsync("cache/#{name}.json", res)
20+
.then( () => info )
21+
)
22+
23+
getInfoCached: (name) ->
24+
return fs.readFileAsync("cache/#{name}.json").then( (data) =>
25+
return JSON.parse(data)
26+
)
27+
28+
getAllPlugins: () ->
29+
console.log "Fetching plugins"
30+
last = null
31+
count = 0
32+
return new Promise( (resolve, reject) =>
33+
packages = []
34+
request(url: 'https://registry.npmjs.org/-/v1/search?text=pimatic-&size=250', (error, response, body) =>
35+
if error
36+
console.error(error, response.statusCode)
37+
reject(error)
38+
)
39+
.pipe(JSONStream.parse('objects..name'))
40+
.on('error', (err) ->
41+
console.error(err)
42+
reject(err)
43+
)
44+
.pipe es.mapSync (data) ->
45+
count++
46+
last = data
47+
if data.indexOf("pimatic-") is 0
48+
return data
49+
else
50+
return
51+
.pipe es.writeArray (err, data) ->
52+
if(err)
53+
reject(err)
54+
else
55+
if data.length > 10
56+
data.sort()
57+
resolve(data)
58+
else
59+
reject(new Error('Incomplete data from npm registry: ' + data))
60+
)
61+
62+
getPluginListCached: () ->
63+
return fs.readFileAsync('cache/pluginlist.json').then( (data) =>
64+
return JSON.parse(data)
65+
).catch( (err) ->
66+
if(err.code == 'NOENT')
67+
return []
68+
throw err
69+
)
70+
71+
getPluginList: () ->
72+
return this.getAllPlugins().then( (allPlugins) =>
73+
blacklist = [
74+
'pimatic-plugin-template', 'pimatic-rest-api', 'pimatic-speak-api',
75+
"pimatic-datalogger", "pimatic-redirect", "pimatic-datalogger",
76+
"pimatic-homeduino-dst-dev", "pimatic-iwy-light-master", "pimatic-weather",
77+
"pimatic-pilight", "pimatic-plugin-iwy-light-master", "pimatic-dhtxx",
78+
"pimatic-plugin-commons"
79+
]
80+
plugins = (
81+
for p in allPlugins
82+
continue if p.length is 0 or p in blacklist
83+
p
84+
)
85+
plugins = ["pimatic"].concat plugins
86+
return fs.writeFileAsync('cache/pluginlist.json', JSON.stringify(plugins))
87+
.then( () => plugins )
88+
)
89+
90+
}

0 commit comments

Comments
 (0)