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.ArrayList;
19 import java.util.HashSet;
20 import java.util.List;
22 import org.apache.log4j.Logger;
24 import eu.svjatoslav.commons.file.IOHelper;
25 import eu.svjatoslav.commons.network.UrlParamEncoder;
26 import eu.svjatoslav.meviz.htmlindexer.layouts.MixedLayout;
27 import eu.svjatoslav.meviz.htmlindexer.metadata.Dimension;
28 import eu.svjatoslav.meviz.htmlindexer.metadata.DirectoryMetadata;
29 import eu.svjatoslav.meviz.htmlindexer.metadata.MetadadaHelper;
30 import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.AbstractFile;
31 import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.DirectoryFile;
32 import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.GeneralFile;
33 import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.Picture;
36 * Main class of HTML indexer.
39 public class FilesystemIndexer extends AbstractIndexer {
41 public static final Logger logger = Logger
42 .getLogger(FilesystemIndexer.class);
44 private final HashSet<String> validMetadataFiles = new HashSet<String>();
46 private final File directoryToIndex;
48 private String thumbnailsPath;
50 private File metadataFile;
52 private DirectoryMetadata metadata;
54 private final IndexingOptions indexingOptions;
56 private final List<String> pathElements;
58 private HashSet<Layout> layouts;
60 public FilesystemIndexer(final File directoryToIndex,
61 final IndexingOptions indexingOptions,
62 final List<String> pathElements) throws IOException,
65 this.directoryToIndex = directoryToIndex;
66 this.indexingOptions = indexingOptions;
67 this.pathElements = pathElements;
69 if (!directoryToIndex.canRead())
72 validMetadataFiles.add(Constants.METADATA_FILE_NAME);
74 initializeThumbnailsDirectory();
75 loadOrCreateMetadata();
81 metadata.removeUnusedMetadataEntries();
83 generateHtmlFromMetadata(layouts);
85 removeUnusedThumbnailFiles();
87 // save directory metadata
89 MetadadaHelper.saveDirectoryMetadata(metadataFile, metadata);
93 public boolean canWriteIndexFile(final File indexFile)
94 throws FileNotFoundException, IOException {
95 boolean canWriteIndexFile = false;
97 if (indexFile.exists()) {
98 // if file already exists, make sure that we can overwrite
100 final FileReader fileReader = new FileReader(indexFile);
101 final BufferedReader reader = new BufferedReader(fileReader);
105 final String line = reader.readLine();
110 if (line.contains(Constants.HTML_MAGIC_STRING)) {
111 canWriteIndexFile = true;
120 canWriteIndexFile = true;
121 return canWriteIndexFile;
124 public void cleanupUnusedMetadataFiles() {
125 final File thumbnailsDirectory = new File(thumbnailsPath);
127 for (final File file : thumbnailsDirectory.listFiles())
128 if (!validMetadataFiles.contains(file.getName()))
132 public void generateHtmlFromMetadata(final HashSet<Layout> layouts) {
133 // Generate HTML from metadata
134 for (final Layout layout : layouts) {
136 final String indexFilePath = directoryToIndex.getAbsolutePath()
137 + "/index" + layout.getFileNameSuffix() + ".html";
141 final File indexFile = new File(indexFilePath);
142 if (canWriteIndexFile(indexFile)) {
144 indexForLayout(layout);
146 IOHelper.overwriteFileIfContentDiffers(indexFile, layout
147 .getHtml(true, true).getBytes());
149 } catch (final Exception e) {
150 logger.error("Error writing index file to:" + indexFilePath, e);
155 public List<String> getChildPath(final File file) {
157 final List<String> result = new ArrayList<String>();
158 result.addAll(pathElements);
159 result.add(file.getName());
165 public String getDirectoryUrl(final AbstractFile directory,
166 final IndexingContext context) {
167 return directory.fileName + "/index.html";
171 public String getParentDirectoryUrl(final IndexingContext context) {
172 return "../index.html";
176 public String getThumbnailUrl(final Picture picture,
177 final Dimension desiredDimension, final IndexingContext context) {
179 // in case thumbnail size was equal to original, then return original
181 if (picture.getDimensions().equals(desiredDimension))
182 return picture.fileName;
184 final String thumbnailFileName = picture
185 .getRelativeThumbnailFileName(desiredDimension);
187 validMetadataFiles.add(thumbnailFileName);
188 final File thumbnailFile = new File(thumbnailsPath + thumbnailFileName);
190 if (!thumbnailFile.exists()) {
192 final File originalFile = new File(
193 directoryToIndex.getAbsolutePath() + "/" + picture.fileName);
195 // generate new thumbnail
196 Picture.makeThumbnail(originalFile, thumbnailFile,
197 desiredDimension.getAwtDimension());
199 return Constants.THUMBNAILS_DIRECTORY_NAME + "/"
200 + UrlParamEncoder.encode(thumbnailFileName);
203 public void indexForLayout(final Layout layout)
204 throws UnsupportedEncodingException {
206 for (final AbstractFile abstractFile : metadata.getFiles())
207 if (abstractFile instanceof GeneralFile) {
209 if (isOgv(abstractFile.getFileExtension()))
210 layout.enlistOgv(abstractFile);
212 layout.enlistFile(abstractFile);
214 } else if (abstractFile instanceof Picture)
215 layout.enlistImage(abstractFile);
216 else if (abstractFile instanceof DirectoryFile)
217 layout.enlistDirectory(abstractFile);
221 public void initializeLayouts() {
222 layouts = new HashSet<Layout>();
223 layouts.add(new MixedLayout());
225 for (final Layout layout : layouts)
226 layout.init(indexingOptions.galleryTitle, pathElements, this,
227 new IndexingContext("", "."));
230 public void initializeThumbnailsDirectory() {
231 // initialize thumbnails directory
232 thumbnailsPath = directoryToIndex.getAbsolutePath() + "/"
233 + Constants.THUMBNAILS_DIRECTORY_NAME + "/";
235 // ensure thumbnails directory exists
236 final File thumbnailsDirectory = new File(thumbnailsPath);
237 if (!thumbnailsDirectory.exists())
238 thumbnailsDirectory.mkdirs();
241 public void loadOrCreateMetadata() {
242 metadataFile = new File(thumbnailsPath + Constants.METADATA_FILE_NAME);
244 metadata = MetadadaHelper.initDirectoryMetadata(metadataFile);
247 private void removeUnusedThumbnailFiles() {
249 final File thumbnailsDirectory = new File(thumbnailsPath);
251 for (final File file : thumbnailsDirectory.listFiles())
252 if (!validMetadataFiles.contains(file.getName()))
257 public void updateMetadata() throws IOException, ImageFormatError {
259 final File[] directoryContent = directoryToIndex.listFiles();
261 for (final File file : directoryContent)
262 if (shallFileBeIndexed(file)) {
264 metadata.ensureFileMetainfoIsUpToDate(directoryToIndex, file);
266 if (file.isDirectory())
267 new FilesystemIndexer(file, indexingOptions,