--- a/client/controlpanel.html Wed Feb 15 12:34:36 2012 +0100
+++ b/client/controlpanel.html Wed Feb 15 18:52:07 2012 +0100
@@ -5,6 +5,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<title>controlpanel</title>
<meta name="description" content="" />
+ <link rel="stylesheet" href="css/base-metric.css" />
<link rel="stylesheet" href="css/controlpanel.css" />
<script type="text/javascript">
$(function() {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/client/css/base-metric.css Wed Feb 15 18:52:07 2012 +0100
@@ -0,0 +1,28 @@
+@font-face {
+ font-family: "Metric";
+ font-weight: normal;
+ font-style: normal;
+ src: url("../font/MetricF-Regular.otf");
+}
+@font-face {
+ font-family: "Metric";
+ font-weight: bold;
+ font-style: normal;
+ src: url("../font/MetricF-Bold.otf");
+}
+@font-face {
+ font-family: "Metric";
+ font-weight: normal;
+ font-style: italic;
+ src: url("../font/MetricF-Italic.otf");
+}
+a, body, div, h1, h2, h3, h4, h5, h6, li, p, span, ul {
+ font-weight: normal; margin: 0; padding: 0; border: none; font-size: 100%;
+ font: inherit; text-decoration: none; color: inherit;
+}
+ul {
+ list-style: none;
+}
+body {
+ font-family: Metric; background: #000000;
+}
\ No newline at end of file
--- a/client/css/controlpanel.css Wed Feb 15 12:34:36 2012 +0100
+++ b/client/css/controlpanel.css Wed Feb 15 18:52:07 2012 +0100
@@ -1,31 +1,4 @@
-@font-face {
- font-family: "Metric";
- font-weight: normal;
- font-style: normal;
- src: url("../font/MetricF-Regular.otf");
-}
-@font-face {
- font-family: "Metric";
- font-weight: bold;
- font-style: normal;
- src: url("../font/MetricF-Bold.otf");
-}
-@font-face {
- font-family: "Metric";
- font-weight: normal;
- font-style: italic;
- src: url("../font/MetricF-Italic.otf");
-}
-a, body, div, h1, h2, h3, h4, h5, h6, li, p, span, ul {
- font-weight: normal; margin: 0; padding: 0; border: none; font-size: 100%;
- font: inherit; text-decoration: none; color: inherit;
-}
-ul {
- list-style: none;
-}
-body {
- font-family: Metric; background: #000000;
-}
+
#btv-cp-container {
position: absolute; top: -65px; width: 100%;
background-image: linear-gradient(bottom, rgb(224,224,224) 20%, rgb(250,250,250) 80%);
--- a/client/js/podium.js Wed Feb 15 12:34:36 2012 +0100
+++ b/client/js/podium.js Wed Feb 15 18:52:07 2012 +0100
@@ -8,7 +8,7 @@
this.options = opts || {};
this.options.container = this.options.container || 'podium';
this.options.spacing = this.options.spacing || 20;
- this.options.background = '#ffffff';
+ this.options.barBgd = this.options.barBgd || '#ffffff';
this.options.transitionDuration = this.options.transitionDuration || 200;
this.$ = this.options.jquery || jQuery;
this._$ = this.$('#' + this.options.container);
@@ -30,7 +30,7 @@
var _newCol = document.createElement("div");
this.$(_newCol).css({
"float": "left",
- "background": this.options.background,
+ "background": this.options.barBgd,
"margin-top": this.options.height,
"width": 0,
"height": 0,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/client/js/tweetsource.js Wed Feb 15 18:52:07 2012 +0100
@@ -0,0 +1,215 @@
+/* Author: Raphaël Velt, IRI
+ *
+ * Licence: CeCILL-B - http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.html
+ *
+ * */
+
+Btv_TweetArray = function() {
+ this.tweets = [];
+ this.idIndex = [];
+}
+
+Btv_TweetArray.prototype.push = function(_tweet) {
+ this.tweets.push(_tweet);
+ this.idIndex.push(_tweet.id_str);
+}
+
+Btv_TweetArray.prototype.addTweet = function(_tweet, _inhibitCallback) {
+ if (this.idIndex.indexOf(_tweet.id_str) != -1) {
+ return;
+ }
+ if (!_tweet.date_value) {
+ _tweet.date_value = Date.parse(_tweet.created_at.replace(/(\+|-)/,'UTC$1'));
+ }
+ var _pos = this.tweets.length;
+ while (_pos && this.idIndex[_pos - 1] > _tweet.id_str) {
+ _pos--;
+ }
+ this.tweets.splice(_pos,0,_tweet);
+ this.idIndex.splice(_pos,0,_tweet.id_str);
+}
+
+Btv_TweetArray.prototype.addMultipleTweets = function(_multiTweets) {
+ var _l = _multiTweets.length;
+ for (var _i = 0; _i < _l; _i++) {
+ this.addTweet(_multiTweets[_i], true);
+ }
+}
+
+Btv_TweetArray.prototype.count = function() {
+ return this.tweets.length;
+}
+
+Btv_TweetArray.prototype.getTweet = function(_i) {
+ return this.tweets(_i);
+}
+
+Btv_TweetArray.prototype.slice = function(_start, _end) {
+ var _slice = this.tweets.slice(_start, _end),
+ _result = new Btv_TweetArray(),
+ _l = _slice.length;
+ for (var _i = 0; _i < _l; _i++) {
+ _result.push(_slice[_i]);
+ }
+ return _result;
+}
+
+Btv_TweetArray.prototype.reverse = function() {
+ var _result = new Btv_TweetArray(),
+ _l = this.tweets.length;
+ for (var _i = _l-1; _i >= 0; _i--) {
+ _result.push(this.tweets[_i]);
+ }
+ return _result;
+}
+
+Btv_TweetArray.prototype.each = function(_callback) {
+ var _l = this.count();
+ for (var _i = 0; _i < _l; _i++) {
+ _callback(this.tweets[_i]);
+ }
+}
+
+Btv_TweetArray.prototype.map = function(_callback) {
+ var _result = [];
+ this.each(function(_tweet) {
+ _result.push(_callback(_tweet))
+ });
+ return _result;
+}
+
+Btv_TweetArray.prototype.search = function(_filter) {
+ var _filtered = new Btv_TweetArray(),
+ _reFilter = new RegExp(_filter.replace(/\W/gim,'\\$1'),'gim');
+ this.each(function(_tweet) {
+ var _mention = '@' + _tweet.from_user;
+ if (( _tweet.text.search(_reFilter) != -1 ) || ( _mention.search(_reFilter) != -1 )) {
+ _filtered.push(_tweet);
+ }
+ });
+ return _filtered;
+}
+
+Btv_TweetArray.prototype.beforeDate = function(_date) {
+ var _filtered = new Btv_TweetArray();
+ this.each(function(_tweet) {
+ if (_tweet.date_value < _date) {
+ _filtered.push(_tweet);
+ }
+ });
+ return _filtered;
+}
+
+Btv_TweetArray.prototype.afterDate = function(_date) {
+ var _filtered = new Btv_TweetArray();
+ this.each(function(_tweet) {
+ if (_tweet.date_value > _date) {
+ _filtered.push(_tweet);
+ }
+ });
+ return _filtered;
+}
+
+Btv_TweetArray.prototype.tweetById = function(_tweetId) {
+ var _index = this.idIndex.indexOf(_tweetId);
+ return (_index ? this.tweets[_index] : null);
+}
+
+Btv_TweetArray.prototype.lastTweet = function() {
+ return this.tweets[this.tweets.length - 1];
+}
+
+/*
+ *
+ */
+
+Btv_TweetSource = function(_opts) {
+ Btv_TweetArray.call(this);
+ this.loading = false;
+ if (!_opts || !_opts.keywords || !_opts.keywords.length) {
+ return;
+ }
+ this.options = _opts;
+ var _this = this;
+ this.retrieveInitialTweets()
+ setInterval(function() {
+ _this.retrieveNewTweets();
+ }, 5000);
+}
+
+Btv_TweetSource.prototype = new Btv_TweetArray();
+
+Btv_TweetSource.prototype.retrieveTweets = function(_opts) {
+
+ function getTwitterUrl(url) {
+ $.getJSON(url, function(data) {
+ _currentPage++;
+ var _isLast = true;
+ if (data.results && data.results.length) {
+ _this.addMultipleTweets(data.results);
+ var _oldestTweetId = data.results[data.results.length - 1].id_str,
+ _maxId = _oldestTweetId;
+ if (_currentPage < _opts.pages) {
+ _isLast = false;
+ getTwitterUrl(_baseurl + _firstparams + '&max_id=' + _maxId + _lastparams);
+ }
+ }
+
+ if (_isLast) {
+ _this.loading = false;
+ if (_this.tweetsCallback) {
+ _this.tweetsCallback();
+ }
+ }
+ });
+ }
+
+ if (this.loading) {
+ return;
+ }
+ this.loading = true;
+
+ var _baseurl = "http://search.twitter.com/search.json",
+ _currentPage = 0,
+ _firstparams = "?q="
+ + encodeURIComponent(this.options.keywords.join(' OR '))
+ + "&rpp=100"
+ + (this.options.lang ? "&lang=" + this.options.lang : '' ),
+ _lastparams = ( _opts.since_id ? "&since_id=" + _opts.since_id : '' )
+ + "&callback=?",
+ _jsonurl = _baseurl + _firstparams + _lastparams,
+ _this = this;
+ getTwitterUrl(_jsonurl);
+
+}
+
+Btv_TweetSource.prototype.retrieveInitialTweets = function() {
+ this.retrieveTweets({
+ "pages": 6
+ });
+}
+
+Btv_TweetSource.prototype.retrieveNewTweets = function() {
+ this.retrieveTweets({
+ "pages": 1,
+ "since_id": this.lastTweet().id_str
+ });
+}
+
+Btv_TweetArray.prototype.setTweetsCallback = function(_callback) {
+ this.tweetsCallback = _callback;
+}
+
+/*
+Btv_TweetSubscriber = function(tweetArray) {
+ this.tweetArray = tweetArray;
+ this.position = 0;
+}
+
+Btv_TweetSubscriber.getTweets = function() {
+ var _p = this.position,
+ _l = this.tweetArray.count();
+ this.position = _l;
+ return this.tweetArray.slice(_p,_l);
+}
+*/
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/client/podium-cp-tweets.html Wed Feb 15 18:52:07 2012 +0100
@@ -0,0 +1,144 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
+ <title>controlpanel</title>
+ <meta name="description" content="" />
+ <link rel="stylesheet" href="css/base-metric.css" />
+ <link rel="stylesheet" href="css/controlpanel.css" />
+ <style type="text/css">
+ #podium-container {
+ width: 800px;
+ margin: 200px auto 0;
+ }
+ #podium {
+ width: 100%;
+ height: 300px;
+ cursor: pointer;
+ }
+ #podium-labels {
+ float: left;
+ width: 100%;
+ clear: both;
+ margin-top: 20px;
+ }
+ #podium-labels li {
+ float: left;
+ width: 200px;
+ color: #ffffff;
+ text-align: center;
+ font-size: 28px;
+ font-weight: bold;
+ }
+ </style>
+ <script type="text/javascript" src="lib/jquery.min.js"></script>
+ <script type="text/javascript" src="js/podium.js"></script>
+ <script type="text/javascript" src="js/tweetsource.js"></script>
+ <script type="text/javascript">
+ var tzero = new Date();
+ $(function() {
+ setInterval(function() {
+ var _t = Math.floor((new Date() - tzero)/1000),
+ _s = _t % 60,
+ _m = Math.floor(_t/60) % 60,
+ _h = Math.floor(_t/3600);
+ $("#btv-cp-temps").html(
+ _h + ':' + (_m < 10 ? '0' : '') + _m + ':' + (_s < 10 ? '0' : '') + _s
+ )
+ }, 500);
+ var _keywords = ['Sarkozy', 'Hollande', 'candidat', 'politique']
+ myTweetSource = new Btv_TweetSource({
+ keywords: _keywords
+ });
+ myPodium = new Btv_Podium([0,0,0,0]);
+ myTweetSource.setTweetsCallback(function() {
+ $("#btv-cp-nb-tweets").html(this.count());
+ var _counts = [];
+ for (var _i = 0; _i < _keywords.length; _i++) {
+ _counts.push(this.search(_keywords[_i]).count());
+ }
+ myPodium.update(_counts);
+ $('#btv-cp-liste-tweets-tout').html(
+ this.reverse().slice(0,20).map(function(_t) {
+ return '<li onclick="addTweet(\''
+ + _t.id_str
+ + '\'); return false;"><a title="Ajouter à la sélection" href="#"><span class="btv-cp-tweet-date">'
+ + _t.created_at.match(/\d+:\d+:\d+/)[0]
+ + '</span> <span class="btv-cp-tweet-from">@'
+ + _t.from_user
+ + '</span> <span class="btv-cp-tweet-text">'
+ + _t.text
+ + '</span><div class="btv-cp-tweet-button btv-cp-tweet-add"></div></a></li>'
+ }).join('')
+ )
+ });
+ });
+ function addTweet(tweetId) {
+ var _t = myTweetSource.tweetById(tweetId);
+ if (_t) {
+ $("#btv-cp-liste-tweets-selection").prepend(
+ '<li onclick="showTweet(\''
+ + _t.id_str
+ + '\'); return false;"><a title="Afficher sur l\'écran" href="#"><span class="btv-cp-tweet-date">'
+ + _t.created_at.match(/\d+:\d+:\d+/)[0]
+ + '</span> <span class="btv-cp-tweet-from">@'
+ + _t.from_user
+ + '</span> <span class="btv-cp-tweet-text">'
+ + _t.text
+ + '</span><div class="btv-cp-tweet-button btv-cp-tweet-show"></div></a></li>'
+ );
+ }
+ }
+ </script>
+ </head>
+ <body>
+ <div id="btv-cp-container">
+ <div class="btv-cp-line">
+ <div class="btv-cp-element">
+ <h2>Bubble <b>TV</b></h2>
+ </div>
+ <div class="btv-cp-element" id="btv-cp-cont-filtre">
+ <h3>Rechercher/Filtrer</h3>
+ <input id="btv-cp-champ-filtre" />
+ <a href="#" id="btv-cp-clear-filtre">x</a>
+ </div>
+ <div class="btv-cp-element">
+ <h3>Derniers tweets</h3>
+ <ul class="btv-cp-liste-tweets" id="btv-cp-liste-tweets-tout">
+ </ul>
+ </div>
+ <div class="btv-cp-element">
+ <h3>Tweets sélectionnés</h3>
+ <ul class="btv-cp-liste-tweets" id="btv-cp-liste-tweets-selection">
+ </ul>
+ </div>
+ <div class="btv-cp-element btv-cp-cont-pause" id="btv-cp-cont-pause-amont">
+ <h3>Arrivée des tweets</h3>
+ <a class="btv-cp-play-pause btv-cp-status-pause" href="#"></a>
+ </div>
+ <div class="btv-cp-element btv-cp-cont-pause" id="btv-cp-cont-pause-aval">
+ <h3>Purge des colonnes</h3>
+ <a class="btv-cp-play-pause btv-cp-status-pause" href="#"></a>
+ </div>
+ <div class="btv-cp-element btv-cp-compteur">
+ <h3>Nombre de tweets</h3>
+ <h4 id="btv-cp-nb-tweets"></h4>
+ </div>
+ <div class="btv-cp-element btv-cp-compteur">
+ <h3>Temps écoulé</h3>
+ <h4 id="btv-cp-temps">0:00:00</h4>
+ </div>
+ </div>
+ </div>
+ <div id="podium-container">
+ <div id="podium"></div>
+ <ul id="podium-labels">
+ <li>Sarkozy</li>
+ <li>Hollande</li>
+ <li>candidat</li>
+ <li>politique</li>
+ </ul>
+ </div>
+ </body>
+</html>