From b10ba982273cea79d5a781259af32bae9910918f Mon Sep 17 00:00:00 2001 From: Brandon Cornejo Date: Mon, 24 Mar 2014 17:38:28 -0500 Subject: [PATCH] Log chat to seperate files, added chat stats to web. --- lib/currency.js | 35 ++++++++ lib/initialize.js | 6 +- lib/irc.js | 17 +++- lib/mysql.js | 4 +- lib/web.js | 11 +++ web/templates/index.jade | 116 ++++++++----------------- web/templates/ladder.jade | 175 ++++++++++++++------------------------ web/templates/layout.jade | 57 +++++++++++++ web/templates/stats.jade | 16 ++++ 9 files changed, 243 insertions(+), 194 deletions(-) create mode 100755 web/templates/layout.jade create mode 100755 web/templates/stats.jade diff --git a/lib/currency.js b/lib/currency.js index 03e26d1..ac2d234 100644 --- a/lib/currency.js +++ b/lib/currency.js @@ -59,6 +59,7 @@ var https = require('https'), http = require('http'), + file = require('fs'), utils = require('./utils.js'); //-------- Construct --------- @@ -236,8 +237,10 @@ Currency.prototype.commands = function (data) { // open / close betting system if (data[4] === 'bet') { + console.log("bet command found"); switch (data[5]) { case 'open': + console.log("bet open command found"); if (data[6] && data[7]) { __self.bets(true, data); } else { @@ -827,10 +830,42 @@ Currency.prototype.handout_coins = function () { if (viewer != __self.irc.config.name.toLowerCase()) { viewer = viewer.slice(1); } + + // add missing chatters to viewer_list if (__self.viewer_list.indexOf(viewer) < 0 && __self.config.ignorelist.indexOf(viewer) < 0) { __self.viewer_list.push(viewer); console.log("[*ADD NAME*] "+viewer+" from CHAT"); } + + // log chat if enabled + if (__self.irc.store_chat && __self.config.ignorelist.indexOf(viewer) < 0) { + file.exists(__self.irc.chat_log, function (exists) { + if (exists) { + // get a timestamp + var date = new Date(), + hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours(), + min = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes(), + sec = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds(), + streaming_time = ''; + + // create start time string + streaming_time += hours.toString() + ':' + min.toString(); + + // craft message + data_split[5] = data_split[5].slice(1); + var message = data_split.slice(5).join(' '); + + // put it all together + var logline = '[' + streaming_time + '] <' + viewer + '> ' + message + '\r\n'; + + file.appendFile(__self.irc.chat_log, logline, 'utf-8', function (err) { + if (err) { + throw err; + } + }); + } + }); + } } }); diff --git a/lib/initialize.js b/lib/initialize.js index 6382a24..98d9d57 100644 --- a/lib/initialize.js +++ b/lib/initialize.js @@ -18,7 +18,8 @@ exports.initialize = function(options) { irc = require('./irc.js')({ name : config.twitch.bot.name, pass : config.twitch.bot.password, - channel : '#' + config.twitch.channel + channel : '#' + config.twitch.channel, + chatlog : config.web.chatlog }); db = require('./mysql.js')({ host : config.currency.host, @@ -43,7 +44,8 @@ exports.initialize = function(options) { title : config.twitch.channel, slogan : config.web.slogan, logo : config.web.logo, - twitter : config.web.twitter + twitter : config.web.twitter, + statdir : config.web.statdir }); //-------- Start ------- diff --git a/lib/irc.js b/lib/irc.js index 68048dd..f2fa153 100644 --- a/lib/irc.js +++ b/lib/irc.js @@ -93,6 +93,13 @@ function IRC(options) { __self.streaming = false; __self.new_file = false; __self.log = ''; + + // chat logging + __self.first_check = true; + __self.store_chat = __self.options.chatlog || false; + __self.chat_log = ''; + + } IRC.prototype = new events.EventEmitter(); @@ -104,7 +111,9 @@ IRC.prototype.start = function () { // check stream status function stream_status() { var time = utils.make_interval(__self.check_streaming); - if (time === 0) { + if (time === 0 || __self.first_check) { + // Important to log chat right away, so lets skip the first 4 minute wait + if (__self.first_check) __self.first_check = false; https.get('https://api.twitch.tv/kraken/streams/' + __self.config.channel.slice(1), function (response) { var body = ''; @@ -140,6 +149,12 @@ IRC.prototype.start = function () { // create new log file __self.log = './../logs/' + __self.config.channel.slice(1) + '_' + streaming_time.toString() + '.txt'; file.open(__self.log, 'w'); + + // create chat log + if (__self.store_chat) { + __self.chat_log = './../logs/chat/' + __self.config.channel.slice(1) + '_' + streaming_time.toString() + '.txt'; + file.open(__self.chat_log, 'w'); + } } else if (!__self.streaming) { __self.new_file = false; __self.log = ''; diff --git a/lib/mysql.js b/lib/mysql.js index 30028c4..b3f5b33 100644 --- a/lib/mysql.js +++ b/lib/mysql.js @@ -52,8 +52,8 @@ DB.prototype.start = function() { scores += '`value` int(11) NOT NULL,'; scores += 'PRIMARY KEY (`name`)'; scores += ') ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;'; - scores += 'INSERT INTO `highscores` (`name`, `value`) VALUES(\'bet_single\', 0);'; - scores += 'INSERT INTO `highscores` (`name`, `value`) VALUES(\'bet_pool\', 0);'; + //scores += 'INSERT INTO `highscores` (`name`, `value`) VALUES(\'bet_single\', 0);'; + //scores += 'INSERT INTO `highscores` (`name`, `value`) VALUES(\'bet_pool\', 0);'; // execute sql, create tables if they don't exist __self.execute(commands + '; ' + viewers + '; ' + scores, function(){}); diff --git a/lib/web.js b/lib/web.js index 669527c..4ccabe6 100644 --- a/lib/web.js +++ b/lib/web.js @@ -12,6 +12,7 @@ function WEB(db, options) { __self.slogan = options.slogan; __self.logo = options.logo; __self.twitter = options.twitter; + __self.statdir = options.statdir; } // ---- Methods ---- @@ -50,6 +51,16 @@ WEB.prototype.start = function () { }); }); }); + __self.srv.get('/stats', function(req, res) { + //get the whole viewer list + res.render('stats', { + title: __self.title, + slogan: __self.slogan, + logo: __self.logo, + twitter: __self.twitter, + statdir: __self.statdir, + }); + }); __self.srv.get('/api/test', function(req, res) { res.send("Hey, its Potatr. This data was pulled from the web."); }); diff --git a/web/templates/index.jade b/web/templates/index.jade index e81df2c..8528665 100755 --- a/web/templates/index.jade +++ b/web/templates/index.jade @@ -1,82 +1,38 @@ -doctype html -html(lang="en") - head - title= title - link(rel='stylesheet', href='/lib/uikit/css/uikit.almost-flat.min.css') - link(rel='stylesheet', href='/css/app.css') - script(src='/lib/jquery.js') - script(src='/lib/uikit/js/uikit.min.js') - - // Favicon stuff - link(rel='apple-touch-icon', sizes='57x57', href='/apple-touch-icon-57x57.png') - link(rel='apple-touch-icon', sizes='114x114', href='/apple-touch-icon-114x114.png') - link(rel='apple-touch-icon', sizes='72x72', href='/apple-touch-icon-72x72.png') - link(rel='apple-touch-icon', sizes='144x144', href='/apple-touch-icon-144x144.png') - link(rel='apple-touch-icon', sizes='60x60', href='/apple-touch-icon-60x60.png') - link(rel='apple-touch-icon', sizes='120x120', href='/apple-touch-icon-120x120.png') - link(rel='apple-touch-icon', sizes='76x76', href='/apple-touch-icon-76x76.png') - link(rel='apple-touch-icon', sizes='152x152', href='/apple-touch-icon-152x152.png') - link(rel='icon', type='image/png', href='/favicon-196x196.png', sizes='196x196') - link(rel='icon', type='image/png', href='/favicon-160x160.png', sizes='160x160') - link(rel='icon', type='image/png', href='/favicon-96x96.png', sizes='96x96') - link(rel='icon', type='image/png', href='/favicon-16x16.png', sizes='16x16') - link(rel='icon', type='image/png', href='/favicon-32x32.png', sizes='32x32') - meta(name='msapplication-TileColor', content='#da532c') - meta(name='msapplication-TileImage', content='/mstile-144x144.png') - - body - div.uk-grid - div.uk-width-1-1 - div.uk-grid - div.uk-width-1-4 - img(src='/img/#{logo}') - div.uk-width-2-4 - // bigimagelogo - h1.uk-text-center #{title}
#{slogan} - div.uk-width-1-4 - img.flip(src='/img/#{logo}') - div.uk-width-1-1 - nav.uk-navbar - ul.uk-navbar-nav.uk-navbar-center - li: a(href='http://www.twitch.tv/#{title}'): img(src='/img/twitch.png', alt='Stream') - li: a(href='/') Home - li: a(href='/ladder') Ladder - li: a(href='#') Chat Stats - li: a(href='http://www.twitter.com/#{twitter}'): img(src='/img/twitter.gif', alt='Twitter') - div.uk-width-1-1 - div.uk-container.uk-container-center - div.uk-grid - br - br - div.uk-width-1-2 - div.uk-panel.uk-panel-box - h2 #{title} is - span#status offline. - div#streambox - div.uk-width-1-2 - div.uk-panel.uk-panel-box - table.uk-table.uk-table-hover.uk-table-striped - caption Top 10 Potato Farmers - thead - tr - th Viewer - th Potatoes - tbody - each row in rows - tr - td #{row.user} - td #{row.points} +extends layout +block content + div.uk-grid + br + br + div.uk-width-1-2 + div.uk-panel.uk-panel-box + h2 #{title} is + span#status offline. + div#streambox + div.uk-width-1-2 + div.uk-panel.uk-panel-box + table.uk-table.uk-table-hover.uk-table-striped + caption Top 10 Potato Farmers + thead + tr + th Viewer + th Potatoes + tbody + each row in rows + tr + td #{row.user} + td #{row.points} - script. - $(document).ready(function(){ - $.getJSON('https://api.twitch.tv/kraken/streams/#{title}?callback=?', function(data){ - if(data.stream) { - $('#status').empty().append('online!'); - $("#streambox").append("Game: "+data.stream.game+"
"); - $("#streambox").append("Viewers: "+data.stream.viewers+"
"); - $("#streambox").append("

