Code refactoring
[meviz.git] / src / main / java / eu / svjatoslav / meviz / htmlindexer / layouts / MixedLayout.java
1 /*
2  * Meviz - Various tools collection to work with multimedia.
3  * Copyright (C) 2012 -- 2019, 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 3 of the GNU Lesser General Public License
7  * or later as published by the Free Software Foundation.
8 */
9
10 package eu.svjatoslav.meviz.htmlindexer.layouts;
11
12 import eu.svjatoslav.commons.file.FilePathParser;
13 import eu.svjatoslav.meviz.htmlindexer.indexer.AbstractIndexer;
14 import eu.svjatoslav.meviz.htmlindexer.Constants;
15 import eu.svjatoslav.meviz.htmlindexer.IndexingContext;
16 import eu.svjatoslav.meviz.htmlindexer.metadata.Dimension;
17 import eu.svjatoslav.meviz.htmlindexer.metadata.DirectoryMetadata;
18 import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.AbstractFile;
19 import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.Picture;
20 import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.Video;
21 import org.apache.log4j.Logger;
22
23 import java.io.IOException;
24 import java.util.List;
25
26 import static eu.svjatoslav.commons.file.FilePathParser.getFileNameWithoutExtension;
27 import static eu.svjatoslav.meviz.htmlindexer.Utils.urlEncode;
28
29 public class MixedLayout implements Layout {
30
31     public static final String encoding = "UTF-8";
32
33     private final Logger logger = Logger.getLogger(MixedLayout.class);
34
35     private StringBuffer dirHtml = new StringBuffer();
36
37     private StringBuffer filesHtml = new StringBuffer();
38
39     private String galleryTitle;
40
41     private List<String> path;
42
43     private AbstractIndexer indexer;
44
45     private IndexingContext indexingContext;
46
47     @Override
48     public void enlistDirectory(final AbstractFile directory,
49                                 final DirectoryMetadata parentDirectoryMetadata) {
50         dirHtml.append("<TR>");
51         dirHtml.append("<TD><b><a href=\""
52                 + indexer.getDirectoryUrl(directory, indexingContext)
53                 + "\"><h2> ==&gt; " + directory.fileName + "</h2></a></b></TD>");
54         dirHtml.append("</TR>\n");
55
56     }
57
58     @Override
59     public void enlistFile(final AbstractFile file,
60                            final DirectoryMetadata parentDirectoryMetadata) {
61
62         final String fullFileName = file.fileName;
63
64         filesHtml.append("<div style=\"clear: both;\"><a href=\""
65                 + indexingContext.getGlobalUrl()
66                 + urlEncode(indexingContext.getLocalUrl() + "/"
67                 + fullFileName) + "\">" + fullFileName + "</a>\n");
68         filesHtml.append("&nbsp;&nbsp;("
69                 + FilePathParser.getFileSizeDescription(file.getFileLength())
70                 + ")</div><br/>\n");
71
72     }
73
74     @Override
75     public void enlistImage(final Picture picture,
76                             final DirectoryMetadata parentDirectoryMetadata) {
77         try {
78             enlistImageInternal(picture);
79         } catch (final Exception e) {
80             logger.error(
81                     "Error generating thumbnails for image file: "
82                             + e.toString()
83                             + ", thumbnail generation skipped, enlisting as ordinary file instead.",
84                     e);
85             enlistFile(picture, parentDirectoryMetadata);
86         }
87     }
88
89     private String enlistImageDimensions(final Picture picture) {
90         final StringBuilder html = new StringBuilder();
91
92         final List<Dimension> recommendedDimensions = Picture
93                 .getThumbnailDimensions(picture.getDimensions());
94
95         int count = 0;
96         for (final Dimension dimension : recommendedDimensions) {
97             count++;
98             if (count > 1)
99                 html.append(", ");
100             html.append("<a href=\""
101                     + indexer.getThumbnailUrl(picture, dimension,
102                     indexingContext) + "\">");
103             html.append(dimension.width + "x" + dimension.height);
104             html.append("</a>");
105         }
106
107         return html.toString();
108     }
109
110     private void enlistImageInternal(final Picture picture) {
111
112         filesHtml.append("<div style=\"float:left; margin: 10px;\">");
113
114         // clickable image thumbnail
115         filesHtml.append("<a href=\""
116                 + indexingContext.getGlobalUrl()
117                 + urlEncode(indexingContext.getLocalUrl() + "/"
118                 + picture.fileName) + "\">\n");
119
120         filesHtml.append("<img border=\"0\" src=\""
121                 + getImageThumbnailUrl(picture) + "\"/></a><br/>\n");
122
123         // file name
124         filesHtml.append("<b>"
125                 + getFileNameWithoutExtension(picture.fileName)
126                 + "</b><br/>");
127
128         // links to thumbnails of various sizes
129         filesHtml.append("(" + enlistImageDimensions(picture) + ")\n");
130
131         filesHtml.append("</div>");
132     }
133
134     /**
135      * {@inheritDoc}
136      */
137     @Override
138     public String getFileNameSuffix() {
139         return "";
140     }
141
142     /**
143      * {@inheritDoc}
144      *
145      * @throws IOException
146      */
147     @Override
148     public String getHtml(final boolean showTitle,
149                           final boolean doHtmlHeaderAndFooter,
150                           final DirectoryMetadata directory) {
151
152         // assemble final page HTML
153         final StringBuilder html = new StringBuilder();
154
155         if (doHtmlHeaderAndFooter)
156             appendHtmlHeader(html);
157
158         if (showTitle)
159             html.append("<CENTER><H1>" + galleryTitle + "</H1></CENTER>\n");
160
161         html.append(showCurrentPath());
162         html.append(listDirectories());
163         html.append(directory.getHeaderMevizMetadataHtml());
164         html.append(filesHtml.toString());
165
166         if (doHtmlHeaderAndFooter)
167             appendHtmlFooter(html);
168
169         return html.toString();
170     }
171
172     private void appendHtmlFooter(StringBuilder html) {
173         html.append("</font></BODY></HTML>\n");
174     }
175
176     private void appendHtmlHeader(StringBuilder html) {
177         // page header
178         html.append("<HTML>\n");
179         html.append("<HEAD>\n");
180         html.append("    <meta HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=UTF-8\"/>\n");
181         html.append("</HEAD>\n");
182         html.append("<BODY bgcolor=\"#000000\" alink=\"#50ffff\" link=\"#50ffff\" vlink=\"#ff50ff\" text=\"#ffffff\">\n");
183         html.append("<!-- " + Constants.HTML_MAGIC_STRING + " -->\n");
184         html.append("<!-- " + Constants.HTML_MEMO + " -->\n");
185         html.append("<font color=\"#ffffff\">\n");
186     }
187
188     private String getImageThumbnailUrl(final Picture picture) {
189         final Dimension imageSize = picture.getDimensions();
190
191         Dimension listingDimension = new Dimension(1500, 450);
192
193         if (listingDimension.width > imageSize.width)
194             if (listingDimension.height > imageSize.height)
195                 listingDimension = imageSize;
196
197         return indexer.getThumbnailUrl(picture, listingDimension,
198                 indexingContext);
199     }
200
201     @Override
202     public void init(final String galleryTitle, final List<String> path,
203                      final AbstractIndexer indexer, final IndexingContext indexingContext) {
204
205         this.indexer = indexer;
206         this.galleryTitle = galleryTitle;
207         this.path = path;
208         this.indexingContext = indexingContext;
209
210         dirHtml = new StringBuffer();
211         filesHtml = new StringBuffer();
212     }
213
214     private String listDirectories() {
215         final StringBuilder html = new StringBuilder();
216         html.append("<TABLE>\n");
217
218         if (path.size() > 0) {
219             html.append("<TR>");
220             html.append("<TD><b><a href=\""
221                     + indexer.getParentDirectoryUrl(indexingContext)
222                     + "\"><h2> &lt;== parent directory</h2></a></b></TD>");
223             html.append("</TR>\n");
224         }
225
226         html.append(dirHtml.toString());
227         html.append("\n<TR><TD><br></TD></TR>\n");
228         html.append("</TABLE>\n");
229
230         return html.toString();
231     }
232
233     private String showCurrentPath() {
234         final StringBuilder html = new StringBuilder();
235         html.append("<CENTER><H2>");
236         for (final String p : path)
237             html.append(" / " + p);
238         html.append("</H2></CENTER>\n");
239
240         return html.toString();
241     }
242
243     @Override
244     public void enlistVideo(Video video) {
245
246         filesHtml.append("<div style=\"margin: 30px; clear: both;\">\n");
247
248         // watchable video
249         filesHtml.append("  <video width=\"640\" controls>\n");
250         filesHtml.append("    <source src=\"" + getFileUrl(video) + "\" type=\"" + video.mimeType + "\"/>\n");
251         filesHtml.append("  </video>\n");
252
253         filesHtml.append("  <br/>\n");
254
255         // video title
256         filesHtml.append("  Video: <b>"
257                         + getFileNameWithoutExtension(video.fileName)
258                         + "<b/>  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
259
260         // video download link
261         filesHtml.append("  <a href=\"" + getFileUrl(video) + "\">download</a>\n");
262
263         filesHtml.append("</div>\n");
264
265         filesHtml.append("\n");
266     }
267
268
269     private String getFileUrl(AbstractFile file) {
270         return indexingContext.getGlobalUrl()
271                     + urlEncode(indexingContext.getLocalUrl() + "/"
272                     + file.fileName);
273     }
274 }