Commit | Line | Data |
---|---|---|
a6395bef NR |
1 | package be.nikiroo.fanfix.reader; |
2 | ||
edd46289 | 3 | import java.awt.Desktop; |
a6395bef NR |
4 | import java.awt.EventQueue; |
5 | import java.io.File; | |
6 | import java.io.IOException; | |
b42117f1 NR |
7 | import java.net.URISyntaxException; |
8 | ||
9 | import javax.swing.JEditorPane; | |
10 | import javax.swing.JLabel; | |
11 | import javax.swing.JOptionPane; | |
12 | import javax.swing.event.HyperlinkEvent; | |
13 | import javax.swing.event.HyperlinkListener; | |
a6395bef NR |
14 | |
15 | import be.nikiroo.fanfix.Instance; | |
16 | import be.nikiroo.fanfix.Library; | |
b42117f1 | 17 | import be.nikiroo.fanfix.VersionCheck; |
b4dc6ab5 | 18 | import be.nikiroo.fanfix.bundles.UiConfig; |
edd46289 | 19 | import be.nikiroo.fanfix.data.MetaData; |
a6395bef NR |
20 | import be.nikiroo.fanfix.data.Story; |
21 | import be.nikiroo.fanfix.output.BasicOutput.OutputType; | |
3b2b638f | 22 | import be.nikiroo.utils.Progress; |
b42117f1 | 23 | import be.nikiroo.utils.Version; |
a6395bef NR |
24 | |
25 | class LocalReader extends BasicReader { | |
26 | private Library lib; | |
27 | ||
28 | public LocalReader() throws IOException { | |
29 | File dir = Instance.getReaderDir(); | |
30 | dir.mkdirs(); | |
31 | if (!dir.exists()) { | |
32 | throw new IOException( | |
33 | "Cannote create cache directory for local reader: " + dir); | |
34 | } | |
35 | ||
edd46289 NR |
36 | OutputType text = null; |
37 | OutputType images = null; | |
38 | ||
39 | try { | |
40 | text = OutputType.valueOfNullOkUC(Instance.getUiConfig().getString( | |
41 | UiConfig.NON_IMAGES_DOCUMENT_TYPE)); | |
42 | if (text == null) { | |
43 | text = OutputType.HTML; | |
44 | } | |
45 | ||
46 | images = OutputType.valueOfNullOkUC(Instance.getUiConfig() | |
47 | .getString(UiConfig.IMAGES_DOCUMENT_TYPE)); | |
48 | if (images == null) { | |
49 | images = OutputType.CBZ; | |
50 | } | |
51 | } catch (Exception e) { | |
52 | UiConfig key = (text == null) ? UiConfig.NON_IMAGES_DOCUMENT_TYPE | |
53 | : UiConfig.IMAGES_DOCUMENT_TYPE; | |
54 | String value = Instance.getUiConfig().getString(key); | |
a6395bef | 55 | |
edd46289 NR |
56 | throw new IOException( |
57 | String.format( | |
58 | "The configuration option %s is not valid: %s", | |
59 | key, value), e); | |
a6395bef | 60 | } |
a6395bef NR |
61 | |
62 | lib = new Library(dir, text, images); | |
63 | } | |
64 | ||
65 | @Override | |
66 | public void read() throws IOException { | |
edd46289 NR |
67 | if (getStory() == null) { |
68 | throw new IOException("No story to read"); | |
69 | } | |
70 | ||
71 | open(getStory().getMeta().getLuid(), null); | |
a6395bef NR |
72 | } |
73 | ||
74 | @Override | |
edd46289 NR |
75 | public void read(int chapter) throws IOException { |
76 | // TODO: show a special page? | |
77 | read(); | |
a6395bef NR |
78 | } |
79 | ||
92fb0719 NR |
80 | /** |
81 | * Import the story into the local reader library, and keep the same LUID. | |
82 | * | |
83 | * @param luid | |
84 | * the Library UID | |
85 | * @param pg | |
86 | * the optional progress reporter | |
87 | * | |
88 | * @throws IOException | |
89 | * in case of I/O error | |
90 | */ | |
91 | public void imprt(String luid, Progress pg) throws IOException { | |
bee7dffe NR |
92 | Progress pgGetStory = new Progress(); |
93 | Progress pgSave = new Progress(); | |
94 | if (pg != null) { | |
95 | pg.setMax(2); | |
96 | pg.addProgress(pgGetStory, 1); | |
97 | pg.addProgress(pgSave, 1); | |
98 | } | |
99 | ||
a6395bef | 100 | try { |
bee7dffe | 101 | Story story = Instance.getLibrary().getStory(luid, pgGetStory); |
3d247bc3 | 102 | if (story != null) { |
bee7dffe | 103 | story = lib.save(story, luid, pgSave); |
3d247bc3 NR |
104 | } else { |
105 | throw new IOException("Cannot find story in Library: " + luid); | |
106 | } | |
a6395bef | 107 | } catch (IOException e) { |
3d247bc3 | 108 | throw new IOException( |
a6395bef | 109 | "Cannot import story from library to LocalReader library: " |
3d247bc3 | 110 | + luid, e); |
a6395bef | 111 | } |
a6395bef NR |
112 | } |
113 | ||
92fb0719 NR |
114 | /** |
115 | * Get the target file related to this {@link Story}. | |
116 | * | |
117 | * @param luid | |
118 | * the LUID of the {@link Story} | |
119 | * @param pg | |
120 | * the optional progress reporter | |
121 | * | |
122 | * @return the target file | |
123 | * | |
124 | * @throws IOException | |
125 | * in case of I/O error | |
126 | */ | |
127 | public File getTarget(String luid, Progress pg) throws IOException { | |
a6395bef NR |
128 | File file = lib.getFile(luid); |
129 | if (file == null) { | |
92fb0719 | 130 | imprt(luid, pg); |
a6395bef | 131 | file = lib.getFile(luid); |
a6395bef NR |
132 | } |
133 | ||
134 | return file; | |
135 | } | |
136 | ||
9843a5e5 NR |
137 | /** |
138 | * Check if the {@link Story} denoted by this Library UID is present in the | |
139 | * {@link LocalReader} cache. | |
140 | * | |
141 | * @param luid | |
142 | * the Library UID | |
143 | * | |
144 | * @return TRUE if it is | |
145 | */ | |
10d558d2 NR |
146 | public boolean isCached(String luid) { |
147 | return lib.getInfo(luid) != null; | |
148 | } | |
149 | ||
a6395bef | 150 | @Override |
333f0e7b | 151 | public void start(String type) { |
b42117f1 NR |
152 | // TODO: improve presentation of update message |
153 | final VersionCheck updates = VersionCheck.check(); | |
154 | StringBuilder builder = new StringBuilder(); | |
155 | ||
156 | final JEditorPane updateMessage = new JEditorPane("text/html", ""); | |
157 | if (updates.isNewVersionAvailable()) { | |
158 | builder.append("A new version of the program is available at <span style='color: blue;'>https://github.com/nikiroo/fanfix/releases</span>"); | |
159 | builder.append("<br>"); | |
160 | builder.append("<br>"); | |
161 | for (Version v : updates.getNewer()) { | |
162 | builder.append("\t<b>Version " + v + "</b>"); | |
163 | builder.append("<br>"); | |
164 | builder.append("<ul>"); | |
165 | for (String item : updates.getChanges().get(v)) { | |
166 | builder.append("<li>" + item + "</li>"); | |
167 | } | |
168 | builder.append("</ul>"); | |
169 | } | |
170 | ||
171 | // html content | |
172 | updateMessage.setText("<html><body>" // | |
173 | + builder// | |
174 | + "</body></html>"); | |
175 | ||
176 | // handle link events | |
177 | updateMessage.addHyperlinkListener(new HyperlinkListener() { | |
178 | public void hyperlinkUpdate(HyperlinkEvent e) { | |
179 | if (e.getEventType().equals( | |
180 | HyperlinkEvent.EventType.ACTIVATED)) | |
181 | try { | |
182 | Desktop.getDesktop().browse(e.getURL().toURI()); | |
183 | } catch (IOException ee) { | |
184 | Instance.syserr(ee); | |
185 | } catch (URISyntaxException ee) { | |
186 | Instance.syserr(ee); | |
187 | } | |
188 | } | |
189 | }); | |
190 | updateMessage.setEditable(false); | |
191 | updateMessage.setBackground(new JLabel().getBackground()); | |
192 | } | |
193 | ||
333f0e7b | 194 | final String typeFinal = type; |
a6395bef NR |
195 | EventQueue.invokeLater(new Runnable() { |
196 | public void run() { | |
b42117f1 NR |
197 | if (updates.isNewVersionAvailable()) { |
198 | int rep = JOptionPane.showConfirmDialog(null, | |
199 | updateMessage, "Updates available", | |
200 | JOptionPane.OK_CANCEL_OPTION); | |
201 | if (rep == JOptionPane.OK_OPTION) { | |
202 | updates.ok(); | |
203 | } else { | |
204 | updates.ignore(); | |
205 | } | |
206 | } | |
207 | ||
a6395bef NR |
208 | new LocalReaderFrame(LocalReader.this, typeFinal) |
209 | .setVisible(true); | |
210 | } | |
211 | }); | |
212 | } | |
10d558d2 | 213 | |
754a5bc2 NR |
214 | // delete from local reader library |
215 | void clearLocalReaderCache(String luid) { | |
10d558d2 NR |
216 | lib.delete(luid); |
217 | } | |
218 | ||
edd46289 | 219 | // delete from main library |
10d558d2 NR |
220 | void delete(String luid) { |
221 | lib.delete(luid); | |
222 | Instance.getLibrary().delete(luid); | |
223 | } | |
edd46289 NR |
224 | |
225 | // open the given book | |
226 | void open(String luid, Progress pg) throws IOException { | |
227 | MetaData meta = Instance.getLibrary().getInfo(luid); | |
228 | File target = getTarget(luid, pg); | |
229 | ||
230 | String program = null; | |
231 | if (meta.isImageDocument()) { | |
232 | program = Instance.getUiConfig().getString( | |
233 | UiConfig.IMAGES_DOCUMENT_READER); | |
234 | } else { | |
235 | program = Instance.getUiConfig().getString( | |
236 | UiConfig.NON_IMAGES_DOCUMENT_READER); | |
237 | } | |
238 | ||
239 | if (program != null && program.trim().isEmpty()) { | |
240 | program = null; | |
241 | } | |
242 | ||
243 | if (program == null) { | |
244 | try { | |
245 | Desktop.getDesktop().browse(target.toURI()); | |
246 | } catch (UnsupportedOperationException e) { | |
247 | Runtime.getRuntime().exec( | |
248 | new String[] { "xdg-open", target.getAbsolutePath() }); | |
249 | ||
250 | } | |
251 | } else { | |
252 | Runtime.getRuntime().exec( | |
253 | new String[] { program, target.getAbsolutePath() }); | |
254 | ||
255 | } | |
256 | } | |
a6395bef | 257 | } |