package play_downloader;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.prefs.Preferences;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JTable;
import play_downloader.DownloadableObjects;
import play_downloader.RunAfterDownloadThread;
import play_downloader.S;
import play_downloader.PlayDownloaderApp;
/**
*
* @author UT_lol
*/
class DownloadThread extends Thread {
private DownloadableObjects[] dObjects;
private JTable jTable1;
private JProgressBar progressBar;
private String saveFolder;
private Preferences prefs;
private String winWorkingFolder = "";
private JPanel mainPanel;
private Pattern PERCENT = Pattern.compile("\\x28((\\d+))\\x2e\\d\\x25\\x29");
public DownloadThread(DownloadableObjects[] dObjects, JTable jTable1, JProgressBar progressBar, JPanel mainPanel){
this.dObjects = dObjects;
this.jTable1 = jTable1;
this.progressBar = progressBar;
this.mainPanel = mainPanel;
winWorkingFolder = System.getProperty("user.dir");
prefs = Preferences.userNodeForPackage(PlayDownloaderApp.class);
File dir = new File (prefs.get(S.PREF_SAVE_FOLDER, "."));
try {
saveFolder = dir.getCanonicalPath() + "/";
} catch (IOException ex) {
PlayDownloaderApp.logger.log(Level.SEVERE, null, ex);
}
}
@Override
public void run() {
for (int curIndex : jTable1.getSelectedRows()) {
String videoLink = dObjects[curIndex].getAddress();
String fileName = dObjects[curIndex].getTitle();
dObjects[curIndex].setStatus(DownloadableObjects.STATUS_DOWNLOADING);
jTable1.setValueAt(dObjects[curIndex].getStatus(), curIndex, 3);
if (!fileName.contains(".mp4") && !fileName.contains(".flv")) {
fileName += ".mp4";
}
if (fileName.contains(".flv")) {
downloadFromHttp(curIndex);
continue;
}
//if(OS_NAME == OS_LINUX || OS_NAME == OS_MAC || OS_NAME == OS_WINDOWS){
fileName = saveFolder + fileName;
//}
ArrayList<String> commands = new ArrayList<String>();
String rtmpdumpPath = S.RTMPDUMP_APP_NAME;
if (prefs.getBoolean(S.PREF_RTMPDUMP_FOLDER_CHECKED, false)) {
rtmpdumpPath = prefs.get(S.PREF_RTMPDUMP_FOLDER, "") + "/" + S.RTMPDUMP_APP_NAME;
}
commands.add(rtmpdumpPath);
commands.add("-o" + fileName);
if (dObjects[curIndex].getOtherArgs() == null) {
commands.add("-r" + videoLink);
} else {
commands.addAll(dObjects[curIndex].getOtherArgs());
}
if (prefs.getBoolean(S.PREF_USE_PROXY, false)) {
String proxyHost = prefs.get(S.PREF_PROXY_HOST_SOCKS, "null");
if (!proxyHost.equals("null")) {
int proxyPort = prefs.getInt(S.PREF_PROXY_PORT_SOCKS, 3128);
commands.add("-S" + proxyHost + ":" + proxyPort);
PlayDownloaderApp.logger.log(Level.INFO, "Is using proxy...");
}
}
try {
ProcessBuilder pb = new ProcessBuilder(commands);
if (S.OS_NAME == S.OS_WINDOWS) {
pb.directory(new File(winWorkingFolder));
}
pb.redirectErrorStream(true);
Process p = pb.start();
dObjects[curIndex].setProcess(p);
InputStream is = p.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
progressBar.setVisible(true);
for (String line = br.readLine(); line != null; line = br.readLine()) {
//System.out.println(line); //get console output
PlayDownloaderApp.logger.log(Level.INFO, line);
Matcher m3 = PERCENT.matcher(line);
if(m3.find()){
int value = Integer.parseInt(m3.group(1));
progressBar.setValue(value);
jTable1.setValueAt(value, curIndex, 4);
}
}
progressBar.setVisible(false);
jTable1.setValueAt(null, curIndex, 4);
try {
p.waitFor();
if (p.exitValue() == 0) { // if rtmpdump ended correctly set the status to STATUS_DOWNLOADED
dObjects[curIndex].setStatus(DownloadableObjects.STATUS_DOWNLOADED);
jTable1.setValueAt(dObjects[curIndex].getStatus(), curIndex, 3); //update the table
startRunAfterDownload(curIndex);
}
} catch (InterruptedException ex) {
PlayDownloaderApp.logger.log(Level.SEVERE, null, ex);
}
} catch (IOException ex) {
if (ex.getMessage().equals("Stream closed")) {
PlayDownloaderApp.logger.log(Level.INFO, "Stream closed");
dObjects[curIndex].setStatus(DownloadableObjects.STATUS_CANCELED);//it is probably canceled so set the status to STATUS_CANCELED
jTable1.setValueAt(dObjects[curIndex].getStatus(), curIndex, 3); //update the table
} else {
PlayDownloaderApp.logger.log(Level.SEVERE, null, ex);
JOptionPane.showMessageDialog(mainPanel, ex.getMessage());
}
}
}
}
private void downloadFromHttp(int curIndex){
DownloadableObjects dbo = dObjects[curIndex];
BufferedInputStream in = null;
FileOutputStream fos = null;
BufferedOutputStream bout = null;
progressBar.setVisible(true);
try{
URL url = new URL(dbo.getAddress());
int fileLength = url.openConnection().getContentLength();
int numberOfNeededReads = fileLength/409600; //4096 * 100
int counter = 0;
in = new BufferedInputStream(url.openStream());
fos = new FileOutputStream(saveFolder + dbo.getTitle());
bout = new BufferedOutputStream(fos,1024);
byte[] data = new byte[4096];
int x=0;
while((x=in.read(data,0,4096))>=0){
bout.write(data,0,x);
int value = counter/numberOfNeededReads;
jTable1.setValueAt(value, curIndex, 4);
progressBar.setValue(value);
counter++;
}
progressBar.setVisible(false);
jTable1.setValueAt(null, curIndex, 4);
dObjects[curIndex].setStatus(DownloadableObjects.STATUS_DOWNLOADED);
jTable1.setValueAt(dObjects[curIndex].getStatus(), curIndex, 3);
bout.close();
fos.close();
in.close();
startRunAfterDownload(curIndex);
}catch(Exception ex){
PlayDownloaderApp.logger.log(Level.SEVERE, null, ex);
}
}
private void startRunAfterDownload(int curIndex){
if (prefs.getBoolean(S.PREF_RUN_AFTER_DOWNLOAD_CHEKED, false)) {//TODO: check this out
RunAfterDownloadThread radThread = new RunAfterDownloadThread(dObjects, jTable1, curIndex);
radThread.start();
dObjects[curIndex].setStatus(DownloadableObjects.STATUS_EXT_APP);
jTable1.setValueAt(dObjects[curIndex].getStatus(), curIndex, 3); //update the table
}
}
}