diff --git a/lib/sublight-ws.jar b/lib/sublight-ws.jar deleted file mode 100644 index e650597d..00000000 Binary files a/lib/sublight-ws.jar and /dev/null differ diff --git a/source/net/sourceforge/filebot/Settings.properties b/source/net/sourceforge/filebot/Settings.properties index 948fc55a..e92d5de4 100644 --- a/source/net/sourceforge/filebot/Settings.properties +++ b/source/net/sourceforge/filebot/Settings.properties @@ -20,6 +20,4 @@ themoviedb.apikey: 5a6edae568130bf10617b6d45be99f13 serienjunkies.apikey: 9fbhw9uebfiwvbefzuwv fanart.tv.apikey: 780b986b22c35e6f7a134a2f392c2deb acoustid.apikey: 0B3qZnQc -pushover.apikey: wcckDz3oygHSU2SdIptvnHxJ92SQKK -sublight.clientid: FileBot2 -sublight.apikey: 79f7a868-c28c-446f-a58e-3637ca24c87a +pushover.apikey: wcckDz3oygHSU2SdIptvnHxJ92SQKK \ No newline at end of file diff --git a/source/net/sourceforge/filebot/WebServices.java b/source/net/sourceforge/filebot/WebServices.java index 3b6f5319..65cb8039 100644 --- a/source/net/sourceforge/filebot/WebServices.java +++ b/source/net/sourceforge/filebot/WebServices.java @@ -61,7 +61,6 @@ public final class WebServices { // subtitle dbs public static final OpenSubtitlesClient OpenSubtitles = new OpenSubtitlesClient(String.format("%s %s", getApplicationName(), getApplicationVersion())); - //TODO remove Subscene/Sublight from codebase // misc public static final FanartTV FanartTV = new FanartTV(Settings.getApplicationProperty("fanart.tv.apikey")); diff --git a/source/net/sourceforge/filebot/web/SublightSubtitleClient.java b/source/net/sourceforge/filebot/web/SublightSubtitleClient.java deleted file mode 100644 index b8fcb143..00000000 --- a/source/net/sourceforge/filebot/web/SublightSubtitleClient.java +++ /dev/null @@ -1,449 +0,0 @@ - -package net.sourceforge.filebot.web; - - -import static java.lang.Math.*; -import static java.util.Collections.*; - -import java.io.File; -import java.io.IOException; -import java.math.BigInteger; -import java.net.URI; -import java.security.MessageDigest; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import java.util.logging.Level; -import java.util.logging.Logger; - -import javax.swing.Icon; -import javax.xml.ws.Holder; -import javax.xml.ws.WebServiceException; - -import net.sourceforge.filebot.ResourceManager; -import net.sourceforge.tuned.Timer; -import net.sublight.webservice.ArrayOfGenre; -import net.sublight.webservice.ArrayOfIMDB; -import net.sublight.webservice.ArrayOfRelease; -import net.sublight.webservice.ArrayOfString; -import net.sublight.webservice.ArrayOfSubtitle; -import net.sublight.webservice.ArrayOfSubtitleLanguage; -import net.sublight.webservice.ClientInfo; -import net.sublight.webservice.Genre; -import net.sublight.webservice.IMDB; -import net.sublight.webservice.Release; -import net.sublight.webservice.Sublight; -import net.sublight.webservice.SublightSoap; -import net.sublight.webservice.Subtitle; -import net.sublight.webservice.SubtitleLanguage; - - -public class SublightSubtitleClient implements SubtitleProvider, VideoHashSubtitleService { - - private static final String iid = "25f30171-518c-463b-a310-b9f8e1eddb40"; - - private final ClientInfo clientInfo = new ClientInfo(); - - private String username; - private String passwordHash; - - private SublightSoap webservice; - private String session; - - - @Override - public String getName() { - return "Sublight"; - } - - - @Override - public URI getLink() { - return URI.create("http://www.sublight.si"); - } - - - @Override - public Icon getIcon() { - return ResourceManager.getIcon("search.sublight"); - } - - - @Override - public List search(String query) throws WebServiceException { - // require login - login(); - - Holder response = new Holder(); - Holder error = new Holder(); - - webservice.findIMDB(query, null, null, response, error); - - // abort if something went wrong - checkError(error); - - List results = new ArrayList(); - - if (response.value != null) { - for (IMDB imdb : response.value.getIMDB()) { - // remove classifier (e.g. tt0436992 -> 0436992) - int id = Integer.parseInt(imdb.getId().substring(2)); - - results.add(new Movie(imdb.getTitle(), imdb.getYear(), id, -1)); - } - } - - return results; - } - - - @Override - public List getSubtitleList(SearchResult searchResult, String languageName) throws WebServiceException { - Movie movie = (Movie) searchResult; - - List subtitles = new ArrayList(); - - // retrieve subtitles by name and year - for (Subtitle subtitle : getSubtitleList(null, movie.getName(), movie.getYear(), languageName)) { - subtitles.add(new SublightSubtitleDescriptor(subtitle, this)); - } - - return subtitles; - } - - - @Override - public Map> getSubtitleList(File[] files, final String languageName) throws Exception { - Map> subtitles = new HashMap>(files.length); - - ExecutorService executor = Executors.newFixedThreadPool(min(files.length, 10)); - List>> requests = new ArrayList>>(); - - try { - // queue and execute requests - for (int i = 0; i < files.length; i++) { - Future> request = null; - - try { - // make call interruptible - if (Thread.interrupted()) - throw new InterruptedException(); - - // compute video hash and execute query in parallel - final String videoHash = SublightVideoHasher.computeHash(files[i]); - - request = executor.submit(new Callable>() { - - @Override - public List call() throws Exception { - return getSubtitleList(videoHash, languageName); - } - }); - } catch (IOException e) { - Logger.getLogger(SublightSubtitleClient.class.getName()).log(Level.WARNING, "Error computing video hash: " + e.getMessage()); - } - - requests.add(i, request); - } - - // collect results - for (int i = 0; i < files.length; i++) { - List response = emptyList(); - - if (requests.get(i) != null) { - response = requests.get(i).get(); - } - - subtitles.put(files[i], response); - } - - return subtitles; - } finally { - // shutdown after all tasks are done or an exception was thrown - executor.shutdownNow(); - } - } - - - public List getSubtitleList(String videoHash, String languageName) throws WebServiceException { - List subtitles = new ArrayList(); - - // retrieve subtitles by video hash - for (Subtitle subtitle : getSubtitleList(videoHash, null, null, languageName)) { - // only keep linked subtitles - if (subtitle.isIsLinked()) { - subtitles.add(new SublightSubtitleDescriptor(subtitle, this)); - } - } - - return subtitles; - } - - - public List getSubtitleList(String videoHash, String name, Integer year, String languageName) throws WebServiceException { - // require login - login(); - - // given language or all languages - ArrayOfSubtitleLanguage languages = new ArrayOfSubtitleLanguage(); - - if (languageName != null) { - // given language - languages.getSubtitleLanguage().add(getSubtitleLanguage(languageName)); - } else { - // all languages - Collections.addAll(languages.getSubtitleLanguage(), SubtitleLanguage.values()); - } - - // hash singleton array - ArrayOfString videoHashes = new ArrayOfString(); - videoHashes.getString().add(videoHash); - - // all genres - ArrayOfGenre genres = new ArrayOfGenre(); - Collections.addAll(genres.getGenre(), Genre.values()); - - // response holders - Holder subtitles = new Holder(); - Holder releases = new Holder(); - Holder error = new Holder(); - - webservice.searchSubtitles4(session, videoHashes, name, year, null, null, languages, genres, null, null, null, subtitles, releases, null, error); - - // abort if something went wrong - checkError(error); - - // return empty list if response is empty - if (subtitles.value == null) { - return Collections.emptyList(); - } - - // map all release names by subtitle id - if (releases.value != null) { - Map releaseNameBySubtitleID = new HashMap(); - - // map release names by subtitle id - for (Release release : releases.value.getRelease()) { - releaseNameBySubtitleID.put(release.getSubtitleID(), release.getName()); - } - - // set release names - for (Subtitle subtitle : subtitles.value.getSubtitle()) { - subtitle.setRelease(releaseNameBySubtitleID.get(subtitle.getSubtitleID())); - } - } - - return subtitles.value.getSubtitle(); - } - - - @Override - public boolean publishSubtitle(int imdbid, String languageName, File[] videoFile, File[] subtitleFile) throws Exception { - //TODO implement upload feature - return false; - } - - - public void publishSubtitle(int imdbid, String videoHash, String languageName, String releaseName, byte[] data) { - // require login - login(); - - Subtitle subtitle = new Subtitle(); - subtitle.setIMDB(String.format("http://www.imdb.com/title/tt%07d", imdbid)); - subtitle.setLanguage(getSubtitleLanguage(languageName)); - subtitle.setRelease(releaseName); - - Holder result = new Holder(); - Holder subid = new Holder(); - Holder error = new Holder(); - - // upload subtitle - webservice.publishSubtitle2(session, subtitle, data, result, subid, null, error); - - // abort if something went wrong - checkError(error); - - // link subtitle to video file - webservice.addHashLink3(session, subid.value, videoHash, null, null, error); - - // abort if something went wrong - checkError(error); - } - - - protected Map getLanguageAliasMap() { - Map languages = new HashMap(4); - - // insert special some additional special handling - languages.put("Brazilian", SubtitleLanguage.PORTUGUESE_BRAZIL); - languages.put("Bosnian", SubtitleLanguage.BOSNIAN_LATIN); - languages.put("Serbian", SubtitleLanguage.SERBIAN_LATIN); - - return languages; - } - - - protected SubtitleLanguage getSubtitleLanguage(String languageName) { - // check subtitle language enum - for (SubtitleLanguage language : SubtitleLanguage.values()) { - if (language.value().equalsIgnoreCase(languageName)) - return language; - } - - // check alias list - for (Entry alias : getLanguageAliasMap().entrySet()) { - if (alias.getKey().equalsIgnoreCase(languageName)) - return alias.getValue(); - } - - // illegal language name - throw new IllegalArgumentException("Illegal language: " + languageName); - } - - - protected String getLanguageName(SubtitleLanguage language) { - // check alias list first - for (Entry alias : getLanguageAliasMap().entrySet()) { - if (language == alias.getValue()) - return alias.getKey(); - } - - // use language value by default - return language.value(); - } - - - protected synchronized byte[] getZipArchive(Subtitle subtitle) throws WebServiceException, InterruptedException { - // require login - login(); - - Holder ticket = new Holder(); - Holder que = new Holder(); - Holder data = new Holder(); - Holder error = new Holder(); - - webservice.getDownloadTicket2(session, null, subtitle.getSubtitleID(), null, ticket, que, null, error); - - // abort if something went wrong - checkError(error); - - // wait x seconds as specified by the download ticket response, download ticket is not valid until then - Thread.sleep(que.value * 1000); - - webservice.downloadByID4(session, subtitle.getSubtitleID(), -1, false, ticket.value, null, data, null, error); - - // abort if something went wrong - checkError(error); - - // return zip file bytes - return data.value; - } - - - @Override - public URI getSubtitleListLink(SearchResult searchResult, String languageName) { - // note that sublight can only be accessed via the soap API - return URI.create("http://www.sublight.si/SearchSubtitles.aspx"); - } - - - public synchronized void setClient(String id, String key) { - clientInfo.setClientId(id); - clientInfo.setApiKey(key); - } - - - public synchronized void setUser(String username, String password) { - this.username = username; - this.passwordHash = password != null && password.length() > 0 ? getPasswordHash(password) : null; - } - - - public String getPasswordHash(String password) { - try { - MessageDigest digest = MessageDigest.getInstance("MD5"); - digest.update(password.getBytes("UTF-16LE")); - return String.format("%032x", new BigInteger(1, digest.digest())); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - - public synchronized void login() throws WebServiceException { - if (clientInfo.getClientId() == null || clientInfo.getClientId().isEmpty()) { - throw new IllegalStateException("Sublight login has not been configured"); - } - - if (webservice == null) { - // lazy initialize because all the JAX-WS class loading can take quite some time - webservice = new Sublight().getSublightSoap(); - } - - if (session == null) { - // args contains only iid - ArrayOfString args = new ArrayOfString(); - args.getString().add(iid); - - Holder session = new Holder(); - Holder error = new Holder(); - - if (username == null || username.isEmpty()) { - webservice.logInAnonymous4(clientInfo, args, session, null, error); - } else { - webservice.logIn6(username, passwordHash, clientInfo, args, session, null, null, null, null, error); - } - - // abort if something went wrong - checkError(error); - - // start session - this.session = session.value; - } - - // reset timer - logoutTimer.set(10, TimeUnit.MINUTES, true); - } - - - protected synchronized void logout() throws WebServiceException { - if (session != null) { - Holder error = new Holder(); - - webservice.logOut(session, null, error); - - // abort if something went wrong - checkError(error); - - // stop session - this.session = null; - - // cancel timer - logoutTimer.cancel(); - } - } - - - protected void checkError(Holder error) throws WebServiceException { - if (error.value != null) { - throw new WebServiceException("Response indicates error: " + error.value); - } - } - - protected final Timer logoutTimer = new Timer() { - - @Override - public void run() { - logout(); - } - }; - -} diff --git a/source/net/sourceforge/filebot/web/SublightSubtitleDescriptor.java b/source/net/sourceforge/filebot/web/SublightSubtitleDescriptor.java deleted file mode 100644 index 2c9def44..00000000 --- a/source/net/sourceforge/filebot/web/SublightSubtitleDescriptor.java +++ /dev/null @@ -1,144 +0,0 @@ - -package net.sourceforge.filebot.web; - - -import java.io.ByteArrayInputStream; -import java.nio.ByteBuffer; -import java.util.Formatter; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; - -import net.sourceforge.tuned.ByteBufferOutputStream; -import net.sublight.webservice.Subtitle; - - -public class SublightSubtitleDescriptor implements SubtitleDescriptor { - - private final Subtitle subtitle; - private final SublightSubtitleClient source; - - private final String name; - private final String languageName; - - - public SublightSubtitleDescriptor(Subtitle subtitle, SublightSubtitleClient source) { - this.subtitle = subtitle; - this.source = source; - - this.name = getName(subtitle); - this.languageName = source.getLanguageName(subtitle.getLanguage()); - } - - - private String getName(Subtitle subtitle) { - String releaseName = subtitle.getRelease(); - - // check if release name contains sufficient information to be used as display name - if (releaseName != null && !releaseName.isEmpty()) { - boolean isValid = true; - - if (subtitle.getSeason() != null) { - isValid &= releaseName.contains(subtitle.getSeason().toString()); - } - - if (subtitle.getEpisode() != null) { - isValid &= releaseName.contains(subtitle.getEpisode().toString()); - } - - if (isValid) { - return releaseName; - } - } - - // format proper display name - Formatter builder = new Formatter(new StringBuilder(subtitle.getTitle())); - - if (subtitle.getSeason() != null || subtitle.getEpisode() != null) { - builder.format(" - S%02dE%02d", subtitle.getSeason(), subtitle.getEpisode()); - } - - if (subtitle.getRelease() != null && !subtitle.getRelease().isEmpty()) { - builder.format(" (%s)", subtitle.getRelease()); - } - - return builder.out().toString(); - } - - - @Override - public String getName() { - return name; - } - - - @Override - public String getLanguageName() { - return languageName; - } - - - @Override - public String getType() { - return subtitle.getSubtitleType().value().toLowerCase(); - } - - - @Override - public long getLength() { - return subtitle.getSize(); - } - - - @Override - public ByteBuffer fetch() throws Exception { - byte[] archive = source.getZipArchive(subtitle); - - // the zip archive will contain exactly one subtitle - ZipInputStream stream = new ZipInputStream(new ByteArrayInputStream(archive)); - - try { - // move to subtitle entry - ZipEntry entry = stream.getNextEntry(); - - ByteBufferOutputStream buffer = new ByteBufferOutputStream(entry.getSize()); - - // read subtitle data - buffer.transferFully(stream); - - // return plain subtitle data - return buffer.getByteBuffer(); - } finally { - stream.close(); - } - } - - - @Override - public String getPath() { - return String.format("%s.%s", getName(), getType()); - } - - - @Override - public int hashCode() { - return subtitle.getSubtitleID().hashCode(); - } - - - @Override - public boolean equals(Object object) { - if (object instanceof SublightSubtitleDescriptor) { - SublightSubtitleDescriptor other = (SublightSubtitleDescriptor) object; - return subtitle.getSubtitleID().equals(other.subtitle.getSubtitleID()); - } - - return false; - } - - - @Override - public String toString() { - return String.format("%s [%s]", getName(), getLanguageName()); - } - -} diff --git a/source/net/sourceforge/filebot/web/SublightVideoHasher.java b/source/net/sourceforge/filebot/web/SublightVideoHasher.java deleted file mode 100644 index 0b20c73e..00000000 --- a/source/net/sourceforge/filebot/web/SublightVideoHasher.java +++ /dev/null @@ -1,124 +0,0 @@ - -package net.sourceforge.filebot.web; - - -import static java.lang.Math.*; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.math.BigInteger; -import java.nio.channels.FileChannel; -import java.nio.channels.FileChannel.MapMode; -import java.security.MessageDigest; -import java.util.Formatter; -import java.util.concurrent.TimeUnit; - -import net.sourceforge.filebot.mediainfo.MediaInfo; -import net.sourceforge.filebot.mediainfo.MediaInfoException; -import net.sourceforge.filebot.mediainfo.MediaInfo.StreamKind; - - -/** - * Compute special hash used by Sublight to identify video files. - * - *
- * The hash is divided into 5 sections:
- * 1 byte : reserved
- * 2 bytes: video duration in seconds
- * 6 bytes: file size in bytes
- * 16 bytes: MD5 hash of the first 5 MB
- * 1 byte: control byte, sum of all other bytes
- * 
- */ -public final class SublightVideoHasher { - - public static String computeHash(File file) throws IOException, MediaInfoException { - byte[][] hash = new byte[4][]; - - // 1 byte = 0 (reserved) - hash[0] = new byte[] { 0 }; - - // 2 bytes (video duration in seconds) - hash[1] = getTrailingBytes(getDuration(file, TimeUnit.SECONDS), 2); - - // 6 bytes (file size in bytes) - hash[2] = getTrailingBytes(file.length(), 6); - - // 16 bytes (md5 hash of the first 5 MB) - hash[3] = getHeadMD5(file, 5 * 1024 * 1024); - - // format and sum - Formatter hex = new Formatter(new StringBuilder(52)); - byte sum = 0; - - for (byte[] group : hash) { - for (byte b : group) { - hex.format("%02x", b); - sum += b; - } - } - - // 1 byte (control byte) - hex.format("%02x", sum); - - // done - return hex.out().toString(); - } - - - protected static byte[] getTrailingBytes(long value, int n) { - byte[] bytes = BigInteger.valueOf(value).toByteArray(); - - // bytes will be initialized with 0 - byte[] trailingBytes = new byte[n]; - - // copy the least significant n bytes to the new array - System.arraycopy(bytes, max(0, bytes.length - n), trailingBytes, max(0, n - bytes.length), min(n, bytes.length)); - - return trailingBytes; - } - - - protected static long getDuration(File file, TimeUnit unit) throws IOException, MediaInfoException { - MediaInfo mediaInfo = new MediaInfo(); - - if (!mediaInfo.open(file)) - throw new IOException("Failed to open file: " + file); - - // get media info - String duration = mediaInfo.get(StreamKind.General, 0, "Duration"); - - // close handle - mediaInfo.close(); - - // sanity check - if (duration.isEmpty()) - throw new IOException("Failed to read video duration"); - - // convert from milliseconds to given unit - return unit.convert(Long.parseLong(duration), TimeUnit.MILLISECONDS); - } - - - protected static byte[] getHeadMD5(File file, long chunkSize) throws IOException { - try { - MessageDigest md5 = MessageDigest.getInstance("MD5"); - - FileChannel channel = new FileInputStream(file).getChannel(); - - try { - // calculate md5 - md5.update(channel.map(MapMode.READ_ONLY, 0, min(channel.size(), chunkSize))); - } finally { - // close channel - channel.close(); - } - - return md5.digest(); - } catch (Exception e) { - throw new IOException("Failed to calculate md5 hash", e); - } - } - -} diff --git a/source/net/sourceforge/filebot/web/SubsceneSubtitleClient.java b/source/net/sourceforge/filebot/web/SubsceneSubtitleClient.java deleted file mode 100644 index ef981ebf..00000000 --- a/source/net/sourceforge/filebot/web/SubsceneSubtitleClient.java +++ /dev/null @@ -1,199 +0,0 @@ - -package net.sourceforge.filebot.web; - - -import static net.sourceforge.filebot.web.WebRequest.*; -import static net.sourceforge.tuned.XPathUtilities.*; - -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URI; -import java.net.URL; -import java.net.URLConnection; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.regex.Pattern; - -import javax.swing.Icon; - -import net.sourceforge.filebot.Cache; -import net.sourceforge.filebot.ResourceManager; - -import org.w3c.dom.Document; -import org.w3c.dom.Node; -import org.xml.sax.SAXException; - - -public class SubsceneSubtitleClient implements SubtitleProvider { - - private static final String host = "subscene.com"; - - - @Override - public String getName() { - return "Subscene"; - } - - - @Override - public URI getLink() { - return URI.create("http://subscene.com"); - } - - - @Override - public Icon getIcon() { - return ResourceManager.getIcon("search.subscene"); - } - - - @Override - public List search(String query) throws IOException, SAXException { - URL searchUrl = new URL("http", host, "/subtitles/title.aspx?q=" + encode(query, true)); - Document dom = getHtmlDocument(searchUrl); - - List nodes = selectNodes("//H2[text()='Close']//following::DIV[@class='title']//A", dom); - List searchResults = new ArrayList(nodes.size()); - - Pattern titleSuffixPattern = Pattern.compile("\\s-\\s([^-]+)[(](\\d{4})[)]$"); - - for (Node node : nodes) { - String title = getTextContent(node); - String href = getAttribute("href", node); - - // simplified name for easy matching - String shortName = titleSuffixPattern.matcher(title).replaceFirst(""); - - try { - searchResults.add(new SubsceneSearchResult(shortName, title, new URL("http", host, href))); - } catch (MalformedURLException e) { - Logger.getLogger(getClass().getName()).log(Level.WARNING, "Invalid href: " + href, e); - } - } - - return searchResults; - } - - - @Override - public List getSubtitleList(SearchResult searchResult, String languageName) throws Exception { - URL subtitleListUrl = getSubtitleListLink(searchResult, languageName).toURL(); - - String filter = getLanguageFilter(languageName); - Document dom = getSubtitleListDocument(subtitleListUrl, filter); - - List rows = selectNodes("//TD[@class='a1']", dom); - List subtitles = new ArrayList(); - for (Node row : rows) { - try { - List fields = selectNodes(".//SPAN", row); - String language = getTextContent(fields.get(0)); - - if (languageName == null || language.equalsIgnoreCase(languageName)) { - String name = getTextContent(fields.get(1)); - String href = selectString(".//A/@href", row); - URL subtitlePage = new URL(subtitleListUrl.getProtocol(), subtitleListUrl.getHost(), href); - subtitles.add(new SubsceneSubtitleDescriptor(name, language, subtitlePage)); - } - } catch (Exception e) { - Logger.getLogger(getClass().getName()).log(Level.WARNING, "Cannot parse subtitle node", e); - } - } - - return subtitles; - } - - - protected Document getSubtitleListDocument(URL subtitleListUrl, String languageFilter) throws IOException, SAXException { - URLConnection connection = subtitleListUrl.openConnection(); - - if (languageFilter != null) { - connection.addRequestProperty("Cookie", "Filter=" + languageFilter); - } - - return getHtmlDocument(connection); - } - - - @SuppressWarnings("unchecked") - protected String getLanguageFilter(String languageName) throws IOException, SAXException { - if (languageName == null || languageName.isEmpty()) { - return null; - } - - // try cache first - Cache cache = Cache.getCache("web-datasource-lv2"); - String cacheKey = getClass().getName() + ".languageFilter"; - - Map filters = cache.get(cacheKey, Map.class); - - if (filters != null) { - return filters.get(languageName.toLowerCase()); - } - - // fetch new language filter data - filters = getLanguageFilterMap(); - - // update cache after sanity check - if (filters.size() > 42) { - cache.put(cacheKey, filters); - } else { - Logger.getLogger(getClass().getName()).log(Level.WARNING, "Failed to scrape language filters: " + filters); - } - - return filters.get(languageName.toLowerCase()); - } - - - protected Map getLanguageFilterMap() throws IOException, SAXException { - Map filters = new HashMap(50); - - Document dom = getHtmlDocument(new URL("http://subscene.com/filter")); - List checkboxes = selectNodes("//INPUT[@type='checkbox']", dom); - - for (Node checkbox : checkboxes) { - String filter = getAttribute("value", checkbox); - if (filter != null) { - String name = selectString("./following::LABEL", checkbox); - filters.put(name.toLowerCase(), filter); - } - } - - return filters; - } - - - @Override - public URI getSubtitleListLink(SearchResult searchResult, String languageName) { - return ((HyperLink) searchResult).getURI(); - } - - - public static class SubsceneSearchResult extends HyperLink { - - private String shortName; - - - public SubsceneSearchResult(String shortName, String title, URL url) { - super(title, url); - this.shortName = shortName; - } - - - @Override - public String getName() { - return shortName; - } - - - @Override - public String toString() { - return super.getName(); - } - } - -} diff --git a/source/net/sourceforge/filebot/web/SubsceneSubtitleDescriptor.java b/source/net/sourceforge/filebot/web/SubsceneSubtitleDescriptor.java deleted file mode 100644 index b81d1494..00000000 --- a/source/net/sourceforge/filebot/web/SubsceneSubtitleDescriptor.java +++ /dev/null @@ -1,96 +0,0 @@ - -package net.sourceforge.filebot.web; - - -import static java.util.Collections.*; -import static net.sourceforge.tuned.XPathUtilities.*; - -import java.io.IOException; -import java.net.URL; -import java.nio.ByteBuffer; - -import org.w3c.dom.Document; -import org.xml.sax.SAXException; - - -public class SubsceneSubtitleDescriptor implements SubtitleDescriptor { - - private String title; - private String language; - - private URL subtitlePage; - - - public SubsceneSubtitleDescriptor(String title, String language, URL subtitlePage) { - this.title = title; - this.language = language; - this.subtitlePage = subtitlePage; - } - - - @Override - public String getName() { - return title; - } - - - @Override - public String getLanguageName() { - return language; - } - - - @Override - public String getType() { - return null; - } - - - @Override - public ByteBuffer fetch() throws Exception { - return WebRequest.fetch(getDownloadLink(), 0, singletonMap("Referer", subtitlePage.toString())); - } - - - private URL getDownloadLink() throws IOException, SAXException { - Document page = WebRequest.getHtmlDocument(subtitlePage); - String file = selectString("id('downloadButton')/@href", page); - return new URL(subtitlePage.getProtocol(), subtitlePage.getHost(), file); - } - - - @Override - public String getPath() { - return getName(); - } - - - @Override - public long getLength() { - return -1; - } - - - @Override - public int hashCode() { - return subtitlePage.getPath().hashCode(); - } - - - @Override - public boolean equals(Object object) { - if (object instanceof SubsceneSubtitleDescriptor) { - SubsceneSubtitleDescriptor other = (SubsceneSubtitleDescriptor) object; - return subtitlePage.getPath().equals(other.getPath()); - } - - return false; - } - - - @Override - public String toString() { - return String.format("%s [%s]", getName(), getLanguageName()); - } - -} diff --git a/test/net/sourceforge/filebot/web/SublightSubtitleClientTest.java b/test/net/sourceforge/filebot/web/SublightSubtitleClientTest.java deleted file mode 100644 index 719ce688..00000000 --- a/test/net/sourceforge/filebot/web/SublightSubtitleClientTest.java +++ /dev/null @@ -1,108 +0,0 @@ - -package net.sourceforge.filebot.web; - - -import static org.junit.Assert.*; - -import java.io.ByteArrayInputStream; -import java.util.List; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; - -import net.sublight.webservice.Subtitle; - -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; - - -public class SublightSubtitleClientTest { - - private static SublightSubtitleClient client = new SublightSubtitleClient(); - - - @BeforeClass - public static void login() { - client.setClient("SublightCmd", "12c72276-b95f-4144-bb2a-879775c71437"); - client.setUser("filebot-test", "correcthorsebatterystaple"); - client.login(); - } - - - @Test - public void search() { - List list = client.search("babylon 5"); - - Movie sample = (Movie) list.get(0); - - // check sample entry - assertEquals("Babylon 5", sample.getName()); - assertEquals(105946, sample.getImdbId()); - - // check size - assertEquals(8, list.size()); - } - - - @Test - public void getSubtitleListEnglish() { - List list = client.getSubtitleList(new Movie("Heroes", 2006, 813715, -1), "English"); - - SubtitleDescriptor sample = list.get(0); - assertEquals("English", sample.getLanguageName()); - - // check size - assertTrue(list.size() > 45); - } - - - @Test - public void getSubtitleListAllLanguages() { - List list = client.getSubtitleList(new Movie("Terminator 2", 1991, 103064, -1), "Croatian"); - - SubtitleDescriptor sample = list.get(0); - - assertEquals("Terminator.2-Judgment.Day[1991]DvDrip-aXXo", sample.getName()); - assertEquals("Croatian", sample.getLanguageName()); - } - - - @Test - public void getSubtitleListVideoHash() throws Exception { - List list = client.getSubtitleList("001c6e0000320458004ee6f6859e5b7844767d44336e5624edbb", null, null, "English"); - - Subtitle sample = list.get(0); - assertEquals("Jurassic Park", sample.getTitle()); - assertEquals("Jurassic.Park[1993]DvDrip-aXXo", sample.getRelease()); - assertEquals(true, sample.isIsLinked()); - } - - - @Test - public void getZipArchive() throws Exception { - Subtitle subtitle = new Subtitle(); - subtitle.setSubtitleID("1b4e9868-dded-49d0-b6e2-2d145328f6d4"); - - byte[] zip = client.getZipArchive(subtitle); - - // read first zip entry - ZipInputStream zipInputStream = new ZipInputStream(new ByteArrayInputStream(zip)); - - try { - ZipEntry entry = zipInputStream.getNextEntry(); - - assertEquals("Terminator The Sarah Connor Chronicles.srt", entry.getName()); - assertEquals(38959, entry.getSize(), 0); - } finally { - zipInputStream.close(); - } - } - - - @AfterClass - public static void logout() { - // logout manually - client.logout(); - } - -} diff --git a/test/net/sourceforge/filebot/web/SubsceneSubtitleClientTest.java b/test/net/sourceforge/filebot/web/SubsceneSubtitleClientTest.java deleted file mode 100644 index 2ccc976e..00000000 --- a/test/net/sourceforge/filebot/web/SubsceneSubtitleClientTest.java +++ /dev/null @@ -1,113 +0,0 @@ - -package net.sourceforge.filebot.web; - - -import static org.junit.Assert.*; - -import java.net.URL; -import java.nio.ByteBuffer; -import java.util.List; -import java.util.Map; - -import net.sourceforge.filebot.vfs.ArchiveType; -import net.sourceforge.filebot.vfs.MemoryFile; -import net.sourceforge.filebot.web.SubsceneSubtitleClient.SubsceneSearchResult; - -import org.junit.BeforeClass; -import org.junit.Test; - - -public class SubsceneSubtitleClientTest { - - /** - * Twin Peaks - First Season, ~ 15 subtitles - */ - private static HyperLink twinpeaksSearchResult; - - /** - * Lost - Fourth Season, ~ 430 subtitles - */ - private static HyperLink lostSearchResult; - - - @BeforeClass - public static void setUpBeforeClass() throws Exception { - twinpeaksSearchResult = new SubsceneSearchResult("Twin Peaks", "Twin Peaks - First Season (1990)", new URL("http://subscene.com/subtitles/twin-peaks-first-season")); - lostSearchResult = new SubsceneSearchResult("Lost", "Lost - Fourth Season (2008)", new URL("http://subscene.com/subtitles/lost-fourth-season")); - } - - private SubsceneSubtitleClient subscene = new SubsceneSubtitleClient(); - - - @Test - public void search() throws Exception { - List results = subscene.search("twin peaks"); - - SubsceneSearchResult result = (SubsceneSearchResult) results.get(0); - assertEquals(twinpeaksSearchResult.toString(), result.toString()); - assertEquals(twinpeaksSearchResult.getURL().toString(), result.getURL().toString()); - assertEquals(twinpeaksSearchResult.getName(), result.getName()); - } - - - @Test - public void search2() throws Exception { - List results = subscene.search("firefly"); - - SubsceneSearchResult result = (SubsceneSearchResult) results.get(0); - assertEquals("Firefly - The Complete Series (2002)", result.toString()); - assertEquals("Firefly", result.getName()); - assertEquals("http://subscene.com/subtitles/firefly-the-complete-series", result.getURL().toString()); - } - - - @Test - public void getSubtitleListSearchResult() throws Exception { - List subtitleList = subscene.getSubtitleList(twinpeaksSearchResult, "Italian"); - assertEquals(10, subtitleList.size()); - - SubtitleDescriptor subtitle = subtitleList.get(0); - assertEquals("Twin-Peaks-S01E00-Pilot-eAlternate-ita sub by IScrew [www.ITALIANSHARE.net]", subtitle.getName()); - assertEquals("Italian", subtitle.getLanguageName()); - } - - - @Test - public void getSubtitleListSearchResultMany() throws Exception { - List subtitleList = subscene.getSubtitleList(lostSearchResult, "Japanese"); - - // lots of subtitles, but only a few Japanese ones - assertEquals(16, subtitleList.size()); - } - - - @Test - public void getLanguageFilterMap() throws Exception { - Map filters = subscene.getLanguageFilterMap(); - - assertEquals("1", filters.get("albanian")); - assertEquals("13", filters.get("english")); - assertEquals("17", filters.get("finnish")); - assertEquals("45", filters.get("vietnamese")); - } - - - @Test - public void getSubtitleListLink() throws Exception { - assertEquals(twinpeaksSearchResult.getURL().toString(), subscene.getSubtitleListLink(twinpeaksSearchResult, null).toURL().toString()); - } - - - @Test - public void downloadSubtitleArchive() throws Exception { - SearchResult selectedResult = subscene.search("firefly").get(0); - SubtitleDescriptor subtitleDescriptor = subscene.getSubtitleList(selectedResult, "English").get(0); - assertEquals("Firefly The Complete Series", subtitleDescriptor.getName()); - - ByteBuffer data = subtitleDescriptor.fetch(); - Iterable archive = ArchiveType.RAR.fromData(data); - MemoryFile file = archive.iterator().next(); - assertEquals("Firefly - 1x01 - Serenity.srt", file.getName()); - } - -} diff --git a/test/net/sourceforge/filebot/web/WebTestSuite.java b/test/net/sourceforge/filebot/web/WebTestSuite.java index 25550877..3acb54e4 100644 --- a/test/net/sourceforge/filebot/web/WebTestSuite.java +++ b/test/net/sourceforge/filebot/web/WebTestSuite.java @@ -1,15 +1,11 @@ - package net.sourceforge.filebot.web; - import org.junit.runner.RunWith; import org.junit.runners.Suite; import org.junit.runners.Suite.SuiteClasses; - @RunWith(Suite.class) -@SuiteClasses( { AnidbClientTest.class, TVRageClientTest.class, TheTVDBClientTest.class, SerienjunkiesClientTest.class, TMDbClientTest.class, IMDbClientTest.class, SubsceneSubtitleClientTest.class, SublightSubtitleClientTest.class, - OpenSubtitlesXmlRpcTest.class }) +@SuiteClasses({ AnidbClientTest.class, TVRageClientTest.class, TheTVDBClientTest.class, SerienjunkiesClientTest.class, TMDbClientTest.class, IMDbClientTest.class, OpenSubtitlesXmlRpcTest.class }) public class WebTestSuite { - + }