c5ea044f79
Ability to set log level, lots of debugging messages Turn on debug logging during tests, simplified test cases for HTML ripper Fix fusktator ripper, added test Fixed gifyo, added test Added tests for *all* rippers Adding a few album-guessing URLs
148 lines
5.7 KiB
Java
148 lines
5.7 KiB
Java
package com.rarchives.ripme.ripper;
|
|
|
|
import java.io.BufferedInputStream;
|
|
import java.io.File;
|
|
import java.io.FileOutputStream;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.io.OutputStream;
|
|
import java.net.HttpURLConnection;
|
|
import java.net.URL;
|
|
|
|
import javax.net.ssl.HttpsURLConnection;
|
|
|
|
import org.apache.log4j.Logger;
|
|
|
|
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 DownloadVideoThread extends Thread {
|
|
|
|
private static final Logger logger = Logger.getLogger(DownloadVideoThread.class);
|
|
|
|
private URL url;
|
|
private File saveAs;
|
|
private String prettySaveAs;
|
|
private AbstractRipper observer;
|
|
private int retries;
|
|
|
|
public DownloadVideoThread(URL url, File saveAs, AbstractRipper observer) {
|
|
super();
|
|
this.url = url;
|
|
this.saveAs = saveAs;
|
|
this.prettySaveAs = Utils.removeCWD(saveAs);
|
|
this.observer = observer;
|
|
this.retries = Utils.getConfigInteger("download.retries", 1);
|
|
}
|
|
|
|
/**
|
|
* Attempts to download the file. Retries as needed.
|
|
* Notifies observers upon completion/error/warn.
|
|
*/
|
|
public void run() {
|
|
try {
|
|
observer.stopCheck();
|
|
} catch (IOException e) {
|
|
observer.downloadErrored(url, "Download interrupted");
|
|
return;
|
|
}
|
|
if (saveAs.exists()) {
|
|
if (Utils.getConfigBoolean("file.overwrite", false)) {
|
|
logger.info("[!] Deleting existing file" + prettySaveAs);
|
|
saveAs.delete();
|
|
} else {
|
|
logger.info("[!] Skipping " + url + " -- file already exists: " + prettySaveAs);
|
|
observer.downloadExists(url, saveAs);
|
|
return;
|
|
}
|
|
}
|
|
|
|
int bytesTotal, bytesDownloaded = 0;
|
|
try {
|
|
bytesTotal = getTotalBytes(this.url);
|
|
} catch (IOException e) {
|
|
logger.error("Failed to get file size at " + this.url, e);
|
|
observer.downloadErrored(this.url, "Failed to get file size of " + this.url);
|
|
return;
|
|
}
|
|
observer.setBytesTotal(bytesTotal);
|
|
observer.sendUpdate(STATUS.TOTAL_BYTES, bytesTotal);
|
|
logger.debug("Size of file at " + this.url + " = " + bytesTotal + "b");
|
|
|
|
int tries = 0; // Number of attempts to download
|
|
do {
|
|
InputStream bis = null; OutputStream fos = null;
|
|
byte[] data = new byte[1024 * 256]; int bytesRead;
|
|
try {
|
|
logger.info(" Downloading file: " + url + (tries > 0 ? " Retry #" + tries : ""));
|
|
observer.sendUpdate(STATUS.DOWNLOAD_STARTED, url.toExternalForm());
|
|
|
|
// Setup HTTP request
|
|
HttpURLConnection huc;
|
|
if (this.url.toString().startsWith("https")) {
|
|
huc = (HttpsURLConnection) this.url.openConnection();
|
|
}
|
|
else {
|
|
huc = (HttpURLConnection) this.url.openConnection();
|
|
}
|
|
huc.setInstanceFollowRedirects(true);
|
|
huc.setConnectTimeout(0); // Never timeout
|
|
huc.setRequestProperty("accept", "*/*");
|
|
huc.setRequestProperty("Referer", this.url.toExternalForm()); // Sic
|
|
huc.setRequestProperty("User-agent", AbstractRipper.USER_AGENT);
|
|
tries += 1;
|
|
logger.debug("Request properties: " + huc.getRequestProperties().toString());
|
|
huc.connect();
|
|
// Check status code
|
|
bis = new BufferedInputStream(huc.getInputStream());
|
|
fos = new FileOutputStream(saveAs);
|
|
while ( (bytesRead = bis.read(data)) != -1) {
|
|
try {
|
|
observer.stopCheck();
|
|
} catch (IOException e) {
|
|
observer.downloadErrored(url, "Download interrupted");
|
|
return;
|
|
}
|
|
fos.write(data, 0, bytesRead);
|
|
bytesDownloaded += bytesRead;
|
|
observer.setBytesCompleted(bytesDownloaded);
|
|
observer.sendUpdate(STATUS.COMPLETED_BYTES, bytesDownloaded);
|
|
}
|
|
bis.close();
|
|
fos.close();
|
|
break; // Download successful: break out of infinite loop
|
|
} catch (IOException e) {
|
|
logger.error("[!] Exception while downloading file: " + url + " - " + e.getMessage(), e);
|
|
} finally {
|
|
// Close any open streams
|
|
try {
|
|
if (bis != null) { bis.close(); }
|
|
} catch (IOException e) { }
|
|
try {
|
|
if (fos != null) { fos.close(); }
|
|
} catch (IOException e) { }
|
|
}
|
|
if (tries > this.retries) {
|
|
logger.error("[!] Exceeded maximum retries (" + this.retries + ") for URL " + url);
|
|
observer.downloadErrored(url, "Failed to download " + url.toExternalForm());
|
|
return;
|
|
}
|
|
} while (true);
|
|
observer.downloadCompleted(url, saveAs);
|
|
logger.info("[+] Saved " + url + " as " + this.prettySaveAs);
|
|
}
|
|
|
|
private int getTotalBytes(URL url) throws IOException {
|
|
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
|
conn.setRequestMethod("HEAD");
|
|
conn.setRequestProperty("accept", "*/*");
|
|
conn.setRequestProperty("Referer", this.url.toExternalForm()); // Sic
|
|
conn.setRequestProperty("User-agent", AbstractRipper.USER_AGENT);
|
|
return conn.getContentLength();
|
|
}
|
|
|
|
} |