summaryrefslogtreecommitdiff
path: root/static
diff options
context:
space:
mode:
authorJon Bergli Heier <snakebite@jvnv.net>2011-08-08 00:11:01 +0200
committerJon Bergli Heier <snakebite@jvnv.net>2011-08-08 00:11:01 +0200
commit97d7c9014855449fe04162308feac66a35e007ea (patch)
tree8133c59cb0f066d992f434109818dd771e73f544 /static
Initial commit.
app.py - WSGI application and handlers. config.py - Config helper class. directory.py - Directory and file helper classes. events.py - zeromq event publisher and subscriber. recode.py - Codecs and stuff static/ - Web interface
Diffstat (limited to 'static')
-rw-r--r--static/audio.js19
-rw-r--r--static/icons/folder.pngbin0 -> 537 bytes
-rw-r--r--static/icons/loading.gifbin0 -> 1737 bytes
-rw-r--r--static/icons/music-cached.pngbin0 -> 633 bytes
-rw-r--r--static/icons/music-queued.pngbin0 -> 646 bytes
-rw-r--r--static/icons/music.pngbin0 -> 385 bytes
-rw-r--r--static/icons/readme.txt22
-rw-r--r--static/index.html28
-rw-r--r--static/player.js170
-rw-r--r--static/style.css9
10 files changed, 248 insertions, 0 deletions
diff --git a/static/audio.js b/static/audio.js
new file mode 100644
index 0000000..6eaec56
--- /dev/null
+++ b/static/audio.js
@@ -0,0 +1,19 @@
+function Audio() {
+ this.audio = document.getElementById('audio');
+
+ this.set_src = function(src) {
+ this.audio.setAttribute('src', src);
+ }
+
+ this.play = function() {
+ this.audio.play();
+ }
+
+ this.pause = function() {
+ this.audio.pause();
+ }
+
+ this.stop = function() {
+ this.audio.stop();
+ }
+}
diff --git a/static/icons/folder.png b/static/icons/folder.png
new file mode 100644
index 0000000..784e8fa
--- /dev/null
+++ b/static/icons/folder.png
Binary files differ
diff --git a/static/icons/loading.gif b/static/icons/loading.gif
new file mode 100644
index 0000000..1560b64
--- /dev/null
+++ b/static/icons/loading.gif
Binary files differ
diff --git a/static/icons/music-cached.png b/static/icons/music-cached.png
new file mode 100644
index 0000000..6802f99
--- /dev/null
+++ b/static/icons/music-cached.png
Binary files differ
diff --git a/static/icons/music-queued.png b/static/icons/music-queued.png
new file mode 100644
index 0000000..5034c06
--- /dev/null
+++ b/static/icons/music-queued.png
Binary files differ
diff --git a/static/icons/music.png b/static/icons/music.png
new file mode 100644
index 0000000..a8b3ede
--- /dev/null
+++ b/static/icons/music.png
Binary files differ
diff --git a/static/icons/readme.txt b/static/icons/readme.txt
new file mode 100644
index 0000000..400a64d
--- /dev/null
+++ b/static/icons/readme.txt
@@ -0,0 +1,22 @@
+Silk icon set 1.3
+
+_________________________________________
+Mark James
+http://www.famfamfam.com/lab/icons/silk/
+_________________________________________
+
+This work is licensed under a
+Creative Commons Attribution 2.5 License.
+[ http://creativecommons.org/licenses/by/2.5/ ]
+
+This means you may use it for any purpose,
+and make any changes you like.
+All I ask is that you include a link back
+to this page in your credits.
+
+Are you using this icon set? Send me an email
+(including a link or picture if available) to
+mjames@gmail.com
+
+Any other questions about this icon set please
+contact mjames@gmail.com \ No newline at end of file
diff --git a/static/index.html b/static/index.html
new file mode 100644
index 0000000..ea20792
--- /dev/null
+++ b/static/index.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>foo</title>
+ <script src="/static/audio.js" type="text/javascript"></script>
+ <script src="/static/player.js" type="text/javascript"></script>
+ <link rel="stylesheet" href="/static/style.css" type="text/css" />
+</head>
+<body>
+ <div id="transcode-div">
+ <label for="trans_enabled"><input type="checkbox" id="trans_enabled" /> Transcode</label>
+ from
+ <select id="trans_from">
+ <option value="ffmpeg">FFmpeg</option>
+ </select>
+ to
+ <select id="trans_to">
+ <option value="ffmpeg">FFmpeg</option>
+ </select>
+ </div>
+ <textarea id="logbox" readonly="readonly" rows="10" cols="50"></textarea>
+ <div><input type="button" value="Close event source" onclick="source.close()" /></div>
+ <div id="current-dir"></div>
+ <ul id="song-links"></ul>
+ <div id="audio-src-url">none</div>
+ <audio id="audio" controls="controls"></audio>
+</body>
+</html>
diff --git a/static/player.js b/static/player.js
new file mode 100644
index 0000000..70b5a6d
--- /dev/null
+++ b/static/player.js
@@ -0,0 +1,170 @@
+audio = null;
+
+// pre-load some icons
+cache_images = new Array(
+ 'music-cached.png',
+ 'music-queued.png',
+ 'loading.gif'
+);
+var img = new Image();
+for(var i = 0; i < cache_images.length; i++) {
+ img.src = '/static/icons/' + cache_images[i];
+}
+
+function MusicListing(type, path, name, cached) {
+ this.type = type;
+ this.path = path;
+ this.name = name ? name : path.split('/').pop();
+ this.a = document.createElement('a');
+ this.a.tag = path;
+
+ this.play = function() {
+ var transcode = document.getElementById('trans_enabled').checked;
+ var trans_from = document.getElementById('trans_from').value;
+ var trans_to = document.getElementById('trans_to').value;
+ var p = path;
+ if(transcode)
+ p += '?decoder=' + trans_from + '&encoder=' + trans_to;
+ log('playing ' + p);
+ change_url('/files/' + p);
+ audio.play();
+ }
+
+ this.cache = function() {
+ var path = '/cache?path=' + encodeURIComponent(this.path) +
+ '&decoder=' + document.getElementById('trans_from').value +
+ '&encoder=' + document.getElementById('trans_to').value;
+ var a = this.a;
+ var ml = this;
+ var xmlhttp = new XMLHttpRequest();
+ a.setAttribute('class', 'file file-queued');
+ xmlhttp.open('GET', path);
+ xmlhttp.send(null);
+ }
+
+ this.get_anchor = function() {
+ var a = this.a;
+ var className = type;
+ if(cached)
+ className += ' file-cached'
+ a.setAttribute('class', className);
+ a.setAttribute('href', '#');
+ a.appendChild(document.createTextNode(this.name));
+ var ml = this;
+
+ a.onclick = function() {
+ if(type == 'dir') {
+ list(path);
+ } else if(type == 'file') {
+ var transcode = document.getElementById('trans_enabled').checked;
+ var trans_from = document.getElementById('trans_from').value;
+ var trans_to = document.getElementById('trans_to').value;
+
+ var p = path;
+ if(transcode) {
+ ml.cache(p);
+ } else {
+ ml.play();
+ }
+ }
+ return false;
+ }
+ return a;
+ }
+}
+
+function set_current(path) {
+ document.getElementById('current-dir').innerHTML = 'Directory: ' + path;
+}
+
+function log(s) {
+ logbox = document.getElementById('logbox');
+ logbox.value += s + '\n';
+ logbox.scrollTop = logbox.scrollHeight;
+}
+
+function change_url(url) {
+ audio.set_src(url);
+
+ var audio_src_url = document.getElementById('audio-src-url');
+ audio_src_url.innerHTML = 'Playing: ' + url.replace('&', '&amp;');
+}
+
+function output_link(obj) {
+ var a = obj.get_anchor();
+
+ var li = document.createElement('li');
+ li.appendChild(a);
+
+ var song_links = document.getElementById('song-links');
+ song_links.appendChild(li);
+}
+
+function list(root) {
+ log('listing ' + root);
+ var xmlhttp = new XMLHttpRequest();
+ xmlhttp.onreadystatechange = function() {
+ if(xmlhttp.readyState == 4) {
+ set_current(root);
+ var json = JSON.parse(xmlhttp.responseText);
+ document.getElementById('song-links').innerHTML = '';
+ // add "up" link
+ if(root.length > 1) {
+ up = root.substr(0, root.lastIndexOf('/'));
+ if(up.length == 0)
+ up = '/';
+ l = new MusicListing('dir', up, '..');
+ output_link(l);
+ }
+ for(var i = 0; i < json.length; i++) {
+ var type = json[i]["type"];
+ var path = json[i]["name"];
+ var name = path.substring(path.lastIndexOf('/')+1);
+ var cached = type == "file" ? json[i]["cached"] : false;
+ var l = new MusicListing(type, path, name, cached);
+ output_link(l);
+ }
+ }
+ }
+
+ path = '/list?directory=' + encodeURIComponent(root);
+ xmlhttp.open('GET', path);
+ xmlhttp.send();
+}
+
+var source = null;
+
+function get_a(path) {
+ var as = document.getElementsByTagName('a');
+ for(var i = 0; i < as.length; i++) {
+ var a = as[i];
+ if(a.tag == path)
+ return a;
+ }
+}
+
+function event_handler(event) {
+ data = JSON.parse(event.data);
+ switch(data['type']) {
+ case 'cached':
+ case 'recoding':
+ log('[' + data['type'] + '] ' + data['path']);
+ var a = get_a(data['path']);
+ if(a)
+ a.setAttribute('class', 'file file-' + data['type']);
+ break;
+ default:
+ log('[event] unknown type: ' + data['type']);
+ }
+}
+
+window.onload = function() {
+ source = new EventSource('/events');
+ source.onopen = function() { log('event source opened'); }
+ source.onmessage = event_handler;
+ source.onerror = function(event) { log('event source error'); }
+ log('event source status: ' + source.readyState);
+
+ audio = new Audio();
+ list('/');
+}
diff --git a/static/style.css b/static/style.css
new file mode 100644
index 0000000..d086227
--- /dev/null
+++ b/static/style.css
@@ -0,0 +1,9 @@
+ul#song-links { list-style-type: none; }
+ul#song-links a { text-decoration: none; color: inherit; }
+ul#song-links a:hover { text-decoration: underline; }
+a.dir { background-image: url('/static/icons/folder.png'); }
+a.file { background-image: url('/static/icons/music.png'); }
+a.file-cached { background-image: url('/static/icons/music-cached.png'); }
+a.dir, a.file { background-repeat: no-repeat; padding-left: 20px; }
+a.file-recoding { background-image: url('/static/icons/loading.gif'); }
+a.file-queued { background-image: url('/static/icons/music-queued.png'); }