Document *all* the things
This commit is contained in:
parent
8b7e471b1c
commit
43948fd320
@ -32,7 +32,6 @@ public abstract class AbstractRipper
|
||||
protected DownloadThreadPool threadPool;
|
||||
protected Observer observer = null;
|
||||
|
||||
protected int itemsTotal;
|
||||
protected Map<URL, File> itemsPending = new HashMap<URL, File>();
|
||||
protected Map<URL, File> itemsCompleted = new HashMap<URL, File>();
|
||||
protected Map<URL, String> itemsErrored = new HashMap<URL, String>();
|
||||
@ -107,6 +106,15 @@ public abstract class AbstractRipper
|
||||
threadPool.addThread(new DownloadFileThread(url, saveAs, this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Queues file to be downloaded and saved. With options.
|
||||
* @param url
|
||||
* URL to download.
|
||||
* @param prefix
|
||||
* Prefix to prepend to the saved filename.
|
||||
* @param subdirectory
|
||||
* Sub-directory of the working directory to save the images to.
|
||||
*/
|
||||
public void addURLToDownload(URL url, String prefix, String subdirectory) {
|
||||
String saveAs = url.toExternalForm();
|
||||
saveAs = saveAs.substring(saveAs.lastIndexOf('/')+1);
|
||||
@ -137,17 +145,32 @@ public abstract class AbstractRipper
|
||||
addURLToDownload(url, saveFileAs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for downloading threads to complete.
|
||||
*/
|
||||
protected void waitForThreads() {
|
||||
completed = false;
|
||||
threadPool.waitForThreads();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies observers that source is being retrieved.
|
||||
* @param url
|
||||
* URL being retrieved
|
||||
*/
|
||||
public void retrievingSource(URL url) {
|
||||
RipStatusMessage msg = new RipStatusMessage(STATUS.LOADING_RESOURCE, url);
|
||||
observer.update(this, msg);
|
||||
observer.notifyAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies observers that a file download has completed.
|
||||
* @param url
|
||||
* URL that was completed.
|
||||
* @param saveAs
|
||||
* Where the downloaded file is stored.
|
||||
*/
|
||||
public void downloadCompleted(URL url, File saveAs) {
|
||||
if (observer == null) {
|
||||
return;
|
||||
@ -167,6 +190,11 @@ public abstract class AbstractRipper
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies observers that a file could not be downloaded (includes a reason).
|
||||
* @param url
|
||||
* @param reason
|
||||
*/
|
||||
public void downloadErrored(URL url, String reason) {
|
||||
if (observer == null) {
|
||||
return;
|
||||
@ -180,6 +208,12 @@ public abstract class AbstractRipper
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify observers that a download could not be completed,
|
||||
* but was not technically an "error".
|
||||
* @param url
|
||||
* @param message
|
||||
*/
|
||||
public void downloadProblem(URL url, String message) {
|
||||
if (observer == null) {
|
||||
return;
|
||||
@ -193,6 +227,9 @@ public abstract class AbstractRipper
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies observers and updates state if all files have been ripped.
|
||||
*/
|
||||
private void checkIfComplete() {
|
||||
if (!completed && itemsPending.size() == 0) {
|
||||
completed = true;
|
||||
@ -209,10 +246,20 @@ public abstract class AbstractRipper
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* Path to the directory in which all files
|
||||
* ripped via this ripper will be stored.
|
||||
*/
|
||||
public File getWorkingDir() {
|
||||
return workingDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets directory to save all ripped files to.
|
||||
* @param url
|
||||
* URL to define how the workin directory should be saved.
|
||||
*/
|
||||
public void setWorkingDir(URL url) throws IOException {
|
||||
String path = Utils.getWorkingDirectory().getCanonicalPath();
|
||||
if (!path.endsWith(File.separator)) {
|
||||
@ -243,12 +290,16 @@ public abstract class AbstractRipper
|
||||
return ripper;
|
||||
} catch (Exception e) {
|
||||
// Incompatible rippers *will* throw exceptions during instantiation.
|
||||
//logger.error("Exception while instantiating: " + constructor.getName(), e);
|
||||
}
|
||||
}
|
||||
throw new Exception("No compatible ripper found");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* List of constructors for all eligible Rippers.
|
||||
* @throws Exception
|
||||
*/
|
||||
private static List<Constructor<?>> getRipperConstructors() throws Exception {
|
||||
List<Constructor<?>> constructors = new ArrayList<Constructor<?>>();
|
||||
for (Class<?> clazz : Utils.getClassesForPackage("com.rarchives.ripme.ripper.rippers")) {
|
||||
@ -259,6 +310,11 @@ public abstract class AbstractRipper
|
||||
return constructors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an update message to the relevant observer(s) on this ripper.
|
||||
* @param status
|
||||
* @param message
|
||||
*/
|
||||
public void sendUpdate(STATUS status, Object message) {
|
||||
if (observer == null) {
|
||||
return;
|
||||
@ -269,11 +325,19 @@ public abstract class AbstractRipper
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* Integer between 0 and 100 defining the progress of the album rip.
|
||||
*/
|
||||
public int getCompletionPercentage() {
|
||||
double total = itemsPending.size() + itemsErrored.size() + itemsCompleted.size();
|
||||
return (int) (100 * ( (total - itemsPending.size()) / total));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* Human-readable information on the status of the current rip.
|
||||
*/
|
||||
public String getStatusText() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(getCompletionPercentage())
|
||||
@ -284,6 +348,9 @@ public abstract class AbstractRipper
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Rips the album when the thread is invoked.
|
||||
*/
|
||||
public void run() {
|
||||
try {
|
||||
rip();
|
||||
|
@ -12,6 +12,10 @@ import org.jsoup.Jsoup;
|
||||
import com.rarchives.ripme.ui.RipStatusMessage.STATUS;
|
||||
import com.rarchives.ripme.utils.Utils;
|
||||
|
||||
/**
|
||||
* Thread for downloading files.
|
||||
* Includes retry logic, observer notifications, and other goodies.
|
||||
*/
|
||||
public class DownloadFileThread extends Thread {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(DownloadFileThread.class);
|
||||
@ -31,8 +35,11 @@ public class DownloadFileThread extends Thread {
|
||||
this.retries = Utils.getConfigInteger("download.retries", 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to download the file. Retries as needed.
|
||||
* Notifies observers upon completion/error/warn.
|
||||
*/
|
||||
public void run() {
|
||||
// Check if file already exists
|
||||
if (saveAs.exists()) {
|
||||
if (Utils.getConfigBoolean("file.overwrite", false)) {
|
||||
logger.info("[!] Deleting existing file" + prettySaveAs);
|
||||
|
@ -8,6 +8,9 @@ import org.apache.log4j.Logger;
|
||||
|
||||
import com.rarchives.ripme.utils.Utils;
|
||||
|
||||
/**
|
||||
* Simple wrapper around a FixedThreadPool.
|
||||
*/
|
||||
public class DownloadThreadPool {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(DownloadThreadPool.class);
|
||||
@ -34,9 +37,10 @@ public class DownloadThreadPool {
|
||||
public void waitForThreads() {
|
||||
threadPool.shutdown();
|
||||
try {
|
||||
threadPool.awaitTermination(60, TimeUnit.SECONDS);
|
||||
// XXX What if some rips take longer than 120 seconds to complete?
|
||||
threadPool.awaitTermination(120, TimeUnit.SECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
logger.error("Interrupted while waiting for threads to finish: ", e);
|
||||
logger.error("[!] Interrupted while waiting for threads to finish: ", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,10 @@ import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* I have no idea why I made this interface. Everything is captured within the AbstractRipper.
|
||||
* Oh well, here's to encapsulation and abstraction! (raises glass)
|
||||
*/
|
||||
public interface RipperInterface {
|
||||
public void rip() throws IOException;
|
||||
public boolean canRip(URL url);
|
||||
|
@ -43,6 +43,9 @@ import org.apache.log4j.Logger;
|
||||
import com.rarchives.ripme.ripper.AbstractRipper;
|
||||
import com.rarchives.ripme.utils.Utils;
|
||||
|
||||
/**
|
||||
* Everything UI-related starts and ends here.
|
||||
*/
|
||||
public class MainWindow implements Runnable {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(MainWindow.class);
|
||||
|
@ -1,5 +1,8 @@
|
||||
package com.rarchives.ripme.ui;
|
||||
|
||||
/**
|
||||
* Contains information about downloaded files and rips, and their states.
|
||||
*/
|
||||
public class RipStatusMessage {
|
||||
|
||||
public enum STATUS {
|
||||
|
@ -14,9 +14,12 @@ import org.apache.commons.configuration.ConfigurationException;
|
||||
import org.apache.commons.configuration.PropertiesConfiguration;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
/**
|
||||
* Common utility functions used in various places throughout the project.
|
||||
*/
|
||||
public class Utils {
|
||||
|
||||
public static final String RIP_DIRECTORY = "rips";
|
||||
public static final String RIP_DIRECTORY = "rips";
|
||||
private static final File configFile = new File("src/main/resources/rip.properties");
|
||||
private static final Logger logger = Logger.getLogger(Utils.class);
|
||||
|
||||
@ -29,6 +32,12 @@ public class Utils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the root rips directory.
|
||||
* @return
|
||||
* Root directory to save rips to.
|
||||
* @throws IOException
|
||||
*/
|
||||
public static File getWorkingDirectory() throws IOException {
|
||||
String path = new File(".").getCanonicalPath() + File.separator;
|
||||
path += RIP_DIRECTORY + File.separator;
|
||||
@ -75,10 +84,25 @@ public class Utils {
|
||||
return prettySaveAs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the current working directory from a given filename
|
||||
* @param file
|
||||
* @return
|
||||
* 'file' without the leading current working directory
|
||||
*/
|
||||
public static String removeCWD(String file) {
|
||||
return removeCWD(new File(file));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of all Classes within a package.
|
||||
* Works with file system projects and jar files!
|
||||
* Borrowed from StackOverflow, but I don't have a link :[
|
||||
* @param pkgname
|
||||
* The name of the package
|
||||
* @return
|
||||
* List of classes within the package
|
||||
*/
|
||||
public static ArrayList<Class<?>> getClassesForPackage(String pkgname) {
|
||||
ArrayList<Class<?>> classes = new ArrayList<Class<?>>();
|
||||
String relPath = pkgname.replace('.', '/');
|
||||
|
Loading…
Reference in New Issue
Block a user