- Deleted unused classes
- Refined and added javadoc - Disabled MetaDataWriter
This commit is contained in:
		
							parent
							
								
									34ea601a95
								
							
						
					
					
						commit
						f8dd7be711
					
				@ -10,7 +10,36 @@
 | 
			
		||||
                <goal>org.codehaus.mojo:exec-maven-plugin:1.5.0:exec</goal>
 | 
			
		||||
            </goals>
 | 
			
		||||
            <properties>
 | 
			
		||||
                <exec.args>-classpath %classpath com.greinet.tvtotalripper.Main</exec.args>
 | 
			
		||||
                <exec.args>-classpath %classpath com.greinet.tvtotalripper.ui.RipperWindow</exec.args>
 | 
			
		||||
                <exec.executable>java</exec.executable>
 | 
			
		||||
            </properties>
 | 
			
		||||
        </action>
 | 
			
		||||
        <action>
 | 
			
		||||
            <actionName>debug</actionName>
 | 
			
		||||
            <packagings>
 | 
			
		||||
                <packaging>jar</packaging>
 | 
			
		||||
            </packagings>
 | 
			
		||||
            <goals>
 | 
			
		||||
                <goal>process-classes</goal>
 | 
			
		||||
                <goal>org.codehaus.mojo:exec-maven-plugin:1.5.0:exec</goal>
 | 
			
		||||
            </goals>
 | 
			
		||||
            <properties>
 | 
			
		||||
                <exec.args>-agentlib:jdwp=transport=dt_socket,server=n,address=${jpda.address} -classpath %classpath com.greinet.tvtotalripper.ui.RipperWindow</exec.args>
 | 
			
		||||
                <exec.executable>java</exec.executable>
 | 
			
		||||
                <jpda.listen>true</jpda.listen>
 | 
			
		||||
            </properties>
 | 
			
		||||
        </action>
 | 
			
		||||
        <action>
 | 
			
		||||
            <actionName>profile</actionName>
 | 
			
		||||
            <packagings>
 | 
			
		||||
                <packaging>jar</packaging>
 | 
			
		||||
            </packagings>
 | 
			
		||||
            <goals>
 | 
			
		||||
                <goal>process-classes</goal>
 | 
			
		||||
                <goal>org.codehaus.mojo:exec-maven-plugin:1.5.0:exec</goal>
 | 
			
		||||
            </goals>
 | 
			
		||||
            <properties>
 | 
			
		||||
                <exec.args>-classpath %classpath com.greinet.tvtotalripper.ui.RipperWindow</exec.args>
 | 
			
		||||
                <exec.executable>java</exec.executable>
 | 
			
		||||
            </properties>
 | 
			
		||||
        </action>
 | 
			
		||||
 | 
			
		||||
@ -1,172 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * To change this license header, choose License Headers in Project Properties.
 | 
			
		||||
 * To change this template file, choose Tools | Templates
 | 
			
		||||
 * and open the template in the editor.
 | 
			
		||||
 */
 | 
			
		||||
package com.greinet.tvtotalripper;
 | 
			
		||||
 | 
			
		||||
import com.greinet.tvtotalripper.crawler.CrawlerUtil;
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileInputStream;
 | 
			
		||||
import java.io.FileOutputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.net.MalformedURLException;
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
import java.nio.channels.Channels;
 | 
			
		||||
import java.nio.channels.ReadableByteChannel;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.logging.Level;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
import org.apache.logging.log4j.LogManager;
 | 
			
		||||
import org.apache.logging.log4j.Logger;
 | 
			
		||||
import org.mp4parser.IsoFile;
 | 
			
		||||
import org.mp4parser.boxes.apple.AppleNameBox;
 | 
			
		||||
import org.mp4parser.tools.Path;
 | 
			
		||||
import org.openqa.selenium.By;
 | 
			
		||||
import org.openqa.selenium.TimeoutException;
 | 
			
		||||
import org.openqa.selenium.WebDriver;
 | 
			
		||||
import org.openqa.selenium.WebElement;
 | 
			
		||||
import org.openqa.selenium.chrome.ChromeDriver;
 | 
			
		||||
import org.openqa.selenium.chrome.ChromeOptions;
 | 
			
		||||
import org.openqa.selenium.support.ui.ExpectedConditions;
 | 
			
		||||
import org.openqa.selenium.support.ui.WebDriverWait;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * @author agreiner
 | 
			
		||||
 */
 | 
			
		||||
public class Main {
 | 
			
		||||
    
 | 
			
