From 07dd81f65e0a9aadac12e590203c9dfea2499d34 Mon Sep 17 00:00:00 2001 From: Prinz23 Date: Thu, 22 Oct 2020 00:46:35 +0200 Subject: [PATCH] Change move scantree to sg_helpers to prevent circular reference of it ever again. --- CHANGES.md | 1 + lib/sg_helpers.py | 40 ++++++++++++++++++++++++++++++++++++++-- sickbeard/browser.py | 2 +- sickbeard/db.py | 4 +--- sickbeard/helpers.py | 38 ++------------------------------------ sickbeard/processTV.py | 3 +-- sickbeard/show_name_helpers.py | 3 ++- sickbeard/webserve.py | 3 ++- 8 files changed, 48 insertions(+), 46 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index e4fce47..d672fd0 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -62,6 +62,7 @@ * Update Beautiful Soup 4.9.1 (r585) to 4.9.2 (r590) * Update Beautiful Soup 4.8.2 (r559) to 4.9.1 (r585) * Fix update Soupsieve (05086ef) broke MC and TVC browse cards +* Change move scantree to sg_helpers to prevent circular reference of it ever again ### 0.22.9 (2020-10-21 11:55:00 UTC) diff --git a/lib/sg_helpers.py b/lib/sg_helpers.py index 8350044..959660d 100644 --- a/lib/sg_helpers.py +++ b/lib/sg_helpers.py @@ -29,7 +29,7 @@ from send2trash import send2trash import encodingKludge as ek import requests -from _23 import decode_bytes, filter_list, html_unescape, list_range, urlparse, urlsplit, urlunparse +from _23 import decode_bytes, filter_list, html_unescape, list_range, scandir, urlparse, urlsplit, urlunparse from six import integer_types, iteritems, iterkeys, itervalues, PY2, string_types, text_type import zipfile @@ -41,8 +41,10 @@ except ImportError: # noinspection PyUnreachableCode if False: # noinspection PyUnresolvedReferences - from typing import Any, AnyStr, Dict, NoReturn, integer_types, Iterable, Iterator, List, Optional, Tuple, Union + from typing import Any, AnyStr, Dict, Generator, NoReturn, integer_types, Iterable, Iterator, List, Optional, \ + Tuple, Union from lxml_etree import etree + from _23 import DirEntry # global tmdb_info cache _TMDB_INFO_CACHE = {'date': datetime.datetime(2000, 1, 1), 'data': None} @@ -1372,3 +1374,37 @@ def compress_file(target, filename, prefer_7z=True, remove_source=True): if remove_source: remove_file_perm(target) return True + + +def scantree(path, # type: AnyStr + exclude=None, # type: Optional[AnyStr, List[AnyStr]] + include=None, # type: Optional[AnyStr, List[AnyStr]] + follow_symlinks=False, # type: bool + filter_kind=None, # type: Optional[bool] + recurse=True # type: bool + ): + # type: (...) -> Generator[DirEntry, None, None] + """Yield DirEntry objects for given path. Returns without yield if path fails sanity check + + :param path: Path to scan, sanity check is_dir and exists + :param exclude: Escaped regex string(s) to exclude + :param include: Escaped regex string(s) to include + :param follow_symlinks: Follow symlinks + :param filter_kind: None to yield everything, True yields directories, False yields files + :param recurse: Recursively scan the tree + """ + if isinstance(path, string_types) and path and ek.ek(os.path.isdir, path): + rc_exc, rc_inc = [re.compile(rx % '|'.join( + [x for x in (param, ([param], [])[None is param])[not isinstance(param, list)]])) + for rx, param in ((r'(?i)^(?:(?!%s).)*$', exclude), (r'(?i)%s', include))] + for entry in ek.ek(scandir, path): + is_dir = entry.is_dir(follow_symlinks=follow_symlinks) + is_file = entry.is_file(follow_symlinks=follow_symlinks) + no_filter = any([None is filter_kind, filter_kind and is_dir, not filter_kind and is_file]) + if (rc_exc.search(entry.name), True)[not exclude] and (rc_inc.search(entry.name), True)[not include] \ + and (no_filter or (not filter_kind and is_dir and recurse)): + if recurse and is_dir: + for subentry in scantree(entry.path, exclude, include, follow_symlinks, filter_kind, recurse): + yield subentry + if no_filter: + yield entry diff --git a/sickbeard/browser.py b/sickbeard/browser.py index ded787c..cc5f512 100644 --- a/sickbeard/browser.py +++ b/sickbeard/browser.py @@ -29,7 +29,7 @@ import encodingKludge as ek from exceptions_helper import ex from . import logger -from .helpers import scantree +from sg_helpers import scantree # this is for the drive letter code, it only works on windows if 'nt' == os.name: diff --git a/sickbeard/db.py b/sickbeard/db.py index 92586a7..9297586 100644 --- a/sickbeard/db.py +++ b/sickbeard/db.py @@ -34,7 +34,7 @@ import sickbeard from . import logger, sgdatetime from .sgdatetime import timestamp_near -from sg_helpers import make_dirs, compress_file, remove_file_perm +from sg_helpers import make_dirs, compress_file, remove_file_perm, scantree from _23 import filter_iter, list_values, scandir from six import iterkeys, iteritems, itervalues @@ -781,8 +781,6 @@ def delete_old_db_backups(target): :param target: backup folder to check """ - from .helpers import scantree - use_count = (1, sickbeard.BACKUP_DB_MAX_COUNT)[not sickbeard.BACKUP_DB_ONEDAY] file_list = [f for f in scantree(target, include=['sickbeard|cache|failed'], filter_kind=False)] if use_count < len(file_list): diff --git a/sickbeard/helpers.py b/sickbeard/helpers.py index f23c2b0..176898d 100644 --- a/sickbeard/helpers.py +++ b/sickbeard/helpers.py @@ -53,7 +53,7 @@ import requests.exceptions import subliminal from lxml_etree import etree, is_lxml -from _23 import b64decodebytes, b64encodebytes, decode_bytes, decode_str, DirEntry, filter_iter, Popen, scandir +from _23 import b64decodebytes, b64encodebytes, decode_bytes, decode_str, filter_iter, Popen, scandir from six import iteritems, PY2, string_types, text_type # noinspection PyUnresolvedReferences from six.moves import zip @@ -63,7 +63,7 @@ from six.moves import zip # noinspection PyUnresolvedReferences from sg_helpers import chmod_as_parent, clean_data, copy_file, fix_set_group_id, get_system_temp_dir, \ get_url, indent_xml, make_dirs, maybe_plural, md5_for_text, move_file, proxy_setting, remove_file, \ - remove_file_perm, replace_extension, try_int, try_ord, write_file + remove_file_perm, replace_extension, scantree, try_int, try_ord, write_file # noinspection PyUnreachableCode if False: @@ -1366,40 +1366,6 @@ def cpu_sleep(): time.sleep(cpu_presets[sickbeard.CPU_PRESET]) -def scantree(path, # type: AnyStr - exclude=None, # type: Optional[AnyStr, List[AnyStr]] - include=None, # type: Optional[AnyStr, List[AnyStr]] - follow_symlinks=False, # type: bool - filter_kind=None, # type: Optional[bool] - recurse=True # type: bool - ): - # type: (...) -> Generator[DirEntry, None, None] - """Yield DirEntry objects for given path. Returns without yield if path fails sanity check - - :param path: Path to scan, sanity check is_dir and exists - :param exclude: Escaped regex string(s) to exclude - :param include: Escaped regex string(s) to include - :param follow_symlinks: Follow symlinks - :param filter_kind: None to yield everything, True yields directories, False yields files - :param recurse: Recursively scan the tree - """ - if isinstance(path, string_types) and path and ek.ek(os.path.isdir, path): - rc_exc, rc_inc = [re.compile(rx % '|'.join( - [x for x in (param, ([param], [])[None is param])[not isinstance(param, list)]])) - for rx, param in ((r'(?i)^(?:(?!%s).)*$', exclude), (r'(?i)%s', include))] - for entry in ek.ek(scandir, path): - is_dir = entry.is_dir(follow_symlinks=follow_symlinks) - is_file = entry.is_file(follow_symlinks=follow_symlinks) - no_filter = any([None is filter_kind, filter_kind and is_dir, not filter_kind and is_file]) - if (rc_exc.search(entry.name), True)[not exclude] and (rc_inc.search(entry.name), True)[not include] \ - and (no_filter or (not filter_kind and is_dir and recurse)): - if recurse and is_dir: - for subentry in scantree(entry.path, exclude, include, follow_symlinks, filter_kind, recurse): - yield subentry - if no_filter: - yield entry - - def cleanup_cache(): """ Delete old cached files diff --git a/sickbeard/processTV.py b/sickbeard/processTV.py index 05a3a4a..59d3d41 100644 --- a/sickbeard/processTV.py +++ b/sickbeard/processTV.py @@ -38,14 +38,13 @@ from exceptions_helper import ex, MultipleShowObjectsException import sickbeard from . import common, db, failedProcessor, helpers, logger, notifiers, postProcessor from .common import SNATCHED_ANY -from .helpers import scantree from .history import reset_status from .name_parser.parser import InvalidNameException, InvalidShowException, NameParser from .sgdatetime import timestamp_near from _23 import filter_list, filter_iter, list_values, map_iter from six import iteritems, iterkeys, string_types, PY2, text_type -from sg_helpers import long_path +from sg_helpers import long_path, scantree import lib.rarfile.rarfile as rarfile diff --git a/sickbeard/show_name_helpers.py b/sickbeard/show_name_helpers.py index e522625..f6940c4 100644 --- a/sickbeard/show_name_helpers.py +++ b/sickbeard/show_name_helpers.py @@ -27,9 +27,10 @@ from exceptions_helper import ex import sickbeard from . import common, db, logger -from .helpers import sanitize_scene_name, scantree +from .helpers import sanitize_scene_name from .name_parser.parser import InvalidNameException, InvalidShowException, NameParser from .scene_exceptions import get_scene_exceptions +from sg_helpers import scantree from _23 import map_list, quote_plus from six import iterkeys, itervalues diff --git a/sickbeard/webserve.py b/sickbeard/webserve.py index 02fabe3..bbadfa9 100644 --- a/sickbeard/webserve.py +++ b/sickbeard/webserve.py @@ -44,6 +44,7 @@ import exceptions_helper # noinspection PyPep8Naming import encodingKludge as ek import sg_helpers +from sg_helpers import scantree import sickbeard from . import classes, clients, config, db, helpers, history, image_cache, logger, naming, \ @@ -52,7 +53,7 @@ from .anime import AniGroupList, pull_anidb_groups, short_group_names from .browser import folders_at_path from .common import ARCHIVED, DOWNLOADED, FAILED, IGNORED, SKIPPED, SNATCHED, SNATCHED_ANY, UNAIRED, UNKNOWN, WANTED, \ SD, HD720p, HD1080p, UHD2160p, Overview, Quality, qualityPresetStrings, statusStrings -from .helpers import has_image_ext, remove_article, remove_file_perm, scantree, starify +from .helpers import has_image_ext, remove_article, remove_file_perm, starify from .indexermapper import MapStatus, map_indexers_to_show, save_mapping from .indexers.indexer_config import TVINFO_IMDB, TVINFO_TRAKT, TVINFO_TVDB from .name_parser.parser import InvalidNameException, InvalidShowException, NameParser