Skip to content

Commit

Permalink
Merge pull request #499 from StuffAnThings/develop
Browse files Browse the repository at this point in the history
4.0.9
  • Loading branch information
bobokun authored Feb 27, 2024
2 parents 0a6e31e + 431614d commit 29690e9
Show file tree
Hide file tree
Showing 29 changed files with 335 additions and 134 deletions.
16 changes: 15 additions & 1 deletion .github/workflows/develop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ jobs:
runs-on: ubuntu-latest

steps:
- name: set lower case owner name
run: |
echo "OWNER_LC=${OWNER,,}" >>${GITHUB_ENV}
env:
OWNER: '${{ github.repository_owner }}'

- name: Check Out Repo
uses: actions/checkout@v4
Expand All @@ -24,6 +29,13 @@ jobs:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}

- name: Login to ghcr.io
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ env.OWNER_LC }}
password: ${{ secrets.GHCR_TOKEN }}

- name: Set up QEMU
uses: docker/setup-qemu-action@master
with:
Expand All @@ -43,7 +55,9 @@ jobs:
"BRANCH_NAME=develop"
platforms: linux/amd64,linux/arm64,linux/arm/v7
push: true
tags: ${{ secrets.DOCKER_HUB_USERNAME }}/qbit_manage:develop
tags: |
${{ secrets.DOCKER_HUB_USERNAME }}/qbit_manage:develop
ghcr.io/${{ env.OWNER_LC }}/qbit_manage:develop
- name: Trigger Hotio Webhook
uses: joelwmale/webhook-action@master
Expand Down
30 changes: 22 additions & 8 deletions .github/workflows/latest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,28 @@ jobs:
runs-on: ubuntu-latest

steps:
- name: set lower case owner name
run: |
echo "OWNER_LC=${OWNER,,}" >>${GITHUB_ENV}
env:
OWNER: '${{ github.repository_owner }}'

- name: Check Out Repo
uses: actions/checkout@v4

- name: Trigger Hotio Webhook
uses: joelwmale/webhook-action@master
with:
url: ${{ secrets.HOTIO_WEBHOOK_URL }}
headers: '{"Authorization": "Bearer ${{ secrets.HOTIO_WEBHOOK_SECRET }}"}'
body: '{ "application": "qbitmanage", "branch": "release" }'

- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}

- name: Login to ghcr.io
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ env.OWNER_LC }}
password: ${{ secrets.GHCR_TOKEN }}

- name: Set up QEMU
uses: docker/setup-qemu-action@master
with:
Expand All @@ -44,4 +49,13 @@ jobs:
file: ./Dockerfile
platforms: linux/amd64,linux/arm64,linux/arm/v7
push: true
tags: ${{ secrets.DOCKER_HUB_USERNAME }}/qbit_manage:latest
tags: |
${{ secrets.DOCKER_HUB_USERNAME }}/qbit_manage:latest
ghcr.io/${{ env.OWNER_LC }}/qbit_manage:latest
- name: Trigger Hotio Webhook
uses: joelwmale/webhook-action@master
with:
url: ${{ secrets.HOTIO_WEBHOOK_URL }}
headers: '{"Authorization": "Bearer ${{ secrets.HOTIO_WEBHOOK_SECRET }}"}'
body: '{ "application": "qbitmanage", "branch": "" }'
17 changes: 15 additions & 2 deletions .github/workflows/version.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ jobs:
runs-on: ubuntu-latest

steps:
- name: set lower case owner name
run: |
echo "OWNER_LC=${OWNER,,}" >>${GITHUB_ENV}
env:
OWNER: '${{ github.repository_owner }}'

- name: Check Out Repo
uses: actions/checkout@v4
Expand All @@ -23,6 +28,13 @@ jobs:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}

- name: Login to ghcr.io
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ env.OWNER_LC }}
password: ${{ secrets.GHCR_TOKEN }}

- name: Set up QEMU
uses: docker/setup-qemu-action@master
with:
Expand All @@ -44,8 +56,9 @@ jobs:
file: ./Dockerfile
platforms: linux/amd64,linux/arm64,linux/arm/v7
push: true
tags: ${{ secrets.DOCKER_HUB_USERNAME }}/qbit_manage:${{ steps.get_version.outputs.VERSION }}

