Merge branch 'subtree'
[fanfix.git] / src / be / nikiroo / fanfix / supported / BasicSupportHelper.java
1 package be.nikiroo.fanfix.supported;
2
3 import java.io.File;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.net.MalformedURLException;
7 import java.net.URL;
8 import java.text.ParseException;
9 import java.text.SimpleDateFormat;
10 import java.util.Date;
11
12 import be.nikiroo.fanfix.Instance;
13 import be.nikiroo.fanfix.bundles.Config;
14 import be.nikiroo.utils.Image;
15 import be.nikiroo.utils.StringUtils;
16
17 /**
18 * Helper class for {@link BasicSupport}, mostly dedicated to text formating for
19 * the classes that implement {@link BasicSupport}.
20 *
21 * @author niki
22 */
23 public class BasicSupportHelper {
24 /**
25 * Get the default cover related to this subject (see <tt>.info</tt> files).
26 *
27 * @param subject
28 * the subject
29 *
30 * @return the cover if any, or NULL
31 */
32 public Image getDefaultCover(String subject) {
33 if (subject != null && !subject.isEmpty() && Instance.getInstance().getCoverDir() != null) {
34 try {
35 File fileCover = new File(Instance.getInstance().getCoverDir(), subject);
36 return getImage(null, fileCover.toURI().toURL(), subject);
37 } catch (MalformedURLException e) {
38 }
39 }
40
41 return null;
42 }
43
44 /**
45 * Return the list of supported image extensions.
46 *
47 * @param emptyAllowed
48 * TRUE to allow an empty extension on first place, which can be
49 * used when you may already have an extension in your input but
50 * are not sure about it
51 *
52 * @return the extensions
53 */
54 public String[] getImageExt(boolean emptyAllowed) {
55 if (emptyAllowed) {
56 return new String[] { "", ".png", ".jpg", ".jpeg", ".gif", ".bmp" };
57 }
58
59 return new String[] { ".png", ".jpg", ".jpeg", ".gif", ".bmp" };
60 }
61
62 /**
63 * Check if the given resource can be a local image or a remote image, then
64 * refresh the cache with it if it is.
65 *
66 * @param support
67 * the linked {@link BasicSupport} (can be NULL)
68 * @param source
69 * the source of the story (for image lookup in the same path if
70 * the source is a file, can be NULL)
71 * @param line
72 * the resource to check
73 *
74 * @return the image if found, or NULL
75 *
76 */
77 public Image getImage(BasicSupport support, URL source, String line) {
78 URL url = getImageUrl(support, source, line);
79 if (url != null) {
80 if ("file".equals(url.getProtocol())) {
81 if (new File(url.getPath()).isDirectory()) {
82 return null;
83 }
84 }
85 InputStream in = null;
86 try {
87 in = Instance.getInstance().getCache().open(url, support, true);
88 return new Image(in);
89 } catch (IOException e) {
90 } finally {
91 if (in != null) {
92 try {
93 in.close();
94 } catch (IOException e) {
95 }
96 }
97 }
98 }
99
100 return null;
101 }
102
103 /**
104 * Check if the given resource can be a local image or a remote image, then
105 * refresh the cache with it if it is.
106 *
107 * @param support
108 * the linked {@link BasicSupport} (can be NULL)
109 * @param source
110 * the source of the story (for image lookup in the same path if
111 * the source is a file, can be NULL)
112 * @param line
113 * the resource to check
114 *
115 * @return the image URL if found, or NULL
116 *
117 */
118 public URL getImageUrl(BasicSupport support, URL source, String line) {
119 URL url = null;
120
121 if (line != null) {
122 // try for files
123 if (source != null) {
124 try {
125
126 String relPath = null;
127 String absPath = null;
128 try {
129 String path = new File(source.getFile()).getParent();
130 relPath = new File(new File(path), line.trim())
131 .getAbsolutePath();
132 } catch (Exception e) {
133 // Cannot be converted to path (one possibility to take
134 // into account: absolute path on Windows)
135 }
136 try {
137 absPath = new File(line.trim()).getAbsolutePath();
138 } catch (Exception e) {
139 // Cannot be converted to path (at all)
140 }
141
142 for (String ext : getImageExt(true)) {
143 File absFile = new File(absPath + ext);
144 File relFile = new File(relPath + ext);
145 if (absPath != null && absFile.exists()
146 && absFile.isFile()) {
147 url = absFile.toURI().toURL();
148 } else if (relPath != null && relFile.exists()
149 && relFile.isFile()) {
150 url = relFile.toURI().toURL();
151 }
152 }
153 } catch (Exception e) {
154 // Should not happen since we control the correct arguments
155 }
156 }
157
158 if (url == null) {
159 // try for URLs
160 try {
161 for (String ext : getImageExt(true)) {
162 if (Instance.getInstance().getCache().check(new URL(line + ext), true)) {
163 url = new URL(line + ext);
164 break;
165 }
166 }
167
168 // try out of cache
169 if (url == null) {
170 for (String ext : getImageExt(true)) {
171 try {
172 url = new URL(line + ext);
173 Instance.getInstance().getCache().refresh(url, support, true);
174 break;
175 } catch (IOException e) {
176 // no image with this ext
177 url = null;
178 }
179 }
180 }
181 } catch (MalformedURLException e) {
182 // Not an url
183 }
184 }
185
186 // refresh the cached file
187 if (url != null) {
188 try {
189 Instance.getInstance().getCache().refresh(url, support, true);
190 } catch (IOException e) {
191 // woops, broken image
192 url = null;
193 }
194 }
195 }
196
197 return url;
198 }
199
200 /**
201 * Fix the author name if it is prefixed with some "by" {@link String}.
202 *
203 * @param author
204 * the author with a possible prefix
205 *
206 * @return the author without prefixes
207 */
208 public String fixAuthor(String author) {
209 if (author != null) {
210 for (String suffix : new String[] { " ", ":" }) {
211 for (String byString : Instance.getInstance().getConfig().getList(Config.CONF_BYS)) {
212 byString += suffix;
213 if (author.toUpperCase().startsWith(byString.toUpperCase())) {
214 author = author.substring(byString.length()).trim();
215 }
216 }
217 }
218
219 // Special case (without suffix):
220 if (author.startsWith("©")) {
221 author = author.substring(1);
222 }
223 }
224
225 return author;
226 }
227
228 /**
229 * Try to convert the date to a known, fixed format.
230 * <p>
231 * If it fails to do so, it will return the date as-is.
232 *
233 * @param date
234 * the date to convert
235 *
236 * @return the converted date, or the date as-is
237 */
238 public String formatDate(String date) {
239 long ms = 0;
240
241 if (date != null && !date.isEmpty()) {
242 // Default Fanfix format:
243 try {
244 ms = StringUtils.toTime(date);
245 } catch (ParseException e) {
246 }
247
248 // Second chance:
249 if (ms <= 0) {
250 SimpleDateFormat sdf = new SimpleDateFormat(
251 "yyyy-MM-dd'T'HH:mm:ssSSS");
252 try {
253 ms = sdf.parse(date).getTime();
254 } catch (ParseException e) {
255 }
256 }
257
258 // Last chance:
259 if (ms <= 0 && date.length() >= 10) {
260 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
261 try {
262 ms = sdf.parse(date.substring(0, 10)).getTime();
263 } catch (ParseException e) {
264 }
265 }
266
267 // If we found something, use THIS format:
268 if (ms > 0) {
269 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
270 return sdf.format(new Date(ms));
271 }
272 }
273
274 if (date == null) {
275 date = "";
276 }
277
278 // :(
279 return date;
280 }
281 }