Browse Source

Support for unpacking 7Zip files.

Same password support as for unrar.
Can be enabled and disabled.
Includes 7za 9.20 for Windows and OSX.
pull/71/head
ShyPike 13 years ago
parent
commit
f27c16ea9f
  1. 5
      SABnzbd.py
  2. 33
      interfaces/Config/templates/config_switches.tmpl
  3. BIN
      osx/7zip/7za
  4. 52
      osx/7zip/License.txt
  5. 5
      package.py
  6. 1
      sabnzbd/cfg.py
  7. 5
      sabnzbd/interface.py
  8. 198
      sabnzbd/newsunpack.py
  9. 2
      sabnzbd/postproc.py
  10. 2
      sabnzbd/skintext.py
  11. BIN
      win/7zip/7za.exe
  12. 29
      win/7zip/license.txt

5
SABnzbd.py

@ -484,6 +484,11 @@ def print_modules():
else:
logging.warning(Ta('unzip binary... NOT found!'))
if sabnzbd.newsunpack.SEVEN_COMMAND:
logging.info("7za binary... found (%s)", sabnzbd.newsunpack.SEVEN_COMMAND)
else:
logging.warning(Ta('7za binary... NOT found!'))
if not sabnzbd.WIN32:
if sabnzbd.newsunpack.NICE_COMMAND:
logging.info("nice binary... found (%s)", sabnzbd.newsunpack.NICE_COMMAND)

33
interfaces/Config/templates/config_switches.tmpl

