mirror of
https://github.com/mitb-archive/filebot
synced 2024-12-23 00:08:51 -05:00
+ Sublight support (build, client, hash, test, lib)
This commit is contained in:
parent
6593bfdbda
commit
7bb739f800
55
build.xml
55
build.xml
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<project name="FileBot" default="jar">
|
||||
|
||||
|
||||
<property name="title" value="${ant.project.name}" />
|
||||
<property name="version" value="1.9" />
|
||||
|
||||
@ -22,15 +22,6 @@
|
||||
<!-- main jar -->
|
||||
<jar destfile="${dir.dist}/filebot.jar">
|
||||
<fileset dir="${dir.build}" excludes="**/*Test*" />
|
||||
|
||||
<manifest>
|
||||
<attribute name="Built-By" value="${user.name}" />
|
||||
<attribute name="Built-Date" value="${today}" />
|
||||
<attribute name="Application-Name" value="${title}" />
|
||||
<attribute name="Application-Version" value="${version}" />
|
||||
<attribute name="Class-Path" value="args4j.jar miglayout.jar glazedlists.jar nekohtml.jar xercesImpl.jar ehcache.jar simmetrics.jar xmlrpc-client.jar" />
|
||||
<attribute name="Main-Class" value="net.sourceforge.filebot.Main" />
|
||||
</manifest>
|
||||
</jar>
|
||||
|
||||
<!-- extra jar containing all the unit tests -->
|
||||
@ -45,25 +36,31 @@
|
||||
<mkdir dir="${dir.dist}/fatjar" />
|
||||
|
||||
<jar destfile="${dir.dist}/fatjar/FileBot.jar" filesetmanifest="merge" duplicate="fail">
|
||||
<manifest>
|
||||
<attribute name="Built-By" value="${user.name}" />
|
||||
<attribute name="Built-Date" value="${today}" />
|
||||
<attribute name="Application-Name" value="${title}" />
|
||||
<attribute name="Application-Version" value="${version}" />
|
||||
<attribute name="Main-Class" value="net.sourceforge.filebot.Main" />
|
||||
</manifest>
|
||||
|
||||
<zipfileset src="${dir.dist}/filebot.jar">
|
||||
<include name="**/*" />
|
||||
</zipfileset>
|
||||
<!-- include build -->
|
||||
<fileset dir="${dir.build}" excludes="**/*Test*" />
|
||||
|
||||
<!-- include libs -->
|
||||
<zipfileset src="${dir.lib}/xercesImpl.jar">
|
||||
<include name="org/apache/**" />
|
||||
<include name="org/w3c/dom/html/**" />
|
||||
</zipfileset>
|
||||
|
||||
|
||||
<zipfileset src="${dir.lib}/nekohtml.jar">
|
||||
<include name="org/cyberneko/html/**" />
|
||||
</zipfileset>
|
||||
|
||||
|
||||
<zipfileset src="${dir.lib}/simmetrics.jar">
|
||||
<include name="uk/ac/shef/wit/simmetrics/**" />
|
||||
</zipfileset>
|
||||
|
||||
|
||||
<zipfileset src="${dir.lib}/glazedlists.jar">
|
||||
<include name="ca/odell/glazedlists/**" />
|
||||
</zipfileset>
|
||||
@ -71,7 +68,7 @@
|
||||
<zipfileset src="${dir.lib}/miglayout.jar">
|
||||
<include name="net/miginfocom/**" />
|
||||
</zipfileset>
|
||||
|
||||
|
||||
<zipfileset src="${dir.lib}/xmlrpc-client.jar">
|
||||
<include name="redstone/xmlrpc/**" />
|
||||
</zipfileset>
|
||||
@ -79,23 +76,27 @@
|
||||
<zipfileset src="${dir.lib}/args4j.jar">
|
||||
<include name="org/kohsuke/args4j/**" />
|
||||
</zipfileset>
|
||||
|
||||
|
||||
<zipfileset src="${dir.lib}/ehcache.jar">
|
||||
<include name="net/sf/ehcache/**" />
|
||||
</zipfileset>
|
||||
|
||||
|
||||
<zipfileset src="${dir.lib}/jna.jar">
|
||||
<!-- include classes and native libraries -->
|
||||
<include name="com/sun/jna/**" />
|
||||
</zipfileset>
|
||||
|
||||
|
||||
<zipfileset src="${dir.lib}/js-engine.jar">
|
||||
<include name="com/sun/phobos/script/**" />
|
||||
</zipfileset>
|
||||
|
||||
|
||||
<zipfileset src="${dir.lib}/js.jar">
|
||||
<include name="org/mozilla/**" />
|
||||
</zipfileset>
|
||||
|
||||
<zipfileset src="${dir.lib}/sublight-ws.jar">
|
||||
<include name="net/sublight/webservice/**" />
|
||||
</zipfileset>
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
@ -110,7 +111,7 @@
|
||||
<fileset dir="${dir.lib}" includes="*.jar" />
|
||||
</classpath>
|
||||
</javac>
|
||||
|
||||
|
||||
<!-- copy resources -->
|
||||
<copy todir="${dir.build}">
|
||||
<fileset dir="${dir.source}">
|
||||
@ -139,7 +140,7 @@
|
||||
</junit>
|
||||
</target>
|
||||
|
||||
|
||||
|
||||
<target name="test-fatjar" depends="fatjar">
|
||||
<junit printsummary="yes" fork="true">
|
||||
<classpath>
|
||||
@ -147,16 +148,16 @@
|
||||
<pathelement location="${dir.dist}/filebot-test.jar" />
|
||||
<pathelement location="${dir.lib}/junit.jar" />
|
||||
</classpath>
|
||||
|
||||
|
||||
<formatter type="plain" />
|
||||
|
||||
<test name="net.sourceforge.filebot.AllTests" outfile="test-report" />
|
||||
</junit>
|
||||
</target>
|
||||
|
||||
|
||||
|
||||
|
||||
<target name="run-fatjar" depends="fatjar">
|
||||
<java jar="${dir.dist}/fatjar/FileBot.jar" fork="true" />
|
||||
</target>
|
||||
|
||||
|
||||
</project>
|
||||
|
BIN
lib/sublight-ws.jar
Normal file
BIN
lib/sublight-ws.jar
Normal file
Binary file not shown.
BIN
source/net/sourceforge/filebot/resources/search.sublight.png
Normal file
BIN
source/net/sourceforge/filebot/resources/search.sublight.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 251 B |
@ -62,8 +62,8 @@ public class IMDbClient implements EpisodeListProvider {
|
||||
List<SearchResult> results = new ArrayList<SearchResult>(nodes.size());
|
||||
|
||||
for (Node node : nodes) {
|
||||
String name = removeQuotationMarks(node.getTextContent().trim());
|
||||
String year = node.getNextSibling().getTextContent().trim();
|
||||
String name = normalizeName(node.getTextContent().trim());
|
||||
String year = node.getNextSibling().getTextContent().trim().replaceAll("\\D+", ""); // remove non-number characters
|
||||
String href = getAttribute("href", node);
|
||||
|
||||
results.add(new MovieDescriptor(name, Integer.parseInt(year), getImdbId(href)));
|
||||
@ -71,7 +71,7 @@ public class IMDbClient implements EpisodeListProvider {
|
||||
|
||||
// we might have been redirected to the movie page
|
||||
if (results.isEmpty()) {
|
||||
String name = removeQuotationMarks(selectString("//H1/text()", dom));
|
||||
String name = normalizeName(selectString("//H1/text()", dom));
|
||||
String year = selectString("//H1//A", dom);
|
||||
String url = selectString("//LINK[@rel='canonical']/@href", dom);
|
||||
|
||||
@ -86,7 +86,7 @@ public class IMDbClient implements EpisodeListProvider {
|
||||
public List<Episode> getEpisodeList(SearchResult searchResult) throws IOException, SAXException {
|
||||
Document dom = getHtmlDocument(openConnection(getEpisodeListLink(searchResult).toURL()));
|
||||
|
||||
String seriesName = removeQuotationMarks(selectString("//H1/A", dom));
|
||||
String seriesName = normalizeName(selectString("//H1/A", dom));
|
||||
|
||||
List<Node> nodes = selectNodes("//TABLE//H3/A[preceding-sibling::text()]", dom);
|
||||
|
||||
@ -129,8 +129,9 @@ public class IMDbClient implements EpisodeListProvider {
|
||||
}
|
||||
|
||||
|
||||
protected String removeQuotationMarks(String name) {
|
||||
return name.replaceAll("^\"|\"$", "");
|
||||
protected String normalizeName(String name) {
|
||||
// remove quotation marks
|
||||
return name.replaceAll("\"", "");
|
||||
}
|
||||
|
||||
|
||||
|
252
source/net/sourceforge/filebot/web/SublightSubtitleClient.java
Normal file
252
source/net/sourceforge/filebot/web/SublightSubtitleClient.java
Normal file
@ -0,0 +1,252 @@
|
||||
|
||||
package net.sourceforge.filebot.web;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
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.ArrayOfSubtitle;
|
||||
import net.sublight.webservice.ArrayOfSubtitleLanguage;
|
||||
import net.sublight.webservice.Genre;
|
||||
import net.sublight.webservice.IMDB;
|
||||
import net.sublight.webservice.Release;
|
||||
import net.sublight.webservice.Subtitle;
|
||||
import net.sublight.webservice.SubtitleLanguage;
|
||||
import net.sublight.webservice.SubtitlesAPI2;
|
||||
import net.sublight.webservice.SubtitlesAPI2Soap;
|
||||
|
||||
|
||||
public class SublightSubtitleClient implements SubtitleProvider {
|
||||
|
||||
private static final String iid = "42cc1701-3752-49e2-a148-332960073452";
|
||||
|
||||
private final String clientInfo;
|
||||
|
||||
private final SubtitlesAPI2Soap webservice;
|
||||
|
||||
private String session;
|
||||
|
||||
|
||||
public SublightSubtitleClient(String clientInfo) {
|
||||
this.clientInfo = clientInfo;
|
||||
this.webservice = new SubtitlesAPI2().getSubtitlesAPI2Soap();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Sublight";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Icon getIcon() {
|
||||
return ResourceManager.getIcon("search.sublight");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<SearchResult> search(String query) throws WebServiceException {
|
||||
// require login
|
||||
login();
|
||||
|
||||
Holder<ArrayOfIMDB> response = new Holder<ArrayOfIMDB>();
|
||||
Holder<String> error = new Holder<String>();
|
||||
|
||||
webservice.findIMDB(query, null, null, response, error);
|
||||
|
||||
// abort if something went wrong
|
||||
checkError(error);
|
||||
|
||||
List<SearchResult> results = new ArrayList<SearchResult>();
|
||||
|
||||
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 MovieDescriptor(imdb.getTitle(), imdb.getYear(), id));
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<SubtitleDescriptor> getSubtitleList(SearchResult searchResult, String languageName) throws WebServiceException {
|
||||
MovieDescriptor movie = (MovieDescriptor) searchResult;
|
||||
|
||||
List<SubtitleDescriptor> subtitles = new ArrayList<SubtitleDescriptor>();
|
||||
|
||||
// retrieve subtitles by name and year
|
||||
for (Subtitle subtitle : getSubtitleList(null, movie.getName(), movie.getYear(), languageName)) {
|
||||
subtitles.add(new SublightSubtitleDescriptor(subtitle));
|
||||
}
|
||||
|
||||
return subtitles;
|
||||
}
|
||||
|
||||
|
||||
public List<SubtitleDescriptor> getSubtitleList(File videoFile, String languageName) throws WebServiceException, IOException {
|
||||
List<SubtitleDescriptor> subtitles = new ArrayList<SubtitleDescriptor>();
|
||||
|
||||
// retrieve subtitles by video hash
|
||||
for (Subtitle subtitle : getSubtitleList(SublightVideoHasher.computeHash(videoFile), null, null, languageName)) {
|
||||
// only keep linked subtitles
|
||||
if (subtitle.isIsLinked()) {
|
||||
subtitles.add(new SublightSubtitleDescriptor(subtitle));
|
||||
}
|
||||
}
|
||||
|
||||
return subtitles;
|
||||
}
|
||||
|
||||
|
||||
protected List<Subtitle> 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());
|
||||
}
|
||||
|
||||
// all genres
|
||||
ArrayOfGenre genres = new ArrayOfGenre();
|
||||
Collections.addAll(genres.getGenre(), Genre.values());
|
||||
|
||||
// response holders
|
||||
Holder<ArrayOfSubtitle> subtitles = new Holder<ArrayOfSubtitle>();
|
||||
Holder<ArrayOfRelease> releases = new Holder<ArrayOfRelease>();
|
||||
Holder<String> error = new Holder<String>();
|
||||
|
||||
webservice.searchSubtitles3(session, videoHash, 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<String, String> releaseNameBySubtitleID = new HashMap<String, String>();
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
|
||||
protected SubtitleLanguage getSubtitleLanguage(String languageName) {
|
||||
for (SubtitleLanguage language : SubtitleLanguage.values()) {
|
||||
if (language.value().equalsIgnoreCase(languageName))
|
||||
return language;
|
||||
}
|
||||
|
||||
// special language name handling
|
||||
if (languageName.equalsIgnoreCase("Brazilian"))
|
||||
return SubtitleLanguage.PORTUGUESE_BRAZIL;
|
||||
if (languageName.equalsIgnoreCase("Bosnian"))
|
||||
return SubtitleLanguage.BOSNIAN_LATIN;
|
||||
if (languageName.equalsIgnoreCase("Serbian"))
|
||||
return SubtitleLanguage.SERBIAN_LATIN;
|
||||
|
||||
// unkown language
|
||||
throw new IllegalArgumentException("Illegal language: " + languageName);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public URI getSubtitleListLink(SearchResult searchResult, String languageName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
protected synchronized void login() throws WebServiceException {
|
||||
if (session == null) {
|
||||
Holder<String> session = new Holder<String>();
|
||||
Holder<String> error = new Holder<String>();
|
||||
|
||||
webservice.logInAnonymous3(clientInfo, iid, session, 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<String> error = new Holder<String>();
|
||||
|
||||
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("Login failed: " + error.value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected final Timer logoutTimer = new Timer() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
logout();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
|
||||
package net.sourceforge.filebot.web;
|
||||
|
||||
|
||||
import net.sourceforge.tuned.DownloadTask;
|
||||
import net.sublight.webservice.Subtitle;
|
||||
|
||||
|
||||
public class SublightSubtitleDescriptor implements SubtitleDescriptor {
|
||||
|
||||
private final Subtitle subtitle;
|
||||
|
||||
|
||||
public SublightSubtitleDescriptor(Subtitle subtitle) {
|
||||
this.subtitle = subtitle;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
// use release name by default
|
||||
String releaseName = subtitle.getRelease();
|
||||
|
||||
if (releaseName == null || releaseName.isEmpty()) {
|
||||
// create name from subtitle information (name, season, episode, ...)
|
||||
String season = subtitle.getSeason() != null ? subtitle.getSeason().toString() : null;
|
||||
String episode = subtitle.getEpisode() != null ? subtitle.getEpisode().toString() : null;
|
||||
|
||||
return EpisodeFormat.getInstance().format(new Episode(subtitle.getTitle(), season, episode, null));
|
||||
}
|
||||
|
||||
return releaseName;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getArchiveType() {
|
||||
return subtitle.getSubtitleType().value().toLowerCase();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getLanguageName() {
|
||||
return subtitle.getLanguage().value();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public DownloadTask createDownloadTask() {
|
||||
// TODO support
|
||||
return new DownloadTask(null);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s [%s]", getName(), getLanguageName());
|
||||
}
|
||||
|
||||
}
|
124
source/net/sourceforge/filebot/web/SublightVideoHasher.java
Normal file
124
source/net/sourceforge/filebot/web/SublightVideoHasher.java
Normal file
@ -0,0 +1,124 @@
|
||||
|
||||
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.MediaInfo.StreamKind;
|
||||
|
||||
|
||||
/**
|
||||
* Compute special hash used by <a href="http://www.subtitles-on.net">Sublight</a> to identify video files.
|
||||
*
|
||||
* <pre>
|
||||
* 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
|
||||
* </pre>
|
||||
*/
|
||||
public final class SublightVideoHasher {
|
||||
|
||||
|
||||
public static String computeHash(File file) throws IOException {
|
||||
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 {
|
||||
try {
|
||||
MediaInfo mediaInfo = new MediaInfo();
|
||||
|
||||
if (!mediaInfo.open(file))
|
||||
throw new IllegalArgumentException("Failed to open file: " + file);
|
||||
|
||||
// get media info
|
||||
String duration = mediaInfo.get(StreamKind.General, 0, "Duration");
|
||||
|
||||
// close handle
|
||||
mediaInfo.close();
|
||||
|
||||
// convert from milliseconds to given unit
|
||||
return unit.convert(Long.parseLong(duration), TimeUnit.MILLISECONDS);
|
||||
} catch (Exception e) {
|
||||
throw new IOException("Failed to get video duration", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -87,8 +87,8 @@ public class IMDbClientTest {
|
||||
|
||||
@Test
|
||||
public void removeQuotationMarks() throws Exception {
|
||||
assertEquals("test", imdb.removeQuotationMarks("\"test\""));
|
||||
assertEquals("test", imdb.normalizeName("\"test\""));
|
||||
|
||||
assertEquals("inner \"quotation marks\"", imdb.removeQuotationMarks("\"inner \"quotation marks\"\""));
|
||||
assertEquals("inner \"quotation marks\"", imdb.normalizeName("\"inner \"quotation marks\"\""));
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,6 @@ import java.io.FileInputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
@ -17,13 +16,12 @@ import org.junit.runners.Parameterized.Parameters;
|
||||
|
||||
|
||||
@RunWith(Parameterized.class)
|
||||
@Ignore("No test data")
|
||||
public class OpenSubtitlesHasherTest {
|
||||
|
||||
private String expectedHash;
|
||||
private File file;
|
||||
|
||||
|
||||
|
||||
public OpenSubtitlesHasherTest(String expectedHash, File file) {
|
||||
this.file = file;
|
||||
this.expectedHash = expectedHash;
|
||||
|
@ -0,0 +1,91 @@
|
||||
|
||||
package net.sourceforge.filebot.web;
|
||||
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
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("Test;0.0");
|
||||
|
||||
|
||||
@BeforeClass
|
||||
public static void login() {
|
||||
// login manually
|
||||
client.login();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void search() {
|
||||
List<SearchResult> list = client.search("babylon 5");
|
||||
|
||||
MovieDescriptor sample = (MovieDescriptor) 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<SubtitleDescriptor> list = client.getSubtitleList(new MovieDescriptor("Heroes", 2006, 813715), "English");
|
||||
|
||||
SubtitleDescriptor sample = list.get(0);
|
||||
|
||||
assertTrue(sample.getName().startsWith("Heroes"));
|
||||
assertEquals("English", sample.getLanguageName());
|
||||
|
||||
// check size
|
||||
assertTrue(list.size() > 45);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void getSubtitleListAllLanguages() {
|
||||
List<SubtitleDescriptor> list = client.getSubtitleList(new MovieDescriptor("Babylon 5", 1994, 105946), null);
|
||||
|
||||
SubtitleDescriptor sample = list.get(0);
|
||||
|
||||
assertEquals("Babylon.5.S01E01.Midnight.on.the.Firing.Line.AC3.DVDRip.DivX-AMC", sample.getName());
|
||||
assertEquals("Slovenian", sample.getLanguageName());
|
||||
|
||||
// check size
|
||||
assertTrue(list.size() > 45);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void getSubtitleListVideoHash() {
|
||||
List<Subtitle> list = client.getSubtitleList("000a20000045eacfebd3c2c83bfb4ea1598b14e9be7db38316fd", null, null, "English");
|
||||
|
||||
Subtitle sample = list.get(0);
|
||||
|
||||
assertEquals("Terminator: The Sarah Connor Chronicles", sample.getTitle());
|
||||
assertEquals(2, sample.getSeason(), 0);
|
||||
assertEquals(22, sample.getEpisode(), 0);
|
||||
assertEquals("Terminator.The.Sarah.Connor.Chronicles.S02E22.HDTV.XviD-2HD", sample.getRelease());
|
||||
assertTrue(sample.isIsLinked());
|
||||
}
|
||||
|
||||
|
||||
@AfterClass
|
||||
public static void logout() {
|
||||
// logout manually
|
||||
client.logout();
|
||||
}
|
||||
|
||||
}
|
@ -8,7 +8,7 @@ import org.junit.runners.Suite.SuiteClasses;
|
||||
|
||||
|
||||
@RunWith(Suite.class)
|
||||
@SuiteClasses( { TVDotComClientTest.class, AnidbClientTest.class, TVRageClientTest.class, TheTVDBClientTest.class, IMDbClientTest.class, SubsceneSubtitleClientTest.class, SubtitleSourceClientTest.class, OpenSubtitlesHasherTest.class })
|
||||
@SuiteClasses( { TVDotComClientTest.class, AnidbClientTest.class, TVRageClientTest.class, TheTVDBClientTest.class, IMDbClientTest.class, SubsceneSubtitleClientTest.class, SubtitleSourceClientTest.class, SublightSubtitleClientTest.class })
|
||||
public class WebTestSuite {
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user