package org.lodder.subtools.multisubdownloader.subtitleproviders.addic7ed;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.TextNode;
import org.jsoup.select.Elements;
import org.lodder.subtools.multisubdownloader.subtitleproviders.addic7ed.model.Addic7edSubtitleDescriptor;
import org.lodder.subtools.sublibrary.Manager;
import org.lodder.subtools.sublibrary.ManagerException;
import org.lodder.subtools.sublibrary.ManagerSetupException;
import org.lodder.subtools.sublibrary.data.Html;
import org.lodder.subtools.sublibrary.util.http.HttpClientException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class JAddic7edApi extends Html {
private final Pattern pattern;
private final static long RATEDURATION = MILLISECONDS.convert(15, TimeUnit.SECONDS);
private boolean speedy;
private Date lastRequest = new Date();
private static final Logger LOGGER = LoggerFactory.getLogger(JAddic7edApi.class);
public JAddic7edApi(boolean speedy, Manager manager) {
super(manager, "Mozilla/5.25 Netscape/5.0 (Windows; I; Win95)");
pattern = Pattern.compile("Version (.+), ([0-9]+).([0-9])+ MBs");
this.speedy = speedy;
}
public JAddic7edApi(String username, String password, boolean speedy, Manager manager)
throws ManagerException {
super(manager, "Mozilla/5.25 Netscape/5.0 (Windows; I; Win95)");
pattern = Pattern.compile("Version (.+), ([0-9]+).([0-9])+ MBs");
login(username, password);
this.speedy = speedy;
}
public void login(String username, String password) throws ManagerException {
Map<String, String> data = new HashMap<String, String>();
data.put("username", username);
data.put("password", password);
data.put("remember", "false");
this.postHtml("http://www.addic7ed.com/dologin.php", data);
}
public String searchSerieName(String name) throws Exception {
String content = searchName(name);
Document doc = Jsoup.parse(content);
Elements aTagWithSerie = doc.select("a[debug]");
for (Element serieFound : aTagWithSerie) {
String text =
serieFound.text().split(" - ")[0].replaceAll("[^A-Za-z]", "").trim().toLowerCase();
name = name.replaceAll("[^A-Za-z]", "").trim().toLowerCase();
if (text.contains(name)) {
String link = serieFound.attr("href");
String seriename = link.replace("serie/", "");
seriename = seriename.substring(0, seriename.indexOf("/"));
return seriename;
}
}
return "";
}
public String searchMovieName(String name) throws Exception {
String content = searchName(name);
Document doc = Jsoup.parse(content);
Elements aTagWithSerie = doc.select("a[debug]");
String link = aTagWithSerie.get(0).attr("href");
String moviename = link.replace("movie/", "");
moviename = moviename.substring(0, moviename.indexOf("/"));
return moviename;
}
private String searchName(String name) throws Exception {
String url =
"http://www.addic7ed.com/search.php?search=" + URLEncoder.encode(name, "UTF-8")
+ "&Submit=Search";
String content = this.getContent(true, url);
if (content.contains("<b>0 results found</b>")) {
if (name.contains(":")) {
name = name.replace(":", "");
return searchName(name);
} else {
throw new Exception("Can't find it on addic7ed, please contact developer!");
}
}
return content;
}
public List<Addic7edSubtitleDescriptor> searchSubtitles(String showname, int season, int episode,
String title) throws Exception {
// http://www.addic7ed.com/serie/Smallville/9/11/Absolute_Justice
String url =
"http://www.addic7ed.com/serie/" + showname.toLowerCase().replace(" ", "_") + "/" + season
+ "/" + episode + "/" + title.toLowerCase().replace(" ", "_").replace("#", "");
String content = this.getContent(false, url);
List<Addic7edSubtitleDescriptor> lSubtitles = new ArrayList<Addic7edSubtitleDescriptor>();
Document doc = Jsoup.parse(content);
String titel = null;
Elements elTitel = doc.getElementsByClass("titulo");
if (elTitel.size() == 1) {
titel = elTitel.get(0).html().substring(0, elTitel.get(0).html().indexOf("<") - 1).trim();
}
String uploader, version, lang, download = null;
boolean hearingImpaired = false;
Elements blocks = doc.getElementsByClass("tabel95");
blocks = blocks.select("table[width=100%]");
for (Element block : blocks) {
uploader = "";
version = null;
lang = null;
download = null;
hearingImpaired = false;
Elements classesNewsTitle = block.getElementsByClass("NewsTitle");
Elements classesNewsDate = block.getElementsByClass("newsDate").select("td[colspan=3]");
Elements imgHearingImpaired = block.select("img").select("img[title~=Hearing]");
if (classesNewsTitle.size() == 1 && classesNewsDate.size() == 1) {
TextNode tn = (TextNode) classesNewsTitle.get(0).childNode(1);
Matcher m = pattern.matcher(tn.text());
if (!m.find()) {
break;
} else {
version =
m.group().substring(0, m.group().lastIndexOf(",")).replace("Version", "") + (" ")
+ classesNewsDate.get(0).text().trim();
uploader = block.getElementsByTag("a").select("a[href*=user/]").get(0).text();
hearingImpaired = imgHearingImpaired.size() > 0;
}
}
if (version != null) {
Elements tds = block.select("tr:contains(Completed)");
Elements reqTds = tds.select("td").not("td[rowspan=2]");
for (Element td : reqTds) {
if (td.hasClass("language")) {
lang = td.html().substring(0, td.html().indexOf("<"));
}
if (lang != null && td.toString().toLowerCase().contains("completed")) {
// incompleted not wanted
if (td.html().toLowerCase().contains("% completed")) lang = null;
}
if (lang != null && td.getElementsByClass("buttonDownload").size() > 0) {
Elements a = td.getElementsByClass("buttonDownload");
if (a.size() == 1) {
download = "http://www.addic7ed.com" + a.get(0).attr("href");
}
if (a.size() == 2) {
download = "http://www.addic7ed.com" + a.get(1).attr("href");
}
}
if (lang != null && download != null && titel != null) {
Addic7edSubtitleDescriptor sub = new Addic7edSubtitleDescriptor();
sub.setUploader(uploader);
sub.setTitel(titel.trim());
sub.setVersion(version.trim());
sub.setUrl(download);
sub.setLanguage(lang.trim());
sub.setHearingImpaired(hearingImpaired);
if (!isDuplicate(lSubtitles, sub)) {
lSubtitles.add(sub);
}
lang = null;
download = null;
}
}
}
}
return lSubtitles;
}
public boolean isDuplicate(List<Addic7edSubtitleDescriptor> lSubtitles,
Addic7edSubtitleDescriptor sub) {
for (Addic7edSubtitleDescriptor s : lSubtitles) {
if (s.getLanguage().equals(sub.getLanguage()) && s.getUrl().equals(sub.getUrl())
&& s.getVersion().equals(sub.getVersion())) return true;
}
return false;
}
private String getContent(boolean disk, String url) {
String content = "";
try {
if (disk) {
content = this.getHtmlDisk(url);
} else {
if (!speedy && !this.isCached(url)) {
long dur = new Date().getTime() - lastRequest.getTime();
if (dur < RATEDURATION) {
LOGGER.info("RateLimiet is bereikt voor ADDIC7ed, gelieve 15 sec te wachten");
}
while ((new Date().getTime() - lastRequest.getTime()) < RATEDURATION) {
try {
// Pause for 1 seconds
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // restore
// interrupted
// status
}
}
lastRequest = new Date();
}
content = this.getHtml(url);
}
} catch (HttpClientException hce) {
LOGGER.error(hce.getMessage(), hce);
} catch (IOException e) {
LOGGER.error(e.getMessage(), e);
} catch (ManagerSetupException e) {
LOGGER.error(e.getMessage(), e);
} catch (ManagerException e) {
LOGGER.error(e.getMessage(), e);
}
return content;
}
}