Persoenliche Mediazentrale
ulrich
2021-04-05 a43e1a055018aab9590c88c45d8495f99bfb6254
Ablageort-Liste
3 files added
10 files modified
181 ■■■■ changed files
src/de/uhilger/mediaz/api/StorageHandler.java 15 ●●●● patch | view | raw | blame | history
src/de/uhilger/mediaz/entity/Ablageort.java 18 ●●●● patch | view | raw | blame | history
src/de/uhilger/mediaz/store/FileStorage.java 4 ●●●● patch | view | raw | blame | history
src/de/uhilger/mediaz/store/Storage.java 17 ●●●●● patch | view | raw | blame | history
www/ui/app.css 11 ●●●●● patch | view | raw | blame | history
www/ui/data/ablageort.css 11 ●●●●● patch | view | raw | blame | history
www/ui/data/ablageort.html 17 ●●●●● patch | view | raw | blame | history
www/ui/data/ablageort_liste.html 43 ●●●●● patch | view | raw | blame | history
www/ui/data/menu/hauptmenue.json 7 ●●●● patch | view | raw | blame | history
www/ui/data/tpl/ablageort_liste.tpl 15 ●●●●● patch | view | raw | blame | history
www/ui/index.html 2 ●●● patch | view | raw | blame | history
www/ui/js/app.js 20 ●●●● patch | view | raw | blame | history
www/ui/js/mustache/mustache.min.js 1 ●●●● patch | view | raw | blame | history
src/de/uhilger/mediaz/api/StorageHandler.java
@@ -18,6 +18,7 @@
package de.uhilger.mediaz.api;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import de.uhilger.mediaz.App;
@@ -169,8 +170,7 @@
      String type = elems[elems.length - 1];
      logger.info(type);
      List list = fs.list(type);
      Gson gson = new Gson();
      return gson.toJson(list);
      return jsonWithEnclosingType(list);
    } else {
      String type = elems[elems.length - 2];
      String elemName = elems[elems.length - 1];
@@ -178,6 +178,17 @@
    }
  }
  
  private String jsonWithEnclosingType(Object o) {
    StringBuilder sb = new StringBuilder();
    sb.append("{\"");
    sb.append(o.getClass().getSimpleName());
    sb.append("\": ");
    Gson gson = new Gson();
    sb.append(gson.toJson(o));
    sb.append("}");
    return sb.toString();
  }
  
  private String bodyLesen(HttpExchange e) throws IOException {
    InputStream is = e.getRequestBody();
src/de/uhilger/mediaz/entity/Ablageort.java
@@ -1,7 +1,19 @@
/*
 * 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.
  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/>.
 */
package de.uhilger.mediaz.entity;
src/de/uhilger/mediaz/store/FileStorage.java
@@ -147,6 +147,8 @@
    File[] files = dir.listFiles();
    List<String> list = new ArrayList();
    for(File file : files) {
      //NamedItem n = new NamedItem();
      //n.setLabel(file.getName());
      list.add(file.getName());
    }
    return list;
@@ -182,7 +184,5 @@
      return false;
    }
  }
  
}
src/de/uhilger/mediaz/store/Storage.java
@@ -66,6 +66,12 @@
   */
  public Entity read(String typ, String name);
  
  /**
   * Ein Objekt als JSON lesen
   * @param typ
   * @param name
   * @return das gewuenschte Objekt als JSON
   */
  public String readJson(String typ, String name);
  
  /**
@@ -75,7 +81,18 @@
   */
  public List<String> list(String typ);
  
  /**
   * Fuer einen gegebenen Namen den Typ bestimmen
   * @param name  der Name des gewuenschten Typs
   * @return der Typ zum Namen
   */
  public TypeToken typeFromName(String name);
  
  /**
   * Ein Objekt aus der Ablage loeschen
   * @param typ  Objekttyp
   * @param name  Name des Objekts, das geloscht werden soll
   * @return true, wenn geloeschn, false wenn nicht
   */
  public boolean delete(String typ, String name);
}
www/ui/app.css
@@ -129,6 +129,17 @@
  margin: 0.4rem;
}
.entity-liste {
  list-style-type: none;
}
.entity-eintrag {
  margin-top: 0.8rem;
  margin-left: 0;
  margin-right: 0;
  margin-bottom: 0;
}
/*
@media (min-width: 800px) {
  .zentrum-behaelter {
www/ui/data/ablageort.css
@@ -17,4 +17,15 @@
.entity-element {
  margin: 0.4rem;
}
.entity-liste {
  list-style-type: none;
}
.entity-eintrag {
  margin-top: 0.8rem;
  margin-left: 0;
  margin-right: 0;
  margin-bottom: 0;
}
www/ui/data/ablageort.html
@@ -18,7 +18,7 @@
-->
<html>
  <head>
    <title>Ablageort</title>
    <title>Ablageorte</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">
@@ -28,16 +28,11 @@
  </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>
      Ablageorte
      <ul class="entity-liste">
        <li class="entity-eintrag">Katalog</li>
        <li class="entity-eintrag">Katalog2</li>
      </ul>
    </div>
  </body>
</html>
www/ui/data/ablageort_liste.html
New file
@@ -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>
www/ui/data/menu/hauptmenue.json
@@ -8,9 +8,14 @@
    },
    "inhalt":  [
      {
        "titel": "Ablageorte",
        "umenue": false,
        "funktion": "app.ablageort_liste"
      },
      {
        "titel": "Neuer Ablageort",
        "umenue": false,
        "funktion": "app.form_ablageort_neu"
        "funktion": "app.ablageort_neu"
      },
      {
        "titel": "Seite umschalten",
www/ui/data/tpl/ablageort_liste.tpl
New file
@@ -0,0 +1,15 @@
<div class='entity-formular'>
  Ablageorte
  <ul class='entity-liste'>
    {{#ArrayList}}
    <li class='entity-eintrag'>{{.}}</li>
    {{/ArrayList}}
  </ul>
</div>
www/ui/index.html
@@ -68,7 +68,7 @@
      Fußzeile
    </div>
    <!-- Skripte -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/2.3.0/mustache.min.js"></script>
    <script src="js/mustache/mustache.min.js"></script>
    <script src="js/app-menu.js"></script>
    <!-- <script src="js/vorlagen.js"></script> -->
    <script src="js/app.js"></script>
www/ui/js/app.js
@@ -12,9 +12,19 @@
  // var vorlagen;
  var cache; // mustache templates
  this.ablageort_liste = function() {
    self.http_get('../api/store/Ablageort/', function (responseText) {
      self.vorlage_laden_und_fuellen("data/tpl/ablageort_liste.tpl", JSON.parse(responseText), function (html) {
        document.querySelector(".zentraler-inhalt").innerHTML = html;
        self.addEvtListener('.entity-eintrag', 'click', function (event) {
          var t = event.target;
          self.meldung_mit_timeout(t.textContent, 1500);
        });
      });
    });
  };
  this.form_ablageort_neu = function () {
  this.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 () {
@@ -26,7 +36,7 @@
        );
        // {"name":"Katalog","ort":"/home/ulrich/Videos","url":"/media/test"}
        var daten = JSON.stringify(a);
        self.http_post('../api/store/Ablageort', daten, function () {
        self.http_post('../api/store/Ablageort', daten, function (responseText) {
          // hier die Antwort verarbeiten
        });
      });
@@ -159,6 +169,8 @@
  this.meldung_mit_timeout = function (meldung, timeout) {
    var s = document.querySelector('.sued');
    s.classList.add('sued-open');
    s.style.height = '1.5em';
    s.textContent = meldung;
    setTimeout(function () {
      s.textContent = 'Bereit.';
@@ -245,6 +257,8 @@
  };
  this.vorlage_fuellen = function (vurl, inhalt, cb) {
    //console.log("vorlage " + self.cache[vurl]);
    //console.log("render " + inhalt);
    cb(Mustache.render(self.cache[vurl], inhalt));
  };
www/ui/js/mustache/mustache.min.js
New file
@@ -0,0 +1 @@
(function defineMustache(global,factory){if(typeof exports==="object"&&exports&&typeof exports.nodeName!=="string"){factory(exports)}else if(typeof define==="function"&&define.amd){define(["exports"],factory)}else{global.Mustache={};factory(global.Mustache)}})(this,function mustacheFactory(mustache){var objectToString=Object.prototype.toString;var isArray=Array.isArray||function isArrayPolyfill(object){return objectToString.call(object)==="[object Array]"};function isFunction(object){return typeof object==="function"}function typeStr(obj){return isArray(obj)?"array":typeof obj}function escapeRegExp(string){return string.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")}function hasProperty(obj,propName){return obj!=null&&typeof obj==="object"&&propName in obj}var regExpTest=RegExp.prototype.test;function testRegExp(re,string){return regExpTest.call(re,string)}var nonSpaceRe=/\S/;function isWhitespace(string){return!testRegExp(nonSpaceRe,string)}var entityMap={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;","/":"&#x2F;","`":"&#x60;","=":"&#x3D;"};function escapeHtml(string){return String(string).replace(/[&<>"'`=\/]/g,function fromEntityMap(s){return entityMap[s]})}var whiteRe=/\s*/;var spaceRe=/\s+/;var equalsRe=/\s*=/;var curlyRe=/\s*\}/;var tagRe=/#|\^|\/|>|\{|&|=|!/;function parseTemplate(template,tags){if(!template)return[];var sections=[];var tokens=[];var spaces=[];var hasTag=false;var nonSpace=false;function stripSpace(){if(hasTag&&!nonSpace){while(spaces.length)delete tokens[spaces.pop()]}else{spaces=[]}hasTag=false;nonSpace=false}var openingTagRe,closingTagRe,closingCurlyRe;function compileTags(tagsToCompile){if(typeof tagsToCompile==="string")tagsToCompile=tagsToCompile.split(spaceRe,2);if(!isArray(tagsToCompile)||tagsToCompile.length!==2)throw new Error("Invalid tags: "+tagsToCompile);openingTagRe=new RegExp(escapeRegExp(tagsToCompile[0])+"\\s*");closingTagRe=new RegExp("\\s*"+escapeRegExp(tagsToCompile[1]));closingCurlyRe=new RegExp("\\s*"+escapeRegExp("}"+tagsToCompile[1]))}compileTags(tags||mustache.tags);var scanner=new Scanner(template);var start,type,value,chr,token,openSection;while(!scanner.eos()){start=scanner.pos;value=scanner.scanUntil(openingTagRe);if(value){for(var i=0,valueLength=value.length;i<valueLength;++i){chr=value.charAt(i);if(isWhitespace(chr)){spaces.push(tokens.length)}else{nonSpace=true}tokens.push(["text",chr,start,start+1]);start+=1;if(chr==="\n")stripSpace()}}if(!scanner.scan(openingTagRe))break;hasTag=true;type=scanner.scan(tagRe)||"name";scanner.scan(whiteRe);if(type==="="){value=scanner.scanUntil(equalsRe);scanner.scan(equalsRe);scanner.scanUntil(closingTagRe)}else if(type==="{"){value=scanner.scanUntil(closingCurlyRe);scanner.scan(curlyRe);scanner.scanUntil(closingTagRe);type="&"}else{value=scanner.scanUntil(closingTagRe)}if(!scanner.scan(closingTagRe))throw new Error("Unclosed tag at "+scanner.pos);token=[type,value,start,scanner.pos];tokens.push(token);if(type==="#"||type==="^"){sections.push(token)}else if(type==="/"){openSection=sections.pop();if(!openSection)throw new Error('Unopened section "'+value+'" at '+start);if(openSection[1]!==value)throw new Error('Unclosed section "'+openSection[1]+'" at '+start)}else if(type==="name"||type==="{"||type==="&"){nonSpace=true}else if(type==="="){compileTags(value)}}openSection=sections.pop();if(openSection)throw new Error('Unclosed section "'+openSection[1]+'" at '+scanner.pos);return nestTokens(squashTokens(tokens))}function squashTokens(tokens){var squashedTokens=[];var token,lastToken;for(var i=0,numTokens=tokens.length;i<numTokens;++i){token=tokens[i];if(token){if(token[0]==="text"&&lastToken&&lastToken[0]==="text"){lastToken[1]+=token[1];lastToken[3]=token[3]}else{squashedTokens.push(token);lastToken=token}}}return squashedTokens}function nestTokens(tokens){var nestedTokens=[];var collector=nestedTokens;var sections=[];var token,section;for(var i=0,numTokens=tokens.length;i<numTokens;++i){token=tokens[i];switch(token[0]){case"#":case"^":collector.push(token);sections.push(token);collector=token[4]=[];break;case"/":section=sections.pop();section[5]=token[2];collector=sections.length>0?sections[sections.length-1][4]:nestedTokens;break;default:collector.push(token)}}return nestedTokens}function Scanner(string){this.string=string;this.tail=string;this.pos=0}Scanner.prototype.eos=function eos(){return this.tail===""};Scanner.prototype.scan=function scan(re){var match=this.tail.match(re);if(!match||match.index!==0)return"";var string=match[0];this.tail=this.tail.substring(string.length);this.pos+=string.length;return string};Scanner.prototype.scanUntil=function scanUntil(re){var index=this.tail.search(re),match;switch(index){case-1:match=this.tail;this.tail="";break;case 0:match="";break;default:match=this.tail.substring(0,index);this.tail=this.tail.substring(index)}this.pos+=match.length;return match};function Context(view,parentContext){this.view=view;this.cache={".":this.view};this.parent=parentContext}Context.prototype.push=function push(view){return new Context(view,this)};Context.prototype.lookup=function lookup(name){var cache=this.cache;var value;if(cache.hasOwnProperty(name)){value=cache[name]}else{var context=this,names,index,lookupHit=false;while(context){if(name.indexOf(".")>0){value=context.view;names=name.split(".");index=0;while(value!=null&&index<names.length){if(index===names.length-1)lookupHit=hasProperty(value,names[index]);value=value[names[index++]]}}else{value=context.view[name];lookupHit=hasProperty(context.view,name)}if(lookupHit)break;context=context.parent}cache[name]=value}if(isFunction(value))value=value.call(this.view);return value};function Writer(){this.cache={}}Writer.prototype.clearCache=function clearCache(){this.cache={}};Writer.prototype.parse=function parse(template,tags){var cache=this.cache;var tokens=cache[template];if(tokens==null)tokens=cache[template]=parseTemplate(template,tags);return tokens};Writer.prototype.render=function render(template,view,partials){var tokens=this.parse(template);var context=view instanceof Context?view:new Context(view);return this.renderTokens(tokens,context,partials,template)};Writer.prototype.renderTokens=function renderTokens(tokens,context,partials,originalTemplate){var buffer="";var token,symbol,value;for(var i=0,numTokens=tokens.length;i<numTokens;++i){value=undefined;token=tokens[i];symbol=token[0];if(symbol==="#")value=this.renderSection(token,context,partials,originalTemplate);else if(symbol==="^")value=this.renderInverted(token,context,partials,originalTemplate);else if(symbol===">")value=this.renderPartial(token,context,partials,originalTemplate);else if(symbol==="&")value=this.unescapedValue(token,context);else if(symbol==="name")value=this.escapedValue(token,context);else if(symbol==="text")value=this.rawValue(token);if(value!==undefined)buffer+=value}return buffer};Writer.prototype.renderSection=function renderSection(token,context,partials,originalTemplate){var self=this;var buffer="";var value=context.lookup(token[1]);function subRender(template){return self.render(template,context,partials)}if(!value)return;if(isArray(value)){for(var j=0,valueLength=value.length;j<valueLength;++j){buffer+=this.renderTokens(token[4],context.push(value[j]),partials,originalTemplate)}}else if(typeof value==="object"||typeof value==="string"||typeof value==="number"){buffer+=this.renderTokens(token[4],context.push(value),partials,originalTemplate)}else if(isFunction(value)){if(typeof originalTemplate!=="string")throw new Error("Cannot use higher-order sections without the original template");value=value.call(context.view,originalTemplate.slice(token[3],token[5]),subRender);if(value!=null)buffer+=value}else{buffer+=this.renderTokens(token[4],context,partials,originalTemplate)}return buffer};Writer.prototype.renderInverted=function renderInverted(token,context,partials,originalTemplate){var value=context.lookup(token[1]);if(!value||isArray(value)&&value.length===0)return this.renderTokens(token[4],context,partials,originalTemplate)};Writer.prototype.renderPartial=function renderPartial(token,context,partials){if(!partials)return;var value=isFunction(partials)?partials(token[1]):partials[token[1]];if(value!=null)return this.renderTokens(this.parse(value),context,partials,value)};Writer.prototype.unescapedValue=function unescapedValue(token,context){var value=context.lookup(token[1]);if(value!=null)return value};Writer.prototype.escapedValue=function escapedValue(token,context){var value=context.lookup(token[1]);if(value!=null)return mustache.escape(value)};Writer.prototype.rawValue=function rawValue(token){return token[1]};mustache.name="mustache.js";mustache.version="2.3.0";mustache.tags=["{{","}}"];var defaultWriter=new Writer;mustache.clearCache=function clearCache(){return defaultWriter.clearCache()};mustache.parse=function parse(template,tags){return defaultWriter.parse(template,tags)};mustache.render=function render(template,view,partials){if(typeof template!=="string"){throw new TypeError('Invalid template! Template should be a "string" '+'but "'+typeStr(template)+'" was given as the first '+"argument for mustache#render(template, view, partials)")}return defaultWriter.render(template,view,partials)};mustache.to_html=function to_html(template,view,partials,send){var result=mustache.render(template,view,partials);if(isFunction(send)){send(result)}else{return result}};mustache.escape=escapeHtml;mustache.Scanner=Scanner;mustache.Context=Context;mustache.Writer=Writer;return mustache});