2 * Meviz - Various tools collection to work with multimedia.
3 * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of version 2 of the GNU General Public License
7 * as published by the Free Software Foundation.
10 package eu.svjatoslav.meviz.htmlindexer;
12 import java.io.BufferedReader;
14 import java.io.FileNotFoundException;
15 import java.io.FileReader;
16 import java.io.IOException;
17 import java.io.UnsupportedEncodingException;
18 import java.util.HashSet;
20 import org.apache.log4j.Logger;
22 import eu.svjatoslav.commons.file.IOHelper;
23 import eu.svjatoslav.meviz.htmlindexer.layouts.MixedLayout;
24 import eu.svjatoslav.meviz.htmlindexer.metadata.Dimension;
25 import eu.svjatoslav.meviz.htmlindexer.metadata.DirectoryMetadata;
26 import eu.svjatoslav.meviz.htmlindexer.metadata.MetadadaHelper;
27 import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.AbstractFile;
28 import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.DirectoryFile;
29 import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.GeneralFile;
30 import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.Picture;
33 * Main class of HTML indexer.
36 public class FilesystemIndexer extends AbstractIndexer {
38 public static final Logger logger = Logger
39 .getLogger(FilesystemIndexer.class);
41 private final HashSet<String> validMetadataFiles = new HashSet<String>();
43 private final File directoryToIndex;
45 private String thumbnailsPath;
47 private File metadataFile;
49 private DirectoryMetadata metadata;
51 private final IndexingOptions indexingOptions;
53 private final String[] pathElements;
55 private HashSet<Layout> layouts;
57 public FilesystemIndexer(final File directoryToIndex,
58 final IndexingOptions indexingOptions, final String[] pathElements)
59 throws IOException, ImageFormatError {
61 this.directoryToIndex = directoryToIndex;
62 this.indexingOptions = indexingOptions;
63 this.pathElements = pathElements;
65 if (!directoryToIndex.canRead())
68 validMetadataFiles.add(Constants.METADATA_FILE_NAME);
70 initializeThumbnailsDirectory();
71 loadOrCreateMetadata();
77 metadata.removeUnusedMetadataEntries();
79 generateHtmlFromMetadata(layouts);
81 removeUnusedThumbnailFiles();
83 // save directory metadata
85 MetadadaHelper.saveDirectoryMetadata(metadataFile, metadata);
89 public boolean canWriteIndexFile(final File indexFile)
90 throws FileNotFoundException, IOException {
91 boolean canWriteIndexFile = false;
93 if (indexFile.exists()) {
94 // if file already exists, make sure that we can overwrite
96 final FileReader fileReader = new FileReader(indexFile);
97 final BufferedReader reader = new BufferedReader(fileReader);
101 final String line = reader.readLine();
106 if (line.contains(Constants.HTML_MAGIC_STRING)) {
107 canWriteIndexFile = true;
116 canWriteIndexFile = true;
117 return canWriteIndexFile;
120 public void cleanupUnusedMetadataFiles() {
121 final File thumbnailsDirectory = new File(thumbnailsPath);
123 for (final File file : thumbnailsDirectory.listFiles())
124 if (!validMetadataFiles.contains(file.getName()))
128 public void generateHtmlFromMetadata(final HashSet<Layout> layouts) {
129 // Generate HTML from metadata
130 for (final Layout layout : layouts) {
132 final String indexFilePath = directoryToIndex.getAbsolutePath()
133 + "/index" + layout.getFileNameSuffix() + ".html";
137 final File indexFile = new File(indexFilePath);
138 if (canWriteIndexFile(indexFile)) {
140 indexForLayout(layout);
142 IOHelper.overwriteFileIfContentDiffers(indexFile, layout
143 .getHtml().getBytes());
145 } catch (final Exception e) {
146 logger.error("Error writing index file to:" + indexFilePath, e);
152 public String getDirectoryUrl(final AbstractFile directory) {
153 return directory.fileName + "/index.html";
156 public String[] getSubPath(final File file) {
158 final String[] subPath = new String[pathElements.length + 1];
160 for (int i = 0; i < pathElements.length; i++)
161 subPath[i] = pathElements[i];
163 subPath[pathElements.length] = file.getName();
168 public String getThumbnailPath(final Picture picture,
169 final Dimension desiredDimension) {
171 // in case thumbnail size was equal to original, then return original
173 if (picture.getDimensions().equals(desiredDimension))
174 return picture.fileName;
176 final String thumbnailFileName = picture
177 .getRelativeThumbnailFileName(desiredDimension);
179 validMetadataFiles.add(thumbnailFileName);
180 final File thumbnailFile = new File(thumbnailsPath + thumbnailFileName);
182 if (!thumbnailFile.exists()) {
184 final File originalFile = new File(
185 directoryToIndex.getAbsolutePath() + "/" + picture.fileName);
187 // generate new thumbnail
188 Picture.makeThumbnail(originalFile, thumbnailFile,
189 desiredDimension.getAwtDimension());
191 return Constants.THUMBNAILS_DIRECTORY_NAME + "/" + thumbnailFileName;
194 public void indexForLayout(final Layout layout)
195 throws UnsupportedEncodingException {
197 for (final AbstractFile abstractFile : metadata.getFiles())
198 if (abstractFile instanceof GeneralFile) {
200 if (isOgv(abstractFile.getFileExtension()))
201 layout.enlistOgv(abstractFile);
203 layout.enlistFile(abstractFile);
205 } else if (abstractFile instanceof Picture)
206 layout.enlistImage(abstractFile);
207 else if (abstractFile instanceof DirectoryFile)
208 layout.enlistDirectory(abstractFile);
212 public void initializeLayouts() {
213 layouts = new HashSet<Layout>();
214 layouts.add(new MixedLayout());
216 for (final Layout layout : layouts)
217 layout.init(indexingOptions.galleryTitle, pathElements, this, "");
220 public void initializeThumbnailsDirectory() {
221 // initialize thumbnails directory
222 thumbnailsPath = directoryToIndex.getAbsolutePath() + "/"
223 + Constants.THUMBNAILS_DIRECTORY_NAME + "/";
225 // ensure thumbnails directory exists
226 final File thumbnailsDirectory = new File(thumbnailsPath);
227 if (!thumbnailsDirectory.exists())
228 thumbnailsDirectory.mkdirs();
231 public void loadOrCreateMetadata() {
232 metadataFile = new File(thumbnailsPath + Constants.METADATA_FILE_NAME);
234 metadata = MetadadaHelper.initDirectoryMetadata(metadataFile);
237 private void removeUnusedThumbnailFiles() {
239 final File thumbnailsDirectory = new File(thumbnailsPath);
241 for (final File file : thumbnailsDirectory.listFiles())
242 if (!validMetadataFiles.contains(file.getName()))
247 public void updateMetadata() throws IOException, ImageFormatError {
249 final File[] directoryContent = directoryToIndex.listFiles();
251 for (final File file : directoryContent)
252 if (shallFileBeIndexed(file)) {
254 metadata.ensureFileMetainfoIsUpToDate(directoryToIndex, file);
256 if (file.isDirectory())
257 new FilesystemIndexer(file, indexingOptions,