GUI: detect remote connection failures
[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;
581d42c0 15import be.nikiroo.utils.Cache;
b42117f1 16import be.nikiroo.utils.IOUtils;
581d42c0 17import be.nikiroo.utils.TraceHandler;
08fe2e33
NR
18import be.nikiroo.utils.resources.Bundles;
19
20/**
21 * Global state for the program (services and singletons).
22 *
23 * @author niki
24 */
25public class Instance {
26 private static ConfigBundle config;
b4dc6ab5 27 private static UiConfigBundle uiconfig;
08fe2e33 28 private static StringIdBundle trans;
f1fb834c 29 private static DataLoader cache;
68e2c6d2 30 private static LocalLibrary lib;
08fe2e33 31 private static File coverDir;
3727aae2 32 private static File readerTmp;
b0e88ebd 33 private static File remoteDir;
b42117f1 34 private static String configDir;
581d42c0 35 private static TraceHandler tracer;
a8209dd0 36
08fe2e33 37 static {
62c63b07
NR
38 // Before we can configure it:
39 tracer = new TraceHandler(true, checkEnv("DEBUG"), false);
40
948637bc 41 // Most of the rest is dependent upon this:
08fe2e33
NR
42 config = new ConfigBundle();
43
b42117f1 44 configDir = System.getProperty("CONFIG_DIR");
22848428
NR
45 if (configDir == null) {
46 configDir = System.getenv("CONFIG_DIR");
47 }
b42117f1 48
fe999aa4
NR
49 if (configDir == null) {
50 configDir = new File(System.getProperty("user.home"), ".fanfix")
51 .getPath();
52 }
39c3c689 53
b42117f1
NR
54 if (!new File(configDir).exists()) {
55 new File(configDir).mkdirs();
56 } else {
fe999aa4
NR
57 Bundles.setDirectory(configDir);
58 }
59
b42117f1
NR
60 try {
61 config = new ConfigBundle();
62 config.updateFile(configDir);
63 } catch (IOException e) {
62c63b07 64 tracer.error(e);
b42117f1
NR
65 }
66 try {
67 uiconfig = new UiConfigBundle();
68 uiconfig.updateFile(configDir);
69 } catch (IOException e) {
62c63b07 70 tracer.error(e);
b42117f1 71 }
99ccbdf6
NR
72
73 // No updateFile for this one! (we do not want the user to have custom
74 // translations that won't accept updates from newer versions)
75 trans = new StringIdBundle(getLang());
76
77 // Fix an old bug (we used to store custom translation files by
78 // default):
79 if (trans.getString(StringId.INPUT_DESC_CBZ) == null) {
80 // TODO: create the deleteFile method
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;
104 }
105
62c63b07 106 tracer = new TraceHandler(true, debug, trace);
581d42c0 107
778d8d85
NR
108 try {
109 lib = new LocalLibrary(getFile(Config.LIBRARY_DIR));
110 } catch (Exception e) {
62c63b07
NR
111 tracer.error(new IOException(
112 "Cannot create library for directory: "
113 + getFile(Config.LIBRARY_DIR), e));
778d8d85
NR
114 }
115
68e370a4
NR
116 // Could have used: System.getProperty("java.io.tmpdir")
117 if (tmp == null) {
118 tmp = new File(configDir, "tmp");
119 }
120 if (readerTmp == null) {
121 readerTmp = new File(configDir, "tmp-reader");
3727aae2 122 }
68e370a4 123 //
08fe2e33
NR
124
125 if (coverDir != null && !coverDir.exists()) {
62c63b07 126 tracer.error(new IOException(
08fe2e33
NR
127 "The 'default covers' directory does not exists: "
128 + coverDir));
129 coverDir = null;
130 }
08fe2e33 131
08fe2e33 132 try {
08fe2e33
NR
133 String ua = config.getString(Config.USER_AGENT);
134 int hours = config.getInteger(Config.CACHE_MAX_TIME_CHANGING, -1);
135 int hoursLarge = config
136 .getInteger(Config.CACHE_MAX_TIME_STABLE, -1);
137
f1fb834c 138 cache = new DataLoader(tmp, ua, hours, hoursLarge);
08fe2e33 139 } catch (IOException e) {
62c63b07 140 tracer.error(new IOException(
08fe2e33
NR
141 "Cannot create cache (will continue without cache)", e));
142 }
143 }
144
581d42c0
NR
145 /**
146 * The traces handler for this {@link Cache}.
62c63b07
NR
147 * <p>
148 * It is never NULL.
581d42c0 149 *
62c63b07 150 * @return the traces handler (never NULL)
581d42c0
NR
151 */
152 public static TraceHandler getTraceHandler() {
153 return tracer;
154 }
155
156 /**
157 * The traces handler for this {@link Cache}.
158 *
159 * @param tracer
160 * the new traces handler or NULL
161 */
162 public static void setTraceHandler(TraceHandler tracer) {
62c63b07
NR
163 if (tracer == null) {
164 tracer = new TraceHandler(false, false, false);
165 }
166
581d42c0
NR
167 Instance.tracer = tracer;
168 }
169
08fe2e33
NR
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 188 /**
f1fb834c 189 * Get the (unique) {@link DataLoader} for the program.
08fe2e33 190 *
f1fb834c 191 * @return the {@link DataLoader}
08fe2e33 192 */
f1fb834c 193 public static DataLoader getCache() {
08fe2e33
NR
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() {
778d8d85
NR
212 if (lib == null) {
213 throw new NullPointerException("We don't have a library to return");
214 }
215
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) {
581d42c0 292 tracer.error(e);
08fe2e33
NR
293 }
294 }
295
296 /**
297 * Return a path, but support the special $HOME variable.
298 *
299 * @return the path
300 */
301 private static File getFile(Config id) {
b4dc6ab5
NR
302 return getFile(config.getString(id));
303 }
304
305 /**
306 * Return a path, but support the special $HOME variable.
307 *
308 * @return the path
309 */
310 private static File getFile(UiConfig id) {
311 return getFile(uiconfig.getString(id));
312 }
313
314 /**
315 * Return a path, but support the special $HOME variable.
316 *
317 * @return the path
318 */
319 private static File getFile(String path) {
08fe2e33 320 File file = null;
08fe2e33
NR
321 if (path != null && !path.isEmpty()) {
322 path = path.replace('/', File.separatorChar);
323 if (path.contains("$HOME")) {
324 path = path.replace("$HOME",
325 "" + System.getProperty("user.home"));
326 }
327
328 file = new File(path);
329 }
330
331 return file;
332 }
333
334 /**
335 * The language to use for the application (NULL = default system language).
336 *
337 * @return the language
338 */
339 private static String getLang() {
340 String lang = config.getString(Config.LANG);
341
342 if (System.getenv("LANG") != null && !System.getenv("LANG").isEmpty()) {
343 lang = System.getenv("LANG");
344 }
345
346 if (lang != null && lang.isEmpty()) {
347 lang = null;
348 }
349
350 return lang;
351 }
d0114000
NR
352
353 /**
354 * Check that the given environment variable is "enabled".
355 *
356 * @param key
357 * the variable to check
358 *
359 * @return TRUE if it is
360 */
361 private static boolean checkEnv(String key) {
362 String value = System.getenv(key);
363 if (value != null) {
364 value = value.trim().toLowerCase();
365 if ("yes".equals(value) || "true".equals(value)
366 || "on".equals(value) || "1".equals(value)
367 || "y".equals(value)) {
368 return true;
369 }
370 }
371
372 return false;
373 }
08fe2e33 374}