tags: |
${{ secrets.DOCKER_HUB_USERNAME }}/qbit_manage:${{ steps.get_version.outputs.VERSION }}
ghcr.io/${{ env.OWNER_LC }}/qbit_manage:${{ steps.get_version.outputs.VERSION }}
- name: Create release
id: create_release
uses: softprops/action-gh-release@v1
Expand Down
14 changes: 8 additions & 6 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ repos:
hooks:
- id: autopep8
- repo: https://github.com/adrienverge/yamllint.git
rev: v1.33.0 # or higher tag
rev: v1.35.1 # or higher tag
hooks:
- id: yamllint
args: [--format, parsable, --strict]
Expand All @@ -31,17 +31,19 @@ repos:
hooks:
- id: yamlfix
exclude: ^.github/
- repo: https://github.com/asottile/reorder-python-imports
rev: v3.12.0
- repo: https://github.com/pycqa/isort
rev: 5.13.2
hooks:
- id: reorder-python-imports
- id: isort
name: isort (python)
args: [--force-single-line-imports, --profile, black]
- repo: https://github.com/asottile/pyupgrade
rev: v3.15.0
rev: v3.15.1
hooks:
- id: pyupgrade
args: [--py3-plus]
- repo: https://github.com/psf/black
rev: 23.12.1
rev: 24.2.0
hooks:
- id: black
language_version: python3
Expand Down
24 changes: 19 additions & 5 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,8 +1,22 @@
# Requirements Updated
- qbittorrent-api==2024.1.58
- qbittorrent-api==2024.2.59
- GitPython==3.1.42
- ruamel.yaml==0.18.6

