-
Notifications
You must be signed in to change notification settings - Fork 36
/
app.js
143 lines (117 loc) · 4.77 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
136
137
138
139
140
141
142
143
/**
* Module dependencies.
*/
var express = require('express')
, io = require('socket.io')
, http = require('http')
, twitter = require('ntwitter')
, cronJob = require('cron').CronJob
, _ = require('underscore')
, path = require('path');
//Create an express app
var app = express();
//Create the HTTP server with the express app as an argument
var server = http.createServer(app);
// IMPORTANT!!
//You will need to get your own key. Don't worry, it's free. But I cannot provide you one
//since it will instantiate a connection on my behalf and will drop all other streaming connections.
//Check out: https://dev.twitter.com/ You should be able to create an application and grab the following
//crednetials from the API Keys section of that application.
var api_key = ''; // <---- Fill me in
var api_secret = ''; // <---- Fill me in
var access_token = ''; // <---- Fill me in
var access_token_secret = ''; // <---- Fill me in
// Twitter symbols array.
var watchSymbols = ['$msft', '$intc', '$hpq', '$goog', '$nok', '$nvda', '$bac', '$orcl', '$csco', '$aapl', '$ntap', '$emc', '$t', '$ibm', '$vz', '$xom', '$cvx', '$ge', '$ko', '$jnj'];
//This structure will keep the total number of tweets received and a map of all the symbols and how many tweets received of that symbol
var watchList = {
total: 0,
symbols: {}
};
//Set the watch symbols to zero.
_.each(watchSymbols, function(v) { watchList.symbols[v] = 0; });
//Generic Express setup
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(require('stylus').middleware(__dirname + '/public'));
app.use(express.static(path.join(__dirname, 'public')));
//We're using bower components so add it to the path to make things easier
app.use('/components', express.static(path.join(__dirname, 'components')));
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
//Our only route! Render it with the current watchList
app.get('/', function(req, res) {
res.render('index', { data: watchList });
});
//Start a Socket.IO listen
var sockets = io.listen(server);
//Set the sockets.io configuration.
//THIS IS NECESSARY ONLY FOR HEROKU!
sockets.configure(function() {
sockets.set('transports', ['xhr-polling']);
sockets.set('polling duration', 10);
});
//If the client just connected, give them fresh data!
sockets.sockets.on('connection', function(socket) {
socket.emit('data', watchList);
});
// Instantiate the twitter connection
var t = new twitter({
consumer_key: api_key,
consumer_secret: api_secret,
access_token_key: access_token,
access_token_secret: access_token_secret
});
// //Tell the twitter API to filter on the watchSymbols
t.stream('statuses/filter', { track: watchSymbols }, function(stream) {
//We have a connection. Now watch the 'data' event for incomming tweets.
stream.on('data', function(tweet) {
//This variable is used to indicate whether a symbol was actually mentioned.
//Since twitter doesnt why the tweet was forwarded we have to search through the text
//and determine which symbol it was ment for. Sometimes we can't tell, in which case we don't
//want to increment the total counter...
var claimed = false;
//Make sure it was a valid tweet
if (tweet.text !== undefined) {
//We're gunna do some indexOf comparisons and we want it to be case agnostic.
var text = tweet.text.toLowerCase();
//Go through every symbol and see if it was mentioned. If so, increment its counter and
//set the 'claimed' variable to true to indicate something was mentioned so we can increment
//the 'total' counter!
_.each(watchSymbols, function(v) {
if (text.indexOf(v.toLowerCase()) !== -1) {
watchList.symbols[v]++;
claimed = true;
}
});
//If something was mentioned, increment the total counter and send the update to all the clients
if (claimed) {
//Increment total
watchList.total++;
//Send to all the clients
sockets.sockets.emit('data', watchList);
}
}
});
});
//Reset everything on a new day!
//We don't want to keep data around from the previous day so reset everything.
new cronJob('0 0 0 * * *', function(){
//Reset the total
watchList.total = 0;
//Clear out everything in the map
_.each(watchSymbols, function(v) { watchList.symbols[v] = 0; });
//Send the update to the clients
sockets.sockets.emit('data', watchList);
}, null, true);
//Create the server
server.listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});