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