Compare commits

...

11 Commits

Author SHA1 Message Date
Safihre
75a16e3588 Update text files for 3.4.2RC1 2021-09-30 09:04:12 +02:00
Safihre
1453032ad6 rXX files are popular extensions and don't need renames
Closes #1955
2021-09-29 13:53:47 +02:00
Safihre
824ab4afad Do not search whole file when checking if txt or nzb file 2021-09-29 13:53:37 +02:00
Safihre
73dd41c67f Only run process_unpacked_par2 when cleanup happened
Relates to https://forums.sabnzbd.org/viewtopic.php?f=1&t=25552
2021-09-29 13:53:32 +02:00
Safihre
59ee77355d Make add_parfile return if it could actually add the file
Maybe it was long finished, which could result in crashes.
Closes #1953
2021-09-29 13:53:20 +02:00
Safihre
5c758773ad Do not rename in decode_par2 if the filename didn't change
Closes #1952
2021-09-29 13:53:14 +02:00
Safihre
46de49df06 Set version to 3.4.1 2021-09-23 09:21:11 +02:00
Safihre
d1c54a9a74 Merge branch 'develop' 2021-09-23 08:50:17 +02:00
Safihre
447a7b684c Update text files for 3.4.1 2021-09-23 08:50:04 +02:00
Safihre
82379481dd Revert "Un-pin version of PyInstaller"
This reverts commit a95714710b.
2021-09-23 08:44:44 +02:00
puzzledsab
06f9e28170 Don't show undefined if metric is bytes in speedometer slider (#1951) 2021-09-22 13:52:57 +02:00
11 changed files with 56 additions and 32 deletions

View File

@@ -1,7 +1,7 @@
Metadata-Version: 1.0
Name: SABnzbd
Version: 3.4.0
Summary: SABnzbd-3.4.0
Version: 3.4.2RC1
Summary: SABnzbd-3.4.2RC1
Home-page: https://sabnzbd.org
Author: The SABnzbd Team
Author-email: team@sabnzbd.org

View File

@@ -1,6 +1,16 @@
Release Notes - SABnzbd 3.4.0
Release Notes - SABnzbd 3.4.2 Release Candidate 1
=========================================================
## Bugfixes since 3.4.1
- Crash when `.par2` files were missing during download.
- Prevent scanning the whole file to identify the correct extension.
- `.rXX` extensions were renamed to `.rXX.rar`.
- Processing unpacked `.par2` files would also process source
`.par2` files and could result in duplicate (`.1`) filenames.
## Bugfixes since 3.4.0
- macOS: Failed to run on M1 systems or older macOS versions.
## Changes since 3.3.1
- Extended `Deobfuscate final filenames` to attempt to set the correct
file extension based on the file signature if the file extension is

View File

@@ -1,5 +1,5 @@
# Basic build requirements
pyinstaller
pyinstaller==4.2
setuptools
pkginfo
certifi

View File

@@ -21,7 +21,7 @@ function ViewModel() {
self.extraQueueColumns = ko.observableArray([]).extend({ persist: 'extraColumns' });
self.extraHistoryColumns = ko.observableArray([]).extend({ persist: 'extraHistoryColumns' });
self.showActiveConnections = ko.observable(false).extend({ persist: 'showActiveConnections' });
self.speedMetrics = { K: "KB/s", M: "MB/s", G: "GB/s" };
self.speedMetrics = { '': "B/s", K: "KB/s", M: "MB/s", G: "GB/s" };
// Set information varibales
self.title = ko.observable();
@@ -1231,4 +1231,4 @@ function ViewModel() {
// Activate tooltips
if(!isMobile) $('[data-tooltip="true"]').tooltip({ trigger: 'hover', container: 'body' })
}
}

View File

