qbit_manage/scripts/mover.py
bobokun eccc96e388
4.1.0 (#520)
* Sample solution.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update modules/config.py

Increase efficiency by using a boolean in place of a functional check.

Co-authored-by: bobokun <12660469+bobokun@users.noreply.github.com>

* Bump softprops/action-gh-release from 1 to 2

Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 1 to 2.
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](https://github.com/softprops/action-gh-release/compare/v1...v2)

---
updated-dependencies:
- dependency-name: softprops/action-gh-release
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* update group_uplolad_speed logic

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Bump dependabot/fetch-metadata from 1.6.0 to 2.0.0

Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 1.6.0 to 2.0.0.
- [Release notes](https://github.com/dependabot/fetch-metadata/releases)
- [Commits](https://github.com/dependabot/fetch-metadata/compare/v1.6.0...v2.0.0)

---
updated-dependencies:
- dependency-name: dependabot/fetch-metadata
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* Bump pre-commit from 3.6.2 to 3.7.0

Bumps [pre-commit](https://github.com/pre-commit/pre-commit) from 3.6.2 to 3.7.0.
- [Release notes](https://github.com/pre-commit/pre-commit/releases)
- [Changelog](https://github.com/pre-commit/pre-commit/blob/main/CHANGELOG.md)
- [Commits](https://github.com/pre-commit/pre-commit/compare/v3.6.2...v3.7.0)

---
updated-dependencies:
- dependency-name: pre-commit
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* [pre-commit.ci] pre-commit autoupdate

updates:
- [github.com/hhatto/autopep8: v2.0.4 → v2.1.0](https://github.com/hhatto/autopep8/compare/v2.0.4...v2.1.0)
- [github.com/asottile/pyupgrade: v3.15.1 → v3.15.2](https://github.com/asottile/pyupgrade/compare/v3.15.1...v3.15.2)
- [github.com/psf/black: 24.2.0 → 24.3.0](https://github.com/psf/black/compare/24.2.0...24.3.0)

* Bump qbittorrent-api from 2024.2.59 to 2024.3.60

Bumps [qbittorrent-api](https://github.com/rmartin16/qbittorrent-api) from 2024.2.59 to 2024.3.60.
- [Release notes](https://github.com/rmartin16/qbittorrent-api/releases)
- [Changelog](https://github.com/rmartin16/qbittorrent-api/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rmartin16/qbittorrent-api/compare/v2024.2.59...v2024.3.60)

---
updated-dependencies:
- dependency-name: qbittorrent-api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Bump 4.0.10

* Revert "Add Aggregate Group Speed Capabilities"

* Bump gitpython from 3.1.42 to 3.1.43

Bumps [gitpython](https://github.com/gitpython-developers/GitPython) from 3.1.42 to 3.1.43.
- [Release notes](https://github.com/gitpython-developers/GitPython/releases)
- [Changelog](https://github.com/gitpython-developers/GitPython/blob/main/CHANGES)
- [Commits](https://github.com/gitpython-developers/GitPython/compare/3.1.42...3.1.43)

---
updated-dependencies:
- dependency-name: gitpython
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Add new args for mover.old

* Revert "Revert "Add Aggregate Group Speed Capabilities""

This reverts commit f112b2c92e.
Fixes bug in original commit code

* Remove username and password from debug logs sinced they are redacted anyways

* adds support for #513

* Fixes #501

* Fixes bug not logging torrents being deleted after meeting share_limits

* Adds additional error checking for invalid share_limits in config

* fixes bug in torrents not untagging min_seeding_time_tag

* Fixes bug in #494

* Bi-directional Wiki Sync Action

* Bump actions/checkout from 2 to 4

Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v2...v4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* Bug fix on share limits being applied every run

* Revert "Revert "Revert "Add Aggregate Group Speed Capabilities"""

This reverts commit 41d5170ba6.

* Fixes #494 with new enable_group_upload_speed flag

* Fixes bug found in #494

* 4.1.0

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Paul Walker <walkerp1@yahoo.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: bakerboy448 <55419169+bakerboy448@users.noreply.github.com>
2024-04-05 20:39:00 -04:00

105 lines
4.1 KiB
Python
Executable file

#!/usr/bin/env python3
# This standalone script is used to pause torrents older than last x days,
# run mover (in Unraid) and start torrents again once completed
import argparse
import os
import sys
import time
from datetime import datetime
from datetime import timedelta
parser = argparse.ArgumentParser(prog="Qbit Mover", description="Stop torrents and kick off Unraid mover process")
parser.add_argument("--host", help="qbittorrent host including port", required=True)
parser.add_argument("-u", "--user", help="qbittorrent user", default="admin")
parser.add_argument("-p", "--password", help="qbittorrent password", default="adminadmin")
parser.add_argument(
"--cache-mount",
"--cache_mount",
help="Cache mount point in Unraid. This is used to additionally filter for only torrents that exists on the cache mount."
"Use this option ONLY if you follow TRaSH Guides folder structure. (For default cache drive set this to /mnt/cache)",
default=None,
)
parser.add_argument(
"--days-from", "--days_from", help="Set Number of Days to stop torrents between two offsets", type=int, default=0
)
parser.add_argument("--days-to", "--days_to", help="Set Number of Days to stop torrents between two offsets", type=int, default=2)
parser.add_argument(
"--mover-old",
help="Use mover.old instead of mover. Useful if you're using the Mover Tuning Plugin",
action="store_true",
default=False,
)
# --DEFINE VARIABLES--#
# --START SCRIPT--#
try:
from qbittorrentapi import APIConnectionError
from qbittorrentapi import Client
from qbittorrentapi import LoginFailed
except ModuleNotFoundError:
print('Requirements Error: qbittorrent-api not installed. Please install using the command "pip install qbittorrent-api"')
sys.exit(1)
def filter_torrents(torrent_list, timeoffset_from, timeoffset_to, cache_mount):
result = []
for torrent in torrent_list:
if torrent.added_on >= timeoffset_to and torrent.added_on <= timeoffset_from:
if not cache_mount or exists_in_cache(cache_mount, torrent.content_path):
result.append(torrent)
elif torrent.added_on < timeoffset_to:
break
return result
def exists_in_cache(cache_mount, content_path):
cache_path = os.path.join(cache_mount, content_path.lstrip("/"))
return os.path.exists(cache_path)
def stop_start_torrents(torrent_list, pause=True):
for torrent in torrent_list:
if pause:
print(f"Pausing: {torrent.name} [{torrent.added_on}]")
torrent.pause()
else:
print(f"Resuming: {torrent.name} [{torrent.added_on}]")
torrent.resume()
if __name__ == "__main__":
current = datetime.now()
args = parser.parse_args()
if args.days_from > args.days_to:
raise ("Config Error: days_from must be set lower than days_to")
try:
client = Client(host=args.host, username=args.user, password=args.password)
except LoginFailed:
raise ("Qbittorrent Error: Failed to login. Invalid username/password.")
except APIConnectionError:
raise ("Qbittorrent Error: Unable to connect to the client.")
except Exception:
raise ("Qbittorrent Error: Unable to connect to the client.")
timeoffset_from = current - timedelta(days=args.days_from)
timeoffset_to = current - timedelta(days=args.days_to)
torrent_list = client.torrents.info(sort="added_on", reverse=True)
torrents = filter_torrents(torrent_list, timeoffset_from.timestamp(), timeoffset_to.timestamp(), args.cache_mount)
# Pause Torrents
print(f"Pausing [{len(torrents)}] torrents from {args.days_from} - {args.days_to} days ago")
stop_start_torrents(torrents, True)
time.sleep(10)
# Start mover
print(f"Starting {'mover.old' if args.mover_old else 'mover'} to move files older than {args.days_to} days to array disks.")
# Or using mover tunning
if args.mover_old:
os.system("/usr/local/sbin/mover.old start")
else:
os.system("/usr/local/sbin/mover start")
# Start Torrents
print(f"Resuming [{len(torrents)}] paused torrents from {args.days_from} - {args.days_to} days ago")
stop_start_torrents(torrents, False)