From b379f5d6fa95c9c938c38ce592739ea732847821 Mon Sep 17 00:00:00 2001 From: ulrich Date: Sun, 04 Apr 2021 18:08:17 +0000 Subject: [PATCH] Durchstich Neuer Ablageort --- www/ui/data/ablageort.css | 20 + www/ui/data/formulare.css | 145 +++++++++++ src/de/uhilger/mediaz/App.java | 2 www/ui/data/menu/hauptmenue.json | 5 src/de/uhilger/mediaz/api/StoreTestHandler.java | 1 www/ui/js/app.js | 76 +++++ www/ui/index.html | 37 +- src/de/uhilger/mediaz/api/StoreHandler.java | 125 +++++++++ www/ui/data/test.html | 28 ++ src/de/uhilger/mediaz/api/AblageTestHandler.java | 11 src/de/uhilger/mediaz/conf/Store.java | 2 www/ui/app.css | 145 +++++++++++ src/mediaz_de_DE.properties | 1 src/de/uhilger/mediaz/Server.java | 76 ++++- www/ui/data/tpl/form_ablageort.tpl | 13 + www/ui/data/ablageort.html | 43 +++ 16 files changed, 683 insertions(+), 47 deletions(-) diff --git a/src/de/uhilger/mediaz/App.java b/src/de/uhilger/mediaz/App.java index 777c985..351bb27 100644 --- a/src/de/uhilger/mediaz/App.java +++ b/src/de/uhilger/mediaz/App.java @@ -53,7 +53,7 @@ * * @param args Kommandozeilenparameter */ - public static void main(String[] args) { + public static void main(String[] args) throws ClassNotFoundException { rb = ResourceBundle.getBundle(RB_NAME); logger.info(new File(".").getAbsolutePath()); diff --git a/src/de/uhilger/mediaz/Server.java b/src/de/uhilger/mediaz/Server.java index 7fbef25..375d7af 100644 --- a/src/de/uhilger/mediaz/Server.java +++ b/src/de/uhilger/mediaz/Server.java @@ -21,7 +21,11 @@ import de.uhilger.mediaz.api.AblageTestHandler; import de.uhilger.mediaz.api.FileHandler; import de.uhilger.mediaz.api.StopServerHandler; +import de.uhilger.mediaz.api.StoreHandler; import de.uhilger.mediaz.api.StoreTestHandler; +import de.uhilger.mediaz.conf.Store; +import de.uhilger.mediaz.entity.Ablageort; +import de.uhilger.mediaz.entity.ConfigurationElement; import java.io.File; import java.io.IOException; import java.util.logging.Logger; @@ -30,76 +34,83 @@ import java.util.logging.Level; /** - * Die Klasse Server stellt Methoden zur Ausführung eines - * HTTP-Servers bereit - * + * Die Klasse Server stellt Methoden zur Ausführung eines HTTP-Servers + * bereit + * * @author Ulrich Hilger * @version 0.1, 25.03.2021 */ public class Server { - + private static final Logger logger = Logger.getLogger(Server.class.getName()); - + public static final String RB_SERVER_START_MSG = "msgServerStart"; public static final String RB_WEBROOT = "webroot"; + public static final String RB_STORE = "store"; //public static final String RB_UI_ROOT = "uiroot"; public static final String RB_STOP_SERVER = "stopServer"; public static final String RB_ABLAGE_TEST = "testAblage"; public static final String RB_STORE_TEST = "testStore"; public static final String RB_SLASH = "slash"; - + private int port; - + private String ctx; - + /** * Ein neues Objekt der Kalsse Server erzeugen - * @param port der Port, über den dieser Server erreichbar sein soll + * + * @param port der Port, über den dieser Server erreichbar sein soll */ public Server(int port) { this.port = port; } - + /** * Den Port angeben, unter dem der Server erreichbar sein soll - * + * * @param port der Port, unter dem der Server erreichbar sein soll */ public void setPort(int port) { this.port = port; } - + /** - * Den Namen des Kontexts angeben, über den dieser Server - * erreichbar sein soll + * Den Namen des Kontexts angeben, über den dieser Server erreichbar sein + * soll + * * @param ctxName Name des Kontexts, unter dem der Server aufrufbar sein soll */ public void setContextName(String ctxName) { String slash = App.getRs(RB_SLASH); - if(!ctxName.startsWith(slash)) { + if (!ctxName.startsWith(slash)) { this.ctx = slash + ctxName; } else { this.ctx = ctxName; } } - + /** - * Die Endpunkte ('Context'e) einrichten, unter denen die Dienste - * dieses Servers erreichbar sein sollen und den Server starten - * - * @throws IOException wenn etwas schief geht, finden sich Angaben - * in diesem Objekt + * Die Endpunkte ('Context'e) einrichten, unter denen die Dienste dieses + * Servers erreichbar sein sollen und den Server starten + * + * @throws IOException wenn etwas schief geht, finden sich Angaben in diesem + * Objekt + * @throws java.lang.ClassNotFoundException */ - public void start() throws IOException { + public void start() throws IOException, ClassNotFoundException { logger.log(Level.INFO, App.getRs(RB_SERVER_START_MSG), Integer.toString(port)); - + String wwwData = App.getInitParameter(App.getRs(App.RB_AP_WWW_DATA)); File wwwDir = new File(wwwData); //String ui = App.getInitParameter(App.getRs(App.RB_AP_UI)); //File uiDir = new File(ui); HttpServer server = HttpServer.create(new InetSocketAddress(port), 0); - server.createContext(ctx + App.getRs(RB_WEBROOT), new FileHandler(wwwDir.getAbsolutePath())); + server.createContext(ctx + App.getRs(RB_WEBROOT), + new FileHandler(wwwDir.getAbsolutePath())); + ablageorteEinklinken(server); + server.createContext(ctx + App.getRs(RB_STORE), new StoreHandler()); //server.createContext(ctx + App.getRs(RB_UI_ROOT), new FileHandler(uiDir.getAbsolutePath())); server.createContext(ctx + App.getRs(RB_STOP_SERVER), new StopServerHandler()); server.createContext(ctx + App.getRs(RB_ABLAGE_TEST), new AblageTestHandler()); @@ -108,4 +119,21 @@ server.start(); } + private void ablageorteEinklinken(HttpServer server) throws ClassNotFoundException, IOException { + Store store = new Store(); + String conf = App.getInitParameter(App.getRs(App.RB_AP_CONF)); + File ablageortDir = new File(conf, Ablageort.class.getSimpleName()); + File[] orte = ablageortDir.listFiles(); + if (orte != null) { + for (File ort : orte) { + ConfigurationElement elem = store.readFromFile(ort); + if (elem instanceof Ablageort) { + Ablageort ablageort = (Ablageort) elem; + server.createContext(ctx + ablageort.getUrl(), + new FileHandler(new File(ablageort.getOrt()).getAbsolutePath())); + } + } + } + } + } diff --git a/src/de/uhilger/mediaz/api/AblageTestHandler.java b/src/de/uhilger/mediaz/api/AblageTestHandler.java index e43f4c4..b22a6f5 100644 --- a/src/de/uhilger/mediaz/api/AblageTestHandler.java +++ b/src/de/uhilger/mediaz/api/AblageTestHandler.java @@ -21,19 +21,20 @@ @Override public void handle(HttpExchange e) throws IOException { - Ablageort ablage = new Ablageort(); - ablage.setName("Katalog"); - ablage.setOrt("/home/ulrich/Videos"); + Ablageort ablageort = new Ablageort(); + ablageort.setName("Katalog"); + ablageort.setOrt("/home/ulrich/Videos"); + ablageort.setUrl("/media/test"); Gson gson = new Gson(); - File mediaOrdner = new File(ablage.getOrt()); + File mediaOrdner = new File(ablageort.getOrt()); File[] files = mediaOrdner.listFiles(); String json = gson.toJson(files); StringBuilder sb = new StringBuilder(); sb.append(json); - json = gson.toJson(ablage); + json = gson.toJson(ablageort); sb.append(json); byte[] b = sb.toString().getBytes(); diff --git a/src/de/uhilger/mediaz/api/StoreHandler.java b/src/de/uhilger/mediaz/api/StoreHandler.java new file mode 100644 index 0000000..4e317bb --- /dev/null +++ b/src/de/uhilger/mediaz/api/StoreHandler.java @@ -0,0 +1,125 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package de.uhilger.mediaz.api; + +import com.google.gson.Gson; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import de.uhilger.mediaz.App; +import de.uhilger.mediaz.Server; +import de.uhilger.mediaz.conf.Store; +import de.uhilger.mediaz.entity.Ablageort; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.util.logging.Logger; + +/** + * + * @author ulrich + */ +public class StoreHandler extends Store implements HttpHandler { + + private static final Logger logger = Logger.getLogger(StoreHandler.class.getName()); + + + /* + + HTTP GET: lies einen Ablageort und schreibe JSON + HTTP PUT: schreibe einen neuen Ablageort auf die Platte + HTTP POST: schreibe Aenderungen auf die Platte + HTTP DELETE: loesche den Ablageort + + Beispiele: + + HTTP GET an /mz/api/store/Ablageort/Katalog + liest den Ablageort namens "Katalog" + + HTTP POST an /mz/api/store/Ablageort + schreibt den neuen Ablageort im Body der Anfrage + + HTTP PUT an /mz/api/store/Ablageort + sucht den Ablageort mit dem Namen laut Body der Anfrage + und schreibt den Inhalt aus der Anfrage in die Datei + + HTTP DELETE an /mz/api/store/Ablageort/Katalog + löscht den Ablageort namens "Katalog" + + */ + + public static final String HTTP_GET = "GET"; + public static final String HTTP_PUT = "PUT"; + public static final String HTTP_POST = "POST"; + public static final String HTTP_DELETE = "DELETE"; + + @Override + public void handle(HttpExchange e) throws IOException { + String method = e.getRequestMethod(); + String path = e.getRequestURI().toString(); + String[] elems = path.split(App.getRs(Server.RB_SLASH)); + String type = ""; + String elemName = ""; + switch(method) { + case HTTP_GET: + type = elems[elems.length - 2]; + elemName = elems[elems.length - 1]; + //this.readFromFile(file); + break; + + case HTTP_PUT: + type = elems[elems.length - 1]; + elemName = "noch bauen: lesen aus Body"; + break; + + case HTTP_POST: + type = elems[elems.length - 1]; + elemName = bodyLesen(e); + if(type.equalsIgnoreCase("Ablageort")) { + Gson gson = new Gson(); + Ablageort ort = gson.fromJson(elemName, Ablageort.class); + elemName = ort.getName(); + } + break; + + case HTTP_DELETE: + type = elems[elems.length - 2]; + elemName = elems[elems.length - 1]; + break; + } + + + String response = "Method: " + method + ", Path: " + path + + ", Type: " + type + ", elemName: " + elemName; + logger.info(response); + e.sendResponseHeaders(200, response.length()); + OutputStream os = e.getResponseBody(); + os.write(response.getBytes()); + os.close(); + } + + + private String bodyLesen(HttpExchange e) throws IOException { + InputStream is = e.getRequestBody(); + BufferedReader r = new BufferedReader(new InputStreamReader(is)); + StringBuilder sb = new StringBuilder(); + String line = r.readLine(); + while(line != null) { + sb.append(line); + line = r.readLine(); + } + r.close(); + // {"Ablageort":{"name":"test1","ort":"test2","url":"test3"}} + //String data = sb.toString(); + //data = data.substring(1, data.length() - 1); + //String json = data.substring(data.indexOf("{")); + // {"name":"test1","ort":"test2","url":"test3"} + String json = sb.toString(); + logger.info("json: " + json); + return json; + } +} diff --git a/src/de/uhilger/mediaz/api/StoreTestHandler.java b/src/de/uhilger/mediaz/api/StoreTestHandler.java index 8e040a0..e1da7c3 100644 --- a/src/de/uhilger/mediaz/api/StoreTestHandler.java +++ b/src/de/uhilger/mediaz/api/StoreTestHandler.java @@ -30,6 +30,7 @@ Ablageort ort = new Ablageort(); ort.setName("Katalog"); ort.setOrt("/home/ulrich/Videos"); + ort.setUrl("/media/test"); Store store = new Store(); File file = store.writeToFile(ort); try { diff --git a/src/de/uhilger/mediaz/conf/Store.java b/src/de/uhilger/mediaz/conf/Store.java index 546aeee..fcfe3ae 100644 --- a/src/de/uhilger/mediaz/conf/Store.java +++ b/src/de/uhilger/mediaz/conf/Store.java @@ -94,4 +94,6 @@ logger.info(parts[parts.length-2]); return parts[parts.length-2]; } + + } diff --git a/src/mediaz_de_DE.properties b/src/mediaz_de_DE.properties index b8e6f6f..b95252e 100644 --- a/src/mediaz_de_DE.properties +++ b/src/mediaz_de_DE.properties @@ -9,6 +9,7 @@ # HTTP-Endpunkte webroot=/ # uiroot=/ui +store=/api/store stopServer=/api/server/stop testAblage=/api/test/ablage testStore=/api/test/store diff --git a/www/ui/app.css b/www/ui/app.css index 5827ce8..d5bae40 100644 --- a/www/ui/app.css +++ b/www/ui/app.css @@ -117,3 +117,148 @@ font-size: 1.3em; color: #b8b8b8; } + +/* ab hier Mediazentrale */ + +.entity-formular { + display: flex; + flex-flow: column; +} + +.entity-element { + margin: 0.4rem; +} + +/* +@media (min-width: 800px) { + .zentrum-behaelter { + padding: 0 1em 0 1em; + } + .zentrum-behaelter, .nord { + margin: 0 10% 0 10%; + } +} + + +/* von Skeleton */ + +/* Buttons +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +.button, +button, +input[type="submit"], +input[type="reset"], +input[type="button"] { + display: inline-block; + height: 38px; + padding: 0 30px; + color: #555; + text-align: center; + font-size: 11px; + font-weight: 600; + line-height: 38px; + letter-spacing: .1rem; + text-transform: uppercase; + text-decoration: none; + white-space: nowrap; + background-color: transparent; + border-radius: 4px; + border: 1px solid #bbb; + cursor: pointer; + box-sizing: border-box; } +.button:hover, +button:hover, +input[type="submit"]:hover, +input[type="reset"]:hover, +input[type="button"]:hover, +.button:focus, +button:focus, +input[type="submit"]:focus, +input[type="reset"]:focus, +input[type="button"]:focus { + color: #333; + border-color: #888; + outline: 0; } +.button.button-primary, +button.button-primary, +input[type="submit"].button-primary, +input[type="reset"].button-primary, +input[type="button"].button-primary { + color: #FFF; + background-color: #33C3F0; + border-color: #33C3F0; } +.button.button-primary:hover, +button.button-primary:hover, +input[type="submit"].button-primary:hover, +input[type="reset"].button-primary:hover, +input[type="button"].button-primary:hover, +.button.button-primary:focus, +button.button-primary:focus, +input[type="submit"].button-primary:focus, +input[type="reset"].button-primary:focus, +input[type="button"].button-primary:focus { + color: #FFF; + background-color: #1EAEDB; + border-color: #1EAEDB; } + + +/* Forms +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +input[type="email"], +input[type="number"], +input[type="search"], +input[type="text"], +input[type="tel"], +input[type="url"], +input[type="password"], +textarea, +select { + height: 38px; + padding: 6px 10px; /* The 6px vertically centers text on FF, ignored by Webkit */ + background-color: #fff; + border: 1px solid #D1D1D1; + border-radius: 4px; + box-shadow: none; + box-sizing: border-box; } +/* Removes awkward default styles on some inputs for iOS */ +input[type="email"], +input[type="number"], +input[type="search"], +input[type="text"], +input[type="tel"], +input[type="url"], +input[type="password"], +textarea { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; } +textarea { + min-height: 65px; + padding-top: 6px; + padding-bottom: 6px; } +input[type="email"]:focus, +input[type="number"]:focus, +input[type="search"]:focus, +input[type="text"]:focus, +input[type="tel"]:focus, +input[type="url"]:focus, +input[type="password"]:focus, +textarea:focus, +select:focus { + border: 1px solid #33C3F0; + outline: 0; } +label, +legend { + display: block; + margin-bottom: .5rem; + font-weight: 600; } +fieldset { + padding: 0; + border-width: 0; } +input[type="checkbox"], +input[type="radio"] { + display: inline; } +label > .label-body { + display: inline-block; + margin-left: .5rem; + font-weight: normal; } diff --git a/www/ui/data/ablageort.css b/www/ui/data/ablageort.css new file mode 100644 index 0000000..923d8ab --- /dev/null +++ b/www/ui/data/ablageort.css @@ -0,0 +1,20 @@ +/* +To change this license header, choose License Headers in Project Properties. +To change this template file, choose Tools | Templates +and open the template in the editor. +*/ +/* + Created on : 04.04.2021, 17:02:13 + Author : ulrich +*/ + + + +.entity-formular { + display: flex; + flex-flow: column; +} + +.entity-element { + margin: 0.4rem; +} \ No newline at end of file diff --git a/www/ui/data/ablageort.html b/www/ui/data/ablageort.html new file mode 100644 index 0000000..34ee44d --- /dev/null +++ b/www/ui/data/ablageort.html @@ -0,0 +1,43 @@ +<!DOCTYPE html> +<!-- + Mediazentrale - Personal Media Center + Copyright (C) 2021 Ulrich Hilger + + This program 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 (at your option) any later version. + + This program 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 this program. If not, see <https://www.gnu.org/licenses/>. +--> +<html> + <head> + <title>Ablageort</title> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <link rel="stylesheet" type="text/css" href="../app.css"> + <link rel="stylesheet" type="text/css" href="formulare.css"> + <link rel="stylesheet" type="text/css" href="ablageort.css"> + + </head> + <body> + <div class="entity-formular"> + Ablageort + + <input class="entity-element" type="text" id="ablageort-name" placeholder="Name" > + <input class="entity-element" type="text" id="ablageort-ort" placeholder="Pfad" > + <input class="entity-element" type="text" id="ablageort-url" placeholder="URL" > + <div class="entity-buttons"> + <button class="button-primary" id="ok-btn">Speichern</button> + <button class="button" id="cancel-btn">Abbrechen</button> + </div> + + </div> + </body> +</html> diff --git a/www/ui/data/formulare.css b/www/ui/data/formulare.css new file mode 100644 index 0000000..a4c677c --- /dev/null +++ b/www/ui/data/formulare.css @@ -0,0 +1,145 @@ +/* +To change this license header, choose License Headers in Project Properties. +To change this template file, choose Tools | Templates +and open the template in the editor. +*/ +/* + Created on : 04.04.2021, 17:05:29 + Author : ulrich +*/ + + + +@media (min-width: 800px) { + .zentrum-behaelter { + padding: 0 1em 0 1em; + } + .zentrum-behaelter, .nord { + margin: 0 10% 0 10%; + } +} + + + +/* von Skeleton */ + +/* Buttons +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +.button, +button, +input[type="submit"], +input[type="reset"], +input[type="button"] { + display: inline-block; + height: 38px; + padding: 0 30px; + color: #555; + text-align: center; + font-size: 11px; + font-weight: 600; + line-height: 38px; + letter-spacing: .1rem; + text-transform: uppercase; + text-decoration: none; + white-space: nowrap; + background-color: transparent; + border-radius: 4px; + border: 1px solid #bbb; + cursor: pointer; + box-sizing: border-box; } +.button:hover, +button:hover, +input[type="submit"]:hover, +input[type="reset"]:hover, +input[type="button"]:hover, +.button:focus, +button:focus, +input[type="submit"]:focus, +input[type="reset"]:focus, +input[type="button"]:focus { + color: #333; + border-color: #888; + outline: 0; } +.button.button-primary, +button.button-primary, +input[type="submit"].button-primary, +input[type="reset"].button-primary, +input[type="button"].button-primary { + color: #FFF; + background-color: #33C3F0; + border-color: #33C3F0; } +.button.button-primary:hover, +button.button-primary:hover, +input[type="submit"].button-primary:hover, +input[type="reset"].button-primary:hover, +input[type="button"].button-primary:hover, +.button.button-primary:focus, +button.button-primary:focus, +input[type="submit"].button-primary:focus, +input[type="reset"].button-primary:focus, +input[type="button"].button-primary:focus { + color: #FFF; + background-color: #1EAEDB; + border-color: #1EAEDB; } + + +/* Forms +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +input[type="email"], +input[type="number"], +input[type="search"], +input[type="text"], +input[type="tel"], +input[type="url"], +input[type="password"], +textarea, +select { + height: 38px; + padding: 6px 10px; /* The 6px vertically centers text on FF, ignored by Webkit */ + background-color: #fff; + border: 1px solid #D1D1D1; + border-radius: 4px; + box-shadow: none; + box-sizing: border-box; } +/* Removes awkward default styles on some inputs for iOS */ +input[type="email"], +input[type="number"], +input[type="search"], +input[type="text"], +input[type="tel"], +input[type="url"], +input[type="password"], +textarea { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; } +textarea { + min-height: 65px; + padding-top: 6px; + padding-bottom: 6px; } +input[type="email"]:focus, +input[type="number"]:focus, +input[type="search"]:focus, +input[type="text"]:focus, +input[type="tel"]:focus, +input[type="url"]:focus, +input[type="password"]:focus, +textarea:focus, +select:focus { + border: 1px solid #33C3F0; + outline: 0; } +label, +legend { + display: block; + margin-bottom: .5rem; + font-weight: 600; } +fieldset { + padding: 0; + border-width: 0; } +input[type="checkbox"], +input[type="radio"] { + display: inline; } +label > .label-body { + display: inline-block; + margin-left: .5rem; + font-weight: normal; } diff --git a/www/ui/data/menu/hauptmenue.json b/www/ui/data/menu/hauptmenue.json index b0685f0..44f268a 100644 --- a/www/ui/data/menu/hauptmenue.json +++ b/www/ui/data/menu/hauptmenue.json @@ -8,6 +8,11 @@ }, "inhalt": [ { + "titel": "Neuer Ablageort", + "umenue": false, + "funktion": "app.form_ablageort_neu" + }, + { "titel": "Seite umschalten", "umenue": false, "funktion": "app.seitenleiste_umschalten" diff --git a/www/ui/data/test.html b/www/ui/data/test.html new file mode 100644 index 0000000..00949d9 --- /dev/null +++ b/www/ui/data/test.html @@ -0,0 +1,28 @@ +<!DOCTYPE html> +<!-- + Mediazentrale - Personal Media Center + Copyright (C) 2021 Ulrich Hilger + + This program 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 (at your option) any later version. + + This program 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 this program. If not, see <https://www.gnu.org/licenses/>. +--> +<html> + <head> + <title>TODO supply a title</title> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + </head> + <body> + <div>TODO write content</div> + </body> +</html> diff --git a/www/ui/data/tpl/form_ablageort.tpl b/www/ui/data/tpl/form_ablageort.tpl new file mode 100644 index 0000000..d6132bf --- /dev/null +++ b/www/ui/data/tpl/form_ablageort.tpl @@ -0,0 +1,13 @@ + <div class="entity-formular"> + Ablageort + + <input class="entity-element" type="text" id="ablageort-name" placeholder="Name" /> + <input class="entity-element" type="text" id="ablageort-ort" placeholder="Pfad" /> + <input class="entity-element" type="text" id="ablageort-url" placeholder="URL" /> + <div class="entity-buttons"> + <button class="button-primary" id="ok-btn">Speichern</button> + <button class="button" id="cancel-btn">Abbrechen</button> + </div> + + </div> + diff --git a/www/ui/index.html b/www/ui/index.html index d206386..2a2f3df 100644 --- a/www/ui/index.html +++ b/www/ui/index.html @@ -1,7 +1,24 @@ <!DOCTYPE html> +<!-- + Mediazentrale - Personal Media Center + Copyright (C) 2021 Ulrich Hilger + + This program 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 (at your option) any later version. + + This program 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 this program. If not, see <https://www.gnu.org/licenses/>. +--> <html> <head> - <title>App-Vorlage</title> + <title>Mediazentrale</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="apple-mobile-web-app-capable" content="yes" /> @@ -21,7 +38,7 @@ </div> </div> <div class="app-titel"> - <span id="app-titel">App-Vorlage</span> + <span id="app-titel">Mediazentrale</span> </div> </div> <div class="inhalt"> @@ -36,19 +53,7 @@ <div class="zentrum"> <div class="zentraler-inhalt"> <p> - Hier kann beliebiger Inhalt erscheinen. - </p> - <p> - Wenn dessen Darstellung mehr - Platz benötigt als das Anzeigegerät bietet wird ein - Rollbalken eingeblendet. Beim Rollen zu anfangs nicht sichtbaren - Teilen des Inhalts bleiben die den Inhaltsbereich - umschließenden Elemente sichtbar. - </p> - <p> - Ein Klick auf das Hamburger-Piktogramm oben links bzw. dessen - Antippen blendet ein Menü ein von dem aus weitere Funktionen - ausgelöst werden können. + Hier erschient der Media-Inhalt. </p> </div> </div> @@ -70,7 +75,7 @@ <script> var app; document.addEventListener('DOMContentLoaded', function () { - app = new AppVorlage(); + app = new Mediazentrale(); app.init(); }); </script> diff --git a/www/ui/js/app.js b/www/ui/js/app.js index 4eaffef..f7cd6be 100644 --- a/www/ui/js/app.js +++ b/www/ui/js/app.js @@ -1,10 +1,84 @@ -function AppVorlage() { +function Ablageort(n, o, u) { + this.name = n; + this.ort = o; + this.url = u; +} + + + +function Mediazentrale() { var self = this; var appMenu; // var vorlagen; var cache; // mustache templates + + this.form_ablageort_neu = function() { + self.vorlage_laden_und_fuellen("data/tpl/form_ablageort.tpl", "", function(html) { + document.querySelector(".zentraler-inhalt").innerHTML = html; + self.addEvtListener('#ok-btn', 'click', function() { + // hier neuen Ablageort speichern + var a = new Ablageort( + document.querySelector('#ablageort-name').value, + document.querySelector('#ablageort-ort').value, + document.querySelector('#ablageort-url').value + ); + // {"name":"Katalog","ort":"/home/ulrich/Videos","url":"/media/test"} + //var daten = self.serialisieren(a); + var daten = JSON.stringify(a); + self.http_post('../api/store/Ablageort', daten, function(){ + // hier die Antwort verarbeiten + }); + }); + self.addEvtListener('#cancel-btn', 'click', function() { + // hier die Aktion abbrechen + }); + }); + }; + + this.addEvtListener = function(selector, eventName, func) { + var elems = document.querySelectorAll(selector); + var index; + for (index = 0; index < elems.length; index++) { + elems[index].addEventListener(eventName, func); + } + }; + + this.http_get = function(u, cb) { + self.http_call('GET', u, null, cb); + }; + + this.http_post = function(u, data, cb) { + self.http_call('POST', u, data, cb); + }; + + this.http_call = function (method, u, data, scallback) { + var xhr = new XMLHttpRequest(); + var url = u; + xhr.onreadystatechange = function() { + if (this.readyState === 4 && this.status === 200) { + scallback(this.responseText); + } + }; + xhr.open(method, url); + if(method === 'GET') { + xhr.send(); + } else if(method === 'POST' || method === 'PUT') { + xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); + xhr.send(data); + } + }; + + this.serialisieren = function(obj) { + return '{"' + obj.constructor.name + '":' + JSON.stringify(obj) + '}'; + }; + + + + + /* ab hier aus App-Vorlage */ + this.init = function() { //self.vorlagen = new Vorlagen(); self.cache = new Array(); -- Gitblit v1.9.3