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
.StringIdBundle
;
10 import be
.nikiroo
.fanfix
.bundles
.UiConfig
;
11 import be
.nikiroo
.fanfix
.bundles
.UiConfigBundle
;
12 import be
.nikiroo
.fanfix
.library
.BasicLibrary
;
13 import be
.nikiroo
.fanfix
.library
.LocalLibrary
;
14 import be
.nikiroo
.fanfix
.output
.BasicOutput
.OutputType
;
15 import be
.nikiroo
.utils
.IOUtils
;
16 import be
.nikiroo
.utils
.resources
.Bundles
;
19 * Global state for the program (services and singletons).
23 public class Instance
{
25 * A handler when a recoverable exception was caught by the program.
29 public interface SyserrHandler
{
31 * An exception happened, log it.
36 * show more details (usually equivalent to the value of
39 public void notify(Exception e
, boolean showDetails
);
43 * A handler when a trace message is sent.
47 public interface TraceHandler
{
49 * A trace happened, show it.
51 * Will only be called if TRACE is true.
56 public void trace(String message
);
59 private static ConfigBundle config
;
60 private static UiConfigBundle uiconfig
;
61 private static StringIdBundle trans
;
62 private static Cache cache
;
63 private static LocalLibrary lib
;
64 private static boolean debug
;
65 private static boolean trace
;
66 private static File coverDir
;
67 private static File readerTmp
;
68 private static File remoteDir
;
69 private static String configDir
;
71 private static SyserrHandler syserrHandler
;
73 private static TraceHandler traceHandler
;
76 // Most of the rest is dependent upon this:
77 config
= new ConfigBundle();
79 configDir
= System
.getProperty("CONFIG_DIR");
80 if (configDir
== null) {
81 configDir
= System
.getenv("CONFIG_DIR");
84 if (configDir
== null) {
85 configDir
= new File(System
.getProperty("user.home"), ".fanfix")
89 if (!new File(configDir
).exists()) {
90 new File(configDir
).mkdirs();
92 Bundles
.setDirectory(configDir
);
96 config
= new ConfigBundle();
97 config
.updateFile(configDir
);
98 } catch (IOException e
) {
102 uiconfig
= new UiConfigBundle();
103 uiconfig
.updateFile(configDir
);
104 } catch (IOException e
) {
108 trans
= new StringIdBundle(getLang());
109 trans
.updateFile(configDir
);
110 } catch (IOException e
) {
114 Bundles
.setDirectory(configDir
);
116 uiconfig
= new UiConfigBundle();
117 trans
= new StringIdBundle(getLang());
119 lib
= new LocalLibrary(getFile(Config
.LIBRARY_DIR
),
120 OutputType
.INFO_TEXT
, OutputType
.CBZ
);
121 } catch (Exception e
) {
122 syserr(new IOException("Cannot create library for directory: "
123 + getFile(Config
.LIBRARY_DIR
), e
));
126 debug
= Instance
.getConfig().getBoolean(Config
.DEBUG_ERR
, false);
127 trace
= Instance
.getConfig().getBoolean(Config
.DEBUG_TRACE
, false);
128 coverDir
= getFile(Config
.DEFAULT_COVERS_DIR
);
129 File tmp
= getFile(Config
.CACHE_DIR
);
130 readerTmp
= getFile(UiConfig
.CACHE_DIR_LOCAL_READER
);
131 remoteDir
= new File(getFile(Config
.LIBRARY_DIR
), "remote");
133 if (checkEnv("NOUTF")) {
134 trans
.setUnicode(false);
137 if (checkEnv("DEBUG")) {
141 // Could have used: System.getProperty("java.io.tmpdir")
143 tmp
= new File(configDir
, "tmp");
145 if (readerTmp
== null) {
146 readerTmp
= new File(configDir
, "tmp-reader");
150 if (coverDir
!= null && !coverDir
.exists()) {
151 syserr(new IOException(
152 "The 'default covers' directory does not exists: "
158 String ua
= config
.getString(Config
.USER_AGENT
);
159 int hours
= config
.getInteger(Config
.CACHE_MAX_TIME_CHANGING
, -1);
160 int hoursLarge
= config
161 .getInteger(Config
.CACHE_MAX_TIME_STABLE
, -1);
163 cache
= new Cache(tmp
, ua
, hours
, hoursLarge
);
164 } catch (IOException e
) {
165 syserr(new IOException(
166 "Cannot create cache (will continue without cache)", e
));
171 * Get the (unique) configuration service for the program.
173 * @return the configuration service
175 public static ConfigBundle
getConfig() {
180 * Get the (unique) UI configuration service for the program.
182 * @return the configuration service
184 public static UiConfigBundle
getUiConfig() {
189 * Get the (unique) {@link Cache} for the program.
191 * @return the {@link Cache}
193 public static Cache
getCache() {
198 * Get the (unique) {link StringIdBundle} for the program.
200 * @return the {link StringIdBundle}
202 public static StringIdBundle
getTrans() {
207 * Get the (unique) {@link LocalLibrary} for the program.
209 * @return the {@link LocalLibrary}
211 public static BasicLibrary
getLibrary() {
216 * Return the directory where to look for default cover pages.
218 * @return the default covers directory
220 public static File
getCoverDir() {
225 * Return the directory where to store temporary files for the local reader.
227 * @return the directory
229 public static File
getReaderDir() {
234 * Return the directory where to store temporary files for the remote
235 * {@link LocalLibrary}.
238 * the remote for this host
240 * @return the directory
242 public static File
getRemoteDir(String host
) {
246 return new File(remoteDir
, host
);
253 * Check if we need to check that a new version of Fanfix is available.
255 * @return TRUE if we need to
257 public static boolean isVersionCheckNeeded() {
259 long wait
= config
.getInteger(Config
.UPDATE_INTERVAL
, 1) * 24 * 60
262 String lastUpString
= IOUtils
.readSmallFile(new File(configDir
,
264 long delay
= new Date().getTime()
265 - Long
.parseLong(lastUpString
);
272 } catch (Exception e
) {
273 // No file or bad file:
281 * Notify that we checked for a new version of Fanfix.
283 public static void setVersionChecked() {
285 IOUtils
.writeSmallFile(new File(configDir
), "LAST_UPDATE",
286 Long
.toString(new Date().getTime()));
287 } catch (IOException e
) {
293 * Replace the global syserr handler.
295 * @param syserrHandler
296 * the new syserr handler
298 public static void setSyserrHandler(SyserrHandler syserrHandler
) {
299 Instance
.syserrHandler
= syserrHandler
;
303 * Replace the global trace handler.
305 * @param traceHandler
306 * the new trace handler
308 public static void setTraceHandler(TraceHandler traceHandler
) {
309 Instance
.traceHandler
= traceHandler
;
313 * Report an error to the user
316 * the {@link Exception} to report
318 public static void syserr(Exception e
) {
319 if (syserrHandler
!= null) {
320 syserrHandler
.notify(e
, debug
);
325 System
.err
.println(e
.getMessage());
331 * Notify of a debug message.
336 public static void trace(String message
) {
338 if (traceHandler
!= null) {
339 traceHandler
.trace(message
);
341 System
.out
.println(message
);
347 * Return a path, but support the special $HOME variable.
351 private static File
getFile(Config id
) {
352 return getFile(config
.getString(id
));
356 * Return a path, but support the special $HOME variable.
360 private static File
getFile(UiConfig id
) {
361 return getFile(uiconfig
.getString(id
));
365 * Return a path, but support the special $HOME variable.
369 private static File
getFile(String path
) {
371 if (path
!= null && !path
.isEmpty()) {
372 path
= path
.replace('/', File
.separatorChar
);
373 if (path
.contains("$HOME")) {
374 path
= path
.replace("$HOME",
375 "" + System
.getProperty("user.home"));
378 file
= new File(path
);
385 * The language to use for the application (NULL = default system language).
387 * @return the language
389 private static String
getLang() {
390 String lang
= config
.getString(Config
.LANG
);
392 if (System
.getenv("LANG") != null && !System
.getenv("LANG").isEmpty()) {
393 lang
= System
.getenv("LANG");
396 if (lang
!= null && lang
.isEmpty()) {
404 * Check that the given environment variable is "enabled".
407 * the variable to check
409 * @return TRUE if it is
411 private static boolean checkEnv(String key
) {
412 String value
= System
.getenv(key
);
414 value
= value
.trim().toLowerCase();
415 if ("yes".equals(value
) || "true".equals(value
)
416 || "on".equals(value
) || "1".equals(value
)
417 || "y".equals(value
)) {