mirror of
https://github.com/clinton-hall/nzbToMedia.git
synced 2025-08-21 05:43:16 -07:00
Fix lint errors
This commit is contained in:
parent
c5a8dc664b
commit
27f6c05788
34 changed files with 313 additions and 285 deletions
62
.flake8
Normal file
62
.flake8
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
[flake8]
|
||||||
|
max-line-length = 79
|
||||||
|
max-doc-length = 79
|
||||||
|
verbose = 2
|
||||||
|
statistics = True
|
||||||
|
min-version = 2.7
|
||||||
|
require-code = True
|
||||||
|
exclude =
|
||||||
|
.github/
|
||||||
|
.pytest_cache/
|
||||||
|
.tox/
|
||||||
|
.venv*/
|
||||||
|
build/
|
||||||
|
htmlcov/
|
||||||
|
logs/
|
||||||
|
ignore =
|
||||||
|
; -- flake8 --
|
||||||
|
; E501 line too long
|
||||||
|
; E722 do not use bare 'except' (duplicates B001)
|
||||||
|
; W503 line break before binary operator
|
||||||
|
; W505 doc line too long
|
||||||
|
E501, E722, W503, W505
|
||||||
|
|
||||||
|
; -- flake8-docstrings --
|
||||||
|
; D100 Missing docstring in public module
|
||||||
|
; D101 Missing docstring in public class
|
||||||
|
; D102 Missing docstring in public method
|
||||||
|
; D103 Missing docstring in public function
|
||||||
|
; D104 Missing docstring in public package
|
||||||
|
; D105 Missing docstring in magic method
|
||||||
|
; D107 Missing docstring in __init__
|
||||||
|
; D200 One-line docstring should fit on one line with quotes
|
||||||
|
; D202 No blank lines allowed after function docstring
|
||||||
|
; D205 1 blank line required between summary line and description
|
||||||
|
; D400 First line should end with a period
|
||||||
|
; D401 First line should be in imperative mood
|
||||||
|
; D402 First line should not be the function's "signature"
|
||||||
|
D100, D101, D102, D103, D104, D105, D107
|
||||||
|
|
||||||
|
; -- flake8-future-import --
|
||||||
|
; x = 1 for missing, 5 for present
|
||||||
|
; FIx6 nested_scopes 2.2
|
||||||
|
; FIx7 generators 2.3
|
||||||
|
; FIx2 with_statement 2.6
|
||||||
|
; FIx1 absolute_import 3.0
|
||||||
|
; FIx0 division 3.0
|
||||||
|
; FIx3 print_function 3.0
|
||||||
|
; FIx4 unicode_literals 3.0
|
||||||
|
; FIx5 generator_stop 3.7
|
||||||
|
; FIx8 annotations 4.0
|
||||||
|
; FI90 __future__ import does not exist
|
||||||
|
FI10, FI11, FI13, FI14, FI58
|
||||||
|
|
||||||
|
per-file-ignores =
|
||||||
|
; F401 imported but unused
|
||||||
|
; E402 module level import not at top of file
|
||||||
|
; nzbTo*.py: E265, E266, E402
|
||||||
|
; TorrentToMedia.py: E402
|
||||||
|
; nzb2media/__init__.py: E402, F401
|
||||||
|
; nzb2media/utils/__init__.py: F401
|
||||||
|
; nzb2media/plugins/downloaders/configuration.py: F401
|
||||||
|
; nzb2media/plugins/downloaders/utils.py: F401
|
|
@ -5,10 +5,45 @@ repos:
|
||||||
- id: trailing-whitespace
|
- id: trailing-whitespace
|
||||||
- id: end-of-file-fixer
|
- id: end-of-file-fixer
|
||||||
- id: check-yaml
|
- id: check-yaml
|
||||||
|
- id: check-json
|
||||||
|
- id: check-toml
|
||||||
|
- id: check-xml
|
||||||
|
- id: check-case-conflict
|
||||||
- id: debug-statements
|
- id: debug-statements
|
||||||
|
- id: detect-private-key
|
||||||
- id: double-quote-string-fixer
|
- id: double-quote-string-fixer
|
||||||
|
- id: fix-byte-order-marker
|
||||||
- id: name-tests-test
|
- id: name-tests-test
|
||||||
- id: requirements-txt-fixer
|
- id: requirements-txt-fixer
|
||||||
|
- repo: https://github.com/pycqa/flake8
|
||||||
|
rev: '6.0.0'
|
||||||
|
hooks:
|
||||||
|
- id: flake8
|
||||||
|
name: Flake8 primary tests
|
||||||
|
additional_dependencies:
|
||||||
|
- flake8-bugbear
|
||||||
|
- flake8-commas
|
||||||
|
- flake8-comprehensions
|
||||||
|
- flake8-docstrings
|
||||||
|
- flake8-future-import
|
||||||
|
- id: flake8
|
||||||
|
name: Flake8 selective tests
|
||||||
|
args: [
|
||||||
|
# ** SELECTIVE TESTS **
|
||||||
|
# Run flake8 tests (with plugins) for specific optional codes defined below
|
||||||
|
# -- flake8 --
|
||||||
|
# E123 closing bracket does not match indentation of opening bracket’s line
|
||||||
|
# E226 missing whitespace around arithmetic operator
|
||||||
|
# E241 multiple spaces after ‘,’
|
||||||
|
# E242 tab after ‘,’
|
||||||
|
# E704 multiple statements on one line
|
||||||
|
# W504 line break after binary operator
|
||||||
|
# W505 doc line too long
|
||||||
|
# -- flake8-bugbear --
|
||||||
|
# B902 Invalid first argument used for instance method.
|
||||||
|
# B903 Data class should be immutable or use __slots__ to save memory.
|
||||||
|
'--select=B902,B903,E123,E226,E241,E242,E704,W504,W505'
|
||||||
|
]
|
||||||
- repo: https://github.com/asottile/add-trailing-comma
|
- repo: https://github.com/asottile/add-trailing-comma
|
||||||
rev: v2.4.0
|
rev: v2.4.0
|
||||||
hooks:
|
hooks:
|
||||||
|
@ -34,5 +69,5 @@ repos:
|
||||||
[
|
[
|
||||||
"-rn", # Only display messages
|
"-rn", # Only display messages
|
||||||
"-sn", # Disable score
|
"-sn", # Disable score
|
||||||
"--rcfile=.pylintrc.ini", # Link to your config file
|
"--rcfile=.pylintrc", # Link to your config file
|
||||||
]
|
]
|
||||||
|
|
|
@ -38,6 +38,70 @@ load-plugins=
|
||||||
# no Warning level messages displayed, use"--disable=all --enable=classes
|
# no Warning level messages displayed, use"--disable=all --enable=classes
|
||||||
# --disable=W"
|
# --disable=W"
|
||||||
|
|
||||||
|
# See below for a list of codes
|
||||||
|
|
||||||
|
disable=
|
||||||
|
E1101, # no-member
|
||||||
|
|
||||||
|
W0141, # bad-builtin
|
||||||
|
W0149, # while-used
|
||||||
|
W0160, # consider-ternary-expression
|
||||||
|
W0201, # attribute-defined-outside-init
|
||||||
|
W0212, # protected-access
|
||||||
|
W0511, # fixme
|
||||||
|
W0601, # global-variable-undefined
|
||||||
|
W0602, # global-variable-not-assigned
|
||||||
|
W0603, # global-statement
|
||||||
|
W0612, # unused-variable
|
||||||
|
W0621, # redefined-outer-name
|
||||||
|
W0631, # undefined-loop-variable
|
||||||
|
W0703, # broad-except
|
||||||
|
W0717, # too-many-try-statements
|
||||||
|
W1202, # logging-format-interpolation
|
||||||
|
W1203, # logging-fstring-interpolation
|
||||||
|
W1404, # implicit-str-concat
|
||||||
|
W2901, # redefined-loop-name
|
||||||
|
W3101, # missing-timeout
|
||||||
|
W6001, # deprecated-typing-alias
|
||||||
|
|
||||||
|
C0103, # invalid-name
|
||||||
|
C0114, # missing-module-docstring
|
||||||
|
C0115, # missing-class-docstring
|
||||||
|
C0116, # missing-function-docstring
|
||||||
|
C0201, # consider-iterating-dictionary
|
||||||
|
C0206, # consider-using-dict-items
|
||||||
|
C0301, # line-too-long
|
||||||
|
C0415, # import-outside-toplevel
|
||||||
|
|
||||||
|
R0204, # redifined-variable-type
|
||||||
|
R0401, # cyclic-import
|
||||||
|
R0801, # duplicate-code
|
||||||
|
R0903, # too-few-public-methods
|
||||||
|
R0902, # too-many-instance-attributes
|
||||||
|
R0911, # too-many-return-statements
|
||||||
|
R0912, # too-many-branches
|
||||||
|
R0913, # too-many-arguments
|
||||||
|
R0914, # too-many-locals
|
||||||
|
R0915, # too-many-statements
|
||||||
|
R0916, # too-many-boolean-expressions
|
||||||
|
R1260, # too-complex
|
||||||
|
R1702, # too-many-nested-blocks
|
||||||
|
R1704, # redefined-argument-from-local
|
||||||
|
R1710, # inconsistent-return-statements
|
||||||
|
R5601, # confusing-consecutive-elif
|
||||||
|
R6103, # consider-using-assignment-expr
|
||||||
|
|
||||||
|
I0011, # locally-disabled
|
||||||
|
I0020, # suppressed-message
|
||||||
|
|
||||||
|
# Enable the message, report, category or checker with the given id(s). You can
|
||||||
|
# either give multiple identifier separated by comma (,) or put this option
|
||||||
|
# multiple time (only on the command line, not in the configuration file where
|
||||||
|
# it should appear only once). See also the "--disable" option for examples.
|
||||||
|
enable=
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------ CODES ------------------------
|
||||||
; # --- FATAL ---------
|
; # --- FATAL ---------
|
||||||
; F0001, # fatal
|
; F0001, # fatal
|
||||||
; F0002, # astroid-error
|
; F0002, # astroid-error
|
||||||
|
@ -459,70 +523,3 @@ load-plugins=
|
||||||
; I0022, # deprecated-pragma
|
; I0022, # deprecated-pragma
|
||||||
; I0023, # use-symbolic-message-instead
|
; I0023, # use-symbolic-message-instead
|
||||||
; I1101, # c-extension-no-member
|
; I1101, # c-extension-no-member
|
||||||
|
|
||||||
disable=
|
|
||||||
E1101, # no-member
|
|
||||||
|
|
||||||
W0141, # bad-builtin
|
|
||||||
W0149, # while-used
|
|
||||||
W0160, # consider-ternary-expression
|
|
||||||
W0201, # attribute-defined-outside-init
|
|
||||||
W0212, # protected-access
|
|
||||||
W0511, # fixme
|
|
||||||
W0601, # global-variable-undefined
|
|
||||||
W0602, # global-variable-not-assigned
|
|
||||||
W0603, # global-statement
|
|
||||||
W0612, # unused-variable
|
|
||||||
W0621, # redefined-outer-name
|
|
||||||
W0631, # undefined-loop-variable
|
|
||||||
W0703, # broad-except
|
|
||||||
W0717, # too-many-try-statements
|
|
||||||
W1202, # logging-format-interpolation
|
|
||||||
W1203, # logging-fstring-interpolation
|
|
||||||
W1404, # implicit-str-concat
|
|
||||||
W2901, # redefined-loop-name
|
|
||||||
W3101, # missing-timeout
|
|
||||||
W6001, # deprecated-typing-alias
|
|
||||||
W9016, # missing-type-do
|
|
||||||
|
|
||||||
C0103, # invalid-name
|
|
||||||
C0114, # missing-module-docstring
|
|
||||||
C0115, # missing-class-docstring
|
|
||||||
C0116, # missing-function-docstring
|
|
||||||
C0199, # docstring-first-line-empty
|
|
||||||
C0201, # consider-iterating-dictionary
|
|
||||||
C0206, # consider-using-dict-items
|
|
||||||
C0301, # line-too-long
|
|
||||||
C0415, # import-outside-toplevel
|
|
||||||
C1901, # compare-to-empty-string
|
|
||||||
C2001, # compare-to-zero
|
|
||||||
|
|
||||||
R0204, # redifined-variable-type
|
|
||||||
R0401, # cyclic-import
|
|
||||||
R0801, # duplicate-code
|
|
||||||
R0903, # too-few-public-methods
|
|
||||||
R0902, # too-many-instance-attributes
|
|
||||||
R0911, # too-many-return-statements
|
|
||||||
R0912, # too-many-branches
|
|
||||||
R0913, # too-many-arguments
|
|
||||||
R0914, # too-many-locals
|
|
||||||
R0915, # too-many-statements
|
|
||||||
R0916, # too-many-boolean-expressions
|
|
||||||
R1260, # too-complex
|
|
||||||
R1702, # too-many-nested-blocks
|
|
||||||
R1704, # redefined-argument-from-local
|
|
||||||
R1710, # inconsistent-return-statements
|
|
||||||
R5501, # else-if-used
|
|
||||||
R5601, # confusing-consecutive-elif
|
|
||||||
R6003, # consider-alternative-union-syntax
|
|
||||||
R6102, # consider-using-tuple
|
|
||||||
R6103, # consider-using-assignment-expr
|
|
||||||
|
|
||||||
I0011, # locally-disabled
|
|
||||||
I0020, # suppressed-message
|
|
||||||
|
|
||||||
# Enable the message, report, category or checker with the given id(s). You can
|
|
||||||
# either give multiple identifier separated by comma (,) or put this option
|
|
||||||
# multiple time (only on the command line, not in the configuration file where
|
|
||||||
# it should appear only once). See also the "--disable" option for examples.
|
|
||||||
enable=
|
|
|
@ -53,7 +53,7 @@ def process_torrent(input_directory, input_name, input_category, input_hash, inp
|
||||||
input_directory, input_name, input_category,
|
input_directory, input_name, input_category,
|
||||||
root, nzb2media.CATEGORIES,
|
root, nzb2media.CATEGORIES,
|
||||||
)
|
)
|
||||||
if input_category == '':
|
if not input_category:
|
||||||
input_category = 'UNCAT'
|
input_category = 'UNCAT'
|
||||||
|
|
||||||
usercat = input_category
|
usercat = input_category
|
||||||
|
@ -132,7 +132,7 @@ def process_torrent(input_directory, input_name, input_category, input_hash, inp
|
||||||
input_files = nzb2media.list_media_files(input_directory, archives=False, other=True, otherext=extensions)
|
input_files = nzb2media.list_media_files(input_directory, archives=False, other=True, otherext=extensions)
|
||||||
else:
|
else:
|
||||||
input_files = nzb2media.list_media_files(input_directory, other=True, otherext=extensions)
|
input_files = nzb2media.list_media_files(input_directory, other=True, otherext=extensions)
|
||||||
if len(input_files) == 0 and os.path.isfile(input_directory):
|
if not input_files and os.path.isfile(input_directory):
|
||||||
input_files = [input_directory]
|
input_files = [input_directory]
|
||||||
log.debug(f'Found 1 file to process: {input_directory}')
|
log.debug(f'Found 1 file to process: {input_directory}')
|
||||||
else:
|
else:
|
||||||
|
@ -173,7 +173,7 @@ def process_torrent(input_directory, input_name, input_category, input_hash, inp
|
||||||
else:
|
else:
|
||||||
continue # This file has not been recently moved or created, skip it
|
continue # This file has not been recently moved or created, skip it
|
||||||
|
|
||||||
if torrent_no_link == 0:
|
if not torrent_no_link:
|
||||||
try:
|
try:
|
||||||
nzb2media.copy_link(input_file, target_file, nzb2media.USE_LINK)
|
nzb2media.copy_link(input_file, target_file, nzb2media.USE_LINK)
|
||||||
nzb2media.remove_read_only(target_file)
|
nzb2media.remove_read_only(target_file)
|
||||||
|
@ -246,7 +246,7 @@ def process_torrent(input_directory, input_name, input_category, input_hash, inp
|
||||||
|
|
||||||
plex_update(input_category)
|
plex_update(input_category)
|
||||||
|
|
||||||
if result.status_code != 0:
|
if result.status_code:
|
||||||
if not nzb2media.TORRENT_RESUME_ON_FAILURE:
|
if not nzb2media.TORRENT_RESUME_ON_FAILURE:
|
||||||
log.error(
|
log.error(
|
||||||
'A problem was reported in the autoProcess* script. '
|
'A problem was reported in the autoProcess* script. '
|
||||||
|
@ -344,11 +344,11 @@ def main(args):
|
||||||
dir_name, input_name, subsection, input_hash or None, input_id or None,
|
dir_name, input_name, subsection, input_hash or None, input_id or None,
|
||||||
client_agent,
|
client_agent,
|
||||||
)
|
)
|
||||||
if results.status_code != 0:
|
if results.status_code:
|
||||||
log.error(f'A problem was reported when trying to perform a manual run for {section}:{subsection}.')
|
log.error(f'A problem was reported when trying to perform a manual run for {section}:{subsection}.')
|
||||||
result = results
|
result = results
|
||||||
|
|
||||||
if result.status_code == 0:
|
if not result.status_code:
|
||||||
log.info(f'The {args[0]} script completed successfully.')
|
log.info(f'The {args[0]} script completed successfully.')
|
||||||
else:
|
else:
|
||||||
log.error(f'A problem was reported in the {args[0]} script.')
|
log.error(f'A problem was reported in the {args[0]} script.')
|
||||||
|
|
|
@ -7,6 +7,20 @@ trigger:
|
||||||
- master
|
- master
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
- job: 'Lint'
|
||||||
|
pool:
|
||||||
|
vmImage: 'Ubuntu-latest'
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- task: UsePythonVersion@0
|
||||||
|
inputs:
|
||||||
|
versionSpec: '3.x'
|
||||||
|
architecture: 'x64'
|
||||||
|
|
||||||
|
- script: |
|
||||||
|
pip install pre-commit pylint -r requirements.txt
|
||||||
|
pre-commit run --all-files
|
||||||
|
displayName: 'Run pre-commit tests'
|
||||||
|
|
||||||
- job: 'Test'
|
- job: 'Test'
|
||||||
pool:
|
pool:
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
black
|
|
||||||
bump2version
|
bump2version
|
||||||
|
flake8
|
||||||
|
flake8-bugbear
|
||||||
|
flake8-commas
|
||||||
|
flake8-comprehensions
|
||||||
|
flake8-docstrings
|
||||||
|
flake8-future-import
|
||||||
mypy
|
mypy
|
||||||
pre-commit
|
pre-commit
|
||||||
pylint[spelling]
|
pylint[spelling]
|
||||||
|
|
|
@ -11,11 +11,11 @@ import subprocess
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
import typing
|
import typing
|
||||||
from subprocess import PIPE, DEVNULL
|
from subprocess import DEVNULL
|
||||||
|
|
||||||
from nzb2media import tool
|
|
||||||
from nzb2media import databases
|
from nzb2media import databases
|
||||||
from nzb2media import main_db
|
from nzb2media import main_db
|
||||||
|
from nzb2media import tool
|
||||||
from nzb2media import version_check
|
from nzb2media import version_check
|
||||||
from nzb2media.configuration import Config
|
from nzb2media.configuration import Config
|
||||||
from nzb2media.nzb.configuration import configure_nzbs
|
from nzb2media.nzb.configuration import configure_nzbs
|
||||||
|
@ -29,22 +29,6 @@ from nzb2media.utils.processes import restart
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
log.addHandler(logging.NullHandler())
|
log.addHandler(logging.NullHandler())
|
||||||
try:
|
|
||||||
import win32event
|
|
||||||
except ImportError:
|
|
||||||
if sys.platform == 'win32':
|
|
||||||
sys.exit('Please install pywin32')
|
|
||||||
|
|
||||||
|
|
||||||
def which(name) -> pathlib.Path | None:
|
|
||||||
with subprocess.Popen(['which', name], stdout=PIPE) as proc:
|
|
||||||
try:
|
|
||||||
proc_out, proc_err = proc.communicate()
|
|
||||||
except Exception:
|
|
||||||
return None
|
|
||||||
else:
|
|
||||||
location = proc_out.strip().decode()
|
|
||||||
return pathlib.Path(location)
|
|
||||||
|
|
||||||
|
|
||||||
def module_path(module=__file__):
|
def module_path(module=__file__):
|
||||||
|
|
|
@ -41,7 +41,7 @@ def process(*, section: str, dir_name: str, input_name: str = '', status: int =
|
||||||
input_name, dir_name = convert_to_ascii(input_name, dir_name)
|
input_name, dir_name = convert_to_ascii(input_name, dir_name)
|
||||||
fields = input_name.split('-')
|
fields = input_name.split('-')
|
||||||
gamez_id = fields[0].replace('[', '').replace(']', '').replace(' ', '')
|
gamez_id = fields[0].replace('[', '').replace(']', '').replace(' ', '')
|
||||||
download_status = 'Downloaded' if status == 0 else 'Wanted'
|
download_status = 'Downloaded' if not status else 'Wanted'
|
||||||
params = {'api_key': apikey, 'mode': 'UPDATEREQUESTEDSTATUS', 'db_id': gamez_id, 'status': download_status}
|
params = {'api_key': apikey, 'mode': 'UPDATEREQUESTEDSTATUS', 'db_id': gamez_id, 'status': download_status}
|
||||||
log.debug(f'Opening URL: {url}')
|
log.debug(f'Opening URL: {url}')
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -151,10 +151,10 @@ def process(*, section: str, dir_name: str, input_name: str = '', status: int =
|
||||||
status = 1
|
status = 1
|
||||||
if 'NZBOP_VERSION' in os.environ and os.environ['NZBOP_VERSION'][0:5] >= '14.0':
|
if 'NZBOP_VERSION' in os.environ and os.environ['NZBOP_VERSION'][0:5] >= '14.0':
|
||||||
print('[NZB] MARK=BAD')
|
print('[NZB] MARK=BAD')
|
||||||
if status == 0:
|
if not status:
|
||||||
if nzb2media.TRANSCODE == 1:
|
if nzb2media.TRANSCODE == 1:
|
||||||
result, new_dir_name = transcoder.transcode_directory(dir_name)
|
result, new_dir_name = transcoder.transcode_directory(dir_name)
|
||||||
if result == 0:
|
if not result:
|
||||||
log.debug(f'Transcoding succeeded for files in {dir_name}')
|
log.debug(f'Transcoding succeeded for files in {dir_name}')
|
||||||
dir_name = new_dir_name
|
dir_name = new_dir_name
|
||||||
log.debug(f'Config setting \'chmodDirectory\' currently set to {oct(chmod_directory)}')
|
log.debug(f'Config setting \'chmodDirectory\' currently set to {oct(chmod_directory)}')
|
||||||
|
|
|
@ -69,7 +69,7 @@ def process(*, section: str, dir_name: str, input_name: str = '', status: int =
|
||||||
# if listMediaFiles(dir_name, media=False, audio=True, meta=False, archives=False) and status:
|
# if listMediaFiles(dir_name, media=False, audio=True, meta=False, archives=False) and status:
|
||||||
# logger.info('Status shown as failed from Downloader, but valid video files found. Setting as successful.', SECTION)
|
# logger.info('Status shown as failed from Downloader, but valid video files found. Setting as successful.', SECTION)
|
||||||
# status = 0
|
# status = 0
|
||||||
if status == 0 and section == 'HeadPhones':
|
if not status and section == 'HeadPhones':
|
||||||
params = {'apikey': apikey, 'cmd': 'forceProcess', 'dir': remote_dir(dir_name) if remote_path else dir_name}
|
params = {'apikey': apikey, 'cmd': 'forceProcess', 'dir': remote_dir(dir_name) if remote_path else dir_name}
|
||||||
res = force_process(params, url, apikey, input_name, dir_name, section, wait_for)
|
res = force_process(params, url, apikey, input_name, dir_name, section, wait_for)
|
||||||
if res.status_code in {0, 1}:
|
if res.status_code in {0, 1}:
|
||||||
|
@ -81,7 +81,7 @@ def process(*, section: str, dir_name: str, input_name: str = '', status: int =
|
||||||
# The status hasn't changed. uTorrent can resume seeding now.
|
# The status hasn't changed. uTorrent can resume seeding now.
|
||||||
log.warning(f'The music album does not appear to have changed status after {wait_for} minutes. Please check your Logs')
|
log.warning(f'The music album does not appear to have changed status after {wait_for} minutes. Please check your Logs')
|
||||||
return ProcessResult.failure(f'{section}: Failed to post-process - No change in wanted status')
|
return ProcessResult.failure(f'{section}: Failed to post-process - No change in wanted status')
|
||||||
if status == 0 and section == 'Lidarr':
|
if not status and section == 'Lidarr':
|
||||||
route = f'{web_root}/api/v1/command'
|
route = f'{web_root}/api/v1/command'
|
||||||
url = nzb2media.utils.common.create_url(scheme, host, port, route)
|
url = nzb2media.utils.common.create_url(scheme, host, port, route)
|
||||||
headers = {'X-Api-Key': apikey}
|
headers = {'X-Api-Key': apikey}
|
||||||
|
|
|
@ -130,10 +130,10 @@ def process(*, section: str, dir_name: str, input_name: str = '', status: int =
|
||||||
import_subs(video)
|
import_subs(video)
|
||||||
rename_subs(dir_name)
|
rename_subs(dir_name)
|
||||||
if num_files > 0:
|
if num_files > 0:
|
||||||
if valid_files == num_files and not status == 0:
|
if valid_files == num_files and status:
|
||||||
log.info('Found Valid Videos. Setting status Success')
|
log.info('Found Valid Videos. Setting status Success')
|
||||||
status = 0
|
status = 0
|
||||||
if valid_files < num_files and status == 0:
|
if valid_files < num_files and not status:
|
||||||
log.info('Found corrupt videos. Setting status Failed')
|
log.info('Found corrupt videos. Setting status Failed')
|
||||||
status = 1
|
status = 1
|
||||||
if 'NZBOP_VERSION' in os.environ and os.environ['NZBOP_VERSION'][0:5] >= '14.0':
|
if 'NZBOP_VERSION' in os.environ and os.environ['NZBOP_VERSION'][0:5] >= '14.0':
|
||||||
|
@ -150,7 +150,7 @@ def process(*, section: str, dir_name: str, input_name: str = '', status: int =
|
||||||
return ProcessResult.success()
|
return ProcessResult.success()
|
||||||
elif nzb_extraction_by == 'Destination':
|
elif nzb_extraction_by == 'Destination':
|
||||||
log.info('Check for media files ignored because nzbExtractionBy is set to Destination.')
|
log.info('Check for media files ignored because nzbExtractionBy is set to Destination.')
|
||||||
if status == 0:
|
if not status:
|
||||||
log.info('Setting Status Success.')
|
log.info('Setting Status Success.')
|
||||||
else:
|
else:
|
||||||
log.info('Downloader reported an error during download or verification. Processing this as a failed download.')
|
log.info('Downloader reported an error during download or verification. Processing this as a failed download.')
|
||||||
|
@ -160,9 +160,10 @@ def process(*, section: str, dir_name: str, input_name: str = '', status: int =
|
||||||
status = 1
|
status = 1
|
||||||
if 'NZBOP_VERSION' in os.environ and os.environ['NZBOP_VERSION'][0:5] >= '14.0':
|
if 'NZBOP_VERSION' in os.environ and os.environ['NZBOP_VERSION'][0:5] >= '14.0':
|
||||||
print('[NZB] MARK=BAD')
|
print('[NZB] MARK=BAD')
|
||||||
if status == 0 and nzb2media.TRANSCODE == 1: # only transcode successful downloads
|
if not status and nzb2media.TRANSCODE == 1:
|
||||||
|
# only transcode successful downloads
|
||||||
result, new_dir_name = transcoder.transcode_directory(dir_name)
|
result, new_dir_name = transcoder.transcode_directory(dir_name)
|
||||||
if result == 0:
|
if not result:
|
||||||
log.debug(f'SUCCESS: Transcoding succeeded for files in {dir_name}')
|
log.debug(f'SUCCESS: Transcoding succeeded for files in {dir_name}')
|
||||||
dir_name = new_dir_name
|
dir_name = new_dir_name
|
||||||
log.debug(f'Config setting \'chmodDirectory\' currently set to {oct(chmod_directory)}')
|
log.debug(f'Config setting \'chmodDirectory\' currently set to {oct(chmod_directory)}')
|
||||||
|
@ -230,7 +231,7 @@ def process(*, section: str, dir_name: str, input_name: str = '', status: int =
|
||||||
for key, val in list(fork_params.items()):
|
for key, val in list(fork_params.items()):
|
||||||
if val is None:
|
if val is None:
|
||||||
del fork_params[key]
|
del fork_params[key]
|
||||||
if status == 0:
|
if not status:
|
||||||
if section == 'NzbDrone' and not apikey:
|
if section == 'NzbDrone' and not apikey:
|
||||||
log.info('No Sonarr apikey entered. Processing completed.')
|
log.info('No Sonarr apikey entered. Processing completed.')
|
||||||
return ProcessResult.success(f'{section}: Successfully post-processed {input_name}')
|
return ProcessResult.success(f'{section}: Successfully post-processed {input_name}')
|
||||||
|
@ -338,9 +339,8 @@ def process(*, section: str, dir_name: str, input_name: str = '', status: int =
|
||||||
elif section == 'SiCKRAGE':
|
elif section == 'SiCKRAGE':
|
||||||
if api_version >= 2:
|
if api_version >= 2:
|
||||||
success = True
|
success = True
|
||||||
else:
|
elif response.json()['result'] == 'success':
|
||||||
if response.json()['result'] == 'success':
|
success = True
|
||||||
success = True
|
|
||||||
elif section == 'NzbDrone':
|
elif section == 'NzbDrone':
|
||||||
try:
|
try:
|
||||||
res = response.json()
|
res = response.json()
|
||||||
|
@ -351,7 +351,7 @@ def process(*, section: str, dir_name: str, input_name: str = '', status: int =
|
||||||
log.warning(f'No scan id was returned due to: {error}')
|
log.warning(f'No scan id was returned due to: {error}')
|
||||||
scan_id = None
|
scan_id = None
|
||||||
started = False
|
started = False
|
||||||
if status != 0 and delete_failed and not os.path.dirname(dir_name) == dir_name:
|
if status and delete_failed and not os.path.dirname(dir_name) == dir_name:
|
||||||
log.debug(f'Deleting failed files and folder {dir_name}')
|
log.debug(f'Deleting failed files and folder {dir_name}')
|
||||||
remove_dir(dir_name)
|
remove_dir(dir_name)
|
||||||
if success:
|
if success:
|
||||||
|
|
|
@ -73,9 +73,8 @@ class Section(configobj.Section):
|
||||||
if key in options:
|
if key in options:
|
||||||
return options[key]
|
return options[key]
|
||||||
del subsections[subsection]
|
del subsections[subsection]
|
||||||
else:
|
elif section not in key:
|
||||||
if section not in key:
|
del to_return[section]
|
||||||
del to_return[section]
|
|
||||||
# cleanout empty sections and subsections
|
# cleanout empty sections and subsections
|
||||||
for key in [k for (k, v) in to_return.items() if not v]:
|
for key in [k for (k, v) in to_return.items() if not v]:
|
||||||
del to_return[key]
|
del to_return[key]
|
||||||
|
|
|
@ -113,21 +113,21 @@ def extract(file_path, output_destination):
|
||||||
cmd2.append('-p-') # don't prompt for password.
|
cmd2.append('-p-') # don't prompt for password.
|
||||||
with Popen(cmd2, stdout=DEVNULL, stderr=DEVNULL, startupinfo=info) as proc:
|
with Popen(cmd2, stdout=DEVNULL, stderr=DEVNULL, startupinfo=info) as proc:
|
||||||
res = proc.wait() # should extract files fine.
|
res = proc.wait() # should extract files fine.
|
||||||
if res == 0: # Both Linux and Windows return 0 for successful.
|
if not res: # Both Linux and Windows return 0 for successful.
|
||||||
log.info(f'EXTRACTOR: Extraction was successful for {file_path} to {output_destination}')
|
log.info(f'EXTRACTOR: Extraction was successful for {file_path} to {output_destination}')
|
||||||
success = 1
|
success = 1
|
||||||
elif len(passwords) > 0 and 'gunzip' not in cmd:
|
elif len(passwords) > 0 and 'gunzip' not in cmd:
|
||||||
log.info('EXTRACTOR: Attempting to extract with passwords')
|
log.info('EXTRACTOR: Attempting to extract with passwords')
|
||||||
for password in passwords:
|
for password in passwords:
|
||||||
if password == '': # if edited in windows or otherwise if blank lines.
|
if not password:
|
||||||
continue
|
continue # if edited in windows or otherwise if blank lines.
|
||||||
cmd2 = cmd
|
cmd2 = cmd
|
||||||
# append password here.
|
# append password here.
|
||||||
passcmd = f'-p{password}'
|
passcmd = f'-p{password}'
|
||||||
cmd2.append(passcmd)
|
cmd2.append(passcmd)
|
||||||
with Popen(cmd2, stdout=DEVNULL, stderr=DEVNULL, startupinfo=info) as proc:
|
with Popen(cmd2, stdout=DEVNULL, stderr=DEVNULL, startupinfo=info) as proc:
|
||||||
res = proc.wait() # should extract files fine.
|
res = proc.wait() # should extract files fine.
|
||||||
if (res >= 0 and platform == 'Windows') or res == 0:
|
if not res or (res >= 0 and platform == 'Windows'):
|
||||||
log.info(f'EXTRACTOR: Extraction was successful for {file_path} to {output_destination} using password: {password}')
|
log.info(f'EXTRACTOR: Extraction was successful for {file_path} to {output_destination} using password: {password}')
|
||||||
success = 1
|
success = 1
|
||||||
break
|
break
|
||||||
|
|
|
@ -20,8 +20,8 @@ class GitHub:
|
||||||
return data.json() if data.ok else []
|
return data.json() if data.ok else []
|
||||||
|
|
||||||
def commits(self):
|
def commits(self):
|
||||||
"""
|
"""Get the 100 most recent commits from the specified user/repo/branch, starting from HEAD.
|
||||||
Get the 100 most recent commits from the specified user/repo/branch, starting from HEAD.
|
|
||||||
user: The github username of the person whose repo you're querying
|
user: The github username of the person whose repo you're querying
|
||||||
repo: The repo name to query
|
repo: The repo name to query
|
||||||
branch: Optional, the branch name to show commits from
|
branch: Optional, the branch name to show commits from
|
||||||
|
@ -30,8 +30,8 @@ class GitHub:
|
||||||
return self._access_api(['repos', self.github_repo_user, self.github_repo, 'commits'], params={'per_page': 100, 'sha': self.branch})
|
return self._access_api(['repos', self.github_repo_user, self.github_repo, 'commits'], params={'per_page': 100, 'sha': self.branch})
|
||||||
|
|
||||||
def compare(self, base, head, per_page=1):
|
def compare(self, base, head, per_page=1):
|
||||||
"""
|
"""Get compares between base and head.
|
||||||
Get compares between base and head.
|
|
||||||
user: The github username of the person whose repo you're querying
|
user: The github username of the person whose repo you're querying
|
||||||
repo: The repo name to query
|
repo: The repo name to query
|
||||||
base: Start compare from branch
|
base: Start compare from branch
|
||||||
|
|
|
@ -11,9 +11,9 @@ log = logging.getLogger(__name__)
|
||||||
log.addHandler(logging.NullHandler())
|
log.addHandler(logging.NullHandler())
|
||||||
|
|
||||||
|
|
||||||
def db_filename(filename='nzbtomedia.db', suffix=None):
|
def db_filename(filename: str = 'nzbtomedia.db', suffix: str | None = None):
|
||||||
"""
|
"""Return the correct location of the database file.
|
||||||
Return the correct location of the database file.
|
|
||||||
@param filename: The sqlite database filename to use. If not specified, will be made to be nzbtomedia.db
|
@param filename: The sqlite database filename to use. If not specified, will be made to be nzbtomedia.db
|
||||||
@param suffix: The suffix to append to the filename. A '.' will be added
|
@param suffix: The suffix to append to the filename. A '.' will be added
|
||||||
automatically, i.e. suffix='v0' will make dbfile.db.v0
|
automatically, i.e. suffix='v0' will make dbfile.db.v0
|
||||||
|
|
|
@ -17,6 +17,7 @@ log.addHandler(logging.NullHandler())
|
||||||
|
|
||||||
class InitSickBeard:
|
class InitSickBeard:
|
||||||
"""SickBeard init class.
|
"""SickBeard init class.
|
||||||
|
|
||||||
Used to determine which SickBeard fork object to initialize.
|
Used to determine which SickBeard fork object to initialize.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -204,7 +205,9 @@ class InitSickBeard:
|
||||||
|
|
||||||
def _init_fork(self):
|
def _init_fork(self):
|
||||||
# These need to be imported here, to prevent a circular import.
|
# These need to be imported here, to prevent a circular import.
|
||||||
from .pymedusa import PyMedusa, PyMedusaApiV1, PyMedusaApiV2
|
from .pymedusa import PyMedusa
|
||||||
|
from .pymedusa import PyMedusaApiV1
|
||||||
|
from .pymedusa import PyMedusaApiV2
|
||||||
|
|
||||||
mapped_forks = {'Medusa': PyMedusa, 'Medusa-api': PyMedusaApiV1, 'Medusa-apiv2': PyMedusaApiV2}
|
mapped_forks = {'Medusa': PyMedusa, 'Medusa-api': PyMedusaApiV1, 'Medusa-apiv2': PyMedusaApiV2}
|
||||||
log.debug(f'Create object for fork {self.fork}')
|
log.debug(f'Create object for fork {self.fork}')
|
||||||
|
@ -243,7 +246,8 @@ class SickBeard:
|
||||||
self.success = False
|
self.success = False
|
||||||
|
|
||||||
def initialize(self, dir_name, input_name=None, failed=False, client_agent='manual'):
|
def initialize(self, dir_name, input_name=None, failed=False, client_agent='manual'):
|
||||||
"""We need to call this explicitely because we need some variables.
|
"""We need to call this explicitly because we need some variables.
|
||||||
|
|
||||||
We can't pass these directly through the constructor.
|
We can't pass these directly through the constructor.
|
||||||
"""
|
"""
|
||||||
self.dir_name = dir_name
|
self.dir_name = dir_name
|
||||||
|
@ -358,6 +362,7 @@ class SickBeard:
|
||||||
|
|
||||||
def process_response(self, response: requests.Response) -> ProcessResult:
|
def process_response(self, response: requests.Response) -> ProcessResult:
|
||||||
"""Iterate over the lines returned, and log.
|
"""Iterate over the lines returned, and log.
|
||||||
|
|
||||||
:param response: Streamed Requests response object.
|
:param response: Streamed Requests response object.
|
||||||
This method will need to be overwritten in the forks, for alternative response handling.
|
This method will need to be overwritten in the forks, for alternative response handling.
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -38,7 +38,7 @@ def process():
|
||||||
continue
|
continue
|
||||||
input_name = os.path.basename(dir_name)
|
input_name = os.path.basename(dir_name)
|
||||||
results = nzb.process(dir_name, input_name, 0, client_agent=client_agent, download_id=download_id or None, input_category=subsection)
|
results = nzb.process(dir_name, input_name, 0, client_agent=client_agent, download_id=download_id or None, input_category=subsection)
|
||||||
if results.status_code != 0:
|
if results.status_code:
|
||||||
log.error(f'A problem was reported when trying to perform a manual run for {section}:{subsection}.')
|
log.error(f'A problem was reported when trying to perform a manual run for {section}:{subsection}.')
|
||||||
result = results
|
result = results
|
||||||
return result
|
return result
|
||||||
|
|
|
@ -85,7 +85,7 @@ def process(input_directory, input_name=None, status=0, client_agent='manual', d
|
||||||
processor = process_map[section_name]
|
processor = process_map[section_name]
|
||||||
result = processor(section=section_name, dir_name=input_directory, input_name=input_name, status=status, client_agent=client_agent, download_id=download_id, input_category=input_category, failure_link=failure_link)
|
result = processor(section=section_name, dir_name=input_directory, input_name=input_name, status=status, client_agent=client_agent, download_id=download_id, input_category=input_category, failure_link=failure_link)
|
||||||
plex_update(input_category)
|
plex_update(input_category)
|
||||||
if result.status_code == 0:
|
if not result.status_code:
|
||||||
if client_agent != 'manual':
|
if client_agent != 'manual':
|
||||||
# update download status in our DB
|
# update download status in our DB
|
||||||
update_download_info_status(input_name, 1)
|
update_download_info_status(input_name, 1)
|
||||||
|
|
|
@ -18,6 +18,7 @@ def process_script():
|
||||||
|
|
||||||
def process(args):
|
def process(args):
|
||||||
"""Process job from SABnzb.
|
"""Process job from SABnzb.
|
||||||
|
|
||||||
SABnzbd arguments:
|
SABnzbd arguments:
|
||||||
1. The final directory of the job (full path)
|
1. The final directory of the job (full path)
|
||||||
2. The original name of the NZB file
|
2. The original name of the NZB file
|
||||||
|
|
|
@ -164,7 +164,7 @@ def par2(dirname):
|
||||||
result = proc.returncode
|
result = proc.returncode
|
||||||
except Exception:
|
except Exception:
|
||||||
log.error(f'par2 file processing for {parfile} has failed')
|
log.error(f'par2 file processing for {parfile} has failed')
|
||||||
if result == 0:
|
if not result:
|
||||||
log.info('par2 file processing succeeded')
|
log.info('par2 file processing succeeded')
|
||||||
os.chdir(pwd)
|
os.chdir(pwd)
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,8 @@ import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
from subprocess import PIPE, DEVNULL
|
from subprocess import DEVNULL
|
||||||
|
from subprocess import PIPE
|
||||||
|
|
||||||
from babelfish import Language
|
from babelfish import Language
|
||||||
|
|
||||||
|
@ -30,7 +31,7 @@ def is_video_good(video: pathlib.Path, status, require_lan=None):
|
||||||
disable = True
|
disable = True
|
||||||
else:
|
else:
|
||||||
test_details, res = get_video_details(nzb2media.TEST_FILE)
|
test_details, res = get_video_details(nzb2media.TEST_FILE)
|
||||||
if res != 0 or test_details.get('error'):
|
if res or test_details.get('error'):
|
||||||
disable = True
|
disable = True
|
||||||
log.info('DISABLED: ffprobe failed to analyse test file. Stopping corruption check.')
|
log.info('DISABLED: ffprobe failed to analyse test file. Stopping corruption check.')
|
||||||
if test_details.get('streams'):
|
if test_details.get('streams'):
|
||||||
|
@ -47,7 +48,7 @@ def is_video_good(video: pathlib.Path, status, require_lan=None):
|
||||||
return True
|
return True
|
||||||
log.info(f'Checking [{video.name}] for corruption, please stand by ...')
|
log.info(f'Checking [{video.name}] for corruption, please stand by ...')
|
||||||
video_details, result = get_video_details(video)
|
video_details, result = get_video_details(video)
|
||||||
if result != 0:
|
if result:
|
||||||
log.error(f'FAILED: [{video.name}] is corrupted!')
|
log.error(f'FAILED: [{video.name}] is corrupted!')
|
||||||
return False
|
return False
|
||||||
if video_details.get('error'):
|
if video_details.get('error'):
|
||||||
|
@ -125,7 +126,7 @@ def get_video_details(videofile, img=None):
|
||||||
|
|
||||||
|
|
||||||
def check_vid_file(video_details, result):
|
def check_vid_file(video_details, result):
|
||||||
if result != 0:
|
if result:
|
||||||
return False
|
return False
|
||||||
if video_details.get('error'):
|
if video_details.get('error'):
|
||||||
return False
|
return False
|
||||||
|
@ -381,7 +382,7 @@ def build_commands(file, new_dir, movie_name):
|
||||||
audio_cmd2.extend([f'-c:a:{used_audio}', 'copy'])
|
audio_cmd2.extend([f'-c:a:{used_audio}', 'copy'])
|
||||||
elif audio3:
|
elif audio3:
|
||||||
# wrong language, wrong codec just pick the default audio track
|
# wrong language, wrong codec just pick the default audio track
|
||||||
_inded = audio3[0]['index']
|
_index = audio3[0]['index']
|
||||||
map_cmd.extend(['-map', f'0:{_index}'])
|
map_cmd.extend(['-map', f'0:{_index}'])
|
||||||
a_mapped.extend([audio3[0]['index']])
|
a_mapped.extend([audio3[0]['index']])
|
||||||
bitrate = int(float(audio3[0].get('bit_rate', 0))) / 1000
|
bitrate = int(float(audio3[0].get('bit_rate', 0))) / 1000
|
||||||
|
@ -423,11 +424,10 @@ def build_commands(file, new_dir, movie_name):
|
||||||
channels = int(float(audio.get('channels', 0)))
|
channels = int(float(audio.get('channels', 0)))
|
||||||
if audio['codec_name'] in nzb2media.ACODEC3_ALLOW:
|
if audio['codec_name'] in nzb2media.ACODEC3_ALLOW:
|
||||||
audio_cmd3.extend([f'-c:a:{used_audio}', 'copy'])
|
audio_cmd3.extend([f'-c:a:{used_audio}', 'copy'])
|
||||||
|
elif nzb2media.ACODEC3:
|
||||||
|
audio_cmd3.extend([f'-c:a:{used_audio}', nzb2media.ACODEC3])
|
||||||
else:
|
else:
|
||||||
if nzb2media.ACODEC3:
|
audio_cmd3.extend([f'-c:a:{used_audio}', 'copy'])
|
||||||
audio_cmd3.extend([f'-c:a:{used_audio}', nzb2media.ACODEC3])
|
|
||||||
else:
|
|
||||||
audio_cmd3.extend([f'-c:a:{used_audio}', 'copy'])
|
|
||||||
if nzb2media.ACHANNELS3 and channels and channels > nzb2media.ACHANNELS3:
|
if nzb2media.ACHANNELS3 and channels and channels > nzb2media.ACHANNELS3:
|
||||||
audio_cmd3.extend([f'-ac:a:{used_audio}', str(nzb2media.ACHANNELS3)])
|
audio_cmd3.extend([f'-ac:a:{used_audio}', str(nzb2media.ACHANNELS3)])
|
||||||
if audio_cmd3[1] == 'copy':
|
if audio_cmd3[1] == 'copy':
|
||||||
|
@ -519,11 +519,10 @@ def build_commands(file, new_dir, movie_name):
|
||||||
map_cmd.extend(['-map', f'{num}:0'])
|
map_cmd.extend(['-map', f'{num}:0'])
|
||||||
if not nzb2media.ALLOWSUBS or (not s_mapped and not num):
|
if not nzb2media.ALLOWSUBS or (not s_mapped and not num):
|
||||||
sub_cmd.extend(['-sn'])
|
sub_cmd.extend(['-sn'])
|
||||||
|
elif nzb2media.SCODEC:
|
||||||
|
sub_cmd.extend(['-c:s', nzb2media.SCODEC])
|
||||||
else:
|
else:
|
||||||
if nzb2media.SCODEC:
|
sub_cmd.extend(['-c:s', 'copy'])
|
||||||
sub_cmd.extend(['-c:s', nzb2media.SCODEC])
|
|
||||||
else:
|
|
||||||
sub_cmd.extend(['-c:s', 'copy'])
|
|
||||||
command.extend(map_cmd)
|
command.extend(map_cmd)
|
||||||
command.extend(video_cmd)
|
command.extend(video_cmd)
|
||||||
command.extend(audio_cmd)
|
command.extend(audio_cmd)
|
||||||
|
@ -586,7 +585,7 @@ def extract_subs(file, newfile_path):
|
||||||
result = proc.returncode
|
result = proc.returncode
|
||||||
except Exception:
|
except Exception:
|
||||||
log.error('Extracting subtitle has failed')
|
log.error('Extracting subtitle has failed')
|
||||||
if result == 0:
|
if not result:
|
||||||
try:
|
try:
|
||||||
shutil.copymode(file, output_file)
|
shutil.copymode(file, output_file)
|
||||||
except Exception:
|
except Exception:
|
||||||
|
@ -888,7 +887,7 @@ def transcode_directory(dir_name):
|
||||||
result = proc.returncode
|
result = proc.returncode
|
||||||
except Exception:
|
except Exception:
|
||||||
log.error(f'Transcoding of video {newfile_path} has failed')
|
log.error(f'Transcoding of video {newfile_path} has failed')
|
||||||
if nzb2media.SUBSDIR and result == 0 and isinstance(file, str):
|
if nzb2media.SUBSDIR and not result and isinstance(file, str):
|
||||||
for sub in get_subs(file):
|
for sub in get_subs(file):
|
||||||
name = os.path.splitext(os.path.split(file)[1])[0]
|
name = os.path.splitext(os.path.split(file)[1])[0]
|
||||||
subname = os.path.split(sub)[1]
|
subname = os.path.split(sub)[1]
|
||||||
|
@ -896,7 +895,7 @@ def transcode_directory(dir_name):
|
||||||
newpath = os.path.join(nzb2media.SUBSDIR, subname.replace(name, newname))
|
newpath = os.path.join(nzb2media.SUBSDIR, subname.replace(name, newname))
|
||||||
if not os.path.isfile(newpath):
|
if not os.path.isfile(newpath):
|
||||||
os.rename(sub, newpath)
|
os.rename(sub, newpath)
|
||||||
if result == 0:
|
if not result:
|
||||||
try:
|
try:
|
||||||
shutil.copymode(file, newfile_path)
|
shutil.copymode(file, newfile_path)
|
||||||
except Exception:
|
except Exception:
|
||||||
|
@ -920,7 +919,7 @@ def transcode_directory(dir_name):
|
||||||
time.sleep(5)
|
time.sleep(5)
|
||||||
os.rmdir(nzb2media.MOUNTED)
|
os.rmdir(nzb2media.MOUNTED)
|
||||||
nzb2media.MOUNTED = None
|
nzb2media.MOUNTED = None
|
||||||
if final_result == 0 and not nzb2media.DUPLICATE:
|
if not final_result and not nzb2media.DUPLICATE:
|
||||||
for file in rem_list:
|
for file in rem_list:
|
||||||
try:
|
try:
|
||||||
os.unlink(file)
|
os.unlink(file)
|
||||||
|
|
|
@ -108,9 +108,9 @@ def external_script(output_destination, torrent_name, torrent_label, settings):
|
||||||
file_name, file_extension = os.path.splitext(file)
|
file_name, file_extension = os.path.splitext(file)
|
||||||
if file_extension in nzb2media.USER_SCRIPT_MEDIAEXTENSIONS or nzb2media.USER_SCRIPT_MEDIAEXTENSIONS == 'ALL':
|
if file_extension in nzb2media.USER_SCRIPT_MEDIAEXTENSIONS or nzb2media.USER_SCRIPT_MEDIAEXTENSIONS == 'ALL':
|
||||||
num_files_new += 1
|
num_files_new += 1
|
||||||
if nzb2media.USER_SCRIPT_CLEAN == int(1) and num_files_new == 0 and final_result == 0:
|
if nzb2media.USER_SCRIPT_CLEAN == 1 and not num_files_new and not final_result:
|
||||||
log.info(f'All files have been processed. Cleaning outputDirectory {output_destination}')
|
log.info(f'All files have been processed. Cleaning outputDirectory {output_destination}')
|
||||||
remove_dir(output_destination)
|
remove_dir(output_destination)
|
||||||
elif nzb2media.USER_SCRIPT_CLEAN == int(1) and num_files_new != 0:
|
elif nzb2media.USER_SCRIPT_CLEAN == 1 and num_files_new:
|
||||||
log.info(f'{num_files} files were processed, but {num_files_new} still remain. outputDirectory will not be cleaned.')
|
log.info(f'{num_files} files were processed, but {num_files_new} still remain. outputDirectory will not be cleaned.')
|
||||||
return ProcessResult(status_code=final_result, message='User Script Completed')
|
return ProcessResult(status_code=final_result, message='User Script Completed')
|
||||||
|
|
|
@ -59,7 +59,8 @@ def char_replace(name_in):
|
||||||
|
|
||||||
def convert_to_ascii(input_name, dir_name):
|
def convert_to_ascii(input_name, dir_name):
|
||||||
ascii_convert = int(nzb2media.CFG['ASCII']['convert'])
|
ascii_convert = int(nzb2media.CFG['ASCII']['convert'])
|
||||||
if ascii_convert == 0 or os.name == 'nt': # just return if we don't want to convert or on windows os and '\' is replaced!.
|
if not ascii_convert or os.name == 'nt':
|
||||||
|
# just return if we don't want to convert or on windows os and '\' is replaced!.
|
||||||
return input_name, dir_name
|
return input_name, dir_name
|
||||||
encoded, input_name = char_replace(input_name)
|
encoded, input_name = char_replace(input_name)
|
||||||
directory, base = os.path.split(dir_name)
|
directory, base = os.path.split(dir_name)
|
||||||
|
|
|
@ -32,7 +32,7 @@ def find_imdbid(dir_name, input_name, omdb_api_key) -> str:
|
||||||
return imdbid
|
return imdbid
|
||||||
if 'NZBPR__DNZB_MOREINFO' in os.environ:
|
if 'NZBPR__DNZB_MOREINFO' in os.environ:
|
||||||
dnzb_more_info = os.environ.get('NZBPR__DNZB_MOREINFO', '')
|
dnzb_more_info = os.environ.get('NZBPR__DNZB_MOREINFO', '')
|
||||||
if dnzb_more_info != '':
|
if dnzb_more_info:
|
||||||
regex = re.compile(r'^http://www.imdb.com/title/(tt[0-9]+)/$', re.IGNORECASE)
|
regex = re.compile(r'^http://www.imdb.com/title/(tt[0-9]+)/$', re.IGNORECASE)
|
||||||
match = regex.match(dnzb_more_info)
|
match = regex.match(dnzb_more_info)
|
||||||
if match:
|
if match:
|
||||||
|
|
|
@ -12,11 +12,12 @@ log = logging.getLogger(__name__)
|
||||||
log.addHandler(logging.NullHandler())
|
log.addHandler(logging.NullHandler())
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from jaraco.windows.filesystem import islink, readlink
|
from jaraco.windows.filesystem import islink
|
||||||
|
from jaraco.windows.filesystem import readlink
|
||||||
except ImportError:
|
except ImportError:
|
||||||
if os.name != 'nt':
|
if os.name != 'nt':
|
||||||
from os.path import islink
|
|
||||||
from os import readlink
|
from os import readlink
|
||||||
|
from os.path import islink
|
||||||
else:
|
else:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,8 @@ import re
|
||||||
|
|
||||||
|
|
||||||
def sanitize_name(name):
|
def sanitize_name(name):
|
||||||
"""
|
"""Remove bad chars from the filename.
|
||||||
Remove bad chars from the filename.
|
|
||||||
>>> sanitize_name('a/b/c')
|
>>> sanitize_name('a/b/c')
|
||||||
'a-b-c'
|
'a-b-c'
|
||||||
>>> sanitize_name('abc')
|
>>> sanitize_name('abc')
|
||||||
|
@ -23,8 +23,8 @@ def sanitize_name(name):
|
||||||
|
|
||||||
|
|
||||||
def clean_file_name(filename):
|
def clean_file_name(filename):
|
||||||
"""
|
"""Clean up nzb name by removing any . and _ characters and trailing hyphens.
|
||||||
Clean up nzb name by removing any . and _ characters and trailing hyphens.
|
|
||||||
Is basically equivalent to replacing all _ and . with a
|
Is basically equivalent to replacing all _ and . with a
|
||||||
space, but handles decimal numbers in string, for example:
|
space, but handles decimal numbers in string, for example:
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -101,7 +101,7 @@ def parse_synods():
|
||||||
log.error('unable to find download details in Synology DS')
|
log.error('unable to find download details in Synology DS')
|
||||||
# Syno paths appear to be relative. Let's test to see if the returned path exists, and if not append to /volume1/
|
# Syno paths appear to be relative. Let's test to see if the returned path exists, and if not append to /volume1/
|
||||||
if not os.path.isdir(input_directory):
|
if not os.path.isdir(input_directory):
|
||||||
for root in ['/volume1/', '/volume2/', '/volume3/', '/volume4/']:
|
for root in ('/volume1/', '/volume2/', '/volume3/', '/volume4/'):
|
||||||
if os.path.isdir(os.path.join(root, input_directory)):
|
if os.path.isdir(os.path.join(root, input_directory)):
|
||||||
input_directory = os.path.join(root, input_directory)
|
input_directory = os.path.join(root, input_directory)
|
||||||
break
|
break
|
||||||
|
|
|
@ -14,8 +14,8 @@ log.addHandler(logging.NullHandler())
|
||||||
|
|
||||||
|
|
||||||
def onerror(func, path, exc_info):
|
def onerror(func, path, exc_info):
|
||||||
"""
|
"""Error handler for ``shutil.rmtree``.
|
||||||
Error handler for ``shutil.rmtree``.
|
|
||||||
If the error is due to an access error (read only file)
|
If the error is due to an access error (read only file)
|
||||||
it attempts to add write permission and then retries.
|
it attempts to add write permission and then retries.
|
||||||
If the error is for another reason it re-raises the error.
|
If the error is for another reason it re-raises the error.
|
||||||
|
@ -83,7 +83,7 @@ def remove_empty_folders(path, remove_root=True):
|
||||||
remove_empty_folders(fullpath)
|
remove_empty_folders(fullpath)
|
||||||
# if folder empty, delete it
|
# if folder empty, delete it
|
||||||
files = os.listdir(path)
|
files = os.listdir(path)
|
||||||
if len(files) == 0 and remove_root:
|
if not files and remove_root:
|
||||||
log.debug(f'Removing empty folder:{path}')
|
log.debug(f'Removing empty folder:{path}')
|
||||||
os.rmdir(path)
|
os.rmdir(path)
|
||||||
|
|
||||||
|
|
|
@ -10,14 +10,12 @@ import typing
|
||||||
import nzb2media
|
import nzb2media
|
||||||
|
|
||||||
if os.name == 'nt':
|
if os.name == 'nt':
|
||||||
# pylint: disable-next=no-name-in-module
|
|
||||||
from win32event import CreateMutex
|
|
||||||
|
|
||||||
# pylint: disable-next=no-name-in-module
|
# pylint: disable-next=no-name-in-module
|
||||||
from win32api import CloseHandle
|
from win32api import CloseHandle
|
||||||
|
|
||||||
# pylint: disable-next=no-name-in-module
|
# pylint: disable-next=no-name-in-module
|
||||||
from win32api import GetLastError
|
from win32api import GetLastError
|
||||||
|
# pylint: disable-next=no-name-in-module
|
||||||
|
from win32event import CreateMutex
|
||||||
from winerror import ERROR_ALREADY_EXISTS
|
from winerror import ERROR_ALREADY_EXISTS
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
@ -96,6 +94,8 @@ class PosixProcess:
|
||||||
self.pidpath.unlink()
|
self.pidpath.unlink()
|
||||||
|
|
||||||
|
|
||||||
|
# Alternative union syntax using | fails on Python < 3.10
|
||||||
|
# pylint: disable-next=consider-alternative-union-syntax
|
||||||
ProcessType = typing.Type[typing.Union[PosixProcess, WindowsProcess]]
|
ProcessType = typing.Type[typing.Union[PosixProcess, WindowsProcess]]
|
||||||
if os.name == 'nt':
|
if os.name == 'nt':
|
||||||
RunningProcess: ProcessType = WindowsProcess
|
RunningProcess: ProcessType = WindowsProcess
|
||||||
|
|
|
@ -30,15 +30,15 @@ def create_torrent_class(client_agent) -> object | None:
|
||||||
def pause_torrent(client_agent, input_hash, input_id, input_name):
|
def pause_torrent(client_agent, input_hash, input_id, input_name):
|
||||||
log.debug(f'Stopping torrent {input_name} in {client_agent} while processing')
|
log.debug(f'Stopping torrent {input_name} in {client_agent} while processing')
|
||||||
try:
|
try:
|
||||||
if client_agent == 'utorrent' and nzb2media.TORRENT_CLASS != '':
|
if client_agent == 'utorrent' and nzb2media.TORRENT_CLASS:
|
||||||
nzb2media.TORRENT_CLASS.stop(input_hash)
|
nzb2media.TORRENT_CLASS.stop(input_hash)
|
||||||
if client_agent == 'transmission' and nzb2media.TORRENT_CLASS != '':
|
if client_agent == 'transmission' and nzb2media.TORRENT_CLASS:
|
||||||
nzb2media.TORRENT_CLASS.stop_torrent(input_id)
|
nzb2media.TORRENT_CLASS.stop_torrent(input_id)
|
||||||
if client_agent == 'synods' and nzb2media.TORRENT_CLASS != '':
|
if client_agent == 'synods' and nzb2media.TORRENT_CLASS:
|
||||||
nzb2media.TORRENT_CLASS.pause_task(input_id)
|
nzb2media.TORRENT_CLASS.pause_task(input_id)
|
||||||
if client_agent == 'deluge' and nzb2media.TORRENT_CLASS != '':
|
if client_agent == 'deluge' and nzb2media.TORRENT_CLASS:
|
||||||
nzb2media.TORRENT_CLASS.core.pause_torrent([input_id])
|
nzb2media.TORRENT_CLASS.core.pause_torrent([input_id])
|
||||||
if client_agent == 'qbittorrent' and nzb2media.TORRENT_CLASS != '':
|
if client_agent == 'qbittorrent' and nzb2media.TORRENT_CLASS:
|
||||||
nzb2media.TORRENT_CLASS.pause(input_hash)
|
nzb2media.TORRENT_CLASS.pause(input_hash)
|
||||||
time.sleep(5)
|
time.sleep(5)
|
||||||
except Exception:
|
except Exception:
|
||||||
|
@ -50,15 +50,15 @@ def resume_torrent(client_agent, input_hash, input_id, input_name):
|
||||||
return
|
return
|
||||||
log.debug(f'Starting torrent {input_name} in {client_agent}')
|
log.debug(f'Starting torrent {input_name} in {client_agent}')
|
||||||
try:
|
try:
|
||||||
if client_agent == 'utorrent' and nzb2media.TORRENT_CLASS != '':
|
if client_agent == 'utorrent' and nzb2media.TORRENT_CLASS:
|
||||||
nzb2media.TORRENT_CLASS.start(input_hash)
|
nzb2media.TORRENT_CLASS.start(input_hash)
|
||||||
if client_agent == 'transmission' and nzb2media.TORRENT_CLASS != '':
|
if client_agent == 'transmission' and nzb2media.TORRENT_CLASS:
|
||||||
nzb2media.TORRENT_CLASS.start_torrent(input_id)
|
nzb2media.TORRENT_CLASS.start_torrent(input_id)
|
||||||
if client_agent == 'synods' and nzb2media.TORRENT_CLASS != '':
|
if client_agent == 'synods' and nzb2media.TORRENT_CLASS:
|
||||||
nzb2media.TORRENT_CLASS.resume_task(input_id)
|
nzb2media.TORRENT_CLASS.resume_task(input_id)
|
||||||
if client_agent == 'deluge' and nzb2media.TORRENT_CLASS != '':
|
if client_agent == 'deluge' and nzb2media.TORRENT_CLASS:
|
||||||
nzb2media.TORRENT_CLASS.core.resume_torrent([input_id])
|
nzb2media.TORRENT_CLASS.core.resume_torrent([input_id])
|
||||||
if client_agent == 'qbittorrent' and nzb2media.TORRENT_CLASS != '':
|
if client_agent == 'qbittorrent' and nzb2media.TORRENT_CLASS:
|
||||||
nzb2media.TORRENT_CLASS.resume(input_hash)
|
nzb2media.TORRENT_CLASS.resume(input_hash)
|
||||||
time.sleep(5)
|
time.sleep(5)
|
||||||
except Exception:
|
except Exception:
|
||||||
|
@ -69,16 +69,16 @@ def remove_torrent(client_agent, input_hash, input_id, input_name):
|
||||||
if nzb2media.DELETE_ORIGINAL == 1 or nzb2media.USE_LINK == 'move':
|
if nzb2media.DELETE_ORIGINAL == 1 or nzb2media.USE_LINK == 'move':
|
||||||
log.debug(f'Deleting torrent {input_name} from {client_agent}')
|
log.debug(f'Deleting torrent {input_name} from {client_agent}')
|
||||||
try:
|
try:
|
||||||
if client_agent == 'utorrent' and nzb2media.TORRENT_CLASS != '':
|
if client_agent == 'utorrent' and nzb2media.TORRENT_CLASS:
|
||||||
nzb2media.TORRENT_CLASS.removedata(input_hash)
|
nzb2media.TORRENT_CLASS.removedata(input_hash)
|
||||||
nzb2media.TORRENT_CLASS.remove(input_hash)
|
nzb2media.TORRENT_CLASS.remove(input_hash)
|
||||||
if client_agent == 'transmission' and nzb2media.TORRENT_CLASS != '':
|
if client_agent == 'transmission' and nzb2media.TORRENT_CLASS:
|
||||||
nzb2media.TORRENT_CLASS.remove_torrent(input_id, True)
|
nzb2media.TORRENT_CLASS.remove_torrent(input_id, True)
|
||||||
if client_agent == 'synods' and nzb2media.TORRENT_CLASS != '':
|
if client_agent == 'synods' and nzb2media.TORRENT_CLASS:
|
||||||
nzb2media.TORRENT_CLASS.delete_task(input_id)
|
nzb2media.TORRENT_CLASS.delete_task(input_id)
|
||||||
if client_agent == 'deluge' and nzb2media.TORRENT_CLASS != '':
|
if client_agent == 'deluge' and nzb2media.TORRENT_CLASS:
|
||||||
nzb2media.TORRENT_CLASS.core.remove_torrent(input_id, True)
|
nzb2media.TORRENT_CLASS.core.remove_torrent(input_id, True)
|
||||||
if client_agent == 'qbittorrent' and nzb2media.TORRENT_CLASS != '':
|
if client_agent == 'qbittorrent' and nzb2media.TORRENT_CLASS:
|
||||||
nzb2media.TORRENT_CLASS.delete_permanently(input_hash)
|
nzb2media.TORRENT_CLASS.delete_permanently(input_hash)
|
||||||
time.sleep(5)
|
time.sleep(5)
|
||||||
except Exception:
|
except Exception:
|
||||||
|
|
|
@ -11,7 +11,8 @@ import stat
|
||||||
import subprocess
|
import subprocess
|
||||||
import tarfile
|
import tarfile
|
||||||
import traceback
|
import traceback
|
||||||
from subprocess import PIPE, STDOUT
|
from subprocess import PIPE
|
||||||
|
from subprocess import STDOUT
|
||||||
from urllib.request import urlretrieve
|
from urllib.request import urlretrieve
|
||||||
|
|
||||||
import nzb2media
|
import nzb2media
|
||||||
|
@ -40,8 +41,8 @@ class CheckVersion:
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def find_install_type():
|
def find_install_type():
|
||||||
"""
|
"""Determine how this copy of SB was installed.
|
||||||
Determine how this copy of SB was installed.
|
|
||||||
returns: type of installation. Possible values are:
|
returns: type of installation. Possible values are:
|
||||||
'win': any compiled windows build
|
'win': any compiled windows build
|
||||||
'git': running from source using git
|
'git': running from source using git
|
||||||
|
@ -55,8 +56,8 @@ class CheckVersion:
|
||||||
return install_type
|
return install_type
|
||||||
|
|
||||||
def check_for_new_version(self, force=False):
|
def check_for_new_version(self, force=False):
|
||||||
"""
|
"""Check the internet for a newer version.
|
||||||
Check the internet for a newer version.
|
|
||||||
returns: bool, True for new version or False for no new version.
|
returns: bool, True for new version or False for no new version.
|
||||||
force: if true the VERSION_NOTIFY setting will be ignored and a check will be forced
|
force: if true the VERSION_NOTIFY setting will be ignored and a check will be forced
|
||||||
"""
|
"""
|
||||||
|
@ -114,7 +115,7 @@ class GitUpdateManager(UpdateManager):
|
||||||
main_git = 'git'
|
main_git = 'git'
|
||||||
log.debug(f'Checking if we can use git commands: {main_git} {test_cmd}')
|
log.debug(f'Checking if we can use git commands: {main_git} {test_cmd}')
|
||||||
output, err, exit_status = self._run_git(main_git, test_cmd)
|
output, err, exit_status = self._run_git(main_git, test_cmd)
|
||||||
if exit_status == 0:
|
if not exit_status:
|
||||||
log.debug(f'Using: {main_git}')
|
log.debug(f'Using: {main_git}')
|
||||||
return main_git
|
return main_git
|
||||||
log.debug(f'Not using: {main_git}')
|
log.debug(f'Not using: {main_git}')
|
||||||
|
@ -131,7 +132,7 @@ class GitUpdateManager(UpdateManager):
|
||||||
for cur_git in alternative_git:
|
for cur_git in alternative_git:
|
||||||
log.debug(f'Checking if we can use git commands: {cur_git} {test_cmd}')
|
log.debug(f'Checking if we can use git commands: {cur_git} {test_cmd}')
|
||||||
output, err, exit_status = self._run_git(cur_git, test_cmd)
|
output, err, exit_status = self._run_git(cur_git, test_cmd)
|
||||||
if exit_status == 0:
|
if not exit_status:
|
||||||
log.debug(f'Using: {cur_git}')
|
log.debug(f'Using: {cur_git}')
|
||||||
return cur_git
|
return cur_git
|
||||||
log.debug(f'Not using: {cur_git}')
|
log.debug(f'Not using: {cur_git}')
|
||||||
|
@ -160,7 +161,7 @@ class GitUpdateManager(UpdateManager):
|
||||||
log.error(f'Command {cmd} didn\'t work')
|
log.error(f'Command {cmd} didn\'t work')
|
||||||
proc_status = 1
|
proc_status = 1
|
||||||
proc_status = 128 if ('fatal:' in result) or proc_err else proc_status
|
proc_status = 128 if ('fatal:' in result) or proc_err else proc_status
|
||||||
if proc_status == 0:
|
if not proc_status:
|
||||||
log.debug(f'{cmd} : returned successful')
|
log.debug(f'{cmd} : returned successful')
|
||||||
proc_status = 0
|
proc_status = 0
|
||||||
elif nzb2media.LOG_GIT and proc_status in {1, 128}:
|
elif nzb2media.LOG_GIT and proc_status in {1, 128}:
|
||||||
|
@ -172,13 +173,13 @@ class GitUpdateManager(UpdateManager):
|
||||||
return result, proc_err, proc_status
|
return result, proc_err, proc_status
|
||||||
|
|
||||||
def _find_installed_version(self):
|
def _find_installed_version(self):
|
||||||
"""
|
"""Attempt to find the currently installed version of Sick Beard.
|
||||||
Attempt to find the currently installed version of Sick Beard.
|
|
||||||
Uses git show to get commit version.
|
Uses git show to get commit version.
|
||||||
Returns: True for success or False for failure
|
Returns: True for success or False for failure
|
||||||
"""
|
"""
|
||||||
output, err, exit_status = self._run_git(self._git_path, 'rev-parse HEAD')
|
output, err, exit_status = self._run_git(self._git_path, 'rev-parse HEAD')
|
||||||
if exit_status == 0 and output:
|
if not exit_status and output:
|
||||||
cur_commit_hash = output.strip()
|
cur_commit_hash = output.strip()
|
||||||
if not re.match('^[a-z0-9]+$', cur_commit_hash):
|
if not re.match('^[a-z0-9]+$', cur_commit_hash):
|
||||||
log.error('Output doesn\'t look like a hash, not using it')
|
log.error('Output doesn\'t look like a hash, not using it')
|
||||||
|
@ -192,7 +193,7 @@ class GitUpdateManager(UpdateManager):
|
||||||
def _find_git_branch(self):
|
def _find_git_branch(self):
|
||||||
nzb2media.NZBTOMEDIA_BRANCH = self.get_github_branch()
|
nzb2media.NZBTOMEDIA_BRANCH = self.get_github_branch()
|
||||||
branch_info, err, exit_status = self._run_git(self._git_path, 'symbolic-ref -q HEAD')
|
branch_info, err, exit_status = self._run_git(self._git_path, 'symbolic-ref -q HEAD')
|
||||||
if exit_status == 0 and branch_info:
|
if not exit_status and branch_info:
|
||||||
branch = branch_info.strip().replace('refs/heads/', '', 1)
|
branch = branch_info.strip().replace('refs/heads/', '', 1)
|
||||||
if branch:
|
if branch:
|
||||||
nzb2media.NZBTOMEDIA_BRANCH = branch
|
nzb2media.NZBTOMEDIA_BRANCH = branch
|
||||||
|
@ -200,8 +201,8 @@ class GitUpdateManager(UpdateManager):
|
||||||
return nzb2media.GIT_BRANCH
|
return nzb2media.GIT_BRANCH
|
||||||
|
|
||||||
def _check_github_for_update(self):
|
def _check_github_for_update(self):
|
||||||
"""
|
"""Check Github for a new version.
|
||||||
Check Github for a new version.
|
|
||||||
Uses git commands to check if there is a newer version than
|
Uses git commands to check if there is a newer version than
|
||||||
the provided commit hash. If there is a newer version it
|
the provided commit hash. If there is a newer version it
|
||||||
sets _num_commits_behind.
|
sets _num_commits_behind.
|
||||||
|
@ -211,12 +212,12 @@ class GitUpdateManager(UpdateManager):
|
||||||
self._num_commits_ahead = 0
|
self._num_commits_ahead = 0
|
||||||
# get all new info from github
|
# get all new info from github
|
||||||
output, err, exit_status = self._run_git(self._git_path, 'fetch origin')
|
output, err, exit_status = self._run_git(self._git_path, 'fetch origin')
|
||||||
if not exit_status == 0:
|
if exit_status:
|
||||||
log.error('Unable to contact github, can\'t check for update')
|
log.error('Unable to contact github, can\'t check for update')
|
||||||
return
|
return
|
||||||
# get latest commit_hash from remote
|
# get latest commit_hash from remote
|
||||||
output, err, exit_status = self._run_git(self._git_path, 'rev-parse --verify --quiet \'@{upstream}\'')
|
output, err, exit_status = self._run_git(self._git_path, 'rev-parse --verify --quiet \'@{upstream}\'')
|
||||||
if exit_status == 0 and output:
|
if not exit_status and output:
|
||||||
cur_commit_hash = output.strip()
|
cur_commit_hash = output.strip()
|
||||||
if not re.match('^[a-z0-9]+$', cur_commit_hash):
|
if not re.match('^[a-z0-9]+$', cur_commit_hash):
|
||||||
log.debug('Output doesn\'t look like a hash, not using it')
|
log.debug('Output doesn\'t look like a hash, not using it')
|
||||||
|
@ -227,7 +228,7 @@ class GitUpdateManager(UpdateManager):
|
||||||
return
|
return
|
||||||
# get number of commits behind and ahead (option --count not supported git < 1.7.2)
|
# get number of commits behind and ahead (option --count not supported git < 1.7.2)
|
||||||
output, err, exit_status = self._run_git(self._git_path, 'rev-list --left-right \'@{upstream}\'...HEAD')
|
output, err, exit_status = self._run_git(self._git_path, 'rev-list --left-right \'@{upstream}\'...HEAD')
|
||||||
if exit_status == 0 and output:
|
if not exit_status and output:
|
||||||
try:
|
try:
|
||||||
self._num_commits_behind = int(output.count('<'))
|
self._num_commits_behind = int(output.count('<'))
|
||||||
self._num_commits_ahead = int(output.count('>'))
|
self._num_commits_ahead = int(output.count('>'))
|
||||||
|
@ -267,7 +268,7 @@ class GitUpdateManager(UpdateManager):
|
||||||
Returns a bool depending on the call's success.
|
Returns a bool depending on the call's success.
|
||||||
"""
|
"""
|
||||||
output, err, exit_status = self._run_git(self._git_path, f'pull origin {self.branch}')
|
output, err, exit_status = self._run_git(self._git_path, f'pull origin {self.branch}')
|
||||||
if exit_status == 0:
|
if not exit_status:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -308,7 +309,7 @@ class SourceUpdateManager(UpdateManager):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _check_github_for_update(self):
|
def _check_github_for_update(self):
|
||||||
""" Check Github for a new version.
|
"""Check Github for a new version.
|
||||||
|
|
||||||
Uses pygithub to ask github if there is a newer version than
|
Uses pygithub to ask github if there is a newer version than
|
||||||
the provided commit hash. If there is a newer version it sets
|
the provided commit hash. If there is a newer version it sets
|
||||||
|
|
|
@ -46,7 +46,7 @@ def main(args, section=None):
|
||||||
else:
|
else:
|
||||||
manual.process()
|
manual.process()
|
||||||
|
|
||||||
if result.status_code == 0:
|
if not result.status_code:
|
||||||
log.info(f'The {args[0]} script completed successfully.')
|
log.info(f'The {args[0]} script completed successfully.')
|
||||||
if result.message:
|
if result.message:
|
||||||
print(result.message + '!')
|
print(result.message + '!')
|
||||||
|
|
|
@ -1,9 +1,16 @@
|
||||||
#! /usr/bin/env python
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
import nzb2media
|
import nzb2media
|
||||||
from nzb2media import transcoder
|
from nzb2media import transcoder
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.xfail(
|
||||||
|
sys.platform == 'win32' and sys.version_info < (3, 8),
|
||||||
|
reason='subprocess.Popen does not support pathlib.Path commands in Python 3.7',
|
||||||
|
)
|
||||||
def test_transcoder_check():
|
def test_transcoder_check():
|
||||||
assert transcoder.is_video_good(nzb2media.TEST_FILE, 1) is True
|
assert transcoder.is_video_good(nzb2media.TEST_FILE, 1) is True
|
||||||
|
|
91
tox.ini
91
tox.ini
|
@ -27,98 +27,15 @@ deps =
|
||||||
pytest-cov
|
pytest-cov
|
||||||
-rrequirements.txt
|
-rrequirements.txt
|
||||||
commands =
|
commands =
|
||||||
{posargs:pytest -vvv --cov --cov-report=term-missing --cov-branch tests}
|
{posargs:pytest -vvv -rA --cov --cov-report=term-missing --cov-branch tests}
|
||||||
|
|
||||||
[flake8]
|
|
||||||
max-line-length = 79
|
|
||||||
max-doc-length = 79
|
|
||||||
verbose = 2
|
|
||||||
statistics = True
|
|
||||||
min-version = 2.7
|
|
||||||
require-code = True
|
|
||||||
exclude =
|
|
||||||
.github/
|
|
||||||
.pytest_cache/
|
|
||||||
.tox/
|
|
||||||
.venv*/
|
|
||||||
build/
|
|
||||||
htmlcov/
|
|
||||||
logs/
|
|
||||||
ignore =
|
|
||||||
; -- flake8 --
|
|
||||||
; E501 line too long
|
|
||||||
; E722 do not use bare 'except' (duplicates B001)
|
|
||||||
; W503 line break before binary operator
|
|
||||||
; W505 doc line too long
|
|
||||||
E501, E722, W503, W505
|
|
||||||
|
|
||||||
; -- flake8-docstrings --
|
|
||||||
; D100 Missing docstring in public module
|
|
||||||
; D101 Missing docstring in public class
|
|
||||||
; D102 Missing docstring in public method
|
|
||||||
; D103 Missing docstring in public function
|
|
||||||
; D104 Missing docstring in public package
|
|
||||||
; D105 Missing docstring in magic method
|
|
||||||
; D107 Missing docstring in __init__
|
|
||||||
; D200 One-line docstring should fit on one line with quotes
|
|
||||||
; D202 No blank lines allowed after function docstring
|
|
||||||
; D205 1 blank line required between summary line and description
|
|
||||||
; D400 First line should end with a period
|
|
||||||
; D401 First line should be in imperative mood
|
|
||||||
; D402 First line should not be the function's "signature"
|
|
||||||
D100, D101, D102, D103, D104, D105, D107
|
|
||||||
|
|
||||||
; -- flake8-future-import --
|
|
||||||
; x = 1 for missing, 5 for present
|
|
||||||
; FIx6 nested_scopes 2.2
|
|
||||||
; FIx7 generators 2.3
|
|
||||||
; FIx2 with_statement 2.6
|
|
||||||
; FIx1 absolute_import 3.0
|
|
||||||
; FIx0 division 3.0
|
|
||||||
; FIx3 print_function 3.0
|
|
||||||
; FIx4 unicode_literals 3.0
|
|
||||||
; FIx5 generator_stop 3.7
|
|
||||||
; FIx8 annotations 4.0
|
|
||||||
; FI90 __future__ import does not exist
|
|
||||||
FI10, FI11, FI13, FI14, FI58
|
|
||||||
|
|
||||||
per-file-ignores =
|
|
||||||
; F401 imported but unused
|
|
||||||
; E402 module level import not at top of file
|
|
||||||
nzbTo*.py: E265, E266, E402
|
|
||||||
TorrentToMedia.py: E402
|
|
||||||
nzb2media/__init__.py: E402, F401
|
|
||||||
nzb2media/utils/__init__.py: F401
|
|
||||||
nzb2media/plugins/downloaders/configuration.py: F401
|
|
||||||
nzb2media/plugins/downloaders/utils.py: F401
|
|
||||||
|
|
||||||
[testenv:check]
|
[testenv:check]
|
||||||
deps =
|
deps =
|
||||||
flake8
|
pre-commit
|
||||||
flake8-bugbear
|
|
||||||
flake8-commas
|
|
||||||
flake8-comprehensions
|
|
||||||
flake8-docstrings
|
|
||||||
flake8-future-import
|
|
||||||
skip_install = true
|
skip_install = true
|
||||||
commands =
|
commands =
|
||||||
; ** PRIMARY TESTS **
|
pre-commit autoupdate
|
||||||
; Run flake8 tests (with plugins) using default test selections
|
pre-commit run --all-files
|
||||||
flake8
|
|
||||||
; ** SELECTIVE TESTS **
|
|
||||||
; Run flake8 tests (with plugins) for specific optional codes defined below
|
|
||||||
; -- flake8 --
|
|
||||||
; E123 closing bracket does not match indentation of opening bracket’s line
|
|
||||||
; E226 missing whitespace around arithmetic operator
|
|
||||||
; E241 multiple spaces after ‘,’
|
|
||||||
; E242 tab after ‘,’
|
|
||||||
; E704 multiple statements on one line
|
|
||||||
; W504 line break after binary operator
|
|
||||||
; W505 doc line too long
|
|
||||||
; -- flake8-bugbear --
|
|
||||||
; B902 Invalid first argument used for instance method.
|
|
||||||
; B903 Data class should be immutable or use __slots__ to save memory.
|
|
||||||
flake8 --select=B902,B903,E123,E226,E241,E242,E704,W504,W505
|
|
||||||
|
|
||||||
[coverage:run]
|
[coverage:run]
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue