Package me.mabra.hellonzb.unrar

Source Code of me.mabra.hellonzb.unrar.CompleteRarExtractor

/*******************************************************************************
* HelloNzb -- The Binary Usenet Tool
* Copyright (C) 2010-2013 Matthias F. Brandstetter
* https://sourceforge.net/projects/hellonzb/
*
* 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/>.
******************************************************************************/

package me.mabra.hellonzb.unrar;

import me.mabra.hellonzb.HelloNzb;
import me.mabra.hellonzb.HelloNzbConstants;
import me.mabra.hellonzb.HelloNzbToolkit;
import me.mabra.hellonzb.parser.NzbParser;
import me.mabra.hellonzb.util.MyLogger;
import me.mabra.hellonzb.util.StreamGobbler;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* This class is used as background thread to extract a RAR archive.
* It will assume all volumes of the RAR archive have already been downloaded.
*
* @author Matthias F. Brandstetter
*/
public class CompleteRarExtractor implements Runnable
{
  /** main application object */
  private HelloNzb mainApp;
 
  /** parser object to process */
  private NzbParser parser;
 
  /** central logger object */
  private MyLogger logger;
 
  /** download directory from application preferences */
  private File dlDir;

  /** nzb file name **/
  private String nzbFilename;

  /** A list of all part files of the RAR archive */
  private List<String> rarPartFiles;
 
 
  public CompleteRarExtractor(HelloNzb mainApp, NzbParser parser) throws RuntimeException
  {
    this.mainApp = mainApp;
    this.logger = mainApp.getLogger();
    this.parser = parser;
    this.rarPartFiles = new ArrayList<>();

    // download directory
    nzbFilename = parser.getName();
    nzbFilename = HelloNzbToolkit.getLastFilename(nzbFilename);
    dlDir = new File(parser.getDownloadFolder());
    if(!dlDir.isDirectory())
      throw new RuntimeException("Invalid directory for RAR extraction");
  }
 
  public void run()
  {
    String rarFilename = "";
   
    // search all files within destination directory
    String filenames[] = dlDir.list();
    if(filenames == null)
      return;
    else
      java.util.Arrays.sort(filenames);
   
    for(String filename : filenames)
    {
      if(filename.toLowerCase().endsWith(".rar"))
      {
        rarFilename = filename;
        break;
      }
    }
   
    // valid rar filename found?
    try
    {
      if(!rarFilename.isEmpty())
      {
        logger.msg("Extracting RAR archive to " + dlDir, MyLogger.SEV_INFO);

        String userPw = parser.getArchivePassword();
        int exitVal = callUnrarCmdLine(rarFilename, dlDir, userPw != null ? userPw : "-");

        // if extraction failed, try to extract password from file names
        if(exitVal > 0)
        {
          // target extraction folder empty?
          File dir = new File(dlDir + File.separator + HelloNzbConstants.UNRAR_SUBDIR);
          File [] files = dir.listFiles();
          if(files == null || files.length == 0)
          {
            // check for a password in the NZB file name
            Pattern pattern = Pattern.compile("\\{\\{.*\\}\\}$");
            Matcher matcher = pattern.matcher(nzbFilename);
            if(matcher.find())
            {
              String pwd = matcher.group();
              pwd = pwd.substring(2, pwd.length() - 2);
              logger.msg("Retrying to extract archive with password = " + pwd, MyLogger.SEV_INFO);
              exitVal = callUnrarCmdLine(rarFilename, dlDir, pwd);
            }
          }
        }

        if(exitVal == 0)
        {
          parser.saveToDelete(rarPartFiles);
          parser.unrarSucceeded(new File(rarFilename).getName());
          parser.setUnrarDestFolder(dlDir + File.separator + HelloNzbConstants.UNRAR_SUBDIR);
        }
        else
          parser.unrarFailed();
      }
      else
      {
        logger.msg("No (suitable) .rar file for extraction found", MyLogger.SEV_INFO);
        parser.unrarFailed();
      }
    }
    catch(Exception ex)
    {
      logger.printStackTrace(ex);
      parser.unrarFailed();
    }
    finally
    {
      mainApp.rarExtractDone(parser);
    }
  }
 
  private int callUnrarCmdLine(String rarFilename, File destination, String pwd)
      throws IOException, InterruptedException
  {
    Vector<String> cmd = new Vector<String>();
    String finalDestDir = destination + File.separator + HelloNzbConstants.UNRAR_SUBDIR;
    File finalDest = new File(finalDestDir);
 
    // check if destination directory exists
    if(!finalDest.exists())
      finalDest.mkdirs();
    if(!finalDest.exists())
    {
      logger.msg("Could not create target archive for RAR extraction", MyLogger.SEV_ERROR);
      return -1;
    }
   
    // yes, do the unrar extract!
    String execLocation = mainApp.getPrefValue("DownloadSettingsUnrarExeLocation");
   
    // create command to execute
    cmd.add(execLocation);
    cmd.add("x");
    cmd.add("-p" + pwd);
    cmd.add("-y");
    cmd.add("-r");
    cmd.add("-idp");
    cmd.add(rarFilename);
    cmd.add(finalDestDir);

    rarPartFiles.clear();
    logger.msg("Starting Unrar extraction: " + cmd, MyLogger.SEV_INFO);
   
    // execute command
    String [] cmdArray = cmd.toArray(new String[] {});
    Runtime rt = Runtime.getRuntime();
    Process proc = rt.exec(cmdArray, null, destination);
    StreamGobbler errGobbler = new StreamGobbler(logger, proc.getErrorStream(), "Unrar (Error)");
    StreamGobbler outGobbler = new StreamGobbler(logger, proc.getInputStream(), "Unrar");
   
    // fetch command's STDOUT and STDERR
    errGobbler.start();
    outGobbler.start();
   
    // wait until program has finished
    int exitVal = proc.waitFor();
    logger.msg("Unrar command exit value: " + exitVal, MyLogger.SEV_INFO);

    // get RAR archive part file names
    for(String line : outGobbler.getLines())
    {
      String l = line.trim();
      if(l.startsWith("Extracting from "))
        rarPartFiles.add(l.substring(16));
    }

    return exitVal;
  }
}








































TOP

Related Classes of me.mabra.hellonzb.unrar.CompleteRarExtractor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.