@@ -64,9 +64,9 @@ def decode_par2(parfile: str) -> List[str]:
with open(filepath, "rb") as fileToMatch:
first16k_data = fileToMatch.read(16384)
# Check if we have this hash
# Check if we have this hash and the filename is different
file_md5of16k = hashlib.md5(first16k_data).digest()
if file_md5of16k in md5of16k:
if file_md5of16k in md5of16k and fn != md5of16k[file_md5of16k]:
new_path = os.path.join(dirname, md5of16k[file_md5of16k])
# Make sure it's a unique name
unique_filename = get_unique_filename(new_path)
@@ -166,7 +166,7 @@ def deobfuscate_list(filelist: List[str], usefulname: str):
# 2. if no meaningful extension, add it
# 3. based on detecting obfuscated filenames
# to be sure, only keep really exsiting files:
# to be sure, only keep really existing files:
filelist = [f for f in filelist if os.path.isfile(f)]
# let's see if there are files with uncommon/unpopular (so: obfuscated) extensions
@@ -176,7 +176,7 @@ def deobfuscate_list(filelist: List[str], usefulname: str):
for file in filelist:
if file_extension.has_popular_extension(file):
# common extension, like .doc or .iso, so assume OK and change nothing
logging.debug("extension of %s looks common", file)
logging.debug("Extension of %s looks common", file)
newlist.append(file)
else:
# uncommon (so: obfuscated) extension
@@ -220,6 +220,7 @@ def deobfuscate_list(filelist: List[str], usefulname: str):
# check that file is still there (and not renamed by the secondary renaming process below)
if not os.path.isfile(filename):
continue
logging.debug("Deobfuscate inspecting %s", filename)
# Do we need to rename this file?
# Criteria: big, not-excluded extension, obfuscated (in that order)

View File

@@ -1118,8 +1118,7 @@ def par2_repair(parfile_nzf: NzbFile, nzo: NzbObject, workdir, setname, single):
readd = False
for extrapar in nzo.extrapars[setname][:]:
# Make sure we only get new par2 files
if extrapar not in nzo.finished_files and extrapar not in nzo.files:
nzo.add_parfile(extrapar)
if nzo.add_parfile(extrapar):
readd = True
if readd:
return readd, result

View File

@@ -1105,8 +1105,7 @@ class NzbObject(TryList):
self.postpone_pars(nzf, setname)
# Get the next one
for new_nzf in self.extrapars[setname]:
if not new_nzf.completed:
self.add_parfile(new_nzf)
if self.add_parfile(new_nzf):
# Add it to the top
self.files.remove(new_nzf)
self.files.insert(0, new_nzf)
@@ -1143,8 +1142,8 @@ class NzbObject(TryList):
added_blocks = 0
while added_blocks < needed_blocks:
new_nzf = block_list.pop()
self.add_parfile(new_nzf)
added_blocks += new_nzf.blocks
if self.add_parfile(new_nzf):
added_blocks += new_nzf.blocks
logging.info("Added %s blocks to %s", added_blocks, self.final_name)
return added_blocks
@@ -1433,15 +1432,18 @@ class NzbObject(TryList):
self.unwanted_ext = 2
@synchronized(NZO_LOCK)
def add_parfile(self, parfile: NzbFile):
def add_parfile(self, parfile: NzbFile) -> bool:
"""Add parfile to the files to be downloaded
Resets trylist just to be sure
Adjust download-size accordingly
Returns False when the file couldn't be added
"""
if not parfile.completed and parfile not in self.files and parfile not in self.finished_files:
parfile.reset_try_list()
self.files.append(parfile)
self.bytes_tried -= parfile.bytes_left
return True
return False
@synchronized(NZO_LOCK)
def remove_parset(self, setname: str):
@@ -1468,12 +1470,12 @@ class NzbObject(TryList):
# from all the sets. This probably means we get too much par2, but it's worth it.
blocks_new = 0
for new_nzf in self.extrapars[parset]:
self.add_parfile(new_nzf)
blocks_new += new_nzf.blocks
# Enough now?
if blocks_new >= self.bad_articles:
logging.info("Prospectively added %s repair blocks to %s", blocks_new, self.final_name)
break
if self.add_parfile(new_nzf):
blocks_new += new_nzf.blocks
# Enough now?
if blocks_new >= self.bad_articles:
logging.info("Prospectively added %s repair blocks to %s", blocks_new, self.final_name)
break
# Reset NZO TryList
self.reset_try_list()

