ulrich
2020-05-30 fcdfa744b5eb262e70560d7c6bf539968b703b62
commit | author | age
5a822d 1 /*
U 2   Aufzeichnungsplaner
3   Copyright (C) 2020  Ulrich Hilger, https://uhilger.de
4
5   This program is free software: you can redistribute it and/or modify
6   it under the terms of the GNU Affero General Public License as published by
7   the Free Software Foundation, either version 3 of the License, or
8   (at your option) any later version.
9
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU Affero General Public License for more details.
14
15   You should have received a copy of the GNU Affero General Public License
16   along with this program.  If not, see <https://www.gnu.org/licenses/>.
17 */
18
19 function App() {
20   var self = this;
21   var wochentag;
22   var mone;
23   var channels;
24   var outPath;
25
26   /**
27    * Den Aufnahmeplaner initialisieren
28    */
29   this.init = function () {
30     self.wochentag = ['Sonntag','Montag','Dienstag','Mittwoch',
31       'Donnerstag','Freitag','Samstag' ];
32     
33     // Monatskuerzel in englisch fuer den 'at'-Befehl
34     self.mone = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 
35       'jul', 'aug', 'sep', 'oct', 'nov', 'dec'];
36     
37     /*
38      * die folgenden Konstanten koennten auch ueber eine Konfigurationsdatei
39      * oder eine API vom Server bereitgestellt werden
40      */
41     self.channels = "/media/extssd/mc/channels.conf";
fcdfa7 42     self.outPath = "/opt/tv/";
5a822d 43     
U 44     self.channelsLesen();
45     
46     // Bedienelemente an Programmlogik binden
47     var elem = self.elementAnbinden("startdatum");
48     elem.valueAsDate = new Date();   
49     self.elementAnbinden("bez");
50     self.elementAnbinden("startzeit");    
51     self.elementAnbinden("dauer");
52     self.elementAnbinden("sender");
53     
54     /*
55      * initial die Einstellungen einsammeln und 
56      *  an der Bedienoberflaeche zeigen
57      */
58     self.collectSettings();
59   };
60   
61   /**
62    * Ein Element aus dem Document Object Model (DOM) an das Eingabe-Ereignis 
63    * (oninput) binden um auf diese Weise dessen geaenderten Inhalt in die 
64    * Ausgabe des Infotextes zu uebernehmen
65    * 
66    * @param {type} ename  name des anzubindenden Elements
67    * @returns {elem|Element}  das angebundene Element
68    */
69   this.elementAnbinden = function(ename) {
70     elem = document.getElementById(ename);
71     elem.oninput = self.collectSettings;
72     return elem;
73   };
74   
75   /*
76    * collectSettings nimmt die aktuellen Einstellungen aus den Eingabeelementen 
77    * und bildet eine Textausgabe aller aktuell eingegebenen Parameter 
78    * sowie das Kommando fuer gnutv und gibt diese in den Elementen 
79    * 'info' und 'cmd' aus.
80    */
81   this.collectSettings = function() {
82     // das Startdatum bestimmen und in den Infotext uebernehmen
83     var start = self.getStart();   
84     var infotext = "<br>Start: " + self.wochentag[start.getDay()] + ", " 
85             + self.datumZuDatumText(start) 
86             + ", " + self.zeitZuText(start, ":") + " Uhr";
87     
88     // den Endezeitpunkt bestimmen und in den Infotext uebernehmen
89     var ende = self.getEnde();
90     var endzeit = self.wochentag[ende.getDay()] + ", " 
91             + self.datumZuDatumText(ende) + ", " 
92             + self.zeitZuText(ende, ":");
93     infotext = infotext + "<br>Ende: " + endzeit + " Uhr";
94     
95     // die Dauer in Sekunden sowie in Minuten bestimmen und dem Infotext anfuegen
96     var dauerSekunden = document.getElementById("dauer").value;
97     infotext = infotext + "<br>Dauer: " + dauerSekunden / 60 + " Minuten" 
98             + " (" + dauerSekunden + " Sekunden)";    
99     
100     /*
101      * Die eingegebene Bezeichnung fuer die Aufnahme bestimmen und um 
102      * Startdatum, -zeit und Sender ergaenzen und das Ganze in den Infotext
103      * uebernehmen
104      * Es wird '.ts' fuer 'transport stream' angefuegt, wenn keine 
105      * Dateierweiterung in der Bezeichnung angegeben ist. Bei DVB wird der 
106      * Inhalt ueblicherweise als 'transport stream' bezeichnet.
107      */
108     var bez = document.getElementById("bez").value;
109     var dotpos = bez.indexOf(".");
110     var fname = self.outPath;
111     var sender = document.getElementById("sender").value;
112     if(dotpos > -1) {
113       fname = fname + bez.substring(0, dotpos) + "-" + self.fts(start) + "-" 
114               + sender + bez.substring(dotpos);
115     } else {
116       fname = fname + bez + "-" + self.fts(start) + "-" + sender + ".ts";
117     }
118     infotext = infotext + "<br>" + fname; 
119     
120     // den Infotext im DOM-Element 'info' anzeigen
121     document.getElementById("info").innerHTML = infotext;
122     
123     /*
124      * im DOM-Element 'cmd' wird der Befehl zusammengstellt und angezeigt 
125      * wie er fuer die Programmierung einer Aufzeichnung mit Hilfe von 
126      * gnutv und at benoetigt wird.
127      *
128      * Beispiel:
129      * echo "gnutv -channels /media/extssd/mc/channels.conf 
130      * -out file /home/fred/work/test-2020-02-01-1050-arteHD.ts 
131      * -timeout 300 arteHD" | at 1050 feb 01
132      */
133     document.getElementById("cmd").innerHTML = 'echo "gnutv -channels ' 
134             + self.channels + ' -out file ' 
135             + fname + ' -timeout ' + dauerSekunden + ' ' + sender 
136             + '" | at ' + self.zeitZuText(start) + ' ' 
137             + self.mone[start.getMonth()] + ' ' + start.getDate();
138   };
139   
140   /*
141    * getEnde fuegt dem Startzeitpunkt aus getStart() die Dauer hinzu 
142    * und bildet so den Endzeitpunkt, der als Datumsobjekt zurueckgegeben wird  
143    */
144   this.getEnde = function() {
145     var endeZeitpunkt = self.getStart();
146     endeZeitpunkt.setMilliseconds(endeZeitpunkt.getMilliseconds() 
147             + (document.getElementById("dauer").value * 1000));
148     return endeZeitpunkt;
149   };
150   
151   /*
152    * getStart setzt aus dem Datumseingabefeld und dem Schieberegler fuer die 
153    * Startzeit den Startzeitpunkt zusammen und gibt diesen als Datumsobjekt
154    * zurueck
155    * 
156    * Wenn das Datumseingabefeld kein Datum enthaelt, wird das heutige Datum 
157    * mit der Zeit des Schiebereglers kombiniert.
158    */  
159   this.getStart = function() {
160     var startdatum = document.getElementById("startdatum").valueAsDate;
161     startdatum.setHours(0);
162     startdatum.setMilliseconds(startdatum.getMilliseconds() 
163             + (document.getElementById("startzeit").value * 1000));
164     return startdatum;
165   };
166
167   /*
168    * Die Sender aus der Datei channels.conf lesen und in eine 
169    * HTML-Auswahlliste ueberfuehren
170    */
171   this.channelsLesen = function() {
172     var url = 'channels.conf';
173     self.http_get(url, function (antwort) {      
174       var zeilen = antwort.split("\n");
175       zeilen.sort();
176       var senderAuswahl = document.getElementById("sender");
177       var sender;
178       for(var i = 0; i < zeilen.length; i++) {
179         sender = document.createElement("option");
180         sender.textContent = zeilen[i].split(":")[0];
181         senderAuswahl.appendChild(sender);
182       }      
183     });
184   };
185   
186   /**
187    * Die Funktion http_get ruft einen Inhalt ueber HTTP GET ab 
188    * 
189    * @param {type} url der aufzurufende URL
190    * @param {type} process  die Funktion, der die Antwort uebergeben 
191    * werden soll
192    */
193   this.http_get = function (url, process) {    
194     var xmlhttp = new XMLHttpRequest();
195     xmlhttp.onreadystatechange = function() {
196       if (this.readyState == 4 && this.status == 200) {
197         process(this.responseText);
198       }
199     };
200     xmlhttp.open("GET", url, true);
201     xmlhttp.send();
202   };
203
204   /* -----------------------------------------------------------------------
205    * Nachfolgend einige Hilfsfunktionen zur Umwandlung von Datum-Objekten 
206    * zu Text.
207    * 
208    * Solche Funktionen gibt es auch fertig in Bibliotheken wie 
209    * z.B. Moment.js. Hier werden allerdings nur wenige solche 
210    * Funktionen benoetigt so dass sich die zusaetzliche 
211    * Abhaengigkeit nicht lohnt, die mit der Verwendung der Bibliothek 
212    * entstuende.
213    * ---------------------------------------------------------------------- */
214   
215   /*
216    * Aus einem Datums-Objekt einen Text im Format JJJJ-MM-TT machen
217    */
218   this.datumZuText = function(datum) {
219     var tag = self.textZweistellig(datum.getDate());
220     var monat = self.textZweistellig(datum.getMonth() + 1);
221     var jahr = datum.getFullYear();
222     return jahr + "-" + monat + "-" + tag;
223   };
224   
225   /*
226    * Aus einem Datums-Objekt einen Text im Format TT.MM.JJJJ machen
227    */
228   this.datumZuDatumText = function(datum) {
229     var tag = self.textZweistellig(datum.getDate());
230     var monat = self.textZweistellig(datum.getMonth() + 1);
231     var jahr = datum.getFullYear();
232     return tag + "." + monat + "." + jahr;
233   };
234   
235   /*
236    * Aus einem Datums-Objekt einen Text im Format SS:MM machen
237    * 
238    * Das Trennzeichen, z.B. ":" kann im Parameter trennzeichen 
239    * uebergeben werden. trennzeichen darf auch leer bleiben.
240    */
241   this.zeitZuText = function(datum, trennzeichen) {
242     var std = self.textZweistellig(datum.getHours());
243     var min = self.textZweistellig(datum.getMinutes());
244     if(trennzeichen) {
245       return std + trennzeichen + min;
246     } else {
247       return std + "" + min;
248     }
249   };
250   
251   /*
252    * Aus einer Zahl einen Text machen und dabei einstellige 
253    * Werte mit einer Null auffuellen
254    */
255   this.textZweistellig = function(zahl) {
256     if(zahl < 10) {
257       return "0" + zahl;
258     } else {
259       return zahl;
260     }
261   };
262   
263   /**
264    * Aus einem Datum den Textausdruck JJJJ-MM-TT-hhmm machen
265    * (fts: file name timestamp)
266    * 
267    * @param {type} datum   das Datumsobjekt aus dem der Text gemacht werden soll
268    * @returns {String} der Text im Format JJJJ-MM-TT-hhmm
269    */
270   this.fts = function(datum) {
271     return self.datumZuText(datum) + "-" + self.zeitZuText(datum);
272   };  
273 }