package be.nikiroo.fanfix.supported; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map.Entry; import java.util.Scanner; import be.nikiroo.fanfix.Instance; import be.nikiroo.fanfix.bundles.Config; import be.nikiroo.fanfix.data.MetaData; import be.nikiroo.utils.Progress; import be.nikiroo.utils.StringUtils; /** * Support class for Faniction.net * stories, a website dedicated to fanfictions of many, many different * universes, from TV shows to novels to games. * * @author niki */ class Fanfiction extends BasicSupport { @Override protected boolean isHtml() { return true; } @Override public String getSourceName() { return "Fanfiction.net"; } @Override protected MetaData getMeta(URL source, InputStream in) throws IOException { MetaData meta = new MetaData(); meta.setTitle(getTitle(reset(in))); meta.setAuthor(getAuthor(reset(in))); meta.setDate(getDate(reset(in))); meta.setTags(getTags(reset(in))); meta.setSource(getSourceName()); meta.setUrl(source.toString()); meta.setPublisher(getSourceName()); meta.setUuid(source.toString()); meta.setLuid(""); meta.setLang("EN"); meta.setSubject(getSubject(reset(in))); meta.setType(getType().toString()); meta.setImageDocument(false); meta.setCover(getCover(source, reset(in))); return meta; } private String getSubject(InputStream in) { String line = getLine(in, "id=pre_story_links", 0); if (line != null) { int pos = line.lastIndexOf('"'); if (pos >= 1) { line = line.substring(pos + 1); pos = line.indexOf('<'); if (pos >= 0) { return StringUtils.unhtml(line.substring(0, pos)).trim(); } } } return null; } private List getTags(InputStream in) throws IOException { List tags = new ArrayList(); String key = "title=\"Send Private Message\""; String line = getLine(in, key, 2); if (line != null) { key = "Rated:"; int pos = line.indexOf(key); if (pos >= 0) { line = line.substring(pos + key.length()); key = "Chapters:"; pos = line.indexOf(key); if (pos >= 0) { line = line.substring(0, pos); line = StringUtils.unhtml(line).trim(); if (line.endsWith("-")) { line = line.substring(0, line.length() - 1); } for (String tag : line.split("-")) { tags.add(StringUtils.unhtml(tag).trim()); } } } } return tags; } private String getTitle(InputStream in) { int i = 0; @SuppressWarnings("resource") Scanner scan = new Scanner(in, "UTF-8"); scan.useDelimiter("\\n"); while (scan.hasNext()) { String line = scan.next(); if (line.contains("xcontrast_txt")) { if ((++i) == 2) { line = StringUtils.unhtml(line).trim(); if (line.startsWith("Follow/Fav")) { line = line.substring("Follow/Fav".length()).trim(); } return StringUtils.unhtml(line).trim(); } } } return null; } private String getAuthor(InputStream in) { String author = null; int i = 0; @SuppressWarnings("resource") Scanner scan = new Scanner(in, "UTF-8"); scan.useDelimiter("\\n"); while (scan.hasNext()) { String line = scan.next(); if (line.contains("xcontrast_txt")) { if ((++i) == 3) { author = StringUtils.unhtml(line).trim(); break; } } } return fixAuthor(author); } private String getDate(InputStream in) { String key = "Published: = 0) { line = line.substring(0, pos).trim(); try { SimpleDateFormat sdf = new SimpleDateFormat( "YYYY-MM-dd"); return sdf .format(new Date(1000 * Long.parseLong(line))); } catch (NumberFormatException e) { Instance.syserr(new IOException( "Cannot convert publication date: " + line, e)); } } } } return null; } @Override protected String getDesc(URL source, InputStream in) { return getLine(in, "title=\"Send Private Message\"", 1); } private BufferedImage getCover(URL url, InputStream in) { String key = "class='cimage"; String line = getLine(in, key, 0); if (line != null) { int pos = line.indexOf(key); if (pos >= 0) { line = line.substring(pos + key.length()); key = "src='"; pos = line.indexOf(key); if (pos >= 0) { line = line.substring(pos + key.length()); pos = line.indexOf('\''); if (pos >= 0) { line = line.substring(0, pos); if (line.startsWith("//")) { line = url.getProtocol() + "://" + line.substring(2); } else if (line.startsWith("//")) { line = url.getProtocol() + "://" + url.getHost() + "/" + line.substring(1); } else { line = url.getProtocol() + "://" + url.getHost() + "/" + url.getPath() + "/" + line; } return getImage(this, null, line); } } } } return null; } @Override protected List> getChapters(URL source, InputStream in, Progress pg) { List> urls = new ArrayList>(); String base = source.toString(); int pos = base.lastIndexOf('/'); String suffix = base.substring(pos); // including '/' at start base = base.substring(0, pos); if (base.endsWith("/1")) { base = base.substring(0, base.length() - 1); // including '/' at end } String line = getLine(in, "id=chap_select", 0); String key = "