<repo_name>jayKayEss/Tootr<file_sep>/sql/tootr.sql
-- MySQL dump 10.13  Distrib 5.5.11, for osx10.6 (i386)
--
-- Host: localhost    Database: tootr
-- ------------------------------------------------------
-- Server version	5.5.11

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Table structure for table `edge`
--

DROP TABLE IF EXISTS `edge`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `edge` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `stream_id` int(10) unsigned NOT NULL,
  `from_id` int(10) unsigned NOT NULL,
  `to_id` int(10) unsigned NOT NULL,
  `rank` int(4) DEFAULT NULL,
  `myrand` int(4) unsigned NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `stream_id` (`stream_id`,`from_id`,`to_id`),
  KEY `updated` (`updated`)
) ENGINE=MyISAM AUTO_INCREMENT=63297 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Table structure for table `node`
--

DROP TABLE IF EXISTS `node`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `node` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `term` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=17307 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Table structure for table `stream`
--

DROP TABLE IF EXISTS `stream`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `stream` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=9 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

-- Dump completed on 2012-01-28 16:04:18
<file_sep>/srv/gettweet.php
<?php

require_once dirname(__FILE__).'/../lib/Consts.php';
require_once dirname(__FILE__).'/../lib/DB.php';
require_once dirname(__FILE__).'/../lib/Generator.php';

$stream = Tootr\Consts::$STREAMS[array_rand(Tootr\Consts::$STREAMS)];
$db = new Tootr\DB();
$streamId = $db->getStreamId($stream);
$generator = new Tootr\Generator($db, $stream);
$tweet = $generator->generate();

header('Content-type: application/json');

print json_encode(array(
    'text' => $tweet,
    'stream' => $stream
));


<file_sep>/assets/tootr.js
(function($){

    $(document).ready(function(){
        var tootr = new Tootr();
        tootr.init();
    });

    function Tootr() {
        this.colors = {
            life: '#737d17',
            death: '#333',
            sex: '#9b6262',
            money: '#4c8046'
        };
    }

    Tootr.prototype = {

        init: function() {
            this.displayTweet();
            var self = this;
            setInterval(function(){
                self.displayTweet();
            }, 15000);
        },

        displayTweet: function() {
            var self = this;
            $.ajax({
                dataType: 'json',
                url: 'srv/gettweet.php',
                success: function(data){
                    var stream = data.stream;
                    var text = data.text;
                    var elem = $('#thetweet');

                    elem.find('.container').fadeOut(function(){
                        $('body').animate({
                            'background-color': $.Color( self.colors[stream] )
                        });
                        elem.find('.user').html('@'+stream);
                        elem.find('.name').html(stream.charAt(0).toUpperCase() + stream.slice(1));
                        elem.find('.text').html(text);
                        elem.find('.avatar img').attr({src: 'img/'+stream+'.png'});

                        elem.find('.container').fadeIn();

                    });
                }
            });
        },

    };

})(jQuery);

<file_sep>/bin/test.php
<?php

namespace Tootr;

require_once 'lib/Consts.php';
require_once 'lib/DB.php';
require_once 'lib/Parser.php';
require_once 'lib/Generator.php';

$db = new DB();

foreach (Consts::$STREAMS as $stream) {
    $streamId = $db->getStreamId($stream);
    $generator = new Generator($db, $stream);
    $tweet = $generator->generate() . "\n";

    print "$stream [".strlen($tweet)."] $tweet\n";
}

<file_sep>/lib/DB.php
<?php

namespace Tootr;

class DB {

    const USER = "tootr";
    const PASS = "<PASSWORD>";

    const GET_STREAM = "SELECT id FROM stream WHERE name=?";
    const NEW_STREAM = "INSERT INTO stream (name) VALUES (?)";

    const GET_NODE = "SELECT id FROM node WHERE term=?";
    const GET_NODE_BY_ID = "SELECT * FROM node WHERE id=?";
    const NEW_NODE = "INSERT INTO node (term) VALUES (?)";

