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