");; - } else { - $("#streambox").append("

Offline

"); - } - }); +block postscript + script. + $(document).ready(function(){ + $.getJSON('https://api.twitch.tv/kraken/streams/#{title}?callback=?', function(data){ + if(data.stream) { + $('#status').empty().append('online!'); + $("#streambox").append("Game: "+data.stream.game+"
"); + $("#streambox").append("Viewers: "+data.stream.viewers+"
"); + $("#streambox").append("

");; + } else { + $("#streambox").append("

Offline

"); + } }); + }); diff --git a/web/templates/ladder.jade b/web/templates/ladder.jade index 0240f99..75aea37 100755 --- a/web/templates/ladder.jade +++ b/web/templates/ladder.jade @@ -1,122 +1,79 @@ -doctype html -html(lang="en") - head - title= title - link(rel='stylesheet', href='/lib/uikit/css/uikit.almost-flat.min.css') - link(rel='stylesheet', href='/css/app.css') - script(src='/lib/jquery.js') - script(src='/lib/uikit/js/uikit.min.js') +extends layout +block content + div.uk-grid + br + br + div.uk-width-1-1 + div.uk-panel.uk-panel-box + div.uk-badge.uk-float-right + form.uk-search + input(class='uk-search-field', type='search', placeholder='Search...') + button(class='uk-close', type='reset') + table.uk-table.uk-table-hover.uk-table-striped + caption Potato Farmer Ladder Rankings + thead + tr + th Rank + th Viewer + th Potatoes + tbody + ul.uk-pagination - // Favicon stuff - link(rel='apple-touch-icon', sizes='57x57', href='/apple-touch-icon-57x57.png') - link(rel='apple-touch-icon', sizes='114x114', href='/apple-touch-icon-114x114.png') - link(rel='apple-touch-icon', sizes='72x72', href='/apple-touch-icon-72x72.png') - link(rel='apple-touch-icon', sizes='144x144', href='/apple-touch-icon-144x144.png') - link(rel='apple-touch-icon', sizes='60x60', href='/apple-touch-icon-60x60.png') - link(rel='apple-touch-icon', sizes='120x120', href='/apple-touch-icon-120x120.png') - link(rel='apple-touch-icon', sizes='76x76', href='/apple-touch-icon-76x76.png') - link(rel='apple-touch-icon', sizes='152x152', href='/apple-touch-icon-152x152.png') - link(rel='icon', type='image/png', href='/favicon-196x196.png', sizes='196x196') - link(rel='icon', type='image/png', href='/favicon-160x160.png', sizes='160x160') - link(rel='icon', type='image/png', href='/favicon-96x96.png', sizes='96x96') - link(rel='icon', type='image/png', href='/favicon-16x16.png', sizes='16x16') - link(rel='icon', type='image/png', href='/favicon-32x32.png', sizes='32x32') - meta(name='msapplication-TileColor', content='#da532c') - meta(name='msapplication-TileImage', content='/mstile-144x144.png') - body - div.uk-grid - div.uk-width-1-1 - div.uk-grid - div.uk-width-1-4 - img(src='/img/#{logo}') - div.uk-width-2-4 - // bigimagelogo - h1.uk-text-center #{title}
#{slogan} - div.uk-width-1-4 - img.flip(src='/img/#{logo}') - div.uk-width-1-1 - nav.uk-navbar - ul.uk-navbar-nav.uk-navbar-center - li: a(href='http://www.twitch.tv/#{title}'): img(src='/img/twitch.png', alt='Stream') - li: a(href='/') Home - li: a(href='/ladder') Ladder - li: a(href='#') Chat Stats - li: a(href='http://www.twitter.com/#{twitter}'): img(src='/img/twitter.gif', alt='Twitter') - div.uk-width-1-1 - div.uk-container.uk-container-center - div.uk-grid - br - br - div.uk-width-1-1 - div.uk-panel.uk-panel-box - div.uk-badge.uk-float-right - form.uk-search - input(class='uk-search-field', type='search', placeholder='Search...') - button(class='uk-close', type='reset') - table.uk-table.uk-table-hover.uk-table-striped - caption Potato Farmer Ladder Rankings - thead - tr - th Rank - th Viewer - th Potatoes - tbody - ul.uk-pagination +block postscript + script. + var perPage = 20, + data = !{JSON.stringify(rows)}; - script. - var perPage = 50, - data = !{JSON.stringify(rows)}; + $(document).ready(function(){ - $(document).ready(function(){ + // Live search of the ladder listings + $('.uk-search-field').keyup(function() { + var query = $(this).val(); - // Live search of the ladder listings - $('.uk-search-field').keyup(function() { - var query = $(this).val(); + if(query.length > 2) { + var temp = $('.uk-active').attr('page'); + $('.uk-active').removeClass('uk-active').empty().append(''+temp+''); + $('table > tbody').empty(); - if(query.length > 2) { - var temp = $('.uk-active').attr('page'); - $('.uk-active').removeClass('uk-active').empty().append(''+temp+''); - $('table > tbody').empty(); - - data.forEach(function(element, index, array) { - if(element.user.search(new RegExp(query, 'i')) != -1) { - $('table > tbody').append($('').append(''+index+''+element.user+''+element.points+'')); - } - }); - } - }); + data.forEach(function(element, index, array) { + if(element.user.search(new RegExp(query, 'i')) != -1) { + $('table > tbody').append($('').append(''+index+''+element.user+''+element.points+'')); + } + }); + } + }); - // Create pagination buttons - for(var i = 1; i <= Math.ceil(data.length/perPage); i++) { - var button = $('
  • ').append(''+i+''); - button.on('click', function(){ - //get page - var z = $(this).attr('page'); - - // cleanup - var temp = $('.uk-active').attr('page'); - $('.uk-active').removeClass('uk-active').empty().append(''+temp+''); - $('table > tbody').empty(); + // Create pagination buttons + for(var i = 1; i <= Math.ceil(data.length/perPage); i++) { + var button = $('
  • ').append(''+i+''); + button.on('click', function(){ + //get page + var z = $(this).attr('page'); + + // cleanup + var temp = $('.uk-active').attr('page'); + $('.uk-active').removeClass('uk-active').empty().append(''+temp+''); + $('table > tbody').empty(); - $(this).addClass('uk-active').empty().append(''+z+''); + $(this).addClass('uk-active').empty().append(''+z+''); - // slice(a, b): a = (n*(x-1))+1, b = n*x where n = perPage and x=curerntPage (skip +1 at end of a for splice) - var a = (perPage*(z-1)), - b = perPage*z; - - data.slice(a, b).forEach(function(element, index, array){ - $('table > tbody').append($('').append(''+(a+index+1)+''+element.user+''+element.points+'')); - }); + // slice(a, b): a = (n*(x-1))+1, b = n*x where n = perPage and x=curerntPage (skip +1 at end of a for splice) + var a = (perPage*(z-1)), + b = perPage*z; + + data.slice(a, b).forEach(function(element, index, array){ + $('table > tbody').append($('').append(''+(a+index+1)+''+element.user+''+element.points+'')); }); - - $('.uk-pagination').append(button); - } - - // When search input is cleared, go back to first page - $('.uk-close').on('click', function(){ - $('ul.uk-pagination > li').first().click(); }); - // Show the first page when we load up + $('.uk-pagination').append(button); + } + + // When search input is cleared, go back to first page + $('.uk-close').on('click', function(){ $('ul.uk-pagination > li').first().click(); }); + + // Show the first page when we load up + $('ul.uk-pagination > li').first().click(); + }); diff --git a/web/templates/layout.jade b/web/templates/layout.jade new file mode 100755 index 0000000..3180cb3 --- /dev/null +++ b/web/templates/layout.jade @@ -0,0 +1,57 @@ +doctype html +html(lang="en") + head + title= title + link(rel='stylesheet', href='/lib/uikit/css/uikit.almost-flat.min.css') + link(rel='stylesheet', href='/css/app.css') + script(src='/lib/jquery.js') + script(src='/lib/uikit/js/uikit.min.js') + + // Favicon stuff + link(rel='apple-touch-icon', sizes='57x57', href='/apple-touch-icon-57x57.png') + link(rel='apple-touch-icon', sizes='114x114', href='/apple-touch-icon-114x114.png') + link(rel='apple-touch-icon', sizes='72x72', href='/apple-touch-icon-72x72.png') + link(rel='apple-touch-icon', sizes='144x144', href='/apple-touch-icon-144x144.png') + link(rel='apple-touch-icon', sizes='60x60', href='/apple-touch-icon-60x60.png') + link(rel='apple-touch-icon', sizes='120x120', href='/apple-touch-icon-120x120.png') + link(rel='apple-touch-icon', sizes='76x76', href='/apple-touch-icon-76x76.png') + link(rel='apple-touch-icon', sizes='152x152', href='/apple-touch-icon-152x152.png') + link(rel='icon', type='image/png', href='/favicon-196x196.png', sizes='196x196') + link(rel='icon', type='image/png', href='/favicon-160x160.png', sizes='160x160') + link(rel='icon', type='image/png', href='/favicon-96x96.png', sizes='96x96') + link(rel='icon', type='image/png', href='/favicon-16x16.png', sizes='16x16') + link(rel='icon', type='image/png', href='/favicon-32x32.png', sizes='32x32') + meta(name='msapplication-TileColor', content='#da532c') + meta(name='msapplication-TileImage', content='/mstile-144x144.png') + + body + div.uk-grid + div.uk-width-1-1 + div.uk-grid + div.uk-width-1-4 + img(src='/img/#{logo}') + div.uk-width-2-4 + // bigimagelogo + h1.uk-text-center #{title}
    #{slogan} + div.uk-width-1-4 + img.flip(src='/img/#{logo}') + div.uk-width-1-1 + nav.uk-navbar + ul.uk-navbar-nav.uk-navbar-center + li: a(href='http://www.twitch.tv/#{title}'): img(src='/img/twitch.png', alt='Stream') + li: a(href='/') Home + li: a(href='/ladder') Ladder + li: a(href='/stats') Chat Stats + li: a(href='http://www.twitter.com/#{twitter}'): img(src='/img/twitter.gif', alt='Twitter') + div.uk-width-1-1 + div.uk-container.uk-container-center + block content + div.uk-width-1-1 + footer.uk-text-center + br + span.tag Visit the potato lord @ + a(href='http://www.twitch.tv/shaneomad') Shaneomad + br + span.copyright Potatr (c) DotaNoobs 2014 + + block postscript diff --git a/web/templates/stats.jade b/web/templates/stats.jade new file mode 100755 index 0000000..9fc1e04 --- /dev/null +++ b/web/templates/stats.jade @@ -0,0 +1,16 @@ +extends layout +block content + div.uk-grid.uk-height-1-1 + br + br + iframe#stats_content.uk-width-1-1(onload="resizeStats(this)") + +block postscript + script. + $(document).ready( function() { + $("#stats_content").attr("src", "statistics/#{statdir}/index.html"); + }); + + function resizeStats(iframe) { + iframe.height = iframe.contentWindow.document.body.scrollHeight + "px"; + }