Browse Source

Log chat to seperate files, added chat stats to web.

doobs
Brandon Cornejo 11 years ago
parent
commit
b10ba98227
  1. 35
      lib/currency.js
  2. 6
      lib/initialize.js
  3. 17
      lib/irc.js
  4. 4
      lib/mysql.js
  5. 11
      lib/web.js
  6. 116
      web/templates/index.jade
  7. 171
      web/templates/ladder.jade
  8. 57
      web/templates/layout.jade
  9. 16
      web/templates/stats.jade

35
lib/currency.js

@ -59,6 +59,7 @@
var https = require('https'), var https = require('https'),
http = require('http'), http = require('http'),
file = require('fs'),
utils = require('./utils.js'); utils = require('./utils.js');
//-------- Construct --------- //-------- Construct ---------
@ -236,8 +237,10 @@ Currency.prototype.commands = function (data) {
// open / close betting system // open / close betting system
if (data[4] === 'bet') { if (data[4] === 'bet') {
console.log("bet command found");
switch (data[5]) { switch (data[5]) {
case 'open': case 'open':
console.log("bet open command found");
if (data[6] && data[7]) { if (data[6] && data[7]) {
__self.bets(true, data); __self.bets(true, data);
} else { } else {
@ -827,10 +830,42 @@ Currency.prototype.handout_coins = function () {
if (viewer != __self.irc.config.name.toLowerCase()) { if (viewer != __self.irc.config.name.toLowerCase()) {
viewer = viewer.slice(1); viewer = viewer.slice(1);
} }
// add missing chatters to viewer_list
if (__self.viewer_list.indexOf(viewer) < 0 && __self.config.ignorelist.indexOf(viewer) < 0) { if (__self.viewer_list.indexOf(viewer) < 0 && __self.config.ignorelist.indexOf(viewer) < 0) {
__self.viewer_list.push(viewer); __self.viewer_list.push(viewer);
console.log("[*ADD NAME*] "+viewer+" from CHAT"); 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;
}
});
}
});
}
} }
}); });

6
lib/initialize.js

@ -18,7 +18,8 @@ exports.initialize = function(options) {
irc = require('./irc.js')({ irc = require('./irc.js')({
name : config.twitch.bot.name, name : config.twitch.bot.name,
pass : config.twitch.bot.password, pass : config.twitch.bot.password,
channel : '#' + config.twitch.channel
channel : '#' + config.twitch.channel,
chatlog : config.web.chatlog
}); });
db = require('./mysql.js')({ db = require('./mysql.js')({
host : config.currency.host, host : config.currency.host,
@ -43,7 +44,8 @@ exports.initialize = function(options) {
title : config.twitch.channel, title : config.twitch.channel,
slogan : config.web.slogan, slogan : config.web.slogan,
logo : config.web.logo, logo : config.web.logo,
twitter : config.web.twitter
twitter : config.web.twitter,
statdir : config.web.statdir
}); });
//-------- Start ------- //-------- Start -------

17
lib/irc.js

@ -93,6 +93,13 @@ function IRC(options) {
__self.streaming = false; __self.streaming = false;
__self.new_file = false; __self.new_file = false;
__self.log = ''; __self.log = '';
// chat logging
__self.first_check = true;
__self.store_chat = __self.options.chatlog || false;
__self.chat_log = '';
} }
IRC.prototype = new events.EventEmitter(); IRC.prototype = new events.EventEmitter();
@ -104,7 +111,9 @@ IRC.prototype.start = function () {
// check stream status // check stream status
function stream_status() { function stream_status() {
var time = utils.make_interval(__self.check_streaming); 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) { https.get('https://api.twitch.tv/kraken/streams/' + __self.config.channel.slice(1), function (response) {
var body = ''; var body = '';
@ -140,6 +149,12 @@ IRC.prototype.start = function () {
// create new log file // create new log file
__self.log = './../logs/' + __self.config.channel.slice(1) + '_' + streaming_time.toString() + '.txt'; __self.log = './../logs/' + __self.config.channel.slice(1) + '_' + streaming_time.toString() + '.txt';
file.open(__self.log, 'w'); 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) { } else if (!__self.streaming) {
__self.new_file = false; __self.new_file = false;
__self.log = ''; __self.log = '';

4
lib/mysql.js

@ -52,8 +52,8 @@ DB.prototype.start = function() {
scores += '`value` int(11) NOT NULL,'; scores += '`value` int(11) NOT NULL,';
scores += 'PRIMARY KEY (`name`)'; scores += 'PRIMARY KEY (`name`)';
scores += ') ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;'; 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 // execute sql, create tables if they don't exist
__self.execute(commands + '; ' + viewers + '; ' + scores, function(){}); __self.execute(commands + '; ' + viewers + '; ' + scores, function(){});

11
lib/web.js

@ -12,6 +12,7 @@ function WEB(db, options) {
__self.slogan = options.slogan; __self.slogan = options.slogan;
__self.logo = options.logo; __self.logo = options.logo;
__self.twitter = options.twitter; __self.twitter = options.twitter;
__self.statdir = options.statdir;
} }
// ---- Methods ---- // ---- 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) { __self.srv.get('/api/test', function(req, res) {
res.send("Hey, its Potatr. This data was pulled from the web."); res.send("Hey, its Potatr. This data was pulled from the web.");
}); });

116
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')
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}
// 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}<br/>#{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}
script.
$(document).ready(function(){
$.getJSON('https://api.twitch.tv/kraken/streams/#{title}?callback=?', function(data){
if(data.stream) {
$('#status').empty().append('online!');
$("#streambox").append("<span>Game:</span> <span class='uk-text-bold uk-text-success'>"+data.stream.game+"</span><br/>");
$("#streambox").append("<span>Viewers:</span> <span class='uk-text-bold uk-text-warning'>"+data.stream.viewers+"</span><br/>");
$("#streambox").append("<br/><br/><img src='"+data.stream.preview.medium+"' />");;
} else {
$("#streambox").append("<h3 class='uk-text-danger'>Offline</h3>");
}
});
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("<span>Game:</span> <span class='uk-text-bold uk-text-success'>"+data.stream.game+"</span><br/>");
$("#streambox").append("<span>Viewers:</span> <span class='uk-text-bold uk-text-warning'>"+data.stream.viewers+"</span><br/>");
$("#streambox").append("<br/><br/><img src='"+data.stream.preview.medium+"' />");;
} else {
$("#streambox").append("<h3 class='uk-text-danger'>Offline</h3>");
}
}); });
});

