/* * Jajuk * Copyright (C) The Jajuk Team * http://jajuk.info * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ package org.jajuk.util; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.Authenticator; import java.net.HttpURLConnection; import java.net.PasswordAuthentication; import java.net.Proxy.Type; import java.net.URL; import java.net.URLConnection; import java.net.URLEncoder; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.jajuk.services.core.SessionService; import org.jajuk.util.log.Log; import ext.services.network.NetworkUtils; import ext.services.network.Proxy; /** * Manages network downloads. */ public final class DownloadManager { private static Proxy proxy; private static final int BUFFER_SIZE = 8000; /** * private constructor to avoid instantiating utility class. */ private DownloadManager() { } /** * Gets the remote covers list. * * @param search * * @return a list of urls * * @throws IOException Signals that an I/O exception has occurred. */ public static List<URL> getRemoteCoversList(String search) throws IOException { List<URL> alOut = new ArrayList<URL>(20); // URL list // check void searches if (search == null || search.trim().equals("")) { return alOut; } URL url = new URL("https://www.google.com/search?q=" + URLEncoder.encode(search, "ISO-8859-1") + "&tbm=isch&biw=1092&source=lnms"); final URLConnection connection = url.openConnection(); // User-Agent is required to avoid 403 Google response connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:25.0) Gecko/20100101 Firefox/25.0"); // Retrieve response String line; final StringBuilder builder = new StringBuilder(); final BufferedReader reader = new BufferedReader( new InputStreamReader(connection.getInputStream())); while ((line = reader.readLine()) != null) { builder.append(line); } // Analyse response with a pattern to extract image url final Pattern pattern = Pattern.compile("data-src=\"https://[^ ]*\""); final Matcher matcher = pattern.matcher(builder); while (matcher.find()) { final String sUrl = matcher.group(); if (sUrl.length() > 11) { url = new URL(sUrl.substring(10, sUrl.length() - 1)); // Remove duplicates if (!alOut.contains(url)) { alOut.add(url); } } } return alOut; } /** * Download the resource at the given url. * * @param url url to download * @param fDestination destination file * * @throws IOException If a network problem occurs. */ public static void download(URL url, File fDestination) throws IOException { HttpURLConnection connection = NetworkUtils.getConnection(url, proxy); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(fDestination)); try { BufferedInputStream bis = new BufferedInputStream(connection.getInputStream()); try { int bytesRead = -1; byte[] buffer = new byte[BUFFER_SIZE]; while ((bytesRead = bis.read(buffer)) != -1) { bos.write(buffer, 0, bytesRead); } } finally { bis.close(); } bos.flush(); } finally { bos.close(); } connection.disconnect(); } /** * Download the resource at the given url and cache it <br> * If the file is already in cache, it is returned immediately <br> * * @param url url to download * * @return cached file or null if a problem occurred * * @throws IOException If a network problem occurs or a temporary file cannot be * written. */ public static File downloadToCache(URL url) throws IOException { // Drop the query if user required "none Internet access from jajuk". // This method shouldn't be called anyway because we views have to deal with // this option at their level, this is a additional control. if (Conf.getBoolean(Const.CONF_NETWORK_NONE_INTERNET_ACCESS)) { return null; } File file = SessionService.getCachePath(url); // We synchronize the (interned) name of the cached file to avoid // probable collisions between views synchronized (file.getName().intern()) { // check if file is not already downloaded or being downloaded if (file.exists() && file.length() > 0) { return file; } download(url,file); return file; } } /** * Download the cover list. * * @param url to download * @param charset * * @return result as an array of bytes, null if a problem occurred * * @throws IOException Signals that an I/O exception has occurred. */ public static String downloadText(URL url, String charset) throws IOException { // Drop the query if user required "none Internet access from jajuk". // This method shouldn't be called anyway because we views have to deal with // this option at their level, this is a additional control. if (Conf.getBoolean(Const.CONF_NETWORK_NONE_INTERNET_ACCESS)) { return null; } HttpURLConnection connection = NetworkUtils.getConnection(url, proxy); try { return NetworkUtils.readURL(connection, charset); } finally { connection.disconnect(); } } /** * Download text with the default charset UTF-8. * * @param url * * @return the string * * @throws IOException Signals that an I/O exception has occurred. */ public static String downloadText(URL url) throws IOException { return downloadText(url, "UTF-8"); } /** * Return a string for a given URL and encoding, used to retrieve text from a * cached file. * * @param url url to read * @param encoding encoding of the content of the file * * @return a string for a given URL and encoding * * @throws IOException Signals that an I/O exception has occurred. */ public static String getTextFromCachedFile(URL url, String encoding) throws IOException { // Drop the query if user required "none Internet access from jajuk". // This method shouldn't be called anyway because we views have to deal with // this option at their level, this is a additional control. if (Conf.getBoolean(Const.CONF_NETWORK_NONE_INTERNET_ACCESS)) { return null; } File file = downloadToCache(url); StringBuilder builder = new StringBuilder(); InputStream input = new BufferedInputStream(new FileInputStream(file)); try { byte[] array = new byte[1024]; int read; while ((read = input.read(array)) > 0) { builder.append(new String(array, 0, read, encoding)); } } finally { input.close(); } return builder.toString(); } /** * Set default proxy settings, used by cobra for ie. */ public synchronized static void setDefaultProxySettings() { String sProxyHost = Conf.getString(Const.CONF_NETWORK_PROXY_HOSTNAME); int iProxyPort = Conf.getInt(Const.CONF_NETWORK_PROXY_PORT); String sProxyLogin = Conf.getString(Const.CONF_NETWORK_PROXY_LOGIN); String sProxyPwd = Conf.getString(Const.CONF_NETWORK_PROXY_PWD); Type proxyType = Type.DIRECT; if (Conf.getBoolean(Const.CONF_NETWORK_USE_PROXY)) { // Set default proxy value if (Const.PROXY_TYPE_HTTP.equals(Conf.getString(Const.CONF_NETWORK_PROXY_TYPE))) { proxyType = Type.HTTP; } else if (Const.PROXY_TYPE_SOCKS.equals(Conf.getString(Const.CONF_NETWORK_PROXY_TYPE))) { proxyType = Type.SOCKS; } try { proxy = new Proxy(proxyType, sProxyHost, iProxyPort, sProxyLogin, sProxyPwd); } catch (Exception e) { Log.error(e); return; } } // Set system defaults proxy values, if we don't use DownloadManager // methods // see http://java.sun.com/j2se/1.4.2/docs/guide/net/properties.html if (Conf.getBoolean(Const.CONF_NETWORK_USE_PROXY)) { System.getProperties().put("proxySet", "true"); if (Const.PROXY_TYPE_HTTP.equals(Conf.getString(Const.CONF_NETWORK_PROXY_TYPE))) { System.setProperty("http.proxyHost", sProxyHost); System.setProperty("http.proxyPort", Integer.toString(iProxyPort)); } else if (Const.PROXY_TYPE_SOCKS.equals(Conf.getString(Const.CONF_NETWORK_PROXY_TYPE))) { System.setProperty("socksProxyHost", sProxyHost); System.setProperty("socksProxyPort ", Integer.toString(iProxyPort)); } Authenticator.setDefault(new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { String user = Conf.getString(Const.CONF_NETWORK_PROXY_LOGIN); char[] pwd = UtilString.rot13(Conf.getString(Const.CONF_NETWORK_PROXY_PWD)).toCharArray(); return new PasswordAuthentication(user, pwd); } }); } } /** * Gets the proxy. * * @return the proxy */ public static Proxy getProxy() { return proxy; } }