diff --git a/themoviedbapi/src/com/moviejukebox/themoviedb/TheMovieDb.java b/themoviedbapi/src/com/moviejukebox/themoviedb/TheMovieDb.java index afe38f2dd..91a0da97c 100644 --- a/themoviedbapi/src/com/moviejukebox/themoviedb/TheMovieDb.java +++ b/themoviedbapi/src/com/moviejukebox/themoviedb/TheMovieDb.java @@ -112,7 +112,7 @@ public class TheMovieDb { movie = DOMParser.parseMovieInfo(doc); } catch (Exception error) { - logger.severe("ERROR: " + error.getMessage()); + logger.severe("TheMovieDb Error: " + error.getMessage()); } return movie; } @@ -141,7 +141,7 @@ public class TheMovieDb { movie = DOMParser.parseMovieInfo(doc); } catch (Exception error) { - logger.severe("ERROR: " + error.getMessage()); + logger.severe("TheMovieDb Error: " + error.getMessage()); } return movie; } @@ -186,7 +186,7 @@ public class TheMovieDb { movie = DOMParser.parseMovieInfo(doc); } catch (Exception error) { - logger.severe("ERROR: " + error.getMessage()); + logger.severe("TheMovieDb Error: " + error.getMessage()); } return movie; } @@ -220,7 +220,7 @@ public class TheMovieDb { movie = DOMParser.parseMovieInfo(doc); } catch (Exception error) { - logger.severe("ERROR: " + error.getMessage()); + logger.severe("TheMovieDb Error: " + error.getMessage()); } return movie; @@ -241,7 +241,6 @@ public class TheMovieDb { return language; } - /** * The Person.search method is used to search for an actor, actress or production member. * http://api.themoviedb.org/2.1/methods/Person.search diff --git a/themoviedbapi/src/com/moviejukebox/themoviedb/tools/Base64.java b/themoviedbapi/src/com/moviejukebox/themoviedb/tools/Base64.java new file mode 100644 index 000000000..e4f56aba0 --- /dev/null +++ b/themoviedbapi/src/com/moviejukebox/themoviedb/tools/Base64.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2004-2010 YAMJ Members + * http://code.google.com/p/moviejukebox/people/list + * + * Web: http://code.google.com/p/moviejukebox/ + * + * This software is licensed under a Creative Commons License + * See this page: http://code.google.com/p/moviejukebox/wiki/License + * + * For any reuse or distribution, you must make clear to others the + * license terms of this work. + */ + +package com.moviejukebox.themoviedb.tools; + +public class Base64 { + public static String base64code = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + + "abcdefghijklmnopqrstuvwxyz" + "0123456789" + "+/"; + + public static int splitLinesAt = 76; + public static String base64Encode(String string) { + + String encoded = ""; + // determine how many padding bytes to add to the output + int paddingCount = (3 - (string.length() % 3)) % 3; + // add any necessary padding to the input + string += "\0\0".substring(0, paddingCount); + // process 3 bytes at a time, churning out 4 output bytes + // worry about CRLF insertions later + for (int i = 0; i < string.length(); i += 3) { + int j = (string.charAt(i) << 16) + (string.charAt(i + 1) << 8) + string.charAt(i + 2); + encoded = encoded + base64code.charAt((j >> 18) & 0x3f) + + base64code.charAt((j >> 12) & 0x3f) + + base64code.charAt((j >> 6) & 0x3f) + + base64code.charAt(j & 0x3f); + } + // replace encoded padding nulls with "=" + // return encoded; + return "Basic " + encoded; + } +} \ No newline at end of file diff --git a/themoviedbapi/src/com/moviejukebox/themoviedb/tools/DOMHelper.java b/themoviedbapi/src/com/moviejukebox/themoviedb/tools/DOMHelper.java index ae4e5efa0..521943db6 100644 --- a/themoviedbapi/src/com/moviejukebox/themoviedb/tools/DOMHelper.java +++ b/themoviedbapi/src/com/moviejukebox/themoviedb/tools/DOMHelper.java @@ -13,10 +13,11 @@ package com.moviejukebox.themoviedb.tools; +import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; +import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; -import java.net.URL; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; @@ -64,11 +65,16 @@ public class DOMHelper { * @throws ParserConfigurationException * @throws SAXException */ - public static Document getEventDocFromUrl(String url) throws MalformedURLException, IOException, ParserConfigurationException, SAXException { - InputStream in = (new URL(url)).openStream(); + public static Document getEventDocFromUrl(String url) + throws MalformedURLException, IOException, ParserConfigurationException, SAXException, UnsupportedEncodingException { + //InputStream in = (new URL(url)).openStream(); + String webPage = WebBrowser.request(url); + InputStream in = new ByteArrayInputStream(webPage.getBytes("UTF-8")); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse(in); + doc.getDocumentElement().normalize(); return doc; } diff --git a/themoviedbapi/src/com/moviejukebox/themoviedb/tools/WebBrowser.java b/themoviedbapi/src/com/moviejukebox/themoviedb/tools/WebBrowser.java new file mode 100644 index 000000000..b9695f2ed --- /dev/null +++ b/themoviedbapi/src/com/moviejukebox/themoviedb/tools/WebBrowser.java @@ -0,0 +1,237 @@ +/* + * Copyright (c) 2004-2010 YAMJ Members + * http://code.google.com/p/moviejukebox/people/list + * + * Web: http://code.google.com/p/moviejukebox/ + * + * This software is licensed under a Creative Commons License + * See this page: http://code.google.com/p/moviejukebox/wiki/License + * + * For any reuse or distribution, you must make clear to others the + * license terms of this work. + */ + +package com.moviejukebox.themoviedb.tools; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.StringWriter; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLConnection; +import java.nio.charset.Charset; +import java.nio.charset.UnsupportedCharsetException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Web browser with simple cookies support + */ +public final class WebBrowser { + private static Map browserProperties = new HashMap(); + private static Map> cookies; + private static String proxyHost = null; + private static String proxyPort = null; + private static String proxyUsername = null; + private static String proxyPassword = null; + private static String proxyEncodedPassword = null; + + public WebBrowser() { + browserProperties.put("User-Agent", "Mozilla/5.25 Netscape/5.0 (Windows; I; Win95)"); + cookies = new HashMap>(); + } + + public static String request(String url) throws IOException { + return request(new URL(url)); + } + + public static URLConnection openProxiedConnection(URL url) throws IOException { + if (proxyHost != null) { + System.getProperties().put("proxySet", "true"); + System.getProperties().put("proxyHost", proxyHost); + System.getProperties().put("proxyPort", proxyPort); + } + + URLConnection cnx = url.openConnection(); + + if (proxyUsername != null) { + cnx.setRequestProperty("Proxy-Authorization", proxyEncodedPassword); + } + + return cnx; + } + + public static String request(URL url) throws IOException { + StringWriter content = null; + + try { + content = new StringWriter(); + + BufferedReader in = null; + URLConnection cnx = null; + try { + cnx = openProxiedConnection(url); + + sendHeader(cnx); + readHeader(cnx); + + in = new BufferedReader(new InputStreamReader(cnx.getInputStream(), getCharset(cnx))); + String line; + while ((line = in.readLine()) != null) { + content.write(line); + } + } finally { + if (in != null) { + in.close(); + } + if (cnx != null) { + if(cnx instanceof HttpURLConnection) { + ((HttpURLConnection)cnx).disconnect(); + } + } + if (cnx != null) { + if(cnx instanceof HttpURLConnection) { + ((HttpURLConnection)cnx).disconnect(); + } + } + } + return content.toString(); + } finally { + if (content != null) { + content.close(); + } + } + } + + private static void sendHeader(URLConnection cnx) { + // send browser properties + for (Map.Entry browserProperty : browserProperties.entrySet()) { + cnx.setRequestProperty(browserProperty.getKey(), browserProperty.getValue()); + } + // send cookies + String cookieHeader = createCookieHeader(cnx); + if (!cookieHeader.isEmpty()) { + cnx.setRequestProperty("Cookie", cookieHeader); + } + } + + private static String createCookieHeader(URLConnection cnx) { + String host = cnx.getURL().getHost(); + StringBuilder cookiesHeader = new StringBuilder(); + for (Map.Entry> domainCookies : cookies.entrySet()) { + if (host.endsWith(domainCookies.getKey())) { + for (Map.Entry cookie : domainCookies.getValue().entrySet()) { + cookiesHeader.append(cookie.getKey()); + cookiesHeader.append("="); + cookiesHeader.append(cookie.getValue()); + cookiesHeader.append(";"); + } + } + } + if (cookiesHeader.length() > 0) { + // remove last ; char + cookiesHeader.deleteCharAt(cookiesHeader.length() - 1); + } + return cookiesHeader.toString(); + } + + private static void readHeader(URLConnection cnx) { + // read new cookies and update our cookies + for (Map.Entry> header : cnx.getHeaderFields().entrySet()) { + if ("Set-Cookie".equals(header.getKey())) { + for (String cookieHeader : header.getValue()) { + String[] cookieElements = cookieHeader.split(" *; *"); + if (cookieElements.length >= 1) { + String[] firstElem = cookieElements[0].split(" *= *"); + String cookieName = firstElem[0]; + String cookieValue = firstElem.length > 1 ? firstElem[1] : null; + String cookieDomain = null; + // find cookie domain + for (int i = 1; i < cookieElements.length; i++) { + String[] cookieElement = cookieElements[i].split(" *= *"); + if ("domain".equals(cookieElement[0])) { + cookieDomain = cookieElement.length > 1 ? cookieElement[1] : null; + break; + } + } + if (cookieDomain == null) { + // if domain isn't set take current host + cookieDomain = cnx.getURL().getHost(); + } + Map domainCookies = cookies.get(cookieDomain); + if (domainCookies == null) { + domainCookies = new HashMap(); + cookies.put(cookieDomain, domainCookies); + } + // add or replace cookie + domainCookies.put(cookieName, cookieValue); + } + } + } + } + } + + private static Charset getCharset(URLConnection cnx) { + Charset charset = null; + // content type will be string like "text/html; charset=UTF-8" or "text/html" + String contentType = cnx.getContentType(); + if (contentType != null) { + // changed 'charset' to 'harset' in regexp because some sites send 'Charset' + Matcher m = Pattern.compile("harset *=[ '\"]*([^ ;'\"]+)[ ;'\"]*").matcher(contentType); + if (m.find()) { + String encoding = m.group(1); + try { + charset = Charset.forName(encoding); + } catch (UnsupportedCharsetException e) { + // there will be used default charset + } + } + } + if (charset == null) { + charset = Charset.defaultCharset(); + } + + return charset; + } + + public static String getProxyHost() { + return proxyHost; + } + + public static void setProxyHost(String tvdbProxyHost) { + WebBrowser.proxyHost = tvdbProxyHost; + } + + public static String getProxyPort() { + return proxyPort; + } + + public static void setProxyPort(String tvdbProxyPort) { + WebBrowser.proxyPort = tvdbProxyPort; + } + + public static String getTvdbProxyUsername() { + return proxyUsername; + } + + public static void setProxyUsername(String tvdbProxyUsername) { + WebBrowser.proxyUsername = tvdbProxyUsername; + } + + public static String getProxyPassword() { + return proxyPassword; + } + + public static void setProxyPassword(String tvdbProxyPassword) { + WebBrowser.proxyPassword = tvdbProxyPassword; + + if (proxyUsername != null) { + proxyEncodedPassword = proxyUsername + ":" + tvdbProxyPassword; + proxyEncodedPassword = Base64.base64Encode(proxyEncodedPassword); + } + } +}