--list was causing problems + move reader
[fanfix.git] / src / be / nikiroo / fanfix / Main.java
CommitLineData
08fe2e33
NR
1package be.nikiroo.fanfix;
2
3import java.io.File;
4import java.io.IOException;
5import java.net.MalformedURLException;
6import java.net.URL;
7
8import be.nikiroo.fanfix.bundles.StringId;
9import be.nikiroo.fanfix.data.Chapter;
10import be.nikiroo.fanfix.data.Story;
11import be.nikiroo.fanfix.output.BasicOutput;
12import be.nikiroo.fanfix.output.BasicOutput.OutputType;
89cb07a6
NR
13import be.nikiroo.fanfix.reader.FanfixReader;
14import be.nikiroo.fanfix.reader.cli.CliReader;
08fe2e33
NR
15import be.nikiroo.fanfix.supported.BasicSupport;
16import be.nikiroo.fanfix.supported.BasicSupport.SupportType;
17
18/**
19 * Main program entry point.
20 *
21 * @author niki
22 */
23public class Main {
24 /**
25 * Main program entry point.
26 * <p>
27 * Known environment variables:
28 * <ul>
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>
34 * </ul>
35 *
36 * @param args
37 * <ol>
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>
45 * </ol>
46 */
47 public static void main(String[] args) {
48 int exitCode = 255;
49
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]);
55 }
56 } else if (action.equals("--export")) {
57 if (args.length > 3) {
58 exitCode = export(args[1], args[2], args[3]);
59 }
60 } else if (action.equals("--convert")) {
61 if (args.length > 3) {
62 exitCode = convert(
63 args[1],
64 args[2],
65 args[3],
66 args.length > 4 ? args[4].toLowerCase().equals(
67 "+info") : false);
68 }
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,
74 false);
75 }
76 } else if (action.equals("--read")) {
77 if (args.length > 1) {
78 exitCode = read(args[1], args.length > 2 ? args[2] : null,
79 true);
80 }
81 }
82 }
83
84 if (exitCode == 255) {
85 syntax();
86 }
87
88 if (exitCode != 0) {
89 System.exit(exitCode);
90 }
91 }
92
93 /**
94 * Return an {@link URL} from this {@link String}, be it a file path or an
95 * actual {@link URL}.
96 *
97 * @param sourceString
98 * the source
99 *
100 * @return the corresponding {@link URL}
101 *
102 * @throws MalformedURLException
103 * if this is neither a file nor a conventional {@link URL}
104 */
105 private static URL getUrl(String sourceString) throws MalformedURLException {
106 if (sourceString == null || sourceString.isEmpty()) {
107 throw new MalformedURLException("Empty url");
108 }
109
110 URL source = null;
111 try {
112 source = new URL(sourceString);
113 } catch (MalformedURLException e) {
114 File sourceFile = new File(sourceString);
115 source = sourceFile.toURI().toURL();
116 }
117
118 return source;
119 }
120
121 /**
122 * Import the given resource into the {@link Library}.
123 *
124 * @param sourceString
125 * the resource to import
126 *
127 * @return the exit return code (0 = success)
128 */
129 private static int imprt(String sourceString) {
130 try {
131 Story story = Instance.getLibrary().imprt(getUrl(sourceString));
132 System.out.println(story.getMeta().getLuid() + ": \""
133 + story.getMeta().getTitle() + "\" imported.");
134 } catch (IOException e) {
135 Instance.syserr(e);
136 return 1;
137 }
138
139 return 0;
140 }
141
142 /**
143 * Export the {@link Story} from the {@link Library} to the given target.
144 *
145 * @param sourceString
146 * the story LUID
147 * @param typeString
148 * the {@link OutputType} to use
149 * @param target
150 * the target
151 *
152 * @return the exit return code (0 = success)
153 */
154 private static int export(String sourceString, String typeString,
155 String target) {
156 OutputType type = OutputType.valueOfNullOkUC(typeString);
157 if (type == null) {
158 Instance.syserr(new Exception(trans(StringId.OUTPUT_DESC,
159 typeString)));
160 return 1;
161 }
162
163 try {
164 Story story = Instance.getLibrary().imprt(new URL(sourceString));
165 Instance.getLibrary().export(story.getMeta().getLuid(), type,
166 target);
167 } catch (IOException e) {
168 Instance.syserr(e);
169 return 4;
170 }
171
172 return 0;
173 }
174
175 /**
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).
178 *
179 * @param typeString
180 * the {@link SupportType} to list the known stories of, or NULL
181 * to list all stories
182 *
183 * @return the exit return code (0 = success)
184 */
185 private static int list(String typeString) {
186 SupportType type = null;
187 try {
188 type = SupportType.valueOfNullOkUC(typeString);
189 } catch (Exception e) {
190 Instance.syserr(new Exception(
191 trans(StringId.INPUT_DESC, typeString), e));
192 return 1;
193 }
194
89cb07a6 195 new CliReader().start(type);
08fe2e33
NR
196
197 return 0;
198 }
199
200 /**
201 * Start the CLI reader for this {@link Story}.
202 *
203 * @param story
204 * the LUID of the {@link Story} in the {@link Library} <b>or</b>
205 * the {@link Story} {@link URL}
206 * @param chap
207 * which {@link Chapter} to read (starting at 1), or NULL to get
208 * the {@link Story} description
209 * @param library
210 * TRUE if the source is the {@link Story} LUID, FALSE if it is a
211 * {@link URL}
212 *
213 * @return the exit return code (0 = success)
214 */
215 private static int read(String story, String chap, boolean library) {
216 try {
89cb07a6 217 FanfixReader reader = new CliReader();
08fe2e33 218 if (library) {
89cb07a6 219 reader.setStory(story);
08fe2e33 220 } else {
89cb07a6 221 reader.setStory(getUrl(story));
08fe2e33
NR
222 }
223
224 if (chap != null) {
225 reader.read(Integer.parseInt(chap));
226 } else {
227 reader.read();
228 }
229 } catch (IOException e) {
230 Instance.syserr(e);
231 return 1;
232 }
233
234 return 0;
235 }
236
237 /**
238 * Convert the {@link Story} into another format.
239 *
240 * @param sourceString
241 * the source {@link Story} to convert
242 * @param typeString
243 * the {@link OutputType} to convert to
244 * @param filename
245 * the target file
246 * @param infoCover
247 * TRUE to also export the cover and info file, even if the given
248 * {@link OutputType} does not usually save them
249 *
250 * @return the exit return code (0 = success)
251 */
252 private static int convert(String sourceString, String typeString,
253 String filename, boolean infoCover) {
254 int exitCode = 0;
255
256 String sourceName = sourceString;
257 try {
258 URL source = getUrl(sourceString);
259 sourceName = source.toString();
260 if (source.toString().startsWith("file://")) {
261 sourceName = sourceName.substring("file://".length());
262 }
263
264 OutputType type = OutputType.valueOfAllOkUC(typeString);
265 if (type == null) {
266 Instance.syserr(new IOException(trans(
267 StringId.ERR_BAD_OUTPUT_TYPE, typeString)));
268
269 exitCode = 2;
270 } else {
271 try {
272 BasicSupport support = BasicSupport.getSupport(source);
273 if (support != null) {
274 Story story = support.process(source);
275
276 try {
277 filename = new File(filename).getAbsolutePath();
278 BasicOutput.getOutput(type, infoCover).process(
279 story, filename);
280 } catch (IOException e) {
281 Instance.syserr(new IOException(trans(
282 StringId.ERR_SAVING, filename), e));
283 exitCode = 5;
284 }
285 } else {
286 Instance.syserr(new IOException(trans(
287 StringId.ERR_NOT_SUPPORTED, source)));
288
289 exitCode = 4;
290 }
291 } catch (IOException e) {
292 Instance.syserr(new IOException(trans(StringId.ERR_LOADING,
293 sourceName), e));
294 exitCode = 3;
295 }
296 }
297 } catch (MalformedURLException e) {
298 Instance.syserr(new IOException(trans(StringId.ERR_BAD_URL,
299 sourceName), e));
300 exitCode = 1;
301 }
302
303 return exitCode;
304 }
305
306 /**
307 * Simple shortcut method to call {link Instance#getTrans()#getString()}.
308 *
309 * @param id
310 * the ID to translate
311 *
312 * @return the translated result
313 */
314 private static String trans(StringId id, Object... params) {
315 return Instance.getTrans().getString(id, params);
316 }
317
318 /**
319 * Display the correct syntax of the program to the user.
320 */
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(),
325 type.getDesc()));
326 builder.append('\n');
327 }
328
329 String typesIn = builder.toString();
330 builder.setLength(0);
331
332 for (OutputType type : OutputType.values()) {
333 builder.append(trans(StringId.ERR_SYNTAX_TYPE, type.toString(),
334 type.getDesc()));
335 builder.append('\n');
336 }
337
338 String typesOut = builder.toString();
339
340 System.err.println(trans(StringId.ERR_SYNTAX, typesIn, typesOut));
341 }
342}