X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fbe%2Fnikiroo%2Ffanfix%2FLibrary.java;h=3868bd3fee03d946214db55f8594f14bf34a5887;hb=b0e88ebd20f8b2950c382694e936da76ac3596b6;hp=69b497fd84f1730feda48aae6fab96b02a76d74c;hpb=4f661b2bb0f64ed54c3e849c0c2c5b6bcfe844df;p=fanfix.git
diff --git a/src/be/nikiroo/fanfix/Library.java b/src/be/nikiroo/fanfix/Library.java
index 69b497f..3868bd3 100644
--- a/src/be/nikiroo/fanfix/Library.java
+++ b/src/be/nikiroo/fanfix/Library.java
@@ -1,5 +1,6 @@
package be.nikiroo.fanfix;
+import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
@@ -16,6 +17,7 @@ import be.nikiroo.fanfix.data.MetaData;
import be.nikiroo.fanfix.data.Story;
import be.nikiroo.fanfix.output.BasicOutput;
import be.nikiroo.fanfix.output.BasicOutput.OutputType;
+import be.nikiroo.fanfix.output.InfoCover;
import be.nikiroo.fanfix.supported.BasicSupport;
import be.nikiroo.fanfix.supported.BasicSupport.SupportType;
import be.nikiroo.fanfix.supported.InfoReader;
@@ -27,12 +29,17 @@ import be.nikiroo.utils.Progress;
*
* Each {@link Story} object will be associated with a (local to the library)
* unique ID, the LUID, which will be used to identify the {@link Story}.
+ *
+ * Most of the {@link Library} functions work on either the LUID or a partial
+ * (cover not included) {@link MetaData} object.
*
* @author niki
*/
public class Library {
- private File baseDir;
- private Map stories;
+ protected File baseDir;
+ protected boolean localSpeed;
+ protected Map stories;
+
private int lastId;
private OutputType text;
private OutputType image;
@@ -48,8 +55,10 @@ public class Library {
* the {@link OutputType} to save the images-focused stories into
*/
public Library(File dir, OutputType text, OutputType image) {
+ this();
+
this.baseDir = dir;
- this.stories = new HashMap();
+
this.lastId = 0;
this.text = text;
this.image = image;
@@ -57,6 +66,15 @@ public class Library {
dir.mkdirs();
}
+ /**
+ * Create a new {@link Library} with no link to the local machine.
+ *
+ * Reserved for extensions.
+ */
+ protected Library() {
+ this.stories = new HashMap();
+ }
+
/**
* Refresh the {@link Library}, that is, make sure all stories are loaded.
*
@@ -68,7 +86,7 @@ public class Library {
}
/**
- * List all the known types of stories.
+ * List all the known types (sources) of stories.
*
* @return the types
*/
@@ -106,6 +124,8 @@ public class Library {
/**
* List all the stories of the given author in the {@link Library}, or all
* the stories if NULL is passed as an author.
+ *
+ * Cover images not included.
*
* @param author
* the author of the stories to retrieve, or NULL for all
@@ -128,18 +148,20 @@ public class Library {
/**
* List all the stories of the given source type in the {@link Library}, or
* all the stories if NULL is passed as a type.
+ *
+ * Cover images not included.
*
* @param type
* the type of story to retrieve, or NULL for all
*
* @return the stories
*/
- public synchronized List getListByType(String type) {
+ public synchronized List getListBySource(String type) {
List list = new ArrayList();
- for (Entry entry : getStories(null).entrySet()) {
- String storyType = entry.getValue().getParentFile().getName();
+ for (MetaData meta : getStories(null).keySet()) {
+ String storyType = meta.getSource();
if (type == null || type.equalsIgnoreCase(storyType)) {
- list.add(entry.getKey());
+ list.add(meta);
}
}
@@ -148,7 +170,8 @@ public class Library {
}
/**
- * Retrieve a {@link File} corresponding to the given {@link Story}.
+ * Retrieve a {@link MetaData} corresponding to the given {@link Story},
+ * cover image MAY not be included.
*
* @param luid
* the Library UID of the story
@@ -187,6 +210,31 @@ public class Library {
return null;
}
+ /**
+ * Return the cover image associated to this story.
+ *
+ * @param luid
+ * the Library UID of the story
+ *
+ * @return the cover image
+ */
+ public synchronized BufferedImage getCover(String luid) {
+ MetaData meta = getInfo(luid);
+ if (meta != null) {
+ getFile(luid); // to help remote implementation
+ try {
+ File infoFile = new File(getExpectedFile(meta).getPath()
+ + ".info");
+ meta = readMeta(infoFile, true).getKey();
+ return meta.getCover();
+ } catch (IOException e) {
+ Instance.syserr(e);
+ }
+ }
+
+ return null;
+ }
+
/**
* Retrieve a specific {@link Story}.
*
@@ -201,23 +249,24 @@ public class Library {
if (luid != null) {
for (Entry entry : getStories(null).entrySet()) {
if (luid.equals(entry.getKey().getLuid())) {
+ MetaData meta = entry.getKey();
+ File file = getFile(luid); // to help remote implementation
try {
- SupportType type = SupportType.valueOfAllOkUC(entry
- .getKey().getType());
- URL url = entry.getValue().toURI().toURL();
+ SupportType type = SupportType.valueOfAllOkUC(meta
+ .getType());
+ URL url = file.toURI().toURL();
if (type != null) {
return BasicSupport.getSupport(type).process(url,
pg);
} else {
throw new IOException("Unknown type: "
- + entry.getKey().getType());
+ + meta.getType());
}
} catch (IOException e) {
// We should not have not-supported files in the
// library
Instance.syserr(new IOException(
- "Cannot load file from library: "
- + entry.getValue().getPath(), e));
+ "Cannot load file from library: " + file, e));
}
}
}
@@ -340,8 +389,8 @@ public class Library {
key.setLuid(luid);
}
- getDir(key).mkdirs();
- if (!getDir(key).exists()) {
+ getExpectedDir(key.getSource()).mkdirs();
+ if (!getExpectedDir(key.getSource()).exists()) {
throw new IOException("Cannot create library dir");
}
@@ -353,7 +402,7 @@ public class Library {
}
BasicOutput it = BasicOutput.getOutput(out, true);
- it.process(story, getFile(key).getPath(), pg);
+ it.process(story, getExpectedFile(key).getPath(), pg);
// empty cache
stories.clear();
@@ -372,63 +421,149 @@ public class Library {
public synchronized boolean delete(String luid) {
boolean ok = false;
+ List files = getFiles(luid);
+ if (!files.isEmpty()) {
+ for (File file : files) {
+ IOUtils.deltree(file);
+ }
+
+ ok = true;
+
+ // clear cache
+ stories.clear();
+ }
+
+ return ok;
+ }
+
+ /**
+ * Change the type (source) of the given {@link Story}.
+ *
+ * @param luid
+ * the {@link Story} LUID
+ * @param newType
+ * the new type
+ *
+ * @return TRUE if the {@link Story} was found
+ */
+ public synchronized boolean changeType(String luid, String newType) {
MetaData meta = getInfo(luid);
- File file = getStories(null).get(meta);
+ if (meta != null) {
+ meta.setSource(newType);
+ File newDir = getExpectedDir(meta.getSource());
+ if (!newDir.exists()) {
+ newDir.mkdir();
+ }
- if (file != null) {
- if (file.delete()) {
- String readerExt = getOutputType(meta)
- .getDefaultExtension(true);
- String fileExt = getOutputType(meta).getDefaultExtension(false);
-
- String path = file.getAbsolutePath();
- if (readerExt != null && !readerExt.equals(fileExt)) {
- path = path
- .substring(0, path.length() - readerExt.length())
- + fileExt;
- file = new File(path);
- IOUtils.deltree(file);
+ List files = getFiles(luid);
+ for (File file : files) {
+ if (file.getName().endsWith(".info")) {
+ try {
+ String name = file.getName().replaceFirst("\\.info$",
+ "");
+ InfoCover.writeInfo(newDir, name, meta);
+ file.delete();
+ } catch (IOException e) {
+ Instance.syserr(e);
+ }
+ } else {
+ file.renameTo(new File(newDir, file.getName()));
}
+ }
- File infoFile = new File(path + ".info");
- if (!infoFile.exists()) {
- infoFile = new File(path.substring(0, path.length()
- - fileExt.length())
- + ".info");
- }
- infoFile.delete();
-
- String coverExt = "."
- + Instance.getConfig().getString(
- Config.IMAGE_FORMAT_COVER);
- File coverFile = new File(path + coverExt);
- if (!coverFile.exists()) {
- coverFile = new File(path.substring(0, path.length()
- - fileExt.length()));
+ // clear cache
+ stories.clear();
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * The library is accessed locally or at local speed (for operations like
+ * {@link Library#getFile(String)}).
+ *
+ * It could be cached, too, it is only about the access speed.
+ *
+ * @return TRUE if it is accessed locally
+ */
+ public boolean isLocalSpeed() {
+ return localSpeed;
+ }
+
+ /**
+ * Return the list of files/dirs on disk for this {@link Story}.
+ *
+ * If the {@link Story} is not found, and empty list is returned.
+ *
+ * @param luid
+ * the {@link Story} LUID
+ *
+ * @return the list of {@link File}s
+ */
+ private List getFiles(String luid) {
+ List files = new ArrayList();
+
+ MetaData meta = getInfo(luid);
+ File file = getFile(luid); // to help remote implementation
+
+ if (file != null) {
+ files.add(file);
+
+ String readerExt = getOutputType(meta).getDefaultExtension(true);
+ String fileExt = getOutputType(meta).getDefaultExtension(false);
+
+ String path = file.getAbsolutePath();
+ if (readerExt != null && !readerExt.equals(fileExt)) {
+ path = path.substring(0, path.length() - readerExt.length())
+ + fileExt;
+ file = new File(path);
+
+ if (file.exists()) {
+ files.add(file);
}
- coverFile.delete();
+ }
- ok = true;
+ File infoFile = new File(path + ".info");
+ if (!infoFile.exists()) {
+ infoFile = new File(path.substring(0,
+ path.length() - fileExt.length())
+ + ".info");
}
- // clear cache
- stories.clear();
+ if (infoFile.exists()) {
+ files.add(infoFile);
+ }
+
+ String coverExt = "."
+ + Instance.getConfig().getString(Config.IMAGE_FORMAT_COVER);
+ File coverFile = new File(path + coverExt);
+ if (!coverFile.exists()) {
+ coverFile = new File(path.substring(0,
+ path.length() - fileExt.length())
+ + coverExt);
+ }
+
+ if (coverFile.exists()) {
+ files.add(coverFile);
+ }
}
- return ok;
+ return files;
}
/**
* The directory (full path) where the {@link Story} related to this
* {@link MetaData} should be located on disk.
*
- * @param key
- * the {@link Story} {@link MetaData}
+ * @param type
+ * the type (source)
*
* @return the target directory
*/
- private File getDir(MetaData key) {
- String source = key.getSource().replaceAll("[^a-zA-Z0-9._+-]", "_");
+ private File getExpectedDir(String type) {
+ String source = type.replaceAll("[^a-zA-Z0-9._+-]", "_");
return new File(baseDir, source);
}
@@ -441,13 +576,14 @@ public class Library {
*
* @return the target
*/
- private File getFile(MetaData key) {
+ private File getExpectedFile(MetaData key) {
String title = key.getTitle();
if (title == null) {
title = "";
}
title = title.replaceAll("[^a-zA-Z0-9._+-]", "_");
- return new File(getDir(key), key.getLuid() + "_" + title);
+ return new File(getExpectedDir(key.getSource()), key.getLuid() + "_"
+ + title);
}
/**
@@ -458,7 +594,7 @@ public class Library {
*
* @return the stories
*/
- private synchronized Map getStories(Progress pg) {
+ protected synchronized Map getStories(Progress pg) {
if (pg == null) {
pg = new Progress();
} else {
@@ -477,12 +613,12 @@ public class Library {
Progress pgDirs = new Progress(0, 100 * dirs.length);
pg.addProgress(pgDirs, 100);
- final String ext = ".info";
for (File dir : dirs) {
File[] files = dir.listFiles(new FileFilter() {
public boolean accept(File file) {
return file != null
- && file.getPath().toLowerCase().endsWith(ext);
+ && file.getPath().toLowerCase()
+ .endsWith(".info");
}
});
@@ -491,34 +627,22 @@ public class Library {
pgDirs.setName("Loading from: " + dir.getName());
for (File file : files) {
+ pgFiles.setName(file.getName());
try {
- pgFiles.setName(file.getName());
- MetaData meta = InfoReader.readMeta(file);
+ Entry entry = readMeta(file, false);
try {
- int id = Integer.parseInt(meta.getLuid());
+ int id = Integer.parseInt(entry.getKey().getLuid());
if (id > lastId) {
lastId = id;
}
- // Replace .info with whatever is needed:
- String path = file.getPath();
- path = path.substring(0,
- path.length() - ext.length());
-
- String newExt = getOutputType(meta)
- .getDefaultExtension(true);
-
- file = new File(path + newExt);
- //
-
- stories.put(meta, file);
-
+ stories.put(entry.getKey(), entry.getValue());
} catch (Exception e) {
// not normal!!
- Instance.syserr(new IOException(
+ throw new IOException(
"Cannot understand the LUID of "
+ file.getPath() + ": "
- + meta.getLuid(), e));
+ + entry.getKey().getLuid(), e);
}
} catch (IOException e) {
// We should not have not-supported files in the
@@ -526,14 +650,8 @@ public class Library {
Instance.syserr(new IOException(
"Cannot load file from library: "
+ file.getPath(), e));
- } finally {
- pgFiles.setProgress(pgFiles.getProgress() + 1);
-
- System.out.println("files: " + pgFiles.getProgress()
- + "/" + pgFiles.getMax());
- System.out.println("dirs : " + pgDirs.getProgress()
- + "/" + pgDirs.getMax());
}
+ pgFiles.add(1);
}
pgFiles.setName(null);
@@ -545,6 +663,35 @@ public class Library {
return stories;
}
+ private Entry readMeta(File infoFile, boolean withCover)
+ throws IOException {
+
+ final MetaData meta = InfoReader.readMeta(infoFile, withCover);
+
+ // Replace .info with whatever is needed:
+ String path = infoFile.getPath();
+ path = path.substring(0, path.length() - ".info".length());
+
+ String newExt = getOutputType(meta).getDefaultExtension(true);
+
+ File targetFile = new File(path + newExt);
+
+ final File ffile = targetFile;
+ return new Entry() {
+ public File setValue(File value) {
+ return null;
+ }
+
+ public File getValue() {
+ return ffile;
+ }
+
+ public MetaData getKey() {
+ return meta;
+ }
+ };
+ }
+
/**
* Return the {@link OutputType} for this {@link Story}.
*