Improve cbz support:
[nikiroo-utils.git] / src / be / nikiroo / fanfix / Instance.java
CommitLineData
08fe2e33
NR
1package be.nikiroo.fanfix;
2
3import java.io.File;
4import java.io.IOException;
b42117f1 5import java.util.Date;
08fe2e33
NR
6
7import be.nikiroo.fanfix.bundles.Config;
8import be.nikiroo.fanfix.bundles.ConfigBundle;
99ccbdf6 9import be.nikiroo.fanfix.bundles.StringId;
08fe2e33 10import be.nikiroo.fanfix.bundles.StringIdBundle;
b4dc6ab5
NR
11import be.nikiroo.fanfix.bundles.UiConfig;
12import be.nikiroo.fanfix.bundles.UiConfigBundle;
e42573a0
NR
13import be.nikiroo.fanfix.library.BasicLibrary;
14import be.nikiroo.fanfix.library.LocalLibrary;
581d42c0 15import be.nikiroo.utils.Cache;
b42117f1 16import be.nikiroo.utils.IOUtils;
581d42c0 17import be.nikiroo.utils.TraceHandler;
08fe2e33
NR
18import be.nikiroo.utils.resources.Bundles;
19
20/**
21 * Global state for the program (services and singletons).
22 *
23 * @author niki
24 */
25public class Instance {
26 private static ConfigBundle config;
b4dc6ab5 27 private static UiConfigBundle uiconfig;
08fe2e33 28 private static StringIdBundle trans;
f1fb834c 29 private static DataLoader cache;
68e2c6d2 30 private static LocalLibrary lib;
08fe2e33 31 private static File coverDir;
3727aae2 32 private static File readerTmp;
b0e88ebd 33 private static File remoteDir;
b42117f1 34 private static String configDir;
581d42c0 35 private static TraceHandler tracer;
a8209dd0 36
08fe2e33 37 static {
948637bc 38 // Most of the rest is dependent upon this:
08fe2e33
NR
39 config = new ConfigBundle();
40
b42117f1 41 configDir = System.getProperty("CONFIG_DIR");
22848428
NR
42 if (configDir == null) {
43 configDir = System.getenv("CONFIG_DIR");
44 }
b42117f1 45
fe999aa4
NR
46 if (configDir == null) {
47 configDir = new File(System.getProperty("user.home"), ".fanfix")
48 .getPath();
49 }
39c3c689 50
b42117f1
NR
51 if (!new File(configDir).exists()) {
52 new File(configDir).mkdirs();
53 } else {
fe999aa4
NR
54 Bundles.setDirectory(configDir);
55 }
56
b42117f1
NR
57 try {
58 config = new ConfigBundle();
59 config.updateFile(configDir);
60 } catch (IOException e) {
61 syserr(e);
62 }
63 try {
64 uiconfig = new UiConfigBundle();
65 uiconfig.updateFile(configDir);
66 } catch (IOException e) {
67 syserr(e);
68 }
99ccbdf6
NR
69
70 // No updateFile for this one! (we do not want the user to have custom
71 // translations that won't accept updates from newer versions)
72 trans = new StringIdBundle(getLang());
73
74 // Fix an old bug (we used to store custom translation files by
75 // default):
76 if (trans.getString(StringId.INPUT_DESC_CBZ) == null) {
77 // TODO: create the deleteFile method
78 // trans.deleteFile(configDir);
b42117f1
NR
79 }
80
81 Bundles.setDirectory(configDir);
82
b4dc6ab5 83 uiconfig = new UiConfigBundle();
08fe2e33 84 trans = new StringIdBundle(getLang());
68686a37 85 try {
e604986c 86 lib = new LocalLibrary(getFile(Config.LIBRARY_DIR));
68686a37
NR
87 } catch (Exception e) {
88 syserr(new IOException("Cannot create library for directory: "
89 + getFile(Config.LIBRARY_DIR), e));
90 }
2206ef66 91
581d42c0
NR
92 boolean debug = Instance.getConfig()
93 .getBoolean(Config.DEBUG_ERR, false);
94 boolean trace = Instance.getConfig().getBoolean(Config.DEBUG_TRACE,
95 false);
08fe2e33 96 coverDir = getFile(Config.DEFAULT_COVERS_DIR);
3727aae2 97 File tmp = getFile(Config.CACHE_DIR);
b4dc6ab5 98 readerTmp = getFile(UiConfig.CACHE_DIR_LOCAL_READER);
e604986c 99 remoteDir = new File(configDir, "remote");
3727aae2 100
d0114000
NR
101 if (checkEnv("NOUTF")) {
102 trans.setUnicode(false);
103 }
104
105 if (checkEnv("DEBUG")) {
106 debug = true;
107 }
108
581d42c0
NR
109 tracer = new TraceHandler();
110 tracer.setShowErrorDetails(debug);
111 tracer.setShowTraces(trace);
112
68e370a4
NR
113 // Could have used: System.getProperty("java.io.tmpdir")
114 if (tmp == null) {
115 tmp = new File(configDir, "tmp");
116 }
117 if (readerTmp == null) {
118 readerTmp = new File(configDir, "tmp-reader");
3727aae2 119 }
68e370a4 120 //
08fe2e33
NR
121
122 if (coverDir != null && !coverDir.exists()) {
123 syserr(new IOException(
124 "The 'default covers' directory does not exists: "
125 + coverDir));
126 coverDir = null;
127 }
08fe2e33 128
08fe2e33 129 try {
08fe2e33
NR
130 String ua = config.getString(Config.USER_AGENT);
131 int hours = config.getInteger(Config.CACHE_MAX_TIME_CHANGING, -1);
132 int hoursLarge = config
133 .getInteger(Config.CACHE_MAX_TIME_STABLE, -1);
134
f1fb834c 135 cache = new DataLoader(tmp, ua, hours, hoursLarge);
08fe2e33
NR
136 } catch (IOException e) {
137 syserr(new IOException(
138 "Cannot create cache (will continue without cache)", e));
139 }
140 }
141
581d42c0
NR
142 /**
143 * The traces handler for this {@link Cache}.
144 *
145 * @return the traces handler or NULL
146 */
147 public static TraceHandler getTraceHandler() {
148 return tracer;
149 }
150
151 /**
152 * The traces handler for this {@link Cache}.
153 *
154 * @param tracer
155 * the new traces handler or NULL
156 */
157 public static void setTraceHandler(TraceHandler tracer) {
158 Instance.tracer = tracer;
159 }
160
08fe2e33
NR
161 /**
162 * Get the (unique) configuration service for the program.
163 *
164 * @return the configuration service
165 */
166 public static ConfigBundle getConfig() {
167 return config;
168 }
169
b4dc6ab5
NR
170 /**
171 * Get the (unique) UI configuration service for the program.
172 *
173 * @return the configuration service
174 */
175 public static UiConfigBundle getUiConfig() {
176 return uiconfig;
177 }
178
08fe2e33 179 /**
f1fb834c 180 * Get the (unique) {@link DataLoader} for the program.
08fe2e33 181 *
f1fb834c 182 * @return the {@link DataLoader}
08fe2e33 183 */
f1fb834c 184 public static DataLoader getCache() {
08fe2e33
NR
185 return cache;
186 }
187
188 /**
189 * Get the (unique) {link StringIdBundle} for the program.
39c3c689 190 *
08fe2e33
NR
191 * @return the {link StringIdBundle}
192 */
193 public static StringIdBundle getTrans() {
194 return trans;
195 }
196
197 /**
68e2c6d2 198 * Get the (unique) {@link LocalLibrary} for the program.
08fe2e33 199 *
68e2c6d2 200 * @return the {@link LocalLibrary}
08fe2e33 201 */
68e2c6d2 202 public static BasicLibrary getLibrary() {
08fe2e33
NR
203 return lib;
204 }
205
206 /**
207 * Return the directory where to look for default cover pages.
208 *
209 * @return the default covers directory
210 */
211 public static File getCoverDir() {
212 return coverDir;
213 }
214
3727aae2
NR
215 /**
216 * Return the directory where to store temporary files for the local reader.
217 *
218 * @return the directory
219 */
220 public static File getReaderDir() {
221 return readerTmp;
222 }
223
b0e88ebd
NR
224 /**
225 * Return the directory where to store temporary files for the remote
68e2c6d2 226 * {@link LocalLibrary}.
b0e88ebd
NR
227 *
228 * @param host
229 * the remote for this host
230 *
231 * @return the directory
232 */
233 public static File getRemoteDir(String host) {
234 remoteDir.mkdirs();
235
236 if (host != null) {
237 return new File(remoteDir, host);
238 }
239
240 return remoteDir;
241 }
242
b42117f1
NR
243 /**
244 * Check if we need to check that a new version of Fanfix is available.
245 *
246 * @return TRUE if we need to
247 */
248 public static boolean isVersionCheckNeeded() {
249 try {
a3641e4b
NR
250 long wait = config.getInteger(Config.UPDATE_INTERVAL, 1) * 24 * 60
251 * 60 * 1000;
b42117f1
NR
252 if (wait >= 0) {
253 String lastUpString = IOUtils.readSmallFile(new File(configDir,
254 "LAST_UPDATE"));
255 long delay = new Date().getTime()
256 - Long.parseLong(lastUpString);
257 if (delay > wait) {
258 return true;
259 }
260 } else {
261 return false;
262 }
263 } catch (Exception e) {
264 // No file or bad file:
265 return true;
266 }
267
268 return false;
269 }
270
271 /**
272 * Notify that we checked for a new version of Fanfix.
273 */
274 public static void setVersionChecked() {
275 try {
276 IOUtils.writeSmallFile(new File(configDir), "LAST_UPDATE",
277 Long.toString(new Date().getTime()));
278 } catch (IOException e) {
279 syserr(e);
280 }
281 }
282
08fe2e33
NR
283 /**
284 * Report an error to the user
285 *
286 * @param e
287 * the {@link Exception} to report
288 */
289 public static void syserr(Exception e) {
581d42c0
NR
290 if (tracer != null) {
291 tracer.error(e);
08fe2e33
NR
292 }
293 }
294
315f14ae 295 /**
a8209dd0 296 * Notify of a debug message.
315f14ae 297 *
a8209dd0
NR
298 * @param message
299 * the message
315f14ae 300 */
a8209dd0 301 public static void trace(String message) {
581d42c0
NR
302 if (tracer != null) {
303 tracer.trace(message);
a8209dd0 304 }
315f14ae
NR
305 }
306
08fe2e33
NR
307 /**
308 * Return a path, but support the special $HOME variable.
309 *
310 * @return the path
311 */
312 private static File getFile(Config id) {
b4dc6ab5
NR
313 return getFile(config.getString(id));
314 }
315
316 /**
317 * Return a path, but support the special $HOME variable.
318 *
319 * @return the path
320 */
321 private static File getFile(UiConfig id) {
322 return getFile(uiconfig.getString(id));
323 }
324
325 /**
326 * Return a path, but support the special $HOME variable.
327 *
328 * @return the path
329 */
330 private static File getFile(String path) {
08fe2e33 331 File file = null;
08fe2e33
NR
332 if (path != null && !path.isEmpty()) {
333 path = path.replace('/', File.separatorChar);
334 if (path.contains("$HOME")) {
335 path = path.replace("$HOME",
336 "" + System.getProperty("user.home"));
337 }
338
339 file = new File(path);
340 }
341
342 return file;
343 }
344
345 /**
346 * The language to use for the application (NULL = default system language).
347 *
348 * @return the language
349 */
350 private static String getLang() {
351 String lang = config.getString(Config.LANG);
352
353 if (System.getenv("LANG") != null && !System.getenv("LANG").isEmpty()) {
354 lang = System.getenv("LANG");
355 }
356
357 if (lang != null && lang.isEmpty()) {
358 lang = null;
359 }
360
361 return lang;
362 }
d0114000
NR
363
364 /**
365 * Check that the given environment variable is "enabled".
366 *
367 * @param key
368 * the variable to check
369 *
370 * @return TRUE if it is
371 */
372 private static boolean checkEnv(String key) {
373 String value = System.getenv(key);
374 if (value != null) {
375 value = value.trim().toLowerCase();
376 if ("yes".equals(value) || "true".equals(value)
377 || "on".equals(value) || "1".equals(value)
378 || "y".equals(value)) {
379 return true;
380 }
381 }
382
383 return false;
384 }
08fe2e33 385}