		||||
    private static final Logger logger = LogManager.getLogger(Main.class);
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    public static void main(String[] args) throws InterruptedException, IOException {
 | 
			
		||||
        //System.setProperty("webdriver.chrome.driver", "resources/chromedriver.exe");
 | 
			
		||||
        File f = new File("H:/Users/Andreas/Music/Bass/videoplayback.mp4");
 | 
			
		||||
        
 | 
			
		||||
        MetaDataWriter mdp = new MetaDataWriter();
 | 
			
		||||
        mdp.writeMetadata(f.getAbsolutePath(), "Raab im Dschungel", "Stefan Raab", "TV Total", "TV Total vom 3.2.2021");
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
        System.exit(0);
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
        System.out.println(CrawlerUtil.getFetchfileURL("https://www.myspass.de/shows/tvshows/tv-total/TV-total-Sendung-vom-08031999--/5716/"));
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
        downloadFile(test());
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
            
 | 
			
		||||
        ChromeOptions options = new ChromeOptions();
 | 
			
		||||
        options.addArguments("start-maximized");
 | 
			
		||||
        
 | 
			
		||||
        WebDriver driver = new ChromeDriver(options);
 | 
			
		||||
        
 | 
			
		||||
        initialize(driver);
 | 
			
		||||
        
 | 
			
		||||
        List<WebElement> seriesElements = getSeriesElements(driver);
 | 
			
		||||
        //seriesElements.forEach(e -> System.out.println(e.getAttribute("href").replaceAll("https://www.myspass.de/shows/tvshows/", "")));
 | 
			
		||||
        
 | 
			
		||||
        System.out.println("\nTV shows\n");
 | 
			
		||||
        // TV shows
 | 
			
		||||
        List<WebElement> tvshows = seriesElements.stream().filter(e -> e.getAttribute("href").contains("tvshows") || e.getAttribute("href").contains("UNKNOWN")).collect(Collectors.toList());
 | 
			
		||||
        tvshows.forEach(e -> System.out.println(e.getAttribute("href")));
 | 
			
		||||
        
 | 
			
		||||
        System.out.println("\nWebshows\n");
 | 
			
		||||
        List<WebElement> webshows = seriesElements.stream().filter(e -> e.getAttribute("href").contains("webshows")).collect(Collectors.toList());
 | 
			
		||||
        webshows.forEach(e -> System.out.println(e.getAttribute("href")));
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
        tvshows.get(3).click();
 | 
			
		||||
        Thread.sleep(3000);
 | 
			
		||||
        navigateToEpisodeOverview(driver);
 | 
			
		||||
        Thread.sleep(3000);
 | 
			
		||||
        getSeasonElements(driver).forEach(e -> System.out.println(e.getText()));
 | 
			
		||||
        Thread.sleep(3000);
 | 
			
		||||
        System.out.println("-------------------------------------------------------------------------------------------------------------------------------------");
 | 
			
		||||
        getEpisodeElements(driver).forEach(e -> System.out.println(e.getAttribute("href")));
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    private static boolean clickWhenClickable(WebDriver driver, By by, int timeout){
 | 
			
		||||
        WebDriverWait wait = new WebDriverWait(driver, timeout);
 | 
			
		||||
        try{
 | 
			
		||||
            WebElement acceptCookiesButton = wait.until(ExpectedConditions.elementToBeClickable(by));
 | 
			
		||||
            acceptCookiesButton.click();
 | 
			
		||||
        }catch(TimeoutException ex){
 | 
			
		||||
            logger.warn("Element represented by ["+by+"] not clickable.");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    private static void initialize(WebDriver driver){
 | 
			
		||||
        //Load start page
 | 
			
		||||
        //String urlStartPage = "https://www.myspass.de/shows/tvshows/tv-total/#bob-subnavi";
 | 
			
		||||
        String urlStartPage = "https://www.myspass.de/sendungen-a-bis-z/";
 | 
			
		||||
        logger.info("Loading start page ["+urlStartPage+"].");
 | 
			
		||||
        driver.get(urlStartPage);
 | 
			
		||||
        
 | 
			
		||||
        // Accept cookies if needed
 | 
			
		||||
        logger.info("Accepting cookies.");
 | 
			
		||||
        boolean cookiesSuccess = clickWhenClickable(driver, By.id("cmpbntyestxt"),5);
 | 
			
		||||
        if(!cookiesSuccess){
 | 
			
		||||
            logger.info("No cookie popup present.");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    private static boolean navigateToEpisodeOverview(WebDriver driver){
 | 
			
		||||
        logger.info("Navigating to episode overview.");
 | 
			
		||||
        return clickWhenClickable(driver, By.xpath("/html/body/div[4]/div[1]/div[2]/ul/li[2]/a"),5);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    private static List<WebElement> getSeriesElements(WebDriver driver){
 | 
			
		||||
        return driver.findElements(By.xpath("/html/body/div[5]/div/div/div/div/a"));
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    private static List<WebElement> getSeasonElements(WebDriver driver){
 | 
			
		||||
        return driver.findElements(By.xpath("/html/body/div[4]/div[1]/div[3]/div[2]/div[1]/select/option"));
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    private static List<WebElement> getEpisodeElements(WebDriver driver){
 | 
			
		||||
        return driver.findElements(By.xpath("/html/body/div[4]/div[1]/div[3]/div[2]/div[4]/div/div/div/a"));
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    private static String test(){
 | 
			
		||||
        WebDriver driver = new ChromeDriver();
 | 
			
		||||
        driver.get("https://de.fetchfile.net/herunterladen-von-myspass/");
 | 
			
		||||
        
 | 
			
		||||
        WebElement textbox = driver.findElement(By.id("videoPath"));
 | 
			
		||||
        textbox.sendKeys("https://www.myspass.de/shows/tvshows/tv-total/TV-total-Sendung-vom-05012015--/20674/");
 | 
			
		||||
        
 | 
			
		||||
        WebElement dlButton = driver.findElement(By.id("home-submit"));
 | 
			
		||||
        dlButton.click();
 | 
			
		||||
        
 | 
			
		||||
        WebDriverWait wait = new WebDriverWait(driver, 20);
 | 
			
		||||
        WebElement vidButton = wait.until(ExpectedConditions.elementToBeClickable(By.className("download-link")));
 | 
			
		||||
        return vidButton.getAttribute("href");
 | 
			
		||||
        
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    private static void downloadFile(String urlString){
 | 
			
		||||
        try {        
 | 
			
		||||
            File f = new File("download.mp4");
 | 
			
		||||
            f.createNewFile();
 | 
			
		||||
            URL url = new URL(urlString);
 | 
			
		||||
            ReadableByteChannel readableByteChannel = Channels.newChannel(url.openStream());
 | 
			
		||||
            FileOutputStream fileOutputStream = new FileOutputStream(f);
 | 
			
		||||
            fileOutputStream.getChannel().transferFrom(readableByteChannel, 0, Long.MAX_VALUE);
 | 
			
		||||
        } catch (MalformedURLException ex) {
 | 
			
		||||
            
 | 
			
		||||
        } catch (IOException ex) {
 | 
			
		||||
            java.util.logging.Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,189 +0,0 @@
 | 
			
		||||
package com.greinet.tvtotalripper;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
import org.mp4parser.Box;
 | 
			
		||||
import org.mp4parser.Container;
 | 
			
		||||
import org.mp4parser.IsoFile;
 | 
			
		||||
import org.mp4parser.boxes.apple.AppleItemListBox;
 | 
			
		||||
import org.mp4parser.boxes.apple.AppleNameBox;
 | 
			
		||||
import org.mp4parser.boxes.iso14496.part12.*;
 | 
			
		||||
import org.mp4parser.tools.Path;
 | 
			
		||||
 | 
			
		||||
import java.io.*;
 | 
			
		||||
import java.nio.ByteBuffer;
 | 
			
		||||
import java.nio.channels.Channels;
 | 
			
		||||
import java.nio.channels.FileChannel;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Change metadata and make sure chunkoffsets are corrected.
 | 
			
		||||
 */
 | 
			
		||||
public class MetaDataParser {
 | 
			
		||||
 | 
			
		||||
    public FileChannel splitFileAndInsert(File f, long pos, long length) throws IOException {
 | 
			
		||||
        FileChannel read = new RandomAccessFile(f, "r").getChannel();
 | 
			
		||||
        File tmp = File.createTempFile("ChangeMetaData", "splitFileAndInsert");
 | 
			
		||||
        FileChannel tmpWrite = new RandomAccessFile(tmp, "rw").getChannel();
 | 
			
		||||
        read.position(pos);
 | 
			
		||||
        tmpWrite.transferFrom(read, 0, read.size() - pos);
 | 
			
		||||
        read.close();
 | 
			
		||||
        FileChannel write = new RandomAccessFile(f, "rw").getChannel();
 | 
			
		||||
        write.position(pos + length);
 | 
			
		||||
        tmpWrite.position(0);
 | 
			
		||||
        long transferred = 0;
 | 
			
		||||
        while ((transferred += tmpWrite.transferTo(0, tmpWrite.size() - transferred, write)) != tmpWrite.size()) {
 | 
			
		||||
            System.out.println(transferred);
 | 
			
		||||
        }
 | 
			
		||||
        System.out.println(transferred);
 | 
			
		||||
        tmpWrite.close();
 | 
			
		||||
        tmp.delete();
 | 
			
		||||
        return write;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    private boolean needsOffsetCorrection(IsoFile isoFile) {
 | 
			
		||||
        if (Path.getPath(isoFile, "moov[0]/mvex[0]") != null) {
 | 
			
		||||
            // Fragmented files don't need a correction
 | 
			
		||||
            return false;
 | 
			
		||||
        } else {
 | 
			
		||||
            // no correction needed if mdat is before moov as insert into moov want change the offsets of mdat
 | 
			
		||||
            for (Box box : isoFile.getBoxes()) {
 | 
			
		||||
                if ("moov".equals(box.getType())) {
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
                if ("mdat".equals(box.getType())) {
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            throw new RuntimeException("I need moov or mdat. Otherwise all this doesn't make sense");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void writeRandomMetadata(String videoFilePath, String title) throws IOException {
 | 
			
		||||
 | 
			
		||||
        File videoFile = new File(videoFilePath);
 | 
			
		||||
        if (!videoFile.exists()) {
 | 
			
		||||
            throw new FileNotFoundException("File " + videoFilePath + " not exists");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!videoFile.canWrite()) {
 | 
			
		||||
            throw new IllegalStateException("No write permissions to file " + videoFilePath);
 | 
			
		||||
        }
 | 
			
		||||
        IsoFile isoFile = new IsoFile(videoFilePath);
 | 
			
		||||
 | 
			
		||||
        MovieBox moov = isoFile.getBoxes(MovieBox.class).get(0);
 | 
			
		||||
        FreeBox freeBox = findFreeBox(moov);
 | 
			
		||||
 | 
			
		||||
        boolean correctOffset = needsOffsetCorrection(isoFile);
 | 
			
		||||
        long sizeBefore = moov.getSize();
 | 
			
		||||
        long offset = 0;
 | 
			
		||||
        for (Box box : isoFile.getBoxes()) {
 | 
			
		||||
            if ("moov".equals(box.getType())) {
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            offset += box.getSize();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Create structure or just navigate to Apple List Box.
 | 
			
		||||
        UserDataBox userDataBox;
 | 
			
		||||
        if ((userDataBox = Path.getPath(moov, "udta")) == null) {
 | 
			
		||||
            userDataBox = new UserDataBox();
 | 
			
		||||
            moov.addBox(userDataBox);
 | 
			
		||||
        }
 | 
			
		||||
        MetaBox metaBox;
 | 
			
		||||
        if ((metaBox = Path.getPath(userDataBox, "meta")) == null) {
 | 
			
		||||
            metaBox = new MetaBox();
 | 
			
		||||
            HandlerBox hdlr = new HandlerBox();
 | 
			
		||||
            hdlr.setHandlerType("mdir");
 | 
			
		||||
            metaBox.addBox(hdlr);
 | 
			
		||||
            userDataBox.addBox(metaBox);
 | 
			
		||||
        }
 | 
			
		||||
        AppleItemListBox ilst;
 | 
			
		||||
        if ((ilst = Path.getPath(metaBox, "ilst")) == null) {
 | 
			
		||||
            ilst = new AppleItemListBox();
 | 
			
		||||
            metaBox.addBox(ilst);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        if (freeBox == null) {
 | 
			
		||||
            freeBox = new FreeBox(128 * 1024);
 | 
			
		||||
            metaBox.addBox(freeBox);
 | 
			
		||||
        }
 | 
			
		||||
        // Got Apple List Box
 | 
			
		||||
 | 
			
		||||
        AppleNameBox nam;
 | 
			
		||||
        if ((nam = Path.getPath(ilst, "©nam")) == null) {
 | 
			
		||||
            nam = new AppleNameBox();
 | 
			
		||||
        }
 | 
			
		||||
        nam.setDataCountry(0);
 | 
			
		||||
        nam.setDataLanguage(0);
 | 
			
		||||
        nam.setValue(title);
 | 
			
		||||
        ilst.addBox(nam);
 | 
			
		||||
 | 
			
		||||
        long sizeAfter = moov.getSize();
 | 
			
		||||
        long diff = sizeAfter - sizeBefore;
 | 
			
		||||
        // This is the difference of before/after
 | 
			
		||||
 | 
			
		||||
        // can we compensate by resizing a Free Box we have found?
 | 
			
		||||
        if (freeBox.getData().limit() > diff) {
 | 
			
		||||
            // either shrink or grow!
 | 
			
		||||
            freeBox.setData(ByteBuffer.allocate((int) (freeBox.getData().limit() - diff)));
 | 
			
		||||
            sizeAfter = moov.getSize();
 | 
			
		||||
            diff = sizeAfter - sizeBefore;
 | 
			
		||||
        }
 | 
			
		||||
        if (correctOffset && diff != 0) {
 | 
			
		||||
            correctChunkOffsets(moov, diff);
 | 
			
		||||
        }
 | 
			
		||||
        BetterByteArrayOutputStream baos = new BetterByteArrayOutputStream();
 | 
			
		||||
        moov.getBox(Channels.newChannel(baos));
 | 
			
		||||
        isoFile.close();
 | 
			
		||||
        FileChannel fc;
 | 
			
		||||
        if (diff != 0) {
 | 
			
		||||
            // this is not good: We have to insert bytes in the middle of the file
 | 
			
		||||
            // and this costs time as it requires re-writing most of the file's data
 | 
			
		||||
            fc = splitFileAndInsert(videoFile, offset, sizeAfter - sizeBefore);
 | 
			
		||||
        } else {
 | 
			
		||||
            // simple overwrite of something with the file
 | 
			
		||||
            fc = new RandomAccessFile(videoFile, "rw").getChannel();
 | 
			
		||||
        }
 | 
			
		||||
        fc.position(offset);
 | 
			
		||||
        fc.write(ByteBuffer.wrap(baos.getBuffer(), 0, baos.size()));
 | 
			
		||||
        fc.close();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    FreeBox findFreeBox(Container c) {
 | 
			
		||||
        for (Box box : c.getBoxes()) {
 | 
			
		||||
            System.err.println(box.getType());
 | 
			
		||||
            if (box instanceof FreeBox) {
 | 
			
		||||
                return (FreeBox) box;
 | 
			
		||||
            }
 | 
			
		||||
            if (box instanceof Container) {
 | 
			
		||||
                FreeBox freeBox = findFreeBox((Container) box);
 | 
			
		||||
                if (freeBox != null) {
 | 
			
		||||
                    return freeBox;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void correctChunkOffsets(MovieBox movieBox, long correction) {
 | 
			
		||||
        List<ChunkOffsetBox> chunkOffsetBoxes = Path.getPaths((Box) movieBox, "trak/mdia[0]/minf[0]/stbl[0]/stco[0]");
 | 
			
		||||
        if (chunkOffsetBoxes.isEmpty()) {
 | 
			
		||||
            chunkOffsetBoxes = Path.getPaths((Box) movieBox, "trak/mdia[0]/minf[0]/stbl[0]/st64[0]");
 | 
			
		||||
        }
 | 
			
		||||
        for (ChunkOffsetBox chunkOffsetBox : chunkOffsetBoxes) {
 | 
			
		||||
            long[] cOffsets = chunkOffsetBox.getChunkOffsets();
 | 
			
		||||
            for (int i = 0; i < cOffsets.length; i++) {
 | 
			
		||||
                cOffsets[i] += correction;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static class BetterByteArrayOutputStream extends ByteArrayOutputStream {
 | 
			
		||||
        byte[] getBuffer() {
 | 
			
		||||
            return buf;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -1,6 +1,5 @@
 | 
			
		||||
package com.greinet.tvtotalripper;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
import org.mp4parser.Box;
 | 
			
		||||
import org.mp4parser.Container;
 | 
			
		||||
import org.mp4parser.IsoFile;
 | 
			
		||||
@ -15,13 +14,11 @@ import java.nio.channels.Channels;
 | 
			
		||||
import java.nio.channels.FileChannel;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import org.mp4parser.boxes.apple.AppleArtistBox;
 | 
			
		||||
import org.mp4parser.boxes.apple.AppleTVEpisodeBox;
 | 
			
		||||
import org.mp4parser.boxes.apple.AppleTVEpisodeNumberBox;
 | 
			
		||||
import org.mp4parser.boxes.apple.AppleTVSeasonBox;
 | 
			
		||||
import org.mp4parser.boxes.apple.AppleTVShowBox;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Change metadata and make sure chunkoffsets are corrected.
 | 
			
		||||
 * Utility class to change mp4 metatdata, more or less copied from https://github.com/sannies/mp4parser/blob/master/examples/src/main/java/org/mp4parser/examples/metadata/MetaDataInsert.java
 | 
			
		||||
 */
 | 
			
		||||
public class MetaDataWriter {
 | 
			
		||||
 | 
			
		||||
@ -43,7 +40,6 @@ public class MetaDataWriter {
 | 
			
		||||
        return write;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    private boolean needsOffsetCorrection(IsoFile isoFile) {
 | 
			
		||||
        if (Path.getPath(isoFile, "moov[0]/mvex[0]") != null) {
 | 
			
		||||
            // Fragmented files don't need a correction
 | 
			
		||||
@ -62,6 +58,15 @@ public class MetaDataWriter {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Write itunes metadata to a mp4 file
 | 
			
		||||
     * @param videoFilePath the file path
 | 
			
		||||
     * @param title the title, or <code>null</code>
 | 
			
		||||
     * @param artist the artist, or <code>null</code>
 | 
			
		||||
     * @param show the show, or <code>null</code>
 | 
			
		||||
     * @param episode the episode, or <code>null</code>
 | 
			
		||||
     * @throws IOException error heandling mp4 file
 | 
			
		||||
     */
 | 
			
		||||
    public void writeMetadata(String videoFilePath, String title, String artist, String show, String episode) throws IOException {
 | 
			
		||||
 | 
			
		||||
        File videoFile = new File(videoFilePath);
 | 
			
		||||
@ -160,8 +165,6 @@ public class MetaDataWriter {
 | 
			
		||||
            ilst.addBox(sh); 
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
        long sizeAfter = moov.getSize();
 | 
			
		||||
        long diff = sizeAfter - sizeBefore;
 | 
			
		||||
        // This is the difference of before/after
 | 
			
		||||
@ -193,7 +196,7 @@ public class MetaDataWriter {
 | 
			
		||||
        fc.close();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    FreeBox findFreeBox(Container c) {
 | 
			
		||||
    private FreeBox findFreeBox(Container c) {
 | 
			
		||||
        for (Box box : c.getBoxes()) {
 | 
			
		||||
            if (box instanceof FreeBox) {
 | 
			
		||||
                return (FreeBox) box;
 | 
			
		||||
 | 
			
		||||
@ -1,77 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * To change this license header, choose License Headers in Project Properties.
 | 
			
		||||
 * To change this template file, choose Tools | Templates
 | 
			
		||||
 * and open the template in the editor.
 | 
			
		||||
 */
 | 
			
		||||
package com.greinet.tvtotalripper;
 | 
			
		||||
 | 
			
		||||
import java.awt.Dimension;
 | 
			
		||||
import java.beans.PropertyChangeEvent;
 | 
			
		||||
import java.beans.PropertyChangeListener;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import javax.swing.JFrame;
 | 
			
		||||
import javax.swing.JLabel;
 | 
			
		||||
import javax.swing.JProgressBar;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * @author agreiner
 | 
			
		||||
 */
 | 
			
		||||
public class SwingInterface implements PropertyChangeListener {
 | 
			
		||||
    
 | 
			
		||||
    private final JFrame frame;
 | 
			
		||||
    private final JLabel label;
 | 
			
		||||
    private final JProgressBar progressBar;
 | 
			
		||||
    
 | 
			
		||||
    private List<PropertyChangeListener> changeListener = new ArrayList<>();
 | 
			
		||||
    
 | 
			
		||||
    public SwingInterface(){
 | 
			
		||||
        
 | 
			
		||||
        frame = new JFrame("TV Total Ripper");
 | 
			
		||||
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 | 
			
		||||
        
 | 
			
		||||
        label = new JLabel("Testlabel");
 | 
			
		||||
        label.setPreferredSize(new Dimension(200, 30));
 | 
			
		||||
        
 | 
			
		||||
        progressBar = new JProgressBar(0, 100);
 | 
			
		||||
        progressBar.setPreferredSize(new Dimension(200, 30));
 | 
			
		||||
        progressBar.setStringPainted(true);
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
        frame.add(label);
 | 
			
		||||
        frame.add(progressBar);
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
        frame.pack();
 | 
			
		||||
        frame.setVisible(true);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public static void main(String[] args) {
 | 
			
		||||
        
 | 
			
		||||
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run() {
 | 
			
		||||
                SwingInterface i = new SwingInterface();
 | 
			
		||||
                i.startDownload();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void startDownload(){
 | 
			
		||||
        //DownloadTask task = new DownloadTask(label, "https://cldf-od.r53.cdn.tv1.eu/secdl/06d6d246daa2c7ec0ffb2f8281149072/6066001f/11021brainpool/ondemand/3583brainpool/163840/myspass2009/11/33/2171/9642/9642_61.mp4", "");
 | 
			
		||||
        //task.addPropertyChangeListener(this);
 | 
			
		||||
        //task.execute();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public void propertyChange(PropertyChangeEvent evt) {
 | 
			
		||||
         if (evt.getPropertyName().equals("progress1")) {
 | 
			
		||||
            int progress = (Integer) evt.getNewValue();
 | 
			
		||||
            progressBar.setValue(progress);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
@ -33,11 +33,12 @@ public class CrawlerUtil {
 | 
			
		||||
    private final static WebDriver driverSeasonsAndEpisodes = createChromeDriver();
 | 
			
		||||
    /** The WebDriver for fetchfile.net URL conversion */
 | 
			
		||||
    private final static WebDriver driverFetchFile = createFetchFileDriver();
 | 
			
		||||
    /** The show */
 | 
			
		||||
    private static String show = "";
 | 
			
		||||
    
 | 
			
		||||
    public static String show = "";
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a basic ChromeDriver
 | 
			
		||||
     * @return 
 | 
			
		||||
     * @return the WebDriver
 | 
			
		||||
     */
 | 
			
		||||
    private static WebDriver createChromeDriver(){
 | 
			
		||||
        ChromeOptions options = new ChromeOptions();
 | 
			
		||||
@ -55,6 +56,10 @@ public class CrawlerUtil {
 | 
			
		||||
        return driver;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Create the WebDriver to get the video URLs from FetchFile.net
 | 
			
		||||
     * @return the WebDriver
 | 
			
		||||
     */
 | 
			
		||||
    private static WebDriver createFetchFileDriver(){
 | 
			
		||||
        WebDriver driver = createChromeDriver();
 | 
			
		||||
        driver.get("https://de.fetchfile.net/herunterladen-von-myspass");
 | 
			
		||||
@ -154,6 +159,11 @@ public class CrawlerUtil {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the FetchFile.net URL to the myspass.com video file
 | 
			
		||||
     * @param myspassURL the URL to the myspass.com video
 | 
			
		||||
     * @return the FetchFile.net URL
 | 
			
		||||
     */
 | 
			
		||||
    public static String getFetchfileURL(String myspassURL){
 | 
			
		||||
        synchronized(driverFetchFile){
 | 
			
		||||
            WebElement videoPathInput = driverFetchFile.findElement(By.id("videoPath"));
 | 
			
		||||
 | 
			
		||||
@ -10,25 +10,25 @@ import java.util.UUID;
 | 
			
		||||
public class EpisodeWrapper {
 | 
			
		||||
    
 | 
			
		||||
    /** The URL to the episode */
 | 
			
		||||
    private String url;
 | 
			
		||||
    private final String url;
 | 
			
		||||
    /** The title */
 | 
			
		||||
    private String title;
 | 
			
		||||
    private final String title;
 | 
			
		||||
    /** The episode */
 | 
			
		||||
    private String episode;
 | 
			
		||||
    private final String episode;
 | 
			
		||||
    /** The season */
 | 
			
		||||
    private String season;
 | 
			
		||||
    private final String season;
 | 
			
		||||
    /** The episode duration */
 | 
			
		||||
    private String duration;
 | 
			
		||||
    private final String duration;
 | 
			
		||||
    /** The unique id */
 | 
			
		||||
    private final long id;
 | 
			
		||||
 | 
			
		||||
    private String show;
 | 
			
		||||
    /** The show */
 | 
			
		||||
    private final String show;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a episode wrapper to store episode information
 | 
			
		||||
     * @param url the URL
 | 
			
		||||
     * @param title the title
 | 
			
		||||
     * @param episodeNumber the episode
 | 
			
		||||
     * @param episode the episode
 | 
			
		||||
     * @param season the season
 | 
			
		||||
     * @param show the show
 | 
			
		||||
     * @param duration the duration
 | 
			
		||||
@ -47,10 +47,6 @@ public class EpisodeWrapper {
 | 
			
		||||
        return show;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public void setShow(String show) {
 | 
			
		||||
        this.show = show;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Return the unique id
 | 
			
		||||
     * @return the id
 | 
			
		||||
@ -67,14 +63,6 @@ public class EpisodeWrapper {
 | 
			
		||||
        return url;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the URL to the episode
 | 
			
		||||
     * @param url the URL
 | 
			
		||||
     */
 | 
			
		||||
    public void setUrl(String url) {
 | 
			
		||||
        this.url = url;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the title of the episode
 | 
			
		||||
     * @return the title
 | 
			
		||||
@ -83,14 +71,6 @@ public class EpisodeWrapper {
 | 
			
		||||
        return title;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the title of the episode 
 | 
			
		||||
     * @param title the title
 | 
			
		||||
     */
 | 
			
		||||
    public void setTitle(String title) {
 | 
			
		||||
        this.title = title;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the episode 
 | 
			
		||||
     * @return the episode 
 | 
			
		||||
@ -99,14 +79,6 @@ public class EpisodeWrapper {
 | 
			
		||||
        return episode;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the episode number
 | 
			
		||||
     * @param episode the episode
 | 
			
		||||
     */
 | 
			
		||||
    public void setEpisodeNumber(String episode) {
 | 
			
		||||
        this.episode = episode;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the season of the episode
 | 
			
		||||
     * @return the season
 | 
			
		||||
@ -115,14 +87,6 @@ public class EpisodeWrapper {
 | 
			
		||||
        return season;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the season of the episode
 | 
			
		||||
     * @param season the season
 | 
			
		||||
     */
 | 
			
		||||
    public void setSeason(String season) {
 | 
			
		||||
        this.season = season;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the duration of the episode
 | 
			
		||||
     * @return the duration
 | 
			
		||||
@ -131,14 +95,6 @@ public class EpisodeWrapper {
 | 
			
		||||
        return duration;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the duration of the episode
 | 
			
		||||
     * @param duration the duration
 | 
			
		||||
     */
 | 
			
		||||
    public void setDuration(String duration) {
 | 
			
		||||
        this.duration = duration;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        return title;
 | 
			
		||||
 | 
			
		||||
@ -16,11 +16,18 @@ import java.net.URL;
 | 
			
		||||
 */
 | 
			
		||||
public class ConnectionUtil {
 | 
			
		||||
    
 | 
			
		||||
    /**  The connection to the download URL */
 | 
			
		||||
    private HttpURLConnection httpConn;
 | 
			
		||||
    /** The input stream from the connection */
 | 
			
		||||
    private InputStream inputStream;
 | 
			
		||||
    private String fileName;
 | 
			
		||||
    /** The download size */
 | 
			
		||||
    private int contentLength;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Prepare the download connection and open the input stream
 | 
			
		||||
     * @param fileUrl the URL to the file
 | 
			
		||||
     * @throws IOException error preparing download
 | 
			
		||||
     */
 | 
			
		||||
    public void prepare(String fileUrl) throws IOException{
 | 
			
		||||
        URL url = new URL(fileUrl);
 | 
			
		||||
        httpConn = (HttpURLConnection) url.openConnection();
 | 
			
		||||
@ -28,29 +35,7 @@ public class ConnectionUtil {
 | 
			
		||||
        
 | 
			
		||||
        // always check HTTP response code first
 | 
			
		||||
        if (responseCode == HttpURLConnection.HTTP_OK) {
 | 
			
		||||
            String disposition = httpConn.getHeaderField("Content-Disposition");
 | 
			
		||||
            String contentType = httpConn.getContentType();
 | 
			
		||||
            contentLength = httpConn.getContentLength();
 | 
			
		||||
 
 | 
			
		||||
            if (disposition != null) {
 | 
			
		||||
                // extracts file name from header field
 | 
			
		||||
                int index = disposition.indexOf("filename=");
 | 
			
		||||
                if (index > 0) {
 | 
			
		||||
                    fileName = disposition.substring(index + 10,
 | 
			
		||||
                            disposition.length() - 1);
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                // extracts file name from URL
 | 
			
		||||
                fileName = fileUrl.substring(fileUrl.lastIndexOf("/") + 1,
 | 
			
		||||
                        fileUrl.length());
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
            // output for debugging purpose only
 | 
			
		||||
            System.out.println("Content-Type = " + contentType);
 | 
			
		||||
            System.out.println("Content-Disposition = " + disposition);
 | 
			
		||||
            System.out.println("Content-Length = " + contentLength);
 | 
			
		||||
            System.out.println("fileName = " + fileName);
 | 
			
		||||
 
 | 
			
		||||
            // opens input stream from the HTTP connection
 | 
			
		||||
            inputStream = httpConn.getInputStream();
 | 
			
		||||
 
 | 
			
		||||
@ -61,19 +46,27 @@ public class ConnectionUtil {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Close the inout stream and disconnect the download
 | 
			
		||||
     * @throws IOException 
 | 
			
		||||
     */
 | 
			
		||||
    public void disconnect() throws IOException {
 | 
			
		||||
        inputStream.close();
 | 
			
		||||
        httpConn.disconnect();
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
    public String getFileName() {
 | 
			
		||||
        return this.fileName;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the content length of the download
 | 
			
		||||
     * @return the content length
 | 
			
		||||
     */
 | 
			
		||||
    public int getContentLength() {
 | 
			
		||||
        return this.contentLength;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the download related inout stream
 | 
			
		||||
     * @return the input stream 
 | 
			
		||||
     */
 | 
			
		||||
    public InputStream getInputStream() {
 | 
			
		||||
        return this.inputStream;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,5 @@
 | 
			
		||||
package com.greinet.tvtotalripper.download;
 | 
			
		||||
 | 
			
		||||
import com.greinet.tvtotalripper.MetaDataWriter;
 | 
			
		||||
import com.greinet.tvtotalripper.crawler.CrawlerUtil;
 | 
			
		||||
import com.greinet.tvtotalripper.crawler.EpisodeWrapper;
 | 
			
		||||
import com.greinet.tvtotalripper.ui.SettingsRipperPanel;
 | 
			
		||||
@ -11,19 +10,27 @@ import java.io.InputStream;
 | 
			
		||||
import javax.swing.SwingWorker;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * @author agreiner
 | 
			
		||||
 * A task representing a single file download
 | 
			
		||||
 */
 | 
			
		||||
public class DownloadTask extends SwingWorker<Void, Void> {
 | 
			
		||||
    private static final int BUFFER_SIZE = 4096;
 | 
			
		||||
    
 | 
			
		||||
    /** The download buffer size */
 | 
			
		||||
    private static final int BUFFER_SIZE = 4096;
 | 
			
		||||
    /** The episode of the downloaded file */
 | 
			
		||||
    private final EpisodeWrapper episodeWrapper;
 | 
			
		||||
    
 | 
			
		||||
     
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a download task for a episode
 | 
			
		||||
     * @param episodeWrapper 
 | 
			
		||||
     */
 | 
			
		||||
    public DownloadTask(EpisodeWrapper episodeWrapper) {
 | 
			
		||||
        this.episodeWrapper = episodeWrapper;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the episode of the download
 | 
			
		||||
     * @return the episode
 | 
			
		||||
     */
 | 
			
		||||
    public EpisodeWrapper getEpisodeWrapper() {
 | 
			
		||||
        return episodeWrapper;
 | 
			
		||||
    }
 | 
			
		||||
@ -33,11 +40,14 @@ public class DownloadTask extends SwingWorker<Void, Void> {
 | 
			
		||||
        return episodeWrapper.getTitle();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public long fileSize = 0;
 | 
			
		||||
    /** The bytes size of the file to download */
 | 
			
		||||
    private long fileSize = 0;
 | 
			
		||||
    
 | 
			
		||||
    public long totalBytesRead = 0;
 | 
			
		||||
    /** the amount of downloaded bytes */
 | 
			
		||||
    private long totalBytesRead = 0;
 | 
			
		||||
    
 | 
			
		||||
    public int percentCompleted = 0;
 | 
			
		||||
    /** The completion percentage */
 | 
			
		||||
    private int percentCompleted = 0;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Executed in background thread
 | 
			
		||||
@ -55,29 +65,30 @@ public class DownloadTask extends SwingWorker<Void, Void> {
 | 
			
		||||
            String fixedTitle = episodeWrapper.getTitle().replace(":", " ");
 | 
			
		||||
            
 | 
			
		||||
            File outputFile = new File(SettingsRipperPanel.DOWNLOADFOLDER, fixedTitle+".mp4");
 | 
			
		||||
            FileOutputStream outputStream = new FileOutputStream(outputFile);
 | 
			
		||||
            byte[] buffer = new byte[BUFFER_SIZE];
 | 
			
		||||
            int bytesRead = -1;
 | 
			
		||||
            totalBytesRead = 0;
 | 
			
		||||
            percentCompleted = 0;
 | 
			
		||||
            int oldPercentCompleted = 0;
 | 
			
		||||
            fileSize = util.getContentLength();
 | 
			
		||||
            try (FileOutputStream outputStream = new FileOutputStream(outputFile)) {
 | 
			
		||||
                byte[] buffer = new byte[BUFFER_SIZE];
 | 
			
		||||
                int bytesRead;
 | 
			
		||||
                totalBytesRead = 0;
 | 
			
		||||
                percentCompleted = 0;
 | 
			
		||||
                int oldPercentCompleted = 0;
 | 
			
		||||
                fileSize = util.getContentLength();
 | 
			
		||||
                
 | 
			
		||||
            while ((bytesRead = inputStream.read(buffer)) != -1) {
 | 
			
		||||
                outputStream.write(buffer, 0, bytesRead);
 | 
			
		||||
                totalBytesRead += bytesRead;
 | 
			
		||||
                percentCompleted = (int) (totalBytesRead * 100 / fileSize);
 | 
			
		||||
                firePropertyChange(Long.toString(episodeWrapper.getId()), oldPercentCompleted, percentCompleted);
 | 
			
		||||
                oldPercentCompleted = percentCompleted;
 | 
			
		||||
                //setProgress(percentCompleted);
 | 
			
		||||
                while ((bytesRead = inputStream.read(buffer)) != -1) {
 | 
			
		||||
                    outputStream.write(buffer, 0, bytesRead);
 | 
			
		||||
                    totalBytesRead += bytesRead;
 | 
			
		||||
                    percentCompleted = (int) (totalBytesRead * 100 / fileSize);
 | 
			
		||||
                    firePropertyChange(Long.toString(episodeWrapper.getId()), oldPercentCompleted, percentCompleted);
 | 
			
		||||
                    oldPercentCompleted = percentCompleted;
 | 
			
		||||
                    //setProgress(percentCompleted);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
            outputStream.close();
 | 
			
		||||
 
 | 
			
		||||
            util.disconnect();
 | 
			
		||||
            
 | 
			
		||||
            MetaDataWriter mdp = new MetaDataWriter();
 | 
			
		||||
            mdp.writeMetadata(outputFile.getAbsolutePath(), episodeWrapper.getTitle(), episodeWrapper.getShow(), episodeWrapper.getShow(), episodeWrapper.getEpisode());
 | 
			
		||||
            
 | 
			
		||||
            // Enable MetaDataWriter
 | 
			
		||||
            // MetaDataWriter mdp = new MetaDataWriter();
 | 
			
		||||
            // mdp.writeMetadata(outputFile.getAbsolutePath(), episodeWrapper.getTitle(), episodeWrapper.getShow(), episodeWrapper.getShow(), episodeWrapper.getEpisode());
 | 
			
		||||
            
 | 
			
		||||
        } catch (IOException ex) {
 | 
			
		||||
            cancel(true);          
 | 
			
		||||
@ -86,7 +97,31 @@ public class DownloadTask extends SwingWorker<Void, Void> {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Executed in Swing's event dispatching thread
 | 
			
		||||
     * Get the download file size in bytes
 | 
			
		||||
     * @return the file size in bytes
 | 
			
		||||
     */
 | 
			
		||||
    public long getFileSize() {
 | 
			
		||||
        return fileSize;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** 
 | 
			
		||||
     * Get the amount of already downloaded bytes
 | 
			
		||||
     * @return the amount of already downloaded bytes  
 | 
			
		||||
     */
 | 
			
		||||
    public long getTotalBytesRead() {
 | 
			
		||||
        return totalBytesRead;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the completiton percentage
 | 
			
		||||
     * @return the completition percentage
 | 
			
		||||
     */
 | 
			
		||||
    public int getPercentCompleted() {
 | 
			
		||||
        return percentCompleted;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Fire a property change event with the progress value of 101 meaning that the task is done
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void done() {
 | 
			
		||||
 | 
			
		||||
@ -17,18 +17,27 @@ import javax.swing.JTextField;
 | 
			
		||||
import javax.swing.event.ListSelectionEvent;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * @author agreiner
 | 
			
		||||
 * The base panel for show and episode visualization
 | 
			
		||||
 */
 | 
			
		||||
public class BaseRipperPanel {
 | 
			
		||||
    
 | 
			
		||||
    /** The JPanel */
 | 
			
		||||
    private final JPanel panel;
 | 
			
		||||
    /** The Jlist for the elements */
 | 
			
		||||
    private JList<String> listPanel;
 | 
			
		||||
    /** The text field for the currently selected element */
 | 
			
		||||
    private JTextField textField;
 | 
			
		||||
    /** The button to select the currently selected element */
 | 
			
		||||
    private final JButton button;
 | 
			
		||||
    /** The label for the element count */
 | 
			
		||||
    private final JLabel label;
 | 
			
		||||
    private Map<String, String> elements;
 | 
			
		||||
    /** The map for the elements */
 | 
			
		||||
    private final Map<String, String> elements;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a base panel the display elements and select a specific one
 | 
			
		||||
     * @param elements the elements
 | 
			
		||||
     */
 | 
			
		||||
    public BaseRipperPanel(Map<String, String> elements){
 | 
			
		||||
        this.elements = elements;
 | 
			
		||||
        
 | 
			
		||||
@ -97,18 +106,34 @@ public class BaseRipperPanel {
 | 
			
		||||
        
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the JPanel
 | 
			
		||||
     * @return the JPanel
 | 
			
		||||
     */
 | 
			
		||||
    public JPanel getJPanel(){
 | 
			
		||||
        return panel;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the selection JButton
 | 
			
		||||
     * @return the JButton
 | 
			
		||||
     */
 | 
			
		||||
    public JButton getJButton(){
 | 
			
		||||
        return button;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the String representing the currently selected element
 | 
			
		||||
     * @return the selected element
 | 
			
		||||
     */
 | 
			
		||||
    public String getCurrentSelected(){
 | 
			
		||||
        return elements.get(listPanel.getSelectedValue());
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the Jlist of the elements
 | 
			
		||||
     * @return the JList
 | 
			
		||||
     */
 | 
			
		||||
    public JList getJList(){
 | 
			
		||||
        return listPanel;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -1,8 +1,3 @@
 | 
			
		||||
/*
 | 
			
		||||
 * To change this license header, choose License Headers in Project Properties.
 | 
			
		||||
 * To change this template file, choose Tools | Templates
 | 
			
		||||
 * and open the template in the editor.
 | 
			
		||||
 */
 | 
			
		||||
package com.greinet.tvtotalripper.ui;
 | 
			
		||||
 | 
			
		||||
import com.greinet.tvtotalripper.download.DownloadTask;
 | 
			
		||||
@ -25,21 +20,28 @@ import javax.swing.ListSelectionModel;
 | 
			
		||||
import javax.swing.event.ListSelectionEvent;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * @author agreiner
 | 
			
		||||
 * A download panel to show the current downloads
 | 
			
		||||
 */
 | 
			
		||||
public class DownloadRipperPanel implements PropertyChangeListener{
 | 
			
		||||
    
 | 
			
		||||
    /** The JPanel for download task visualization */
 | 
			
		||||
    private final JPanel panel;
 | 
			
		||||
    /** The JList for the downloads */
 | 
			
		||||
    private JList<DownloadTask> listTasks;
 | 
			
		||||
    private DefaultListModel<DownloadTask> listModel;
 | 
			
		||||
    /** The ListModel for the DownloadTasks */
 | 
			
		||||
    private final DefaultListModel<DownloadTask> listModel;
 | 
			
		||||
    /** The text field for the currently selected task */
 | 
			
		||||
    private JTextField textSelectedTask;
 | 
			
		||||
    /** The JLabel for the DownloadTask count */
 | 
			
		||||
    private final JLabel labelTaskCount;
 | 
			
		||||
    
 | 
			
		||||
    /** The list of download tasks */
 | 
			
		||||
    private final List<DownloadTask> downloadTasks;
 | 
			
		||||
    
 | 
			
		||||
    /** The information panel for the currently selected task */
 | 
			
		||||
    private DownloadTaskInformationPanel infoPanel;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a download panel
 | 
			
		||||
     */
 | 
			
		||||
    public DownloadRipperPanel(){
 | 
			
		||||
        
 | 
			
		||||
        downloadTasks = new ArrayList<>();
 | 
			
		||||
@ -102,14 +104,26 @@ public class DownloadRipperPanel implements PropertyChangeListener{
 | 
			
		||||
        panel.add(labelTaskCount, c);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the JPanel
 | 
			
		||||
     * @return the JPanel
 | 
			
		||||
     */
 | 
			
		||||
    public JPanel getJPanel(){
 | 
			
		||||
        return panel;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the currently selected task
 | 
			
		||||
     * @return the selected task
 | 
			
		||||
     */
 | 
			
		||||
    public DownloadTask getSelectedTask(){
 | 
			
		||||
        return listTasks.getSelectedValue();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Add a download task to be executed
 | 
			
		||||
     * @param task 
 | 
			
		||||
     */
 | 
			
		||||
    public void addTask(DownloadTask task){
 | 
			
		||||
        downloadTasks.add(task);
 | 
			
		||||
        task.execute();
 | 
			
		||||
@ -119,6 +133,10 @@ public class DownloadRipperPanel implements PropertyChangeListener{
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Listen to the property change events and remove a task if the new value is 101
 | 
			
		||||
     * @param evt the event parameters
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public void propertyChange(PropertyChangeEvent evt) {
 | 
			
		||||
        if(evt.getNewValue().equals(101)){
 | 
			
		||||
@ -137,6 +155,9 @@ public class DownloadRipperPanel implements PropertyChangeListener{
 | 
			
		||||
        panel.repaint();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Update the current task count
 | 
			
		||||
     */
 | 
			
		||||
    private void updateTaskCount(){
 | 
			
		||||
        labelTaskCount.setText(Integer.toString(listTasks.getModel().getSize()));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -8,7 +8,6 @@ package com.greinet.tvtotalripper.ui;
 | 
			
		||||
import com.greinet.tvtotalripper.download.DownloadTask;
 | 
			
		||||
import java.awt.GridLayout;
 | 
			
		||||
import java.beans.PropertyChangeEvent;
 | 
			
		||||
import java.beans.PropertyChangeListener;
 | 
			
		||||
import javax.swing.JLabel;
 | 
			
		||||
import javax.swing.JPanel;
 | 
			
		||||
import javax.swing.JProgressBar;
 | 
			
		||||
@ -21,22 +20,37 @@ import org.apache.commons.io.FileUtils;
 | 
			
		||||
 */
 | 
			
		||||
public class DownloadTaskInformationPanel extends JPanel{
 | 
			
		||||
    
 | 
			
		||||
    private JLabel labelTitle;
 | 
			
		||||
    private JLabel labelShow;
 | 
			
		||||
    private JLabel labelSeason;
 | 
			
		||||
    private JLabel labelEpisode;
 | 
			
		||||
    private JLabel labelDuration;
 | 
			
		||||
    private JLabel labelProgress;
 | 
			
		||||
    
 | 
			
		||||
    private JTextField textTitle;
 | 
			
		||||
    private JTextField textShow;
 | 
			
		||||
    private JTextField textSeason;
 | 
			
		||||
    private JTextField textEpisode;
 | 
			
		||||
    private JTextField textDuration;
 | 
			
		||||
    private JProgressBar progressBar;
 | 
			
		||||
    /** The label for the title */
 | 
			
		||||
    private final JLabel labelTitle;
 | 
			
		||||
    /** The label for the show */
 | 
			
		||||
    private final JLabel labelShow;
 | 
			
		||||
    /** The label for the season */
 | 
			
		||||
    private final JLabel labelSeason;
 | 
			
		||||
    /** The label for the episode */
 | 
			
		||||
    private final JLabel labelEpisode;
 | 
			
		||||
    /** The label for the duration */
 | 
			
		||||
    private final JLabel labelDuration;
 | 
			
		||||
    /** The label for the download progress */
 | 
			
		||||
    private final JLabel labelProgress;
 | 
			
		||||
    /** The text field for the title */
 | 
			
		||||
    private final JTextField textTitle;
 | 
			
		||||
    /** The text field for the show */
 | 
			
		||||
    private final JTextField textShow;
 | 
			
		||||
    /** The text field for the season */
 | 
			
		||||
    private final JTextField textSeason;
 | 
			
		||||
    /** The text field for the episode */
 | 
			
		||||
    private final JTextField textEpisode;
 | 
			
		||||
    /** The text field for the duration */
 | 
			
		||||
    private final JTextField textDuration;
 | 
			
		||||
    /** The text field for the download progress */
 | 
			
		||||
    private final JProgressBar progressBar;
 | 
			
		||||
    
 | 
			
		||||
    /** The currently visualized download task */
 | 
			
		||||
    public DownloadTask selectedDownloadTask;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a Panel for DownloadTask information visualization
 | 
			
		||||
     */
 | 
			
		||||
    public DownloadTaskInformationPanel(){
 | 
			
		||||
        
 | 
			
		||||
        labelTitle = new JLabel("Title");
 | 
			
		||||
@ -79,6 +93,9 @@ public class DownloadTaskInformationPanel extends JPanel{
 | 
			
		||||
        add(progressBar);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Clear all information
 | 
			
		||||
     */
 | 
			
		||||
    public void clearInformation(){
 | 
			
		||||
        this.selectedDownloadTask = null;
 | 
			
		||||
        textTitle.setText("");
 | 
			
		||||
@ -90,6 +107,10 @@ public class DownloadTaskInformationPanel extends JPanel{
 | 
			
		||||
        progressBar.setString("");
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the information of the download task
 | 
			
		||||
     * @param downloadTask the download task
 | 
			
		||||
     */
 | 
			
		||||
    public void setInformation(DownloadTask downloadTask){
 | 
			
		||||
        textTitle.setText(downloadTask.getEpisodeWrapper().getTitle());
 | 
			
		||||
        textTitle.setEditable(false);
 | 
			
		||||
@ -102,10 +123,10 @@ public class DownloadTaskInformationPanel extends JPanel{
 | 
			
		||||
        textDuration.setText(downloadTask.getEpisodeWrapper().getDuration());
 | 
			
		||||
        
 | 
			
		||||
        if(selectedDownloadTask != null && selectedDownloadTask.equals(downloadTask)){
 | 
			
		||||
            progressBar.setValue(downloadTask.percentCompleted);
 | 
			
		||||
            progressBar.setValue(downloadTask.getPercentCompleted());
 | 
			
		||||
            progressBar.setStringPainted(true);
 | 
			
		||||
            String done = FileUtils.byteCountToDisplaySize(downloadTask.totalBytesRead);
 | 
			
		||||
            String todo = FileUtils.byteCountToDisplaySize(downloadTask.fileSize);
 | 
			
		||||
            String done = FileUtils.byteCountToDisplaySize(downloadTask.getTotalBytesRead());
 | 
			
		||||
            String todo = FileUtils.byteCountToDisplaySize(downloadTask.getFileSize());
 | 
			
		||||
            progressBar.setString(done+"/"+todo);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
@ -114,8 +135,8 @@ public class DownloadTaskInformationPanel extends JPanel{
 | 
			
		||||
            if(selectedDownloadTask != null && evt.getPropertyName().equals(Long.toString(selectedDownloadTask.getEpisodeWrapper().getId()))){
 | 
			
		||||
                progressBar.setValue((int)evt.getNewValue());
 | 
			
		||||
                progressBar.setStringPainted(true);
 | 
			
		||||
                String done = FileUtils.byteCountToDisplaySize(downloadTask.totalBytesRead);
 | 
			
		||||
                String todo = FileUtils.byteCountToDisplaySize(downloadTask.fileSize);
 | 
			
		||||
                String done = FileUtils.byteCountToDisplaySize(downloadTask.getTotalBytesRead());
 | 
			
		||||
                String todo = FileUtils.byteCountToDisplaySize(downloadTask.getFileSize());
 | 
			
		||||
                progressBar.setString(done+"/"+todo);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
@ -16,23 +16,30 @@ import javax.swing.JTextField;
 | 
			
		||||
import javax.swing.event.ListSelectionEvent;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * @author agreiner
 | 
			
		||||
 * A panel to display the episodes of a season
 | 
			
		||||
 */
 | 
			
		||||
public class EpisodesRipperPanel {
 | 
			
		||||
    
 | 
			
		||||
    /** The JPanel */
 | 
			
		||||
    private final JPanel panel;
 | 
			
		||||
    
 | 
			
		||||
    /** The list for the episodes */
 | 
			
		||||
    private JList<EpisodeWrapper> listPanel;
 | 
			
		||||
    /** The list model for the episode list */
 | 
			
		||||
    private DefaultListModel<EpisodeWrapper> listModel;
 | 
			
		||||
    
 | 
			
		||||
    /** The text field for the currently selected episode */
 | 
			
		||||
    private JTextField textField;
 | 
			
		||||
    /** The button to start the episode download */
 | 
			
		||||
    private final JButton buttonDownload;
 | 
			
		||||
    /** The label for the episode count */
 | 
			
		||||
    private final JLabel label;
 | 
			
		||||
    /** The list of episodes */
 | 
			
		||||
    private final List<EpisodeWrapper> episodes;
 | 
			
		||||
    
 | 
			
		||||
    /** The button to download all episodes in the list */
 | 
			
		||||
    private final JButton buttonDownloadAll;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a panel to display episodes in a list
 | 
			
		||||
     * @param episodes the episodes to display
 | 
			
		||||
     */
 | 
			
		||||
    public EpisodesRipperPanel(List<EpisodeWrapper> episodes){
 | 
			
		||||
        this.episodes = episodes;
 | 
			
		||||
        
 | 
			
		||||
@ -104,19 +111,34 @@ public class EpisodesRipperPanel {
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the JPanel
 | 
			
		||||
     * @return the JPanel
 | 
			
		||||
     */
 | 
			
		||||
    public JPanel getJPanel(){
 | 
			
		||||
        return panel;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the currently selecte episode
 | 
			
		||||
     * @return 
 | 
			
		||||
     */
 | 
			
		||||
    public EpisodeWrapper getCurrentSelected(){
 | 
			
		||||
        return listPanel.getSelectedValue();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the download button
 | 
			
		||||
     * @return the download button 
 | 
			
		||||
     */
 | 
			
		||||
    public JButton getDownloadButton(){
 | 
			
		||||
        return buttonDownload;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the download all button
 | 
			
		||||
     * @return the download all button
 | 
			
		||||
     */
 | 
			
		||||
    public JButton getDownloadAllButton(){
 | 
			
		||||
        return buttonDownloadAll;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -21,22 +21,30 @@ import org.openqa.selenium.WebElement;
 | 
			
		||||
 * @author agreiner
 | 
			
		||||
 */
 | 
			
		||||
public class RipperWindow {
 | 
			
		||||
    
 | 
			
		||||
    private final JFrame frame;
 | 
			
		||||
    /** The pane managing the tabs */
 | 
			
		||||
    private final JTabbedPane tabbedPane;
 | 
			
		||||
    
 | 
			
		||||
    /** The panel for the shows */
 | 
			
		||||
    private JComponent panel1;
 | 
			
		||||
    /** The panel for the seasons */
 | 
			
		||||
    private JComponent panel2;
 | 
			
		||||
    /** The panel for the episodes */
 | 
			
		||||
    private JComponent panel3;
 | 
			
		||||
    private JComponent panel4;
 | 
			
		||||
    private JComponent panel5;
 | 
			
		||||
    
 | 
			
		||||
    private BaseRipperPanel showRipperPanel;
 | 
			
		||||
    private SettingsRipperPanel srp;
 | 
			
		||||
    private DownloadRipperPanel drp;
 | 
			
		||||
    /** The panel for the downloads */
 | 
			
		||||
    private final JComponent panel4;
 | 
			
		||||
    /** The panel for the settings */
 | 
			
		||||
    private final JComponent panel5;
 | 
			
		||||
    /** The show panel */
 | 
			
		||||
    private final BaseRipperPanel showRipperPanel;
 | 
			
		||||
    /** The settings panel */
 | 
			
		||||
    private final SettingsRipperPanel srp;
 | 
			
		||||
    /** The downloads panel */
 | 
			
		||||
    private final DownloadRipperPanel drp;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Create the main application UI
 | 
			
		||||
     */
 | 
			
		||||
    public RipperWindow(){
 | 
			
		||||
        frame = new JFrame("TV Total Ripper");
 | 
			
		||||
        JFrame frame = new JFrame("TV Total Ripper");
 | 
			
		||||
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 | 
			
		||||
        
 | 
			
		||||
        tabbedPane = new JTabbedPane();
 | 
			
		||||
@ -69,10 +77,18 @@ public class RipperWindow {
 | 
			
		||||
        frame.setVisible(true);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * The main method to start the program
 | 
			
		||||
     * @param args the arguments
 | 
			
		||||
     */
 | 
			
		||||
    public static void main(String[] args) {
 | 
			
		||||
        RipperWindow ripperWindow = new RipperWindow();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a show panel listing all available shows
 | 
			
		||||
     * @return the shopw panel
 | 
			
		||||
     */
 | 
			
		||||
    private BaseRipperPanel createShowsPanel(){
 | 
			
		||||
        List<WebElement> shows = CrawlerUtil.getShows();
 | 
			
		||||
        Map<String, String> namesToUrls = shows.stream().collect(Collectors.toMap(e -> e.findElement(By.xpath(".//img")).getAttribute("alt") , e -> e.getAttribute("href")));
 | 
			
		||||
@ -91,6 +107,11 @@ public class RipperWindow {
 | 
			
		||||
        return brp;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a seaon panel for a selected show
 | 
			
		||||
     * @param url the URL to the show
 | 
			
		||||
     * @return the season panel
 | 
			
		||||
     */
 | 
			
		||||
    private BaseRipperPanel createSeasonsPanel(String url){
 | 
			
		||||
        List<WebElement> seasons = CrawlerUtil.getSeasons(url);
 | 
			
		||||
        Map<String, String> elements = seasons.stream().collect(Collectors.toMap(e -> e.getText(), e -> e.getText()));
 | 
			
		||||
@ -108,23 +129,23 @@ public class RipperWindow {
 | 
			
		||||
        return brp;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a episode panel
 | 
			
		||||
     * @param url the URL to the episode list
 | 
			
		||||
     * @param seasonName the name of the selected season
 | 
			
		||||
     * @return the episode panel
 | 
			
		||||
     */
 | 
			
		||||
    private EpisodesRipperPanel createEpisodesPanel(String url, String seasonName){
 | 
			
		||||
        List<EpisodeWrapper> episodes = CrawlerUtil.getEpisodes(url, seasonName);
 | 
			
		||||
        
 | 
			
		||||
        EpisodesRipperPanel erp = new EpisodesRipperPanel(episodes);
 | 
			
		||||
        
 | 
			
		||||
        erp.getDownloadButton().addActionListener(new ActionListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void actionPerformed(ActionEvent e) {
 | 
			
		||||
                drp.addTask(new DownloadTask(erp.getCurrentSelected()));
 | 
			
		||||
            }
 | 
			
		||||
        erp.getDownloadButton().addActionListener((ActionEvent e) -> {
 | 
			
		||||
            drp.addTask(new DownloadTask(erp.getCurrentSelected()));
 | 
			
		||||
        });
 | 
			
		||||
        
 | 
			
		||||
        erp.getDownloadAllButton().addActionListener(new ActionListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void actionPerformed(ActionEvent e) {
 | 
			
		||||
                episodes.forEach(d -> drp.addTask(new DownloadTask(d)));
 | 
			
		||||
            }
 | 
			
		||||
        erp.getDownloadAllButton().addActionListener((ActionEvent e) -> {
 | 
			
		||||
            episodes.forEach(d -> drp.addTask(new DownloadTask(d)));
 | 
			
		||||
        });
 | 
			
		||||
        return erp;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -22,13 +22,22 @@ import javax.swing.JTextField;
 | 
			
		||||
 */
 | 
			
		||||
public class SettingsRipperPanel {
 | 
			
		||||
    
 | 
			
		||||
    /** The JPanel to visualize the settings */
 | 
			
		||||
    private JPanel panel;
 | 
			
		||||
    private JLabel labelDownloadFolder;
 | 
			
		||||
    /** The JLabel for the download folder selection */
 | 
			
		||||
    private final JLabel labelDownloadFolder;
 | 
			
		||||
    /** The text field for the current download folder */
 | 
			
		||||
    private JTextField textDownloadFolder;
 | 
			
		||||
    /** The file chooser to select the download folder */
 | 
			
		||||
    private JFileChooser fileChooserDownloadFolder;
 | 
			
		||||
    /** The download folder */
 | 
			
		||||
    public static File DOWNLOADFOLDER = new File(".");
 | 
			
		||||
    private JButton button;
 | 
			
		||||
    /** The JButton to open the file chooser dialog */
 | 
			
		||||
    private final JButton button;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a settings panel
 | 
			
		||||
     */
 | 
			
		||||
    public SettingsRipperPanel(){
 | 
			
		||||
        panel = new JPanel();
 | 
			
		||||
        panel.setLayout(new GridBagLayout());
 | 
			
		||||
@ -53,10 +62,6 @@ public class SettingsRipperPanel {
 | 
			
		||||
        textDownloadFolder.setPreferredSize(new Dimension(500, 30));
 | 
			
		||||
        panel.add(textDownloadFolder,gbc);
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
        gbc.gridx=8;
 | 
			
		||||
        gbc.gridy=1;
 | 
			
		||||
        gbc.gridwidth=1;
 | 
			
		||||
@ -81,10 +86,12 @@ public class SettingsRipperPanel {
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the JPanel
 | 
			
		||||
     * @return  the JPanel
 | 
			
		||||
     */
 | 
			
		||||
    public JPanel getPanel() {
 | 
			
		||||
        return panel;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user