View File

@@ -520,7 +520,8 @@ def process_job(nzo: NzbObject):
# Run further post-processing
if (all_ok or not cfg.safe_postproc()) and not nzb_list:
# Use par2 files to deobfuscate unpacked file names
if cfg.process_unpacked_par2():
# Only if we also run cleanup, so not to process the "regular" par2 files
if flag_delete and cfg.process_unpacked_par2():
newfiles = deobfuscate.recover_par2_names(newfiles)
if cfg.deobfuscate_final_filenames():

View File

@@ -8,10 +8,11 @@ Note: extension always contains a leading dot
import puremagic
import os
import sys
import re
from typing import List
from pathlib import Path
from sabnzbd.filesystem import get_ext
# common extension from https://www.computerhope.com/issues/ch001789.htm
POPULAR_EXT = (
"3g2",
@@ -234,16 +235,19 @@ DOWNLOAD_EXT = (
"xpi",
)
# combine to one tuple, with unique entries:
# Combine to one tuple, with unique entries:
ALL_EXT = tuple(set(POPULAR_EXT + DOWNLOAD_EXT))
# prepend a dot to each extension, because we work with a leading dot in extensions
# Prepend a dot to each extension, because we work with a leading dot in extensions
ALL_EXT = tuple(["." + i for i in ALL_EXT])
# Match old-style multi-rar extensions
SIMPLE_RAR_RE = re.compile(r"\.r\d\d\d?$", re.I)
def has_popular_extension(file_path: str) -> bool:
"""returns boolean if the extension of file_path is a popular, well-known extension"""
file_extension = get_ext(file_path)
return file_extension in ALL_EXT
return file_extension in ALL_EXT or SIMPLE_RAR_RE.match(file_extension)
def all_possible_extensions(file_path: str) -> List[str]:
@@ -264,9 +268,12 @@ def what_is_most_likely_extension(file_path: str) -> str:
# Check if text or NZB, as puremagic is not good at that.
try:
txt = Path(file_path).read_text()
# Only read the start, don't need the whole file
with open(file_path, "r") as inp_file:
txt = inp_file.read(200).lower()
# Yes, a text file ... so let's check if it's even an NZB:
if txt.lower().find("<nzb xmlns=") >= 0 or txt.lower().find("!doctype nzb public") >= 0:
if "!doctype nzb public" in txt or "<nzb xmlns=" in txt:
# yes, contains NZB signals:
return ".nzb"
else:

View File

@@ -5,5 +5,5 @@
# You MUST use double quotes (so " and not ')
__version__ = "3.4.0"
__baseline__ = "7d5207aa67c7d558d2490595ed03aa7809fe9f70"
__version__ = "3.4.1"
__baseline__ = "447a7b684c32ca28dc8dfff285330c2c7de98377"

View File

@@ -29,6 +29,10 @@ class Test_File_Extension:
assert file_extension.has_popular_extension("blabla/blabla.mkv")
assert file_extension.has_popular_extension("blabla/blabla.srt")
assert file_extension.has_popular_extension("djjddj/aaaaa.epub")
assert file_extension.has_popular_extension("test/testing.r01")
assert file_extension.has_popular_extension("test/testing.r901")
assert not file_extension.has_popular_extension("test/testing")
assert not file_extension.has_popular_extension("test/testing.rar01")
assert not file_extension.has_popular_extension("98ads098f098fa.a0ds98f098asdf")
def test_what_is_most_likely_extension(self):