added webm support
[meviz.git] / src / main / java / eu / svjatoslav / meviz / htmlindexer / FilesystemIndexer.java
1 /*
2  * Meviz - Various tools collection to work with multimedia.
3  * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
4  *
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.
8  */
9
10 package eu.svjatoslav.meviz.htmlindexer;
11
12 import java.io.File;
13 import java.io.FileNotFoundException;
14 import java.io.IOException;
15 import java.util.ArrayList;
16 import java.util.HashSet;
17 import java.util.List;
18
19 import org.apache.log4j.Logger;
20
21 import eu.svjatoslav.commons.file.IOHelper;
22 import eu.svjatoslav.commons.network.UrlParamEncoder;
23 import eu.svjatoslav.meviz.htmlindexer.metadata.Dimension;
24 import eu.svjatoslav.meviz.htmlindexer.metadata.DirectoryMetadata;
25 import eu.svjatoslav.meviz.htmlindexer.metadata.MetadadaHelper;
26 import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.AbstractFile;
27 import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.Picture;
28
29 /**
30  * Main class of HTML indexer.
31  */
32
33 public class FilesystemIndexer extends AbstractIndexer {
34
35         public static final Logger logger = Logger
36                         .getLogger(FilesystemIndexer.class);
37
38         private final HashSet<String> validMetadataFiles = new HashSet<String>();
39
40         private final File directoryToIndex;
41
42         private File metadataFile;
43
44         private DirectoryMetadata metadata;
45
46         private final List<String> pathElements;
47
48         private HashSet<Layout> layouts;
49
50         private final CommandlineHandler commandlineHandler;
51
52         public FilesystemIndexer(final File directoryToIndex,
53                         final CommandlineHandler commandlineHandler,
54                         final List<String> pathElements) throws Exception {
55
56                 this.directoryToIndex = directoryToIndex;
57                 this.commandlineHandler = commandlineHandler;
58                 this.pathElements = pathElements;
59
60                 if (!directoryToIndex.canRead())
61                         return;
62
63                 validMetadataFiles.add(Constants.METADATA_FILE_NAME);
64
65                 initializeThumbnailsDirectory();
66                 loadOrCreateMetadata();
67
68                 initializeLayouts();
69
70                 updateMetadata();
71
72                 metadata.removeUnusedMetadataEntries();
73
74                 generateHtmlFromMetadata(layouts);
75
76                 removeUnusedThumbnailFiles();
77
78                 // save directory metadata
79                 if (metadata.changed)
80                         MetadadaHelper.saveDirectoryMetadata(metadataFile, metadata);
81
82         }
83
84         public boolean canWriteIndexFile(final File indexFile)
85                         throws FileNotFoundException, IOException {
86
87                 if (!indexFile.exists())
88                         return true;
89
90                 return Utils.isMevizGeneratedIndexFile(indexFile);
91         }
92
93         public void generateHtmlFromMetadata(final HashSet<Layout> layouts) {
94                 // Generate HTML from metadata
95                 for (final Layout layout : layouts)
96                         try {
97                                 final File indexFile = Utils.getLayoutIndexFile(layout,
98                                                 directoryToIndex);
99
100                                 if (canWriteIndexFile(indexFile)) {
101
102                                         compileHtml(layout, metadata);
103
104                                         IOHelper.overwriteFileIfContentDiffers(indexFile, layout
105                                                         .getHtml(true, true, metadata).getBytes());
106                                 }
107                         } catch (final Exception e) {
108                                 logger.error("Error writing index file. ", e);
109                         }
110         }
111
112         public List<String> getChildPath(final File file) {
113
114                 final List<String> result = new ArrayList<String>();
115                 result.addAll(pathElements);
116                 result.add(file.getName());
117
118                 return result;
119         }
120
121         @Override
122         public String getDirectoryUrl(final AbstractFile directory,
123                         final IndexingContext context) {
124                 return directory.fileName + "/index.html";
125         }
126
127         @Override
128         public String getParentDirectoryUrl(final IndexingContext context) {
129                 return "../index.html";
130         }
131
132         @Override
133         public String getThumbnailUrl(final Picture picture,
134                         final Dimension desiredDimension, final IndexingContext context) {
135
136                 // in case thumbnail size was equal to original, then return original
137                 // file path
138                 if (picture.getDimensions().equals(desiredDimension))
139                         return picture.fileName;
140
141                 final String thumbnailFileName = picture
142                                 .getRelativeThumbnailFileName(desiredDimension);
143
144                 validMetadataFiles.add(thumbnailFileName);
145                 final File thumbnailFile = new File(
146                                 Utils.getThumbnailsDirectoryPath(directoryToIndex)
147                                                 + thumbnailFileName);
148
149                 if (!thumbnailFile.exists()) {
150
151                         final File originalFile = new File(
152                                         directoryToIndex.getAbsolutePath() + "/" + picture.fileName);
153
154                         // generate new thumbnail
155                         Picture.makeThumbnail(originalFile, thumbnailFile,
156                                         desiredDimension.getAwtDimension());
157                 }
158                 return Constants.THUMBNAILS_DIRECTORY_NAME + "/"
159                                 + UrlParamEncoder.encode(thumbnailFileName);
160         }
161
162         public void initializeLayouts() {
163
164                 layouts = Utils.getLayouts();
165
166                 final String galleryTitle = commandlineHandler.getGalleryTitle();
167
168                 for (final Layout layout : layouts)
169                         layout.init(galleryTitle, pathElements, this, new IndexingContext(
170                                         "", "."));
171         }
172
173         public void initializeThumbnailsDirectory() {
174                 final File thumbnailsDirectory = Utils
175                                 .getThumbnailsDirectory(directoryToIndex);
176
177                 if (!thumbnailsDirectory.exists())
178                         thumbnailsDirectory.mkdirs();
179         }
180
181         public void loadOrCreateMetadata() {
182
183                 metadataFile = new File(
184                                 Utils.getThumbnailsDirectoryPath(directoryToIndex)
185                                                 + Constants.METADATA_FILE_NAME);
186
187                 metadata = MetadadaHelper.initDirectoryMetadata(metadataFile);
188         }
189
190         private void removeUnusedThumbnailFiles() {
191
192                 for (final File file : Utils.getThumbnailsDirectory(directoryToIndex)
193                                 .listFiles())
194                         if (!validMetadataFiles.contains(file.getName()))
195                                 file.delete();
196
197         }
198
199         public void updateMetadata() throws Exception {
200
201                 for (final File file : directoryToIndex.listFiles())
202                         if (shallFileBeIndexed(file)) {
203
204                                 metadata.ensureFileMetainfoIsUpToDate(directoryToIndex, file);
205
206                                 if (file.isDirectory())
207                                         new FilesystemIndexer(file, commandlineHandler,
208                                                         getChildPath(file));
209                         }
210         }
211 }