Fix remote saving
[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 {
0fa0fe95
NR
194 final String[] luidSaved = new String[1];
195 Progress pgSave = new Progress();
196 Progress pgRefresh = new Progress();
197 if (pg == null) {
198 pg = new Progress();
199 }
200
201 pg.setMinMax(0, 10);
202 pg.addProgress(pgSave, 9);
203 pg.addProgress(pgRefresh, 1);
204
205 final Progress pgF = pgSave;
b9ce9cad
NR
206
207 new ConnectActionClientObject(host, port, true) {
208 @Override
209 public void action(Version serverVersion) throws Exception {
210 Progress pg = pgF;
b9ce9cad
NR
211 if (story.getMeta().getWords() <= Integer.MAX_VALUE) {
212 pg.setMinMax(0, (int) story.getMeta().getWords());
213 }
214
416c54f8 215 send(new Object[] { md5, "SAVE_STORY", luid });
b9ce9cad
NR
216
217 List<Object> list = RemoteLibraryServer.breakStory(story);
218 for (Object obj : list) {
219 send(obj);
220 pg.add(1);
221 }
222
0fa0fe95
NR
223 send(null); // done sending the story
224 luidSaved[0] = (String) send(null); // get LUID
225
b9ce9cad
NR
226 pg.done();
227 }
228
229 @Override
230 protected void onError(Exception e) {
231 Instance.getTraceHandler().error(e);
232 }
233 }.connect();
085a2f9a
NR
234
235 // because the meta changed:
236 clearCache();
0fa0fe95
NR
237 refresh(pgRefresh);
238 story.setMeta(getInfo(luidSaved[0]));
239
240 pg.done();
085a2f9a
NR
241
242 return story;
68e2c6d2
NR
243 }
244
245 @Override
b9ce9cad
NR
246 public synchronized void delete(final String luid) throws IOException {
247 new ConnectActionClientObject(host, port, true) {
248 @Override
249 public void action(Version serverVersion) throws Exception {
416c54f8 250 send(new Object[] { md5, "DELETE_STORY", luid });
b9ce9cad
NR
251 }
252
253 @Override
254 protected void onError(Exception e) {
255 Instance.getTraceHandler().error(e);
256 }
257 }.connect();
68e2c6d2
NR
258 }
259
260 @Override
b9ce9cad
NR
261 public void setSourceCover(final String source, final String luid) {
262 try {
263 new ConnectActionClientObject(host, port, true) {
264 @Override
265 public void action(Version serverVersion) throws Exception {
416c54f8 266 send(new Object[] { md5, "SET_SOURCE_COVER", source, luid });
b9ce9cad
NR
267 }
268
269 @Override
270 protected void onError(Exception e) {
271 Instance.getTraceHandler().error(e);
272 }
273 }.connect();
274 } catch (IOException e) {
275 Instance.getTraceHandler().error(e);
276 }
68e2c6d2
NR
277 }
278
ff05b828 279 @Override
2249988a 280 public synchronized File getFile(final String luid, Progress pg) {
ff05b828
NR
281 throw new java.lang.InternalError(
282 "Operation not supportorted on remote Libraries");
283 }
284
468b960b
NR
285 /**
286 * Stop the server.
287 */
288 public void exit() {
289 try {
290 new ConnectActionClientObject(host, port, true) {
291 @Override
292 public void action(Version serverVersion) throws Exception {
293 send(new Object[] { md5, "EXIT" });
294 }
295
296 @Override
297 protected void onError(Exception e) {
298 Instance.getTraceHandler().error(e);
299 }
300 }.connect();
301 } catch (IOException e) {
302 Instance.getTraceHandler().error(e);
303 }
304 }
305
14b57448 306 @Override
b9ce9cad
NR
307 protected List<MetaData> getMetas(Progress pg) {
308 final Progress pgF = pg;
309 final List<MetaData> metas = new ArrayList<MetaData>();
74a40dfb 310
ff05b828 311 try {
62c63b07 312 new ConnectActionClientObject(host, port, true) {
ff05b828
NR
313 @Override
314 public void action(Version serverVersion) throws Exception {
b9ce9cad
NR
315 Progress pg = pgF;
316 if (pg == null) {
317 pg = new Progress();
851dd538 318 }
74a40dfb 319
416c54f8 320 Object rep = send(new Object[] { md5, "GET_METADATA", "*" });
74a40dfb 321
b9ce9cad
NR
322 while (true) {
323 if (!RemoteLibraryServer.updateProgress(pg, rep)) {
324 break;
325 }
74a40dfb 326
b9ce9cad 327 rep = send(null);
ff05b828 328 }
851dd538 329
b9ce9cad
NR
330 for (MetaData meta : (MetaData[]) rep) {
331 metas.add(meta);
332 }
851dd538
NR
333 }
334
335 @Override
336 protected void onError(Exception e) {
337 Instance.getTraceHandler().error(e);
ff05b828
NR
338 }
339 }.connect();
ff05b828 340 } catch (Exception e) {
62c63b07 341 Instance.getTraceHandler().error(e);
ff05b828 342 }
b9ce9cad
NR
343
344 return metas;
345 }
346
347 @Override
348 protected void clearCache() {
349 }
350
351 // The following methods are only used by Save and Delete in BasicLibrary:
352
353 @Override
354 protected int getNextId() {
355 throw new java.lang.InternalError("Should not have been called");
356 }
357
358 @Override
359 protected void doDelete(String luid) throws IOException {
360 throw new java.lang.InternalError("Should not have been called");
361 }
362
363 @Override
364 protected Story doSave(Story story, Progress pg) throws IOException {
365 throw new java.lang.InternalError("Should not have been called");
e604986c 366 }
b0e88ebd 367}