Added WebP thumbnail support
[meviz.git] / src / main / java / eu / svjatoslav / meviz / htmlindexer / indexer / WebIndexer.java
1 package eu.svjatoslav.meviz.htmlindexer.indexer;
2
3 import eu.svjatoslav.meviz.htmlindexer.Constants;
4 import eu.svjatoslav.meviz.htmlindexer.IndexingContext;
5 import eu.svjatoslav.meviz.htmlindexer.layouts.Layout;
6 import eu.svjatoslav.meviz.htmlindexer.layouts.MixedLayout;
7 import eu.svjatoslav.meviz.htmlindexer.metadata.Dimension;
8 import eu.svjatoslav.meviz.htmlindexer.metadata.DirectoryMetadata;
9 import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.AbstractFile;
10 import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.Picture;
11
12 import java.io.BufferedInputStream;
13 import java.io.IOException;
14 import java.io.ObjectInputStream;
15 import java.io.UnsupportedEncodingException;
16 import java.net.URL;
17 import java.util.List;
18
19 import static eu.svjatoslav.meviz.htmlindexer.Constants.METADATA_FILE_NAME;
20 import static eu.svjatoslav.meviz.htmlindexer.Utils.urlEncode;
21
22 public class WebIndexer extends AbstractIndexer {
23
24     private static final int METADATA_LOAD_TRY_COUNT = 10;
25
26     /**
27      * Example: "https://www3.svjatoslav.eu/web/photos"
28      */
29     private final String contentServerRootUrl;
30
31     /**
32      * Example: "http://www3.svjatoslav.eu/web/photos"
33      */
34     private String metadataServerRootUrl;
35
36     /**
37      * Path relative to frontend server. For example, if full URL is "http://127.0.0.1:8080/photos"
38      * then relative URL would be "/photos"
39      */
40     private final String frontendServerRelativeRootUrl;
41
42     /**
43      * Example full URL: http://127.0.0.1:8080/photos/Spain
44      *
45      * @param contentServerRootUrl {@link #contentServerRootUrl}
46      * @param frontendServerRelativeRootUrl {@link #frontendServerRelativeRootUrl}
47      */
48     public WebIndexer(
49             final String contentServerRootUrl,
50             final String metadataServerRootUrl,
51             final String frontendServerRelativeRootUrl) {
52         this.contentServerRootUrl = contentServerRootUrl;
53         this.metadataServerRootUrl = metadataServerRootUrl;
54         this.frontendServerRelativeRootUrl = frontendServerRelativeRootUrl;
55     }
56
57     @Override
58     public void compileHtml(final Layout layout,
59                             final DirectoryMetadata directory)
60             throws UnsupportedEncodingException {
61         super.compileHtml(layout, directory);
62     }
63
64     @Override
65     public String getDirectoryUrl(final AbstractFile directory,
66                                   final IndexingContext context) {
67         return frontendServerRelativeRootUrl + context.getLocalUrl() + "/" + directory.fileName;
68     }
69
70     /**
71      * @param frontendServerRequestRelativeUrl example: /Spain
72      */
73     public String getHtml(String frontendServerRequestRelativeUrl) throws
74             IOException, ClassNotFoundException {
75
76         if (frontendServerRequestRelativeUrl == null)
77             frontendServerRequestRelativeUrl = "";
78
79         if (frontendServerRequestRelativeUrl.equals("/"))
80             frontendServerRequestRelativeUrl = "";
81
82         final MixedLayout layout = new MixedLayout();
83
84         final IndexingContext context = new IndexingContext(
85                 contentServerRootUrl,
86                 frontendServerRequestRelativeUrl);
87
88         layout.init("Photos", context.getLocalPathComponents(), this, context);
89
90         final DirectoryMetadata directory = getMetadataForPath(frontendServerRequestRelativeUrl);
91
92         compileHtml(layout, directory);
93
94         return layout.getHtml(false, false, directory);
95     }
96
97     private DirectoryMetadata getMetadataForPath(final String requestPath)
98             throws ClassNotFoundException, IOException {
99
100         final String url = metadataServerRootUrl + urlEncode(requestPath) + "/.thumbnails/"+ METADATA_FILE_NAME;
101
102         for (int attempt = 0; true; attempt++)
103             try {
104                 return attemptDirectoryMetadataDownload(url);
105             } catch (final IOException e) {
106                 if (attempt > METADATA_LOAD_TRY_COUNT) throw e;
107             }
108     }
109
110     private DirectoryMetadata attemptDirectoryMetadataDownload(String urlString)
111             throws IOException, ClassNotFoundException {
112
113         final BufferedInputStream inputStream = new BufferedInputStream(new URL(urlString).openStream());
114         final ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
115         final DirectoryMetadata directory = (DirectoryMetadata) objectInputStream.readObject();
116         inputStream.close();
117
118         return directory;
119     }
120
121     @Override
122     public String getParentDirectoryUrl(final IndexingContext context) {
123         final StringBuilder result = new StringBuilder();
124
125         result.append(frontendServerRelativeRootUrl);
126
127         final List<String> components = context.getLocalPathComponents();
128
129         for (final String pathComponent : components.subList(0,
130                 components.size() - 1)) {
131             result.append("/");
132             result.append(pathComponent);
133         }
134
135         return result.toString();
136     }
137
138     @Override
139     public String getThumbnailUrl(final Picture picture,
140                                   final Dimension desiredDimension, final IndexingContext context) {
141
142         // in case thumbnail size was equal to original, then return original
143         // file path
144         if (picture.getDimensions().equals(desiredDimension))
145             return context.getGlobalUrl() + context.getLocalUrl() + "/"
146                     + picture.fileName;
147
148         final String thumbnailFileName = picture
149                 .getRelativeThumbnailFileName(desiredDimension);
150
151         return context.getGlobalUrl() + context.getLocalUrl() + "/"
152                 + Constants.THUMBNAILS_DIRECTORY_NAME + "/"
153                 + urlEncode(thumbnailFileName);
154     }
155
156 }