@ -156,72 +156,77 @@
<input type="checkbox" name="quick_check" id="quick_check" value="1" <!--#if int($quick_check) > 0 then 'checked="checked"' else ""#--> />
<span class="desc">$T('explain-quick_check')</span>
</div>
<div class="field-pair alt">
<div class="field-pair alt <!--#if not $have_unrar then "disabled" else "" #-->">
<label class="config" for="enable_unrar">$T('opt-enable_unrar')</label>
<input type="checkbox" name="enable_unrar" id="enable_unrar" value="1" <!--#if int($enable_unrar) > 0 then 'checked="checked"' else ""#--> />
<span class="desc">$T('explain-enable_unrar')</span>
</div>
<div class="field-pair">
<div class="field-pair <!--#if not $have_unzip then "disabled" else "" #-->">
<label class="config" for="enable_unzip">$T('opt-enable_unzip')</label>
<input type="checkbox" name="enable_unzip" id="enable_unzip" value="1" <!--#if int($enable_unzip) > 0 then 'checked="checked"' else ""#--> />
<span class="desc">$T('explain-enable_unzip')</span>
</div>
<div class="field-pair alt">
<div class="field-pair alt <!--#if not $have_7zip then "disabled" else "" #-->">
<label class="config" for="enable_7zip">$T('opt-enable_7zip')</label>
<input type="checkbox" name="enable_7zip" id="enable_7zip" value="1" <!--#if int($enable_7zip) > 0 then 'checked="checked"' else ""#--> />
<span class="desc">$T('explain-enable_7zip')</span>
</div>
<div class="field-pair">
<label class="config" for="enable_filejoin">$T('opt-enable_filejoin')</label>
<input type="checkbox" name="enable_filejoin" id="enable_filejoin" value="1" <!--#if int($enable_filejoin) > 0 then 'checked="checked"' else ""#--> />
<span class="desc">$T('explain-enable_filejoin')</span>
</div>
<div class="field-pair">
<div class="field-pair alt">
<label class="config" for="enable_tsjoin">$T('opt-enable_tsjoin')</label>
<input type="checkbox" name="enable_tsjoin" id="enable_tsjoin" value="1" <!--#if int($enable_tsjoin) > 0 then 'checked="checked"' else ""#--> />
<span class="desc">$T('explain-ts_join')</span>
</div>
<div class="field-pair alt">
<div class="field-pair">
<label class="config" for="enable_par_cleanup">$T('opt-enable_par_cleanup')</label>
<input type="checkbox" name="enable_par_cleanup" id="enable_par_cleanup" value="1" <!--#if int($enable_par_cleanup) > 0 then 'checked="checked"' else ""#--> />
<span class="desc">$T('explain-enable_par_cleanup')</span>
</div>
<div class="field-pair">
<div class="field-pair alt">
<label class="config" for="fail_on_crc">$T('opt-fail_on_crc')</label>
<input type="checkbox" name="fail_on_crc" id="fail_on_crc" value="1" <!--#if int($fail_on_crc) > 0 then 'checked="checked"' else ""#--> />
<span class="desc">$T('explain-fail_on_crc')</span>
</div>
<div class="field-pair alt">
<div class="field-pair">
<label class="config" for="safe_postproc">$T('opt-safe_postproc')</label>
<input type="checkbox" name="safe_postproc" id="safe_postproc" value="1" <!--#if int($safe_postproc) > 0 then 'checked="checked"' else ""#--> />
<span class="desc">$T('explain-safe_postproc')</span>
</div>
<div class="field-pair">
<div class="field-pair alt">
<label class="config" for="sfv_check">$T('opt-sfv_check')</label>
<input type="checkbox" name="sfv_check" id="sfv_check" value="1" <!--#if int($sfv_check) > 0 then 'checked="checked"' else ""#--> />
<span class="desc">$T('explain-sfv_check')</span>
</div>
<div class="field-pair alt">
<div class="field-pair">
<label class="config" for="unpack_check">$T('opt-unpack_check')</label>
<input type="checkbox" name="unpack_check" id="unpack_check" value="1" <!--#if int($unpack_check) > 0 then 'checked="checked"' else ""#--> />
<span class="desc">$T('explain-unpack_check')</span>
</div>
<div class="field-pair <!--#if not $nt then "disabled" else "" #-->">
<div class="field-pair alt <!--#if not $nt then "disabled" else "" #-->">
<label class="config" for="par2_multicore">$T('opt-par2_multicore')</label>
<input type="checkbox" name="par2_multicore" id="par2_multicore" value="1" <!--#if int($par2_multicore) > 0 then 'checked="checked"' else ""#--> <!--#if not $nt then 'readonly="readonly" disabled="disabled"' else "" #--> />
<span class="desc">$T('explain-par2_multicore')</span>
</div>
<div class="field-pair alt">
<div class="field-pair">
<label class="config" for="par_option">$T('opt-par_option')</label>
<input type="text" name="par_option" id="par_option" value="$par_option" size="20" />
<span class="desc">$T('explain-par_option')</span>
</div>
<div class="field-pair <!--#if not $have_nice then "disabled" else "" #-->">
<div class="field-pair alt <!--#if not $have_nice then "disabled" else "" #-->">
<label class="config" for="nice">$T('opt-nice')</label>
<input type="text" name="nice" id="nice" value="$nice" size="20" <!--#if not $have_nice then 'readonly="readonly" disabled="disabled"' else "" #--> />
<span class="desc">$T('explain-nice')</span>
</div>
<div class="field-pair alt <!--#if not $have_ionice then "disabled" else "" #-->">
<div class="field-pair <!--#if not $have_ionice then "disabled" else "" #-->">
<label class="config" for="ionice">$T('opt-ionice')</label>
<input type="text" name="ionice" id="ionice" value="$ionice" size="20" <!--#if not $have_ionice then 'readonly="readonly" disabled="disabled"' else "" #--> />
<span class="desc">$T('explain-ionice')</span>
</div>
<div class="field-pair">
<div class="field-pair alt">
<input type="submit" value="$T('button-saveChanges')" class="saveButton" />
</div>
</fieldset>

BIN
osx/7zip/7za

Binary file not shown.

52
osx/7zip/License.txt

