diff --git a/Dockerfile b/Dockerfile index e7e4faa..b0b53bd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.11.4-alpine3.18 as base +FROM python:3.12.0-alpine3.18 as base FROM base as pip WORKDIR /install diff --git a/qbittools/commands/orphaned.py b/qbittools/commands/orphaned.py index f9c6532..b6378d1 100644 --- a/qbittools/commands/orphaned.py +++ b/qbittools/commands/orphaned.py @@ -13,7 +13,7 @@ def __init__(args, logger): completed_dir_list = completed_dir.split(os.sep) exclude_patterns = [i for s in args.exclude_pattern for i in s] - logger.info(f"Gathering a list of all torrents in qBittorrent...") + # Gather list of all torrents in qBittorrent qbittorrent_items = set() for torrent in client.torrents.info(): item_path = torrent['content_path'] @@ -27,9 +27,8 @@ def __init__(args, logger): qbittorrent_items.add(item_path) if os.path.isdir(item_path): qbittorrent_items.add(item_path) - logger.info(f"Done gathering {len(qbittorrent_items)} torrents in qBittorrent") - logger.info(f"Deleting orphaned files on disk not in qBittorrent...") + # Delete orphaned files on disk not in qBittorrent folders = [folder for folder in os.listdir(completed_dir) if os.path.isdir(os.path.join(completed_dir, folder))] for folder in folders: folder_path = os.path.join(completed_dir, folder) @@ -41,11 +40,9 @@ def __init__(args, logger): if not args.dry_run: try: if os.path.isfile(item_path): - logger.info(f"Deleting file {item_path}...") os.remove(item_path) logger.info(f"Deleted file {item_path}") elif os.path.isdir(item_path): - logger.info(f"Deleting folder {item_path}...") shutil.rmtree(item_path) logger.info(f"Deleted folder {item_path}") else: @@ -53,12 +50,9 @@ def __init__(args, logger): except Exception as e: logger.error(f"An error occurred: {e}") else: - logger.info(f"The flag --dry-run is set, skipping item {item_path}...") - + logger.info(f"Skipping {item_path} because --dry-run was specified") else: - logger.info(f"Skipping {item_path} because it matches an exclude pattern...") - #TODO: Add more stats like total reclaimed data, total items deleted, etc. - logger.info(f"Done deleting orphaned files on disk not in qBittorrent") + logger.info(f"Skipping {item_path} because it matches an exclude pattern") def add_arguments(subparser): """ @@ -71,9 +65,6 @@ def add_arguments(subparser): qbittools.py orphaned --exclude-pattern "*_unpackerred" --exclude-pattern "*/manual/*" --dry-run """ parser = subparser.add_parser('orphaned') - parser.add_argument('--exclude-pattern', nargs='*', action='append', metavar='mypattern', default=[], help='Exclude pattern, can be repeated multiple times', required=False) - parser.add_argument('--dry-run', action='store_true', help='Do not delete any data on disk', default=False, required=False) - qbittools.add_default_args(parser) diff --git a/qbittools/commands/prune.py b/qbittools/commands/prune.py index a8cbd86..0409c4b 100644 --- a/qbittools/commands/prune.py +++ b/qbittools/commands/prune.py @@ -15,9 +15,10 @@ def __init__(args, logger): if len(exclude_tags): filtered_torrents = list(filter(lambda x: not any(y in x.tags for y in exclude_tags), filtered_torrents)) - logger.info(f"Deleting torrents with tags [{' AND '.join(include_tags)}] but does not contain tags [{' OR '.join(exclude_tags)}]...") + logger.info(f"Pruning torrents with tags [{' AND '.join(include_tags)}] but does not contain tags [{' OR '.join(exclude_tags)}]...") + for t in filtered_torrents: - logger.info(f"Removed torrent {t['name']} with category [{t.category}] and tags [{t.tags}] and ratio [{round(t['ratio'], 2)}] and seeding time [{qbittools.utils.dhms(t['seeding_time'])}]") + logger.info(f"Pruned torrent {t['name']} with category [{t.category}] and tags [{t.tags}] and ratio [{round(t['ratio'], 2)}] and seeding time [{qbittools.utils.dhms(t['seeding_time'])}]") if not args.dry_run: t.delete(delete_files=args.with_data) @@ -34,12 +35,9 @@ def add_arguments(subparser): qbittools.py prune --include-tag expired --include-tag added:30d --exclude-tag site:oink --exclude-tag site:whatcd --dry-run """ parser = subparser.add_parser('prune') - parser.add_argument('--include-tag', nargs='*', action='append', metavar='mytag', default=[], help='Include torrents containing all of these tags, can be repeated multiple times', required=True) parser.add_argument('--exclude-tag', nargs='*', action='append', metavar='mytag', default=[], help='Exclude torrents containing any of these tags, can be repeated multiple times', required=False) parser.add_argument('--exclude-category', nargs='*', action='append', metavar='mycategory', default=[], help='Exclude torrents in this category, can be repeated multiple times', required=False) - parser.add_argument('--dry-run', action='store_true', help='Do not delete torrents', default=False, required=False) parser.add_argument('--with-data', action='store_true', help='Delete torrents with data', default=False, required=False) - qbittools.add_default_args(parser) diff --git a/qbittools/commands/reannounce.py b/qbittools/commands/reannounce.py index f2e0f31..6247719 100755 --- a/qbittools/commands/reannounce.py +++ b/qbittools/commands/reannounce.py @@ -54,7 +54,7 @@ def process_seeding(): logger.info(f"[{t.name}] is not working, active for {t.time_active}s, reannouncing...") t.reannounce() - logger.info("Started reannounce process") + logger.info("Starting reannounce process...") while True: iterations += 1 @@ -71,8 +71,6 @@ def process_seeding(): def add_arguments(subparser): parser = subparser.add_parser("reannounce") - parser.add_argument("--pause-resume", action="store_true", help="Pause+resume torrents that are invalid.") parser.add_argument("--process-seeding", action="store_true", help="Include seeding torrents for reannouncements.") - qbittools.add_default_args(parser) diff --git a/qbittools/commands/tagging.py b/qbittools/commands/tagging.py index 4ec3999..05ed9bc 100755 --- a/qbittools/commands/tagging.py +++ b/qbittools/commands/tagging.py @@ -54,6 +54,8 @@ ] def __init__(args, logger): + logger.info(f"Tagging torrents in qBittorrent...") + client = qbittools.qbit_client(args) trackers = qbittools.get_config(args, "trackers", []) @@ -71,7 +73,7 @@ def __init__(args, logger): if len(exclude_tags): filtered_torrents = list(filter(lambda x: any(y not in x.tags for y in exclude_tags), filtered_torrents)) - logger.info(f"Gathering items to tag in qBittorrent...") + # Gather items to tag in qBittorrent for t in filtered_torrents: tags_to_add = [] @@ -154,9 +156,7 @@ def __init__(args, logger): if args.size: tag_sizes[tag] += t.size - #TODO: Add more stats like total torrents, total items to tag, etc. - logger.info(f"Done gathering items to tag in qBittorrent") - + # Remove old tags default_tags = list(filter(lambda tag: any(tag.lower().startswith(x.lower()) for x in DEFAULT_TAGS), client.torrents_tags())) if default_tags: hashes = list(map(lambda t: t.hash, filtered_torrents)) @@ -170,8 +170,7 @@ def __init__(args, logger): for hash_list in tag_hashes.values(): unique_hashes.update(hash_list) - logger.info(f'Applying {len(tag_hashes)} various tags to {len(unique_hashes)} unique torrents...') - + # Apply tags for tag in tag_hashes: if args.size: size = qbittools.utils.format_bytes(tag_sizes[tag]) @@ -179,7 +178,7 @@ def __init__(args, logger): else: client.torrents_add_tags(tags=tag, torrent_hashes=tag_hashes[tag]) - logger.info(f'Done applying {len(tag_hashes)} various tags to {len(unique_hashes)} unique torrents') + logger.info(f'Completed tagging {len(unique_hashes)} torrents with {len(tag_hashes)} tags') def add_arguments(subparser): """ @@ -192,10 +191,8 @@ def add_arguments(subparser): qbittools.py tagging --exclude-category manual --added-on --expired --last-activity --sites --unregistered """ parser = subparser.add_parser('tagging') - parser.add_argument('--exclude-category', nargs='*', action='append', metavar='mycategory', default=[], help='Exclude all torrent with this category, can be repeated multiple times', required=False) parser.add_argument('--exclude-tag', nargs='*', action='append', metavar='mytag', default=[], help='Exclude all torrents with this tag, can be repeated multiple times', required=False) - parser.add_argument('--added-on', action='store_true', help='Tag torrents with added date (last 24h, 7 days, 30 days, etc)') parser.add_argument('--domains', action='store_true', help='Tag torrents with tracker domains') parser.add_argument('--duplicates', action='store_true', help='Tag torrents with the same content path') @@ -207,5 +204,4 @@ def add_arguments(subparser): parser.add_argument('--size', action='store_true', help='Add size of tagged torrents to created tags') parser.add_argument('--tracker-down', action='store_true', help='Tag torrents with temporarily down trackers') parser.add_argument('--unregistered', action='store_true', help='Tag torrents with unregistered tracker status message') - qbittools.add_default_args(parser) diff --git a/requirements.txt b/requirements.txt index d41e457..4491089 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -qbittorrent-api==2023.7.52 -tldextract==3.4.4 +qbittorrent-api==2023.9.53 +tldextract==5.0.0 pyyaml==6.0.1