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