171
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}<br/>#{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('<a>'+temp+'</a>');
$('table > tbody').empty();
if(query.length > 2) {
var temp = $('.uk-active').attr('page');
$('.uk-active').removeClass('uk-active').empty().append('<a>'+temp+'</a>');
$('table > tbody').empty();
data.forEach(function(element, index, array) {
if(element.user.search(new RegExp(query, 'i')) != -1) {
$('table > tbody').append($('<tr></tr>').append('<td>'+index+'</td><td>'+element.user+'</td><td>'+element.points+'</td>'));
}
});
}
});
data.forEach(function(element, index, array) {
if(element.user.search(new RegExp(query, 'i')) != -1) {
$('table > tbody').append($('<tr></tr>').append('<td>'+index+'</td><td>'+element.user+'</td><td>'+element.points+'</td>'));
}
});
}
});
// Create pagination buttons
for(var i = 1; i <= Math.ceil(data.length/perPage); i++) {
var button = $('<li page='+i+'></li>').append('<a>'+i+'</a>');
button.on('click', function(){
//get page
var z = $(this).attr('page');
// Create pagination buttons
for(var i = 1; i <= Math.ceil(data.length/perPage); i++) {
var button = $('<li page='+i+'></li>').append('<a>'+i+'</a>');
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('<a>'+temp+'</a>');
$('table > tbody').empty();
// cleanup
var temp = $('.uk-active').attr('page');
$('.uk-active').removeClass('uk-active').empty().append('<a>'+temp+'</a>');
$('table > tbody').empty();
$(this).addClass('uk-active').empty().append('<span>'+z+'</span>');
$(this).addClass('uk-active').empty().append('<span>'+z+'</span>');
// 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;
// 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($('<tr></tr>').append('<td>'+(a+index+1)+'</td><td>'+element.user+'</td><td>'+element.points+'</td>'));
});
data.slice(a, b).forEach(function(element, index, array){
$('table > tbody').append($('<tr></tr>').append('<td>'+(a+index+1)+'</td><td>'+element.user+'</td><td>'+element.points+'</td>'));
}); });
$('.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(); $('ul.uk-pagination > li').first().click();
}); });
// Show the first page when we load up
$('ul.uk-pagination > li').first().click();
});

57
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}<br/>#{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

16
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";
}
Loading…
Cancel
Save