BasicSearchable
authorNiki Roo <niki@nikiroo.be>
Tue, 9 Apr 2019 21:26:44 +0000 (23:26 +0200)
committerNiki Roo <niki@nikiroo.be>
Tue, 9 Apr 2019 21:26:44 +0000 (23:26 +0200)
src/be/nikiroo/fanfix/searchable/BasicSearchable.java [new file with mode: 0644]
src/be/nikiroo/fanfix/searchable/SearchableTag.java [new file with mode: 0644]

diff --git a/src/be/nikiroo/fanfix/searchable/BasicSearchable.java b/src/be/nikiroo/fanfix/searchable/BasicSearchable.java
new file mode 100644 (file)
index 0000000..25c388a
--- /dev/null
@@ -0,0 +1,199 @@
+package be.nikiroo.fanfix.searchable;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.List;
+
+import org.jsoup.helper.DataUtil;
+import org.jsoup.nodes.Document;
+
+import be.nikiroo.fanfix.Instance;
+import be.nikiroo.fanfix.data.MetaData;
+import be.nikiroo.fanfix.supported.BasicSupport;
+import be.nikiroo.fanfix.supported.SupportType;
+
+/**
+ * This class supports browsing through stories on the supported websites. It
+ * will fetch some {@link MetaData} that satisfy a search query or some tags if
+ * supported.
+ * 
+ * @author niki
+ */
+public abstract class BasicSearchable {
+       private SupportType type;
+       private BasicSupport support;
+
+       /**
+        * Create a new {@link BasicSearchable} of the given type.
+        * 
+        * @param type
+        *            the type, must not be NULL
+        */
+       public BasicSearchable(SupportType type) {
+               setType(type);
+               support = BasicSupport.getSupport(getType(), null);
+       }
+
+       /**
+        * The support type.
+        * 
+        * @return the type
+        */
+       public SupportType getType() {
+               return type;
+       }
+
+       /**
+        * The support type.
+        * 
+        * @param type
+        *            the new type
+        */
+       protected void setType(SupportType type) {
+               this.type = type;
+       }
+
+       /**
+        * The associated {@link BasicSupport}.
+        * <p>
+        * Mostly used to download content.
+        * 
+        * @return the support
+        */
+       protected BasicSupport getSupport() {
+               return support;
+       }
+
+       /**
+        * Get a list of tags that can be browsed here.
+        * 
+        * @return the list of tags
+        * 
+        * @throws IOException
+        *             in case of I/O error
+        */
+       abstract public List<SearchableTag> getTags() throws IOException;
+
+       /**
+        * Fill the tag (set it 'complete') with more information from the support.
+        * 
+        * @param tag
+        *            the tag to fill
+        * 
+        * @throws IOException
+        *             in case of I/O error
+        */
+       abstract protected void fillTag(SearchableTag tag) throws IOException;
+
+       /**
+        * Search for the given term and return a list of stories satisfying this
+        * search term.
+        * <p>
+        * Not that the returned stories will <b>NOT</b> be complete, but will only
+        * contain enough information to present them to the user and retrieve them.
+        * <p>
+        * URL is guaranteed to be usable, LUID will always be NULL.
+        * 
+        * @param search
+        *            the term to search for
+        * 
+        * @return a list of stories that satisfy that search term
+        * 
+        * @throws IOException
+        *             in case of I/O error
+        */
+       abstract public List<MetaData> search(String search) throws IOException;
+
+       /**
+        * Search for the given tag and return a list of stories satisfying this
+        * tag.
+        * <p>
+        * Not that the returned stories will <b>NOT</b> be complete, but will only
+        * contain enough information to present them to the user and retrieve them.
+        * <p>
+        * URL is guaranteed to be usable, LUID will always be NULL.
+        * 
+        * @param tagId
+        *            the tag to search for
+        * 
+        * @return a list of stories that satisfy that search term
+        * 
+        * @throws IOException
+        *             in case of I/O error
+        */
+       abstract public List<MetaData> search(SearchableTag tag) throws IOException;
+
+       /**
+        * Load a document from its url.
+        * 
+        * @param url
+        *            the URL to load
+        * @return the document
+        * 
+        * @throws IOException
+        *             in case of I/O error
+        */
+       protected Document load(String url) throws IOException {
+               return load(new URL(url));
+       }
+
+       /**
+        * Load a document from its url.
+        * 
+        * @param url
+        *            the URL to load
+        * @return the document
+        * 
+        * @throws IOException
+        *             in case of I/O error
+        */
+       protected Document load(URL url) throws IOException {
+               return DataUtil.load(Instance.getCache().open(url, support, false),
+                               "UTF-8", url.toString());
+       }
+
+       /**
+        * Return a {@link BasicSearchable} implementation supporting the given
+        * type, or NULL if it does not exist.
+        * 
+        * @param type
+        *            the type, must not be NULL
+        * 
+        * @return an implementation that supports it, or NULL
+        */
+       public static BasicSearchable getSearchable(SupportType type) {
+               BasicSearchable support = null;
+
+               switch (type) {
+               case FIMFICTION:
+                       // TODO
+                       break;
+               case FANFICTION:
+                       support = new Fanfiction(type);
+                       break;
+               case MANGAFOX:
+                       // TODO
+                       break;
+               case E621:
+                       // TODO
+                       break;
+               case YIFFSTAR:
+                       // TODO
+                       break;
+               case E_HENTAI:
+                       // TODO
+                       break;
+               case MANGA_LEL:
+                       // TODO
+                       break;
+               case CBZ:
+               case HTML:
+               case INFO_TEXT:
+               case TEXT:
+               case EPUB:
+                       break;
+               }
+
+               return support;
+       }
+}
diff --git a/src/be/nikiroo/fanfix/searchable/SearchableTag.java b/src/be/nikiroo/fanfix/searchable/SearchableTag.java
new file mode 100644 (file)
index 0000000..c877bd7
--- /dev/null
@@ -0,0 +1,178 @@
+package be.nikiroo.fanfix.searchable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class represents a tag that can be searched on a supported website.
+ * 
+ * @author niki
+ */
+public class SearchableTag {
+       private String id;
+       private String name;
+       private boolean complete;
+       private long count;
+       private List<SearchableTag> children;
+
+       /**
+        * Create a new {@link SearchableTag}.
+        * 
+        * @param id
+        *            the ID (usually a way to find the linked stories later on)
+        * @param name
+        *            the tag name, which can be displayed to the user
+        * @param complete
+        *            TRUE for a {@link SearchableTag} that cannot be "filled" by
+        *            the {@link BasicSearchable} in order to get (more?) subtag
+        *            children
+        */
+       public SearchableTag(String id, String name, boolean complete) {
+               this.id = id;
+               this.name = name;
+               this.complete = complete;
+
+               children = new ArrayList<SearchableTag>();
+       }
+
+       public String getId() {
+               return id;
+       }
+
+       public String getName() {
+               return name;
+       }
+
+       /**
+        * This tag can still be completed via a "fill" tag operation from a
+        * {@link BasicSearchable}, in order to gain (more?) subtag children.
+        * 
+        * @return TRUE if it can
+        */
+       public boolean isComplete() {
+               return complete;
+       }
+
+       /**
+        * This tag can still be completed via a "fill" tag operation from a
+        * {@link BasicSearchable}, in order to gain (more?) subtag children.
+        * 
+        * @param complete
+        *            TRUE if it can
+        */
+       public void setComplete(boolean complete) {
+               this.complete = complete;
+       }
+
+       /**
+        * The number of items that can be found with this tag if it is searched.
+        * <p>
+        * Will report the number of subtags by default.
+        * 
+        * @return the number of items
+        */
+       public long getCount() {
+               long count = this.count;
+               if (count <= 0) {
+                       count = children.size();
+               }
+
+               return count;
+       }
+
+       /**
+        * The number of items that can be found with this tag if it is searched,
+        * displayable format.
+        * <p>
+        * Will report the number of subtags by default.
+        * 
+        * @return the number of items
+        */
+       public String getCountDisplay() {
+               long count = this.count;
+               if (count <= 0) {
+                       count = children.size();
+               }
+
+               if (count > 999999) {
+                       return count / 1000000 + "M";
+               }
+
+               if (count > 2000) {
+                       return count / 1000 + "k";
+               }
+
+               return Long.toString(count);
+       }
+
+       /**
+        * The number of items that can be found with this tag if it is searched.
+        * 
+        * @param count
+        *            the new count
+        */
+       public void setCount(long count) {
+               this.count = count;
+       }
+
+       /**
+        * The subtag children of this {@link SearchableTag}.
+        * <p>
+        * Never NULL.
+        * <p>
+        * Note that if {@link SearchableTag#isComplete()} returns false, you can
+        * still fill (more?) subtag children with a {@link BasicSearchable}.
+        * 
+        * @return the subtag children, never NULL
+        */
+       public List<SearchableTag> getChildren() {
+               return children;
+       }
+
+       /**
+        * Add the given {@link SearchableTag} as a subtag child.
+        * 
+        * @param tag
+        *            the tag to add
+        */
+       public void add(SearchableTag tag) {
+               children.add(tag);
+       }
+
+       /**
+        * Display a DEBUG {@link String} representation of this object.
+        */
+       @Override
+       public String toString() {
+               String rep = name + " [" + id + "]";
+               if (!complete) {
+                       rep += "*";
+               }
+
+               if (getCount() > 0) {
+                       rep += " (" + getCountDisplay() + ")";
+               }
+
+               if (!children.isEmpty()) {
+                       String tags = "";
+                       int i = 1;
+                       for (SearchableTag tag : children) {
+                               if (!tags.isEmpty()) {
+                                       tags += ", ";
+                               }
+
+                               if (i > 10) {
+                                       tags += "...";
+                                       break;
+                               }
+
+                               tags += tag;
+                               i++;
+                       }
+
+                       rep += ": " + tags;
+               }
+
+               return rep;
+       }
+}