# HG changeset patch # User Raphael Velt # Date 1319527197 -7200 # Node ID 738594562e4477841e8058b844774c58a2cd2810 # Parent 03c69425efa60f4d908d969064918a27221aa447 Reorganisation branche node diff -r 03c69425efa6 -r 738594562e44 tweetcast/nodejs/client/css/style.css --- a/tweetcast/nodejs/client/css/style.css Mon Oct 24 18:01:55 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,189 +0,0 @@ -/* Browser-reset CSS */ - -html, body, div, span, applet, object, iframe, -h1, h2, h3, h4, h5, h6, p, blockquote, pre, -a, abbr, acronym, address, big, cite, code, -del, dfn, em, img, ins, kbd, q, s, samp, -small, strike, strong, sub, sup, tt, var, -b, u, i, center, -dl, dt, dd, ol, ul, li, -fieldset, form, label, legend, -table, caption, tbody, tfoot, thead, tr, th, td, -article, aside, canvas, details, embed, -figure, figcaption, footer, header, hgroup, -menu, nav, output, ruby, section, summary, -time, mark, audio, video { - margin: 0; - padding: 0; - border: 0; - font-size: 100%; - font: inherit; - vertical-align: baseline; -} - -body { - font-family: Helvetica, Arial, sans-serif; -} - -/* Liste de Tweets */ - -#tweetlist { - position: absolute; left: 50px; top: 50px; width: 250px; height: 600px; list-style: none; border: 1px solid #999; -} - -li.tweet, li.placeholder { - border: 1px solid; overflow: hidden; float: left; margin: -1px 0 0 -1px; border-color: #ccc; -} - -li.tweet { - position: relative; background: #fff; -} - -li.full { - width: 240px; height: 119px; border-right: 10px solid #ff0; -} - -li.half { - width: 250px; height: 49px; -} - -li.quarter { - width: 124px; height: 44px; -} - -li.icons { - width: 24px; height: 24px; -} - -li.placeholder { - height: 0; visibility: hidden; -} - -.tweet h4 { - font-weight: bold; -} - -.quarter p { - word-break: break-all; -} - -.full h4, .full p, .half p { - margin: 5px; -} - -.full h4 { - font-size: 15px; -} - -.full p, .half p { - font-size: 12px; -} - -.quarter p { - margin: 2px; font-size: 10px; -} - -img.profile_image { - float: left; -} - -.full .profile_image { - margin: 5px; width: 48px; height: 48px; -} - -.half .profile_image { - margin: 5px; width: 39px; height: 39px; -} - -.quarter .profile_image { - margin: 2px; width: 22px; height: 22px; -} - -.icons .profile_image { - margin: 2px; width: 20px; height: 20px; -} - -.full .created_at { - font-style: italic; color: #999; -} - -.half h4, .half p.created_at, .quarter h4, .quarter p.created_at, .icons h4, .icons p { - display: none -} - -.full .tweet_text { - clear: left; -} - -.annotations { - position: absolute; margin: 0; padding: 0; top: 0; left: 0; width: 100%; height: 100%; -} - -/*.icons .annotations { - position: absolute; width: 6px; height: 6px; right: 2px; bottom: 2px; border: 1px solid #ccc; z-index: 3; -}*/ - -div.annotation { - float: left; height: 100%; -} - -div.twmain { - position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 2; overflow: hidden; -} - -.full .twmain { -} - -.half .twmain { - opacity: .9 -} - -.half.fade .twmain { - opacity: .8 -} - -.quarter .twmain { - opacity: .7 -} - -.quarter.fade .twmain { - opacity: .6 -} - -.icons .twmain { - opacity: .5 -} - -.icons.fade .twmain { - opacity: .4 -} - -.positive { - background: #c5e7cd; -} - -.negative { - background: #f6ced0; -} - -.reference { - background: #ecedc1; -} - -.question { - background: #bfdbec; -} - -/* timeline */ - -#timeline, #timewindow { - position: absolute; top: 50px; left: 301px; height: 600px; width: 220px; border: 1px solid #999; -} - -#timeline { - z-index: 42 -} - -#timewindow { - z-index: 47 -} \ No newline at end of file diff -r 03c69425efa6 -r 738594562e44 tweetcast/nodejs/client/index.html --- a/tweetcast/nodejs/client/index.html Mon Oct 24 18:01:55 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,23 +0,0 @@ - - - - - Polemic Tweet “TweetCast” - - - - - - - - - -
-
- - \ No newline at end of file diff -r 03c69425efa6 -r 738594562e44 tweetcast/nodejs/client/js/jquery.mousewheel.min.js --- a/tweetcast/nodejs/client/js/jquery.mousewheel.min.js Mon Oct 24 18:01:55 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,11 +0,0 @@ -/* Copyright (c) 2009 Brandon Aaron (http://brandonaaron.net) - * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) - * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. - * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers. - * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix. - * - * Version: 3.0.2 - * - * Requires: 1.2.2+ - */ -(function(c){var a=["DOMMouseScroll","mousewheel"];c.event.special.mousewheel={setup:function(){if(this.addEventListener){for(var d=a.length;d;){this.addEventListener(a[--d],b,false)}}else{this.onmousewheel=b}},teardown:function(){if(this.removeEventListener){for(var d=a.length;d;){this.removeEventListener(a[--d],b,false)}}else{this.onmousewheel=null}}};c.fn.extend({mousewheel:function(d){return d?this.bind("mousewheel",d):this.trigger("mousewheel")},unmousewheel:function(d){return this.unbind("mousewheel",d)}});function b(f){var d=[].slice.call(arguments,1),g=0,e=true;f=c.event.fix(f||window.event);f.type="mousewheel";if(f.wheelDelta){g=f.wheelDelta/120}if(f.detail){g=-f.detail/3}d.unshift(f,g);return c.event.handle.apply(this,d)}})(jQuery); \ No newline at end of file diff -r 03c69425efa6 -r 738594562e44 tweetcast/nodejs/client/js/raphael-min.js --- a/tweetcast/nodejs/client/js/raphael-min.js Mon Oct 24 18:01:55 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,8 +0,0 @@ -// ┌─────────────────────────────────────────────────────────────────────┐ \\ -// │ Raphaël 2.0 - JavaScript Vector Library │ \\ -// ├─────────────────────────────────────────────────────────────────────┤ \\ -// │ Copyright (c) 2008-2011 Dmitry Baranovskiy (http://raphaeljs.com) │ \\ -// │ Copyright (c) 2008-2011 Sencha Labs (http://sencha.com) │ \\ -// │ Licensed under the MIT (http://raphaeljs.com/license.html) license. │ \\ -// └─────────────────────────────────────────────────────────────────────┘ \\ -(function(a){var b="0.3.2",c="hasOwnProperty",d=/[\.\/]/,e="*",f=function(){},g=function(a,b){return a-b},h,i,j={n:{}},k=function(a,b){var c=j,d=i,e=Array.prototype.slice.call(arguments,2),f=k.listeners(a),l=0,m=!1,n,o=[],p={},q=[],r=[];h=a,i=0;for(var s=0,t=f.length;sf*b.top){e=b.percents[y],p=b.percents[y-1]||0,t=t/b.top*(e-p),o=b.percents[y+1],j=b.anim[e];break}f&&d.attr(b.anim[b.percents[y]])}if(!!j){if(!k){for(attr in j)if(j[g](attr))if(U[g](attr)||d.paper.customAttributes[g](attr)){u[attr]=d.attr(attr),u[attr]==null&&(u[attr]=T[attr]),v[attr]=j[attr];switch(U[attr]){case C:w[attr]=(v[attr]-u[attr])/t;break;case"colour":u[attr]=a.getRGB(u[attr]);var A=a.getRGB(v[attr]);w[attr]={r:(A.r-u[attr].r)/t,g:(A.g-u[attr].g)/t,b:(A.b-u[attr].b)/t};break;case"path":var B=bG(u[attr],v[attr]),D=B[1];u[attr]=B[0],w[attr]=[];for(y=0,z=u[attr].length;yd)return d;while(cf?c=e:d=e,e=(d-c)/2+c}return e}function n(a,b){var c=o(a,b);return((l*c+k)*c+j)*c}function m(a){return((i*a+h)*a+g)*a}var g=3*b,h=3*(d-b)-g,i=1-g-h,j=3*c,k=3*(e-c)-j,l=1-j-k;return n(a,1/(200*f))}function cd(){return this.x+q+this.y+q+this.width+" × "+this.height}function cc(){return this.x+q+this.y}function bR(a,b,c,d,e,f){a!=null?(this.a=+a,this.b=+b,this.c=+c,this.d=+d,this.e=+e,this.f=+f):(this.a=1,this.b=0,this.c=0,this.d=1,this.e=0,this.f=0)}function bw(a){var b=[];for(var c=0,d=a.length;d-2>c;c+=2){var e=[{x:+a[c],y:+a[c+1]},{x:+a[c],y:+a[c+1]},{x:+a[c+2],y:+a[c+3]},{x:+a[c+4],y:+a[c+5]}];d-4==c?(e[0]={x:+a[c-2],y:+a[c-1]},e[3]=e[2]):c&&(e[0]={x:+a[c-2],y:+a[c-1]}),b.push(["C",(-e[0].x+6*e[1].x+e[2].x)/6,(-e[0].y+6*e[1].y+e[2].y)/6,(e[1].x+6*e[2].x-e[3].x)/6,(e[1].y+6*e[2].y-e[3].y)/6,e[2].x,e[2].y])}return b}function bv(){return this.hex}function bt(a,b,c){function d(){var e=Array.prototype.slice.call(arguments,0),f=e.join("␀"),h=d.cache=d.cache||{},i=d.count=d.count||[];if(h[g](f)){bs(i,f);return c?c(h[f]):h[f]}i.length>=1e3&&delete h[i.shift()],i.push(f),h[f]=a[m](b,e);return c?c(h[f]):h[f]}return d}function bs(a,b){for(var c=0,d=a.length;c',bk=bj.firstChild,bk.style.behavior="url(#default#VML)";if(!bk||typeof bk.adj!="object")return a.type=p;bj=null}a.svg=!(a.vml=a.type=="VML"),a._Paper=j,a.fn=k=j.prototype=a.prototype,a._id=0,a._oid=0,a.is=function(a,b){b=v.call(b);if(b=="finite")return!M[g](+a);if(b=="array")return a instanceof Array;return b=="null"&&a===null||b==typeof a&&a!==null||b=="object"&&a===Object(a)||b=="array"&&Array.isArray&&Array.isArray(a)||H.call(a).slice(8,-1).toLowerCase()==b},a.angle=function(b,c,d,e,f,g){if(f==null){var h=b-d,i=c-e;if(!h&&!i)return 0;return(180+w.atan2(-i,-h)*180/B+360)%360}return a.angle(b,c,f,g)-a.angle(d,e,f,g)},a.rad=function(a){return a%360*B/180},a.deg=function(a){return a*180/B%360},a.snapTo=function(b,c,d){d=a.is(d,"finite")?d:10;if(a.is(b,E)){var e=b.length;while(e--)if(z(b[e]-c)<=d)return b[e]}else{b=+b;var f=c%b;if(fb-d)return c-f+b}return c};var bl=a.createUUID=function(a,b){return function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(a,b).toUpperCase()}}(/[xy]/g,function(a){var b=w.random()*16|0,c=a=="x"?b:b&3|8;return c.toString(16)});a.setWindow=function(b){eve("setWindow",a,h.win,b),h.win=b,h.doc=h.win.document,initWin&&initWin(h.win)};var bm=function(b){if(a.vml){var c=/^\s+|\s+$/g,d;try{var e=new ActiveXObject("htmlfile");e.write(""),e.close(),d=e.body}catch(f){d=createPopup().document.body}var g=d.createTextRange();bm=bt(function(a){try{d.style.color=r(a).replace(c,p);var b=g.queryCommandValue("ForeColor");b=(b&255)<<16|b&65280|(b&16711680)>>>16;return"#"+("000000"+b.toString(16)).slice(-6)}catch(e){return"none"}})}else{var i=h.doc.createElement("i");i.title="Raphaël Colour Picker",i.style.display="none",h.doc.body.appendChild(i),bm=bt(function(a){i.style.color=a;return h.doc.defaultView.getComputedStyle(i,p).getPropertyValue("color")})}return bm(b)},bn=function(){return"hsb("+[this.h,this.s,this.b]+")"},bo=function(){return"hsl("+[this.h,this.s,this.l]+")"},bp=function(){return this.hex},bq=function(b,c,d){c==null&&a.is(b,"object")&&"r"in b&&"g"in b&&"b"in b&&(d=b.b,c=b.g,b=b.r);if(c==null&&a.is(b,D)){var e=a.getRGB(b);b=e.r,c=e.g,d=e.b}if(b>1||c>1||d>1)b/=255,c/=255,d/=255;return[b,c,d]},br=function(b,c,d,e){b*=255,c*=255,d*=255;var f={r:b,g:c,b:d,hex:a.rgb(b,c,d),toString:bp};a.is(e,"finite")&&(f.opacity=e);return f};a.color=function(b){var c;a.is(b,"object")&&"h"in b&&"s"in b&&"b"in b?(c=a.hsb2rgb(b),b.r=c.r,b.g=c.g,b.b=c.b,b.hex=c.hex):a.is(b,"object")&&"h"in b&&"s"in b&&"l"in b?(c=a.hsl2rgb(b),b.r=c.r,b.g=c.g,b.b=c.b,b.hex=c.hex):(a.is(b,"string")&&(b=a.getRGB(b)),a.is(b,"object")&&"r"in b&&"g"in b&&"b"in b?(c=a.rgb2hsl(b),b.h=c.h,b.s=c.s,b.l=c.l,c=a.rgb2hsb(b),b.v=c.b):(b={hex:"none"},crl.r=b.g=b.b=b.h=b.s=b.v=b.l=-1)),b.toString=bp;return b},a.hsb2rgb=function(a,b,c,d){this.is(a,"object")&&"h"in a&&"s"in a&&"b"in a&&(c=a.b,b=a.s,a=a.h,d=a.o),a*=360;var e,f,g,h,i;a=a%360/60,i=c*b,h=i*(1-z(a%2-1)),e=f=g=c-i,a=~~a,e+=[i,h,0,0,h,i][a],f+=[h,i,i,h,0,0][a],g+=[0,0,h,i,i,h][a];return br(e,f,g,d)},a.hsl2rgb=function(a,b,c,d){this.is(a,"object")&&"h"in a&&"s"in a&&"l"in a&&(c=a.l,b=a.s,a=a.h);if(a>1||b>1||c>1)a/=360,b/=100,c/=100;a*=360;var e,f,g,h,i;a=a%360/60,i=2*b*(c<.5?c:1-c),h=i*(1-z(a%2-1)),e=f=g=c-i/2,a=~~a,e+=[i,h,0,0,h,i][a],f+=[h,i,i,h,0,0][a],g+=[0,0,h,i,i,h][a];return br(e,f,g,d)},a.rgb2hsb=function(a,b,c){c=bq(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g;f=x(a,b,c),g=f-y(a,b,c),d=g==0?null:f==a?(b-c)/g:f==b?(c-a)/g+2:(a-b)/g+4,d=(d+360)%6*60/360,e=g==0?0:g/f;return{h:d,s:e,b:f,toString:bn}},a.rgb2hsl=function(a,b,c){c=bq(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g,h,i;g=x(a,b,c),h=y(a,b,c),i=g-h,d=i==0?null:g==a?(b-c)/i:g==b?(c-a)/i+2:(a-b)/i+4,d=(d+360)%6*60/360,f=(g+h)/2,e=i==0?0:f<.5?i/(2*f):i/(2-2*f);return{h:d,s:e,l:f,toString:bo}},a._path2string=function(){return this.join(",").replace(X,"$1")};var bu=a._preload=function(a,b){var c=h.doc.createElement("img");c.style.cssText="position:absolute;left:-9999em;top-9999em",c.onload=function(){b.call(this),this.onload=null,h.doc.body.removeChild(this)},c.onerror=function(){h.doc.body.removeChild(this)},h.doc.body.appendChild(c),c.src=a};a.getRGB=bt(function(b){if(!b||!!((b=r(b)).indexOf("-")+1))return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:bv};if(b=="none")return{r:-1,g:-1,b:-1,hex:"none",toString:bv};!W[g](b.toLowerCase().substring(0,2))&&b.charAt()!="#"&&(b=bm(b));var c,d,e,f,h,i,j,k=b.match(L);if(k){k[2]&&(f=R(k[2].substring(5),16),e=R(k[2].substring(3,5),16),d=R(k[2].substring(1,3),16)),k[3]&&(f=R((i=k[3].charAt(3))+i,16),e=R((i=k[3].charAt(2))+i,16),d=R((i=k[3].charAt(1))+i,16)),k[4]&&(j=k[4][s](V),d=Q(j[0]),j[0].slice(-1)=="%"&&(d*=2.55),e=Q(j[1]),j[1].slice(-1)=="%"&&(e*=2.55),f=Q(j[2]),j[2].slice(-1)=="%"&&(f*=2.55),k[1].toLowerCase().slice(0,4)=="rgba"&&(h=Q(j[3])),j[3]&&j[3].slice(-1)=="%"&&(h/=100));if(k[5]){j=k[5][s](V),d=Q(j[0]),j[0].slice(-1)=="%"&&(d*=2.55),e=Q(j[1]),j[1].slice(-1)=="%"&&(e*=2.55),f=Q(j[2]),j[2].slice(-1)=="%"&&(f*=2.55),(j[0].slice(-3)=="deg"||j[0].slice(-1)=="°")&&(d/=360),k[1].toLowerCase().slice(0,4)=="hsba"&&(h=Q(j[3])),j[3]&&j[3].slice(-1)=="%"&&(h/=100);return a.hsb2rgb(d,e,f,h)}if(k[6]){j=k[6][s](V),d=Q(j[0]),j[0].slice(-1)=="%"&&(d*=2.55),e=Q(j[1]),j[1].slice(-1)=="%"&&(e*=2.55),f=Q(j[2]),j[2].slice(-1)=="%"&&(f*=2.55),(j[0].slice(-3)=="deg"||j[0].slice(-1)=="°")&&(d/=360),k[1].toLowerCase().slice(0,4)=="hsla"&&(h=Q(j[3])),j[3]&&j[3].slice(-1)=="%"&&(h/=100);return a.hsl2rgb(d,e,f,h)}k={r:d,g:e,b:f,toString:bv},k.hex="#"+(16777216|f|e<<8|d<<16).toString(16).slice(1),a.is(h,"finite")&&(k.opacity=h);return k}return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:bv}},a),a.hsb=bt(function(b,c,d){return a.hsb2rgb(b,c,d).hex}),a.hsl=bt(function(b,c,d){return a.hsl2rgb(b,c,d).hex}),a.rgb=bt(function(a,b,c){return"#"+(16777216|c|b<<8|a<<16).toString(16).slice(1)}),a.getColor=function(a){var b=this.getColor.start=this.getColor.start||{h:0,s:1,b:a||.75},c=this.hsb2rgb(b.h,b.s,b.b);b.h+=.075,b.h>1&&(b.h=0,b.s-=.2,b.s<=0&&(this.getColor.start={h:0,s:1,b:b.b}));return c.hex},a.getColor.reset=function(){delete this.start},a.parsePathString=bt(function(b){if(!b)return null;var c={a:7,c:6,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,z:0},d=[];a.is(b,E)&&a.is(b[0],E)&&(d=by(b)),d.length||r(b).replace(Y,function(a,b,e){var f=[],g=b.toLowerCase();e.replace($,function(a,b){b&&f.push(+b)}),g=="m"&&f.length>2&&(d.push([b][n](f.splice(0,2))),g="l",b=b=="m"?"l":"L");if(g=="r")d.push([b][n](f));else while(f.length>=c[g]){d.push([b][n](f.splice(0,c[g])));if(!c[g])break}}),d.toString=a._path2string;return d}),a.parseTransformString=bt(function(b){if(!b)return null;var c={r:3,s:4,t:2,m:6},d=[];a.is(b,E)&&a.is(b[0],E)&&(d=by(b)),d.length||r(b).replace(Z,function(a,b,c){var e=[],f=v.call(b);c.replace($,function(a,b){b&&e.push(+b)}),d.push([b][n](e))}),d.toString=a._path2string;return d}),a.findDotsAtSegment=function(a,b,c,d,e,f,g,h,i){var j=1-i,k=A(j,3),l=A(j,2),m=i*i,n=m*i,o=k*a+l*3*i*c+j*3*i*i*e+n*g,p=k*b+l*3*i*d+j*3*i*i*f+n*h,q=a+2*i*(c-a)+m*(e-2*c+a),r=b+2*i*(d-b)+m*(f-2*d+b),s=c+2*i*(e-c)+m*(g-2*e+c),t=d+2*i*(f-d)+m*(h-2*f+d),u=j*a+i*c,v=j*b+i*d,x=j*e+i*g,y=j*f+i*h,z=90-w.atan2(q-s,r-t)*180/B;(q>s||r1&&(v=w.sqrt(v),c=v*c,d=v*d);var x=c*c,y=d*d,A=(f==g?-1:1)*w.sqrt(z((x*y-x*u*u-y*t*t)/(x*u*u+y*t*t))),C=A*c*u/d+(a+h)/2,D=A*-d*t/c+(b+i)/2,E=w.asin(((b-D)/d).toFixed(9)),F=w.asin(((i-D)/d).toFixed(9));E=aF&&(E=E-B*2),!g&&F>E&&(F=F-B*2)}else E=j[0],F=j[1],C=j[2],D=j[3];var G=F-E;if(z(G)>k){var H=F,I=h,J=i;F=E+k*(g&&F>E?1:-1),h=C+c*w.cos(F),i=D+d*w.sin(F),m=bD(h,i,c,d,e,0,g,I,J,[F,H,C,D])}G=F-E;var K=w.cos(E),L=w.sin(E),M=w.cos(F),N=w.sin(F),O=w.tan(G/4),P=4/3*c*O,Q=4/3*d*O,R=[a,b],S=[a+P*L,b-Q*K],T=[h+P*N,i-Q*M],U=[h,i];S[0]=2*R[0]-S[0],S[1]=2*R[1]-S[1];if(j)return[S,T,U][n](m);m=[S,T,U][n](m).join()[s](",");var V=[];for(var W=0,X=m.length;W"1e12"&&(l=.5),z(n)>"1e12"&&(n=.5),l>0&&l<1&&(q=bE(a,b,c,d,e,f,g,h,l),p.push(q.x),o.push(q.y)),n>0&&n<1&&(q=bE(a,b,c,d,e,f,g,h,n),p.push(q.x),o.push(q.y)),i=f-2*d+b-(h-2*f+d),j=2*(d-b)-2*(f-d),k=b-d,l=(-j+w.sqrt(j*j-4*i*k))/2/i,n=(-j-w.sqrt(j*j-4*i*k))/2/i,z(l)>"1e12"&&(l=.5),z(n)>"1e12"&&(n=.5),l>0&&l<1&&(q=bE(a,b,c,d,e,f,g,h,l),p.push(q.x),o.push(q.y)),n>0&&n<1&&(q=bE(a,b,c,d,e,f,g,h,n),p.push(q.x),o.push(q.y));return{min:{x:y[m](0,p),y:y[m](0,o)},max:{x:x[m](0,p),y:x[m](0,o)}}}),bG=a._path2curve=bt(function(a,b){var c=bA(a),d=b&&bA(b),e={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},f={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},g=function(a,b){var c,d;if(!a)return["C",b.x,b.y,b.x,b.y,b.x,b.y];!(a[0]in{T:1,Q:1})&&(b.qx=b.qy=null);switch(a[0]){case"M":b.X=a[1],b.Y=a[2];break;case"A":a=["C"][n](bD[m](0,[b.x,b.y][n](a.slice(1))));break;case"S":c=b.x+(b.x-(b.bx||b.x)),d=b.y+(b.y-(b.by||b.y)),a=["C",c,d][n](a.slice(1));break;case"T":b.qx=b.x+(b.x-(b.qx||b.x)),b.qy=b.y+(b.y-(b.qy||b.y)),a=["C"][n](bC(b.x,b.y,b.qx,b.qy,a[1],a[2]));break;case"Q":b.qx=a[1],b.qy=a[2],a=["C"][n](bC(b.x,b.y,a[1],a[2],a[3],a[4]));break;case"L":a=["C"][n](bB(b.x,b.y,a[1],a[2]));break;case"H":a=["C"][n](bB(b.x,b.y,a[1],b.y));break;case"V":a=["C"][n](bB(b.x,b.y,b.x,a[1]));break;case"Z":a=["C"][n](bB(b.x,b.y,b.X,b.Y))}return a},h=function(a,b){if(a[b].length>7){a[b].shift();var e=a[b];while(e.length)a.splice(b++,0,["C"][n](e.splice(0,6)));a.splice(b,1),k=x(c.length,d&&d.length||0)}},i=function(a,b,e,f,g){a&&b&&a[g][0]=="M"&&b[g][0]!="M"&&(b.splice(g,0,["M",f.x,f.y]),e.bx=0,e.by=0,e.x=a[g][1],e.y=a[g][2],k=x(c.length,d&&d.length||0))};for(var j=0,k=x(c.length,d&&d.length||0);j=j)return p;o=p}if(j==null)return k},cg=function(b,c){return function(d,e,f){d=bG(d);var g,h,i,j,k="",l={},m,n=0;for(var o=0,p=d.length;oe){if(c&&!l.start){m=cf(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n),k+=["C"+m.start.x,m.start.y,m.m.x,m.m.y,m.x,m.y];if(f)return k;l.start=k,k=["M"+m.x,m.y+"C"+m.n.x,m.n.y,m.end.x,m.end.y,i[5],i[6]].join(),n+=j,g=+i[5],h=+i[6];continue}if(!b&&!c){m=cf(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n);return{x:m.x,y:m.y,alpha:m.alpha}}}n+=j,g=+i[5],h=+i[6]}k+=i.shift()+i}l.end=k,m=b?n:c?l:a.findDotsAtSegment(g,h,i[0],i[1],i[2],i[3],i[4],i[5],1),m.alpha&&(m={x:m.x,y:m.y,alpha:m.alpha});return m}},ch=cg(1),ci=cg(),cj=cg(0,1);a.getTotalLength=ch,a.getPointAtLength=ci,a.getSubpath=function(a,b,c){if(this.getTotalLength(a)-c<1e-6)return cj(a,b).end;var d=cj(a,c,1);return b?cj(d,b).end:d},b_.getTotalLength=function(){if(this.type=="path"){if(this.node.getTotalLength)return this.node.getTotalLength();return ch(this.attrs.path)}},b_.getPointAtLength=function(a){if(this.type=="path")return ci(this.attrs.path,a)},b_.getSubpath=function(b,c){if(this.type=="path")return a.getSubpath(this.attrs.path,b,c)};var ck=a.easing_formulas={linear:function(a){return a},"<":function(a){return A(a,1.7)},">":function(a){return A(a,.48)},"<>":function(a){var b=.48-a/1.04,c=w.sqrt(.1734+b*b),d=c-b,e=A(z(d),1/3)*(d<0?-1:1),f=-c-b,g=A(z(f),1/3)*(f<0?-1:1),h=e+g+.5;return(1-h)*3*h*h+h*h*h},backIn:function(a){var b=1.70158;return a*a*((b+1)*a-b)},backOut:function(a){a=a-1;var b=1.70158;return a*a*((b+1)*a+b)+1},elastic:function(a){if(a==!!a)return a;return A(2,-10*a)*w.sin((a-.075)*2*B/.3)+1},bounce:function(a){var b=7.5625,c=2.75,d;a<1/c?d=b*a*a:a<2/c?(a-=1.5/c,d=b*a*a+.75):a<2.5/c?(a-=2.25/c,d=b*a*a+.9375):(a-=2.625/c,d=b*a*a+.984375);return d}};ck.easeIn=ck["ease-in"]=ck["<"],ck.easeOut=ck["ease-out"]=ck[">"],ck.easeInOut=ck["ease-in-out"]=ck["<>"],ck["back-in"]=ck.backIn,ck["back-out"]=ck.backOut;var cl=[],cm=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(a){setTimeout(a,16)},cn=function(){var b=+(new Date),c=0;for(;c1&&!d.next){for(s in k)k[g](s)&&(r[s]=d.totalOrigin[s]);d.el.attr(r),cr(d.anim,d.el,d.anim.percents[0],null,d.totalOrigin,d.repeat-1)}d.next&&!d.stop&&cr(d.anim,d.el,d.next,null,d.totalOrigin,d.repeat)}}a.svg&&m&&m.paper&&m.paper.safari(),cl.length&&cm(cn)},co=function(a){return a>255?255:a<0?0:a};b_.animateWith=function(b,c,d,e,f,g){var h=d?a.animation(d,e,f,g):c;status=b.status(c);return this.animate(h).status(h,status*c.ms/h.ms)},b_.onAnimation=function(a){a?eve.on("anim.frame."+this.id,a):eve.unbind("anim.frame."+this.id);return this},cq.prototype.delay=function(a){var b=new cq(this.anim,this.ms);b.times=this.times,b.del=+a||0;return b},cq.prototype.repeat=function(a){var b=new cq(this.anim,this.ms);b.del=this.del,b.times=w.floor(x(a,0))||1;return b},a.animation=function(b,c,d,e){if(b instanceof cq)return b;if(a.is(d,"function")||!d)e=e||d||null,d=null;b=Object(b),c=+c||0;var f={},h,i;for(i in b)b[g](i)&&Q(i)!=i&&Q(i)+"%"!=i&&(h=!0,f[i]=b[i]);if(!h)return new cq(b,c);d&&(f.easing=d),e&&(f.callback=e);return new cq({100:f},c)},b_.animate=function(b,c,d,e){var f=this;if(f.removed){e&&e.call(f);return f}var g=b instanceof cq?b:a.animation(b,c,d,e);cr(g,f,g.percents[0],null,f.attr());return f},b_.setTime=function(a,b){a&&b!=null&&this.status(a,y(b,a.ms)/a.ms);return this},b_.status=function(a,b){var c=[],d=0,e,f;if(b!=null){cr(a,this,-1,y(b,1));return this}e=cl.length;for(;d.5)*2-1;i(m-.5,2)+i(n-.5,2)>.25&&(n=f.sqrt(.25-i(m-.5,2))*e+.5)&&n!=.5&&(n=n.toFixed(5)-1e-5*e)}return l}),e=e.split(/\s*\-\s*/);if(j=="linear"){var t=e.shift();t=-d(t);if(isNaN(t))return null;var u=[0,0,f.cos(a.rad(t)),f.sin(a.rad(t))],v=1/(g(h(u[2]),h(u[3]))||1);u[2]*=v,u[3]*=v,u[2]<0&&(u[0]=-u[2],u[2]=0),u[3]<0&&(u[1]=-u[3],u[3]=0)}var w=a._parseDots(e);if(!w)return null;b.gradient&&(p.defs.removeChild(b.gradient),delete b.gradient),k=k.replace(/[\(\)\s,\xb0#]/g,"-"),s=q(j+"Gradient",{id:k}),b.gradient=s,q(s,j=="radial"?{fx:m,fy:n}:{x1:u[0],y1:u[1],x2:u[2],y2:u[3],gradientTransform:b.matrix.invert()}),p.defs.appendChild(s);for(var x=0,y=w.length;x1?E.opacity/100:E.opacity});case"stroke":E=a.getRGB(p),i.setAttribute(o,E.hex),o=="stroke"&&E[b]("opacity")&&q(i,{"stroke-opacity":E.opacity>1?E.opacity/100:E.opacity}),o=="stroke"&&d._.arrows&&("startString"in d._.arrows&&w(d,d._.arrows.startString),"endString"in d._.arrows&&w(d,d._.arrows.endString,1));break;case"gradient":(d.type=="circle"||d.type=="ellipse"||c(p).charAt()!="r")&&u(d,p);break;case"opacity":k.gradient&&!k[b]("stroke-opacity")&&q(i,{"stroke-opacity":p>1?p/100:p});case"fill-opacity":if(k.gradient){F=a._g.doc.getElementById(i.getAttribute("fill").replace(/^url\(#|\)$/g,l)),F&&(G=F.getElementsByTagName("stop"),q(G[G.length-1],{"stop-opacity":p}));break};default:o=="font-size"&&(p=e(p,10)+"px");var H=o.replace(/(\-.)/g,function(a){return a.substring(1).toUpperCase()});i.style[H]=p,d._.dirty=1,i.setAttribute(o,p)}}B(d,f),i.style.visibility=m},A=1.2,B=function(d,f){if(d.type=="text"&&!!(f[b]("text")||f[b]("font")||f[b]("font-size")||f[b]("x")||f[b]("y"))){var g=d.attrs,h=d.node,i=h.firstChild?e(a._g.doc.defaultView.getComputedStyle(h.firstChild,l).getPropertyValue("font-size"),10):10;if(f[b]("text")){g.text=f.text;while(h.firstChild)h.removeChild(h.firstChild);var j=c(f.text).split("\n"),k=[],m;for(var n=0,o=j.length;n"));var Y=V.getBoundingClientRect();t.W=m.w=(Y.right-Y.left)/W,t.H=m.h=(Y.bottom-Y.top)/W,t.X=m.x,t.Y=m.y+t.H/2,("x"in i||"y"in i)&&(t.path.v=a.format("m{0},{1}l{2},{1}",f(m.x*u),f(m.y*u),f(m.x*u)+1));var Z=["x","y","text","font","font-family","font-weight","font-style","font-size"];for(var $=0,_=Z.length;$<_;$++)if(Z[$]in i){t._.dirty=1;break}switch(m["text-anchor"]){case"start":t.textpath.style["v-text-align"]="left",t.bbx=t.W/2;break;case"end":t.textpath.style["v-text-align"]="right",t.bbx=-t.W/2;break;default:t.textpath.style["v-text-align"]="center",t.bbx=0}t.textpath.style["v-text-kern"]=!0}},addGradientFill=function(b,f,g){b.attrs=b.attrs||{};var h=b.attrs,i=Math.pow,j,k,l="linear",m=".5 .5";b.attrs.gradient=f,f=c(f).replace(a._radial_gradient,function(a,b,c){l="radial",b&&c&&(b=d(b),c=d(c),i(b-.5,2)+i(c-.5,2)>.25&&(c=e.sqrt(.25-i(b-.5,2))*((c>.5)*2-1)+.5),m=b+n+c);return o}),f=f.split(/\s*\-\s*/);if(l=="linear"){var p=f.shift();p=-d(p);if(isNaN(p))return null}var q=a._parseDots(f);if(!q)return null;b=b.shape||b.node;if(q.length){b.removeChild(g),g.on=!0,g.method="none",g.color=q[0].color,g.color2=q[q.length-1].color;var r=[];for(var s=0,t=q.length;s')}}catch(c){B=function(a){return b.createElement("<"+a+' xmlns="urn:schemas-microsoft.com:vml" class="rvml">')}}};C(a._g.win),a._engine.create=function(){var b=a._getContainer.apply(0,arguments),c=b.container,d=b.height,e,f=b.width,g=b.x,h=b.y;if(!c)throw new Error("VML container not found.");var i=new a._Paper,j=i.canvas=a._g.doc.createElement("div"),k=j.style;g=g||0,h=h||0,f=f||512,d=d||342,i.width=f,i.height=d,f==+f&&(f+="px"),d==+d&&(d+="px"),i.coordsize=u*1e3+n+u*1e3,i.coordorigin="0 0",i.span=a._g.doc.createElement("span"),i.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;",j.appendChild(i.span),k.cssText=a.format("top:0;left:0;width:{0};height:{1};display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden",f,d),c==1?(a._g.doc.body.appendChild(j),k.left=g+"px",k.top=h+"px",k.position="absolute"):c.firstChild?c.insertBefore(j,c.firstChild):c.appendChild(j),i.renderfix=function(){};return i},a.prototype.clear=function(){a.eve("clear",this),this.canvas.innerHTML=o,this.span=a._g.doc.createElement("span"),this.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;",this.canvas.appendChild(this.span),this.bottom=this.top=null},a.prototype.remove=function(){a.eve("remove",this),this.canvas.parentNode.removeChild(this.canvas);for(var b in this)this[b]=removed(b);return!0};var D=a.st;for(var E in A)A[b](E)&&!D[b](E)&&(D[E]=function(a){return function(){var b=arguments;return this.forEach(function(c){c[a].apply(c,b)})}}(E))}(window.Raphael) \ No newline at end of file diff -r 03c69425efa6 -r 738594562e44 tweetcast/nodejs/client/js/script.js --- a/tweetcast/nodejs/client/js/script.js Mon Oct 24 18:01:55 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,336 +0,0 @@ -var socket, - tlPaper, - twPaper, - tweetData = { - "tweetcount" : 0, - "position" : 0, - "followLast" : true, - "zoomLevel" : 3, - "timeLevel" : 2, - "tweets" : [], - "posIndex" : [], - "tlChanged" : true - }, - colors = { - 'positive' : "#1D973D", - 'reference' : "#C5A62D", - 'negative' : "#CE0A15", - 'question' : "#036AAE", - 'neutre' : "#585858" - }, - annotations = { - 'positive' : '++', - 'negative' : '--', - 'reference' : '==', - 'question' : '??' - }, - displaySplitting = [ - { - positions : [ 10, 20, 22, 24, 25, 26, 27, 28, 29, 31, 33, 43, 53 ], - classNames : [ 'icons fade', 'icons', 'quarter fade', 'quarter', 'half fade', 'half', 'full', 'half', 'half fade', 'quarter', 'quarter fade', 'icons', 'icons fade' ] - }, - { - positions : [ 1, 3, 5, 7, 13, 33, 53 ], - classNames : [ 'full', 'half', 'half fade', 'quarter', 'quarter fade', 'icons', 'icons fade' ] - } - ], - blockUpdate = false, - waitUpdate = true, - wheeldelta = 0; - -function placeHolder(className) { - return '
  • '; -} - -function tweetToHtml(tweet, className) { - html = '
  • '; - } - html += ''; - } - html += '
    '; - a_user = ''; - if (tweet.user.profile_image_url) { - html += a_user + ''; - } - html += '

    ' + a_user + '@' + tweet.user.screen_name + '

    ' + new Date(tweet.created_at).toLocaleTimeString() + '

    '; - lastend = 0; - txt = ''; - entities = []; - for (var i in tweet.entities.hashtags) { - entities.push({ - "start" : tweet.entities.hashtags[i].indices[0], - "end" : tweet.entities.hashtags[i].indices[1], - "html" : '#' + tweet.entities.hashtags[i].text + '' - }); - } - for (var i in tweet.entities.urls) { - entities.push({ - "start" : tweet.entities.urls[i].indices[0], - "end" : tweet.entities.urls[i].indices[1], - "html" : '' + tweet.entities.urls[i].display_url + '' - }); - } - for (var i in tweet.entities.user_mentions) { - entities.push({ - "start" : tweet.entities.user_mentions[i].indices[0], - "end" : tweet.entities.user_mentions[i].indices[1], - "html" : '@' + tweet.entities.user_mentions[i].screen_name + '' - }); - } - entities.sort(function(a, b) { return a.start - b.start }); - for (var i in entities) { - txt += tweet.text.substring(lastend, entities[i].start) + entities[i].html; - lastend = entities[i].end; - } - txt += tweet.text.substring(lastend); - html += txt + '

  • '; - return html; -} - - -function getUpdate() { - tweetData.posToDisplay = []; - if (tweetData.followLast) { - for (var i = tweetData.tweetcount; i >= tweetData.tweetcount - 52; i--) { - tweetData.posToDisplay.push( i > 0 ? i : -1 ); - } - tweetData.end = tweetData.tweetcount; - tweetData.start = Math.max(1, tweetData.end - 52); - } else { - for (var i = tweetData.position + 26; i >= tweetData.position - 26; i--) { - tweetData.posToDisplay.push( i > 0 && i <= tweetData.tweetcount ? i : -1 ); - } - tweetData.end = Math.min(tweetData.tweetcount, tweetData.position + 26 ); - tweetData.start = Math.max(1, tweetData.position - 26); - } - var tweetsToGet = []; - for (var i = tweetData.start; i <= tweetData.end; i++) { - if (!tweetByPos(i)) { - tweetsToGet.push(i); - } - } - if (tweetsToGet.length) { - socket.emit('updateTweets', { - "tweets" : tweetsToGet - }); - } else { - drawTweetList(); - //drawDisplay(); - } - if (tweetData.tlChanged) { - socket.emit('updateTimeline', { - "level" : tweetData.timeLevel - }); - } else { - drawTimeLine(); - } -} - -function tweetByPos(pos) { - var index = tweetData.posIndex.indexOf(pos); - return (index == -1 ? false : tweetData.tweets[index]); -} - -function delayedUpdate() { - blockUpdate = false; - if (waitUpdate) { - updateDisplay(); - } -} - -function updateDisplay() { - if (blockUpdate) { - waitUpdate = true; - } else { - waitUpdate = false; - getUpdate(); - blockUpdate = true; - setTimeout(delayedUpdate, 100); - } -} - -function setTimeZoom(level) { - if (level >= 0 && level <= 4) { - tweetData.timeLevel = level; - tweetData.tlChanged = true; - updateDisplay(); - } -} - -function drawTweetList() { - html = ''; - var i = 0; - while (i < tweetData.posIndex.length) { - if (tweetData.posToDisplay.indexOf(tweetData.posIndex[i]) == -1) { - tweetData.posIndex.splice(i,1); - tweetData.tweets.splice(i,1); - } else { - i++; - } - } - for (var i in tweetData.posToDisplay) { - var ds = displaySplitting[tweetData.followLast ? 1 : 0]; - for (var j in ds.positions) { - if (ds.positions[j] > i) { - var className = ds.classNames[j]; - break; - } - } - html += ( tweetData.posToDisplay[i] != -1 ? tweetToHtml(tweetByPos(tweetData.posToDisplay[i]), className) : placeHolder(className) ); - } - $("#tweetlist").html(html); - if (tweetData.followLast) { - $("#tweet_" + tweetData.position).fadeIn(500); - } - drawTimeWindow(); -} - -function drawTimeWindow() { - twPaper.clear(); - if (!tweetData.timeline || !tweetData.timeline.length) return; - - var dtfintl = new Date ( tweetData.timeline[ tweetData.timeline.length - 1 ].end ), - dtdebtl = new Date ( tweetData.timeline[0].start ), - dtfintw = new Date( tweetByPos( tweetData.end ).created_at ), - dtdebtw = new Date( tweetByPos( tweetData.start ).created_at ), - scY = 600 / ( dtfintl - dtdebtl ); - twPaper.rect( 0, scY * ( dtfintl - dtfintw ), 300, scY * ( dtfintw - dtdebtw )).attr({"stroke":"none","fill":"#8080ff","fill-opacity":.2}); - var dtcour = new Date( tweetByPos( tweetData.position ).created_at ), - posY = scY * ( dtfintl - dtcour ); - twPaper.path("M0 "+posY+"L300 "+posY).attr({"stroke":"#ff0"}); -} - -function drawTimeLine() { - tlPaper.clear(); - if (!tweetData.timeline || !tweetData.timeline.length) return; - tweetData.tlTweetRects = []; - var scaleY = 600 / tweetData.timeline.length, - max = 0; - for (var i = 0; i < tweetData.timeline.length; i++) { - max = Math.max(max, tweetData.timeline[i].tweets); - } - var scaleX = 160 / max; - - // dessin de l'axe vertical - - tlPaper.path("M160 0L160 600").attr({"stroke":"#ccc"}); - - // dessin de la date de début - - tlPaper.text(165, 592, new Date(tweetData.timeline[0].start).toLocaleTimeString()).attr({ "text-anchor" : "start", "font-size": "12px" }); - - // dessin de la date de fin - - tlPaper.text(165, 7, new Date(tweetData.timeline[tweetData.timeline.length - 1].end).toLocaleTimeString()).attr({ "text-anchor" : "start", "font-size": "12px" }); - for (var i = 0; i < tweetData.timeline.length; i++) { - var posY = 600 - (i * scaleY); - - // Si on est à une demi-heure, on trace un axe secondaire + heure - - if (i && !(new Date(tweetData.timeline[i].start).valueOf() % 1800000)) { - tlPaper.path("M0 "+posY+"L165 "+posY).attr({"stroke":"#ccc"}); - tlPaper.text(165, posY, new Date(tweetData.timeline[i].start).toLocaleTimeString()).attr({ "text-anchor" : "start", "font-size": "12px" }); - } - var anz = { - "neutre" :tweetData.timeline[i].tweets - }; - for (var j in tweetData.timeline[i].annotations) { - anz.neutre -= tweetData.timeline[i].annotations[j]; - anz[j] = tweetData.timeline[i].annotations[j]; - } - var posX = 0; - for (var j in anz) { - var largX = scaleX * anz[j]; - tlPaper.rect(posX, 600 - scaleY * (i+1), largX, scaleY).attr({"stroke": "none", "fill": colors[j]}); - posX += largX; - } - } - - drawTimeWindow(); -/* for (var i = 0; i < tweetData.arcs.length; i++) { - var x1 = scaleX * (tmptw[tweetData.arcs[i].from].x + .5), - x2 = scaleX * (tmptw[tweetData.arcs[i].to].x + .5), - y1 = 600 - scaleY * (tmptw[tweetData.arcs[i].from].y + .5), - y2 = 600 - scaleY * (tmptw[tweetData.arcs[i].to].y + .5), - d = "M"+x1+" "+y1+"C"; - if (y1 == y2) { - d += x1+" "+(y1 - 30)+" "+x2+" "+(y2 - 30); - } else { - d += (x1 + 60)+" "+y1+" "+(x2 + 60)+" "+y2; - } - paper.path(d+" "+x2+" "+y2); - } */ -} - -$(document).ready(function() { - tlPaper = Raphael("timeline", 220, 600); - twPaper = Raphael("timewindow", 220, 600); - socket = io.connect('http://' + S_IO_HOST + ':' + S_IO_PORT ); - socket.on('tweetSummary', function (data) { - if (tweetData.tweetcount != data.tweetcount) { - tweetData.tweetcount = data.tweetcount; - tweetData.tlChanged = true; - if (tweetData.followLast) { - tweetData.position = data.tweetcount; - } - updateDisplay(); - } - }); - socket.on('tweets', function (data) { - for (var i in data) { - if (tweetData.posIndex.indexOf(data[i].pos) == -1) { - tweetData.tweets.push(data[i]); - tweetData.posIndex.push(data[i].pos); - } - } - drawTweetList(); - }); - socket.on('timeline', function (data) { - tweetData.timeline = data; - drawTimeLine(); - }); - socket.on('display', function (data) { - tweetData.tlChanged = false; - for (var i in data.tweets) { - if (tweetData.posIndex.indexOf(data.tweets[i].pos) == -1) { - tweetData.tweets.push(data.tweets[i]); - tweetData.posIndex.push(data.tweets[i].pos); - } - } - if (data.timeline) { - tweetData.timeline = data.timeline - } - tweetData.arcs = data.arcs; - drawDisplay(); - }); - $("#tweetlist").mousewheel(function(e, d) { - wheeldelta += d; - if (Math.abs(wheeldelta) >= 1) { - tweetData.position = Math.min( tweetData.tweetcount, Math.max(1, parseInt(wheeldelta) + tweetData.position ) ); - tweetData.followLast = (tweetData.position == tweetData.tweetcount); - updateDisplay(); - wheeldelta = 0; - } - return false; - }); - $("#timewindow").mousewheel(function(e, d) { - wheeldelta += d; - if (Math.abs(wheeldelta) >= 1) { - if (wheeldelta > 0) { - setTimeZoom(tweetData.timeLevel + 1); - } else { - setTimeZoom(tweetData.timeLevel - 1); - } - wheeldelta = 0; - } - return false; - }); -}); \ No newline at end of file diff -r 03c69425efa6 -r 738594562e44 tweetcast/nodejs/node-direct.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tweetcast/nodejs/node-direct.js Tue Oct 25 09:19:57 2011 +0200 @@ -0,0 +1,310 @@ +/* CONFIGURATION */ + +RECORD_NEW_TWEETS = true; +DEFAULT_SIO_PORT = 8000; +/* Overriden par the "-p" parameter, e.g. node tweetcast.js -p 8080 */ +SQLITE_FILE_DIR = __dirname + '/'; +SQLITE_FILE_START = 'tweets-'; +SQLITE_FILE_EXT = '.sqlite'; +DEFAULT_TRACKING_KEYWORD = 'Bieber'; +/* Overriden par the "-T" parameter, e.g. node tweetcast.js -T "Bieber" */ +TWITTER_USER = 'materiauxnum'; +TWITTER_PASS = 'm473r14ux7w337'; + +/* FUNCTIONS */ + +function createTables() { + + var requete = "CREATE TABLE IF NOT EXISTS tweets ( pos INTEGER PRIMARY KEY, tweet_id TEXT UNIQUE, created_at INTEGER, json TEXT" + annotations.map(function(a) { return ', a_' + a + ' INTEGER' }).join("") + " )"; + db.execute(requete, function(err) { + if (err) throw err; + db.execute("CREATE INDEX IF NOT EXISTS idx_created_at ON tweets ( created_at )", function(err) { if (err) throw err; }); + getSendLastPos(); + }); + + db.execute("CREATE TABLE IF NOT EXISTS tweet_refs ( id INTEGER PRIMARY KEY, from_id TEXT, to_id TEXT, ref_type TEXT )", function(err) { if (err) throw err; }); +} + +function commitReference(from_id, to_id, ref_type) { + db.execute( + "INSERT INTO tweet_refs ( from_id, to_id, ref_type ) VALUES ( ?, ?, ? )", + [ from_id, to_id, ref_type ], + function(err) { if (err) throw err; } + ); +} + +function commitTweet(data) { + + var tweet = JSON.parse(data), + ann = []; + + textids(tweet); + for (var j in keys_to_delete) { + delete tweet[keys_to_delete[j]]; + } + textids(tweet.user); + for (var j in user_keys_to_delete) { + delete tweet.user[user_keys_to_delete[j]]; + } + if (tweet.retweeted_status) { + textids(tweet.retweeted_status); + for (var j in keys_to_delete) { + delete tweet.retweeted_status[keys_to_delete[j]]; + } + } + for (var i in annotations_keywords) { + for (var j in annotations_keywords[i]) { + if (tweet.text.indexOf(annotations_keywords[i][j]) != -1) { + ann.push(annotations[i]); + break; + } + } + } + tweet.annotations = ann; + tweet.created_at = new Date(tweet.created_at); + + if (tweet.in_reply_to_status_id) { + commitReference( tweet.id, tweet.in_reply_to_status_id, "reply" ); + } + if (tweet.retweeted_status) { + commitReference( tweet.id, tweet.retweeted_status.id, "retweet" ); + } + db.execute( + "INSERT INTO tweets ( tweet_id, created_at, json " + + annotations.map(function(a) { return ', a_' + a }).join("") + + " ) VALUES ( ?, ?, ? " + + annotations.map(function(a) { return ', ?' }).join("") + + " )", + [ tweet.id, tweet.created_at.valueOf(), JSON.stringify(tweet) ].concat(annotations.map(function(a) { return ann.indexOf(a) == -1 ? 0 : 1 })), + function(err) { + if (err) throw err; + getSendLastPos(); + } + ); +} + +function callBackNewTweets(chunk) { + var newdata = chunk.split('\r\n'); + for (var i in newdata) { + if (newdata[i].length > 0) { + commitTweet(newdata[i]); + } + } + console.log("New tweets received"); +} + +function getSendLastPos() { + db.execute("SELECT MAX(pos) lastpos FROM tweets", function (err, results) { + if (err) throw err; + lastpos = results[0].lastpos ? results[0].lastpos : 0; + console.log("Broadcasting last pos = ",lastpos); + io.sockets.emit('tweetSummary', { + tweetcount : lastpos + }); + }); +} + + +function getSendTweets(posList, socket) { + console.log("request for tweets ("+posList.join(',')+") from "+socket.id); + db.execute("SELECT * FROM tweets WHERE pos IN ( " + posList.join(',') + " )", function (err, results) { + if (err) throw err; + socket.emit('tweets', + results.map(function(line) { + var tw = JSON.parse(line.json); + tw.pos = line.pos; + return tw; + }) + ); + }); +} + +function getSendTimeline(level, socket) { + console.log("request for timeline ("+level+") from "+socket.id); + var lvl = date_levels[level], + requete = "SELECT COUNT(*) AS nb, " + + lvl + + "*ROUND(created_at/" + + lvl + + ") AS tranche" + + annotations.map(function (a) { return " , SUM(a_" + a + ") AS s_" + a }).join("") + + " FROM tweets GROUP BY tranche ORDER BY tranche DESC LIMIT 0,50"; + db.execute(requete, function (err, results) { + if (err) throw err; + var tbl = [], + lastend = parseInt(results[results.length - 1].tranche); + for (var i = results.length - 1; i >= 0; i--) { + var start = parseInt(results[i].tranche); + while (start > lastend) { + var struct = { "start": lastend, "tweets" : 0, "annotations" : {} }; + lastend += lvl; + struct.end = lastend; + tbl.push(struct); + } + lastend += lvl; + var struct = { + "start" : start, + "end" : lastend, + "tweets" : results[i].nb, + "annotations" : {} + } + for (var j in annotations) { + struct.annotations[annotations[j]] = results[i]['s_' + annotations[j]]; + } + tbl.push(struct); + } + socket.emit('timeline', tbl); + }); +} + +function textids(object) { + for (var key in object) { + if (key.substr(-2) == 'id') { + object[key] = object[key + '_str']; + delete object[key + '_str']; + } + } +} + +function httpHandler(req, res) { + var url = req.url + ( req.url[req.url.length - 1] == "/" ? "index.html" : "" ); + fs.readFile(__dirname + "/client" + url, function(err, data) { + if (err) { + res.writeHead(404); + return res.end('File not found'); + } + res.writeHead(200); + res.end(data); + }); +} + +/* Initialization */ + +var fs = require('fs'), + http = require('http'), + https = require('https'), + sqlite = require('sqlite'), + socketio = require('socket.io'), + tweets = [], + lastpos = 0, + arcs = [], + tweet_ids = [], + date_struct = [], + date_levels = [ + 3600 * 1000, + 15 * 60 * 1000, + 5 * 60 * 1000, + 60 * 1000, + 15 * 1000 + ], + annotations = [ 'positive', 'negative', 'reference', 'question' ], + annotations_keywords = [ [ '++' ], [ '--' ], [ '==' ], [ '??' ] ], + annkw = { + 'positive' : '++', + 'negative' : '--', + 'reference' : '==', + 'question' : '??' + }, + keys_to_delete = [ + 'in_reply_to_screen_name', + 'in_reply_to_user_id', + 'retweeted', + 'place', + 'geo', + 'source', + 'contributors', + 'coordinates', + 'retweet_count', + 'favorited', + 'truncated', + 'possibly_sensitive' + ], + user_keys_to_delete = [ + 'default_profile_image', + 'show_all_inline_media', + 'contributors_enabled', + 'profile_sidebar_fill_color', + 'created_at', + 'lang', + 'time_zone', + 'profile_sidebar_border_color', + 'follow_request_sent', + 'profile_background_image_url', + 'profile_background_image_url_https', + 'followers_count', + 'description', + 'url', + 'geo_enabled', + 'profile_use_background_image', + 'default_profile', + 'following', + 'profile_text_color', + 'is_translator', + 'favourites_count', + 'listed_count', + 'friends_count', + 'profile_link_color', + 'protected', + 'location', + 'notifications', + 'profile_image_url_https', + 'statuses_count', + 'verified', + 'profile_background_color', + 'profile_background_tile', + 'utc_offset' + ], + app = http.createServer(httpHandler), + port_flag = process.argv.indexOf("-p"), + sio_port = ( port_flag != -1 && port_flag < process.argv.length - 1 && parseInt(process.argv[port_flag + 1]) ? parseInt(process.argv[port_flag + 1]) : DEFAULT_SIO_PORT ) + io = socketio.listen(app), + track_flag = process.argv.indexOf("-T"), + tracking_keyword = ( track_flag != -1 && track_flag < process.argv.length - 1 ? process.argv[track_flag + 1] : DEFAULT_TRACKING_KEYWORD ), + sqlfile = SQLITE_FILE_DIR + SQLITE_FILE_START + encodeURIComponent(tracking_keyword) + SQLITE_FILE_EXT, + db = new sqlite.Database(); + +/* MAIN CODE */ + +app.listen(sio_port); + +console.log("Listening on port: "+sio_port); +console.log("Opening SQLITE file: "+sqlfile); +db.open(sqlfile , function(err) { + if (err) throw err; + createTables(); +}); + +if (RECORD_NEW_TWEETS) { + console.log("Requesting Twitter to track keyword(s): "+tracking_keyword); + var req = https.request({ + host: "stream.twitter.com", + path: "/1/statuses/filter.json", + method: "POST", + headers: { + 'Authorization': 'Basic ' + new Buffer( TWITTER_USER + ":" + TWITTER_PASS ).toString('base64'), + 'Content-Type': 'application/x-www-form-urlencoded' + } + }, function(res) { + console.log('Reply from stream.twitter.com: ' + res.statusCode); + console.log('Headers: ' + JSON.stringify(res.headers)); + res.setEncoding('utf8'); + res.on('data', callBackNewTweets); + }); + + req.write('track=' + encodeURIComponent(tracking_keyword)); + req.end(); +} + +io.set('log level', 0); +io.sockets.on('connection', function(socket) { + console.log("New connection from" + socket.handshake.address.address + " with id=" + socket.id); + socket.emit('tweetSummary', { tweetcount : tweets.length }); + socket.on('updateTweets', function(data) { + if (data.tweets.length) { + getSendTweets(data.tweets, socket); + } + }); + socket.on('updateTimeline', function(data) { + getSendTimeline(data.level, socket); + }); +}); \ No newline at end of file diff -r 03c69425efa6 -r 738594562e44 tweetcast/nodejs/server/node-direct.js --- a/tweetcast/nodejs/server/node-direct.js Mon Oct 24 18:01:55 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,294 +0,0 @@ -/* CONFIGURATION */ - -RECORD_NEW_TWEETS = true; -DEFAULT_SIO_PORT = 8000; -/* Overriden par the "-p" parameter, e.g. node tweetcast.js -p 8080 */ -SQLITE_FILE_DIR = './'; -SQLITE_FILE_START = 'tweets-'; -SQLITE_FILE_EXT = '.sqlite'; -DEFAULT_TRACKING_KEYWORD = 'Bieber'; -/* Overriden par the "-T" parameter, e.g. node tweetcast.js -T "Bieber" */ -TWITTER_USER = 'materiauxnum'; -TWITTER_PASS = 'm473r14ux7w337'; - -/* FUNCTIONS */ - -function createTables() { - - var requete = "CREATE TABLE IF NOT EXISTS tweets ( pos INTEGER PRIMARY KEY, tweet_id TEXT UNIQUE, created_at INTEGER, json TEXT" + annotations.map(function(a) { return ', a_' + a + ' INTEGER' }).join("") + " )"; - db.execute(requete, function(err) { - if (err) throw err; - db.execute("CREATE INDEX IF NOT EXISTS idx_created_at ON tweets ( created_at )", function(err) { if (err) throw err; }); - getSendLastPos(); - }); - - db.execute("CREATE TABLE IF NOT EXISTS tweet_refs ( id INTEGER PRIMARY KEY, from_id TEXT, to_id TEXT, ref_type TEXT )", function(err) { if (err) throw err; }); -} - -function commitReference(from_id, to_id, ref_type) { - db.execute( - "INSERT INTO tweet_refs ( from_id, to_id, ref_type ) VALUES ( ?, ?, ? )", - [ from_id, to_id, ref_type ], - function(err) { if (err) throw err; } - ); -} - -function commitTweet(data) { - - var tweet = JSON.parse(data), - ann = []; - - textids(tweet); - for (var j in keys_to_delete) { - delete tweet[keys_to_delete[j]]; - } - textids(tweet.user); - for (var j in user_keys_to_delete) { - delete tweet.user[user_keys_to_delete[j]]; - } - if (tweet.retweeted_status) { - textids(tweet.retweeted_status); - for (var j in keys_to_delete) { - delete tweet.retweeted_status[keys_to_delete[j]]; - } - } - for (var i in annotations_keywords) { - for (var j in annotations_keywords[i]) { - if (tweet.text.indexOf(annotations_keywords[i][j]) != -1) { - ann.push(annotations[i]); - break; - } - } - } - tweet.annotations = ann; - tweet.created_at = new Date(tweet.created_at); - - if (tweet.in_reply_to_status_id) { - commitReference( tweet.id, tweet.in_reply_to_status_id, "reply" ); - } - if (tweet.retweeted_status) { - commitReference( tweet.id, tweet.retweeted_status.id, "retweet" ); - } - db.execute( - "INSERT INTO tweets ( tweet_id, created_at, json " - + annotations.map(function(a) { return ', a_' + a }).join("") - + " ) VALUES ( ?, ?, ? " - + annotations.map(function(a) { return ', ?' }).join("") - + " )", - [ tweet.id, tweet.created_at.valueOf(), JSON.stringify(tweet) ].concat(annotations.map(function(a) { return ann.indexOf(a) == -1 ? 0 : 1 })), - function(err) { - if (err) throw err; - getSendLastPos(); - } - ); -} - -function callBackNewTweets(chunk) { - var newdata = chunk.split('\r\n'); - for (var i in newdata) { - if (newdata[i].length > 0) { - commitTweet(newdata[i]); - } - } - console.log("New tweets received"); -} - -function getSendLastPos() { - db.execute("SELECT MAX(pos) lastpos FROM tweets", function (err, results) { - if (err) throw err; - lastpos = results[0].lastpos ? results[0].lastpos : 0; - console.log("Broadcasting last pos = ",lastpos); - io.sockets.emit('tweetSummary', { - tweetcount : lastpos - }); - }); -} - - -function getSendTweets(posList, socket) { - console.log("request for tweets ("+posList.join(',')+") from "+socket.id); - db.execute("SELECT * FROM tweets WHERE pos IN ( " + posList.join(',') + " )", function (err, results) { - if (err) throw err; - socket.emit('tweets', - results.map(function(line) { - var tw = JSON.parse(line.json); - tw.pos = line.pos; - return tw; - }) - ); - }); -} - -function getSendTimeline(level, socket) { - console.log("request for timeline ("+level+") from "+socket.id); - var lvl = date_levels[level], - requete = "SELECT COUNT(*) AS nb, " - + lvl - + "*ROUND(created_at/" - + lvl - + ") AS tranche" - + annotations.map(function (a) { return " , SUM(a_" + a + ") AS s_" + a }).join("") - + " FROM tweets GROUP BY tranche ORDER BY tranche DESC LIMIT 0,50"; - db.execute(requete, function (err, results) { - if (err) throw err; - var tbl = [], - lastend = parseInt(results[results.length - 1].tranche); - for (var i = results.length - 1; i >= 0; i--) { - var start = parseInt(results[i].tranche); - while (start > lastend) { - var struct = { "start": lastend, "tweets" : 0, "annotations" : {} }; - lastend += lvl; - struct.end = lastend; - tbl.push(struct); - } - lastend += lvl; - var struct = { - "start" : start, - "end" : lastend, - "tweets" : results[i].nb, - "annotations" : {} - } - for (var j in annotations) { - struct.annotations[annotations[j]] = results[i]['s_' + annotations[j]]; - } - tbl.push(struct); - } - socket.emit('timeline', tbl); - }); -} - -function textids(object) { - for (var key in object) { - if (key.substr(-2) == 'id') { - object[key] = object[key + '_str']; - delete object[key + '_str']; - } - } -} - -/* Initialization */ - -var fs = require('fs'), - https = require('https'), - sqlite = require('sqlite'), - socketio = require('socket.io'), - tweets = [], - lastpos = 0, - arcs = [], - tweet_ids = [], - date_struct = [], - date_levels = [ - 3600 * 1000, - 15 * 60 * 1000, - 5 * 60 * 1000, - 60 * 1000, - 15 * 1000 - ], - annotations = [ 'positive', 'negative', 'reference', 'question' ], - annotations_keywords = [ [ '++' ], [ '--' ], [ '==' ], [ '??' ] ], - annkw = { - 'positive' : '++', - 'negative' : '--', - 'reference' : '==', - 'question' : '??' - }, - keys_to_delete = [ - 'in_reply_to_screen_name', - 'in_reply_to_user_id', - 'retweeted', - 'place', - 'geo', - 'source', - 'contributors', - 'coordinates', - 'retweet_count', - 'favorited', - 'truncated', - 'possibly_sensitive' - ], - user_keys_to_delete = [ - 'default_profile_image', - 'show_all_inline_media', - 'contributors_enabled', - 'profile_sidebar_fill_color', - 'created_at', - 'lang', - 'time_zone', - 'profile_sidebar_border_color', - 'follow_request_sent', - 'profile_background_image_url', - 'profile_background_image_url_https', - 'followers_count', - 'description', - 'url', - 'geo_enabled', - 'profile_use_background_image', - 'default_profile', - 'following', - 'profile_text_color', - 'is_translator', - 'favourites_count', - 'listed_count', - 'friends_count', - 'profile_link_color', - 'protected', - 'location', - 'notifications', - 'profile_image_url_https', - 'statuses_count', - 'verified', - 'profile_background_color', - 'profile_background_tile', - 'utc_offset' - ], - port_flag = process.argv.indexOf("-p"), - sio_port = ( port_flag != -1 && port_flag < process.argv.length - 1 && parseInt(process.argv[port_flag + 1]) ? parseInt(process.argv[port_flag + 1]) : DEFAULT_SIO_PORT ) - io = socketio.listen(sio_port), - track_flag = process.argv.indexOf("-T"), - tracking_keyword = ( track_flag != -1 && track_flag < process.argv.length - 1 ? process.argv[track_flag + 1] : DEFAULT_TRACKING_KEYWORD ), - sqlfile = SQLITE_FILE_DIR + SQLITE_FILE_START + encodeURIComponent(tracking_keyword) + SQLITE_FILE_EXT, - db = new sqlite.Database(); - -/* MAIN CODE */ - -console.log("Listening on port: "+sio_port); -console.log("Opening SQLITE file: "+sqlfile); -db.open(sqlfile , function(err) { - if (err) throw err; - createTables(); -}); - -if (RECORD_NEW_TWEETS) { - console.log("Requesting Twitter to track keyword(s): "+tracking_keyword); - var req = https.request({ - host: "stream.twitter.com", - path: "/1/statuses/filter.json", - method: "POST", - headers: { - 'Authorization': 'Basic ' + new Buffer( TWITTER_USER + ":" + TWITTER_PASS ).toString('base64'), - 'Content-Type': 'application/x-www-form-urlencoded' - } - }, function(res) { - console.log('Reply from stream.twitter.com: ' + res.statusCode); - console.log('Headers: ' + JSON.stringify(res.headers)); - res.setEncoding('utf8'); - res.on('data', callBackNewTweets); - }); - - req.write('track=' + encodeURIComponent(tracking_keyword)); - req.end(); -} - -io.set('log level', 0); -io.sockets.on('connection', function(socket) { - console.log("New connection from" + socket.handshake.address.address + " with id=" + socket.id); - socket.emit('tweetSummary', { tweetcount : tweets.length }); - socket.on('updateTweets', function(data) { - if (data.tweets.length) { - getSendTweets(data.tweets, socket); - } - }); - socket.on('updateTimeline', function(data) { - getSendTimeline(data.level, socket); - }); -}); \ No newline at end of file