Merge pull request #46 from StuffAnThings/develop

Merge to master v2.2
This commit is contained in:
bobokun 2021-12-01 11:45:01 -05:00 committed by GitHub
commit cb6592e5f8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 189 additions and 156 deletions

View file

@ -17,5 +17,6 @@ config
Dockerfile
venv
.idea
.env
test.py
!config/config.yml.sample

4
.gitignore vendored
View file

@ -6,4 +6,6 @@ __pycache__/
*.log*
*.yml
.vscode/*
!.github/**
!.github/**
*.svg
.env

View file

@ -1,4 +1,4 @@
# qBit Management
# <img src="qbm_logo.png" width="75"> qBit Management
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/StuffAnThings/qbit_manage?style=plastic)](https://github.com/StuffAnThings/qbit_manage/releases)
[![GitHub commits since latest release (by SemVer)](https://img.shields.io/github/commits-since/StuffAnThings/qbit_manage/latest/develop?label=Commits%20in%20Develop&style=plastic)](https://github.com/StuffAnThings/qbit_manage/tree/develop)
@ -9,10 +9,10 @@
This is a program used to manage your qBittorrent instance such as:
* Tag torrents based on tracker URL (only tag torrents that have no tags)
* Tag torrents based on tracker URL and set seed goals/limit upload speed by tag (only tag torrents that have no tags)
* Update categories based on save directory
* Remove unregistered torrents (delete data & torrent if it is not being cross-seeded, otherwise it will just remove the torrent)
* Automatically add [cross-seed](https://github.com/mmgoodnow/cross-seed) torrents in paused state (used in conjunction with the [cross-seed](https://github.com/mmgoodnow/cross-seed) script) <-- cross-seed now allows for torrent injections directly to qBit.
* Automatically add [cross-seed](https://github.com/mmgoodnow/cross-seed) torrents in paused state. **\*Note: cross-seed now allows for torrent injections directly to qBit, making this feature obsolete.\***
* Recheck paused torrents sorted by lowest size and resume if completed
* Remove orphaned files from your root directory that are not referenced by qBittorrent
* Tag any torrents that have no hard links and allows optional cleanup to delete these torrents and contents based on maximum ratio and/or time seeded
@ -30,7 +30,7 @@ To run the script in an interactive terminal run:
* add your qBittorrent host, user and pass. If you are not using a username and password you can remove the `user` and `pass` lines.
* add your `cross_seed` and `root_dir`. If you're running cross-seed in a docker container you must fill out `remote_dir` as well.
* Add your categories and save path to match with what is being used in your qBittorrent instance. I suggest using the full path when defining `save_path`
* Add the `tag` definition based on tracker URL
* Add the `tag` definition based on tracker URL (optional add seed goals/limit upload speed by tag)
* Modify the `nohardlinks` by specifying your completed movies/series category to match with qBittorrent. Please ensure the `root_dir` and/or `remote_dir` is added in the `directory` section
* `root_dir` needs to be defined in order to use the RecycleBin function. If optional `empty_after_x_days` is not defined then it will never empty the RecycleBin. Setting it to 0 will empty the RecycleBin immediately.
* Modify the `orphaned` section to define file patterns not to consider as orphans. Use this to exclude your incomplete torrents directory, or to ignore auto-generated files such as Thumbs.db.
@ -51,7 +51,7 @@ python qbit_manage.py -h
| `-cs` or `--cross-seed` | QBT_CROSS_SEED | Use this after running [cross-seed script](https://github.com/mmgoodnow/cross-seed) to add torrents from the cross-seed output folder to qBittorrent | False |
| `-re` or `--recheck` | QBT_RECHECK | Recheck paused torrents sorted by lowest size. Resume if Completed. | False |
| `-cu` or `--cat-update` | QBT_CAT_UPDATE | Use this if you would like to update your categories. | False |
| `-tu` or `--tag-update` | QBT_TAG_UPDATE | Use this if you would like to update your tags. (Only adds tags to untagged torrents) | False |
| `-tu` or `--tag-update` | QBT_TAG_UPDATE | Use this if you would like to update your tags and/or set seed goals/limit upload speed by tag. (Only adds tags to untagged torrents) | False |
| `-ru` or `--rem-unregistered` | QBT_REM_UNREGISTERED | Use this if you would like to remove unregistered torrents. (It will the delete data & torrent if it is not being cross-seeded, otherwise it will just remove the torrent without deleting data) | False |
| `-ro` or `--rem-orphaned` | QBT_REM_ORPHANED | Use this if you would like to remove orphaned files from your `root_dir` directory that are not referenced by any torrents. It will scan your `root_dir` directory and compare it with what is in qBittorrent. Any data not referenced in qBittorrent will be moved into `/data/torrents/orphaned_data` folder for you to review/delete. | False |
| `-tnhl` or `--tag-nohardlinks` | QBT_TAG_NOHARDLINKS | Use this to tag any torrents that do not have any hard links associated with any of the files. This is useful for those that use Sonarr/Radarr that hard links your media files with the torrents for seeding. When files get upgraded they no longer become linked with your media therefore will be tagged with a new tag noHL. You can then safely delete/remove these torrents to free up any extra space that is not being used by your media folder. | False |

View file

@ -1 +1 @@
2.1
2.2

View file

@ -1,87 +0,0 @@
# qBittorrent parameters
qbt:
host: "localhost:8080"
user: "username"
pass: "password"
directory:
# Do not remove these
# Cross-seed var: </your/path/here/> #Output directory of cross-seed
# root_dir var: </your/path/here/> #Root downloads directory used to check for orphaned files and used in RecycleBin
# <OPTIONAL> remote_dir var: </your/path/here/> # Path of docker host mapping of root_dir. Must be set if you are using docker!
cross_seed: "/your/path/here/"
root_dir: "/data/torrents/"
remote_dir: "/mnt/user/data/torrents/"
# Category/Pathing Parameters
cat:
# <Category Name> : <save_path> #Path of your save directory. Can be a keyword or full path
movies: "/data/torrents/Movies"
tv: "TV"
# Tag Parameters
tags:
# <Tracker URL Keyword>: <Tag Name>
animebytes.tv: AnimeBytes
avistaz: Avistaz
beyond-hd: Beyond-HD
blutopia: Blutopia
cartoonchaos: CartoonChaos
digitalcore: DigitalCore
gazellegames: GGn
hdts: HDTorrents
landof.tv: BroadcasTheNet
myanonamouse: MaM
passthepopcorn: PassThePopcorn
privatehd: PrivateHD
tleechreload: TorrentLeech
torrentdb: TorrentDB
torrentleech: TorrentLeech
tv-vault: TV-Vault
#Tag Movies/Series that are not hard linked
nohardlinks:
# Mandatory to fill out directory parameter above to use this function (root_dir/remote_dir)
# This variable should be set to your category name of your completed movies/completed series in qbit. Acceptable variable can be any category you would like to tag if there are no hardlinks found
movies-completed:
#<OPTIONAL> exclude_tags var: Will exclude the following tags when searching through the category.
exclude_tags:
- Beyond-HD
- AnimeBytes
- MaM
#<OPTIONAL> cleanup var: WARNING!! Setting this as true Will remove and delete contents of any torrents that are in paused state and has the NoHL tag
cleanup: false
#<OPTIONAL> max_ratio var: Will set the torrent Maximum share ratio until torrent is stopped from seeding/uploading
max_ratio: 4.0
#<OPTIONAL> seeding time var: Will set the torrent Maximum seeding time (min) until torrent is stopped from seeding
max_seeding_time: 86400
#Can have additional categories set with separate ratio/seeding times defined.
series-completed:
#<OPTIONAL> exclude_tags var: Will exclude the following tags when searching through the category.
exclude_tags:
- Beyond-HD
- BroadcasTheNet
#<OPTIONAL> cleanup var: WARNING!! Setting this as true Will remove and delete contents of any torrents that are in paused state and has the NoHL tag
cleanup: false
#<OPTIONAL> max_ratio var: Will set the torrent Maximum share ratio until torrent is stopped from seeding/uploading
max_ratio: 4.0
#<OPTIONAL> seeding time var: Will set the torrent Maximum seeding time (min) until torrent is stopped from seeding
max_seeding_time: 86400
#Recycle Bin method of deletion will move files into the recycle bin instead of directly deleting them in qbit
recyclebin:
enabled: true
#<OPTIONAL> empty_after_x_days var: Will automatically remove all files and folders in recycle bin after x days.
# If this variable is not defined it, the RecycleBin will never be emptied.
# Setting this variable to 0 will delete files immediately.
empty_after_x_days: 60
# Orphaned files are those in the root_dir download directory that are not referenced by any active torrents.
orphaned:
# File patterns that will not be considered orphaned files. Handy for generated files that aren't part of the torrent but belong with the torrent's files
exclude_patterns:
- "**/.DS_Store"
- "**/Thumbs.db"
- "**/@eaDir"
- "/data/torrents/temp/**"

