+ /**
+ * Fetch the stories from the given page.
+ *
+ * @param sourceUrl
+ * the url of the document
+ * @param doc
+ * the document to use (if NULL, will be loaded from
+ * <tt>sourceUrl</tt>)
+ * @param mainSubject
+ * the main subject (the anime/book/movie item related to the
+ * stories, like "MLP" or "Doctor Who"), or NULL if none
+ *
+ * @return the stories found in it
+ *
+ * @throws IOException
+ * in case of I/O errors
+ */
+ private List<MetaData> getStories(String sourceUrl, Document doc,
+ String mainSubject) throws IOException {
+ List<MetaData> metas = new ArrayList<MetaData>();
+
+ if (doc == null) {
+ doc = load(sourceUrl, false);
+ }
+
+ for (Element story : doc.getElementsByClass("z-list")) {
+ MetaData meta = new MetaData();
+ meta.setImageDocument(false);
+ meta.setSource(getType().getSourceName());
+ meta.setPublisher(getType().getSourceName());
+ meta.setType(getType().toString());
+
+ // Title, URL, Cover
+ Element stitle = story.getElementsByClass("stitle").first();
+ if (stitle != null) {
+ meta.setTitle(stitle.text());
+ meta.setUrl(stitle.absUrl("href"));
+ meta.setUuid(meta.getUrl());
+ Element cover = stitle.getElementsByTag("img").first();
+ if (cover != null) {
+ // note: see data-original if needed?
+ String coverUrl = cover.absUrl("src");
+
+ try {
+ InputStream in = Instance.getInstance().getCache().open(new URL(coverUrl), getSupport(), true);
+ try {
+ meta.setCover(new Image(in));
+ } finally {
+ in.close();
+ }
+ } catch (Exception e) {
+ // Should not happen on Fanfiction.net
+ Instance.getInstance().getTraceHandler().error(new Exception(
+ "Cannot download cover for Fanfiction story in search mode: " + meta.getTitle(), e));
+ }
+ }
+ }
+
+ // Author
+ Elements as = story.getElementsByTag("a");
+ if (as.size() > 1) {
+ meta.setAuthor(as.get(1).text());
+ }
+
+ // Tags (concatenated text), published date, updated date, Resume
+ String tags = "";
+ List<String> tagList = new ArrayList<String>();
+ Elements divs = story.getElementsByTag("div");
+ if (divs.size() > 1 && divs.get(1).childNodeSize() > 0) {
+ String resume = divs.get(1).text();
+ if (divs.size() > 2) {
+ tags = divs.get(2).text();
+ resume = resume.substring(0,
+ resume.length() - tags.length()).trim();
+
+ for (Element d : divs.get(2).getElementsByAttribute(
+ "data-xutime")) {
+ String secs = d.attr("data-xutime");
+ try {
+ String date = new SimpleDateFormat("yyyy-MM-dd")
+ .format(new Date(
+ Long.parseLong(secs) * 1000));
+ // (updated, ) published
+ if (meta.getDate() != null) {
+ tagList.add("Updated: " + meta.getDate());
+ }
+ meta.setDate(date);
+ } catch (Exception e) {
+ }
+ }
+ }