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