View file

@ -20,17 +20,25 @@ cat:
movies: "/data/torrents/Movies"
tv: "TV"
# Tag Parameters
# Tag Parameters (Use either Format 1 or Format 2)
tags:
# Format 1
# <Tracker URL Keyword>: <Tag Name>
# Format 2
# <Tracker URL Keyword>:
# tag: <Tag Name>
# <MANDATORY> Will set the torrent Maximum share ratio until torrent is stopped from seeding/uploading. -2 means the global limit should be used, -1 means no limit.
# max_ratio: 5.0
# <OPTIONAL> Will set the torrent Maximum seeding time (min) until torrent is stopped from seeding. -2 means the global limit should be used, -1 means no limit.
# max_seeding_time: 129600
# <OPTIONAL> Will limit the upload speed KiB/s (KiloBytes/second) (-1 sets the limit to infinity)
# limit_upload_speed: 150
#Format 1 Examples
animebytes.tv: AnimeBytes
avistaz: Avistaz
beyond-hd: Beyond-HD
blutopia: Blutopia
cartoonchaos: CartoonChaos
digitalcore: DigitalCore
gazellegames: GGn
hdts: HDTorrents
landof.tv: BroadcasTheNet
myanonamouse: MaM
passthepopcorn: PassThePopcorn
@ -39,6 +47,22 @@ tags:
torrentdb: TorrentDB
torrentleech: TorrentLeech
tv-vault: TV-Vault
#Format 2 Examples
avistaz:
tag: Avistaz
max_ratio: 5.0
max_seeding_time: 129600
limit_upload_speed: 150
digitalcore
tag: DigitalCore
max_ratio: 5.0
gazellegames:
tag: GGn
limit_upload_speed: 150
hdts:
tag: HDTorrents
max_seeding_time: 129600
#Tag Movies/Series that are not hard linked
nohardlinks:

