Added WebP thumbnail support
[meviz.git] / src / main / java / eu / svjatoslav / meviz / htmlindexer / metadata / DirectoryMetadata.java
1 /*
2  * Meviz - Various tools collection to work with multimedia. Author: Svjatoslav Agejenko.
3  * This project is released under Creative Commons Zero (CC0) license.
4  */
5
6
7 package eu.svjatoslav.meviz.htmlindexer.metadata;
8
9 import eu.svjatoslav.commons.file.FilePathParser;
10 import eu.svjatoslav.meviz.htmlindexer.FileSortComparator;
11 import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.*;
12
13 import java.io.File;
14 import java.io.Serializable;
15 import java.util.*;
16
17 import static eu.svjatoslav.meviz.htmlindexer.indexer.AbstractIndexer.isImage;
18 import static eu.svjatoslav.meviz.htmlindexer.indexer.AbstractIndexer.isVideo;
19
20 /**
21  * Corresponds to single filesystem directory.
22  */
23 public class DirectoryMetadata implements Serializable {
24
25     private static final long serialVersionUID = 3526489102725366334L;
26
27     private final HashMap<String, AbstractFile> fileNameToFileMap = new HashMap<>();
28
29     public transient boolean changed;
30
31     /**
32      * Performs cleanup of directory model. In particular removes metadata for
33      * images that no longer exist in the filesystem.
34      */
35     public void cleanup() {
36         final Iterator<AbstractFile> fileIterator = fileNameToFileMap.values()
37                 .iterator();
38
39         while (fileIterator.hasNext()) {
40             final AbstractFile file = fileIterator.next();
41
42             if (!file.isMetadataVerified())
43                 fileIterator.remove();
44         }
45     }
46
47     public void ensureFileMetadataIsUpToDate(final File parentDirectory,
48                                              final File file) throws Exception {
49
50         final String fileName = file.getName();
51
52         if (fileNameToFileMap.containsKey(fileName)) {
53             final boolean metadataUpdated = fileNameToFileMap.get(fileName)
54                     .ensureFileMetadataIsUpToDate(parentDirectory);
55
56             if (metadataUpdated)
57                 changed = true;
58         } else
59             registerFile(parentDirectory, file);
60
61     }
62
63     private AbstractFile getAbstractFile(final File parentDirectory,
64                                          final File file, final String fileName) throws Exception {
65
66         if (file.isDirectory())
67             return new DirectoryFile(parentDirectory, fileName);
68
69         final String fileExtension = FilePathParser.getFileExtension(fileName)
70                 .toLowerCase();
71
72         if (isImage(fileExtension))
73             try {
74                 return new Picture(parentDirectory, fileName);
75             } catch (final Exception exception) {
76                 System.out.println("Failed to decode image \"" + fileName +"\" indexing as normal file instead.");
77
78                 // in case image decoding failed, handle image as general file
79                 return new GeneralFile(parentDirectory, fileName);
80             }
81
82         if (isVideo(fileExtension))
83             try {
84                 return new Video(parentDirectory, fileName);
85             } catch (final Exception exception) {
86                 // in case video decoding failed, handle it as general file
87                 return new GeneralFile(parentDirectory, fileName);
88             }
89
90         if (fileName.endsWith(".meviz.org"))
91             return new MevizSpecialFile(parentDirectory, fileName);
92
93         if (fileName.endsWith(".meviz.html"))
94             return new MevizSpecialFile(parentDirectory, fileName);
95
96         return new GeneralFile(parentDirectory, fileName);
97     }
98
99     private AbstractFile getFile(final String fileName) {
100         return fileNameToFileMap.get(fileName);
101     }
102
103     public Collection<AbstractFile> getFiles() {
104
105         final ArrayList<AbstractFile> files = new ArrayList<>(
106                 fileNameToFileMap.values());
107
108         Collections.sort(files, new FileSortComparator());
109
110         return files;
111     }
112
113     public String getHeaderMevizMetadataHtml() {
114         final AbstractFile headerFile = getFile("header.meviz.html");
115         if (headerFile == null)
116             return "";
117
118         final MevizSpecialFile mevizSpecialFile = (MevizSpecialFile) headerFile;
119         return mevizSpecialFile.getFileContent();
120     }
121
122     public Dimension getImageDimensions(final String fileName) {
123
124         return ((Picture) getFile(fileName)).getDimensions();
125     }
126
127     private AbstractFile registerFile(final File parentDirectory, final File file)
128             throws Exception {
129
130         final String fileName = file.getName();
131
132         final AbstractFile abstractFile = getAbstractFile(parentDirectory,
133                 file, fileName);
134
135         fileNameToFileMap.put(fileName, abstractFile);
136
137         changed = true;
138
139         return abstractFile;
140     }
141
142     public void removeUnusedMetadataEntries() {
143
144         new HashSet<>(fileNameToFileMap.keySet()).stream().filter(key -> !fileNameToFileMap.get(key).isMetadataVerified()).forEach(key -> {
145             fileNameToFileMap.remove(key);
146             changed = true;
147         });
148
149     }
150 }