diff options
| -rw-r--r-- | gold/bitcoinwisdom/beep.js | 30 | ||||
| -rw-r--r-- | gold/bitcoinwisdom/index.js | 84 | ||||
| -rw-r--r-- | gold/bitcoinwisdom/ticker.js | 95 | ||||
| -rwxr-xr-x | ledger/lib/balance | 2 | ||||
| -rwxr-xr-x | util/bin/jbo | 42 | ||||
| -rw-r--r-- | webchat/hello_web.js | 106 | ||||
| -rw-r--r-- | webchat/index.js | 120 | ||||
| -rw-r--r-- | webchat/public/client.js | 34 | ||||
| -rw-r--r-- | webchat/public/reset.css | 49 | 
9 files changed, 452 insertions, 110 deletions
diff --git a/gold/bitcoinwisdom/beep.js b/gold/bitcoinwisdom/beep.js new file mode 100644 index 00000000..80a0cb0f --- /dev/null +++ b/gold/bitcoinwisdom/beep.js @@ -0,0 +1,30 @@ +module.exports = { +  create_beeper: create_beeper, +} + +var child_process = require('child_process'); + +function create_beeper (spec) { +  return { +    beep: beep, +  } +  function beep (freq, len) { +    var child = child_process.spawn('beep', [ +        '-f', freq, +        '-l', len, +    ]); +    child.stdout.on('data', function (data) { +      console.log('stdout: ' + data); +    }); + +    child.stderr.on('data', function (data) { +      console.log('stderr: ' + data); +    }); + +    child.on('close', function (code) { +      if (code !== 0) { +        console.log('child process exited with code ' + code); +      } +    }); +  } +} diff --git a/gold/bitcoinwisdom/index.js b/gold/bitcoinwisdom/index.js new file mode 100644 index 00000000..95861229 --- /dev/null +++ b/gold/bitcoinwisdom/index.js @@ -0,0 +1,84 @@ +var http = require('http'); +var beeper = require('./beep.js').create_beeper(); + +setInterval(get_ticker, 1000); + +function get_ticker () { +  http.get('http://s1.bitcoinwisdom.com:8080/ticker', ticker_response_handler); +} + +function ticker_response_handler (res) { +  var data = ''; +  res.on('data', function (chunk) { +    data += chunk; +  }); +  res.on('end', function () { +    try { +      data = JSON.parse(data); +    } catch (err) { +      return console.log('Error:', err); +    } +    ticker_data_handler(data); +  }); +} + +var last_data = { +  btceltcbtc: { +    last: 0, // price +    date: 0, +    tid: 0, +  }, +} + +function ticker_data_handler (data) { +  //console.log(data) + +  var ticker = data.btceltcbtc +  var last_ticker = last_data.btceltcbtc + +  if (ticker.date !== last_ticker.date) { + +    var diff = ticker.last - last_ticker.last; + +    var lag = data.now - ticker.date; + +    freq = (2000 + 1000000 * diff) | 0; + +    var out = [ +      format_date(data.now) + '+' + pad_left(lag, 2, '0'), +      'btceltcbtc', +      '[' + diff_color(diff) + 'm' + ticker.last + '[m', +      lag, +      freq, +    ]; + +    console.log(out.join(' ')); + +    beeper.beep(freq, 10); +  } + +  last_data.btceltcbtc = data.btceltcbtc; +} + +function diff_color (diff) { +  if (diff < 0) { +    return '31;1'; +  } else if (diff > 0) { +    return '32;1'; +  } else { +    return '33;1'; +  } +} + +function format_date (unix) { +  return (new Date(unix * 1000)).toISOString() +    .replace(/\.000Z$/, 'Z') +} + +function pad_left (obj, num, char) { +  var str = obj.toString(); +  while (str.length < num) { +    str += char; +  } +  return str; +} diff --git a/gold/bitcoinwisdom/ticker.js b/gold/bitcoinwisdom/ticker.js new file mode 100644 index 00000000..002f8502 --- /dev/null +++ b/gold/bitcoinwisdom/ticker.js @@ -0,0 +1,95 @@ +var http = require('http'); +var beeper = require('./beep.js').create_beeper(); + +setInterval(get_ticker, 1000); + +function get_ticker () { +  http.get('http://s1.bitcoinwisdom.com:8080/ticker', ticker_response_handler); +} + +function ticker_response_handler (res) { +  var data = ''; +  res.on('data', function (chunk) { +    data += chunk; +  }); +  res.on('end', function () { +    try { +      data = JSON.parse(data); +    } catch (err) { +      return console.log('Error:', err); +    } +    ticker_data_handler(data); +  }); +} + +var last_data = { +  btceltcbtc: { +    last: 0, // price +    date: 0, +    tid: 0, +  }, +} + +function ticker_data_handler (data) { +  //console.log(data) + +  var symbol = 'btceltcbtc' + +  var ticker = data[symbol] +  var last_ticker = last_data[symbol] + +  if (ticker.date !== last_ticker.date) { + +    var diff = ticker.last - last_ticker.last; + +    var lag = data.now - ticker.date; + +    freq = ( Math.pow(2000, ticker.last / last_ticker.last )) | 0; + +    var out = [ +      format_date(data.now) + '+' + pad(lag, -2, '0'), +      '\x1b[' + diff_color(diff) + 'm' +        + ticker.last.toFixed(8) +        + '\x1b[m', +      symbol, +      freq, +    ]; + +    console.log(out.join(' ')); + +    beeper.beep(freq, 10); +  } + +  last_data[symbol] = data[symbol]; +} + +function diff_color (diff) { +  if (diff < 0) { +    return '31;1'; +  } else if (diff > 0) { +    return '32;1'; +  } else { +    return '33;1'; +  } +} + +function format_date (unix) { +  return (new Date(unix * 1000)).toISOString() +    .replace(/\.000Z$/, 'Z') +} + +// num < 0: pad left +// num > 0: pad right +function pad (obj, num, char) { +  var str = obj.toString(); +  if (num < 0) { +    while (str.length < -num) { +      str = char + str; +    } +  } if (num > 0) { +    while (str.length < num) { +      str = str + char; +    } +  } +  return str; +} diff --git a/ledger/lib/balance b/ledger/lib/balance index 77cb7f6d..c9a1fd87 100755 --- a/ledger/lib/balance +++ b/ledger/lib/balance @@ -1,4 +1,4 @@ -#! /bin/awk -f +#! /usr/bin/awk -f  #  # ledger balance calculator  # diff --git a/util/bin/jbo b/util/bin/jbo new file mode 100755 index 00000000..76f86680 --- /dev/null +++ b/util/bin/jbo @@ -0,0 +1,42 @@ +#! /bin/sh +# usage: jbo WORDS... +set -euf + +if test $# = 0; then +  while read line; do +    if test "${clear-}" = true; then +      echo -n 'c' +    fi +    "$0" "$line" +  done +  exit +fi + +echo "$*" | +tr 'h' "'" | +jbofihe -H | +tr '\n' ' ' | +sed -r ' +  s@</?(HTML|HEAD|TITLE|BODY|FONT)[^>]*>@@g +  s@Lojban translation@@ +' | { +  sed 's:<SUB>[^>]*</SUB>:\n&\n:g' | +  sed '/^<SUB>/y/0123456789/₀₁₂₃₄₅₆₇₈₉/' | +      tr -d '\n' | +      sed 's:</\?SUB>::g' +} | +sed -r ' +  s|<B>|[32m|g; s|</B>|[m|g + +  s|<I> </I>|<I>_</I>|g +  s|<I>|[31m|g; s|</I>|[m|g + +  #s|<U>|[4m|g; s|</U>|[m|g +  s|<U>||g; s|</U>||g + +  s|<|<|g +  s|>|>|g + +  s@^ *@@ +  $s/$/\n/ +' diff --git a/webchat/hello_web.js b/webchat/hello_web.js deleted file mode 100644 index 45f6fc56..00000000 --- a/webchat/hello_web.js +++ /dev/null @@ -1,106 +0,0 @@ -var fs = require('fs'); -var http = require('https'); -var sockjs = require('sockjs'); -var connect = require('connect'); -var irc = require('irc'); -var Clients = []; -Clients.broadcast = function(object) { -  Clients.forEach(function(client) { -    client.write(JSON.stringify(object)); -  }); -} -var pingTimeoutDelay = 5*60*1000 -var lastping = setTimeout(reconnect, pingTimeoutDelay) - -var irc_client = new irc.Client('irc.freenode.net', 'kweb', { -  channels: ['#krebs'], -  sasl: true, -  secure: true, -  userName: 'kweb', -  realName: 'kweb', -  password: fs.readFileSync(__dirname+'/local_config/irc.key').toString(), -  debug: true, -  showErrors: true, -  port: 6697, -  autoRejoin: true, -  autoConnect: true, -  stripColors: true -}); - -var reconnect = function() { -  console.log("reconnecting due to pingtimeout"); -  irc_client.disconnect(); -  irc_client.connect(); -} - -irc_client.on('ping', function(server) { -  console.log("got ping from server, renewing timeout for automatic reconnect"); -  clearTimeout(lastping); -  lastping = setTimeout(reconnect, pingTimeoutDelay); -}) - -irc_client.on('message#krebs', function(from, message) { -  console.log({ from: from, message: message }); -  Clients.broadcast({ from: from, message: message }); -  clearTimeout(lastping); -}); - -var echo = sockjs.createServer(); -echo.on('connection', function(conn) { -  var origin = '['+conn.remoteAddress+':'+conn.remotePort+']'; -  Clients.push(conn); -  Clients.broadcast({from: 'system', message: origin + ' has joined'}) -  irc_client.say("#krebs", origin + ' has joined'); -  conn.write(JSON.stringify({from: 'system', message: 'hello'})) -  conn.on('data', function(data) { -    console.log('data:',data); -    try { -      var object = JSON.parse(data); -      if (/^\/nick\s+(.+)$/.test(object.message)) { -        object.from = origin; -      } else if (typeof object.nick === 'string') { -        object.from = object.nick; -      } else { -        object.from = origin; -      }; -    console.log(object.message); -  irc_client.say("#krebs", object.from + ' → ' + object.message); -  Clients.broadcast(object); - -    } catch (error) { -      console.log(error); -    } -  }); -conn.on('close', function() { -  Clients.splice(Clients.indexOf(conn)); -  Clients.broadcast({from: 'system', message: origin + ' has quit'}) -  irc_client.say("#krebs", origin + ' has quit'); -}); -}); - -var options = { -  key: fs.readFileSync(__dirname+'/local_config/server_npw.key'), -  cert: fs.readFileSync(__dirname+'/local_config/server.crt'), -}; - -var app = connect() -  .use(connect.logger('dev')) -  .use(connect.static(__dirname+'/public')) -  .use( function (req, res) { -    res.writeHead(200, {'Content-Type': 'text/html'}); -    res.write('<!doctype html>'); -    res.write('<link rel="stylesheet" type="text/css" href="reset.css">'); -    res.write('<script src="sockjs-0.3.min.js"></script>'); -    res.write('<script src="jquery-2.0.3.min.js"></script>'); -    res.write('<script src="client.js"></script>'); -    res.write('<div id=bg>'); -    res.write('hello, this is #krebs:<br>'); -    res.write('<table id="chatbox"></table>'); -    res.end('<input type="text" id="input"><br>'); -    res.write('</div>'); - -  }) -var server = http.createServer(options, app); -echo.installHandlers(server, {prefix:'/echo'}); -server.listen(1337, '0.0.0.0'); -console.log('Server running at https://127.0.0.1:1337/'); diff --git a/webchat/index.js b/webchat/index.js new file mode 100644 index 00000000..8ef737fc --- /dev/null +++ b/webchat/index.js @@ -0,0 +1,120 @@ +var fs = require('fs'); +var http = require('https'); +var sockjs = require('sockjs'); +var connect = require('connect'); +var irc = require('irc'); +var Clients = []; + +Clients.broadcast = function(object) { //broadcast to all clients +  Clients.forEach(function(client) { +    client.write(JSON.stringify(object)); +  }); +} + +var irc_reconnect = function() { //reconnt to irc +  console.log("reconnecting due to pingtimeout"); +  irc_client.disconnect(); +  irc_client.connect(); +} + +var pingTimeoutDelay = 3*60*1000 +var lastping = setTimeout(irc_reconnect, pingTimeoutDelay) + +var irc_client = new irc.Client('irc.freenode.net', 'kweb', { //create irc_client to talk to irc +  channels: ['#krebs'], //todo: read from local_config +  sasl: true,  +  secure: true, +  userName: 'kweb', //todo: read from local_config +  realName: 'kweb', //todo: read from local_config +  password: fs.readFileSync(__dirname+'/local_config/irc.key').toString(), +  debug: false, +  showErrors: true, +  floodProtection: true, +  port: 6697, +  autoRejoin: true, +  autoConnect: true, +  stripColors: true +}); + + +irc_client.on('ping', function(server) { //restart timer on server ping +  console.log("got ping from server, renewing timeout for automatic reconnect"); +  clearTimeout(lastping); +  lastping = setTimeout(irc_reconnect, pingTimeoutDelay); //reconnect after irc timeout +}) + +irc_client.on('message#krebs', function(from, message) { +  console.log({ from: from, message: message }); +  Clients.broadcast({ from: from, message: message }); //broadcast irc messages to all connected clients +  clearTimeout(lastping); +}); + +var web_serv_options = { //certificates for https +  key: fs.readFileSync(__dirname+'/local_config/server_npw.key'), +  cert: fs.readFileSync(__dirname+'/local_config/server.crt'), +}; + +var echo = sockjs.createServer(); +echo.on('connection', function(conn) { +  var origin = conn.remoteAddress; +  Clients.push(conn); +  Clients.broadcast({from: 'system', message: origin + ' has joined'}) +//  irc_client.say("#krebs", origin + ' has joined'); +  conn.write(JSON.stringify({from: 'system', message: 'hello'})) //welcome message +  conn.on('data', function(data) { +    console.log('data:',data); +    try { +      var object = JSON.parse(data); +      if (object.message.length > 0) { //if message is not empty +        if (/^\/nick\s+(.+)$/.test(object.message)) { //if nick is send use nick instead of ip +          object.from = origin; +        } else if (typeof object.nick === 'string') { +          object.from = object.nick; +        } else { +          object.from = origin; +        }; +        console.log(object.message); +        irc_client.say("#krebs", object.from + ' → ' + object.message); +        Clients.broadcast(object); +      } + +    } catch (error) { +      console.log(error); +    } +  }); +  conn.on('close', function() { //propagate if client quits the page +  Clients.splice(Clients.indexOf(conn)); +  Clients.broadcast({from: 'system', message: origin + ' has quit'}) +//  irc_client.say("#krebs", origin + ' has quit'); +}); +}); + + +var app = connect() +  .use(connect.logger('dev')) +  .use(connect.static(__dirname+'/public')) +  .use( function (req, res) { +    res.writeHead(200, {'Content-Type': 'text/html'}); +    page_template='<!doctype html>\n'; +    page_template+='<link rel="stylesheet" type="text/css" href="reset.css">\n'; +    page_template+='<script src="sockjs-0.3.min.js"></script>\n'; +    page_template+='<script src="jquery-2.0.3.min.js"></script>\n'; +    page_template+='<script src="client.js"></script>\n'; +    page_template+='<div id="bg">'; +    page_template+='<div id="chatter">'; +    page_template+='<div id="space"></div>'; +    page_template+='hello, this is the official krebs support:<br>\n'; +    page_template+='<table id="chatbox"><tr id="foot"><td id="time"></td><td id="nick" class="chat_from"></td><td><input type="text" id="input"></td></tr></table>\n'; +    page_template+='</div>'; +    page_template+='<div id="sideboard"><div id="links">'; +    page_template+='<a href="http://gold.krebsco.de/">krebsgold browser plugin</a><br>'; +    page_template+='<a href="http://ire:1027/dashboard/">ire: Retiolum Dashboard</a><br>'; +    page_template+='<a href="http://pigstarter/">pigstarter: network graphs</a><br>'; +    page_template+='</div></div></div>'; +    res.end(page_template); + +  }) +var server = http.createServer(web_serv_options, app); +echo.installHandlers(server, {prefix:'/echo'}); +server.listen(1337, '0.0.0.0'); +console.log('Server running at https://127.0.0.1:1337/'); diff --git a/webchat/public/client.js b/webchat/public/client.js index 95b67ad0..ca71b537 100644 --- a/webchat/public/client.js +++ b/webchat/public/client.js @@ -6,9 +6,36 @@ function setMaybeNick (input) {    var match = /^\/nick\s+(.+)$/.exec(input);    if (match) {      nick = match[1]; +    $('#nick').html(nick);    }  } +function getCurTime () { +  date = new Date; +  h = date.getHours(); +  if(h<10) +  { +    h = "0"+h; +  } +  m = date.getMinutes(); +  if(m<10) +  { +    m = "0"+m; +  } +  s = date.getSeconds(); +  if(s<10) +  { +    s = "0"+s; +  } +  return ''+h+':'+m+':'+s; +}; + +$(function updateTime () { +  $('#time').html(getCurTime()); +  setTimeout(updateTime,'1000'); +  return true; +}); +  var nick;  $(function connect() { @@ -25,8 +52,11 @@ $(function connect() {        console.log(object.message);        var safe_message = $('<div/>').text(object.message).html();        safe_message = replaceURLWithHTMLLinks(safe_message); -  var safe_from = $('<div/>').text(object.from).html(); -  $('#chatbox').append('<tr><td class="chat_from">'+safe_from+'</td><td class="chat_msg">'+safe_message+'</td></tr>'); +      var safe_from = $('<div/>').text(object.from).html(); +      $('<tr><td class="chat_date">'+getCurTime()+'</td><td class="chat_from">'+safe_from+'</td><td class="chat_msg">'+safe_message+'</td></tr>').insertBefore('#foot'); + +      var elem = document.getElementById('chatter'); +      elem.scrollTop = elem.scrollHeight;      } catch (error) {        console.log(error); diff --git a/webchat/public/reset.css b/webchat/public/reset.css index 17e10567..65f68058 100644 --- a/webchat/public/reset.css +++ b/webchat/public/reset.css @@ -21,6 +21,7 @@ time, mark, audio, video {    border: 0;    font-size: 100%;    font: inherit; +  font-family: monospace;    vertical-align: baseline;  }  /* HTML5 display-role reset for older browsers */ @@ -47,13 +48,21 @@ q:before, q:after {  #chatbox {    border-collapse: collapse;    border-spacing: 0; -  background-color: black; +  color: white; +  width: 100%; +  vertical-align: bottom; +} +#input{ +  width: 100%; +  background-color: #555555; +  border: 1px solid black;    color: white;  }  .chat_from {    color:grey;    font-weight: bold;    text-align: right; +  font-size:12px;  }  .chat_from:after {    content: ":"; @@ -67,6 +76,44 @@ q:before, q:after {    left: 0;    right: 0;  } +#chatter { +  width: 75%; +  height: 100%; +  background-color: black; +  opacity: 0.8; +  overflow: auto; +  overflow-x: hidden; +  vertical-align: bottom; +} +.chat_date,.chat_from,.chat_msg{ +} +.chat_msg{ +  width: 100%; +}  a {    color: red;  } +.chat_date { +  color: green; +} +.chat_date:after { +  content: ""; +  padding-right: 4px; +} +#time { +  color: #00FF00; +} +#sideboard { +  position: absolute; +  top: 0; +  right: 0; +  height: 100%; +  width: 24%; +  background-color: black; +  opacity: 0.8; +} +#links { +  font-size: 14px; +  position: absolute; +  bottom: 5px; +}
\ No newline at end of file  | 
