82f442791b673262932988b4f3c054cc031e10e0
1 package be
.nikiroo
.fanfix
;
4 import java
.io
.IOException
;
7 import be
.nikiroo
.fanfix
.bundles
.Config
;
8 import be
.nikiroo
.fanfix
.bundles
.ConfigBundle
;
9 import be
.nikiroo
.fanfix
.bundles
.StringId
;
10 import be
.nikiroo
.fanfix
.bundles
.StringIdBundle
;
11 import be
.nikiroo
.fanfix
.bundles
.UiConfig
;
12 import be
.nikiroo
.fanfix
.bundles
.UiConfigBundle
;
13 import be
.nikiroo
.fanfix
.library
.BasicLibrary
;
14 import be
.nikiroo
.fanfix
.library
.CacheLibrary
;
15 import be
.nikiroo
.fanfix
.library
.LocalLibrary
;
16 import be
.nikiroo
.fanfix
.library
.RemoteLibrary
;
17 import be
.nikiroo
.utils
.Cache
;
18 import be
.nikiroo
.utils
.IOUtils
;
19 import be
.nikiroo
.utils
.TraceHandler
;
20 import be
.nikiroo
.utils
.resources
.Bundles
;
23 * Global state for the program (services and singletons).
27 public class Instance
{
28 private static ConfigBundle config
;
29 private static UiConfigBundle uiconfig
;
30 private static StringIdBundle trans
;
31 private static DataLoader cache
;
32 private static BasicLibrary lib
;
33 private static File coverDir
;
34 private static File readerTmp
;
35 private static File remoteDir
;
36 private static String configDir
;
37 private static TraceHandler tracer
;
40 // Before we can configure it:
41 tracer
= new TraceHandler(true, checkEnv("DEBUG"), checkEnv("DEBUG"));
43 // Most of the rest is dependent upon this:
44 config
= new ConfigBundle();
46 configDir
= System
.getProperty("CONFIG_DIR");
47 if (configDir
== null) {
48 configDir
= System
.getenv("CONFIG_DIR");
51 if (configDir
== null) {
52 configDir
= new File(getHome(), ".fanfix").getPath();
55 if (!new File(configDir
).exists()) {
56 new File(configDir
).mkdirs();
58 Bundles
.setDirectory(configDir
);
62 config
= new ConfigBundle();
63 config
.updateFile(configDir
);
64 } catch (IOException e
) {
68 uiconfig
= new UiConfigBundle();
69 uiconfig
.updateFile(configDir
);
70 } catch (IOException e
) {
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());
78 // Fix an old bug (we used to store custom translation files by
80 if (trans
.getString(StringId
.INPUT_DESC_CBZ
) == null) {
81 trans
.deleteFile(configDir
);
84 Bundles
.setDirectory(configDir
);
86 uiconfig
= new UiConfigBundle();
87 trans
= new StringIdBundle(getLang());
89 boolean debug
= Instance
.getConfig()
90 .getBoolean(Config
.DEBUG_ERR
, false);
91 boolean trace
= Instance
.getConfig().getBoolean(Config
.DEBUG_TRACE
,
93 coverDir
= getFile(Config
.DEFAULT_COVERS_DIR
);
94 File tmp
= getFile(Config
.CACHE_DIR
);
95 readerTmp
= getFile(UiConfig
.CACHE_DIR_LOCAL_READER
);
96 remoteDir
= new File(configDir
, "remote");
98 if (checkEnv("NOUTF")) {
99 trans
.setUnicode(false);
102 if (checkEnv("DEBUG")) {
107 tracer
= new TraceHandler(true, debug
, trace
);
109 String remoteLib
= config
.getString(Config
.DEFAULT_LIBRARY
);
110 if (remoteLib
== null || remoteLib
.trim().isEmpty()) {
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
));
119 int pos
= remoteLib
.lastIndexOf(":");
121 String port
= remoteLib
.substring(pos
+ 1).trim();
122 remoteLib
= remoteLib
.substring(0, pos
);
123 pos
= remoteLib
.lastIndexOf(":");
125 String host
= remoteLib
.substring(pos
+ 1).trim();
126 String key
= remoteLib
.substring(0, pos
).trim();
129 tracer
.trace("Selecting remote library " + host
+ ":"
131 lib
= new RemoteLibrary(key
, host
,
132 Integer
.parseInt(port
));
133 lib
= new CacheLibrary(getRemoteDir(host
), lib
);
135 } catch (Exception e
) {
141 tracer
.error(new IOException(
142 "Cannot create remote library for: " + remoteLib
));
146 // Could have used: System.getProperty("java.io.tmpdir")
148 tmp
= new File(configDir
, "tmp");
150 if (readerTmp
== null) {
151 readerTmp
= new File(configDir
, "tmp-reader");
155 if (coverDir
!= null && !coverDir
.exists()) {
156 tracer
.error(new IOException(
157 "The 'default covers' directory does not exists: "
162 String ua
= config
.getString(Config
.USER_AGENT
);
164 int hours
= config
.getInteger(Config
.CACHE_MAX_TIME_CHANGING
, -1);
165 int hoursLarge
= config
166 .getInteger(Config
.CACHE_MAX_TIME_STABLE
, -1);
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 cache
= new DataLoader(ua
);
174 cache
.setTraceHandler(tracer
);
178 * The traces handler for this {@link Cache}.
182 * @return the traces handler (never NULL)
184 public static TraceHandler
getTraceHandler() {
189 * The traces handler for this {@link Cache}.
192 * the new traces handler or NULL
194 public static void setTraceHandler(TraceHandler tracer
) {
195 if (tracer
== null) {
196 tracer
= new TraceHandler(false, false, false);
199 Instance
.tracer
= tracer
;
200 cache
.setTraceHandler(tracer
);
204 * Get the (unique) configuration service for the program.
206 * @return the configuration service
208 public static ConfigBundle
getConfig() {
213 * Get the (unique) UI configuration service for the program.
215 * @return the configuration service
217 public static UiConfigBundle
getUiConfig() {
222 * Reset the configuration.
225 * also reset the translation files
227 public static void resetConfig(boolean resetTrans
) {
228 String dir
= Bundles
.getDirectory();
229 Bundles
.setDirectory(null);
232 ConfigBundle config
= new ConfigBundle();
233 config
.updateFile(configDir
);
234 } catch (IOException e
) {
238 UiConfigBundle uiconfig
= new UiConfigBundle();
239 uiconfig
.updateFile(configDir
);
240 } catch (IOException e
) {
246 StringIdBundle trans
= new StringIdBundle(null);
247 trans
.updateFile(configDir
);
248 } catch (IOException e
) {
253 Bundles
.setDirectory(dir
);
258 * Get the (unique) {@link DataLoader} for the program.
260 * @return the {@link DataLoader}
262 public static DataLoader
getCache() {
267 * Get the (unique) {link StringIdBundle} for the program.
269 * @return the {link StringIdBundle}
271 public static StringIdBundle
getTrans() {
276 * Get the (unique) {@link LocalLibrary} for the program.
278 * @return the {@link LocalLibrary}
280 public static BasicLibrary
getLibrary() {
282 throw new NullPointerException("We don't have a library to return");
289 * Return the directory where to look for default cover pages.
291 * @return the default covers directory
293 public static File
getCoverDir() {
298 * Return the directory where to store temporary files for the local reader.
300 * @return the directory
302 public static File
getReaderDir() {
307 * Return the directory where to store temporary files for the remote
308 * {@link LocalLibrary}.
311 * the remote for this host
313 * @return the directory
315 public static File
getRemoteDir(String host
) {
319 return new File(remoteDir
, host
);
326 * Check if we need to check that a new version of Fanfix is available.
328 * @return TRUE if we need to
330 public static boolean isVersionCheckNeeded() {
332 long wait
= config
.getInteger(Config
.UPDATE_INTERVAL
, 1) * 24 * 60
335 String lastUpString
= IOUtils
.readSmallFile(new File(configDir
,
337 long delay
= new Date().getTime()
338 - Long
.parseLong(lastUpString
);
345 } catch (Exception e
) {
346 // No file or bad file:
354 * Notify that we checked for a new version of Fanfix.
356 public static void setVersionChecked() {
358 IOUtils
.writeSmallFile(new File(configDir
), "LAST_UPDATE",
359 Long
.toString(new Date().getTime()));
360 } catch (IOException e
) {
366 * Return a path, but support the special $HOME variable.
370 private static File
getFile(Config id
) {
371 return getFile(config
.getString(id
));
375 * Return a path, but support the special $HOME variable.
379 private static File
getFile(UiConfig id
) {
380 return getFile(uiconfig
.getString(id
));
384 * Return a path, but support the special $HOME variable.
388 private static File
getFile(String path
) {
390 if (path
!= null && !path
.isEmpty()) {
391 path
= path
.replace('/', File
.separatorChar
);
392 if (path
.contains("$HOME")) {
393 path
= path
.replace("$HOME", getHome());
396 file
= new File(path
);
403 * Return the home directory from the system properties.
407 private static String
getHome() {
408 String home
= System
.getProperty("user.home");
409 if (home
== null || home
.trim().isEmpty()) {
410 home
= System
.getProperty("java.io.tmpdir");
421 * The language to use for the application (NULL = default system language).
423 * @return the language
425 private static String
getLang() {
426 String lang
= config
.getString(Config
.LANG
);
428 if (System
.getenv("LANG") != null && !System
.getenv("LANG").isEmpty()) {
429 lang
= System
.getenv("LANG");
432 if (lang
!= null && lang
.isEmpty()) {
440 * Check that the given environment variable is "enabled".
443 * the variable to check
445 * @return TRUE if it is
447 private static boolean checkEnv(String key
) {
448 String value
= System
.getenv(key
);
450 value
= value
.trim().toLowerCase();
451 if ("yes".equals(value
) || "true".equals(value
)
452 || "on".equals(value
) || "1".equals(value
)
453 || "y".equals(value
)) {