server-side-source/utils/format-for-keyword-vis.coffee
Tweet = require '../models/Tweet' # The Tweet model
MakeSummarySentences = require '../utils/make-summary-sentences'
removeWords = require 'remove-words'
sentimentAnalysis = require 'sentiment-analysis'
FetchTweets = require 'fetch-tweets'
# API keys
twitterKey = require('../config/keys').twitter
fetchTweets = new FetchTweets twitterKey
class FormatWordsForCloud
# Converts ordinary Tweet array to suitable form for word cloud
formatResultsForCloud= (twitterResults, allWords = false) ->
results = []
tweetWords = makeTweetWords twitterResults
for word in tweetWords
sent = sentimentAnalysis word
if allWords or sent != 0
f = results.filter((item) -> item.text == word)
if f.length == 0 then results.push(text: word, sentiment: sent, freq: 1)
else for res in results then if res.text == word then res.freq++
results
findTopWords= (cloudWords) ->
posData = cloudWords.filter (cw) -> cw.sentiment > 0
negData = cloudWords.filter (cw) -> cw.sentiment < 0
neutData = cloudWords.filter (cw) -> cw.sentiment == 0
posData.sort (a, b) -> parseFloat(a.freq) - parseFloat(b.freq)
posData = posData.reverse().slice(0,5)
negData.sort (a, b) -> parseFloat(a.freq) - parseFloat(b.freq)
negData = negData.reverse().slice(0,5)
neutData.sort (a, b) -> parseFloat(a.freq) - parseFloat(b.freq)
neutData = neutData.reverse().slice(0,5)
{topPositive: posData, topNegative: negData, topNeutral: neutData}
findTrendingWords = (cloudWords) ->
cloudWords.sort (a, b) -> parseFloat(a.freq) - parseFloat(b.freq)
cloudWords = cloudWords.reverse().slice(0,10)
# Make a paragraph of keywords
makeTweetWords = (twitterResults) ->
para = ''
for tweet in twitterResults then para += tweet.body + ' '
removeWords para, false
# Merge two sets of results
mergeResults = (res1, res2) -> res1.concat res2
# Make sentence description for map
makeSentence = (data, searchTerm) ->
(new MakeSummarySentences data, searchTerm).makeMapSentences()
# Calls methods to fetch and format Tweets from the database
renderWithDatabaseResults: (cb) ->
Tweet.getAllTweets (tweets) ->
cloudData = formatResultsForCloud(tweets)
sentence = makeSentence(tweets, null)
sentence.topWords = findTopWords cloudData
cb cloudData, sentence
# Calls methods to fetch fresh Twitter, sentiment, and place data
renderWithFreshData: (searchTerm, cb) ->
fetchTweets.byTopic searchTerm, (webTweets) ->
Tweet.searchTweets searchTerm, (dbTweets) -> # Fetch matching db results
data = mergeResults webTweets, dbTweets
cloudData = formatResultsForCloud(data, true)
sentence = makeSentence(data, searchTerm)
sentence.topWords = findTopWords cloudData
sentence.trending = findTrendingWords cloudData
cb cloudData, sentence
findTrends: (tweets) ->
findTopWords formatResultsForCloud tweets, true
fwfc = new FormatWordsForCloud()
module.exports.getFreshData = fwfc.renderWithFreshData
module.exports.getDbData = fwfc.renderWithDatabaseResults
module.exports.findTopWords = fwfc.findTrends