Skip to content

Commit

Permalink
Major new functionality
Browse files Browse the repository at this point in the history
Featues
- Added http file downloader, integrated into TVRageProvider
- Implemented 'check for updates' and preference option

Code changes
- FINALLY made preferences static (yay!)
- Renaming of many UIStarter variables to conform to nameType
- Moved string handling into StringUtils
- Updated tests
  • Loading branch information
daveharris committed Feb 28, 2011
1 parent 5c0dd4a commit f594066
Show file tree
Hide file tree
Showing 17 changed files with 461 additions and 293 deletions.
Binary file added lib/mockito-all-1.8.5.jar
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package com.google.code.tvrenamer.controller;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.GZIPInputStream;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;

import com.google.code.tvrenamer.controller.util.StringUtils;

public class HttpConnectionHandler {
private static Logger logger = Logger.getLogger(HttpConnectionHandler.class.getName());
private static final int CONNECT_TIMEOUT_MS = 2000;
private static final int READ_TIMEOUT_MS = 5000;

/**
* Download the URL and return as a String
* @param urlString the URL as a String
* @return String of the contents
*/
public String downloadUrl(String urlString) {
try {
return downloadUrl(new URL(urlString));
} catch (MalformedURLException e) {
logger.log(Level.SEVERE, urlString + " is not a valid URL ", e);
return "";
}
}

/**
* Download the URL and return as a String.
* Gzip handling from http://goo.gl/J88WG
*
* @param url
* the URL to download
* @return String of the URL contents
* @throws IOException
* when there is an error connecting or reading the URL
*/
public String downloadUrl(URL url) {
InputStream inputStream = null;
StringBuilder contents = new StringBuilder();

try {
if (url != null) {
logger.info("Downloading URL " + url.toString());

HttpURLConnection conn = (HttpURLConnection) url.openConnection();

HttpURLConnection.setFollowRedirects(true);
// allow both GZip and Deflate (ZLib) encodings
conn.setRequestProperty("Accept-Encoding", "gzip, deflate");
conn.setConnectTimeout(CONNECT_TIMEOUT_MS);
conn.setReadTimeout(READ_TIMEOUT_MS);

// create the appropriate stream wrapper based on the encoding type
String encoding = conn.getContentEncoding();
if (encoding != null && encoding.equalsIgnoreCase("gzip")) {
inputStream = new GZIPInputStream(conn.getInputStream());
} else if (encoding != null && encoding.equalsIgnoreCase("deflate")) {
inputStream = new InflaterInputStream(conn.getInputStream(), new Inflater(true));
} else {
inputStream = conn.getInputStream();
}

BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));

logger.finer("Before reading url stream");

String s;
while ((s = reader.readLine()) != null) {
contents.append(s);
}

if (logger.isLoggable(Level.FINEST)) {
logger.finest("Url stream:\n" + StringUtils.encodeSpecialCharacters(contents.toString()));
}
}
} catch (Exception e) {
logger.log(Level.SEVERE, "Exception when attempting to download and parse URL " + url, e);
} finally {
try {
if(inputStream != null) {
inputStream.close();
}
} catch (IOException e) {
logger.log(Level.SEVERE, "Exception when attempting to close input stream", e);
}
}

return StringUtils.encodeSpecialCharacters(contents.toString());
}
}
55 changes: 9 additions & 46 deletions src/main/com/google/code/tvrenamer/controller/TVRageProvider.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
package com.google.code.tvrenamer.controller;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.net.ConnectException;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.logging.Level;
Expand All @@ -23,6 +19,7 @@
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import com.google.code.tvrenamer.controller.util.StringUtils;
import com.google.code.tvrenamer.model.Season;
import com.google.code.tvrenamer.model.Show;

Expand Down Expand Up @@ -67,34 +64,17 @@ private TVRageProvider() {
*/
public static ArrayList<Show> getShowOptions(String showName) throws ConnectException, UnknownHostException {
ArrayList<Show> options = new ArrayList<Show>();
showName = showName.replaceAll(" ", "%20");
String searchURL = BASE_SEARCH_URL + showName;
String searchURL = BASE_SEARCH_URL + StringUtils.encodeSpecialCharacters(showName);

try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

URL url = new URL(searchURL);

logger.info("About to retrieve search results from " + url.toString());

InputStream inputStream = url.openStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));

logger.finer("Before encoding XML");

String s;
String xml = "";
while ((s = reader.readLine()) != null) {
if (logger.isLoggable(Level.FINEST)) {
logger.finest(s);
}
xml += encodeSpecialCharacters(s);
}

logger.finest("xml:\n" + xml);
logger.info("About to retrieve search results from " + searchURL);

String searchXml = new HttpConnectionHandler().downloadUrl(searchURL);

DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new InputSource(new StringReader(xml)));
Document doc = db.parse(new InputSource(new StringReader(searchXml)));

XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();
Expand Down Expand Up @@ -141,8 +121,10 @@ public static void getShowListing(Show show) {

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
String showXml = new HttpConnectionHandler().downloadUrl(showURL);

DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(showURL);
Document doc = db.parse(new InputSource(new StringReader(showXml)));
XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();

Expand Down Expand Up @@ -172,23 +154,4 @@ public static void getShowListing(Show show) {
logger.log(Level.WARNING, "Caught exception when attempting to parse show detail xml", e);
}
}

/**
* Replaces unsafe HTML Characters with HTML Entities
*
* @param input
* string to encode
* @return HTML safe representation of input
*/
private static String encodeSpecialCharacters(String input) {
if (input == null || input.length() == 0) {
return "";
}

// TODO: determine other characters that need to be replaced (eg "'", "-")
logger.finest("Input before encoding: [" + input + "]");
input = input.replaceAll("& ", "&amp; ");
logger.finest("Input after encoding: [" + input + "]");
return input;
}
}
27 changes: 27 additions & 0 deletions src/main/com/google/code/tvrenamer/controller/UpdateChecker.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.google.code.tvrenamer.controller;

import java.util.logging.Logger;

import com.google.code.tvrenamer.model.util.Constants;

public class UpdateChecker {
private static Logger logger = Logger.getLogger(UpdateChecker.class.getName());

private static final String VERSION_URL = "http://r.ac.nz/tvrenamer.version";

/**
* Checks if a newer version is available.
* @return the new version number as a string if available, empty string if no new version or null if an error has occurred
*/
public static boolean isUpdateAvailable() {
String latestVersion = new HttpConnectionHandler().downloadUrl(VERSION_URL);

boolean newVersionAvailable = latestVersion.compareToIgnoreCase(Constants.VERSION_NUMBER) > 0;

if (newVersionAvailable) {
logger.info("There is a new version available, running " + Constants.VERSION_NUMBER + ", new version is " + latestVersion);
return true;
}
return false;
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.google.code.tvrenamer.view;
package com.google.code.tvrenamer.controller;

public interface UpdateCompleteHandler {
void onUpdateComplete();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.google.code.tvrenamer.model;
package com.google.code.tvrenamer.controller;

/**
* Represents a change event of user preferences
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,28 @@
package com.google.code.tvrenamer.model;
package com.google.code.tvrenamer.controller;

import java.util.Observable;
import java.util.Observer;
import java.util.logging.Logger;

import com.google.code.tvrenamer.model.UserPreferences;
import com.google.code.tvrenamer.view.UIStarter;

public class UserPreferencesListener implements Observer {
private static Logger logger = Logger.getLogger(UserPreferencesListener.class.getName());
public class UserPreferencesChangeListener implements Observer {
private static Logger logger = Logger.getLogger(UserPreferencesChangeListener.class.getName());

/* (non-Javadoc)
* @see java.util.Observer#update(java.util.Observable, java.lang.Object)
*/
public void update(Observable observable, Object value) {
logger.info("Preference change for: " + observable + ", " + value);
logger.info("Preference change event: " + value);

if(observable instanceof UserPreferences && value instanceof UserPreferencesChangeEvent) {
UserPreferences preferences = (UserPreferences) observable;
UserPreferencesChangeEvent upce = (UserPreferencesChangeEvent) value;

if(upce.getPreference().equals("moveEnabled")) {
UIStarter.setRenameButtonText();
UIStarter.setColumnDestText();
} else if(upce.getPreference().equals("proxy")) {
preferences.getProxy().apply();
}
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public static UserPreferences retrieve(File file) {
} catch (FileNotFoundException e) {
// If file doesn't exist, assume defaults
logger.log(Level.FINER, "Preferences file '" + file.getAbsolutePath() + "' does not exist - assuming defaults");
preferences = new UserPreferences();
preferences = UserPreferences.getInstance();
}

return preferences;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.google.code.tvrenamer.controller.util;

import java.util.logging.Logger;

public class StringUtils {
private static Logger logger = Logger.getLogger(StringUtils.class.getName());

public static String sanitiseTitle(String title) {
// need to add more mappings, such as ':'
Expand All @@ -22,5 +25,28 @@ public static String getExtension(String filename) {
int dot = filename.lastIndexOf('.');
return filename.substring(dot + 1);
}

/**
* Replaces unsafe HTML Characters with HTML Entities
*
* @param input
* string to encode
* @return HTML safe representation of input
*/
public static String encodeSpecialCharacters(String input) {
if (input == null || input.length() == 0) {
return "";
}

// TODO: determine other characters that need to be replaced (eg "'", "-")
logger.finest("Input before encoding: [" + input + "]");
input = input.replaceAll("& ", "&amp; ");

// Don't encode string within xml data strings
if(!input.startsWith("<?xml")) {
input = input.replaceAll(" ", "%20");
}
logger.finest("Input after encoding: [" + input + "]");
return input;
}
}

0 comments on commit f594066

Please sign in to comment.