Skip to content

Commit

Permalink
Use proper Python packaging (#35)
Browse files Browse the repository at this point in the history
* Use proper package file structure

* Move 'config.json' inside 'fertilizer' package

* Use pyproject-based package definition

Make use of PEP 621 and PEP 735 based project metadata, for use with
modern package managers.

* Add 'uv' lockfile

* Got Docker booting again

* Formatting

---------

Co-authored-by: moleculekayak <[email protected]>
  • Loading branch information
ambroisie and moleculekayak authored Dec 19, 2024
1 parent 53d78a5 commit 56c4a18
Show file tree
Hide file tree
Showing 42 changed files with 427 additions and 57 deletions.
7 changes: 2 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,12 @@ FROM python:3.11-slim-buster

WORKDIR /app

COPY requirements.txt main.py docker_start ./
COPY pyproject.toml docker_start ./
COPY src src

RUN apt-get update \
&& echo "----- Installing python requirements" \
&& pip install --trusted-host pypi.python.org -r requirements.txt \
&& echo "----- Creating executable" \
&& echo "#!/bin/bash\npython3 /app/main.py \$@" >/bin/fertilizer \
&& chmod +x /bin/fertilizer \
&& pip install --trusted-host pypi.python.org . \
&& echo "----- Preparing directories" \
&& mkdir /config /data /torrents \
&& echo "----- Cleanup" \
Expand Down
2 changes: 1 addition & 1 deletion docker_start
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/bin/sh

if [ ! -f /config/config.json ]; then
cp /app/src/config.json /config/config.json
cp /app/src/fertilizer/config.json /config/config.json
fi

$@
29 changes: 29 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,32 @@
[project]
name = "fertilizer"
version = "0.2.4"
description = "fertilizer helps your seeds grow"
readme = "README.md"
requires-python = ">=3.11"
dependencies = [
"bencoder",
"colorama",
"requests",
"flask",
"pytest",
"requests-mock",
"ruff",
]

[project.scripts]
fertilizer = "fertilizer.main:main"

[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"

[dependency-groups]
dev = [
"pytest",
"requests-mock",
]

[tool.ruff]
line-length = 120
indent-width = 2
Expand Down
7 changes: 0 additions & 7 deletions requirements.txt

This file was deleted.

File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion src/args.py → src/fertilizer/args.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def parse_args(args=None):
"--config-file",
type=str,
help="path to a configuration file",
default="src/config.json",
default="src/fertilizer/config.json",
)

parsed = parser.parse_args(args)
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from urllib.parse import urlparse, unquote

from src.utils import url_join
from fertilizer.utils import url_join


class TorrentClient:
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
18 changes: 11 additions & 7 deletions main.py → src/fertilizer/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@

from colorama import Fore

from src.args import parse_args
from src.config import Config
from src.injection import Injection
from src.scanner import scan_torrent_directory, scan_torrent_file
from src.config_validator import ConfigValidator
from src.webserver import run_webserver
from fertilizer.args import parse_args
from fertilizer.config import Config
from fertilizer.injection import Injection
from fertilizer.scanner import scan_torrent_directory, scan_torrent_file
from fertilizer.config_validator import ConfigValidator
from fertilizer.webserver import run_webserver


def cli_entrypoint(args):
Expand Down Expand Up @@ -60,11 +60,15 @@ def maybe_print(str, *args, **kwargs):
raise e


if __name__ == "__main__":
def main():
args = parse_args()

try:
cli_entrypoint(args)
except KeyboardInterrupt:
print(f"{Fore.RED}Exiting...{Fore.RESET}")
exit(1)


if __name__ == "__main__":
main()
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
6 changes: 3 additions & 3 deletions src/webserver.py → src/fertilizer/webserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@

from flask import Flask, request

from src.errors import TorrentAlreadyExistsError, TorrentNotFoundError
from src.parser import is_valid_infohash
from src.scanner import scan_torrent_file
from fertilizer.errors import TorrentAlreadyExistsError, TorrentNotFoundError
from fertilizer.parser import is_valid_infohash
from fertilizer.scanner import scan_torrent_file

app = Flask(__name__)

Expand Down
4 changes: 2 additions & 2 deletions tests/clients/test_deluge.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
torrent_info_matcher,
)

from src.errors import TorrentClientError, TorrentClientAuthenticationError, TorrentExistsInClientError
from src.clients.deluge import Deluge
from fertilizer.errors import TorrentClientError, TorrentClientAuthenticationError, TorrentExistsInClientError
from fertilizer.clients.deluge import Deluge


@pytest.fixture
Expand Down
4 changes: 2 additions & 2 deletions tests/clients/test_qbittorrent.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

from tests.helpers import SetupTeardown, get_torrent_path

from src.errors import TorrentClientError, TorrentClientAuthenticationError, TorrentExistsInClientError
from src.clients.qbittorrent import Qbittorrent
from fertilizer.errors import TorrentClientError, TorrentClientAuthenticationError, TorrentExistsInClientError
from fertilizer.clients.qbittorrent import Qbittorrent


@pytest.fixture
Expand Down
4 changes: 2 additions & 2 deletions tests/clients/test_transmission.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

from tests.helpers import SetupTeardown, get_torrent_path