@ -0,0 +1,52 @@
7-Zip source code
~~~~~~~~~~~~~~~~~
License for use and distribution
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7-Zip Copyright (C) 1999-2010 Igor Pavlov.
Licenses for files are:
1) CPP/7zip/Compress/Rar* files: GNU LGPL + unRAR restriction
2) All other files: GNU LGPL
The GNU LGPL + unRAR restriction means that you must follow both
GNU LGPL rules and unRAR restriction rules.
GNU LGPL information
--------------------
This library 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 2.1 of the License, or (at your option) any later version.
This library 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 library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
unRAR restriction
-----------------
The decompression engine for RAR archives was developed using source
code of unRAR program.
All copyrights to original unRAR code are owned by Alexander Roshal.
The license for original unRAR code has the following restriction:
The unRAR sources cannot be used to re-create the RAR compression algorithm,
which is proprietary. Distribution of modified unRAR sources in separate form
or as a part of other software is permitted, provided that it is clearly
stated in the documentation and source comments that the code may
not be used to develop a RAR (WinRAR) compatible archiver.
--
Igor Pavlov

5
package.py

@ -327,6 +327,7 @@ data_files = [
'win/par2/',
'win/unzip/',
'win/unrar/',
'win/7zip/',
'icons/'
]
@ -418,7 +419,7 @@ if target == 'app':
setup_requires=['py2app'],
)
# copy unrar & par2 binary to avoid striping
# copy unrar, 7zip & par2 binary to avoid striping
os.system("mkdir dist/SABnzbd.app/Contents/Resources/osx>/dev/null")
os.system("mkdir dist/SABnzbd.app/Contents/Resources/osx/par2>/dev/null")
os.system("cp -pR osx/par2/ dist/SABnzbd.app/Contents/Resources/osx/par2>/dev/null")
@ -428,6 +429,8 @@ if target == 'app':
os.system("cp -pR osx/unrar/unrar dist/SABnzbd.app/Contents/Resources/osx/unrar/ >/dev/null")
else:
os.system("cp -pR osx/unrar/unrar-leopard dist/SABnzbd.app/Contents/Resources/osx/unrar/unrar >/dev/null")
os.system("cp -pR osx/7zip/License.txt dist/SABnzbd.app/Contents/Resources/osx/7zip/ >/dev/null")
os.system("cp -pR osx/7zip/7za dist/SABnzbd.app/Contents/Resources/osx/7zip/ >/dev/null")
os.system("cp icons/sabnzbd.ico dist/SABnzbd.app/Contents/Resources >/dev/null")
os.system("cp README.rtf dist/SABnzbd.app/Contents/Resources/Credits.rtf >/dev/null")
os.system("find dist/SABnzbd.app -name .git | xargs rm -rf")

1
sabnzbd/cfg.py

@ -87,6 +87,7 @@ start_paused = OptionBool('misc', 'start_paused', False)
enable_unrar = OptionBool('misc', 'enable_unrar', True)
enable_unzip = OptionBool('misc', 'enable_unzip', True)
enable_7zip = OptionBool('misc', 'enable_7zip', True)
enable_filejoin = OptionBool('misc', 'enable_filejoin', True)
enable_tsjoin = OptionBool('misc', 'enable_tsjoin', True)
enable_par_cleanup = OptionBool('misc', 'enable_par_cleanup', True)

5
sabnzbd/interface.py

@ -1134,7 +1134,7 @@ SWITCH_LIST = \
'ignore_samples', 'pause_on_post_processing', 'quick_check', 'nice', 'ionice',
'ssl_type', 'pre_script', 'pause_on_pwrar', 'ampm', 'sfv_check', 'folder_rename',
'unpack_check', 'quota_size', 'quota_day', 'quota_resume', 'quota_period',
'pre_check', 'max_art_tries', 'max_art_opt'
'pre_check', 'max_art_tries', 'max_art_opt', 'enable_7zip'
)
#------------------------------------------------------------------------------
@ -1154,6 +1154,9 @@ class ConfigSwitches(object):
conf['nt'] = sabnzbd.WIN32
conf['have_nice'] = bool(sabnzbd.newsunpack.NICE_COMMAND)
conf['have_ionice'] = bool(sabnzbd.newsunpack.IONICE_COMMAND)
conf['have_unrar'] = bool(sabnzbd.newsunpack.RAR_COMMAND)
conf['have_unzip'] = bool(sabnzbd.newsunpack.ZIP_COMMAND)
conf['have_7zip'] = bool(sabnzbd.newsunpack.SEVEN_COMMAND)
for kw in SWITCH_LIST:
conf[kw] = config.get_config('misc', kw)()

