2011-03-12 17:44:54 -05:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2011 moparisthebest
|
|
|
|
*
|
|
|
|
* 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 3 of the License, or
|
|
|
|
* (at your option) 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, see <http://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
* Official forums are http://www.moparscape.org/smf/
|
|
|
|
* Email me at admin@moparisthebest.com , I read it but don't usually respond.
|
|
|
|
*/
|
|
|
|
|
|
|
|
package org.moparscape.res.impl;
|
|
|
|
|
|
|
|
import org.moparscape.res.ChecksumInputStream;
|
2011-03-15 02:51:04 -04:00
|
|
|
import org.moparscape.res.DownloadListener;
|
2011-03-12 17:44:54 -05:00
|
|
|
|
|
|
|
import javax.swing.*;
|
|
|
|
import java.awt.*;
|
|
|
|
import java.io.*;
|
|
|
|
import java.util.zip.*;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Created by IntelliJ IDEA.
|
|
|
|
* User: mopar
|
|
|
|
* Date: 3/12/11
|
|
|
|
* Time: 3:16 PM
|
|
|
|
* To change this template use File | Settings | File Templates.
|
|
|
|
*/
|
|
|
|
public abstract class Downloader {
|
|
|
|
|
2011-03-15 02:51:04 -04:00
|
|
|
public abstract void download(String url, String savePath, DownloadListener callback);
|
2011-03-12 17:44:54 -05:00
|
|
|
|
2011-03-15 02:51:04 -04:00
|
|
|
/**
|
|
|
|
* Downloads resource specified by url to savePath.
|
|
|
|
*
|
|
|
|
* @param url This can be any URL Java can natively handle, in addition to magnet links, and torrent files both locally and at http and https URLs.
|
|
|
|
* @param savePath Directory to save the URL to.
|
|
|
|
* @throws IOException Passed from calls this method makes.
|
|
|
|
|
|
|
|
public static void download(String url, String savePath) throws IOException {
|
|
|
|
download(url, savePath, false);
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
/**
|
|
|
|
* Downloads resource specified by url to savePath, then extracts the downloaded file. Current supported types are .zip.gz, .zip, and .gz.
|
|
|
|
*
|
|
|
|
* @param url This can be any URL Java can natively handle, in addition to magnet links, and torrent files both locally and at http and https URLs.
|
|
|
|
* @param savePath Directory to save the URL to, and extract the supported files to.
|
|
|
|
* @throws IOException Passed from calls this method makes.
|
|
|
|
*/
|
|
|
|
/* public static void downloadExtract(String url, String savePath) throws IOException {
|
|
|
|
download(url, savePath, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void download(String url, String savePath, boolean extract) throws IOException {
|
|
|
|
if (isTorrent(url)) {
|
|
|
|
|
|
|
|
} else {
|
|
|
|
String toExtract = "";//new HTTPDownloader.download(url, savePath);
|
|
|
|
if (extract)
|
|
|
|
extractFile(toExtract, savePath);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*/
|
2011-03-12 17:44:54 -05:00
|
|
|
protected static void writeStream(InputStream in, OutputStream out) throws IOException {
|
|
|
|
byte[] buffer = new byte[1024];
|
|
|
|
int len;
|
|
|
|
while ((len = in.read(buffer)) >= 0) {
|
|
|
|
out.write(buffer, 0, len);
|
|
|
|
}
|
|
|
|
// if its a ZipInputStream we don't want to close it
|
|
|
|
if (!(in instanceof ZipInputStream))
|
|
|
|
in.close();
|
|
|
|
out.close();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Currently supports .zip, .gz, and .zip.gz
|
|
|
|
*
|
|
|
|
* @param fileName
|
|
|
|
* @param savePath
|
|
|
|
* @throws IOException
|
|
|
|
*/
|
2011-03-15 02:51:04 -04:00
|
|
|
public static void extractFile(String fileName, String savePath, DownloadListener callback) {
|
2011-03-12 17:44:54 -05:00
|
|
|
File file = new File(fileName);
|
2011-03-15 02:51:04 -04:00
|
|
|
try {
|
|
|
|
long length = file.length();
|
2011-03-12 17:44:54 -05:00
|
|
|
|
2011-03-15 02:51:04 -04:00
|
|
|
InputStream is = new FileInputStream(file);
|
|
|
|
if (callback != null) {
|
|
|
|
callback.extracting("Extracting " + fileName, length, "to " + savePath + "...");
|
|
|
|
is = new ProgressInputStream(is, callback);
|
|
|
|
}
|
2011-03-12 17:44:54 -05:00
|
|
|
|
2011-03-15 02:51:04 -04:00
|
|
|
if (fileName.endsWith(".zip.gz"))
|
|
|
|
is = new GZIPInputStream(is);
|
|
|
|
else if (fileName.endsWith(".gz")) {
|
|
|
|
// strip .gz off the end
|
|
|
|
fileName = file.getName();
|
|
|
|
fileName = fileName.substring(0, fileName.length() - 3);
|
|
|
|
if (badExtension(fileName))
|
|
|
|
return;
|
|
|
|
if (callback != null)
|
|
|
|
callback.setInfo("Extracting File: " + fileName);
|
|
|
|
writeStream(new GZIPInputStream(is), new FileOutputStream(savePath + fileName));
|
|
|
|
return;
|
|
|
|
} else if (fileName.endsWith(".zip")) {
|
|
|
|
// if we are here, the streams are all set up to unzip below, so don't do anything
|
|
|
|
} else {
|
|
|
|
// otherwise this file can't be extracted, so just return for now
|
|
|
|
if (callback != null)
|
|
|
|
callback.error("Extraction of this file type is unsupported: " + fileName);
|
2011-03-12 17:44:54 -05:00
|
|
|
return;
|
|
|
|
}
|
2011-03-15 02:51:04 -04:00
|
|
|
ZipInputStream zin = new ZipInputStream(is);
|
|
|
|
ZipEntry entry;
|
|
|
|
while ((entry = zin.getNextEntry()) != null) {
|
|
|
|
String name = entry.getName();
|
|
|
|
if (entry.isDirectory()) { // Checks if the entry is a directory.
|
|
|
|
File folder = new File(savePath + name);
|
|
|
|
deleteDirectory(folder);
|
|
|
|
if (callback != null)
|
|
|
|
callback.setInfo("Creating Directory: " + name);
|
|
|
|
folder.mkdir();
|
|
|
|
} else {// If the entry isn't a directory, then it should be a file?
|
|
|
|
if (badExtension(entry.getName()))
|
|
|
|
continue;
|
|
|
|
if (callback != null)
|
|
|
|
callback.setInfo("Extracting File: " + name);
|
|
|
|
writeStream(zin, new FileOutputStream(savePath + name));
|
2011-03-12 17:44:54 -05:00
|
|
|
}
|
2011-03-15 02:51:04 -04:00
|
|
|
try{ Thread.sleep(1000); }catch(InterruptedException e){ e.printStackTrace(); }
|
2011-03-12 17:44:54 -05:00
|
|
|
}
|
2011-03-15 02:51:04 -04:00
|
|
|
zin.close();
|
|
|
|
} catch (IOException e) {
|
|
|
|
if (callback != null)
|
|
|
|
callback.error("Extraction of this file failed: " + file.getAbsolutePath());
|
2011-03-12 17:44:54 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This function recursively checksums an entire directory, optionally applying a whitelist or a blacklist
|
|
|
|
*
|
|
|
|
* @param savePath
|
|
|
|
* @param cs
|
|
|
|
* @param list
|
|
|
|
* @param whitelist true if whitelist, false if blacklist.
|
|
|
|
* @return
|
|
|
|
*/
|
|
|
|
public static long checksum(String savePath, Checksum cs, String[] list, final boolean whitelist) {
|
2011-03-15 02:51:04 -04:00
|
|
|
if (!savePath.endsWith("/"))
|
|
|
|
savePath += "/";
|
|
|
|
if (cs == null)
|
2011-03-12 17:44:54 -05:00
|
|
|
cs = new CRC32();
|
|
|
|
FileFilter ff = null;
|
|
|
|
if (list != null) {
|
|
|
|
final File[] flist = new File[list.length];
|
|
|
|
for (int x = 0; x < list.length; ++x)
|
2011-03-15 02:51:04 -04:00
|
|
|
flist[x] = new File(savePath + list[x]);
|
2011-03-12 17:44:54 -05:00
|
|
|
ff = new FileFilter() {
|
2011-03-15 02:51:04 -04:00
|
|
|
public boolean accept(File name) {
|
|
|
|
for (File f : flist)
|
|
|
|
if (f.equals(name))
|
|
|
|
return whitelist;
|
|
|
|
return !whitelist;
|
|
|
|
}
|
|
|
|
};
|
2011-03-12 17:44:54 -05:00
|
|
|
}
|
|
|
|
recursiveChecksum(new File(savePath), cs, new NullOutputStream(), ff);
|
|
|
|
return cs.getValue();
|
|
|
|
}
|
|
|
|
|
|
|
|
private static void recursiveChecksum(File path, Checksum cs, NullOutputStream nos, FileFilter filter) {
|
|
|
|
if (!path.exists())
|
|
|
|
return;
|
|
|
|
for (File file : path.listFiles(filter)) {
|
2011-03-15 02:51:04 -04:00
|
|
|
System.out.println("Checksum so far: " + cs.getValue());
|
|
|
|
System.out.println("Checking filename: " + file.getAbsolutePath());
|
2011-03-12 17:44:54 -05:00
|
|
|
if (file.isDirectory()) {
|
|
|
|
recursiveChecksum(file, cs, nos, filter);
|
|
|
|
} else {
|
|
|
|
try {
|
|
|
|
writeStream(new ChecksumInputStream(new FileInputStream(file), cs), nos);
|
|
|
|
} catch (Exception e) {
|
|
|
|
// if there is an exception, just ignore it
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected static boolean deleteDirectory(File path) {
|
|
|
|
if (path.exists()) {
|
|
|
|
File[] files = path.listFiles();
|
|
|
|
for (int i = 0; i < files.length; i++) {
|
|
|
|
if (files[i].isDirectory()) {
|
|
|
|
deleteDirectory(files[i]);
|
|
|
|
} else {
|
|
|
|
files[i].delete();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return (path.delete());
|
|
|
|
}
|
|
|
|
|
|
|
|
protected static boolean badExtension(String file) {
|
|
|
|
String[] badExts = new String[]{".exe", ".bat", ".cmd", ".com", ".sh", ".bash"};
|
|
|
|
for (String badExt : badExts)
|
|
|
|
if (file.endsWith(badExt))
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Reports whether a url describes a torrent or not.
|
|
|
|
*
|
|
|
|
* @param url URL to resource.
|
|
|
|
* @return true if this is a torrent, false otherwise.
|
|
|
|
*/
|
|
|
|
protected static boolean isTorrent(String url) {
|
|
|
|
return url.startsWith("magnet:") || url.endsWith(".torrent");
|
|
|
|
}
|
|
|
|
|
|
|
|
protected static class ProgressFrame {
|
|
|
|
|
|
|
|
private enum Type {
|
|
|
|
HTTP, TORRENT, EXTRACT
|
|
|
|
}
|
|
|
|
|
|
|
|
JFrame dlFrame = null;
|
|
|
|
JProgressBar progressBar = null;
|
|
|
|
JLabel bottom = null;
|
|
|
|
|
|
|
|
String bottomLabel = null;
|
|
|
|
|
|
|
|
public ProgressFrame(String url, String savePath, long length, Type pType) {
|
|
|
|
String title, topLabel;
|
|
|
|
switch (pType) {
|
|
|
|
case HTTP:
|
|
|
|
title = "HTTP Download Progress";
|
|
|
|
topLabel = "Downloading " + url;
|
|
|
|
bottomLabel = "to " + savePath + "...";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TORRENT:
|
|
|
|
title = "Torrent Download Progress";
|
|
|
|
topLabel = "Downloading " + url;
|
|
|
|
bottomLabel = "to " + savePath + "...";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EXTRACT:
|
|
|
|
title = "Extraction Progress";
|
|
|
|
topLabel = "Extracting " + url;
|
|
|
|
bottomLabel = "to " + savePath + "...";
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
throw new RuntimeException("Unknown Progress Type.");
|
|
|
|
}
|
|
|
|
|
|
|
|
dlFrame = new JFrame(title);
|
|
|
|
dlFrame.setLayout(new BorderLayout());
|
|
|
|
progressBar = new JProgressBar(0, (int) length);
|
|
|
|
progressBar.setValue(0);
|
|
|
|
progressBar.setStringPainted(true);
|
|
|
|
dlFrame.getContentPane().add(new JLabel(topLabel), BorderLayout.NORTH);
|
|
|
|
dlFrame.getContentPane().add(progressBar, BorderLayout.CENTER);
|
|
|
|
dlFrame.getContentPane().add(bottom = new JLabel(bottomLabel), BorderLayout.SOUTH);
|
|
|
|
|
|
|
|
dlFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
|
|
|
|
dlFrame.setResizable(false);
|
|
|
|
dlFrame.pack();
|
|
|
|
// sets the frame to appear in the middle of the screen
|
|
|
|
// when called after pack()
|
|
|
|
dlFrame.setLocationRelativeTo(null);
|
|
|
|
dlFrame.setVisible(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
public ProgressFrame(String url, String savePath, long length) {
|
|
|
|
this(url, savePath, length, Type.HTTP);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void dispose() {
|
|
|
|
dlFrame.dispose();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void addProgress(int progress) {
|
|
|
|
progressBar.setValue(progressBar.getValue() + progress);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setProgress(int progress) {
|
|
|
|
progressBar.setValue(progress);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setText(String text) {
|
|
|
|
bottom.setText("<html>" + bottomLabel + "<hr>" + text + "</html>");
|
|
|
|
dlFrame.pack();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
protected static class ProgressInputStream extends FilterInputStream {
|
|
|
|
|
2011-03-15 02:51:04 -04:00
|
|
|
private DownloadListener dl = null;
|
2011-03-12 17:44:54 -05:00
|
|
|
|
2011-03-15 02:51:04 -04:00
|
|
|
protected ProgressInputStream(InputStream in, DownloadListener dl) {
|
2011-03-12 17:44:54 -05:00
|
|
|
super(in);
|
2011-03-15 02:51:04 -04:00
|
|
|
this.dl = dl;
|
2011-03-12 17:44:54 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int read() throws IOException {
|
|
|
|
int byteValue = super.read();
|
2011-03-15 02:51:04 -04:00
|
|
|
if (byteValue != -1) dl.incrementProgress(1);
|
2011-03-12 17:44:54 -05:00
|
|
|
return byteValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int read(byte[] b) throws IOException {
|
|
|
|
int bytesRead = super.read(b);
|
2011-03-15 02:51:04 -04:00
|
|
|
if (bytesRead != -1) dl.incrementProgress(bytesRead);
|
2011-03-12 17:44:54 -05:00
|
|
|
return bytesRead;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int read(byte[] b, int off, int len) throws IOException {
|
|
|
|
int bytesRead = super.read(b, off, len);
|
2011-03-15 02:51:04 -04:00
|
|
|
if (bytesRead != -1) dl.incrementProgress(bytesRead);
|
2011-03-12 17:44:54 -05:00
|
|
|
return bytesRead;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void close() throws IOException {
|
2011-03-15 02:51:04 -04:00
|
|
|
//dl.finished();
|
|
|
|
//dl.stopped();
|
2011-03-12 17:44:54 -05:00
|
|
|
super.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected static class NullOutputStream extends OutputStream {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void write(byte[] b, int off, int len) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void write(int b) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void write(byte[] b) throws IOException {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|