from src.errors import TorrentClientError, TorrentClientAuthenticationError, TorrentExistsInClientError
from src.clients.transmission import TransmissionBt
from fertilizer.errors import TorrentClientError, TorrentClientAuthenticationError, TorrentExistsInClientError
from fertilizer.clients.transmission import TransmissionBt


@pytest.fixture
Expand Down
4 changes: 2 additions & 2 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import pytest
import requests_mock

from src.config import Config
from src.api import RedAPI, OpsAPI
from fertilizer.config import Config
from fertilizer.api import RedAPI, OpsAPI


@pytest.fixture
Expand Down
4 changes: 2 additions & 2 deletions tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

from .helpers import SetupTeardown

from src.errors import AuthenticationError
from src.api import GazelleAPI
from fertilizer.errors import AuthenticationError
from fertilizer.api import GazelleAPI


class MockApi(GazelleAPI):
Expand Down
4 changes: 2 additions & 2 deletions tests/test_args.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from .helpers import SetupTeardown

from src.args import parse_args
from fertilizer.args import parse_args


class TestArgs(SetupTeardown):
Expand All @@ -11,7 +11,7 @@ def test_parses_args(self):

assert args.input_directory == "foo"
assert args.output_directory == "bar"
assert args.config_file == "src/config.json"
assert args.config_file == "src/fertilizer/config.json"

def test_sets_input_directory(self, capsys):
args = parse_args(["-i", "foo", "-o", "bar"])
Expand Down
2 changes: 1 addition & 1 deletion tests/test_config.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from .helpers import SetupTeardown

from src.config import Config
from fertilizer.config import Config


class TestConfig(SetupTeardown):
Expand Down
2 changes: 1 addition & 1 deletion tests/test_config_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from .helpers import SetupTeardown

from src.config_validator import ConfigValidator
from fertilizer.config_validator import ConfigValidator


@pytest.fixture
Expand Down
2 changes: 1 addition & 1 deletion tests/test_filesystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from .helpers import SetupTeardown

from src.filesystem import sane_join, mkdir_p, assert_path_exists, list_files_of_extension, replace_extension
from fertilizer.filesystem import sane_join, mkdir_p, assert_path_exists, list_files_of_extension, replace_extension


class TestSaneJoin(SetupTeardown):
Expand Down
10 changes: 5 additions & 5 deletions tests/test_injection.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@

from .helpers import get_torrent_path, get_support_file_path, copy_and_mkdir, SetupTeardown

from src.clients.deluge import Deluge
from src.clients.qbittorrent import Qbittorrent
from src.clients.transmission import TransmissionBt
from src.errors import TorrentInjectionError
from src.injection import Injection
from fertilizer.clients.deluge import Deluge
from fertilizer.clients.qbittorrent import Qbittorrent
from fertilizer.clients.transmission import TransmissionBt
from fertilizer.errors import TorrentInjectionError
from fertilizer.injection import Injection


class ConfigMock:
Expand Down
6 changes: 3 additions & 3 deletions tests/test_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@

from .helpers import get_torrent_path, SetupTeardown

from src.errors import TorrentDecodingError
from src.trackers import RedTracker, OpsTracker
from src.parser import (
from fertilizer.errors import TorrentDecodingError
from fertilizer.trackers import RedTracker, OpsTracker
from fertilizer.parser import (
is_valid_infohash,
get_source,
get_name,
Expand Down
4 changes: 2 additions & 2 deletions tests/test_scanner.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@

from .helpers import SetupTeardown, get_torrent_path, copy_and_mkdir

from src.errors import TorrentExistsInClientError, TorrentDecodingError
from src.scanner import scan_torrent_directory, scan_torrent_file
from fertilizer.errors import TorrentExistsInClientError, TorrentDecodingError
from fertilizer.scanner import scan_torrent_directory, scan_torrent_file


class TestScanTorrentFile(SetupTeardown):
Expand Down
8 changes: 4 additions & 4 deletions tests/test_torrent.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@

from .helpers import get_torrent_path, SetupTeardown, copy_and_mkdir

from src.trackers import RedTracker
from src.parser import get_bencoded_data
from src.errors import TorrentAlreadyExistsError, TorrentDecodingError, UnknownTrackerError, TorrentNotFoundError
from src.torrent import generate_new_torrent_from_file
from fertilizer.trackers import RedTracker
from fertilizer.parser import get_bencoded_data
from fertilizer.errors import TorrentAlreadyExistsError, TorrentDecodingError, UnknownTrackerError, TorrentNotFoundError
from fertilizer.torrent import generate_new_torrent_from_file


class TestGenerateNewTorrentFromFile(SetupTeardown):
Expand Down
2 changes: 1 addition & 1 deletion tests/test_trackers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from .helpers import SetupTeardown

from src.trackers import RedTracker, OpsTracker
from fertilizer.trackers import RedTracker, OpsTracker


class TestTrackerMethods(SetupTeardown):
Expand Down
2 changes: 1 addition & 1 deletion tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from .helpers import SetupTeardown

from src.utils import flatten, url_join
from fertilizer.utils import flatten, url_join


class TestFlatten(SetupTeardown):
Expand Down
2 changes: 1 addition & 1 deletion tests/test_webserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from .helpers import SetupTeardown, get_torrent_path, copy_and_mkdir

from src.webserver import app as webserver_app
from fertilizer.webserver import app as webserver_app


@pytest.fixture()
Expand Down
Loading

0 comments on commit 56c4a18

Please sign in to comment.