/*
* This file is part of Spoutcraft (http://wiki.getspout.org/).
*
* Spoutcraft is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Spoutcraft 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.getspout.spout.io;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Iterator;
import java.util.concurrent.ConcurrentLinkedQueue;
public class FileDownloadThread extends Thread{
private static FileDownloadThread instance = null;
private final ConcurrentLinkedQueue<Download> downloads = new ConcurrentLinkedQueue<Download>();
private final ConcurrentLinkedQueue<Runnable> actions = new ConcurrentLinkedQueue<Runnable>();
private final byte[] buffer = new byte[1024*1024];
private volatile String activeDownload = null;
protected FileDownloadThread() {
super("File Download Thread");
}
public static FileDownloadThread getInstance() {
if (instance == null) {
instance = new FileDownloadThread();
instance.start();
}
return instance;
}
public void addToDownloadQueue(Download download){
downloads.add(download);
}
public boolean isDownloading(String url) {
Iterator<Download> i = downloads.iterator();
while(i.hasNext()) {
Download download = i.next();
if (download.getDownloadUrl().equals(url)) {
return true;
}
}
return false;
}
public void onTick() {
Iterator<Runnable> i = actions.iterator();
while(i.hasNext()) {
Runnable action = i.next();
action.run();
i.remove();
}
}
public void abort() {
this.interrupt();
downloads.clear();
}
public String getActiveDownload() {
return activeDownload;
}
public int getDownloadsRemaining() {
return downloads.size();
}
public void run() {
while(true) {
Download next = downloads.poll();
if (next != null) {
try {
if (!next.isDownloaded()) {
System.out.println("Downloading File: " + next.getDownloadUrl());
activeDownload = FileUtil.getFileName(next.getDownloadUrl());
URL url = new URL(next.getDownloadUrl());
URLConnection conn = url.openConnection();
InputStream in = conn.getInputStream();
FileOutputStream fos = new FileOutputStream(next.getTempFile());
long length = conn.getContentLength();
int bytes;
long totalBytes = 0;
long last = 0;
long step = Math.max(1024*1024, length / 8);
while ((bytes = in.read(buffer)) >= 0) {
fos.write(buffer, 0, bytes);
totalBytes += bytes;
if (length > 0 && totalBytes > (last + step)) {
last = totalBytes;
long mb = totalBytes/(1024*1024);
System.out.println("Downloading: " + next.getDownloadUrl() + " " + mb + "MB/" + (length/(1024*1024)));
}
try {
Thread.sleep(25);
} catch (InterruptedException e) {
}
}
in.close();
fos.close();
next.move();
System.out.println("File moved to: " + next.directory.getCanonicalPath());
try {
sleep(10); //cool off after heavy network useage
} catch (InterruptedException e) {}
}
if (next.getCompletedAction() != null) {
actions.add(next.getCompletedAction());
}
}
catch (Exception e) {
System.out.println("-----------------------");
System.out.println("Download Failed!");
e.printStackTrace();
System.out.println("-----------------------");
}
activeDownload = null;
}
else {
try {
sleep(100);
} catch (InterruptedException e) {}
}
}
}
}