From f417e58d71ee256b42a59f4ffa8fe21389e73af3 Mon Sep 17 00:00:00 2001 From: Peter Grassberger Date: Fri, 1 Apr 2016 20:28:38 +0200 Subject: websocket test (breaking commit) diff --git a/www/js/apps.js b/www/js/apps.js index dd5b337..945b454 100644 --- a/www/js/apps.js +++ b/www/js/apps.js @@ -105,12 +105,13 @@ function apps_select(app) { } function apps_init() { - importer = new Rdxport.Importer(); apps_current = locationHrefValue(); if(auth_token && auth_username) { // todo: do this at a central place + importer = new Rdxport.Importer(auth_username, auth_token); + rdxport = new Rdxport.Rdxport(auth_username, auth_token, '/rd-bin/rdxport.cgi'); rdxport.setListDropboxesEndpoint('/rh-bin/listdropboxes.cgi'); rdxport.setMusicgridEndpoint('/rh-bin/musicgrid.cgi'); @@ -121,6 +122,8 @@ function apps_init() { $(window).on('popstate', function(event) { if(auth_token && auth_username) { // todo: do this at a central place + importer = new Rdxport.Importer(auth_username, auth_token); + rdxport = new Rdxport.Rdxport(auth_username, auth_token, '/rd-bin/rdxport.cgi'); rdxport.setListDropboxesEndpoint('/rh-bin/listdropboxes.cgi'); rdxport.setMusicgridEndpoint('/rh-bin/musicgrid.cgi'); diff --git a/www/js/auth.js b/www/js/auth.js index d01b70d..dd21e39 100644 --- a/www/js/auth.js +++ b/www/js/auth.js @@ -39,6 +39,8 @@ function auth_loginSuccess(data) { sessionStorage.setItem("auth_token", auth_token); // todo: do this at a central place + importer = new Rdxport.Importer(auth_username, auth_token); + rdxport = new Rdxport.Rdxport(auth_username, auth_token, '/rd-bin/rdxport.cgi'); rdxport.setListDropboxesEndpoint('/rh-bin/listdropboxes.cgi'); rdxport.setMusicgridEndpoint('/rh-bin/musicgrid.cgi'); diff --git a/www/js/importer.js b/www/js/importer.js index 4ea55b3..96c7dac 100644 --- a/www/js/importer.js +++ b/www/js/importer.js @@ -24,10 +24,88 @@ var Rdxport = Rdxport || {}; -Rdxport.Importer = function() { - this.$el = $('#uploadModal'); +Rdxport.Importer = function(username, token) { + this.username = username; + this.token = token; + this.$el = $('#uploadModal'); this.uploads = []; + this.webSocket = null; + + this.initWebSocket(); +}; + +Rdxport.Importer.CMD_LIST = 'list'; +Rdxport.Importer.CMD_NEW = 'new'; +Rdxport.Importer.CMD_RECONNECT = 'reconnect'; + +Rdxport.Importer.prototype.initWebSocket = function() { + var importer = this; + + var webSocket = new WebSocket('wss://import.helsinki.at/rhimportd'); + + webSocket.onclose = function(code, reason) { + console.log('close'); + console.log(code); + console.log(reason); + }; + + webSocket.onerror = function() { + console.log('error'); + }; + + webSocket.onopen = function() { + console.log('open'); + + console.log('send list'); + var sendOptions = { + COMMAND: Rdxport.Importer.CMD_NEW, + LOGIN_NAME: importer.username, + PASSWORD: importer.token, + TIMEOUT: 200, + REFERENCE_ID: 999, + SHOW_ID: 10000, + CLEAR_SHOW_CARTS: true, + SOURCE_URI: 'archiv://2016/03/31/05/00' + }; + console.log(sendOptions); + this.send(JSON.stringify(sendOptions)); + }; + + webSocket.onmessage = function(event) { + console.log('message'); + console.log(event.data); + }; + + /*this.webSocket = new WebSocket('wss://import.helsinki.at/rhimportd'); + + this.webSocket.onclose = function(code, reason) { + console.log('close'); + console.log(code); + console.log(reason); + }; + + this.webSocket.onerror = function() { + console.log('error'); + }; + + this.webSocket.onopen = function() { + console.log('open'); + + console.log('send reconnect'); + var reconnectOptions = { + COMMAND: Rdxport.Importer.CMD_RECONNECT, + LOGIN_NAME: importer.username, + PASSWORD: importer.token + }; + console.log(reconnectOptions); + this.send(JSON.stringify(reconnectOptions)); + }; + + this.webSocket.onmessage = function(event) { + console.log('message'); + console.log(event.data); + };*/ }; Rdxport.Importer.prototype.resetModal = function() { -- cgit v0.10.2 From ab1bdfd0d66e9a1b72433ecb374584e7a123023f Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Sat, 2 Apr 2016 23:43:12 +0200 Subject: added /upload proxy to apache sample config diff --git a/README b/README index 1144e89..9dc98a0 100644 --- a/README +++ b/README @@ -71,8 +71,9 @@ add the following to the virtualhost config: - ProxyPass "/ntp" "ws://localhost:3000/ntp" - ProxyPass "/rhimportd" "ws://localhost:4080/public/socket" + ProxyPass "/ntp" "ws://localhost:3000/ntp" + ProxyPass "/rhimportd" "ws://localhost:4080/public/socket" + ProxyPass "/upload" "http://localhost:4080/public/upload" DocumentRoot /var/www/rhwebimport/www/ -- cgit v0.10.2 From 7eed6d7aa3bb7b0ee22fa3cf310976cfbeaf46b8 Mon Sep 17 00:00:00 2001 From: Peter Grassberger Date: Wed, 13 Apr 2016 18:28:02 +0200 Subject: fix websocket archiv source format diff --git a/contrib/Pflichtenheft-Peter.md b/contrib/Pflichtenheft-Peter.md index 74362b8..1cbc487 100644 --- a/contrib/Pflichtenheft-Peter.md +++ b/contrib/Pflichtenheft-Peter.md @@ -59,7 +59,7 @@ Es ist ein Interface zu entwickeln, mit dessen Hilfe die Zuweisung der Musikpool Es soll möglich sein Dateien direkt aus verschiednen exteren Quellen zu importieren. Zu diesem Zweck gibt es serverseitig die Komponente `rhimportd`. Diese wird über eine Websocket-API gesteuert und kümmert sich um den tatsächlichen Import. `rhwebimport` initiiert den Import und visualisiert den Fortschritt. Ausserdem soll es möglich sein den Fortschritt etwaiger laufender Import-Prozesse nach einem erneuten Einloggen (zb. nach einem Verbindungsabbruch) weiter anzuzeigen. `rhimportd` bietet alle dafür notwendigen API Funktionen. Sollten zu diese Zweck Änderungen an der API notwendig sein sollen diese gemeinsam mit dem Radio Helsinki Technik-Team erarbeitet werden. Die Änderungen an `rhimportd` werden von Radio Helsinki erledigt. Folgende externe Quellen sollen unterstützt werden: - - archiv://YYYY/MM/DD/hh/00 - import aus dem Sendungsarchiv von Radio Helsinki (immer volle Stunden) + - archiv://YYYY/MM/DD/hh - import aus dem Sendungsarchiv von Radio Helsinki (immer volle Stunden) - http://, https://, ftp://, ftps:// - import von der entsprechenden URL ### zustätliche Importquelle: `public:///` diff --git a/www/js/importer.js b/www/js/importer.js index 96c7dac..6803921 100644 --- a/www/js/importer.js +++ b/www/js/importer.js @@ -63,10 +63,10 @@ Rdxport.Importer.prototype.initWebSocket = function() { LOGIN_NAME: importer.username, PASSWORD: importer.token, TIMEOUT: 200, - REFERENCE_ID: 999, + REFERENCE_ID: "999", SHOW_ID: 10000, CLEAR_SHOW_CARTS: true, - SOURCE_URI: 'archiv://2016/03/31/05/00' + SOURCE_URI: 'archiv://2016/03/31/05' }; console.log(sendOptions); this.send(JSON.stringify(sendOptions)); -- cgit v0.10.2 From f66535fef191f9183fde73a6eeb01e8678593c7e Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Fri, 15 Apr 2016 23:11:00 +0200 Subject: make show rhythm fancier diff --git a/www/index.html b/www/index.html index eb8e3d2..68b2d36 100644 --- a/www/index.html +++ b/www/index.html @@ -160,7 +160,10 @@ Tag:
- Rythmus: + Rythmus: 1 + 2 + 3 + 4
Startzeit: diff --git a/www/js/shows.js b/www/js/shows.js index 8fcba8b..1086620 100644 --- a/www/js/shows.js +++ b/www/js/shows.js @@ -189,10 +189,23 @@ Rdxport.ShowView = function(model) { Rdxport.ShowView.prototype.render = function() { $('#show-title').text(this.model.title); $('#show-dow').text(weekday[this.model.dayofweek]); - $('#show-rhythm').text(this.model.rhythm); $('#show-starttime').text(this.model.starttime); $('#show-length').text(this.model.length + ' Min.'); + for(var w = 0; w < 4; w++) { + if(this.model.rhythm.charAt(w) == '1') { + var s = $('#show-rhythm-w' + (w+1)).attr('class', 'label') + switch(w+1) { + case 1: s.addClass('label-info'); break; + case 2: s.addClass('label-warning'); break; + case 3: s.addClass('label-success'); break; + case 4: s.addClass('label-danger'); break; + } + } else { + $('#show-rhythm-w' + (w+1)).attr('class', 'label label-default') + } + } + var $tableBody = $('#app-shows table tbody'); $('tr', $tableBody).remove(); -- cgit v0.10.2 From aff9aaaa27bfb989432e23c768b2ec52fc8e70f7 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Tue, 19 Apr 2016 21:28:01 +0200 Subject: improved rendering of show rhythm diff --git a/www/js/shows.js b/www/js/shows.js index 1086620..f0eb34e 100644 --- a/www/js/shows.js +++ b/www/js/shows.js @@ -202,7 +202,7 @@ Rdxport.ShowView.prototype.render = function() { case 4: s.addClass('label-danger'); break; } } else { - $('#show-rhythm-w' + (w+1)).attr('class', 'label label-default') + $('#show-rhythm-w' + (w+1)).attr('class', 'label label-disabled') } } diff --git a/www/styles/shows.css b/www/styles/shows.css index 2daa8b6..c977334 100644 --- a/www/styles/shows.css +++ b/www/styles/shows.css @@ -28,3 +28,8 @@ margin-top: 1.5em; margin-bottom: 1em; } + +.label-disabled { + background-color: #EEE; + color: #888; +} -- cgit v0.10.2 From 16b507e9ab3b7d9bfbe72319d2197cea98905294 Mon Sep 17 00:00:00 2001 From: Peter Grassberger Date: Wed, 20 Apr 2016 17:58:14 +0200 Subject: rewrite auth and apps diff --git a/www/index.html b/www/index.html index 68b2d36..9bc89ec 100644 --- a/www/index.html +++ b/www/index.html @@ -15,20 +15,6 @@ - - - - - - - - - - - - - - @@ -40,7 +26,7 @@ radio helsinki logo - +

Radio Helsinki - Import

@@ -76,7 +62,7 @@ @@ -430,11 +416,21 @@
- + + + + + + + + + + + + + + + diff --git a/www/js/auth.js b/www/js/auth.js index d01b70d..c533219 100644 --- a/www/js/auth.js +++ b/www/js/auth.js @@ -24,94 +24,89 @@ var Rdxport = Rdxport || {}; -var auth_username = null; -var auth_fullname = null; -var auth_token = null; - -function auth_loginSuccess(data) { - if (data.status == 'OK') { - auth_username = data.username; - auth_fullname = data.fullname; - auth_token = data.token; - - sessionStorage.setItem("auth_username", auth_username); - sessionStorage.setItem("auth_fullname", auth_fullname); - sessionStorage.setItem("auth_token", auth_token); - - // todo: do this at a central place - rdxport = new Rdxport.Rdxport(auth_username, auth_token, '/rd-bin/rdxport.cgi'); - rdxport.setListDropboxesEndpoint('/rh-bin/listdropboxes.cgi'); - rdxport.setMusicgridEndpoint('/rh-bin/musicgrid.cgi'); - - apps_select(apps_current); - - $('#username-field').html(auth_fullname + ' (' + auth_username + ')'); - $('#loginbox').slideUp(); - $('#mainwindow').fadeIn(); - } else { - alertbox.error('loginbox', "Fehler beim Login", data.errorstring); - auth_cleanup(); - } -} - -function auth_loginError(req, status, error) { - var message = req.status + ': ' + error; - if(req.status == 401) { - message = "Benutzer und/oder Passwort sind falsch!"; - } - alertbox.error('loginbox', "Fehler beim Login", message); - $("#password").val(''); -} - -function auth_logout() { - if (importer && importer.isUploading()) { - alert('Achtung: Es laufen noch imports.'); - return; - } - - auth_cleanup(); - apps_cleanup(); +Rdxport.Auth = function() { + console.log('auth'); + this.username = sessionStorage.getItem('auth_username'); + this.fullname = sessionStorage.getItem('auth_fullname'); + this.token = sessionStorage.getItem('auth_token'); +}; + +Rdxport.Auth.prototype.isLoggedIn = function() { + console.log('isLoggedIn'); + return this.username && this.fullname && this.token; +}; + +Rdxport.Auth.prototype.set = function(username, fullname, token) { + console.log('set'); + this.username = username; + this.fullname = fullname; + this.token = token; + + sessionStorage.setItem('auth_username', this.username); + sessionStorage.setItem('auth_fullname', this.fullname); + sessionStorage.setItem('auth_token', this.token); +}; + +Rdxport.Auth.prototype.cleanup = function() { + console.log('cleanup'); + sessionStorage.removeItem('auth_username'); + sessionStorage.removeItem('auth_fullname'); + sessionStorage.removeItem('auth_token'); + + this.username = null; + this.fullname = null; + this.token = null; +}; + +Rdxport.AuthView = function(model) { + console.log('AuthView'); + this.model = model; +}; + +Rdxport.AuthView.prototype.renderLoggedIn = function() { + $('#loginbox').slideUp(); + $('#mainwindow').fadeIn(); + $('#username-field').html(this.model.fullname + ' (' + this.model.username + ')'); + + $('button.logout').off().on('click', function() { + router.logout(); + }); +}; - $(".alert").alert('close'); - $("#username").val(''); - $("#password").val(''); - $("#mainwindow").fadeOut(); - $('#username-field').html(''); +Rdxport.AuthView.prototype.renderLoginForm = function() { + $('.alert').alert('close'); $('#loginbox').slideDown(); -} + $('#mainwindow').fadeOut(); + $('#username-field').empty(); -function auth_init() { - auth_username = sessionStorage.getItem("auth_username"); - auth_fullname = sessionStorage.getItem("auth_fullname"); - auth_token = sessionStorage.getItem("auth_token"); - - if(auth_token && auth_username && auth_fullname) { - $("#loginbox").hide(); - $('#username-field').html(auth_fullname + ' (' + auth_username + ')'); - } else { - $("#mainwindow").hide(); - } - $("#loginform").submit(function(event) { + var self = this; + $('#loginform').on('submit', function(event) { event.preventDefault(); - Rdxport.Rdxport.authLogin( - '/rh-bin/authtoken.json', - $("#username").val(), - $("#password").val(), - auth_loginSuccess - ).fail(auth_loginError); + '/rh-bin/authtoken.json', + $("#username").val(), + $("#password").val(), + function(data) { + if (data.status == 'OK') { + self.model.set( + data.username, + data.fullname, + data.token + ); + + router.route(); + } else { + alertbox.error('loginbox', "Fehler beim Login", data.errorstring); + self.model.cleanup(); + } + } + ).fail(function(req, status, error) { + var message = req.status + ': ' + error; + if(req.status == 401) { + message = "Benutzer und/oder Passwort sind falsch!"; + } + alertbox.error('loginbox', "Fehler beim Login", message); + $("#password").val(''); + }); }); -} - -function auth_cleanup() { - sessionStorage.removeItem("auth_username"); - sessionStorage.removeItem("auth_fullname"); - sessionStorage.removeItem("auth_token"); - - auth_username = null; - auth_fullname = null; - auth_token = null; - - $("#username").val('').focus(); - $("#password").val(''); -} +}; diff --git a/www/js/clock.js b/www/js/clock.js index 96ec9e4..eb04eed 100644 --- a/www/js/clock.js +++ b/www/js/clock.js @@ -44,11 +44,11 @@ function Clock() { time_str += (rdtime.getUTCSeconds() > 9 ? ':' : ':0') + rdtime.getUTCSeconds(); this.draw_callbacks.fireWith(window, [date_str, time_str, get_rd_week(rdtime_ms)]); - } + }; this.addCallback = function(cb) { this.draw_callbacks.add(cb); - } + }; this.ntp_update = function(event) { var t4 = (+new Date()); @@ -59,18 +59,18 @@ function Clock() { this.clock_offset = ((msg.t2 - msg.t1) + (msg.t3 - msg.t4)) / 2; this.clock_rtt = (msg.t4 - msg.t1) - (msg.t3 - msg.t2); // console.log('got new ntp message from rhrdtime (rtt=' + this.clock_rtt + ' ms): new offset = ' + this.clock_offset + ' ms'); - } + }; this.ntp_request = function() { this.sock.send(JSON.stringify({ t1: (+new Date()), t2: 0, t3: 0, t4: 0, tz_offset: 0, week: 0 })); - } + }; this.sock_onopen = function() { // console.log('clock websocket connection established'); this.state = 'CONNECTED'; this.ntp_request(); this.interval_request = setInterval(this.ntp_request.bind(this), 2000); - } + }; this.sock_onclose = function(event) { if(this.state == 'STOPPED') { @@ -84,7 +84,7 @@ function Clock() { setTimeout(this.connect.bind(this), 1000); this.state = 'RECONNECTING'; } - } + }; this.connect = function() { this.sock = new WebSocket('wss://' + window.location.host + '/ntp'); @@ -92,12 +92,12 @@ function Clock() { this.sock.onopen = this.sock_onopen.bind(this); this.sock.onclose = this.sock_onclose.bind(this); this.state = 'CONNECTING'; - } + }; this.start = function() { this.connect(); this.interval_redraw = setInterval(this.redraw.bind(this), 200); - } + }; this.stop = function() { this.state = 'STOPPED'; @@ -106,7 +106,7 @@ function Clock() { clearInterval(this.interval_request); delete this.interval_request; this.sock.close(); - } + }; } var clock = new Clock(); diff --git a/www/js/router.js b/www/js/router.js new file mode 100644 index 0000000..ce84950 --- /dev/null +++ b/www/js/router.js @@ -0,0 +1,74 @@ +/* + * rhwebimport + * + * Copyright (C) 2014-2016 Christian Pointner + * Copyright (C) 2015-2016 Peter Grassberger + * + * This file is part of rhwebimport. + * + * rhwebimport is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * rhwebimport is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with rhwebimport. If not, see . + */ + +'use strict'; + +var auth = null; +var router = null; + +$(document).ready(function() { + auth = new Rdxport.Auth(); + router = new Rdxport.Router(auth); + router.route(); +}); + +Rdxport.Router = function(auth) { + console.log('Router'); + this.auth = auth; + this.authView = new Rdxport.AuthView(this.auth); +}; + +Rdxport.Router.prototype.route = function(page, subpage) { + console.log('route'); + if (!this.auth.isLoggedIn()) { + this.login(); + return; + } + + this.authView.renderLoggedIn(); + + // todo: if previously login form + //$('#username-field').html(auth_fullname + ' (' + auth_username + ')'); + //$('#loginbox').slideUp(); + //$('#mainwindow').fadeIn(); + + // todo: route.. +}; + +Rdxport.Router.prototype.login = function() { + console.log('login'); + this.authView.renderLoginForm(); +}; + +Rdxport.Router.prototype.logout = function() { + console.log('logout'); + if (importer && importer.isUploading()) { + alert('Achtung: Es laufen noch imports.'); + return; + } + + this.auth.cleanup(); + // todo: more cleanup? + //apps_cleanup(); + + this.login(); +}; diff --git a/www/styles/main-style.css b/www/styles/main-style.css index fc7e357..969dcc6 100644 --- a/www/styles/main-style.css +++ b/www/styles/main-style.css @@ -32,6 +32,14 @@ body { width: 100% !important; } +#loginbox, #mainwindow { + display: none; +} + +#app-shows, #app-jingles, #app-musicpools, #app-musicgrid { + display: none; +} + .progress { margin-bottom: 0; } -- cgit v0.10.2 From ee11338a3399a3eb56fa371389218c81ac746058 Mon Sep 17 00:00:00 2001 From: Peter Grassberger Date: Wed, 20 Apr 2016 18:51:41 +0200 Subject: replace apps with router diff --git a/www/index.html b/www/index.html index 9bc89ec..ec7ba8b 100644 --- a/www/index.html +++ b/www/index.html @@ -53,10 +53,10 @@ -
+
@@ -180,7 +180,7 @@
-
+
@@ -189,7 +189,7 @@
-
+
@@ -206,7 +206,7 @@
-
+

Musikgrid

@@ -425,7 +425,6 @@ - diff --git a/www/js/apps.js b/www/js/apps.js deleted file mode 100644 index dd5b337..0000000 --- a/www/js/apps.js +++ /dev/null @@ -1,154 +0,0 @@ -/* - * rhwebimport - * - * Copyright (C) 2014-2016 Christian Pointner - * Copyright (C) 2015-2016 Peter Grassberger - * - * This file is part of rhwebimport. - * - * rhwebimport is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * rhwebimport is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with rhwebimport. If not, see . - */ - -'use strict'; - -var Rdxport = Rdxport || {}; - -var apps_current = null; -var rdxport = null; -var importer = null; - -function apps_select(app) { - if (importer && importer.isUploading()) { - alert('Achtung: Es laufen noch imports.'); - return; - } - - $('.container').removeClass('fullWidth'); - - shows_cleanup(); - jingles_cleanup(); - musicpools_cleanup(); - musicgrid_cleanup(); - - switch(app) { - case "musicgrid": - $('#app-shows').hide(); - $('#nav-btn-shows').removeClass('active'); - $('#app-jingles').hide(); - $('#nav-btn-jingles').removeClass('active'); - $('#app-musicpools').hide(); - $('#nav-btn-musicpools').removeClass('active'); - - $('.container').addClass('fullWidth'); - $('#app-musicgrid').show(); - $('#nav-btn-musicgrid').addClass('active'); - - apps_current = app; - musicgrid_init(); - break; - case "musicpools": - $('#app-shows').hide(); - $('#nav-btn-shows').removeClass('active'); - $('#app-jingles').hide(); - $('#nav-btn-jingles').removeClass('active'); - $('#app-musicgrid').hide(); - $('#nav-btn-musicgrid').removeClass('active'); - - $('#app-musicpools').show(); - $('#nav-btn-musicpools').addClass('active'); - - apps_current = app; - musicpools_init(); - break; - case "jingles": - $('#app-shows').hide(); - $('#nav-btn-shows').removeClass('active'); - $('#app-musicpools').hide(); - $('#nav-btn-musicpools').removeClass('active'); - $('#app-musicgrid').hide(); - $('#nav-btn-musicgrid').removeClass('active'); - - $('#app-jingles').show(); - $('#nav-btn-jingles').addClass('active'); - - apps_current = app; - jingles_init(); - break; - default: - $('#app-jingles').hide(); - $('#nav-btn-jingles').removeClass('active'); - $('#app-musicpools').hide(); - $('#nav-btn-musicpools').removeClass('active'); - $('#app-musicgrid').hide(); - $('#nav-btn-musicgrid').removeClass('active'); - - $('#app-shows').show(); - $('#nav-btn-shows').addClass('active'); - - apps_current = app = 'shows'; - shows_init(); - } - if (locationHrefValue() !== app) { - history.pushState(null, null, '/' + app + '/'); - } -} - -function apps_init() { - importer = new Rdxport.Importer(); - - apps_current = locationHrefValue(); - - if(auth_token && auth_username) { - // todo: do this at a central place - rdxport = new Rdxport.Rdxport(auth_username, auth_token, '/rd-bin/rdxport.cgi'); - rdxport.setListDropboxesEndpoint('/rh-bin/listdropboxes.cgi'); - rdxport.setMusicgridEndpoint('/rh-bin/musicgrid.cgi'); - - apps_select(apps_current); - } - - $(window).on('popstate', function(event) { - if(auth_token && auth_username) { - // todo: do this at a central place - rdxport = new Rdxport.Rdxport(auth_username, auth_token, '/rd-bin/rdxport.cgi'); - rdxport.setListDropboxesEndpoint('/rh-bin/listdropboxes.cgi'); - rdxport.setMusicgridEndpoint('/rh-bin/musicgrid.cgi'); - - apps_select(locationHrefValue()); - } - }); - - $(document).ajaxError(function(event, jqXHR, settings, thrownError) { - //todo: add errors - }); - - window.onbeforeunload = function(e) { - if (importer && importer.isUploading()) { - return 'Achtung: Es laufen noch imports.'; - } - }; -} - -function apps_cleanup() { - shows_cleanup(); - jingles_cleanup(); - musicpools_cleanup(); - musicgrid_cleanup(); - - $(window).off('popstate'); - - importer = null; - rdxport = null; - apps_current = null; -} diff --git a/www/js/auth.js b/www/js/auth.js index c533219..3931022 100644 --- a/www/js/auth.js +++ b/www/js/auth.js @@ -25,19 +25,16 @@ var Rdxport = Rdxport || {}; Rdxport.Auth = function() { - console.log('auth'); this.username = sessionStorage.getItem('auth_username'); this.fullname = sessionStorage.getItem('auth_fullname'); this.token = sessionStorage.getItem('auth_token'); }; Rdxport.Auth.prototype.isLoggedIn = function() { - console.log('isLoggedIn'); return this.username && this.fullname && this.token; }; Rdxport.Auth.prototype.set = function(username, fullname, token) { - console.log('set'); this.username = username; this.fullname = fullname; this.token = token; @@ -48,7 +45,6 @@ Rdxport.Auth.prototype.set = function(username, fullname, token) { }; Rdxport.Auth.prototype.cleanup = function() { - console.log('cleanup'); sessionStorage.removeItem('auth_username'); sessionStorage.removeItem('auth_fullname'); sessionStorage.removeItem('auth_token'); @@ -59,7 +55,6 @@ Rdxport.Auth.prototype.cleanup = function() { }; Rdxport.AuthView = function(model) { - console.log('AuthView'); this.model = model; }; @@ -69,7 +64,7 @@ Rdxport.AuthView.prototype.renderLoggedIn = function() { $('#username-field').html(this.model.fullname + ' (' + this.model.username + ')'); $('button.logout').off().on('click', function() { - router.logout(); + router.route('logout'); }); }; diff --git a/www/js/importer.js b/www/js/importer.js index 4ea55b3..08a49fb 100644 --- a/www/js/importer.js +++ b/www/js/importer.js @@ -258,8 +258,8 @@ Rdxport.Upload.prototype.addCut = function(file) { file.cutNumber = cutNumberLeading; formData.append('COMMAND', 2); - formData.append('LOGIN_NAME', auth_username); - formData.append('PASSWORD', auth_token); + formData.append('LOGIN_NAME', auth.username); + formData.append('PASSWORD', auth.token); formData.append('CART_NUMBER', self.cart.number); formData.append('CUT_NUMBER', cutNumber); formData.append('CHANNELS', 2); diff --git a/www/js/router.js b/www/js/router.js index ce84950..e3ab4e5 100644 --- a/www/js/router.js +++ b/www/js/router.js @@ -24,6 +24,8 @@ var auth = null; var router = null; +var importer = null; +var rdxport = null; $(document).ready(function() { auth = new Rdxport.Auth(); @@ -32,43 +34,136 @@ $(document).ready(function() { }); Rdxport.Router = function(auth) { - console.log('Router'); this.auth = auth; this.authView = new Rdxport.AuthView(this.auth); }; Rdxport.Router.prototype.route = function(page, subpage) { - console.log('route'); if (!this.auth.isLoggedIn()) { this.login(); return; } + if (importer && importer.isUploading()) { + alert('Achtung: Es laufen noch imports.'); + return; + } + + if (!importer) { + importer = new Rdxport.Importer(); + window.onbeforeunload = function(event) { + if (importer.isUploading()) { + return 'Achtung: Es laufen noch imports.'; + } + }; + } + if (!rdxport) { + rdxport = new Rdxport.Rdxport(this.auth.username, this.auth.token, '/rd-bin/rdxport.cgi'); + rdxport.setListDropboxesEndpoint('/rh-bin/listdropboxes.cgi'); + rdxport.setMusicgridEndpoint('/rh-bin/musicgrid.cgi'); + } + + /*$(document).ajaxError(function(event, jqXHR, settings, thrownError) { + //todo: add errors + });*/ + + if (!page && !subpage) { + page = locationHrefValue(); + subpage = ''; + } + + shows_cleanup(); + jingles_cleanup(); + musicpools_cleanup(); + musicgrid_cleanup(); this.authView.renderLoggedIn(); + $('.navbar-nav li').removeClass('active'); + $('.app-tab').hide(); + $('.container').removeClass('fullWidth'); - // todo: if previously login form - //$('#username-field').html(auth_fullname + ' (' + auth_username + ')'); - //$('#loginbox').slideUp(); - //$('#mainwindow').fadeIn(); + var self = this; + $('.navbar-nav li a').off().on('click', function(event) { + event.preventDefault(); + var href = $(this).attr('href').split('/'); + self.route(href[1], href[2]); + }); + $(window).on('popstate', function(event) { + self.route(locationHrefValue(), ''); + }); - // todo: route.. + switch (page) { + default : + page = 'shows'; + // fallthrough + case 'shows': + this.shows(subpage); + break; + case 'jingles': + this.jingles(); + break; + case 'musicpools': + this.musicpools(subpage); + break; + case 'musicgrid': + this.musicgrid(); + break; + case 'logout': + this.logout(); + break; + } + + if (locationHrefValue() !== page && page !== 'logout') { + var url = '/' + page + '/'; + if (subpage) { + url +=+ subpage + '/'; + } + history.pushState(null, null, url); + } }; Rdxport.Router.prototype.login = function() { - console.log('login'); this.authView.renderLoginForm(); }; Rdxport.Router.prototype.logout = function() { - console.log('logout'); if (importer && importer.isUploading()) { alert('Achtung: Es laufen noch imports.'); return; } + shows_cleanup(); + jingles_cleanup(); + musicpools_cleanup(); + musicgrid_cleanup(); this.auth.cleanup(); - // todo: more cleanup? - //apps_cleanup(); + + importer = null; + rdxport = null; this.login(); }; + +Rdxport.Router.prototype.shows = function(subpage) { + $('#app-shows').show(); + $('#nav-btn-shows').addClass('active'); + shows_init(); +}; + +Rdxport.Router.prototype.jingles = function() { + $('#app-jingles').show(); + $('#nav-btn-jingles').addClass('active'); + jingles_init(); +}; + +Rdxport.Router.prototype.musicpools = function(subpage) { + $('#app-musicpools').show(); + $('#nav-btn-musicpools').addClass('active'); + musicpools_init(); +}; + +Rdxport.Router.prototype.musicgrid = function() { + $('.container').addClass('fullWidth'); + $('#app-musicgrid').show(); + $('#nav-btn-musicgrid').addClass('active'); + musicgrid_init(); +}; -- cgit v0.10.2 From 964822ed420618d8fd75cd0843424ead5d6fb159 Mon Sep 17 00:00:00 2001 From: Peter Grassberger Date: Thu, 21 Apr 2016 21:42:17 +0200 Subject: init clock diff --git a/www/js/clock.js b/www/js/clock.js index eb04eed..3562b1e 100644 --- a/www/js/clock.js +++ b/www/js/clock.js @@ -109,12 +109,6 @@ function Clock() { }; } -var clock = new Clock(); - -function clock_init() { - clock.start(); -} - function clock_add_callback(cb) { clock.addCallback(cb); } diff --git a/www/js/router.js b/www/js/router.js index e3ab4e5..62b9a77 100644 --- a/www/js/router.js +++ b/www/js/router.js @@ -22,12 +22,15 @@ 'use strict'; +var clock = null; var auth = null; var router = null; var importer = null; var rdxport = null; $(document).ready(function() { + clock = new Clock(); + clock.start(); auth = new Rdxport.Auth(); router = new Rdxport.Router(auth); router.route(); -- cgit v0.10.2 From 8dd1c416db47a8689fb520db8785d109da6719ff Mon Sep 17 00:00:00 2001 From: Peter Grassberger Date: Fri, 6 May 2016 23:02:07 +0200 Subject: add subpages to router diff --git a/www/js/musicpools.js b/www/js/musicpools.js index 400c0bd..065b4d8 100644 --- a/www/js/musicpools.js +++ b/www/js/musicpools.js @@ -26,9 +26,9 @@ var Rdxport = Rdxport || {}; var musicpoolsView = null; -function musicpools_init() { +function musicpools_init(subpage) { var musicpools = new Rdxport.GroupList(); - musicpoolsView = new Rdxport.MusicpoolsView(musicpools); + musicpoolsView = new Rdxport.MusicpoolsView(musicpools, subpage); } function musicpools_cleanup() { @@ -36,11 +36,13 @@ function musicpools_cleanup() { musicpoolsView = null; } -Rdxport.MusicpoolsView = function(model) { +Rdxport.MusicpoolsView = function(model, subpage) { this.model = model; this.musicpoolViews = []; - this.currentPoolId = sessionStorage.getItem('currentPoolId'); + this.currentPoolId = null; + + this.setCurrentPoolId(subpage); var self = this; $(this.model).on('update', function() { @@ -54,6 +56,16 @@ Rdxport.MusicpoolsView = function(model) { }; Rdxport.MusicpoolsView.prototype.setCurrentPoolId = function(currentPoolId) { + if (!currentPoolId) { + return; + } + if (this.currentPoolId !== currentPoolId) { + if (this.currentPoolId) { + history.pushState(null, null, '/musicpools/' + currentPoolId + '/'); + } else { + history.replaceState(null, null, '/musicpools/' + currentPoolId + '/'); + } + } this.currentPoolId = currentPoolId; sessionStorage.setItem('currentPoolId', this.currentPoolId); }; @@ -91,8 +103,14 @@ Rdxport.MusicpoolsView.prototype.updateSelector = function() { $musicpoolSelector.append($(''); - $tr.append($('
').html(musicpool.clock)); - $tr.append($('').html(musicpool.title)); + $tr.append($('').text(musicpool.clock)); + $tr.append($('').text(musicpool.title)); $tr.append($('').html($button)); $('tbody', $modalBody).append($tr); diff --git a/www/js/musicpools.js b/www/js/musicpools.js index 065b4d8..ac5a07e 100644 --- a/www/js/musicpools.js +++ b/www/js/musicpools.js @@ -154,7 +154,7 @@ Rdxport.MusicpoolView.prototype.render = function() { this.$el = $('#hiddenTemplates .musicpoolTemplate').clone().removeClass('musicpoolTemplate'); $('#app-musicpools .musicpoolContainer').html(this.$el); - $('h2', this.$el).html(this.model.title); + $('h2', this.$el).text(this.model.title); $('table tbody tr', this.$el).remove(); this.cartViews = []; @@ -202,7 +202,7 @@ Rdxport.MusicpoolView.prototype.uploadError = function(upload, file, msg, xhr, a //var msg = $(xmlDoc); //var responseCode = msg.find('ResponseCode').text(); //var errorString = msg.find('ErrorString').text(); - var reason = $('').addClass('label').addClass('label-danger').text(responseCode).after($('').html(' ' + errorString)); + var reason = $('').addClass('label').addClass('label-danger').text(responseCode).after($('').text(' ' + errorString)); var dismiss_button = ''; diff --git a/www/js/shows.js b/www/js/shows.js index bb8058d..9104bec 100644 --- a/www/js/shows.js +++ b/www/js/shows.js @@ -277,7 +277,7 @@ Rdxport.ShowView.prototype.uploadError = function(upload, file, msg, xhr, acknow //var msg = $(xmlDoc); //var responseCode = msg.find('ResponseCode').text(); //var errorString = msg.find('ErrorString').text(); - var reason = $('').addClass('label').addClass('label-danger').text(responseCode).after($('').html(' ' + errorString)); + var reason = $('').addClass('label').addClass('label-danger').text(responseCode).after($('').text(' ' + errorString)); var dismiss_button = ''; -- cgit v0.10.2 From cd9721306a975793fb81dc136e5016f3309bd0de Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Mon, 9 May 2016 19:18:53 +0200 Subject: reverted to original archiv url format after rhimportd finally implementing it correctly diff --git a/README b/README index 9dc98a0..f5ede27 100644 --- a/README +++ b/README @@ -90,3 +90,11 @@ add the following to the virtualhost config: ~~~/snip~~~ # ./build.sh + + +Pflichtenheft +============= + +To generate to PDF from markdown use pandoc + +# pandoc -o Pflichtenheft-Peter.pdf Pflichtenheft-Peter.md diff --git a/contrib/Pflichtenheft-Peter.md b/contrib/Pflichtenheft-Peter.md index 1cbc487..c9bebd8 100644 --- a/contrib/Pflichtenheft-Peter.md +++ b/contrib/Pflichtenheft-Peter.md @@ -59,7 +59,7 @@ Es ist ein Interface zu entwickeln, mit dessen Hilfe die Zuweisung der Musikpool Es soll möglich sein Dateien direkt aus verschiednen exteren Quellen zu importieren. Zu diesem Zweck gibt es serverseitig die Komponente `rhimportd`. Diese wird über eine Websocket-API gesteuert und kümmert sich um den tatsächlichen Import. `rhwebimport` initiiert den Import und visualisiert den Fortschritt. Ausserdem soll es möglich sein den Fortschritt etwaiger laufender Import-Prozesse nach einem erneuten Einloggen (zb. nach einem Verbindungsabbruch) weiter anzuzeigen. `rhimportd` bietet alle dafür notwendigen API Funktionen. Sollten zu diese Zweck Änderungen an der API notwendig sein sollen diese gemeinsam mit dem Radio Helsinki Technik-Team erarbeitet werden. Die Änderungen an `rhimportd` werden von Radio Helsinki erledigt. Folgende externe Quellen sollen unterstützt werden: - - archiv://YYYY/MM/DD/hh - import aus dem Sendungsarchiv von Radio Helsinki (immer volle Stunden) + - archiv://YYYY/MM/DD/hh/mm - import aus dem Sendungsarchiv von Radio Helsinki (derzeit nur für volle Stunden, dh. mm muss immer 00 sein) - http://, https://, ftp://, ftps:// - import von der entsprechenden URL ### zustätliche Importquelle: `public:///` -- cgit v0.10.2 From 1338103170bf4b2b116f0a0134db86459c176f9a Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Wed, 11 May 2016 15:45:09 +0200 Subject: moved to JSON::MaybeXS diff --git a/README b/README index f5ede27..79db43c 100644 --- a/README +++ b/README @@ -31,7 +31,7 @@ LICENSE Installation ============ -# sudo aptitude install apache2 libapache2-mpm-itk libapache2-mod-perl2 libjson-any-perl libxml-quote-perl librhrd-perl libjs-jquery libjs-bootstrap rivendell-server +# sudo aptitude install apache2 libapache2-mpm-itk libapache2-mod-perl2 libjson-maybexs-perl libxml-quote-perl librhrd-perl libjs-jquery libjs-bootstrap rivendell-server # sudo a2enmod ssl authnz_ldap perl proxy_wstunnel # sudo /etc/init.d/apache2 restart diff --git a/rh-bin/authtoken.json b/rh-bin/authtoken.json index 9e4c332..13a73d3 100755 --- a/rh-bin/authtoken.json +++ b/rh-bin/authtoken.json @@ -23,7 +23,7 @@ use strict; use RHRD::rddb; -use JSON; +use JSON::MaybeXS; my $status = 'ERROR'; my $errorstring = 'unknown'; @@ -57,6 +57,8 @@ $answer{'username'} = $username; $answer{'fullname'} = $fullname; $answer{'token'} = $token; +my $j = JSON::MaybeXS->new(utf8 => 0); + print "Content-type: application/json; charset=UTF-8\n"; print "Status: $responsecode\n\n"; -print JSON->new->encode(\%answer); +print $j->encode(\%answer); -- cgit v0.10.2 From 83067ca7cb512cd76db625e5db9d08dd385df8e3 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Thu, 23 Jun 2016 00:05:35 +0200 Subject: sorting show and musicpool names for selector diff --git a/www/js/musicpools.js b/www/js/musicpools.js index ac5a07e..9d21427 100644 --- a/www/js/musicpools.js +++ b/www/js/musicpools.js @@ -98,7 +98,9 @@ Rdxport.MusicpoolsView.prototype.updateSelector = function() { $musicpoolSelector.off(); $('option', $musicpoolSelector).remove(); - $(this.model.groups).each(function(index, musicpool) { + $(this.model.groups).sort(function(a, b) { + return a.title.toLowerCase() >= b.title.toLowerCase() + }).each(function(index, musicpool) { var name = musicpool.title + ' (' + musicpool.clock + ')'; $musicpoolSelector.append($('