src/de/uhilger/httpserver/cm/DirList.java | ●●●●● patch | view | raw | blame | history | |
src/de/uhilger/httpserver/cm/FileManager.java | ●●●●● patch | view | raw | blame | history | |
src/de/uhilger/httpserver/cm/actor/Lister.java | ●●●●● patch | view | raw | blame | history | |
src/de/uhilger/httpserver/cm/actor/Mover.java | ●●●●● patch | view | raw | blame | history |
src/de/uhilger/httpserver/cm/DirList.java
New file @@ -0,0 +1,49 @@ /* http-cm - File management extensions to jdk.httpserver 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.httpserver.cm; import de.uhilger.httpserver.image.Datei; import java.util.List; /** * Einfache Transportklasse fuer eine Verzeichnisliste * * @author Ulrich Hilger, 15. Januar 2024 */ public class DirList { private String pfad; private List<Datei> dateien; public String getPfad() { return pfad; } public void setPfad(String pfad) { this.pfad = pfad; } public List<Datei> getDateien() { return dateien; } public void setDateien(List<Datei> dateien) { this.dateien = dateien; } } src/de/uhilger/httpserver/cm/FileManager.java
@@ -28,6 +28,8 @@ import de.uhilger.httpserver.base.HttpResponder; import de.uhilger.httpserver.base.HttpHelper; import de.uhilger.httpserver.base.handler.FileHandler; import de.uhilger.httpserver.cm.actor.Lister; import de.uhilger.httpserver.cm.actor.Mover; import de.uhilger.httpserver.image.Datei; import de.uhilger.httpserver.image.ImageActor; import de.uhilger.httpserver.image.ImageThread; @@ -100,7 +102,7 @@ * @author Ulrich Hilger * @version 1, 13. Mai 2021 */ public class FileManager extends FileHandler implements ThreadListener { public class FileManager extends FileHandler { /* private static final String[] specialChars = {new String("\u00c4"), new String("\u00d6"), @@ -128,18 +130,12 @@ public static final String ATTR_ROLE = "role"; private final List waitingThreads; private final int maxThreads; private int threadCount; //private String role; //public FileManager(String absoluteDirectoryPathAndName, String role, String ctx) { public FileManager() { //super(absoluteDirectoryPathAndName, ctx); //super(absoluteDirectoryPathAndName); waitingThreads = new ArrayList(); maxThreads = 4; threadCount = 0; //this.role = role; } @@ -156,7 +152,23 @@ HttpHelper helper = new HttpHelper(); switch (method) { case HttpHelper.HTTP_GET: liste(e, helper); String path = e.getRequestURI().toString(); if (path.endsWith(STR_SLASH)) { String json = new Lister().liste(helper.getFileName(e), e.getHttpContext().getPath(), e.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString(), path); if(null != json) { HttpResponder r = new HttpResponder(); r.antwortSenden(e, SC_OK, json); } else { emptyListResponse(e); } } else { new Lister().b64Action(helper.getFileName(e), e.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString()); super.handle(e); } break; case HttpHelper.HTTP_PUT: put(e, helper); @@ -192,7 +204,9 @@ break; case P_DUPLICATE: if(Boolean.parseBoolean(params[1])) { String neuerDateiName = duplizieren(exchange, helper); String neuerDateiName = new Mover().duplizieren( exchange.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString(), helper.getFileName(exchange)); //logger.fine("neuer Name: " + neuerDateiName); standardHeaderUndAntwort(exchange, SC_OK, neuerDateiName); } @@ -228,155 +242,6 @@ } } public class DirList { private String pfad; private List<Datei> dateien; public String getPfad() { return pfad; } public void setPfad(String pfad) { this.pfad = pfad; } public List<Datei> getDateien() { return dateien; } public void setDateien(List<Datei> dateien) { this.dateien = dateien; } } private void liste(HttpExchange e, HttpHelper helper) throws IOException { String path = e.getRequestURI().toString(); //logger.fine(path); String fName = helper.getFileName(e); String dirListPath = e.getHttpContext().getPath() + fName; if (path.endsWith(STR_SLASH)) { //logger.fine("fName: " + fName); File dir = new File(e.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString(), fName); //logger.fine("absPath: " + dir.getAbsolutePath()); File[] files = dir.listFiles(new ImageFileFilter()); if(files != null && files.length > 0) { Arrays.sort(files); ArrayList liste = new ArrayList(); for (File file : files) { Datei datei = new Datei(); String dateiName = file.getName(); datei.setName(dateiName); if (file.isDirectory()) { datei.setTyp(Datei.TYP_ORDNER); } else { datei.setTyp(Datei.TYP_DATEI); } //datei.setPfad(e.getHttpContext().getPath() + fName); String lowerName = dateiName.toLowerCase(); if (lowerName.endsWith(ImageActor.JPEG) || lowerName.endsWith(ImageActor.JPG) || lowerName.endsWith(ImageActor.PNG)) { datei.setBild(true); String ext = dateiName.substring(dateiName.lastIndexOf(STR_DOT)); String ohneExt = dateiName.substring(0, dateiName.lastIndexOf(STR_DOT)); datei.setMiniurl(ohneExt + ImageActor.TN + ext); buildImgSrc(file, datei, ohneExt, ext); } liste.add(datei); } while(threadCount > 0) { try { Thread.sleep(50); } catch (InterruptedException ex) { Logger.getLogger(FileManager.class.getName()).log(Level.SEVERE, null, ex); } } if(liste.size() > 0) { DirList list = new DirList(); list.setPfad(dirListPath); list.setDateien(liste); Gson gson = new Gson(); //String json = gson.toJson(liste); String json = gson.toJson(list); //byte[] bytes = json.getBytes(); //logger.fine("json: '" + json + "'"); HttpResponder r = new HttpResponder(); r.antwortSenden(e, SC_OK, json); } else { emptyListResponse(e); } } else { emptyListResponse(e); } } else { String lowerName = fName.toLowerCase(); if(lowerName.contains(ImageActor.B64)) { ImageActor actor = new ImageActor(); String fromName = fName.replace(ImageActor.B64, ""); File fromFile = new File(e.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString(), fromName); File toFile = new File(e.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString(), fName); //logger.fine("from " + fromFile.getAbsolutePath() + ", to " + toFile.getAbsolutePath()); if(!toFile.exists()) { actor.b64Image(fromFile, toFile); } super.handle(e); } else { super.handle(e); } } } // data:[<mime type>][;charset=<Zeichensatz>][;base64],<Daten> /* [So. Juni 13 13:23:32 MESZ 2021] FEIN: file: /home/ulrich/helix-files/bild-test/10419903-14-2-1920-r.jpg, relname: bild-test/10419903-14-2-1920-r.jpg, ohneExt: 10419903-14-2-1920-r, ext: .jpg (de.uhilger.helix.FileManager buildImgSrc) */ private void buildImgSrc(File file, Datei datei, String ohneExt, String ext) throws IOException { //logger.fine("file: " + file.getAbsolutePath() + ", ohneExt: " + ohneExt + ", ext: " + ext); File dir = file.getParentFile(); String newRelName = ohneExt + ImageActor.TN + ImageActor.B64 + ext; File b64File = new File(dir, newRelName); //logger.fine("b64File: " + b64File.getAbsolutePath()); if(!b64File.exists()) { //BildErzeuger be = new BildErzeuger(); //be.bildErzeugen(dir, newRelName, BildErzeuger.TN, 120, b64File); ImageThread it = new ImageThread(dir, newRelName, ImageActor.TN, 120, b64File, datei, ext); it.addListener(this); if(threadCount < maxThreads) { ++threadCount; //logger.fine("Thread started, threadCount: " + threadCount); it.start(); } else { waitingThreads.add(it); //logger.fine("Thread added to wait queue."); } } else { ImageActor be = new ImageActor(); be.setImgSrc(datei, ext, b64File); } } @Override public void finished() { --threadCount; //logger.fine("Thread finished, threadCound now: " + threadCount); if (threadCount < maxThreads) { if (waitingThreads.size() > 0) { Object o = waitingThreads.get(0); if (o instanceof ImageThread) { waitingThreads.remove(o); ImageThread it = (ImageThread) o; ++threadCount; //logger.fine("Thread started from wait queue, threadCount now: " + threadCount); it.start(); } } } } private void emptyListResponse(HttpExchange e) throws IOException { HttpResponder r = new HttpResponder(); @@ -462,45 +327,8 @@ private void copyOrMove(HttpExchange exchange, String quelle, String ziel, int op) throws IOException { //logger.fine("quelle: " + quelle + ", ziel: " + ziel); String[] dateiNamen = dateiliste(exchange); copyOrMoveFiles(quelle, ziel, dateiNamen, op, exchange); new Mover().copyOrMoveFiles(quelle, ziel, dateiNamen, op, exchange.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString()); standardHeaderUndAntwort(exchange, SC_OK, "Dateien verarbeitet."); } private String copyOrMoveFiles(String fromPath, String toPath, String[] fileNames, int operation, HttpExchange e) throws IOException { String result = null; File srcDir = new File(e.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString(), fromPath); File targetDir = new File(e.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString(), toPath); for (String fileName : fileNames) { File srcFile = new File(srcDir, fileName); //logger.fine("srcFile: " + srcFile); if (srcFile.isDirectory()) { //logger.fine("srcFile is directory."); OrdnerBearbeiter bearbeiter = new OrdnerBearbeiter(); bearbeiter.setTargetDir(targetDir.toPath()); bearbeiter.setOperation(operation); Files.walkFileTree(srcFile.toPath(), bearbeiter); } else { Path source = srcFile.toPath(); File destFile = targetDir.toPath().resolve(source.getFileName()).toFile(); if (destFile.exists()) { FileTransporter trans = new FileTransporter(); destFile = trans.getNewFileName(destFile); } if (operation == OP_MOVE) { String fname = srcFile.getName().toLowerCase(); if (fname.endsWith(ImageActor.JPEG) || fname.endsWith(ImageActor.JPG) || fname.endsWith(ImageActor.PNG)) { moveImgFilesToDirectory(srcFile, srcDir, targetDir, false); } else { Files.move(source, destFile.toPath()); } } else { Files.copy(source, destFile.toPath()); } } } return result; } private void loeschen(HttpExchange exchange, HttpHelper helper) throws IOException { @@ -517,39 +345,6 @@ return gson.fromJson(body, String[].class); } public String duplizieren(HttpExchange exchange, HttpHelper helper) throws IOException { String relPfad = helper.getFileName(exchange); File srcFile = new File(exchange.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString(), relPfad); String fnameext = srcFile.getName(); int dotpos = fnameext.lastIndexOf(STR_DOT); String fname = fnameext.substring(0, dotpos); String ext = fnameext.substring(dotpos); File srcDir = srcFile.getParentFile(); File destFile = new File(srcDir, fname + "-Kopie" + ext); int i = 1; while (destFile.exists()) { destFile = new File(srcDir, fname + "-Kopie-" + Integer.toString(++i) + ext); } Files.copy(srcFile.toPath(), destFile.toPath()); return destFile.getName(); } private void moveImgFilesToDirectory(File srcFile, File srcDir, File targetDir, boolean createDestDir) throws IOException { String fnameext = srcFile.getName(); int dotpos = fnameext.lastIndexOf(STR_DOT); String fname = fnameext.substring(0, dotpos); String ext = fnameext.substring(dotpos); //logger.fine("fname: " + fname + ", ext: " + ext); Path targetPath = targetDir.toPath(); DirectoryStream<Path> stream = Files.newDirectoryStream(srcDir.toPath(), fname + "*" + ext); //"*.{txt,doc,pdf,ppt}" for (Path path : stream) { //logger.fine(path.getFileName().toString()); //Files.delete(path); Files.move(path, targetPath.resolve(path.getFileName())); } stream.close(); } private void standardHeaderUndAntwort(HttpExchange exchange, int status, String antwort) throws IOException { Headers resHeaders = exchange.getResponseHeaders(); src/de/uhilger/httpserver/cm/actor/Lister.java
New file @@ -0,0 +1,184 @@ /* http-cm - File management extensions to jdk.httpserver 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.httpserver.cm.actor; import com.google.gson.Gson; import com.sun.net.httpserver.HttpExchange; import de.uhilger.httpserver.base.HttpHelper; import de.uhilger.httpserver.base.HttpResponder; import de.uhilger.httpserver.base.handler.FileHandler; import static de.uhilger.httpserver.base.handler.FileHandler.SC_OK; import de.uhilger.httpserver.cm.DirList; import de.uhilger.httpserver.cm.FileManager; import static de.uhilger.httpserver.cm.FileManager.STR_DOT; import static de.uhilger.httpserver.cm.FileManager.STR_SLASH; import de.uhilger.httpserver.cm.ImageFileFilter; import de.uhilger.httpserver.image.Datei; import de.uhilger.httpserver.image.ImageActor; import de.uhilger.httpserver.image.ImageThread; import de.uhilger.httpserver.image.ImageThread.ThreadListener; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; /** * Klasse zum Erzeugen von Dateilisten * * @author Ulrich Hilger, 15. Januar 2024 */ public class Lister implements ThreadListener { private final List waitingThreads; private final int maxThreads; private int threadCount; public Lister() { waitingThreads = new ArrayList(); maxThreads = 4; threadCount = 0; } public String liste(String fName, String ctxPath, String base, String path) throws IOException { String dirListPath = ctxPath + fName; //if (path.endsWith(STR_SLASH)) { //logger.fine("fName: " + fName); File dir = new File(base, fName); //logger.fine("absPath: " + dir.getAbsolutePath()); File[] files = dir.listFiles(new ImageFileFilter()); if(files != null && files.length > 0) { Arrays.sort(files); ArrayList liste = new ArrayList(); for (File file : files) { Datei datei = new Datei(); String dateiName = file.getName(); datei.setName(dateiName); if (file.isDirectory()) { datei.setTyp(Datei.TYP_ORDNER); } else { datei.setTyp(Datei.TYP_DATEI); } //datei.setPfad(e.getHttpContext().getPath() + fName); String lowerName = dateiName.toLowerCase(); if (lowerName.endsWith(ImageActor.JPEG) || lowerName.endsWith(ImageActor.JPG) || lowerName.endsWith(ImageActor.PNG)) { datei.setBild(true); String ext = dateiName.substring(dateiName.lastIndexOf(STR_DOT)); String ohneExt = dateiName.substring(0, dateiName.lastIndexOf(STR_DOT)); datei.setMiniurl(ohneExt + ImageActor.TN + ext); buildImgSrc(file, datei, ohneExt, ext); } liste.add(datei); } while(threadCount > 0) { try { Thread.sleep(50); } catch (InterruptedException ex) { Logger.getLogger(FileManager.class.getName()).log(Level.SEVERE, null, ex); } } if(liste.size() > 0) { DirList list = new DirList(); list.setPfad(dirListPath); list.setDateien(liste); Gson gson = new Gson(); //String json = gson.toJson(liste); String json = gson.toJson(list); //byte[] bytes = json.getBytes(); //logger.fine("json: '" + json + "'"); return json; } else { return null; } } else { return null; } //} else { //} } public void b64Action(String fName, String base) throws IOException { String lowerName = fName.toLowerCase(); if(lowerName.contains(ImageActor.B64)) { ImageActor actor = new ImageActor(); String fromName = fName.replace(ImageActor.B64, ""); File fromFile = new File(base, fromName); File toFile = new File(base, fName); //logger.fine("from " + fromFile.getAbsolutePath() + ", to " + toFile.getAbsolutePath()); if(!toFile.exists()) { actor.b64Image(fromFile, toFile); } } } // data:[<mime type>][;charset=<Zeichensatz>][;base64],<Daten> /* [So. Juni 13 13:23:32 MESZ 2021] FEIN: file: /home/ulrich/helix-files/bild-test/10419903-14-2-1920-r.jpg, relname: bild-test/10419903-14-2-1920-r.jpg, ohneExt: 10419903-14-2-1920-r, ext: .jpg (de.uhilger.helix.FileManager buildImgSrc) */ private void buildImgSrc(File file, Datei datei, String ohneExt, String ext) throws IOException { //logger.fine("file: " + file.getAbsolutePath() + ", ohneExt: " + ohneExt + ", ext: " + ext); File dir = file.getParentFile(); String newRelName = ohneExt + ImageActor.TN + ImageActor.B64 + ext; File b64File = new File(dir, newRelName); //logger.fine("b64File: " + b64File.getAbsolutePath()); if(!b64File.exists()) { //BildErzeuger be = new BildErzeuger(); //be.bildErzeugen(dir, newRelName, BildErzeuger.TN, 120, b64File); ImageThread it = new ImageThread(dir, newRelName, ImageActor.TN, 120, b64File, datei, ext); it.addListener(this); if(threadCount < maxThreads) { ++threadCount; //logger.fine("Thread started, threadCount: " + threadCount); it.start(); } else { waitingThreads.add(it); //logger.fine("Thread added to wait queue."); } } else { ImageActor be = new ImageActor(); be.setImgSrc(datei, ext, b64File); } } @Override public void finished() { --threadCount; //logger.fine("Thread finished, threadCound now: " + threadCount); if (threadCount < maxThreads) { if (waitingThreads.size() > 0) { Object o = waitingThreads.get(0); if (o instanceof ImageThread) { waitingThreads.remove(o); ImageThread it = (ImageThread) o; ++threadCount; //logger.fine("Thread started from wait queue, threadCount now: " + threadCount); it.start(); } } } } } src/de/uhilger/httpserver/cm/actor/Mover.java
New file @@ -0,0 +1,111 @@ /* http-cm - File management extensions to jdk.httpserver 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.httpserver.cm.actor; import com.sun.net.httpserver.HttpExchange; import de.uhilger.httpserver.base.HttpHelper; import de.uhilger.httpserver.base.handler.FileHandler; import static de.uhilger.httpserver.base.handler.FileHandler.SC_OK; import static de.uhilger.httpserver.cm.FileManager.OP_MOVE; import static de.uhilger.httpserver.cm.FileManager.STR_DOT; import de.uhilger.httpserver.cm.FileTransporter; import de.uhilger.httpserver.cm.OrdnerBearbeiter; import de.uhilger.httpserver.image.ImageActor; import java.io.File; import java.io.IOException; import java.nio.file.DirectoryStream; import java.nio.file.Files; import java.nio.file.Path; /** * Eine Klasse mit Methoden zum Kopieren und Verschieben von Dateien * * @author Ulrich Hilger, 15. Janaur 2024 */ public class Mover { public String copyOrMoveFiles(String fromPath, String toPath, String[] fileNames, int operation, String base) throws IOException { String result = null; File srcDir = new File(base, fromPath); File targetDir = new File(base, toPath); for (String fileName : fileNames) { File srcFile = new File(srcDir, fileName); //logger.fine("srcFile: " + srcFile); if (srcFile.isDirectory()) { //logger.fine("srcFile is directory."); OrdnerBearbeiter bearbeiter = new OrdnerBearbeiter(); bearbeiter.setTargetDir(targetDir.toPath()); bearbeiter.setOperation(operation); Files.walkFileTree(srcFile.toPath(), bearbeiter); } else { Path source = srcFile.toPath(); File destFile = targetDir.toPath().resolve(source.getFileName()).toFile(); if (destFile.exists()) { FileTransporter trans = new FileTransporter(); destFile = trans.getNewFileName(destFile); } if (operation == OP_MOVE) { String fname = srcFile.getName().toLowerCase(); if (fname.endsWith(ImageActor.JPEG) || fname.endsWith(ImageActor.JPG) || fname.endsWith(ImageActor.PNG)) { moveImgFilesToDirectory(srcFile, srcDir, targetDir, false); } else { Files.move(source, destFile.toPath()); } } else { Files.copy(source, destFile.toPath()); } } } return result; } private void moveImgFilesToDirectory(File srcFile, File srcDir, File targetDir, boolean createDestDir) throws IOException { String fnameext = srcFile.getName(); int dotpos = fnameext.lastIndexOf(STR_DOT); String fname = fnameext.substring(0, dotpos); String ext = fnameext.substring(dotpos); //logger.fine("fname: " + fname + ", ext: " + ext); Path targetPath = targetDir.toPath(); DirectoryStream<Path> stream = Files.newDirectoryStream(srcDir.toPath(), fname + "*" + ext); //"*.{txt,doc,pdf,ppt}" for (Path path : stream) { //logger.fine(path.getFileName().toString()); //Files.delete(path); Files.move(path, targetPath.resolve(path.getFileName())); } stream.close(); } public String duplizieren(String base, String relPfad) throws IOException { File srcFile = new File(base, relPfad); String fnameext = srcFile.getName(); int dotpos = fnameext.lastIndexOf(STR_DOT); String fname = fnameext.substring(0, dotpos); String ext = fnameext.substring(dotpos); File srcDir = srcFile.getParentFile(); File destFile = new File(srcDir, fname + "-Kopie" + ext); int i = 1; while (destFile.exists()) { destFile = new File(srcDir, fname + "-Kopie-" + Integer.toString(++i) + ext); } Files.copy(srcFile.toPath(), destFile.toPath()); return destFile.getName(); } }