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