View file

@ -1,6 +1,6 @@
#!/usr/bin/python3
import argparse, logging, os, sys, time, shutil, urllib3, stat, fnmatch
import argparse, logging, os, sys, time, shutil, stat, fnmatch
from logging.handlers import RotatingFileHandler
from datetime import timedelta,datetime
from collections import Counter
@ -8,7 +8,7 @@ from pathlib import Path
try:
import yaml, schedule
from qbittorrentapi import Client
from qbittorrentapi import Client, LoginFailed, APIConnectionError
from modules.docker import GracefulKiller
from modules import util
except ModuleNotFoundError:
@ -28,7 +28,7 @@ parser.add_argument('-lf', '--log-file', dest='logfile', action='store',default=
parser.add_argument('-cs', '--cross-seed', dest='cross_seed', action="store_true", default=False, help='Use this after running cross-seed script to add torrents from the cross-seed output folder to qBittorrent')
parser.add_argument('-re', '--recheck', dest='recheck', action="store_true", default=False, help='Recheck paused torrents sorted by lowest size. Resume if Completed.')
parser.add_argument('-cu', '--cat-update', dest='cat_update', action="store_true", default=False, help='Use this if you would like to update your categories.')
parser.add_argument('-tu', '--tag-update', dest='tag_update', action="store_true", default=False, help='Use this if you would like to update your tags. (Only adds tags to untagged torrents)')
parser.add_argument('-tu', '--tag-update', dest='tag_update', action="store_true", default=False, help='Use this if you would like to update your tags and/or set seed goals/limit upload speed by tag. (Only adds tags to untagged torrents)')
parser.add_argument('-ru', '--rem-unregistered', dest='rem_unregistered', action="store_true", default=False, help='Use this if you would like to remove unregistered torrents.')
parser.add_argument('-ro', '--rem-orphaned', dest='rem_orphaned', action="store_true", default=False, help='Use this if you would like to remove unregistered torrents.')
parser.add_argument('-tnhl', '--tag-nohardlinks', dest='tag_nohardlinks', action="store_true", default=False, help='Use this to tag any torrents that do not have any hard links associated with any of the files. This is useful for those that use Sonarr/Radarr which hard link your media files with the torrents for seeding. When files get upgraded they no longer become linked with your media therefore will be tagged with a new tag noHL. You can then safely delete/remove these torrents to free up any extra space that is not being used by your media folder.')
@ -132,8 +132,6 @@ else:
os.makedirs(os.path.join(default_dir, "logs"), exist_ok=True)
urllib3.disable_warnings()
logger = logging.getLogger('qBit Manage')
logging.DRYRUN = 25
@ -180,10 +178,12 @@ if 'pass' in cfg['qbt']:
else:
password = ''
client = Client(host=host,
username=username,
password=password)
client = Client(host=host, username=username, password=password)
try:
client.auth_log_in()
except (LoginFailed,APIConnectionError)as e:
logger.error(e)
sys.exit(0)
############FUNCTIONS##############
#truncate the value of the torrent url to remove sensitive information
@ -203,24 +203,42 @@ def get_category(path):
category = ''
return category
category = ''
logger.warning('No categories matched. Check your config.yml file. - Setting category to NULL')
logger.warning(f'No categories matched for the save path {path}. Check your config.yml file. - Setting category to NULL')
return category
#Get tags from config file based on keyword
def get_tags(urls):
if 'tags' in cfg and cfg["tags"] != None:
tag_path = cfg['tags']
for i, f in tag_path.items():
new_tag = ''
max_ratio = ''
max_seeding_time = ''
limit_upload_speed = ''
url = trunc_val(urls[0], '/')
if 'tags' in cfg and cfg["tags"] != None and urls:
tag_values = cfg['tags']
for tag_url, tag_details in tag_values.items():
new_tag = ''
max_ratio = ''
max_seeding_time = ''
limit_upload_speed = ''
# If using Format 1
if(type(tag_details) == str):
new_tag = tag_details
# Using Format 2
else:
if 'tag' in tag_details:
new_tag = tag_details['tag']
else:
logger.warning(f'No tags defined for {tag_url}. Please check your config.yml file.')
if 'max_ratio' in tag_details: max_ratio = tag_details['max_ratio']
if 'max_seeding_time' in tag_details: max_seeding_time = tag_details['max_seeding_time']
if 'limit_upload_speed' in tag_details: limit_upload_speed = tag_details['limit_upload_speed']
for url in urls:
if i in url:
tag = f
if tag: return tag,trunc_val(url, '/')
if tag_url in url:
return (new_tag,trunc_val(url, '/'),max_ratio,max_seeding_time,limit_upload_speed)
else:
tag = ('','')
return tag
tag = ('','')
logger.warning('No tags matched. Check your config.yml file. Setting tag to NULL')
return tag
return (new_tag,url,max_ratio,max_seeding_time,limit_upload_speed)
logger.warning(f'No tags matched for {url}. Please check your config.yml file. Setting tag to NULL')
return (new_tag,url,max_ratio,max_seeding_time,limit_upload_speed)
#Move files from source to destination, mod variable is to change the date modified of the file being moved
@ -266,6 +284,8 @@ def get_torrent_info(t_list):
save_path = torrent.save_path
category = get_category(save_path)
is_complete = False
msg = None
status = None
if torrent.name in torrentdict:
t_count = torrentdict[torrent.name]['count'] + 1
msg_list = torrentdict[torrent.name]['msg']
@ -278,9 +298,12 @@ def get_torrent_info(t_list):
status_list = []
is_complete = torrent.state_enum.is_complete
first_hash = torrent.hash
msg,status = [(x.msg,x.status) for x in torrent.trackers if x.url.startswith('http')][0]
msg_list.append(msg)
status_list.append(status)
try:
msg,status = [(x.msg,x.status) for x in torrent.trackers if x.url.startswith('http')][0]
except IndexError:
pass
if msg != None: msg_list.append(msg)
if status != None: status_list.append(status)
torrentattr = {'Category': category, 'save_path': save_path, 'count': t_count, 'msg': msg_list, 'status': status_list, 'is_complete': is_complete, 'first_hash':first_hash}
torrentdict[torrent.name] = torrentattr
return torrentdict
@ -293,8 +316,7 @@ def set_recheck():
torrent_sorted_list = client.torrents.info(status_filter='paused',sort='size')
if torrent_sorted_list:
for torrent in torrent_sorted_list:
new_tag,t_url = get_tags([x.url for x in torrent.trackers if x.url.startswith('http')])
if torrent.tags == '' or ('cross-seed' in torrent.tags and len([e for e in torrent.tags.split(",") if not 'noHL' in e]) == 1): torrent.add_tags(tags=new_tag)
new_tag = get_tags([x.url for x in torrent.trackers if x.url.startswith('http')])[0]
#Resume torrent if completed
if torrent.progress == 1:
#Check to see if torrent meets AutoTorrentManagement criteria
@ -304,16 +326,16 @@ def set_recheck():
logger.debug(util.insert_space(f'-- Seeding Time vs Max Seed Time: {timedelta(seconds=torrent.seeding_time)} < {timedelta(minutes=torrent.max_seeding_time)}',4))
if torrent.ratio < torrent.max_ratio and (torrent.seeding_time < (torrent.max_seeding_time * 60)):
if dry_run:
logger.dryrun(f'Not Resuming {new_tag} - {torrent.name}')
logger.dryrun(f'Not Resuming [{new_tag}] - {torrent.name}')
else:
logger.info(f'Resuming {new_tag} - {torrent.name}')
logger.info(f'Resuming [{new_tag}] - {torrent.name}')
torrent.resume()
#Recheck
elif torrent.progress == 0 and torrentdict[torrent.name]['is_complete'] and not torrent.state_enum.is_checking:
if dry_run:
logger.dryrun(f'Not Rechecking {new_tag} - {torrent.name}')
logger.dryrun(f'Not Rechecking [{new_tag}] - {torrent.name}')
else:
logger.info(f'Rechecking {new_tag} - {torrent.name}')
logger.info(f'Rechecking [{new_tag}] - {torrent.name}')
torrent.recheck()
# Function used to move any torrents from the cross seed directory to the correct save directory
@ -406,21 +428,22 @@ def set_category():
num_cat = 0
for torrent in torrent_list:
if torrent.category == '':
for x in torrent.trackers:
if x.url.startswith('http'):
t_url = trunc_val(x.url, '/')
new_cat = get_category(torrent.save_path)
if dry_run:
logger.dryrun(util.insert_space(f'Torrent Name: {torrent.name}',3))
logger.dryrun(util.insert_space(f'New Category: {new_cat}',3))
logger.dryrun(util.insert_space(f'Tracker: {t_url}',8))
num_cat += 1
else:
logger.info(util.insert_space(f'- Torrent Name: {torrent.name}',1))
logger.info(util.insert_space(f'-- New Category: {new_cat}',5))
logger.info(util.insert_space(f'-- Tracker: {t_url}',5))
torrent.set_category(category=new_cat)
num_cat += 1
new_cat = get_category(torrent.save_path)
try:
t_url = [trunc_val(x.url, '/') for x in torrent.trackers if x.url.startswith('http')][0]
except IndexError:
t_url = None
if dry_run:
logger.dryrun(util.insert_space(f'Torrent Name: {torrent.name}',3))
logger.dryrun(util.insert_space(f'New Category: {new_cat}',3))
logger.dryrun(util.insert_space(f'Tracker: {t_url}',8))
num_cat += 1
else:
logger.info(util.insert_space(f'- Torrent Name: {torrent.name}',1))
logger.info(util.insert_space(f'-- New Category: {new_cat}',5))
logger.info(util.insert_space(f'-- Tracker: {t_url}',5))
torrent.set_category(category=new_cat)
num_cat += 1
if dry_run:
if num_cat >= 1:
logger.dryrun(f'Did not update {num_cat} new categories.')
@ -439,18 +462,84 @@ def set_tags():
num_tags = 0
for torrent in torrent_list:
if torrent.tags == '' or ('cross-seed' in torrent.tags and len([e for e in torrent.tags.split(",") if not 'noHL' in e]) == 1):
new_tag,t_url = get_tags([x.url for x in torrent.trackers if x.url.startswith('http')])
if dry_run:
logger.dryrun(util.insert_space(f'Torrent Name: {torrent.name}',3))
logger.dryrun(util.insert_space(f'New Tag: {new_tag}',8))
logger.dryrun(util.insert_space(f'Tracker: {t_url}',8))
num_tags += 1
else:
logger.info(util.insert_space(f'Torrent Name: {torrent.name}',3))
logger.info(util.insert_space(f'New Tag: {new_tag}',8))
logger.info(util.insert_space(f'Tracker: {t_url}',8))
torrent.add_tags(tags=new_tag)
num_tags += 1
new_tag,url,max_ratio,max_seeding_time,limit_upload_speed = get_tags([x.url for x in torrent.trackers if x.url.startswith('http')])
if new_tag:
if dry_run:
num_tags += 1
logger.dryrun(util.insert_space(f'Torrent Name: {torrent.name}',3))
logger.dryrun(util.insert_space(f'New Tag: {new_tag}',8))
logger.dryrun(util.insert_space(f'Tracker: {url}',8))
if limit_upload_speed:
if limit_upload_speed == -1:
logger.dryrun(util.insert_space(f'Limit UL Speed: Infinity',1))
else:
logger.dryrun(util.insert_space(f'Limit UL Speed: {limit_upload_speed} kB/s',1))
if max_ratio:
if max_ratio == -2:
logger.dryrun(util.insert_space(f'Share Limit: Use Global Share Limit',4))
continue
elif max_ratio == -1:
logger.dryrun(util.insert_space(f'Share Limit: Set No Share Limit',4))
continue
else:
max_ratio = torrent.max_ratio
if max_seeding_time:
if max_seeding_time == -2:
logger.dryrun(util.insert_space(f'Share Limit: Use Global Share Limit',4))
continue
elif max_seeding_time == -1:
logger.dryrun(util.insert_space(f'Share Limit: Set No Share Limit',4))
continue
else:
max_seeding_time = torrent.max_seeding_time
if max_ratio != torrent.max_ratio and max_seeding_time != torrent.max_seeding_time:
logger.dryrun(util.insert_space(f'Share Limit: Max Ratio = {max_ratio}, Max Seed Time = {max_seeding_time} min',4))
elif max_ratio != torrent.max_ratio:
logger.dryrun(util.insert_space(f'Share Limit: Max Ratio = {max_ratio}',4))
elif max_seeding_time != torrent.max_seeding_time:
logger.dryrun(util.insert_space(f'Share Limit: Max Seed Time = {max_seeding_time} min',4))
else:
torrent.add_tags(tags=new_tag)
num_tags += 1
logger.info(util.insert_space(f'Torrent Name: {torrent.name}',3))
logger.info(util.insert_space(f'New Tag: {new_tag}',8))
logger.info(util.insert_space(f'Tracker: {url}',8))
if limit_upload_speed:
if limit_upload_speed == -1:
logger.info(util.insert_space(f'Limit UL Speed: Infinity',1))
else:
logger.info(util.insert_space(f'Limit UL Speed: {limit_upload_speed} kB/s',1))
torrent.set_upload_limit(limit_upload_speed*1024)
if max_ratio:
if max_ratio == -2:
logger.info(util.insert_space(f'Share Limit: Use Global Share Limit',4))
torrent.set_share_limits(-2,-2)
continue
elif max_ratio == -1:
logger.info(util.insert_space(f'Share Limit: Set No Share Limit',4))
torrent.set_share_limits(-1,-1)
continue
else:
max_ratio = torrent.max_ratio
if max_seeding_time:
if max_seeding_time == -2:
logger.info(util.insert_space(f'Share Limit: Use Global Share Limit',4))
torrent.set_share_limits(-2,-2)
continue
elif max_seeding_time == -1:
logger.info(util.insert_space(f'Share Limit: Set No Share Limit',4))
torrent.set_share_limits(-1,-1)
continue
else:
max_seeding_time = torrent.max_seeding_time
if max_ratio != torrent.max_ratio and max_seeding_time != torrent.max_seeding_time:
logger.info(util.insert_space(f'Share Limit: Max Ratio = {max_ratio}, Max Seed Time = {max_seeding_time} min',4))
elif max_ratio != torrent.max_ratio:
logger.info(util.insert_space(f'Share Limit: Max Ratio = {max_ratio}',4))
elif max_seeding_time != torrent.max_seeding_time:
logger.info(util.insert_space(f'Share Limit: Max Seed Time = {max_seeding_time} min',4))
torrent.set_share_limits(max_ratio,max_seeding_time)
if dry_run:
if num_tags >= 1:
logger.dryrun(f'Did not update {num_tags} new tags.')
@ -552,6 +641,7 @@ def set_rem_unregistered():
def set_rem_orphaned():
if rem_orphaned:
util.separator(f"Checking for Orphaned Files", space=False, border=False)
global torrent_list
torrent_files = []
root_files = []
orphaned_files = []
@ -562,6 +652,9 @@ def set_rem_orphaned():
root_files = [os.path.join(path.replace(remote_path,root_path), name) for path, subdirs, files in os.walk(remote_path) for name in files if os.path.join(remote_path,'orphaned_data') not in path and os.path.join(remote_path,'.RecycleBin') not in path]
else:
root_files = [os.path.join(path, name) for path, subdirs, files in os.walk(root_path) for name in files if os.path.join(root_path,'orphaned_data') not in path and os.path.join(root_path,'.RecycleBin') not in path]
#Get an updated list of torrents
torrent_list = client.torrents.info(sort='added_on')
for torrent in torrent_list:
for file in torrent.files:

BIN
qbm_logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 KiB