198
sabnzbd/newsunpack.py

@ -60,6 +60,8 @@ TARGET_RE = re.compile(r'^(?:File|Target): "(.+)" -')
EXTRACTFROM_RE = re.compile(r'^Extracting\sfrom\s(.+)')
SPLITFILE_RE = re.compile(r'\.(\d\d\d$)', re.I)
ZIP_RE = re.compile(r'\.(zip$)', re.I)
SEVENZIP_RE = re.compile(r'\.7z$', re.I)
SEVENMULTI_RE = re.compile(r'\.7z\.\d+$', re.I)
VOLPAR2_RE = re.compile(r'\.*vol[0-9]+\+[0-9]+\.par2', re.I)
FULLVOLPAR2_RE = re.compile(r'(.*[^.])(\.*vol[0-9]+\+[0-9]+\.par2)', re.I)
TS_RE = re.compile(r'\.(\d+)\.(ts$)', re.I)
@ -69,6 +71,7 @@ PAR2C_COMMAND = None
RAR_COMMAND = None
NICE_COMMAND = None
ZIP_COMMAND = None
SEVEN_COMMAND = None
IONICE_COMMAND = None
RAR_PROBLEM = False
CURL_COMMAND = None
@ -96,6 +99,8 @@ def find_programs(curdir):
sabnzbd.newsunpack.PAR2_COMMAND = check(curdir, 'osx/par2/par2-classic')
sabnzbd.newsunpack.RAR_COMMAND = check(curdir, 'osx/unrar/unrar')
if sabnzbd.DARWIN_INTEL:
sabnzbd.newsunpack.SEVEN_COMMAND = check(curdir, 'osx/7zip/7za')
if sabnzbd.WIN32:
if sabnzbd.WIN64 and cfg.allow_64bit_tools.get():
@ -107,6 +112,7 @@ def find_programs(curdir):
sabnzbd.newsunpack.RAR_COMMAND = check(curdir, 'win/unrar/UnRAR.exe')
sabnzbd.newsunpack.PAR2C_COMMAND = check(curdir, 'win/par2/par2-classic.exe')
sabnzbd.newsunpack.ZIP_COMMAND = check(curdir, 'win/unzip/unzip.exe')
sabnzbd.newsunpack.SEVEN_COMMAND = check(curdir, 'win/7zip/7za.exe')
sabnzbd.newsunpack.CURL_COMMAND = check(curdir, 'lib/curl.exe')
else:
if not sabnzbd.newsunpack.PAR2_COMMAND:
@ -116,6 +122,7 @@ def find_programs(curdir):
sabnzbd.newsunpack.NICE_COMMAND = find_on_path('nice')
sabnzbd.newsunpack.IONICE_COMMAND = find_on_path('ionice')
sabnzbd.newsunpack.ZIP_COMMAND = find_on_path('unzip')
sabnzbd.newsunpack.SEVEN_COMMAND = find_on_path('7za')
if not (sabnzbd.WIN32 or sabnzbd.DARWIN):
sabnzbd.newsunpack.RAR_PROBLEM = not unrar_check(sabnzbd.newsunpack.RAR_COMMAND)
@ -164,7 +171,7 @@ def SimpleRarExtract(rarfile, name):
return ret, output
#------------------------------------------------------------------------------
def unpack_magic(nzo, workdir, workdir_complete, dele, one_folder, joinables, zips, rars, ts, depth=0):
def unpack_magic(nzo, workdir, workdir_complete, dele, one_folder, joinables, zips, rars, sevens, ts, depth=0):
""" Do a recursive unpack from all archives in 'workdir' to 'workdir_complete'
"""
if depth > 5:
@ -174,9 +181,9 @@ def unpack_magic(nzo, workdir, workdir_complete, dele, one_folder, joinables, zi
if depth == 1:
# First time, ignore anything in workdir_complete
xjoinables, xzips, xrars, xts = build_filelists(workdir, None)
xjoinables, xzips, xrars, xsevens, xts = build_filelists(workdir, None)
else:
xjoinables, xzips, xrars, xts = build_filelists(workdir, workdir_complete)
xjoinables, xzips, xrars, xsevens, xts = build_filelists(workdir, workdir_complete)
rerun = False
newfiles = []
@ -214,6 +221,16 @@ def unpack_magic(nzo, workdir, workdir_complete, dele, one_folder, joinables, zi
logging.info('Unzip finished on %s', workdir)
nzo.set_action_line()
if cfg.enable_7zip():
new_sevens = [seven for seven in xsevens if seven not in sevens]
if new_sevens:
rerun = True
logging.info('7za starting on %s', workdir)
if unseven(nzo, workdir, workdir_complete, dele, one_folder, new_sevens):
error = True
logging.info('7za finished on %s', workdir)
nzo.set_action_line()
if cfg.enable_tsjoin():
new_ts = [_ts for _ts in xts if _ts not in ts]
if new_ts:
@ -228,7 +245,7 @@ def unpack_magic(nzo, workdir, workdir_complete, dele, one_folder, joinables, zi
if rerun:
z, y = unpack_magic(nzo, workdir, workdir_complete, dele, one_folder,
xjoinables, xzips, xrars, xts, depth)
xjoinables, xzips, xrars, xsevens, xts, depth)
if z:
error = z
if y:
@ -748,12 +765,169 @@ def ZIP_Extract(zipfile, extraction_path, one_folder):
startupinfo=stup, creationflags=creationflags)
output = p.stdout.read()
logging.debug('unzip output: %s', output)
ret = p.wait()
return ret
#------------------------------------------------------------------------------
# 7Zip Functions
#------------------------------------------------------------------------------
def unseven(nzo, workdir, workdir_complete, delete, one_folder, sevens):
""" Unpack multiple sets '7z' of 7Zip files from 'workdir' to 'workdir_complete.
When 'delete' is set, originals will be deleted.
"""
i = 0
unseven_failed = False
tms = time()
# Find multi-volume sets, because 7zip will not provide actual set members
sets = {}
for seven in sevens:
name, ext = os.path.splitext(seven)
ext = ext.strip('.')
if not ext.isdigit():
name = seven
ext = None
if name not in sets:
sets[name] = []
if ext:
sets[name].append(ext)
# Unpack each set
for seven in sets:
extensions = sets[seven]
logging.info("Starting extract on 7zip set/file: %s ", seven)
nzo.set_action_line(T('Unpacking'), '%s' % unicoder(seven))
if workdir_complete and seven.startswith(workdir):
extraction_path = workdir_complete
else:
extraction_path = os.path.split(seven)[0]
res, msg = seven_extract(nzo, seven, extensions, extraction_path, one_folder, delete)
if res:
unseven_failed = True
nzo.set_unpack_info('Unpack', msg)
else:
i += 1
if not unseven_failed:
msg = T('%s files in %s') % (str(i), format_time_string(time() - tms))
nzo.set_unpack_info('Unpack', msg)
return unseven_failed
def seven_extract(nzo, sevenset, extensions, extraction_path, one_folder, delete):
""" Unpack single set 'sevenset' to 'extraction_path',
with password tries
Return fail==0(ok)/fail==1(error)/fail==2(wrong password), new_files, sevens
"""
fail = 0
if nzo.password:
passwords = [nzo.password]
else:
passwords = []
pw_file = cfg.password_file.get_path()
if pw_file:
try:
pwf = open(pw_file, 'r')
passwords = pwf.read().split('\n')
# Remove empty lines and space-only passwords and remove surrounding spaces
passwords = [pw.strip('\r\n ') for pw in passwords if pw.strip('\r\n ')]
pwf.close()
logging.info('Read the passwords file %s', pw_file)
except IOError:
logging.info('Failed to read the passwords file %s', pw_file)
if nzo.password:
# If an explicit password was set, add a retry without password, just in case.
passwords.append('')
elif not passwords or not nzo.encrypted:
# If we're not sure about encryption, start with empty password
# and make sure we have at least the empty password
passwords.insert(0, '')
for password in passwords:
if password:
logging.debug('Trying 7zip with password "%s"', password)
msg = T('Trying 7zip with password "%s"') % unicoder(password)
nzo.fail_msg = msg
nzo.set_unpack_info('Unpack', msg)
fail, msg = seven_extract_core(sevenset, extensions, extraction_path, one_folder, delete, password)
if fail != 2:
break
nzo.fail_msg = ''
if fail == 2:
logging.error('%s (%s)', Ta('Unpacking failed, archive requires a password'), latin1(os.path.split(sevenset)[1]))
return fail, msg
def seven_extract_core(sevenset, extensions, extraction_path, one_folder, delete, password):
""" Unpack single 7Z set 'sevenset' to 'extraction_path'
Return fail==0(ok)/fail==1(error)/fail==2(wrong password), message
"""
msg = None
if one_folder:
method = 'e' # Unpack without folders
else:
method = 'x' # Unpack with folders
if sabnzbd.WIN32 or sabnzbd.DARWIN:
case = '-ssc-' # Case insensitive
else:
case = '-ssc' # Case sensitive
if password:
password = '-p%s' % password
else:
password = '-p'
if len(extensions) > 0:
name = '%s.001' % sevenset
else:
name = sevenset
if not os.path.exists(name):
return 1, T('7ZIP set "%s" is incomplete, cannot unpack') % unicoder(sevenset)
command = [SEVEN_COMMAND, method, '-y', '-aou', case, password,
'-o%s' % extraction_path, name]
stup, need_shell, command, creationflags = build_command(command)
p = subprocess.Popen(command, shell=need_shell, stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
startupinfo=stup, creationflags=creationflags)
output = p.stdout.read()
logging.debug('7za output: %s', output)
ret = p.wait()
if ret == 0 and delete:
if extensions:
for ext in extensions:
path = '%s.%s' % (sevenset, ext)
try:
os.remove(path)
except:
logging.warning(Ta('Deleting %s failed!'), latin1(path))
else:
try:
os.remove(sevenset)
except:
logging.warning(Ta('Deleting %s failed!'), latin1(sevenset))
# Always return an error message, even when return code is 0
return ret, T('Could not unpack %s') % unicoder(sevenset)
#------------------------------------------------------------------------------
# PAR2 Functions
#------------------------------------------------------------------------------
@ -786,7 +960,7 @@ def par2_repair(parfile_nzf, nzo, workdir, setname):
nzo.set_action_line(T('Repair'), T('Starting Repair'))
logging.info('Scanning "%s"', parfile)
joinables, zips, rars, ts = build_filelists(workdir, None, check_rar=False)
joinables, zips, rars, sevens, ts = build_filelists(workdir, None, check_rar=False)
finished, readd, pars, datafiles, used_joinables = PAR_Verify(parfile, parfile_nzf, nzo,
setname, joinables)
@ -1235,7 +1409,7 @@ def build_filelists(workdir, workdir_complete, check_rar=True):
""" Build filelists, if workdir_complete has files, ignore workdir.
Optionally test content to establish RAR-ness
"""
joinables, zips, rars, filelist = ([], [], [], [])
joinables, zips, rars, sevens, filelist = ([], [], [], [], [])
if workdir_complete:
for root, dirs, files in os.walk(workdir_complete):
@ -1247,10 +1421,13 @@ def build_filelists(workdir, workdir_complete, check_rar=True):
for _file in files:
filelist.append(os.path.join(root, _file))
sevens = [f for f in filelist if SEVENZIP_RE.search(f)]
sevens.extend([f for f in filelist if SEVENMULTI_RE.search(f)])
if check_rar:
joinables = [f for f in filelist if SPLITFILE_RE.search(f) and not is_rarfile(f)]
joinables = [f for f in filelist if f not in sevens and SPLITFILE_RE.search(f) and not is_rarfile(f)]
else:
joinables = [f for f in filelist if SPLITFILE_RE.search(f)]
joinables = [f for f in filelist if f not in sevens and SPLITFILE_RE.search(f)]
zips = [f for f in filelist if ZIP_RE.search(f)]
@ -1259,14 +1436,15 @@ def build_filelists(workdir, workdir_complete, check_rar=True):
else:
rars = [f for f in filelist if RAR_RE.search(f)]
ts = [f for f in filelist if TS_RE.search(f) and f not in joinables]
ts = [f for f in filelist if TS_RE.search(f) and f not in joinables and f not in sevens]
logging.debug("build_filelists(): joinables: %s", joinables)
logging.debug("build_filelists(): zips: %s", zips)
logging.debug("build_filelists(): rars: %s", rars)
logging.debug("build_filelists(): 7zips: %s", sevens)
logging.debug("build_filelists(): ts: %s", ts)
return (joinables, zips, rars, ts)
return (joinables, zips, rars, sevens, ts)
def QuickCheck(set, nzo):

2
sabnzbd/postproc.py

@ -340,7 +340,7 @@ def process_job(nzo):
#set the current nzo status to "Extracting...". Used in History
nzo.status = Status.EXTRACTING
logging.info("Running unpack_magic on %s", filename)
unpack_error, newfiles = unpack_magic(nzo, workdir, tmp_workdir_complete, flag_delete, one_folder, (), (), (), ())
unpack_error, newfiles = unpack_magic(nzo, workdir, tmp_workdir_complete, flag_delete, one_folder, (), (), (), (), ())
logging.info("unpack_magic finished on %s", filename)
else:
nzo.set_unpack_info('Unpack', T('No post-processing because of failed verification'))

2
sabnzbd/skintext.py

@ -365,6 +365,8 @@ SKIN_TEXT = {
'explain-enable_unrar' : TT('Enable built-in unrar functionality.'),
'opt-enable_unzip' : TT('Enable Unzip'),
'explain-enable_unzip' : TT('Enable built-in unzip functionality.'),
'opt-enable_7zip' : TT('Enable 7zip'),
'explain-enable_7zip' : TT('Enable built-in 7zip functionality.'),
'opt-enable_filejoin' : TT('Enable Filejoin'),
'explain-enable_filejoin' : TT('Join files ending in .001, .002 etc. into one file.'),
'opt-enable_tsjoin' : TT('Enable TS Joining'),

BIN
win/7zip/7za.exe

Binary file not shown.

29
win/7zip/license.txt

@ -0,0 +1,29 @@
7-Zip Command line version
~~~~~~~~~~~~~~~~~~~~~~~~~~
License for use and distribution
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7-Zip Copyright (C) 1999-2010 Igor Pavlov.
7za.exe is distributed under the GNU LGPL license
Notes:
You can use 7-Zip on any computer, including a computer in a commercial
organization. You don't need to register or pay for 7-Zip.
GNU LGPL information
--------------------
This library 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 2.1 of the License, or (at your option) any later version.
This library 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 can receive a copy of the GNU Lesser General Public License from
http://www.gnu.org/
Loading…
Cancel
Save