From 450de98d32713795f4c0f0749eaf6352549594c1 Mon Sep 17 00:00:00 2001 From: Jeena Date: Mon, 2 Jun 2025 06:56:36 +0900 Subject: [PATCH] Make it a proper python module --- PKGBUILD | 28 +++++--- README.md | 97 ++++++++++++++++++++++++++ pyproject.toml | 13 ++++ src/app.py | 30 -------- src/{ => recoder}/__init__.py | 0 src/recoder/app.py | 30 ++++++++ src/{ => recoder}/config.py | 0 src/{ => recoder}/models.py | 0 src/{ => recoder}/transcoder_worker.py | 0 src/{ => recoder}/ui.py | 4 +- 10 files changed, 160 insertions(+), 42 deletions(-) create mode 100644 pyproject.toml delete mode 100755 src/app.py rename src/{ => recoder}/__init__.py (100%) create mode 100755 src/recoder/app.py rename src/{ => recoder}/config.py (100%) rename src/{ => recoder}/models.py (100%) rename src/{ => recoder}/transcoder_worker.py (100%) rename src/{ => recoder}/ui.py (98%) diff --git a/PKGBUILD b/PKGBUILD index 9d15fb1..436ff48 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -18,17 +18,25 @@ optdepends=( 'libcanberra: play system notification sounds' 'sound-theme-freedesktop: standard system sounds like "complete.oga"' ) -makedepends=('python-setuptools') +makedepends=( + 'python-setuptools' + 'python-build' + 'python-installer' +) source=() sha256sums=() -package() { - install -Dm755 "../src/app.py" "$pkgdir/usr/bin/recoder" - install -Dm644 "../src/config.py" "$pkgdir/usr/lib/recoder/config.py" - install -Dm644 "../src/models.py" "$pkgdir/usr/lib/recoder/models.py" - install -Dm644 "../src/transcoder_worker.py" "$pkgdir/usr/lib/recoder/transcoder_worker.py" - install -Dm644 "../src/ui.py" "$pkgdir/usr/lib/recoder/ui.py" - install -Dm644 "../resources/net.jeena.Recoder.desktop" "$pkgdir/usr/share/applications/net.jeena.Recoder.desktop" - install -Dm644 "../resources/net.jeena.Recoder.png" "$pkgdir/usr/share/icons/hicolor/256x256/apps/net.jeena.Recoder.png" - install -Dm644 "../src/__init__.py" "$pkgdir/usr/lib/recoder/__init__.py" +build() { + cd "$srcdir" + python -m build --wheel } + +package() { + cd "$srcdir" + python -m installer --destdir="$pkgdir" dist/*.whl + + install -Dm644 resources/net.jeena.Recoder.desktop \ + "$pkgdir/usr/share/applications/net.jeena.Recoder.desktop" + install -Dm644 resources/net.jeena.Recoder.png \ + "$pkgdir/usr/share/icons/hicolor/256x256/apps/net.jeena.Recoder.png" +} \ No newline at end of file diff --git a/README.md b/README.md index e69de29..0ecc0f7 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,97 @@ +# Recoder + +**Recoder** is a GTK4-based GUI application for video transcoding. It provides a clean, modern interface using Libadwaita and integrates with `ffmpeg` to convert videos with ease. + +![screenshot](resources/net.jeena.Recoder.png) + +--- + +## โœจ Features + +- Simple and elegant GTK4 interface +- Built with Libadwaita for a native GNOME look +- Supports common video formats using `ffmpeg` +- Lightweight and fast +- System notifications on task completion + +--- + +## ๐Ÿ›  Requirements + +- Python 3.10+ +- GTK4 +- Libadwaita +- `ffmpeg` +- Python bindings: + - `python-gobject` + +--- + +## ๐Ÿš€ Installation (Arch Linux) + +```bash +git clone https://github.com/jeena/recoder.git +cd recoder +makepkg -si +``` + +This will install Recoder system-wide using Pacman, so you can later remove it cleanly: + +```bash +sudo pacman -R recoder +``` + +--- + +## ๐Ÿงช Development Setup + +If you're hacking on Recoder: + +```bash +git clone https://github.com/jeena/recoder.git +cd recoder +python -m venv .venv +source .venv/bin/activate +pip install -e . +``` + +Then run: + +```bash +recoder +``` + +--- + +## ๐Ÿ“ Project Structure + +``` +src/ +โ””โ”€โ”€ recoder/ + โ”œโ”€โ”€ app.py + โ”œโ”€โ”€ config.py + โ”œโ”€โ”€ models.py + โ”œโ”€โ”€ transcoder_worker.py + โ””โ”€โ”€ ui.py +resources/ +โ”œโ”€โ”€ net.jeena.Recoder.desktop +โ””โ”€โ”€ net.jeena.Recoder.png +``` + +--- + +## ๐Ÿ“ฆ Packaging + +Recoder follows modern Python packaging using `pyproject.toml` and `setuptools`. The Arch package installs Python modules to `site-packages` and the desktop file + icon in appropriate locations. + +--- + +## ๐Ÿ“„ License + +Licensed under the GPLv3. See `LICENSE` for details. + +--- + +## ๐Ÿ‘ค Author + +Made by Jeena ยท [github.com/jeena](https://github.com/jeena) \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..b53877a --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,13 @@ +[project] +name = "recoder" +version = "1.0.0" +description = "A GTK4 video transcoding GUI application" +authors = [{name = "Jeena", email = "hello@jeena.net"}] +license = "GPL-3.0-or-later" + +[project.scripts] +recoder = "recoder.app:main" # This creates the /usr/bin/recoder entrypoint + +[build-system] +requires = ["setuptools", "wheel"] +build-backend = "setuptools.build_meta" diff --git a/src/app.py b/src/app.py deleted file mode 100755 index 369b24f..0000000 --- a/src/app.py +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env python3 - -import sys -import gi - -gi.require_version('Gtk', '4.0') -gi.require_version('Adw', '1') - -from gi.repository import Adw, Gio -from ui import RecoderWindow - -Adw.init() - -class RecoderApp(Adw.Application): - def __init__(self): - super().__init__(application_id="net.jeena.Recoder", - flags=Gio.ApplicationFlags.FLAGS_NONE) - self.window = None - - def do_activate(self): - if not self.window: - self.window = RecoderWindow(application=self) - self.window.present() - -def main(): - app = RecoderApp() - return app.run(sys.argv) - -if __name__ == "__main__": - sys.exit(main()) diff --git a/src/__init__.py b/src/recoder/__init__.py similarity index 100% rename from src/__init__.py rename to src/recoder/__init__.py diff --git a/src/recoder/app.py b/src/recoder/app.py new file mode 100755 index 0000000..8b8b362 --- /dev/null +++ b/src/recoder/app.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python3 +import sys +import gi + +gi.require_version('Gtk', '4.0') +gi.require_version('Adw', '1') + +from gi.repository import Adw, Gio + +Adw.init() + +def main(): + from recoder.ui import RecoderWindow # delayed import + + class RecoderApp(Adw.Application): + def __init__(self): + super().__init__(application_id="net.jeena.Recoder", + flags=Gio.ApplicationFlags.FLAGS_NONE) + self.window = None + + def do_activate(self): + if not self.window: + self.window = RecoderWindow(application=self) + self.window.present() + + app = RecoderApp() + return app.run(sys.argv) + +if __name__ == "__main__": + sys.exit(main()) diff --git a/src/config.py b/src/recoder/config.py similarity index 100% rename from src/config.py rename to src/recoder/config.py diff --git a/src/models.py b/src/recoder/models.py similarity index 100% rename from src/models.py rename to src/recoder/models.py diff --git a/src/transcoder_worker.py b/src/recoder/transcoder_worker.py similarity index 100% rename from src/transcoder_worker.py rename to src/recoder/transcoder_worker.py diff --git a/src/ui.py b/src/recoder/ui.py similarity index 98% rename from src/ui.py rename to src/recoder/ui.py index 24e5599..c5599bd 100644 --- a/src/ui.py +++ b/src/recoder/ui.py @@ -7,8 +7,8 @@ gi.require_version('Adw', '1') from gi.repository import Gtk, Adw, Gio, Gdk, GLib from functools import partial -from config import load_config, save_config -from transcoder_worker import TranscoderWorker +from recoder.config import load_config, save_config +from recoder.transcoder_worker import TranscoderWorker class RecoderWindow(Adw.ApplicationWindow): def __init__(self, **kwargs):