forked from edsu/wikistream
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.js
135 lines (105 loc) · 3.19 KB
/
app.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
// imports
var fs = require('fs'),
sys = require('sys'),
path = require('path'),
redis = require('redis'),
sio = require('socket.io'),
express = require('express');
// little helper to package up zrevrange redis query results
function zresults(resp) {
results = []
for (var i=0; i < resp.length; i+=2) {
r = JSON.parse(resp[i]);
r['score'] = resp[i+1];
results.push(r)
}
return results;
}
// get the configuration
var configPath = path.join(__dirname, "config.json");
var config = JSON.parse(fs.readFileSync(configPath));
var app = module.exports = express.createServer();
var requestCount = 0;
// get the wikipedia shortnames sorted by their longname
var wikisSorted = [];
for (var chan in config.wikipedias) wikisSorted.push(chan);
wikisSorted.sort(function(a, b) {
w1 = config.wikipedias[a].long;
w2 = config.wikipedias[b].long;
if (w1 == w2) return 0;
else if (w1 < w2) return -1;
else if (w1 > w2) return 1;
});
// set up the web app
app.configure(function(){
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});
app.configure('development', function(){
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});
app.configure('production', function(){
app.use(express.errorHandler());
});
app.get('/', function(req, res){
res.render('index', {
title: 'wikistream',
wikis: config.wikipedias,
wikisSorted: wikisSorted
});
});
app.get('/trends/', function(req, res){
res.render('trends', {
title: 'wikistream daily trends',
});
});
app.get('/about/', function(req, res){
res.render('about', {
title: 'about wikistream',
});
});
// TODO: might be able to create one stats view that does all these?
stats = redis.createClient(),
app.get('/stats/users-daily.json', function(req, res){
stats.zrevrange(['users-daily', 0, 99, 'withscores'], function(e, r) {
res.send(zresults(r));
});
});
app.get('/stats/articles-daily.json', function(req, res){
stats.zrevrange(['articles-daily', 0, 99, 'withscores'], function (e, r) {
res.send(zresults(r));
});
});
app.get('/stats/articles-hourly.json', function(req, res){
stats.zrevrange(['articles-hourly', 0, 99, 'withscores'], function (e, r) {
res.send(zresults(r));
});
});
app.get('/stats/robots-daily.json', function(req, res){
stats.zrevrange(['robots-daily', 0, 99, 'withscores'], function (e, r) {
res.send(zresults(r));
});
});
app.listen(3000);
// set up the socket.io update stream
var io = sio.listen(app);
io.configure('production', function() {
io.set('log level', 2);
// disabled websocket since it doesn't seem to work with node http-proxy
// which I am using on inkdroid.org to partition traffic YMMV
io.set('transports', ['flashsocket', 'htmlfile', 'xhr-polling', 'jsonp-polling']);
});
io.sockets.on('connection', function(socket) {
var updates = redis.createClient();
updates.subscribe('wikipedia');
updates.on("message", function (channel, message) {
socket.send(message);
});
socket.on('disconnect', function() {
updates.quit();
});
});