From: Svjatoslav Agejenko Date: Sat, 19 Jan 2019 12:56:26 +0000 (+0200) Subject: Code refactoring X-Git-Tag: meviz-1.2~21 X-Git-Url: http://www2.svjatoslav.eu/gitweb/?a=commitdiff_plain;h=35252da406b80b367bf8ff130991165c7e865687;p=meviz.git Code refactoring --- diff --git a/install b/install index 933f49d..6dc8f7f 100755 --- a/install +++ b/install @@ -1,6 +1,6 @@ #!/bin/bash -sudo apt-get install maven lame vorbis-tools imagemagick ffmpeg2theora libav-tools --yes +sudo apt-get install maven lame vorbis-tools imagemagick ffmpeg2theora --yes mvn clean mvn package diff --git a/pom.xml b/pom.xml index 02b8fda..9ad5714 100644 --- a/pom.xml +++ b/pom.xml @@ -93,20 +93,6 @@ - - org.apache.maven.plugins - maven-javadoc-plugin - 2.9 - - - attach-javadocs - - jar - - - - - org.apache.maven.plugins maven-release-plugin diff --git a/src/main/java/eu/svjatoslav/meviz/htmlindexer/AbstractIndexer.java b/src/main/java/eu/svjatoslav/meviz/htmlindexer/AbstractIndexer.java deleted file mode 100644 index 22ec825..0000000 --- a/src/main/java/eu/svjatoslav/meviz/htmlindexer/AbstractIndexer.java +++ /dev/null @@ -1,63 +0,0 @@ -package eu.svjatoslav.meviz.htmlindexer; - -import eu.svjatoslav.meviz.htmlindexer.metadata.Dimension; -import eu.svjatoslav.meviz.htmlindexer.metadata.DirectoryMetadata; -import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.*; - -import java.io.File; -import java.io.UnsupportedEncodingException; - -import static eu.svjatoslav.meviz.htmlindexer.Constants.SUPPORTED_IMAGE_EXTENSIONS; -import static eu.svjatoslav.meviz.htmlindexer.Constants.SUPPORTED_VIDEO_EXTENSIONS; - -public abstract class AbstractIndexer { - - public static boolean isImage(final String fileExtension) { - for (final String ext : SUPPORTED_IMAGE_EXTENSIONS) - if (ext.equals(fileExtension)) - return true; - return false; - } - - public static boolean isVideo(final String fileExtension) { - for (final String ext : SUPPORTED_VIDEO_EXTENSIONS) - if (ext.equals(fileExtension)) - return true; - return false; - } - - static boolean shallFileBeIndexed(final File file) { - - if (file.getName().startsWith(".")) - return false; - if (file.getName().startsWith("index")) - if (file.getName().endsWith(".html")) - return false; - - return true; - } - - void compileHtml(final Layout layout, - final DirectoryMetadata directory) - throws UnsupportedEncodingException { - - for (final AbstractFile file : directory.getFiles()) - if (file instanceof GeneralFile) { - layout.enlistFile(file, directory); - } else if (file instanceof Picture){ - layout.enlistImage((Picture) file, directory); - } else if (file instanceof Video){ - layout.enlistVideo((Video) file); - } else if (file instanceof DirectoryFile) - layout.enlistDirectory(file, directory); - } - - public abstract String getDirectoryUrl(final AbstractFile directory, - IndexingContext context); - - public abstract String getParentDirectoryUrl(IndexingContext context); - - public abstract String getThumbnailUrl(Picture picture, - final Dimension desiredDimension, IndexingContext context); - -} diff --git a/src/main/java/eu/svjatoslav/meviz/htmlindexer/CommandlineHandler.java b/src/main/java/eu/svjatoslav/meviz/htmlindexer/CommandlineHandler.java index 1b945c1..93a9d7b 100755 --- a/src/main/java/eu/svjatoslav/meviz/htmlindexer/CommandlineHandler.java +++ b/src/main/java/eu/svjatoslav/meviz/htmlindexer/CommandlineHandler.java @@ -17,7 +17,7 @@ import eu.svjatoslav.meviz.encoder.EncodingOptions; import java.io.File; -class CommandlineHandler { +public class CommandlineHandler { final Parser parser = new Parser(); final NullParameter removeIndex = parser.add( diff --git a/src/main/java/eu/svjatoslav/meviz/htmlindexer/FilesystemIndexRemover.java b/src/main/java/eu/svjatoslav/meviz/htmlindexer/FilesystemIndexRemover.java deleted file mode 100644 index 30f1099..0000000 --- a/src/main/java/eu/svjatoslav/meviz/htmlindexer/FilesystemIndexRemover.java +++ /dev/null @@ -1,49 +0,0 @@ -package eu.svjatoslav.meviz.htmlindexer; - -import eu.svjatoslav.commons.file.IOHelper; - -import java.io.File; -import java.io.IOException; - -class FilesystemIndexRemover { - - private final CommandlineHandler commandlineHandler; - - public FilesystemIndexRemover(final CommandlineHandler commandlineHandler) - throws IOException { - this.commandlineHandler = commandlineHandler; - - removeIndex(commandlineHandler.getWorkingDirectory()); - } - - private void removeIndex(final File workingDirectory) throws IOException { - - // remove thumbnails directory from current directory - final File thumbnailsDirectory = Utils - .getThumbnailsDirectory(workingDirectory); - if (thumbnailsDirectory.exists()) { - System.out.println("Deleting thumbnails directory: " - + thumbnailsDirectory); - IOHelper.deleteRecursively(thumbnailsDirectory); - } - - // recursively remove thumbnail directories from sub directories - for (final File subFile : workingDirectory.listFiles()) - if (subFile.isDirectory()) - removeIndex(subFile); - - for (final Layout layout : Utils.getLayouts()) { - final File indexFile = Utils.getLayoutIndexFile(layout, - workingDirectory); - - if (indexFile.exists()) - if (Utils.isMevizGeneratedIndexFile(indexFile)) { - System.out.println("Deleting generated index file: " - + indexFile); - indexFile.delete(); - } - } - - } - -} diff --git a/src/main/java/eu/svjatoslav/meviz/htmlindexer/FilesystemIndexer.java b/src/main/java/eu/svjatoslav/meviz/htmlindexer/FilesystemIndexer.java deleted file mode 100755 index f001d6a..0000000 --- a/src/main/java/eu/svjatoslav/meviz/htmlindexer/FilesystemIndexer.java +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Meviz - Various tools collection to work with multimedia. - * Copyright (C) 2012 -- 2019, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 3 of the GNU Lesser General Public License - * or later as published by the Free Software Foundation. -*/ - -package eu.svjatoslav.meviz.htmlindexer; - -import eu.svjatoslav.commons.file.IOHelper; -import eu.svjatoslav.meviz.htmlindexer.metadata.Dimension; -import eu.svjatoslav.meviz.htmlindexer.metadata.DirectoryMetadata; -import eu.svjatoslav.meviz.htmlindexer.metadata.MetadadaHelper; -import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.AbstractFile; -import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.Picture; -import org.apache.log4j.Logger; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; - -/** - * Main class of HTML indexer. - */ - -public class FilesystemIndexer extends AbstractIndexer { - - private static final Logger logger = Logger - .getLogger(FilesystemIndexer.class); - - private final HashSet validMetadataFiles = new HashSet<>(); - - private final File directoryToIndex; - private final List pathElements; - private final CommandlineHandler commandlineHandler; - private File metadataFile; - private DirectoryMetadata metadata; - private HashSet layouts; - - public FilesystemIndexer(final File directoryToIndex, - final CommandlineHandler commandlineHandler, - final List pathElements) throws Exception { - - this.directoryToIndex = directoryToIndex; - this.commandlineHandler = commandlineHandler; - this.pathElements = pathElements; - - if (!directoryToIndex.canRead()) - return; - - validMetadataFiles.add(Constants.METADATA_FILE_NAME); - - initializeThumbnailsDirectory(); - loadOrCreateMetadata(); - - initializeLayouts(); - - updateMetadata(); - - metadata.removeUnusedMetadataEntries(); - - generateHtmlFromMetadata(layouts); - - removeUnusedThumbnailFiles(); - - // save directory metadata - if (metadata.changed) - MetadadaHelper.saveDirectoryMetadata(metadataFile, metadata); - - } - - private boolean canWriteIndexFile(final File indexFile) - throws IOException { - - return !indexFile.exists() || Utils.isMevizGeneratedIndexFile(indexFile); - - } - - private void generateHtmlFromMetadata(final HashSet layouts) { - // Generate HTML from metadata - for (final Layout layout : layouts) - try { - final File indexFile = Utils.getLayoutIndexFile(layout, - directoryToIndex); - - if (canWriteIndexFile(indexFile)) { - - compileHtml(layout, metadata); - - IOHelper.overwriteFileIfContentDiffers(indexFile, layout - .getHtml(true, true, metadata).getBytes()); - } - } catch (final Exception e) { - logger.error("Error writing index file. ", e); - } - } - - private List getChildPath(final File file) { - - final List result = new ArrayList<>(); - result.addAll(pathElements); - result.add(file.getName()); - - return result; - } - - @Override - public String getDirectoryUrl(final AbstractFile directory, - final IndexingContext context) { - return Utils.urlEncode(directory.fileName) + "/index.html"; - } - - @Override - public String getParentDirectoryUrl(final IndexingContext context) { - return "../index.html"; - } - - @Override - public String getThumbnailUrl(final Picture picture, - final Dimension desiredDimension, final IndexingContext context) { - - // in case thumbnail size was equal to original, then return original - // file path - if (picture.getDimensions().equals(desiredDimension)) - return picture.fileName; - - final String thumbnailFileName = picture - .getRelativeThumbnailFileName(desiredDimension); - - validMetadataFiles.add(thumbnailFileName); - final File thumbnailFile = new File( - Utils.getThumbnailsDirectoryPath(directoryToIndex) - + thumbnailFileName); - - if (!thumbnailFile.exists()) { - - final File originalFile = new File( - directoryToIndex.getAbsolutePath() + "/" + picture.fileName); - - // generate new thumbnail - Picture.makeThumbnail(originalFile, thumbnailFile, - desiredDimension.getAwtDimension()); - } - return Constants.THUMBNAILS_DIRECTORY_NAME + "/" - + Utils.urlEncode(thumbnailFileName); - } - - private void initializeLayouts() { - - layouts = Utils.getLayouts(); - - final String galleryTitle = commandlineHandler.getGalleryTitle(); - - for (final Layout layout : layouts) - layout.init(galleryTitle, pathElements, this, new IndexingContext( - "", ".")); - } - - private void initializeThumbnailsDirectory() { - final File thumbnailsDirectory = Utils - .getThumbnailsDirectory(directoryToIndex); - - if (!thumbnailsDirectory.exists()) - thumbnailsDirectory.mkdirs(); - } - - private void loadOrCreateMetadata() { - - metadataFile = new File( - Utils.getThumbnailsDirectoryPath(directoryToIndex) - + Constants.METADATA_FILE_NAME); - - metadata = MetadadaHelper.initDirectoryMetadata(metadataFile); - } - - private void removeUnusedThumbnailFiles() { - - for (final File file : Utils.getThumbnailsDirectory(directoryToIndex) - .listFiles()) - if (!validMetadataFiles.contains(file.getName())) - file.delete(); - - } - - private void updateMetadata() throws Exception { - - for (final File file : directoryToIndex.listFiles()) - if (shallFileBeIndexed(file)) { - - metadata.ensureFileMetadataIsUpToDate(directoryToIndex, file); - - if (file.isDirectory()) - new FilesystemIndexer(file, commandlineHandler, - getChildPath(file)); - } - } -} diff --git a/src/main/java/eu/svjatoslav/meviz/htmlindexer/Layout.java b/src/main/java/eu/svjatoslav/meviz/htmlindexer/Layout.java deleted file mode 100755 index 5083b39..0000000 --- a/src/main/java/eu/svjatoslav/meviz/htmlindexer/Layout.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Meviz - Various tools collection to work with multimedia. - * Copyright (C) 2012 -- 2019, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 3 of the GNU Lesser General Public License - * or later as published by the Free Software Foundation. -*/ - -package eu.svjatoslav.meviz.htmlindexer; - -import eu.svjatoslav.meviz.htmlindexer.metadata.DirectoryMetadata; -import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.AbstractFile; -import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.Picture; -import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.Video; - -import java.util.List; - -/** - * In order to have possibility of several different layouts per directory. - * Universal interface is defined. - *

