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