1 package be
.nikiroo
.fanfix
;
4 import java
.io
.IOException
;
5 import java
.net
.MalformedURLException
;
8 import be
.nikiroo
.fanfix
.bundles
.StringId
;
9 import be
.nikiroo
.fanfix
.data
.Chapter
;
10 import be
.nikiroo
.fanfix
.data
.Story
;
11 import be
.nikiroo
.fanfix
.output
.BasicOutput
;
12 import be
.nikiroo
.fanfix
.output
.BasicOutput
.OutputType
;
13 import be
.nikiroo
.fanfix
.reader
.FanfixReader
;
14 import be
.nikiroo
.fanfix
.reader
.cli
.CliReader
;
15 import be
.nikiroo
.fanfix
.supported
.BasicSupport
;
16 import be
.nikiroo
.fanfix
.supported
.BasicSupport
.SupportType
;
19 * Main program entry point.
25 * Main program entry point.
27 * Known environment variables:
29 * <li>NOUTF: if set to 1, the program will prefer non-unicode
30 * {@link String}s when possible</li>
31 * <li>CONFIG_DIR: a path where to look for the <tt>.properties</tt> files
32 * before taking the included ones; they will also be saved/updated into
33 * this path when the program starts</li>
38 * <li>--import [URL]: import into library</li> <li>--export [id]
39 * [output_type] [target]: export story to target</li> <li>
40 * --convert [URL] [output_type] [target]: convert URL into
41 * target</li> <li>--read [id]: read the given story from the
42 * library</li> <li>--read-url [URL]: convert on the fly and read
43 * the story, without saving it</li> <li>--list: list the stories
44 * present in the library</li>
47 public static void main(String
[] args
) {
50 if (args
.length
> 0) {
51 String action
= args
[0];
52 if (action
.equals("--import")) {
53 if (args
.length
> 1) {
54 exitCode
= imprt(args
[1]);
56 } else if (action
.equals("--export")) {
57 if (args
.length
> 3) {
58 exitCode
= export(args
[1], args
[2], args
[3]);
60 } else if (action
.equals("--convert")) {
61 if (args
.length
> 3) {
66 args
.length
> 4 ? args
[4].toLowerCase().equals(
69 } else if (action
.equals("--list")) {
70 exitCode
= list(args
.length
> 1 ? args
[1] : null);
71 } else if (action
.equals("--read-url")) {
72 if (args
.length
> 1) {
73 exitCode
= read(args
[1], args
.length
> 2 ? args
[2] : null,
76 } else if (action
.equals("--read")) {
77 if (args
.length
> 1) {
78 exitCode
= read(args
[1], args
.length
> 2 ? args
[2] : null,
84 if (exitCode
== 255) {
89 System
.exit(exitCode
);
94 * Return an {@link URL} from this {@link String}, be it a file path or an
100 * @return the corresponding {@link URL}
102 * @throws MalformedURLException
103 * if this is neither a file nor a conventional {@link URL}
105 private static URL
getUrl(String sourceString
) throws MalformedURLException
{
106 if (sourceString
== null || sourceString
.isEmpty()) {
107 throw new MalformedURLException("Empty url");
112 source
= new URL(sourceString
);
113 } catch (MalformedURLException e
) {
114 File sourceFile
= new File(sourceString
);
115 source
= sourceFile
.toURI().toURL();
122 * Import the given resource into the {@link Library}.
124 * @param sourceString
125 * the resource to import
127 * @return the exit return code (0 = success)
129 private static int imprt(String sourceString
) {
131 Story story
= Instance
.getLibrary().imprt(getUrl(sourceString
));
132 System
.out
.println(story
.getMeta().getLuid() + ": \""
133 + story
.getMeta().getTitle() + "\" imported.");
134 } catch (IOException e
) {
143 * Export the {@link Story} from the {@link Library} to the given target.
145 * @param sourceString
148 * the {@link OutputType} to use
152 * @return the exit return code (0 = success)
154 private static int export(String sourceString
, String typeString
,
156 OutputType type
= OutputType
.valueOfNullOkUC(typeString
);
158 Instance
.syserr(new Exception(trans(StringId
.OUTPUT_DESC
,
164 Story story
= Instance
.getLibrary().imprt(new URL(sourceString
));
165 Instance
.getLibrary().export(story
.getMeta().getLuid(), type
,
167 } catch (IOException e
) {
176 * List the stories of the given type from the {@link Library} (unless NULL
177 * is passed, in which case all stories will be listed).
180 * the {@link SupportType} to list the known stories of, or NULL
181 * to list all stories
183 * @return the exit return code (0 = success)
185 private static int list(String typeString
) {
186 SupportType type
= null;
188 type
= SupportType
.valueOfNullOkUC(typeString
);
189 } catch (Exception e
) {
190 Instance
.syserr(new Exception(
191 trans(StringId
.INPUT_DESC
, typeString
), e
));
195 new CliReader().start(type
);
201 * Start the CLI reader for this {@link Story}.
204 * the LUID of the {@link Story} in the {@link Library} <b>or</b>
205 * the {@link Story} {@link URL}
207 * which {@link Chapter} to read (starting at 1), or NULL to get
208 * the {@link Story} description
210 * TRUE if the source is the {@link Story} LUID, FALSE if it is a
213 * @return the exit return code (0 = success)
215 private static int read(String story
, String chap
, boolean library
) {
217 FanfixReader reader
= new CliReader();
219 reader
.setStory(story
);
221 reader
.setStory(getUrl(story
));
225 reader
.read(Integer
.parseInt(chap
));
229 } catch (IOException e
) {
238 * Convert the {@link Story} into another format.
240 * @param sourceString
241 * the source {@link Story} to convert
243 * the {@link OutputType} to convert to
247 * TRUE to also export the cover and info file, even if the given
248 * {@link OutputType} does not usually save them
250 * @return the exit return code (0 = success)
252 private static int convert(String sourceString
, String typeString
,
253 String filename
, boolean infoCover
) {
256 String sourceName
= sourceString
;
258 URL source
= getUrl(sourceString
);
259 sourceName
= source
.toString();
260 if (source
.toString().startsWith("file://")) {
261 sourceName
= sourceName
.substring("file://".length());
264 OutputType type
= OutputType
.valueOfAllOkUC(typeString
);
266 Instance
.syserr(new IOException(trans(
267 StringId
.ERR_BAD_OUTPUT_TYPE
, typeString
)));
272 BasicSupport support
= BasicSupport
.getSupport(source
);
273 if (support
!= null) {
274 Story story
= support
.process(source
);
277 filename
= new File(filename
).getAbsolutePath();
278 BasicOutput
.getOutput(type
, infoCover
).process(
280 } catch (IOException e
) {
281 Instance
.syserr(new IOException(trans(
282 StringId
.ERR_SAVING
, filename
), e
));
286 Instance
.syserr(new IOException(trans(
287 StringId
.ERR_NOT_SUPPORTED
, source
)));
291 } catch (IOException e
) {
292 Instance
.syserr(new IOException(trans(StringId
.ERR_LOADING
,
297 } catch (MalformedURLException e
) {
298 Instance
.syserr(new IOException(trans(StringId
.ERR_BAD_URL
,
307 * Simple shortcut method to call {link Instance#getTrans()#getString()}.
310 * the ID to translate
312 * @return the translated result
314 private static String
trans(StringId id
, Object
... params
) {
315 return Instance
.getTrans().getString(id
, params
);
319 * Display the correct syntax of the program to the user.
321 private static void syntax() {
322 StringBuilder builder
= new StringBuilder();
323 for (SupportType type
: SupportType
.values()) {
324 builder
.append(trans(StringId
.ERR_SYNTAX_TYPE
, type
.toString(),
326 builder
.append('\n');
329 String typesIn
= builder
.toString();
330 builder
.setLength(0);
332 for (OutputType type
: OutputType
.values()) {
333 builder
.append(trans(StringId
.ERR_SYNTAX_TYPE
, type
.toString(),
335 builder
.append('\n');
338 String typesOut
= builder
.toString();
340 System
.err
.println(trans(StringId
.ERR_SYNTAX
, typesIn
, typesOut
));