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