diff --git a/.meteor/.gitignore b/.meteor/.gitignore new file mode 100644 index 0000000..4083037 --- /dev/null +++ b/.meteor/.gitignore @@ -0,0 +1 @@ +local diff --git a/.meteor/packages b/.meteor/packages new file mode 100644 index 0000000..e92ff78 --- /dev/null +++ b/.meteor/packages @@ -0,0 +1,14 @@ +# Meteor packages used by this project, one per line. +# +# 'meteor add' and 'meteor remove' will edit this file for you, +# but you can also edit it by hand. + +standard-app-packages +insecure +preserve-inputs +coffeescript +accounts-ui +npm +accounts-facebook +accounts-password +router diff --git a/.meteor/release b/.meteor/release new file mode 100644 index 0000000..ef5e445 --- /dev/null +++ b/.meteor/release @@ -0,0 +1 @@ +0.6.5 diff --git a/client/_soundmanager2-nodebug-jsmin.js b/client/_soundmanager2-nodebug-jsmin.js new file mode 100755 index 0000000..c86f7cb --- /dev/null +++ b/client/_soundmanager2-nodebug-jsmin.js @@ -0,0 +1,81 @@ +/** @license + * + * SoundManager 2: JavaScript Sound for the Web + * ---------------------------------------------- + * http://schillmania.com/projects/soundmanager2/ + * + * Copyright (c) 2007, Scott Schiller. All rights reserved. + * Code provided under the BSD License: + * http://schillmania.com/projects/soundmanager2/license.txt + * + * V2.97a.20130512 + */ +(function(l,h){function V(V,la){function W(b){return c.preferFlash&&D&&!c.ignoreFlash&&c.flash[b]!==h&&c.flash[b]}function r(b){return function(c){var d=this._s;return!d||!d._a?null:b.call(this,c)}}this.setupOptions={url:V||null,flashVersion:8,debugMode:!0,debugFlash:!1,useConsole:!0,consoleOnly:!0,waitForWindowLoad:!1,bgColor:"#ffffff",useHighPerformance:!1,flashPollingInterval:null,html5PollingInterval:null,flashLoadTimeout:1E3,wmode:null,allowScriptAccess:"always",useFlashBlock:!1,useHTML5Audio:!0, +html5Test:/^(probably|maybe)$/i,preferFlash:!0,noSWFCache:!1,idPrefix:"sound"};this.defaultOptions={autoLoad:!1,autoPlay:!1,from:null,loops:1,onid3:null,onload:null,whileloading:null,onplay:null,onpause:null,onresume:null,whileplaying:null,onposition:null,onstop:null,onfailure:null,onfinish:null,multiShot:!0,multiShotEvents:!1,position:null,pan:0,stream:!0,to:null,type:null,usePolicyFile:!1,volume:100};this.flash9Options={isMovieStar:null,usePeakData:!1,useWaveformData:!1,useEQData:!1,onbufferchange:null, +ondataerror:null};this.movieStarOptions={bufferTime:3,serverURL:null,onconnect:null,duration:null};this.audioFormats={mp3:{type:['audio/mpeg; codecs\x3d"mp3"',"audio/mpeg","audio/mp3","audio/MPA","audio/mpa-robust"],required:!0},mp4:{related:["aac","m4a","m4b"],type:['audio/mp4; codecs\x3d"mp4a.40.2"',"audio/aac","audio/x-m4a","audio/MP4A-LATM","audio/mpeg4-generic"],required:!1},ogg:{type:["audio/ogg; codecs\x3dvorbis"],required:!1},opus:{type:["audio/ogg; codecs\x3dopus","audio/opus"],required:!1}, +wav:{type:['audio/wav; codecs\x3d"1"',"audio/wav","audio/wave","audio/x-wav"],required:!1}};this.movieID="sm2-container";this.id=la||"sm2movie";this.debugID="soundmanager-debug";this.debugURLParam=/([#?&])debug=1/i;this.versionNumber="V2.97a.20130512";this.altURL=this.movieURL=this.version=null;this.enabled=this.swfLoaded=!1;this.oMC=null;this.sounds={};this.soundIDs=[];this.didFlashBlock=this.muted=!1;this.filePattern=null;this.filePatterns={flash8:/\.mp3(\?.*)?$/i,flash9:/\.mp3(\?.*)?$/i};this.features= +{buffering:!1,peakData:!1,waveformData:!1,eqData:!1,movieStar:!1};this.sandbox={};this.html5={usingFlash:null};this.flash={};this.ignoreFlash=this.html5Only=!1;var Ja,c=this,Ka=null,k=null,X,p=navigator.userAgent,La=l.location.href.toString(),n=document,ma,Ma,na,m,u=[],L=!1,M=!1,q=!1,x=!1,oa=!1,N,w,pa,Y,qa,E,F,G,Na,ra,Z,sa,$,ta,H,ua,O,va,aa,I,Oa,wa,Pa,xa,Qa,P=null,ya=null,Q,za,J,ba,ca,s,R=!1,Aa=!1,Ra,Sa,Ta,da=0,S=null,ea,Ua=[],fa,v=null,Va,ga,T,y,ha,Ba,Wa,t,fb=Array.prototype.slice,z=!1,Ca,D,Da,Xa, +B,ia,Ya=0,U=p.match(/(ipad|iphone|ipod)/i),Za=p.match(/android/i),C=p.match(/msie/i),gb=p.match(/webkit/i),ja=p.match(/safari/i)&&!p.match(/chrome/i),Ea=p.match(/opera/i),hb=p.match(/firefox/i),Fa=p.match(/(mobile|pre\/|xoom)/i)||U||Za,$a=!La.match(/usehtml5audio/i)&&!La.match(/sm2\-ignorebadua/i)&&ja&&!p.match(/silk/i)&&p.match(/OS X 10_6_([3-7])/i),Ga=n.hasFocus!==h?n.hasFocus():null,ka=ja&&(n.hasFocus===h||!n.hasFocus()),ab=!ka,bb=/(mp3|mp4|mpa|m4a|m4b)/i,Ha=n.location?n.location.protocol.match(/http/i): +null,cb=!Ha?"http://":"",db=/^\s*audio\/(?:x-)?(?:mpeg4|aac|flv|mov|mp4||m4v|m4a|m4b|mp4v|3gp|3g2)\s*(?:$|;)/i,eb="mpeg4 aac flv mov mp4 m4v f4v m4a m4b mp4v 3gp 3g2".split(" "),ib=RegExp("\\.("+eb.join("|")+")(\\?.*)?$","i");this.mimePattern=/^\s*audio\/(?:x-)?(?:mp(?:eg|3))\s*(?:$|;)/i;this.useAltURL=!Ha;var Ia;try{Ia=Audio!==h&&(Ea&&opera!==h&&10>opera.version()?new Audio(null):new Audio).canPlayType!==h}catch(jb){Ia=!1}this.hasHTML5=Ia;this.setup=function(b){var e=!c.url;b!==h&&q&&v&&c.ok();pa(b); +b&&(e&&(O&&b.url!==h)&&c.beginDelayedInit(),!O&&(b.url!==h&&"complete"===n.readyState)&&setTimeout(H,1));return c};this.supported=this.ok=function(){return v?q&&!x:c.useHTML5Audio&&c.hasHTML5};this.getMovie=function(b){return X(b)||n[b]||l[b]};this.createSound=function(b,e){function d(){a=ba(a);c.sounds[a.id]=new Ja(a);c.soundIDs.push(a.id);return c.sounds[a.id]}var a,f=null;if(!q||!c.ok())return!1;e!==h&&(b={id:b,url:e});a=w(b);a.url=ea(a.url);void 0===a.id&&(a.id=c.setupOptions.idPrefix+Ya++);if(s(a.id, +!0))return c.sounds[a.id];if(ga(a))f=d(),f._setup_html5(a);else{if(c.html5Only||c.html5.usingFlash&&a.url&&a.url.match(/data\:/i))return d();8a.instanceCount?(l(),f=a._setup_html5(),a.setPosition(a._iO.position),f.play()):(g=new Audio(a._iO.url),K=function(){t.remove(g,"onended",K);a._onfinish(a);ha(g);g=null},A=function(){t.remove(g,"canplay",A);try{g.currentTime=a._iO.position/1E3}catch(b){}g.play()},t.add(g,"ended",K),a._iO.position?t.add(g,"canplay",A):g.play()):(f=k._start(a.id,a._iO.loops|| +1,9===m?a.position:a.position/1E3,a._iO.multiShot||!1),9===m&&!f&&a._iO.onplayerror&&a._iO.onplayerror.apply(a))}return a};this.stop=function(b){var c=a._iO;1===a.playState&&(a._onbufferchange(0),a._resetOnPosition(0),a.paused=!1,a.isHTML5||(a.playState=0),v(),c.to&&a.clearOnPosition(c.to),a.isHTML5?a._a&&(b=a.position,a.setPosition(0),a.position=b,a._a.pause(),a.playState=0,a._onTimer(),A()):(k._stop(a.id,b),c.serverURL&&a.unload()),a.instanceCount=0,a._iO={},c.onstop&&c.onstop.apply(a));return a}; +this.setAutoPlay=function(b){a._iO.autoPlay=b;a.isHTML5||(k._setAutoPlay(a.id,b),b&&!a.instanceCount&&1===a.readyState&&a.instanceCount++)};this.getAutoPlay=function(){return a._iO.autoPlay};this.setPosition=function(b){b===h&&(b=0);var c=a.isHTML5?Math.max(b,0):Math.min(a.duration||a._iO.duration,Math.max(b,0));a.position=c;b=a.position/1E3;a._resetOnPosition(a.position);a._iO.position=c;if(a.isHTML5){if(a._a){if(a._html5_canplay){if(a._a.currentTime!==b)try{a._a.currentTime=b,(0===a.playState|| +a.paused)&&a._a.pause()}catch(e){}}else if(b)return a;a.paused&&a._onTimer(!0)}}else b=9===m?a.position:b,a.readyState&&2!==a.readyState&&k._setPosition(a.id,b,a.paused||!a.playState,a._iO.multiShot);return a};this.pause=function(b){if(a.paused||0===a.playState&&1!==a.readyState)return a;a.paused=!0;a.isHTML5?(a._setup_html5().pause(),A()):(b||b===h)&&k._pause(a.id,a._iO.multiShot);a._iO.onpause&&a._iO.onpause.apply(a);return a};this.resume=function(){var b=a._iO;if(!a.paused)return a;a.paused=!1; +a.playState=1;a.isHTML5?(a._setup_html5().play(),l()):(b.isMovieStar&&!b.serverURL&&a.setPosition(a.position),k._pause(a.id,b.multiShot));!r&&b.onplay?(b.onplay.apply(a),r=!0):b.onresume&&b.onresume.apply(a);return a};this.togglePause=function(){if(0===a.playState)return a.play({position:9===m&&!a.isHTML5?a.position:a.position/1E3}),a;a.paused?a.resume():a.pause();return a};this.setPan=function(b,c){b===h&&(b=0);c===h&&(c=!1);a.isHTML5||k._setPan(a.id,b);a._iO.pan=b;c||(a.pan=b,a.options.pan=b);return a}; +this.setVolume=function(b,e){b===h&&(b=100);e===h&&(e=!1);a.isHTML5?a._a&&(a._a.volume=Math.max(0,Math.min(1,b/100))):k._setVolume(a.id,c.muted&&!a.muted||a.muted?0:b);a._iO.volume=b;e||(a.volume=b,a.options.volume=b);return a};this.mute=function(){a.muted=!0;a.isHTML5?a._a&&(a._a.muted=!0):k._setVolume(a.id,0);return a};this.unmute=function(){a.muted=!1;var b=a._iO.volume!==h;a.isHTML5?a._a&&(a._a.muted=!1):k._setVolume(a.id,b?a._iO.volume:a.options.volume);return a};this.toggleMute=function(){return a.muted? +a.unmute():a.mute()};this.onposition=this.onPosition=function(b,c,e){p.push({position:parseInt(b,10),method:c,scope:e!==h?e:a,fired:!1});return a};this.clearOnPosition=function(a,b){var c;a=parseInt(a,10);if(isNaN(a))return!1;for(c=0;c=b)return!1;for(b-=1;0<=b;b--)c=p[b],!c.fired&&a.position>=c.position&&(c.fired=!0,q++,c.method.apply(c.scope, +[c.position]));return!0};this._resetOnPosition=function(a){var b,c;b=p.length;if(!b)return!1;for(b-=1;0<=b;b--)c=p[b],c.fired&&a<=c.position&&(c.fired=!1,q--);return!0};x=function(){var b=a._iO,c=b.from,e=b.to,d,f;f=function(){a.clearOnPosition(e,f);a.stop()};d=function(){if(null!==e&&!isNaN(e))a.onPosition(e,f)};null!==c&&!isNaN(c)&&(b.position=c,b.multiShot=!1,d());return b};n=function(){var b,c=a._iO.onposition;if(c)for(b in c)if(c.hasOwnProperty(b))a.onPosition(parseInt(b,10),c[b])};v=function(){var b, +c=a._iO.onposition;if(c)for(b in c)c.hasOwnProperty(b)&&a.clearOnPosition(parseInt(b,10))};l=function(){a.isHTML5&&Ra(a)};A=function(){a.isHTML5&&Sa(a)};f=function(b){b||(p=[],q=0);r=!1;a._hasTimer=null;a._a=null;a._html5_canplay=!1;a.bytesLoaded=null;a.bytesTotal=null;a.duration=a._iO&&a._iO.duration?a._iO.duration:null;a.durationEstimate=null;a.buffered=[];a.eqData=[];a.eqData.left=[];a.eqData.right=[];a.failures=0;a.isBuffering=!1;a.instanceOptions={};a.instanceCount=0;a.loaded=!1;a.metadata={}; +a.readyState=0;a.muted=!1;a.paused=!1;a.peakData={left:0,right:0};a.waveformData={left:[],right:[]};a.playState=0;a.position=null;a.id3={}};f();this._onTimer=function(b){var c,f=!1,g={};if(a._hasTimer||b){if(a._a&&(b||(0opera.version()?new Audio(null):new Audio,c=a._a,c._called_load=!1,z&&(Ka=c);a.isHTML5=!0;a._a=c;c._s=a;g();a._apply_loop(c,b.loops);b.autoLoad||b.autoPlay?a.load():(c.autobuffer=!1,c.preload="auto");return c};g=function(){if(a._a._added_events)return!1;var b;a._a._added_events=!0;for(b in B)B.hasOwnProperty(b)&&a._a&&a._a.addEventListener(b,B[b],!1);return!0};K=function(){var b;a._a._added_events=!1;for(b in B)B.hasOwnProperty(b)&&a._a&&a._a.removeEventListener(b,B[b],!1)};this._onload=function(b){var c= +!!b||!a.isHTML5&&8===m&&a.duration;a.loaded=c;a.readyState=c?3:2;a._onbufferchange(0);a._iO.onload&&ia(a,function(){a._iO.onload.apply(a,[c])});return!0};this._onbufferchange=function(b){if(0===a.playState||b&&a.isBuffering||!b&&!a.isBuffering)return!1;a.isBuffering=1===b;a._iO.onbufferchange&&a._iO.onbufferchange.apply(a);return!0};this._onsuspend=function(){a._iO.onsuspend&&a._iO.onsuspend.apply(a);return!0};this._onfailure=function(b,c,e){a.failures++;if(a._iO.onfailure&&1===a.failures)a._iO.onfailure(a, +b,c,e)};this._onfinish=function(){var b=a._iO.onfinish;a._onbufferchange(0);a._resetOnPosition(0);a.instanceCount&&(a.instanceCount--,a.instanceCount||(v(),a.playState=0,a.paused=!1,a.instanceCount=0,a.instanceOptions={},a._iO={},A(),a.isHTML5&&(a.position=0)),(!a.instanceCount||a._iO.multiShotEvents)&&b&&ia(a,function(){b.apply(a)}))};this._whileloading=function(b,c,e,d){var f=a._iO;a.bytesLoaded=b;a.bytesTotal=c;a.duration=Math.floor(e);a.bufferLength=d;a.durationEstimate=!a.isHTML5&&!f.isMovieStar? +f.duration?a.duration>f.duration?a.duration:f.duration:parseInt(a.bytesTotal/a.bytesLoaded*a.duration,10):a.duration;a.isHTML5||(a.buffered=[{start:0,end:a.duration}]);(3!==a.readyState||a.isHTML5)&&f.whileloading&&f.whileloading.apply(a)};this._whileplaying=function(b,c,e,d,f){var g=a._iO;if(isNaN(b)||null===b)return!1;a.position=Math.max(0,b);a._processOnPosition();!a.isHTML5&&8opera.version()?new Audio(null):new Audio:null,d,a,f={},g;g=c.audioFormats;for(d in g)if(g.hasOwnProperty(d)&&(a="audio/"+d,f[d]=b(g[d].type),f[a]= +f[d],d.match(bb)?(c.flash[d]=!0,c.flash[a]=!0):(c.flash[d]=!1,c.flash[a]=!1),g[d]&&g[d].related))for(a=g[d].related.length-1;0<=a;a--)f["audio/"+g[d].related[a]]=f[d],c.html5[g[d].related[a]]=f[d],c.flash[g[d].related[a]]=f[d];f.canPlayType=e?b:null;c.html5=w(c.html5,f);c.html5.usingFlash=Va();v=c.html5.usingFlash;return!0};sa={};Q=function(){};ba=function(b){8===m&&(1m)&&(c.flashVersion=m=9);c.version=c.versionNumber+(c.html5Only?" (HTML5-only mode)":9===m?" (AS3/Flash 9)":" (AS2/Flash 8)");8b&&(e=!0));setTimeout(function(){b=c.getMoviePercent();if(e)return R=!1,l.setTimeout(G,1),!1;!q&&ab&&(null===b?c.useFlashBlock||0===c.flashLoadTimeout?c.useFlashBlock&&za():!c.useFlashBlock&&fa?l.setTimeout(function(){c.setup({preferFlash:!1}).reboot(); +c.didFlashBlock=!0;c.beginDelayedInit()},1):E({type:"ontimeout",ignoreInit:!0}):0!==c.flashLoadTimeout&&xa(!0))},c.flashLoadTimeout)};Z=function(){if(Ga||!ka)return t.remove(l,"focus",Z),!0;Ga=ab=!0;R=!1;G();t.remove(l,"focus",Z);return!0};N=function(b){if(q)return!1;if(c.html5Only)return q=!0,F(),!0;var e=!0,d;if(!c.useFlashBlock||!c.flashLoadTimeout||c.getMoviePercent())q=!0,x&&(d={type:!D&&v?"NO_FLASH":"INIT_TIMEOUT"});if(x||b)c.useFlashBlock&&c.oMC&&(c.oMC.className=J()+" "+(null===c.getMoviePercent()? +"swf_timedout":"swf_error")),E({type:"ontimeout",error:d,ignoreInit:!0}),I(d),e=!1;x||(c.waitForWindowLoad&&!oa?t.add(l,"load",F):F());return e};Ma=function(){var b,e=c.setupOptions;for(b in e)e.hasOwnProperty(b)&&(c[b]===h?c[b]=e[b]:c[b]!==e[b]&&(c.setupOptions[b]=c[b]))};na=function(){if(q)return!1;if(c.html5Only)return q||(t.remove(l,"load",c.beginDelayedInit),c.enabled=!0,N()),!0;$();try{k._externalInterfaceTest(!1),Oa(!0,c.flashPollingInterval||(c.useHighPerformance?10:50)),c.debugMode||k._disableDebug(), +c.enabled=!0,c.html5Only||t.add(l,"unload",ma)}catch(b){return I({type:"JS_TO_FLASH_EXCEPTION",fatal:!0}),xa(!0),N(),!1}N();t.remove(l,"load",c.beginDelayedInit);return!0};H=function(){if(O)return!1;O=!0;Ma();wa();!D&&c.hasHTML5&&c.setup({useHTML5Audio:!0,preferFlash:!1});Wa();!D&&v&&(Ua.push(sa.needFlash),c.setup({flashLoadTimeout:1}));n.removeEventListener&&n.removeEventListener("DOMContentLoaded",H,!1);$();return!0};Ba=function(){"complete"===n.readyState&&(H(),n.detachEvent("onreadystatechange", +Ba));return!0};ua=function(){oa=!0;t.remove(l,"load",ua)};ta=function(){if(Fa&&(c.setupOptions.useHTML5Audio=!0,c.setupOptions.preferFlash=!1,U||Za&&!p.match(/android\s2\.3/i)))U&&(c.ignoreFlash=!0),z=!0};ta();Da();t.add(l,"focus",Z);t.add(l,"load",G);t.add(l,"load",ua);n.addEventListener?n.addEventListener("DOMContentLoaded",H,!1):n.attachEvent?n.attachEvent("onreadystatechange",Ba):I({type:"NO_DOM2_EVENTS",fatal:!0})}var la=null;if(void 0===l.SM2_DEFER||!SM2_DEFER)la=new V;l.SoundManager=V;l.soundManager= +la})(window); \ No newline at end of file diff --git a/client/music.coffee b/client/music.coffee new file mode 100644 index 0000000..2207c9e --- /dev/null +++ b/client/music.coffee @@ -0,0 +1,69 @@ +# Meteor.subscribe("songs"); +# Songs = new Meteor.Collection("song") +# Meteor.startup -> +# Template.songList.songs = ()-> +# return Songs.find({},{limit:10})# {artist:{$regex: 'Big', $options: 'i'}}) +Template.header.events = + 'click #pause' : (ev)-> + soundManager.pauseAll() + false + 'click #play' : (ev)-> + player.play() + false + 'click #progress' : (ev)-> + player.progressClick(ev.layerX) + false +Template.songList.events = + 'click tr' : (ev)-> + song = + title: ev.currentTarget.getAttribute('data-title') + artist: ev.currentTarget.getAttribute('data-artist') + Meteor.call 'getSong', song, (err, url) -> + song.url = url + player.create song + # console.log "return getsong", err, url + # document.getElementById('player').setAttribute('src', url) + # document.getElementById('player').play() + # Session.set('serverSimpleResponse', response); + false + +soundManager.setup + url: '/swf/' + flashVersion: 9 + onready: ()-> + # // Ready to use; soundManager.createSound() etc. can now be called. + +player = + list: [] + current: null + pause: ()-> + soundManager.pause() + play: ()-> + @current.play() + progressClick: (prog)-> + position = @duration() * (prog / $("#progress").width()) + @current.setPosition(position) + duration: ()-> + duration = if @current.bytesLoaded < @current.bytesTotal then @current.durationEstimate else @current.duration + return duration + create: (song)-> + sound = soundManager.createSound + id: song.SongID + url: song.url + autoLoad: true + autoPlay: true + onload: ()-> + console.log('The sound '+@id+' loaded!', song) + whileplaying: ()-> + duration = if @bytesLoaded < @bytesTotal then @durationEstimate else @duration + width = (@position/duration)*100 + $("#progress-bar").width(width+"%") + whileloading: ()-> + width = (@bytesLoaded / @bytesTotal)*100 + $("#loaded-bar").width(width+"%") + + + # console.log('at pos: '+@position, @) + volume: 50 + @list.push sound + @current = sound \ No newline at end of file diff --git a/client/music.css b/client/music.css new file mode 100644 index 0000000..ac0f932 --- /dev/null +++ b/client/music.css @@ -0,0 +1,27 @@ +#progress { + height: 10px; + width: 200px; + background-color: #ccc; + position: relative; + padding: 0; + margin: 20px 0 0 0; + display: inline-block; + +} +#progress b { + position: absolute; + width: 0; + display: block; + left: 0; + height: 10px; + top: 0; +} +#progress-bar { + background-color: #666; + z-index: 3; +} + +#loaded-bar { + background-color: #eee; + z-index: 2; +} \ No newline at end of file diff --git a/client/music.html b/client/music.html new file mode 100644 index 0000000..06d5d59 --- /dev/null +++ b/client/music.html @@ -0,0 +1,119 @@ + + + music + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/router.coffee b/client/router.coffee new file mode 100644 index 0000000..18befde --- /dev/null +++ b/client/router.coffee @@ -0,0 +1,56 @@ +Meteor.Router.add + "/songs": -> + if Meteor.userId() + "songs" + else + "signin" + + "*": "not_found" + + + + +Meteor.Router.filters isSignedIn: (page) -> + if Meteor.loggingIn() + "loading" + else if Meteor.user() + page + else + "signin" + + + +Meteor.Router.filter('isSignedIn', {except: 'signin'}) + + + + + +# iron router version +# Router.map -> +# @route 'home', path: '/' +# @route 'about' +# @route 'songs', +# waitOn: songsSub +# data: ()-> +# songs: Songs.find({},{limit:10})# {artist:{$regex: 'Big', $options: 'i'}}) + + +# Router.configure layout: 'layout' +# songsSub = Meteor.subscribe("songs") +# Songs = new Meteor.Collection("song") + +# class @SongsController extends RouteController +# template: 'songs' + +# renderTemplates: +# 'header': to: 'header' +# 'footer': to: 'footer' + +# data: -> +# songs: Songs.find({},{limit:10})# {artist:{$regex: 'Big', $options: 'i'}}) + +# run: -> +# console.log 'running'#, @data() +# super + diff --git a/packages.json b/packages.json new file mode 100644 index 0000000..d483255 --- /dev/null +++ b/packages.json @@ -0,0 +1,3 @@ +{ + "grooveshark": "0.0.3" +} \ No newline at end of file diff --git a/packages/.gitignore b/packages/.gitignore new file mode 100644 index 0000000..ad9564e --- /dev/null +++ b/packages/.gitignore @@ -0,0 +1,4 @@ +router +page-js-ie-support +HTML5-History-API +iron-router diff --git a/packages/npm/.gitignore b/packages/npm/.gitignore new file mode 100644 index 0000000..677a6fc --- /dev/null +++ b/packages/npm/.gitignore @@ -0,0 +1 @@ +.build* diff --git a/packages/npm/.npm/package/.gitignore b/packages/npm/.npm/package/.gitignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/packages/npm/.npm/package/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/packages/npm/.npm/package/README b/packages/npm/.npm/package/README new file mode 100644 index 0000000..3d49255 --- /dev/null +++ b/packages/npm/.npm/package/README @@ -0,0 +1,7 @@ +This directory and the files immediately inside it are automatically generated +when you change this package's NPM dependencies. Commit the files in this +directory (npm-shrinkwrap.json, .gitignore, and this README) to source control +so that others run the same versions of sub-dependencies. + +You should NOT check in the node_modules directory that Meteor automatically +creates; if you are using git, the .gitignore file tells git to ignore it. diff --git a/packages/npm/.npm/package/npm-shrinkwrap.json b/packages/npm/.npm/package/npm-shrinkwrap.json new file mode 100644 index 0000000..8008981 --- /dev/null +++ b/packages/npm/.npm/package/npm-shrinkwrap.json @@ -0,0 +1,12 @@ +{ + "dependencies": { + "grooveshark": { + "version": "0.0.3", + "dependencies": { + "request": { + "version": "2.10.0" + } + } + } + } +} diff --git a/packages/npm/index.js b/packages/npm/index.js new file mode 100644 index 0000000..8caed3a --- /dev/null +++ b/packages/npm/index.js @@ -0,0 +1,37 @@ +var Future = Npm.require('fibers/future'); + +Meteor.require = function(moduleName) { + var module = Npm.require(moduleName); + return module; +}; + +Meteor.sync = function(asynFunction) { + var future = new Future(); + var sent = false; + var payload; + + setTimeout(function() { + asynFunction(done); + function done(err, result) { + if(!sent) { + payload = { + result: result, + error: err + }; + + if(future.ret) { + //for 0.6.4.1 and older + future.ret(); + } else { + //for 0.6.5 and newer + future.return(); + } + } + } + }, 0); + + future.wait(); + sent = true; + + return payload; +}; diff --git a/packages/npm/package.js b/packages/npm/package.js new file mode 100644 index 0000000..eddefca --- /dev/null +++ b/packages/npm/package.js @@ -0,0 +1,33 @@ +var path = Npm.require('path'); +var fs = Npm.require('fs'); +var packagesJsonFile = path.resolve('./packages.json'); + +//creating `packages.json` file for the first-time if not exists +if(!fs.existsSync(packagesJsonFile)) { + fs.writeFileSync(packagesJsonFile, '{\n \n}') +} + +try { + var fileContent = fs.readFileSync(packagesJsonFile); + var packages = JSON.parse(fileContent.toString()); + Npm.depends(packages); +} catch(ex) { + console.error('ERROR: packages.json parsing error [ ' + ex.message + ' ]'); +} + +Package.describe({ + summary: "complete npm integration/support for Meteor" +}); + +Package.on_use(function (api, where) { + var isNewerMeteor = fs.readFileSync('./.meteor/packages', 'utf8').match(/\nstandard-app-packages/); + if(isNewerMeteor) { + api.add_files(['index.js', '../../packages.json'], 'server'); + } else { + api.add_files(['index.js'], 'server'); + } +}); + +Package.on_test(function (api) { + api.add_files(['index.js', 'test.js'], 'server'); +}); diff --git a/packages/npm/test.js b/packages/npm/test.js new file mode 100644 index 0000000..433f32c --- /dev/null +++ b/packages/npm/test.js @@ -0,0 +1,22 @@ +Tinytest.add('Meteor.sync with done()', function(test) { + var output = Meteor.sync(function(done) { + setTimeout(function() { + done(null, 10001); + }, 10); + }); + + test.equal(output.result, 10001); + test.equal(output.error, null); +}); + +Tinytest.add('Meteor.sync with error()', function(test) { + + var output = Meteor.sync(function(done) { + setTimeout(function() { + done({message: 'error-message', code: 402}); + }, 10); + }); + + test.equal(output.result, undefined); + test.equal(output.error.code, 402); +}); \ No newline at end of file diff --git a/public/swf/soundmanager2.swf b/public/swf/soundmanager2.swf new file mode 100755 index 0000000..dc383ce Binary files /dev/null and b/public/swf/soundmanager2.swf differ diff --git a/public/swf/soundmanager2_debug.swf b/public/swf/soundmanager2_debug.swf new file mode 100755 index 0000000..bfa601a Binary files /dev/null and b/public/swf/soundmanager2_debug.swf differ diff --git a/public/swf/soundmanager2_flash9.swf b/public/swf/soundmanager2_flash9.swf new file mode 100755 index 0000000..df23168 Binary files /dev/null and b/public/swf/soundmanager2_flash9.swf differ diff --git a/public/swf/soundmanager2_flash9_debug.swf b/public/swf/soundmanager2_flash9_debug.swf new file mode 100755 index 0000000..adc545a Binary files /dev/null and b/public/swf/soundmanager2_flash9_debug.swf differ diff --git a/public/swf/soundmanager2_flash_xdomain.zip b/public/swf/soundmanager2_flash_xdomain.zip new file mode 100755 index 0000000..059fc11 Binary files /dev/null and b/public/swf/soundmanager2_flash_xdomain.zip differ diff --git a/server/grooveshark.coffee b/server/grooveshark.coffee new file mode 100644 index 0000000..3338766 --- /dev/null +++ b/server/grooveshark.coffee @@ -0,0 +1,102 @@ +# require = Npm.require +Grooveshark = Meteor.require("grooveshark") +# events = require('events') +# Meteor.startup -> + +grooveshark = new Grooveshark(share.config.grooveshark.key, share.config.grooveshark.secret) +# grooveshark.events = new events.EventEmitter() + +grooveshark.authenticate share.config.grooveshark.user, share.config.grooveshark.pass, (err) -> + throw err if err + # grooveshark.events.emit('ready') + # @authenticated = true + +grooveshark.getCountry = (ip, next)-> + params = {} + params.ip = ip if ip + grooveshark.request "getCountry", params, (err, status, country) -> + return next(err) if err + next(null, country) + +grooveshark.getStreamKey = (songID, country, next)-> # get a stream key for a single song for a single browser play + grooveshark.request "getStreamKeyStreamServer", + songID: songID + country: country + , (err, status, body) -> + return next(err) if err + grooveshark.streamServerID = body.StreamServerID + next(null, body) + +grooveshark.markStreamKeyOver30Secs = (streamKey, next)-> + grooveshark.request "markStreamKeyOver30Secs", + streamKey: streamKey + streamServerID: grooveshark.streamServerID + , (err, status, body) -> + return next(err) if err + next(null, body) + +grooveshark.markSongComplete = (songID, streamKey, next)-> + grooveshark.request "markSongComplete", + songID: songID + streamKey: streamKey + streamServerID: grooveshark.streamServerID + , (err, status, body) -> + return next(err) if err + next(null, body) + +grooveshark.findSong = (query, country, next)-> + grooveshark.request "getSongSearchResults", + query: query + country: country + limit: 1 + offset: 0 + , (err, status, body) -> + return next(err) if err + song = if body.songs?[0] then body.songs[0] else false + next(null, song) + +grooveshark.doesSongExist = (songID, next)-> + grooveshark.request "getDoesSongExist", + songID: songID + , (err, status, doesExist) -> + return next(err) if err + next(null, doesExist) + +grooveshark.getUrlFromSongName = (song, ip, next)-> # song: {id, title, artist} + grooveshark.getCountry ip, (err, country)-> + grooveshark.findSong "#{song.artist} #{song.title}", country, (err, song2)-> + # console.log "findSong ERR", err, song2 + grooveshark.getStreamKey song2.SongID, country, (err, streamKey)-> + next(null, streamKey.url) + +grooveshark.getUrlFromSong = (song, ip, next)-> # song: {id, title, artist} + if song.id + grooveshark.getCountry ip, (err, country)-> + grooveshark.doesSongExist song.id, (err, doesExist)-> + if doesExist + grooveshark.getStreamKey song.id, country, (err, streamKey)-> + next(streamKey.url) + else + grooveshark.getUrlFromSongName song, ip, (err, url)-> + next null, url + else + grooveshark.getUrlFromSongName song, ip, (err, url)-> + next null, url + +Meteor.methods + getSong: (song)-> + ip = share.getIP(Meteor.userId()) + Future = Meteor.require('fibers/future') + future = new Future() + grooveshark.getUrlFromSong song, ip, (err, url)-> + future.return url + + return future.wait() + + # console.log('on server, getSong called',song) + # return new Date() + + + + +# share.grooveshark = grooveshark \ No newline at end of file diff --git a/server/ip.coffee b/server/ip.coffee new file mode 100644 index 0000000..0080b68 --- /dev/null +++ b/server/ip.coffee @@ -0,0 +1,10 @@ +share.getIP = (userId) -> + ip = undefined + for key, session of Meteor.default_server.sessions + if session.userId == userId and session.socket != null + if session.socket.headers['x-forwarded-for'] + ip = session.socket.headers['x-forwarded-for'] + else if session.socket.remoteAddress + ip = session.socket.remoteAddress + break + ip \ No newline at end of file diff --git a/server/songs.coffee b/server/songs.coffee new file mode 100644 index 0000000..f02fe77 --- /dev/null +++ b/server/songs.coffee @@ -0,0 +1,24 @@ +Songs = new Meteor.Collection("song") +Meteor.startup -> + # @setUserId (if @userId then @userId else new Meteor.Collection.ObjectID()._str) + if Songs.find().count() == 0 + songs = [ + { + title: "Ada" + artist: "The National" + album: "Sky Violet" + }, + { + title: "When Doves Cry" + artist: "Prince" + album: "Purple Rain" + } + ] + for s in songs + Songs.insert(s) + +Meteor.publish "songs", ()-> + if @userId + return Songs.find({}) # {artist:{$regex: 'Big', $options: 'i'}}) + else + return undefined diff --git a/smart.json b/smart.json new file mode 100644 index 0000000..68005ed --- /dev/null +++ b/smart.json @@ -0,0 +1,6 @@ +{ + "packages": { + "router": {}, + "iron-router": {} + } +} diff --git a/smart.lock b/smart.lock new file mode 100644 index 0000000..6b23156 --- /dev/null +++ b/smart.lock @@ -0,0 +1,31 @@ +{ + "meteor": {}, + "dependencies": { + "basePackages": { + "router": {}, + "iron-router": {} + }, + "packages": { + "router": { + "git": "https://github.com/tmeasday/meteor-router.git", + "tag": "v0.5.4", + "commit": "e40ee450a756b54a32ed67be4595772403256fb5" + }, + "iron-router": { + "git": "https://github.com/EventedMind/iron-router.git", + "tag": "v0.5.4", + "commit": "3e0e22ff85630b7503d0daa1538c6d90abb84020" + }, + "page-js-ie-support": { + "git": "https://github.com/tmeasday/meteor-page-js-ie-support.git", + "tag": "v1.3.5", + "commit": "b99ed8380aefd10b2afc8f18d9eed4dd0d8ea9cb" + }, + "HTML5-History-API": { + "git": "https://github.com/tmeasday/meteor-HTML5-History-API.git", + "tag": "v4.0.0", + "commit": "dc4965f1424cfca625ec3fbea17eace03f8e32c5" + } + } + } +}