7f775830edf8c7641eeb3303abdddf3fcdb48fbd
1 package be
.nikiroo
.fanfix
.library
;
4 import java
.io
.IOException
;
5 import java
.io
.InputStream
;
7 import java
.util
.ArrayList
;
8 import java
.util
.HashMap
;
12 import org
.json
.JSONArray
;
13 import org
.json
.JSONObject
;
15 import be
.nikiroo
.fanfix
.Instance
;
16 import be
.nikiroo
.fanfix
.data
.Chapter
;
17 import be
.nikiroo
.fanfix
.data
.JsonIO
;
18 import be
.nikiroo
.fanfix
.data
.MetaData
;
19 import be
.nikiroo
.fanfix
.data
.Paragraph
;
20 import be
.nikiroo
.fanfix
.data
.Paragraph
.ParagraphType
;
21 import be
.nikiroo
.fanfix
.data
.Story
;
22 import be
.nikiroo
.utils
.IOUtils
;
23 import be
.nikiroo
.utils
.Image
;
24 import be
.nikiroo
.utils
.Progress
;
27 * This {@link BasicLibrary} will access a remote server to list the available
28 * stories, and download the ones you try to load to the local directory
29 * specified in the configuration.
31 * This remote library uses http:// or https://.
35 public class WebLibrary
extends BasicLibrary
{
38 private final String key
;
39 private final String subkey
;
41 // informative only (server will make the actual checks)
45 * Create a {@link RemoteLibrary} linked to the given server.
47 * Note that the key is structured:
48 * <tt><b><i>xxx</i></b>(|<b><i>yyy</i></b>|<b>wl</b>)(|<b>rw</b>)</tt>
50 * Note that anything before the first pipe (<tt>|</tt>) character is
51 * considered to be the encryption key, anything after that character is
52 * called the subkey (including the other pipe characters and flags!).
54 * This is important because the subkey (including the pipe characters and
55 * flags) must be present as-is in the server configuration file to be
58 * <li><b><i>xxx</i></b>: the encryption key used to communicate with the
60 * <li><b><i>yyy</i></b>: the secondary key</li>
61 * <li><b>rw</b>: flag to allow read and write access if it is not the
62 * default on this server</li>
63 * <li><b>wl</b>: flag to allow access to all the stories (bypassing the
64 * whitelist if it exists)</li>
69 * <li><b>my_key</b>: normal connection, will take the default server
71 * <li><b>my_key|agzyzz|wl</b>: will ask to bypass the white list (if it
73 * <li><b>my_key|agzyzz|rw</b>: will ask read-write access (if the default
75 * <li><b>my_key|agzyzz|wl|rw</b>: will ask both read-write access and white
80 * the key that will allow us to exchange information with the
83 * the host to contact or NULL for localhost
85 * the port to contact it on
87 public WebLibrary(String key
, String host
, int port
) {
90 index
= key
.indexOf('|');
94 this.key
= key
.substring(0, index
);
95 this.subkey
= key
.substring(index
+ 1);
101 this.rw
= subkey
.contains("|rw");
106 // TODO: not supported yet
111 public Status
getStatus() {
114 } catch (IOException e
) {
116 download("/style.css");
117 return Status
.UNAUTHORIZED
;
118 } catch (IOException ioe
) {
119 return Status
.INVALID
;
123 return rw ? Status
.READ_WRITE
: Status
.READ_ONLY
;
127 public String
getLibraryName() {
128 return (rw ?
"[READ-ONLY] " : "") + host
+ ":" + port
;
132 public Image
getCover(String luid
) throws IOException
{
133 InputStream in
= download("/story/" + luid
+ "/cover");
135 return new Image(in
);
142 public Image
getCustomSourceCover(final String source
) throws IOException
{
143 // TODO maybe global system in BasicLib ?
148 public Image
getCustomAuthorCover(final String author
) throws IOException
{
149 // TODO maybe global system in BasicLib ?
154 public void setSourceCover(String source
, String luid
) throws IOException
{
155 // TODO Auto-generated method stub
156 throw new IOException("Not implemented yet");
160 public void setAuthorCover(String author
, String luid
) throws IOException
{
161 // TODO Auto-generated method stub
162 throw new IOException("Not implemented yet");
166 public synchronized Story
getStory(final String luid
, Progress pg
)
172 InputStream in
= download("/story/" + luid
+ "/json");
174 JSONObject json
= new JSONObject(IOUtils
.readSmallStream(in
));
175 story
= JsonIO
.toStory(json
);
180 story
.getMeta().setCover(getCover(luid
));
182 for (Chapter chap
: story
) {
184 for (Paragraph para
: chap
) {
185 if (para
.getType() == ParagraphType
.IMAGE
) {
186 InputStream subin
= download(
187 "/story/" + luid
+ "/" + chapNum
+ "/" + number
);
189 para
.setContentImage(new Image(subin
));
205 protected List
<MetaData
> getMetas(Progress pg
) throws IOException
{
206 List
<MetaData
> metas
= new ArrayList
<MetaData
>();
207 InputStream in
= download("/list/luids");
208 JSONArray jsonArr
= new JSONArray(IOUtils
.readSmallStream(in
));
209 for (int i
= 0; i
< jsonArr
.length(); i
++) {
210 JSONObject json
= jsonArr
.getJSONObject(i
);
211 metas
.add(JsonIO
.toMetaData(json
));
218 // Could work (more slowly) without it
219 public MetaData
imprt(final URL url
, Progress pg
) throws IOException
{
221 throw new IOException("Not implemented yet");
223 // Import the file locally if it is actually a file
225 if (url
== null || url
.getProtocol().equalsIgnoreCase("file")) {
226 return super.imprt(url
, pg
);
229 // Import it remotely if it is an URL
232 return super.imprt(url
, pg
);
236 // Could work (more slowly) without it
237 protected synchronized void changeSTA(final String luid
,
238 final String newSource
, final String newTitle
,
239 final String newAuthor
, Progress pg
) throws IOException
{
241 super.changeSTA(luid
, newSource
, newTitle
, newAuthor
, pg
);
245 protected void updateInfo(MetaData meta
) {
246 // Will be taken care of directly server side
250 protected void invalidateInfo(String luid
) {
251 // Will be taken care of directly server side
254 // The following methods are only used by Save and Delete in BasicLibrary:
257 protected int getNextId() {
258 throw new java
.lang
.InternalError("Should not have been called");
262 protected void doDelete(String luid
) throws IOException
{
263 throw new java
.lang
.InternalError("Should not have been called");
267 protected Story
doSave(Story story
, Progress pg
) throws IOException
{
268 throw new java
.lang
.InternalError("Should not have been called");
274 public File
getFile(final String luid
, Progress pg
) {
275 throw new java
.lang
.InternalError(
276 "Operation not supportorted on remote Libraries");
280 private InputStream
download(String path
) throws IOException
{
281 URL url
= new URL(host
+ ":" + port
+ path
);
283 Map
<String
, String
> post
= new HashMap
<String
, String
>();
284 post
.put("login", subkey
);
285 post
.put("password", key
);
287 return Instance
.getInstance().getCache().openNoCache(url
, null, post
,