Skip to content
This repository has been archived by the owner on Jul 25, 2023. It is now read-only.

Commit

Permalink
[minor] Add support for Docker and create a docker image (#26)
Browse files Browse the repository at this point in the history
  • Loading branch information
Drapersniper authored Jan 25, 2022
1 parent 285ec61 commit 635fd14
Show file tree
Hide file tree
Showing 9 changed files with 237 additions and 55 deletions.
15 changes: 15 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.git
.gitignore
.github
.gitattributes

.bumpversion.cfg
.grenrc.yml
.pre-commit-config.yaml

CHANGELOG.md
README.md

dist/
build/
qBitrr.egg-info/
7 changes: 7 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
version: 2
updates:
# Maintain dependencies for GitHub Actions
- package-ecosystem: github-actions
directory: /
schedule:
interval: daily
26 changes: 26 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -284,3 +284,29 @@ jobs:
commit_user_name: ${{ steps.import_gpg.outputs.name }}
commit_user_email: ${{ steps.import_gpg.outputs.email }}
commit_author: ${{ steps.import_gpg.outputs.name }} <${{ steps.import_gpg.outputs.email }}>
docker_image:
name: Build Docker Image
needs: [bump_version, release_hash]
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
ref: master
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v2
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: drapersniper/qbitrr:latest
24 changes: 24 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Pin Python to the latest supported version
# (This avoid it auto updating to a higher untested version)
FROM pypy:3.8-7.3.7

LABEL Maintainer="Draper"

# Env used by the script to determine if its inside a docker -
# if this is set to 69420 it will change the working dir for docker specific values
ENV QBITRR_DOCKER_RUNNING=69420

COPY . /app

WORKDIR /app/

ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

RUN pypy -m ensurepip --default-pip && \
pip install -U pip wheel && \
pip install -e .

WORKDIR /config

ENTRYPOINT ["pypy", "-m", "qBitrr.main"]
46 changes: 46 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[![PyPI](https://img.shields.io/pypi/v/qBitrr)](https://pypi.org/project/qBitrr/)
[![PyPI](https://img.shields.io/pypi/dm/qbitrr)](https://pypi.org/project/qBitrr/)
[![PyPI - License](https://img.shields.io/pypi/l/qbitrr)](https://github.com/Drapersniper/Qbitrr/blob/master/LICENSE)
[![Pulls](https://img.shields.io/docker/pulls/drapersniper/qbitrr.svg)](https://hub.docker.com/r/drapersniper/qbitrr)

![PyPI - Python Version](https://img.shields.io/pypi/pyversions/qbitrr)
![Platforms](https://img.shields.io/badge/platform-linux--64%20%7C%20osx--64%20%7C%20win--32%20%7C%20win--64-lightgrey)
Expand Down Expand Up @@ -76,3 +77,48 @@ Alternatively:
#### Example behaviour

![image](https://user-images.githubusercontent.com/27962761/146447714-5309d3e6-51fd-472c-9587-9df491f121b3.png)


#### Docker Image
- The docker image can be found [here](https://hub.docker.com/r/drapersniper/qbitrr)

#### Docker Compose
```json
version: "3"
services:
qbitrr:
image: qbitrr
user: 1000:1000 # Required to ensure teh container is run as the user who has perms to see the 2 mount points and the ability to write to the CompletedDownloadFolder mount
restart: unless-stopped
# networks: This container MUST share a network with your Sonarr/Radarr instances
enviroment:
TZ: Europe/London
volumes:
- /etc/localtime:/etc/localtime:ro
- /path/to/appdata/qbitrr:/config # All qbitrr files are stored in the `/config` folder when using a docker container
- /path/to/sonarr/db:/sonarr.db/path/in/container:ro # This is only needed if you want episode search handling :ro means it is only ever mounted as a read-only folder, the script never needs more than read access
- /path/to/radarr/db:/radarr.db/path/in/container:ro # This is only needed if you want movie search handling, :ro means it is only ever mounted as a read-only folder, the script never needs more than read access
- /path/to/completed/downloads/folder:/completed_downloads/folder/in/container:rw # The script will ALWAYS require write permission in this folder if mounted, this folder is used to monitor completed downloads and if not present will cause the script to ignore downloaded file monitoring.
# Now just to make sure it is clean, when using this script in a docker you will need to ensure you config.toml values reflect the mounted folders.#
# For example, for your Sonarr.DatabaseFile value using the values above you'd add
# DatabaseFile = /sonarr.db/path/in/container/sonarr.db
# Because this is where you mounted it to
# The same would apply to Settings.CompletedDownloadFolder
# e.g CompletedDownloadFolder = /completed_downloads/folder/in/container

logging: # this script will generate a LOT of logs - so it is up to you to decide how much of it you want to store
driver: "json-file"
options:
max-size: "50m"
max-file: 3
depends_on: # Not needed but this ensures qBitrr only starts if the dependencies are up and running
- qbittorrent
- radarr-1080p
- sonarr-1080p
- animarr-1080p
- overseerr
```
##### Important mentions for docker
- The script will always expect a completed config.toml file
- When you first start the container a "config.rename_me.toml" will be added to `/path/to/appdata/qbitrr`
- Make sure to rename it to 'config.toml' then edit it to your desired values
22 changes: 12 additions & 10 deletions qBitrr/arss.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,21 +77,21 @@ def __init__(
f"Group '{self._name}' is trying to manage Arr instance: "
f"'{self.uri}' which has already been registered."
)

self.category = CONFIG.get(f"{name}.Category", fallback=self._name)
self.manager = manager
self._LOG_LEVEL = self.manager.qbit_manager.logger.level
self.logger = logging.getLogger(f"qBitrr.{self._name}")
run_logs(self.logger)
self.completed_folder = pathlib.Path(COMPLETED_DOWNLOAD_FOLDER).joinpath(self.category)
if not self.completed_folder.exists():
try:
self.completed_folder.mkdir(parents=True)
self.completed_folder.mkdir(parents=True, exist_ok=True)
except Exception:
raise OSError(
f"{self._name} completed folder is a requirement, "
f"The specified folder does not exist '{self.completed_folder}'"
self.logger.warning(
f"{self._name} completed folder is a soft requirement. "
f"The specified folder does not exist '{self.completed_folder}' "
"and cannot be created. This will disable all file monitoring."
)
self.manager = manager
self._LOG_LEVEL = self.manager.qbit_manager.logger.level
self.logger = logging.getLogger(f"qBitrr.{self._name}")
run_logs(self.logger)
self.apikey = CONFIG.get_or_raise(f"{name}.APIKey")
self.re_search = CONFIG.get(f"{name}.ReSearch", fallback=False)
self.import_mode = CONFIG.get(f"{name}.importMode", fallback="Move")
Expand Down Expand Up @@ -3222,11 +3222,13 @@ def __init__(self, qbitmanager: qBitManager):

def build_arr_instances(self):
for key in CONFIG.sections():
if search := re.match("(rad|son)arr.*", key, re.IGNORECASE):
if search := re.match("(rad|son|anim)arr.*", key, re.IGNORECASE):
name = search.group(0)
match = search.group(1)
if match.lower() == "son":
call_cls = SonarrAPI
elif match.lower() == "anim":
call_cls = SonarrAPI
elif match.lower() == "rad":
call_cls = RadarrAPI
else:
Expand Down
23 changes: 16 additions & 7 deletions qBitrr/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@

from qBitrr.bundled_data import license_text, patched_version
from qBitrr.gen_config import MyConfig, generate_doc
from qBitrr.home_path import HOME_PATH, ON_DOCKER

APPDATA_FOLDER = pathlib.Path().home().joinpath(".config", "qBitManager")
APPDATA_FOLDER = HOME_PATH.joinpath(".config", "qBitManager")
APPDATA_FOLDER.mkdir(parents=True, exist_ok=True)


Expand Down Expand Up @@ -81,12 +82,20 @@ def process_flags() -> argparse.Namespace | bool:
CONFIG = MyConfig(CONFIG_FILE, config=generate_doc())
COPIED_TO_NEW_DIR = None
elif (not CONFIG_FILE.exists()) and (not CONFIG_PATH.exists()):
print(f"{file} has not been found")
print(f"{file} must be added to {CONFIG_FILE}")
print(
"You can run me with the `--gen-config` flag to generate a "
"template config file which you can then edit."
)
if ON_DOCKER:
print(f"{file} has not been found")
from qBitrr.gen_config import _write_config_file

CONFIG_FILE = _write_config_file(docker=True)
print(f"'{CONFIG_FILE.name}' has been generated")
print('Rename it to "config.toml" then edit it and restart the container')
else:
print(f"{file} has not been found")
print(f"{file} must be added to {CONFIG_FILE}")
print(
"You can run me with the `--gen-config` flag to generate a "
"template config file which you can then edit."
)
sys.exit(1)

elif CONFIG_FILE.exists():
Expand Down
Loading

0 comments on commit 635fd14

Please sign in to comment.