/* Tango - 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 . */ package de.uhilger.tango.api; import com.sun.net.httpserver.Headers; import com.sun.net.httpserver.HttpExchange; import de.uhilger.tango.App; import de.uhilger.tango.Server; import de.uhilger.tango.entity.Einstellung; import de.uhilger.tango.entity.Entity; import de.uhilger.tango.store.FileStorage; import de.uhilger.tango.store.Storage; import de.uhilger.tango.store.StorageFile; import java.io.File; import java.io.FileFilter; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import org.farng.mp3.MP3File; import org.farng.mp3.TagException; import org.farng.mp3.id3.AbstractID3v2; import org.farng.mp3.id3.ID3v1; /** * * @author ulrich */ public class ListFileHandler extends FileHandler { public static final String RB_AUDIOEXTS = "audioexts"; public static final String RB_VIDEOEXTS = "videoexts"; /* Der Logger fuer diesen ListFileHandler */ private static final Logger logger = Logger.getLogger(ListFileHandler.class.getName()); private static final String[] specialChars = {new String("\u00c4"), new String("\u00d6"), new String("\u00dc"), new String("\u00e4"), new String("\u00f6"), new String("\u00fc"), new String("\u00df")}; public static final String UNWANTED_PATTERN = "[^a-zA-Z_0-9 ]"; Map extMap = new HashMap(); private String conf; public ListFileHandler(String absoluteDirectoryPathAndName, String conf) { super(absoluteDirectoryPathAndName); /* Ermittlung von Dateifiltern. Sie werden erwartet in den Einstellungen 'audioexts' und 'videoexts' jeweils als Dateierweiterungen mit Komma getrennt z.B. "mp4,m4v" */ FileStorage fs = new FileStorage(conf); initMap(fs, getResString(RB_AUDIOEXTS), StorageFile.TYP_AUDIO); initMap(fs, getResString(RB_VIDEOEXTS), StorageFile.TYP_VIDEO); } private void initMap(Storage s, String key, String typ) { Entity e = s.read(Einstellung.class.getSimpleName(), key); if(e instanceof Einstellung) { String[] exts = ((Einstellung) e).getValue().split(","); for(String ext : exts) { extMap.put(ext, typ); } } } @Override public void handle(HttpExchange e) throws IOException { String path = e.getRequestURI().toString(); logger.fine(path); if(path.endsWith(Server.SLASH)) { String fName = getFileName(e); logger.fine(fName); File dir = new File(fileBase, fName); logger.fine(dir.getAbsolutePath()); File[] files = dir.listFiles(new FileFilter() { @Override public boolean accept(File pathname) { Set keys = extMap.keySet(); String fname = pathname.getName(); int pos = fname.lastIndexOf("."); String ext = fname.substring(pos+1); return keys.contains(ext) || pathname.isDirectory(); } }); Arrays.sort(files); ArrayList list = new ArrayList(); if(files != null) { for(File file : files) { StorageFile sf = new StorageFile(); String fname = file.getName(); sf.setName(fname); sf.setTitelAnzName(fname); if(file.isDirectory()) { sf.setTyp(StorageFile.TYP_FOLDER); } else { int pos = fname.lastIndexOf("."); String ext = fname.substring(pos+1); logger.log(Level.FINE, "ext: {0}", ext); Object o = extMap.get(ext); if(o instanceof String) { sf.setTyp(o.toString()); getMetadata(file, sf); } else { sf.setTyp(StorageFile.TYP_FILE); } } list.add(sf); } } //Collections.sort(list); String rawjson = jsonWithCustomType(list, "Medialiste"); String json = escapeHtml(rawjson); logger.fine(json); Headers headers = e.getResponseHeaders(); headers.add("Content-Type", "application/json; charset=UTF-8"); e.sendResponseHeaders(200, json.length()); OutputStream os = e.getResponseBody(); os.write(json.getBytes()); os.close(); } else { super.handle(e); } } public String escapeHtml(String text) { text = text.replace(specialChars[0], "Ae"); text = text.replace(specialChars[1], "Oe"); text = text.replace(specialChars[2], "Ue"); text = text.replace(specialChars[3], "ae"); text = text.replace(specialChars[4], "oe"); text = text.replace(specialChars[5], "ue"); text = text.replace(specialChars[6], "ss"); /* text = text.replace(specialChars[0], "Ä"); text = text.replace(specialChars[1], "Ö"); text = text.replace(specialChars[2], "Ü"); text = text.replace(specialChars[3], "ä"); text = text.replace(specialChars[4], "ö"); text = text.replace(specialChars[5], "ü"); text = text.replace(specialChars[6], "ß"); */ return text; } private void getMetadata(File file, StorageFile sf) { if(sf.getTyp().equalsIgnoreCase(StorageFile.TYP_AUDIO)) { try { MP3File mp3 = new MP3File(file); ID3v1 tag = mp3.getID3v1Tag(); if(tag == null) { AbstractID3v2 tag2 = mp3.getID3v2Tag(); sf.setInterpret(tag2.getLeadArtist().replaceAll(UNWANTED_PATTERN, "")); String trackTitel = tag2.getSongTitle().replaceAll(UNWANTED_PATTERN, ""); if(trackTitel != null && trackTitel.length() > 0) { sf.setTitelAnzName(trackTitel); } sf.setAlbum(tag2.getAlbumTitle().replaceAll(UNWANTED_PATTERN, "")); } else { sf.setInterpret(tag.getArtist().replaceAll(UNWANTED_PATTERN, "")); String trackTitel = tag.getTitle().replaceAll(UNWANTED_PATTERN, ""); if(trackTitel != null && trackTitel.length() > 0) { sf.setTitelAnzName(trackTitel); } sf.setAlbum(tag.getAlbumTitle().replaceAll(UNWANTED_PATTERN, "")); } } catch (IOException ex) { Logger.getLogger(ListFileHandler.class.getName()).log(Level.SEVERE, null, ex); } catch (TagException ex) { Logger.getLogger(ListFileHandler.class.getName()).log(Level.SEVERE, null, ex); } } } }