- * Layout implementation is responsible for actual HTML generation. - */ - -public interface Layout { - - /** - * Enlist directory. - */ - void enlistDirectory(AbstractFile directory, - DirectoryMetadata parentDirectoryMetadata); - - /** - * Enlist simple file. - */ - void enlistFile(AbstractFile file, - DirectoryMetadata parentDirectoryMetadata); - - /** - * Enlist image file. - */ - void enlistImage(Picture picture, - DirectoryMetadata parentDirectoryMetadata); - - /** - * Enlist video file. - */ - void enlistVideo(Video file); - - /** - * Return layout specific suffix that will be appended between - * index(suffix).html of generated file. This way multiple layouts can - * coexist in the same directory, each residing in its own HTML file. - */ - String getFileNameSuffix(); - - /** - * After necessary files have been enlisted for particular directory, use - * this method to retrieve generated HTML result. - */ - String getHtml(final boolean showTitle, - final boolean doHtmlHeaderAndFooter, DirectoryMetadata metadata) - ; - - /** - * Initialize layout for particular directory. - */ - void init(String galleryTitle, List path, - final AbstractIndexer indexer, IndexingContext context); - -} diff --git a/src/main/java/eu/svjatoslav/meviz/htmlindexer/Main.java b/src/main/java/eu/svjatoslav/meviz/htmlindexer/Main.java index 6c26761..e3e1c7f 100644 --- a/src/main/java/eu/svjatoslav/meviz/htmlindexer/Main.java +++ b/src/main/java/eu/svjatoslav/meviz/htmlindexer/Main.java @@ -1,6 +1,8 @@ package eu.svjatoslav.meviz.htmlindexer; import eu.svjatoslav.meviz.Module; +import eu.svjatoslav.meviz.htmlindexer.indexer.FilesystemIndexRemover; +import eu.svjatoslav.meviz.htmlindexer.indexer.FilesystemIndexer; import java.util.ArrayList; diff --git a/src/main/java/eu/svjatoslav/meviz/htmlindexer/Utils.java b/src/main/java/eu/svjatoslav/meviz/htmlindexer/Utils.java index 82c4b58..01f2d37 100755 --- a/src/main/java/eu/svjatoslav/meviz/htmlindexer/Utils.java +++ b/src/main/java/eu/svjatoslav/meviz/htmlindexer/Utils.java @@ -9,6 +9,7 @@ package eu.svjatoslav.meviz.htmlindexer; +import eu.svjatoslav.meviz.htmlindexer.layouts.Layout; import eu.svjatoslav.meviz.htmlindexer.layouts.MixedLayout; import java.awt.image.BufferedImage; diff --git a/src/main/java/eu/svjatoslav/meviz/htmlindexer/WebIndexer.java b/src/main/java/eu/svjatoslav/meviz/htmlindexer/WebIndexer.java deleted file mode 100644 index d2aabcd..0000000 --- a/src/main/java/eu/svjatoslav/meviz/htmlindexer/WebIndexer.java +++ /dev/null @@ -1,121 +0,0 @@ -package eu.svjatoslav.meviz.htmlindexer; - -import eu.svjatoslav.meviz.htmlindexer.layouts.MixedLayout; -import eu.svjatoslav.meviz.htmlindexer.metadata.Dimension; -import eu.svjatoslav.meviz.htmlindexer.metadata.DirectoryMetadata; -import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.AbstractFile; -import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.Picture; - -import java.io.BufferedInputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.UnsupportedEncodingException; -import java.net.URL; -import java.util.List; - -public class WebIndexer extends AbstractIndexer { - - private static final int METADATA_LOAD_TRY_COUNT = 10; - private final String globalPrefix; - private final String jspPath; - - public WebIndexer(final String globalPrefix, final String jspPath) { - this.globalPrefix = globalPrefix; - this.jspPath = jspPath; - } - - @Override - public void compileHtml(final Layout layout, - final DirectoryMetadata directory) - throws UnsupportedEncodingException { - super.compileHtml(layout, directory); - } - - @Override - public String getDirectoryUrl(final AbstractFile directory, - final IndexingContext context) { - return jspPath + context.getLocalUrl() + "/" + directory.fileName; - } - - public String getHtml(String requestPath) throws - IOException, ClassNotFoundException { - - if (requestPath == null) - requestPath = ""; - - if (requestPath.equals("/")) - requestPath = ""; - - final MixedLayout layout = new MixedLayout(); - final IndexingContext context = new IndexingContext(globalPrefix, - requestPath); - layout.init("Photos", context.getLocalPathComponents(), this, context); - - final DirectoryMetadata directory = getMetadataForPath(requestPath); - - compileHtml(layout, directory); - - return layout.getHtml(false, false, directory); - } - - private DirectoryMetadata getMetadataForPath(final String requestPath) - throws ClassNotFoundException, IOException { - - final String urlString = globalPrefix + Utils.urlEncode(requestPath) + "/.thumbnails/metadata_6.dat"; - - for (int i = 0; true; i++) - try { - return attemptDirectoryMetadataDownload(urlString); - } catch (final IOException e) { - if (i > METADATA_LOAD_TRY_COUNT) throw e; - } - } - - private DirectoryMetadata attemptDirectoryMetadataDownload(String urlString) throws IOException, ClassNotFoundException { - final BufferedInputStream inputStream = new BufferedInputStream(new URL( - urlString).openStream()); - - final ObjectInputStream objectInputStream = new ObjectInputStream(inputStream); - final DirectoryMetadata directory = (DirectoryMetadata) objectInputStream - .readObject(); - inputStream.close(); - - return directory; - } - - @Override - public String getParentDirectoryUrl(final IndexingContext context) { - final StringBuilder result = new StringBuilder(); - - result.append(jspPath); - - final List components = context.getLocalPathComponents(); - - for (final String pathComponent : components.subList(0, - components.size() - 1)) { - result.append("/"); - result.append(pathComponent); - } - - return result.toString(); - } - - @Override - public String getThumbnailUrl(final Picture picture, - final Dimension desiredDimension, final IndexingContext context) { - - // in case thumbnail size was equal to original, then return original - // file path - if (picture.getDimensions().equals(desiredDimension)) - return context.getGlobalUrl() + context.getLocalUrl() + "/" - + picture.fileName; - - final String thumbnailFileName = picture - .getRelativeThumbnailFileName(desiredDimension); - - return context.getGlobalUrl() + context.getLocalUrl() + "/" - + Constants.THUMBNAILS_DIRECTORY_NAME + "/" - + Utils.urlEncode(thumbnailFileName); - } - -} diff --git a/src/main/java/eu/svjatoslav/meviz/htmlindexer/indexer/AbstractIndexer.java b/src/main/java/eu/svjatoslav/meviz/htmlindexer/indexer/AbstractIndexer.java new file mode 100644 index 0000000..0329989 --- /dev/null +++ b/src/main/java/eu/svjatoslav/meviz/htmlindexer/indexer/AbstractIndexer.java @@ -0,0 +1,65 @@ +package eu.svjatoslav.meviz.htmlindexer.indexer; + +import eu.svjatoslav.meviz.htmlindexer.IndexingContext; +import eu.svjatoslav.meviz.htmlindexer.layouts.Layout; +import eu.svjatoslav.meviz.htmlindexer.metadata.Dimension; +import eu.svjatoslav.meviz.htmlindexer.metadata.DirectoryMetadata; +import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.*; + +import java.io.File; +import java.io.UnsupportedEncodingException; + +import static eu.svjatoslav.meviz.htmlindexer.Constants.SUPPORTED_IMAGE_EXTENSIONS; +import static eu.svjatoslav.meviz.htmlindexer.Constants.SUPPORTED_VIDEO_EXTENSIONS; + +public abstract class AbstractIndexer { + + public static boolean isImage(final String fileExtension) { + for (final String ext : SUPPORTED_IMAGE_EXTENSIONS) + if (ext.equals(fileExtension)) + return true; + return false; + } + + public static boolean isVideo(final String fileExtension) { + for (final String ext : SUPPORTED_VIDEO_EXTENSIONS) + if (ext.equals(fileExtension)) + return true; + return false; + } + + static boolean shallFileBeIndexed(final File file) { + + if (file.getName().startsWith(".")) + return false; + if (file.getName().startsWith("index")) + if (file.getName().endsWith(".html")) + return false; + + return true; + } + + void compileHtml(final Layout layout, + final DirectoryMetadata directory) + throws UnsupportedEncodingException { + + for (final AbstractFile file : directory.getFiles()) + if (file instanceof GeneralFile) { + layout.enlistFile(file, directory); + } else if (file instanceof Picture){ + layout.enlistImage((Picture) file, directory); + } else if (file instanceof Video){ + layout.enlistVideo((Video) file); + } else if (file instanceof DirectoryFile) + layout.enlistDirectory(file, directory); + } + + public abstract String getDirectoryUrl(final AbstractFile directory, + IndexingContext context); + + public abstract String getParentDirectoryUrl(IndexingContext context); + + public abstract String getThumbnailUrl(Picture picture, + final Dimension desiredDimension, IndexingContext context); + +} diff --git a/src/main/java/eu/svjatoslav/meviz/htmlindexer/indexer/FilesystemIndexRemover.java b/src/main/java/eu/svjatoslav/meviz/htmlindexer/indexer/FilesystemIndexRemover.java new file mode 100644 index 0000000..9023697 --- /dev/null +++ b/src/main/java/eu/svjatoslav/meviz/htmlindexer/indexer/FilesystemIndexRemover.java @@ -0,0 +1,52 @@ +package eu.svjatoslav.meviz.htmlindexer.indexer; + +import eu.svjatoslav.commons.file.IOHelper; +import eu.svjatoslav.meviz.htmlindexer.CommandlineHandler; +import eu.svjatoslav.meviz.htmlindexer.layouts.Layout; +import eu.svjatoslav.meviz.htmlindexer.Utils; + +import java.io.File; +import java.io.IOException; + +public class FilesystemIndexRemover { + + private final CommandlineHandler commandlineHandler; + + public FilesystemIndexRemover(final CommandlineHandler commandlineHandler) + throws IOException { + this.commandlineHandler = commandlineHandler; + + removeIndex(commandlineHandler.getWorkingDirectory()); + } + + private void removeIndex(final File workingDirectory) throws IOException { + + // remove thumbnails directory from current directory + final File thumbnailsDirectory = Utils + .getThumbnailsDirectory(workingDirectory); + if (thumbnailsDirectory.exists()) { + System.out.println("Deleting thumbnails directory: " + + thumbnailsDirectory); + IOHelper.deleteRecursively(thumbnailsDirectory); + } + + // recursively remove thumbnail directories from sub directories + for (final File subFile : workingDirectory.listFiles()) + if (subFile.isDirectory()) + removeIndex(subFile); + + for (final Layout layout : Utils.getLayouts()) { + final File indexFile = Utils.getLayoutIndexFile(layout, + workingDirectory); + + if (indexFile.exists()) + if (Utils.isMevizGeneratedIndexFile(indexFile)) { + System.out.println("Deleting generated index file: " + + indexFile); + indexFile.delete(); + } + } + + } + +} diff --git a/src/main/java/eu/svjatoslav/meviz/htmlindexer/indexer/FilesystemIndexer.java b/src/main/java/eu/svjatoslav/meviz/htmlindexer/indexer/FilesystemIndexer.java new file mode 100755 index 0000000..6add6be --- /dev/null +++ b/src/main/java/eu/svjatoslav/meviz/htmlindexer/indexer/FilesystemIndexer.java @@ -0,0 +1,203 @@ +/* + * Meviz - Various tools collection to work with multimedia. + * Copyright (C) 2012 -- 2019, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 3 of the GNU Lesser General Public License + * or later as published by the Free Software Foundation. +*/ + +package eu.svjatoslav.meviz.htmlindexer.indexer; + +import eu.svjatoslav.commons.file.IOHelper; +import eu.svjatoslav.meviz.htmlindexer.*; +import eu.svjatoslav.meviz.htmlindexer.layouts.Layout; +import eu.svjatoslav.meviz.htmlindexer.metadata.Dimension; +import eu.svjatoslav.meviz.htmlindexer.metadata.DirectoryMetadata; +import eu.svjatoslav.meviz.htmlindexer.metadata.MetadadaHelper; +import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.AbstractFile; +import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.Picture; +import org.apache.log4j.Logger; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; + +/** + * Main class of HTML indexer. + */ + +public class FilesystemIndexer extends AbstractIndexer { + + private static final Logger logger = Logger + .getLogger(FilesystemIndexer.class); + + private final HashSet validMetadataFiles = new HashSet<>(); + + private final File directoryToIndex; + private final List pathElements; + private final CommandlineHandler commandlineHandler; + private File metadataFile; + private DirectoryMetadata metadata; + private HashSet layouts; + + public FilesystemIndexer(final File directoryToIndex, + final CommandlineHandler commandlineHandler, + final List pathElements) throws Exception { + + this.directoryToIndex = directoryToIndex; + this.commandlineHandler = commandlineHandler; + this.pathElements = pathElements; + + if (!directoryToIndex.canRead()) + return; + + validMetadataFiles.add(Constants.METADATA_FILE_NAME); + + initializeThumbnailsDirectory(); + loadOrCreateMetadata(); + + initializeLayouts(); + + updateMetadata(); + + metadata.removeUnusedMetadataEntries(); + + generateHtmlFromMetadata(layouts); + + removeUnusedThumbnailFiles(); + + // save directory metadata + if (metadata.changed) + MetadadaHelper.saveDirectoryMetadata(metadataFile, metadata); + + } + + private boolean canWriteIndexFile(final File indexFile) + throws IOException { + + return !indexFile.exists() || Utils.isMevizGeneratedIndexFile(indexFile); + + } + + private void generateHtmlFromMetadata(final HashSet layouts) { + // Generate HTML from metadata + for (final Layout layout : layouts) + try { + final File indexFile = Utils.getLayoutIndexFile(layout, + directoryToIndex); + + if (canWriteIndexFile(indexFile)) { + + compileHtml(layout, metadata); + + IOHelper.overwriteFileIfContentDiffers(indexFile, layout + .getHtml(true, true, metadata).getBytes()); + } + } catch (final Exception e) { + logger.error("Error writing index file. ", e); + } + } + + private List getChildPath(final File file) { + + final List result = new ArrayList<>(); + result.addAll(pathElements); + result.add(file.getName()); + + return result; + } + + @Override + public String getDirectoryUrl(final AbstractFile directory, + final IndexingContext context) { + return Utils.urlEncode(directory.fileName) + "/index.html"; + } + + @Override + public String getParentDirectoryUrl(final IndexingContext context) { + return "../index.html"; + } + + @Override + public String getThumbnailUrl(final Picture picture, + final Dimension desiredDimension, final IndexingContext context) { + + // in case thumbnail size was equal to original, then return original + // file path + if (picture.getDimensions().equals(desiredDimension)) + return picture.fileName; + + final String thumbnailFileName = picture + .getRelativeThumbnailFileName(desiredDimension); + + validMetadataFiles.add(thumbnailFileName); + final File thumbnailFile = new File( + Utils.getThumbnailsDirectoryPath(directoryToIndex) + + thumbnailFileName); + + if (!thumbnailFile.exists()) { + + final File originalFile = new File( + directoryToIndex.getAbsolutePath() + "/" + picture.fileName); + + // generate new thumbnail + Picture.makeThumbnail(originalFile, thumbnailFile, + desiredDimension.getAwtDimension()); + } + return Constants.THUMBNAILS_DIRECTORY_NAME + "/" + + Utils.urlEncode(thumbnailFileName); + } + + private void initializeLayouts() { + + layouts = Utils.getLayouts(); + + final String galleryTitle = commandlineHandler.getGalleryTitle(); + + for (final Layout layout : layouts) + layout.init(galleryTitle, pathElements, this, new IndexingContext( + "", ".")); + } + + private void initializeThumbnailsDirectory() { + final File thumbnailsDirectory = Utils + .getThumbnailsDirectory(directoryToIndex); + + if (!thumbnailsDirectory.exists()) + thumbnailsDirectory.mkdirs(); + } + + private void loadOrCreateMetadata() { + + metadataFile = new File( + Utils.getThumbnailsDirectoryPath(directoryToIndex) + + Constants.METADATA_FILE_NAME); + + metadata = MetadadaHelper.initDirectoryMetadata(metadataFile); + } + + private void removeUnusedThumbnailFiles() { + + for (final File file : Utils.getThumbnailsDirectory(directoryToIndex) + .listFiles()) + if (!validMetadataFiles.contains(file.getName())) + file.delete(); + + } + + private void updateMetadata() throws Exception { + + for (final File file : directoryToIndex.listFiles()) + if (shallFileBeIndexed(file)) { + + metadata.ensureFileMetadataIsUpToDate(directoryToIndex, file); + + if (file.isDirectory()) + new FilesystemIndexer(file, commandlineHandler, + getChildPath(file)); + } + } +} diff --git a/src/main/java/eu/svjatoslav/meviz/htmlindexer/indexer/WebIndexer.java b/src/main/java/eu/svjatoslav/meviz/htmlindexer/indexer/WebIndexer.java new file mode 100644 index 0000000..966d10f --- /dev/null +++ b/src/main/java/eu/svjatoslav/meviz/htmlindexer/indexer/WebIndexer.java @@ -0,0 +1,125 @@ +package eu.svjatoslav.meviz.htmlindexer.indexer; + +import eu.svjatoslav.meviz.htmlindexer.Constants; +import eu.svjatoslav.meviz.htmlindexer.IndexingContext; +import eu.svjatoslav.meviz.htmlindexer.layouts.Layout; +import eu.svjatoslav.meviz.htmlindexer.Utils; +import eu.svjatoslav.meviz.htmlindexer.layouts.MixedLayout; +import eu.svjatoslav.meviz.htmlindexer.metadata.Dimension; +import eu.svjatoslav.meviz.htmlindexer.metadata.DirectoryMetadata; +import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.AbstractFile; +import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.Picture; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.UnsupportedEncodingException; +import java.net.URL; +import java.util.List; + +public class WebIndexer extends AbstractIndexer { + + private static final int METADATA_LOAD_TRY_COUNT = 10; + private final String globalPrefix; + private final String jspPath; + + public WebIndexer(final String globalPrefix, final String jspPath) { + this.globalPrefix = globalPrefix; + this.jspPath = jspPath; + } + + @Override + public void compileHtml(final Layout layout, + final DirectoryMetadata directory) + throws UnsupportedEncodingException { + super.compileHtml(layout, directory); + } + + @Override + public String getDirectoryUrl(final AbstractFile directory, + final IndexingContext context) { + return jspPath + context.getLocalUrl() + "/" + directory.fileName; + } + + public String getHtml(String requestPath) throws + IOException, ClassNotFoundException { + + if (requestPath == null) + requestPath = ""; + + if (requestPath.equals("/")) + requestPath = ""; + + final MixedLayout layout = new MixedLayout(); + final IndexingContext context = new IndexingContext(globalPrefix, + requestPath); + layout.init("Photos", context.getLocalPathComponents(), this, context); + + final DirectoryMetadata directory = getMetadataForPath(requestPath); + + compileHtml(layout, directory); + + return layout.getHtml(false, false, directory); + } + + private DirectoryMetadata getMetadataForPath(final String requestPath) + throws ClassNotFoundException, IOException { + + final String urlString = globalPrefix + Utils.urlEncode(requestPath) + "/.thumbnails/metadata_6.dat"; + + for (int i = 0; true; i++) + try { + return attemptDirectoryMetadataDownload(urlString); + } catch (final IOException e) { + if (i > METADATA_LOAD_TRY_COUNT) throw e; + } + } + + private DirectoryMetadata attemptDirectoryMetadataDownload(String urlString) throws IOException, ClassNotFoundException { + final BufferedInputStream inputStream = new BufferedInputStream(new URL( + urlString).openStream()); + + final ObjectInputStream objectInputStream = new ObjectInputStream(inputStream); + final DirectoryMetadata directory = (DirectoryMetadata) objectInputStream + .readObject(); + inputStream.close(); + + return directory; + } + + @Override + public String getParentDirectoryUrl(final IndexingContext context) { + final StringBuilder result = new StringBuilder(); + + result.append(jspPath); + + final List components = context.getLocalPathComponents(); + + for (final String pathComponent : components.subList(0, + components.size() - 1)) { + result.append("/"); + result.append(pathComponent); + } + + return result.toString(); + } + + @Override + public String getThumbnailUrl(final Picture picture, + final Dimension desiredDimension, final IndexingContext context) { + + // in case thumbnail size was equal to original, then return original + // file path + if (picture.getDimensions().equals(desiredDimension)) + return context.getGlobalUrl() + context.getLocalUrl() + "/" + + picture.fileName; + + final String thumbnailFileName = picture + .getRelativeThumbnailFileName(desiredDimension); + + return context.getGlobalUrl() + context.getLocalUrl() + "/" + + Constants.THUMBNAILS_DIRECTORY_NAME + "/" + + Utils.urlEncode(thumbnailFileName); + } + +} diff --git a/src/main/java/eu/svjatoslav/meviz/htmlindexer/layouts/Layout.java b/src/main/java/eu/svjatoslav/meviz/htmlindexer/layouts/Layout.java new file mode 100755 index 0000000..ef250e5 --- /dev/null +++ b/src/main/java/eu/svjatoslav/meviz/htmlindexer/layouts/Layout.java @@ -0,0 +1,74 @@ +/* + * Meviz - Various tools collection to work with multimedia. + * Copyright (C) 2012 -- 2019, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 3 of the GNU Lesser General Public License + * or later as published by the Free Software Foundation. +*/ + +package eu.svjatoslav.meviz.htmlindexer.layouts; + +import eu.svjatoslav.meviz.htmlindexer.IndexingContext; +import eu.svjatoslav.meviz.htmlindexer.indexer.AbstractIndexer; +import eu.svjatoslav.meviz.htmlindexer.metadata.DirectoryMetadata; +import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.AbstractFile; +import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.Picture; +import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.Video; + +import java.util.List; + +/** + * In order to have possibility of several different layouts per directory. + * Universal interface is defined. + *

+ * Layout implementation is responsible for actual HTML generation. + */ + +public interface Layout { + + /** + * Enlist directory. + */ + void enlistDirectory(AbstractFile directory, + DirectoryMetadata parentDirectoryMetadata); + + /** + * Enlist simple file. + */ + void enlistFile(AbstractFile file, + DirectoryMetadata parentDirectoryMetadata); + + /** + * Enlist image file. + */ + void enlistImage(Picture picture, + DirectoryMetadata parentDirectoryMetadata); + + /** + * Enlist video file. + */ + void enlistVideo(Video file); + + /** + * Return layout specific suffix that will be appended between + * index(suffix).html of generated file. This way multiple layouts can + * coexist in the same directory, each residing in its own HTML file. + */ + String getFileNameSuffix(); + + /** + * After necessary files have been enlisted for particular directory, use + * this method to retrieve generated HTML result. + */ + String getHtml(final boolean showTitle, + final boolean doHtmlHeaderAndFooter, DirectoryMetadata metadata) + ; + + /** + * Initialize layout for particular directory. + */ + void init(String galleryTitle, List path, + final AbstractIndexer indexer, IndexingContext context); + +} diff --git a/src/main/java/eu/svjatoslav/meviz/htmlindexer/layouts/MixedLayout.java b/src/main/java/eu/svjatoslav/meviz/htmlindexer/layouts/MixedLayout.java index 13aaff3..49ffa7e 100755 --- a/src/main/java/eu/svjatoslav/meviz/htmlindexer/layouts/MixedLayout.java +++ b/src/main/java/eu/svjatoslav/meviz/htmlindexer/layouts/MixedLayout.java @@ -10,10 +10,9 @@ package eu.svjatoslav.meviz.htmlindexer.layouts; import eu.svjatoslav.commons.file.FilePathParser; -import eu.svjatoslav.meviz.htmlindexer.AbstractIndexer; +import eu.svjatoslav.meviz.htmlindexer.indexer.AbstractIndexer; import eu.svjatoslav.meviz.htmlindexer.Constants; import eu.svjatoslav.meviz.htmlindexer.IndexingContext; -import eu.svjatoslav.meviz.htmlindexer.Layout; import eu.svjatoslav.meviz.htmlindexer.metadata.Dimension; import eu.svjatoslav.meviz.htmlindexer.metadata.DirectoryMetadata; import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.AbstractFile; diff --git a/src/main/java/eu/svjatoslav/meviz/htmlindexer/metadata/DirectoryMetadata.java b/src/main/java/eu/svjatoslav/meviz/htmlindexer/metadata/DirectoryMetadata.java index ec10f90..f165694 100755 --- a/src/main/java/eu/svjatoslav/meviz/htmlindexer/metadata/DirectoryMetadata.java +++ b/src/main/java/eu/svjatoslav/meviz/htmlindexer/metadata/DirectoryMetadata.java @@ -17,8 +17,8 @@ import java.io.File; import java.io.Serializable; import java.util.*; -import static eu.svjatoslav.meviz.htmlindexer.AbstractIndexer.isImage; -import static eu.svjatoslav.meviz.htmlindexer.AbstractIndexer.isVideo; +import static eu.svjatoslav.meviz.htmlindexer.indexer.AbstractIndexer.isImage; +import static eu.svjatoslav.meviz.htmlindexer.indexer.AbstractIndexer.isVideo; /** * Corresponds to single filesystem directory.