# Updates
- Adds arguments for mover script (Adds #473)
# New Features
- Adds support for filtering more than just Completed torrents. Closes [#115](https://github.com/StuffAnThings/qbit_manage/issues/115)
- Updates mover script (Add check if file is still on cache mount #493)
- Adds support for ghcr.io container registry
- Adds support for custom [share_limits/cross-seed tags](https://github.com/StuffAnThings/qbit_manage/commit/9f8be69a4f2680501d492a8c7148969ae5ac5b72#diff-e5794b6d2186004aa3ee69cd4dee7bbd48d8e0edd9f1da90d03393ec28cbf912) Closes [#457](https://github.com/StuffAnThings/qbit_manage/issues/457)

Special thanks to @NooNameR for their contributions!
**Full Changelog**: https://github.com/StuffAnThings/qbit_manage/compare/v4.0.7...v4.0.8

# Bug Fixes
- Fixes [#359](https://github.com/StuffAnThings/qbit_manage/issues/359)
- Fixes [#479](https://github.com/StuffAnThings/qbit_manage/issues/479)
- Fixes [#487](https://github.com/StuffAnThings/qbit_manage/issues/487)
- Fixes [#488](https://github.com/StuffAnThings/qbit_manage/issues/488)
- Fixes [#490](https://github.com/StuffAnThings/qbit_manage/issues/490)
- Update script header so that env python3 is used.

Special thanks to @NooNameR, @ShanaryS, @ext4xfs for their contributions!
**Full Changelog**: https://github.com/StuffAnThings/qbit_manage/compare/v4.0.8...v4.0.9
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4.0.8
4.0.9
18 changes: 14 additions & 4 deletions config/config.yml.sample
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,20 @@ settings:
tracker_error_tag: issue # Will set the tag of any torrents that do not have a working tracker.
nohardlinks_tag: noHL # Will set the tag of any torrents with no hardlinks.
share_limits_tag: ~share_limit # Will add this tag when applying share limits to provide an easy way to filter torrents by share limit group/priority for each torrent
share_limits_min_seeding_time_tag: MinSeedTimeNotReached # Tag to be added to torrents that have not yet reached the minimum seeding time
share_limits_min_num_seeds_tag: MinSeedsNotMet # Tag to be added to torrents that have not yet reached the minimum number of seeds
share_limits_last_active_tag: LastActiveLimitNotReached # Tag to be added to torrents that have not yet reached the last active limit
ignoreTags_OnUpdate: # When running tag-update function, it will update torrent tags for a given torrent even if the torrent has at least one or more of the tags defined here. Otherwise torrents will not be tagged if tags exist.
- noHL
- issue
- cross-seed
- MinSeedTimeNotReached
- MinSeedsNotMet
- LastActiveLimitNotReached
cross_seed_tag: cross-seed # Will set the tag of any torrents that are added by cross-seed command
cat_filter_completed: True # Filters for completed torrents only when running cat_update command
share_limits_filter_completed: True # Filters for completed torrents only when running share_limits command
tag_nohardlinks_filter_completed: True # Filters for completed torrents only when running tag_nohardlinks command
directory:
# Do not remove these
# Cross-seed var: </your/path/here/> # Output directory of cross-seed
Expand Down Expand Up @@ -172,10 +182,10 @@ share_limits:
categories:
- RadarrComplete
- SonarrComplete
# <OPTIONAL> max_ratio <float>: Will set the torrent Maximum share ratio until torrent is stopped from seeding/uploading.
# <OPTIONAL> max_ratio <float>: Will set the torrent Maximum share ratio until torrent is stopped from seeding/uploading and may be cleaned up / removed if the minimums have been met.
# Will default to -1 (no limit) if not specified for the group.
max_ratio: 5.0
# <OPTIONAL> max_seeding_time <int>: Will set the torrent Maximum seeding time (minutes) until torrent is stopped from seeding.
# <OPTIONAL> max_seeding_time <int>: Will set the torrent Maximum seeding time (minutes) until torrent is stopped from seeding/uploading and may be cleaned up / removed if the minimums have been met.
# Will default to -1 (no limit) if not specified for the group.
max_seeding_time: 129600
# <OPTIONAL> min_seeding_time <int>: Will prevent torrent deletion by cleanup variable if torrent has not yet minimum seeding time (minutes).
Expand All @@ -188,14 +198,14 @@ share_limits:
last_active: 43200
# <OPTIONAL> Limit Upload Speed <int>: Will limit the upload speed KiB/s (KiloBytes/second) (`-1` : No Limit)
limit_upload_speed: 0
# <OPTIONAL> cleanup <bool>: WARNING!! Setting this as true Will remove and delete contents of any torrents that satisfies the share limits
# <OPTIONAL> cleanup <bool>: WARNING!! Setting this as true Will remove and delete contents of any torrents that satisfies the share limits (max time OR max ratio)
cleanup: false
# <OPTIONAL> resume_torrent_after_change <bool>: This variable will resume your torrent after changing share limits. Default is true
resume_torrent_after_change: true
# <OPTIONAL> add_group_to_tag <bool>: This adds your grouping as a tag with a prefix defined in settings . Default is true
# Example: A grouping defined as noHL will have a tag set to ~share_limit.noHL (if using the default prefix)
add_group_to_tag: true
# <OPTIONAL> min_num_seeds <int>: This will prevent torrent deletion by cleanup variable if the number of seeds is less than the value set here.
# <OPTIONAL> min_num_seeds <int>: Will prevent torrent deletion by cleanup variable if the number of seeds is less than the value set here.
# If the torrent has less number of seeds than the min_num_seeds, the share limits will be changed back to no limits and resume the torrent to continue seeding.
# Will default to 0 if not specified for the group.
min_num_seeds: 0
Expand Down
1 change: 1 addition & 0 deletions modules/apprise.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Apprise notification class"""

import time

from modules import util
Expand Down
1 change: 1 addition & 0 deletions modules/bhd.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Module for BeyondHD (BHD) tracker."""

from json import JSONDecodeError

from modules import util
Expand Down
48 changes: 41 additions & 7 deletions modules/config.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Config class for qBittorrent-Manage"""

import os
import re
import stat
Expand All @@ -13,9 +14,9 @@
from modules.bhd import BeyondHD
from modules.notifiarr import Notifiarr
from modules.qbittorrent import Qbt
from modules.util import check
from modules.util import Failed
from modules.util import YAML
from modules.util import Failed
from modules.util import check
from modules.webhooks import Webhooks

logger = util.logger
Expand Down Expand Up @@ -167,17 +168,47 @@ def hooks(attr):
"share_limits_tag": self.util.check_for_attribute(
self.data, "share_limits_tag", parent="settings", default=share_limits_tag
),
"share_limits_min_seeding_time_tag": self.util.check_for_attribute(
self.data, "share_limits_min_seeding_time_tag", parent="settings", default="MinSeedTimeNotReached"
),
"share_limits_min_num_seeds_tag": self.util.check_for_attribute(
self.data, "share_limits_min_num_seeds_tag", parent="settings", default="MinSeedsNotMet"
),
"share_limits_last_active_tag": self.util.check_for_attribute(
self.data, "share_limits_last_active_tag", parent="settings", default="LastActiveLimitNotReached"
),
"cross_seed_tag": self.util.check_for_attribute(self.data, "cross_seed_tag", parent="settings", default="cross-seed"),
"cat_filter_completed": self.util.check_for_attribute(
self.data, "cat_filter_completed", parent="settings", var_type="bool", default=True
),
"share_limits_filter_completed": self.util.check_for_attribute(
self.data, "share_limits_filter_completed", parent="settings", var_type="bool", default=True
),
"tag_nohardlinks_filter_completed": self.util.check_for_attribute(
self.data, "tag_nohardlinks_filter_completed", parent="settings", var_type="bool", default=True
),
}

self.tracker_error_tag = self.settings["tracker_error_tag"]
self.nohardlinks_tag = self.settings["nohardlinks_tag"]
self.share_limits_tag = self.settings["share_limits_tag"]

default_ignore_tags = [self.nohardlinks_tag, self.tracker_error_tag, "cross-seed"]
self.share_limits_min_seeding_time_tag = self.settings["share_limits_min_seeding_time_tag"]
self.share_limits_min_num_seeds_tag = self.settings["share_limits_min_num_seeds_tag"]
self.share_limits_last_active_tag = self.settings["share_limits_last_active_tag"]
self.cross_seed_tag = self.settings["cross_seed_tag"]

self.default_ignore_tags = [
self.nohardlinks_tag,
self.tracker_error_tag,
self.cross_seed_tag,
self.share_limits_min_seeding_time_tag,
self.share_limits_min_num_seeds_tag,
self.share_limits_last_active_tag,
]
self.settings["ignoreTags_OnUpdate"] = self.util.check_for_attribute(
self.data, "ignoreTags_OnUpdate", parent="settings", default=default_ignore_tags, var_type="list"
self.data, "ignoreTags_OnUpdate", parent="settings", default=self.default_ignore_tags, var_type="list"
)
"Migrate settings from v4.0.0 to v4.0.1 and beyond. Convert 'share_limits_suffix_tag' to 'share_limits_tag'"
# "Migrate settings from v4.0.0 to v4.0.1 and beyond. Convert 'share_limits_suffix_tag' to 'share_limits_tag'"
if "share_limits_suffix_tag" in self.data["settings"]:
self.util.overwrite_attributes(self.settings, "settings")

Expand Down Expand Up @@ -280,6 +311,8 @@ def hooks(attr):
cat_str = list(cat.keys())[0]
self.nohardlinks[cat_str] = {}
exclude_tags = cat[cat_str].get("exclude_tags", [])
if exclude_tags is None:
exclude_tags = []
if isinstance(exclude_tags, str):
exclude_tags = [exclude_tags]
self.nohardlinks[cat_str]["exclude_tags"] = exclude_tags
Expand Down Expand Up @@ -687,7 +720,8 @@ def cleanup_dirs(self, location):
if num_del > 0:
if not self.dry_run:
for path in location_path_list:
util.remove_empty_directories(path, "**/*")
if path != location_path:
util.remove_empty_directories(path, "**/*")
body += logger.print_line(
f"{'Did not delete' if self.dry_run else 'Deleted'} {num_del} files "
f"({util.human_readable_size(size_bytes)}) from the {location}.",
Expand Down
5 changes: 3 additions & 2 deletions modules/core/category.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@ def __init__(self, qbit_manager):
self.torrents_updated = [] # List of torrents updated
self.notify_attr = [] # List of single torrent attributes to send to notifiarr
self.uncategorized_mapping = "Uncategorized"
self.status_filter = "completed" if self.config.settings["cat_filter_completed"] else "all"

self.category()
self.config.webhooks_factory.notify(self.torrents_updated, self.notify_attr, group_by="category")

def category(self):
"""Update category for torrents that don't have any category defined and returns total number categories updated"""
logger.separator("Updating Categories", space=False, border=False)
torrent_list = self.qbt.get_torrents({"category": "", "status_filter": "completed"})
torrent_list = self.qbt.get_torrents({"category": "", "status_filter": self.status_filter})
for torrent in torrent_list:
new_cat = self.get_tracker_cat(torrent) or self.qbt.get_category(torrent.save_path)
if new_cat == self.uncategorized_mapping:
Expand All @@ -32,7 +33,7 @@ def category(self):
# Change categories
if self.config.cat_change:
for old_cat in self.config.cat_change:
torrent_list = self.qbt.get_torrents({"category": old_cat, "status_filter": "completed"})
torrent_list = self.qbt.get_torrents({"category": old_cat, "status_filter": self.status_filter})
for torrent in torrent_list:
new_cat = self.config.cat_change[old_cat]
self.update_cat(torrent, new_cat, True)
Expand Down
Loading

0 comments on commit 29690e9

Please sign in to comment.