    const NEW_EDGE = <<<'EOL'
INSERT INTO edge (stream_id, from_id, to_id, rank, myrand) VALUES (?, ?, ?, 1, cast(rand()*10000 as unsigned)) 
ON DUPLICATE KEY UPDATE rank=rank+1
EOL;

    const GET_EDGES = "SELECT * FROM edge WHERE stream_id=? AND from_id=?";

    protected $dbh;

    function __construct() {
       $this->dbh = new \PDO('mysql:host=127.0.0.1;dbname=tootr', self::USER, self::PASS); 
    }

    function getStreamId($name) {
        $query = $this->dbh->prepare(self::GET_STREAM);
        $query->execute(array($name));

        if ($rec = $query->fetch(\PDO::FETCH_ASSOC)) {
            return $rec['id'];
        }

        $query = $this->dbh->prepare(self::NEW_STREAM);
        $query->execute(array($name));

        return $this->dbh->lastInsertId();
    }

    function getNodeId($term) {
        $query = $this->dbh->prepare(self::GET_NODE);
        $query->execute(array($term));

        if ($rec = $query->fetch(\PDO::FETCH_ASSOC)) {
            return $rec['id'];
        }

        $query = $this->dbh->prepare(self::NEW_NODE);
        $query->execute(array($term));

        return $this->dbh->lastInsertId();
    }

    function getNode($id) {
        $query = $this->dbh->prepare(self::GET_NODE_BY_ID);
        $query->execute(array($id));

        if ($rec = $query->fetch(\PDO::FETCH_ASSOC)) {
            return $rec;
        }
    }

    function addEdge($streamId, $fromId, $toId) {
        $query = $this->dbh->prepare(self::NEW_EDGE);
        $query->execute(array($streamId, $fromId, $toId));
    }

    function getRandomEdge($streamId, $fromId) {
        $query = $this->dbh->prepare(self::GET_EDGES);
        $query->execute(array($streamId, $fromId));

        $picked = null;
        $count = 1;

        while ($rec = $query->fetch(\PDO::FETCH_ASSOC)) {
            $max = $count + $rec['rank'];
            $rand = rand(1, $max);

            if ($rand > $count && $rand <= $max) {
                $picked = $rec;
            }

            $count = $max;
        }

        if (isset($picked)) {
            return $picked;
        } else if (isset($rec)) {
            return $rec;
        } else {
            return null;
        }
    }

}
<file_sep>/lib/Parser.php
<?php

namespace Tootr;

class Parser {

    protected $db;
    protected $streamId;

    function __construct($db, $streamName) {
        $this->db = $db;
        $this->streamId = $db->getStreamId($streamName);
    }

    function parse($text) {
        $words = preg_split('/\s+/', $text);

        $lastWord = null;
        $endOfSentence = false;

        foreach ($words as $word) {
            if (empty($word)) continue;
            if (preg_match('/^http/', $word)) continue;
            if (preg_match('/^@/', $word)) continue;
            if (strtoupper($word) == 'RT') continue;
            if (strtolower($word) == 'moneyblogs') continue;
            if (strtolower($word) == '.info') continue;

            if (preg_match('/[.?!]$/', $word)) {
                $endOfSentence = true;
            }

            if ($lastWord) {
                $this->addEdge($lastWord, $word);
            } else {
                $this->addEdge(null, $word); // headword
            }

            if ($endOfSentence) {
                $lastWord = null;
                $endOfSentence = false;
            } else {
                $lastWord = $word;
            }
        }

    }

    function addEdge($from, $to) {
        if (!empty($from)) {
            $fromId = $this->db->getNodeId($from);
        } else {
            $fromId = 0;
        }
        $toId = $this->db->getNodeId($to);
        $this->db->addEdge($this->streamId, $fromId, $toId);
    }

}
