1
0
mirror of https://github.com/mitb-archive/filebot synced 2024-11-17 23:05:03 -05:00
filebot/source/net/sourceforge/filebot/web/OpenSubtitlesClient.java
Reinhard Pointner ac9473ff07 * automatic episode list download and matching in RenamePanel
* added SeriesNameMatcher
* added SeasonEpisodeMatcher
* access Preferences via new Settings class
* adapt TVDotComClient to site changes (episodes  no longer ordered in reverse)
* added ActionPopup (inspired by the eclipse quickfix popup)

refactoring:
* renamed *Util classes to *Utilities
* renamed HyperlinkLabel to LinkButton as it extends JButton now
* refactored FileBotUtilities and FileUtilities
2009-01-25 00:08:57 +00:00

206 lines
5.5 KiB
Java

package net.sourceforge.filebot.web;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.sourceforge.filebot.web.OpenSubtitlesSubtitleDescriptor.Property;
import redstone.xmlrpc.XmlRpcClient;
import redstone.xmlrpc.XmlRpcException;
import redstone.xmlrpc.XmlRpcFault;
/**
* Client for the OpenSubtitles XML-RPC API.
*/
public class OpenSubtitlesClient {
private static final String url = "http://www.opensubtitles.org/xml-rpc";
private final String useragent;
private String token = null;
public OpenSubtitlesClient(String useragent) {
this.useragent = useragent;
}
/**
* Login as anonymous user
*
* @throws XmlRpcFault
*/
public void loginAnonymous() throws XmlRpcFault {
login("", "");
}
/**
* Login as user and use English as language
*
* @param username
* @param password
* @throws XmlRpcFault
*/
public void login(String username, String password) throws XmlRpcFault {
login(username, password, "en");
}
/**
* This will login user. This method should be called always when starting talking with
* server.
*
* @param username username (blank for anonymous user)
* @param password password (blank for anonymous user)
* @param language <a
* href="http://en.wikipedia.org/wiki/List_of_ISO_639-2_codes">ISO639</a>
* 2-letter codes as language and later communication will be done in this
* language if applicable (error codes and so on).
*/
@SuppressWarnings("unchecked")
public synchronized void login(String username, String password, String language) throws XmlRpcFault {
Map<String, String> response = (Map<String, String>) invoke("LogIn", username, password, language, useragent);
checkStatus(response.get("status"));
token = response.get("token");
}
/**
* This will logout user (ends session id). Good call this function is before ending
* (closing) clients program.
*
* @throws XmlRpcFault
*/
public synchronized void logout() throws XmlRpcFault {
try {
invoke("LogOut", token);
// anonymous users will always get a 401 Unauthorized when trying to logout
// do not check status for logout response
// checkStatus(response.get("status"));
} finally {
token = null;
}
}
public synchronized boolean isLoggedOn() {
return token != null;
}
/**
* Check whether status is OK or not
*
* @param status status code and message (e.g. 200 OK, 401 Unauthorized, ...)
* @throws XmlRpcFault thrown if status code is not OK
*/
private void checkStatus(String status) throws XmlRpcFault {
if (status.equals("200 OK"))
return;
Matcher m = Pattern.compile("(\\d+).*").matcher(status);
if (!m.matches())
throw new XmlRpcException("Illegal status code: " + status);
throw new XmlRpcFault(Integer.parseInt(m.group(1)), status);
}
private Object invoke(String method, Object... arguments) throws XmlRpcFault {
try {
XmlRpcClient rpc = new XmlRpcClient(url, false);
return rpc.invoke(method, arguments);
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}
/**
* This simple function returns basic server info.
*/
@SuppressWarnings("unchecked")
public Map<String, String> getServerInfo() throws XmlRpcFault {
return (Map<String, String>) invoke("ServerInfo", token);
}
@SuppressWarnings("unchecked")
public List<OpenSubtitlesSubtitleDescriptor> searchSubtitles(int imdbid, Locale language) throws XmlRpcFault {
Map<String, String> searchListEntry = new HashMap<String, String>(2);
// pad imdbId with zeros
//TODO needed???
searchListEntry.put("imdbid", String.format("%07d", imdbid));
searchListEntry.put("sublanguageid", getSubLanguageID(language));
List<Map<String, String>> searchList = Collections.singletonList(searchListEntry);
Map<String, List<Map<String, String>>> response = (Map<String, List<Map<String, String>>>) invoke("SearchSubtitles", token, searchList);
List<OpenSubtitlesSubtitleDescriptor> subs = new ArrayList<OpenSubtitlesSubtitleDescriptor>();
try {
for (Map<String, String> subtitleData : response.get("data")) {
subs.add(new OpenSubtitlesSubtitleDescriptor(Property.asEnumMap(subtitleData)));
}
} catch (ClassCastException e) {
// if the response is an error message, generic types won't match
throw new XmlRpcException("Illegal response: " + response.toString(), e);
}
return subs;
}
private String getSubLanguageID(Locale locale) {
//TODO test if sublanguageid is really ISO3 language code
return locale.getISO3Language();
}
@SuppressWarnings("unchecked")
public List<MovieDescriptor> searchMoviesOnIMDB(String query) throws XmlRpcFault {
Map<String, List<Map<String, String>>> response = (Map<String, List<Map<String, String>>>) invoke("SearchMoviesOnIMDB", token, query);
ArrayList<MovieDescriptor> movies = new ArrayList<MovieDescriptor>();
for (Map<String, String> movie : response.get("data")) {
movies.add(new MovieDescriptor(movie.get("title"), new Integer(movie.get("id"))));
}
return movies;
}
@SuppressWarnings("unchecked")
public boolean noOperation() {
try {
Map<String, String> response = (Map<String, String>) invoke("NoOperation", token);
checkStatus(response.get("status"));
return true;
} catch (Exception e) {
return false;
}
}
}