Fix remote save, better GUI if bad import url
[nikiroo-utils.git] / src / be / nikiroo / fanfix / library / RemoteLibrary.java
CommitLineData
e42573a0 1package be.nikiroo.fanfix.library;
b0e88ebd 2
68e2c6d2 3import java.awt.image.BufferedImage;
b0e88ebd
NR
4import java.io.File;
5import java.io.IOException;
e6249b0f 6import java.net.UnknownHostException;
68e2c6d2
NR
7import java.util.ArrayList;
8import java.util.List;
b0e88ebd 9
e42573a0 10import be.nikiroo.fanfix.Instance;
b0e88ebd
NR
11import be.nikiroo.fanfix.data.MetaData;
12import be.nikiroo.fanfix.data.Story;
b0e88ebd 13import be.nikiroo.utils.Progress;
416c54f8 14import be.nikiroo.utils.StringUtils;
b0e88ebd 15import be.nikiroo.utils.Version;
62c63b07 16import be.nikiroo.utils.serial.server.ConnectActionClientObject;
b0e88ebd 17
68e2c6d2
NR
18/**
19 * This {@link BasicLibrary} will access a remote server to list the available
a85e8077 20 * stories, and download the ones you try to load to the local directory
68e2c6d2
NR
21 * specified in the configuration.
22 *
23 * @author niki
24 */
25public class RemoteLibrary extends BasicLibrary {
b0e88ebd
NR
26 private String host;
27 private int port;
416c54f8 28 private final String md5;
68e2c6d2
NR
29
30 /**
31 * Create a {@link RemoteLibrary} linked to the given server.
32 *
2070ced5
NR
33 * @param key
34 * the key that will allow us to exchange information with the
35 * server
68e2c6d2
NR
36 * @param host
37 * the host to contact or NULL for localhost
38 * @param port
39 * the port to contact it on
40 */
2070ced5 41 public RemoteLibrary(String key, String host, int port) {
416c54f8 42 this.md5 = StringUtils.getMd5Hash(key);
b0e88ebd
NR
43 this.host = host;
44 this.port = port;
b0e88ebd
NR
45 }
46
99ccbdf6
NR
47 @Override
48 public String getLibraryName() {
49 return host + ":" + port;
50 }
51
e6249b0f
NR
52 @Override
53 public Status getStatus() {
54 final Status[] result = new Status[1];
55
56 result[0] = Status.INVALID;
57
58 ConnectActionClientObject action = null;
59 try {
60 action = new ConnectActionClientObject(host, port, true) {
61 @Override
62 public void action(Version serverVersion) throws Exception {
416c54f8 63 Object rep = send(new Object[] { md5, "PING" });
e6249b0f
NR
64 if ("PONG".equals(rep)) {
65 result[0] = Status.READY;
66 } else {
67 result[0] = Status.UNAUTORIZED;
68 }
69 }
70
71 @Override
72 protected void onError(Exception e) {
73 result[0] = Status.UNAVAILABLE;
74 }
75 };
76
77 } catch (UnknownHostException e) {
78 result[0] = Status.INVALID;
79 } catch (IllegalArgumentException e) {
80 result[0] = Status.INVALID;
81 } catch (Exception e) {
82 result[0] = Status.UNAVAILABLE;
83 }
84
85 if (action != null) {
86 try {
87 action.connect();
88 } catch (Exception e) {
89 result[0] = Status.UNAVAILABLE;
90 }
91 }
92
93 return result[0];
94 }
95
b0e88ebd 96 @Override
b9ce9cad
NR
97 public BufferedImage getCover(final String luid) {
98 final BufferedImage[] result = new BufferedImage[1];
b0e88ebd 99
b9ce9cad
NR
100 try {
101 new ConnectActionClientObject(host, port, true) {
102 @Override
103 public void action(Version serverVersion) throws Exception {
416c54f8 104 Object rep = send(new Object[] { md5, "GET_COVER", luid });
b9ce9cad
NR
105 result[0] = (BufferedImage) rep;
106 }
b0e88ebd 107
b9ce9cad
NR
108 @Override
109 protected void onError(Exception e) {
110 Instance.getTraceHandler().error(e);
111 }
112 }.connect();
113 } catch (Exception e) {
114 Instance.getTraceHandler().error(e);
115 }
b0e88ebd 116
b9ce9cad 117 return result[0];
085a2f9a
NR
118 }
119
120 @Override
121 public BufferedImage getSourceCover(final String source) {
b9ce9cad
NR
122 final BufferedImage[] result = new BufferedImage[1];
123
124 try {
125 new ConnectActionClientObject(host, port, true) {
126 @Override
127 public void action(Version serverVersion) throws Exception {
416c54f8 128 Object rep = send(new Object[] { md5, "GET_SOURCE_COVER",
b9ce9cad
NR
129 source });
130 result[0] = (BufferedImage) rep;
131 }
132
133 @Override
134 protected void onError(Exception e) {
135 Instance.getTraceHandler().error(e);
136 }
137 }.connect();
138 } catch (Exception e) {
139 Instance.getTraceHandler().error(e);
140 }
141
142 return result[0];
b0e88ebd 143 }
68e2c6d2
NR
144
145 @Override
ff05b828 146 public synchronized Story getStory(final String luid, Progress pg) {
b9ce9cad
NR
147 final Progress pgF = pg;
148 final Story[] result = new Story[1];
68e2c6d2 149
b9ce9cad
NR
150 try {
151 new ConnectActionClientObject(host, port, true) {
152 @Override
153 public void action(Version serverVersion) throws Exception {
154 Progress pg = pgF;
155 if (pg == null) {
156 pg = new Progress();
157 }
158
416c54f8 159 Object rep = send(new Object[] { md5, "GET_STORY", luid });
b9ce9cad
NR
160
161 MetaData meta = null;
162 if (rep instanceof MetaData) {
163 meta = (MetaData) rep;
164 if (meta.getWords() <= Integer.MAX_VALUE) {
165 pg.setMinMax(0, (int) meta.getWords());
166 }
167 }
168
169 List<Object> list = new ArrayList<Object>();
170 for (Object obj = send(null); obj != null; obj = send(null)) {
171 list.add(obj);
172 pg.add(1);
173 }
174
175 result[0] = RemoteLibraryServer.rebuildStory(list);
176 pg.done();
177 }
178
179 @Override
180 protected void onError(Exception e) {
181 Instance.getTraceHandler().error(e);
182 }
183 }.connect();
184 } catch (Exception e) {
185 Instance.getTraceHandler().error(e);
186 }
187
188 return result[0];
68e2c6d2
NR
189 }
190
191 @Override
b9ce9cad
NR
192 public synchronized Story save(final Story story, final String luid,
193 Progress pg) throws IOException {
194 final Progress pgF = pg;
195
196 new ConnectActionClientObject(host, port, true) {
197 @Override
198 public void action(Version serverVersion) throws Exception {
199 Progress pg = pgF;
200 if (pg == null) {
201 pg = new Progress();
202 }
203
204 if (story.getMeta().getWords() <= Integer.MAX_VALUE) {
205 pg.setMinMax(0, (int) story.getMeta().getWords());
206 }
207
416c54f8 208 send(new Object[] { md5, "SAVE_STORY", luid });
b9ce9cad
NR
209
210 List<Object> list = RemoteLibraryServer.breakStory(story);
211 for (Object obj : list) {
212 send(obj);
213 pg.add(1);
214 }
215
216 send(null);
217 pg.done();
218 }
219
220 @Override
221 protected void onError(Exception e) {
222 Instance.getTraceHandler().error(e);
223 }
224 }.connect();
085a2f9a
NR
225
226 // because the meta changed:
227 clearCache();
228 story.setMeta(getInfo(luid));
229
230 return story;
68e2c6d2
NR
231 }
232
233 @Override
b9ce9cad
NR
234 public synchronized void delete(final String luid) throws IOException {
235 new ConnectActionClientObject(host, port, true) {
236 @Override
237 public void action(Version serverVersion) throws Exception {
416c54f8 238 send(new Object[] { md5, "DELETE_STORY", luid });
b9ce9cad
NR
239 }
240
241 @Override
242 protected void onError(Exception e) {
243 Instance.getTraceHandler().error(e);
244 }
245 }.connect();
68e2c6d2
NR
246 }
247
248 @Override
b9ce9cad
NR
249 public void setSourceCover(final String source, final String luid) {
250 try {
251 new ConnectActionClientObject(host, port, true) {
252 @Override
253 public void action(Version serverVersion) throws Exception {
416c54f8 254 send(new Object[] { md5, "SET_SOURCE_COVER", source, luid });
b9ce9cad
NR
255 }
256
257 @Override
258 protected void onError(Exception e) {
259 Instance.getTraceHandler().error(e);
260 }
261 }.connect();
262 } catch (IOException e) {
263 Instance.getTraceHandler().error(e);
264 }
68e2c6d2
NR
265 }
266
ff05b828 267 @Override
2249988a 268 public synchronized File getFile(final String luid, Progress pg) {
ff05b828
NR
269 throw new java.lang.InternalError(
270 "Operation not supportorted on remote Libraries");
271 }
272
14b57448 273 @Override
b9ce9cad
NR
274 protected List<MetaData> getMetas(Progress pg) {
275 final Progress pgF = pg;
276 final List<MetaData> metas = new ArrayList<MetaData>();
74a40dfb 277
ff05b828 278 try {
62c63b07 279 new ConnectActionClientObject(host, port, true) {
ff05b828
NR
280 @Override
281 public void action(Version serverVersion) throws Exception {
b9ce9cad
NR
282 Progress pg = pgF;
283 if (pg == null) {
284 pg = new Progress();
851dd538 285 }
74a40dfb 286
416c54f8 287 Object rep = send(new Object[] { md5, "GET_METADATA", "*" });
74a40dfb 288
b9ce9cad
NR
289 while (true) {
290 if (!RemoteLibraryServer.updateProgress(pg, rep)) {
291 break;
292 }
74a40dfb 293
b9ce9cad 294 rep = send(null);
ff05b828 295 }
851dd538 296
b9ce9cad
NR
297 for (MetaData meta : (MetaData[]) rep) {
298 metas.add(meta);
299 }
851dd538
NR
300 }
301
302 @Override
303 protected void onError(Exception e) {
304 Instance.getTraceHandler().error(e);
ff05b828
NR
305 }
306 }.connect();
ff05b828 307 } catch (Exception e) {
62c63b07 308 Instance.getTraceHandler().error(e);
ff05b828 309 }
b9ce9cad
NR
310
311 return metas;
312 }
313
314 @Override
315 protected void clearCache() {
316 }
317
318 // The following methods are only used by Save and Delete in BasicLibrary:
319
320 @Override
321 protected int getNextId() {
322 throw new java.lang.InternalError("Should not have been called");
323 }
324
325 @Override
326 protected void doDelete(String luid) throws IOException {
327 throw new java.lang.InternalError("Should not have been called");
328 }
329
330 @Override
331 protected Story doSave(Story story, Progress pg) throws IOException {
332 throw new java.lang.InternalError("Should not have been called");
e604986c 333 }
b0e88ebd 334}