diff --git a/readme.md b/readme.md index dbdc974..f647252 100644 --- a/readme.md +++ b/readme.md @@ -1,18 +1,30 @@ # Medios-Macina -- Audio -- Video -- Image -- Text -### Configuration +Medios-Macina is a CLI-first media ingestion and management toolkit focused on reliably downloading, tagging, and storing media (audio, video, images, and text) from a variety of providers and sources. It is designed around a compact, pipeable command language ("cmdlets") so complex workflows can be composed simply and repeatably. -The default config format is `config.conf`. +## Highlights ✅ +- Flexible pipeline-based CLI: chain cmdlets with `|` and use saved selections with `@N`. +- Multi-store support: HydrusNetwork, local folders, and provider-backed stores. +- Provider integrations: YouTube, OpenLibrary/Archive.org, Soulseek, LibGen, AllDebrid, and more. +- Utility cmdlets: screenshots (Playwright), metadata extraction, merging, and automated tagging. +- MPV-friendly: integrate with MPV playback and playlists for quick ingestion. -- Required: `temp` (where temporary/intermediate files are written) -- Optional: any number of stores and provider credentials -- Modular: you can add extra `.conf` fragments in `config.d\*.conf` (they will be merged) +## Quick start ⚡ +1. Install Python requirements: -Example `config.conf`: +```powershell +python -m pip install -r requirements.txt + +# Automated setup (recommended): run the single Python setup script which installs +# all Python dependencies (from requirements.txt) and downloads Playwright browsers. +# Usage: +python ./scripts/setup.py + +# Advanced options: +# - Skip dependency installation: python ./scripts/setup.py --skip-deps +# - Install only Playwright browsers: python ./scripts/setup.py --playwright-only +``` +2. Copy or edit `config.conf` and set a required `temp` directory where intermediate files are written. Example: ```ini temp="C:\\Users\\Admin\\Downloads" @@ -31,70 +43,63 @@ email="user@example.com" password="..." ``` -### File Store -- HydrusNetwork https://github.com/hydrusnetwork/hydrus -- Local drive (C://mylibrary/path) +3. Start the CLI: -### File Providers -- Youtube -- Openlibrary/Archive.org (free account needed) -- Soulseek -- Gog-Games (limited without paid API) -- Libgen -- All-Debrid https://alldebrid.com/ - -### Features -- Full MPV integration https://github.com/mpv-player/mpv -- Database file management -- API/CLI exclusive -- Plug and play stores and add-ons -- YT-DLP integration -- CMDLET easy syntax -- CLI auto-complete - -Install what you need and want, after you have the requirements.txt installed as well you will need to open terminal at the repository download location and run the cli file like . - - -#### Quick - -```shell +```powershell cd "C:\location\to\repository\medios-machina\" python cli.py ``` -Adding your first file -```python -.pipe -list # List MPV current playing/list -.pipe -save # Save current MPV playlist to local library -.pipe -load # List saved playlists; use @N to load one -.pipe "https://www.youtube.com/watch?v=_23dFb50Z2Y" # Add URL to current playlist -``` -Example pipelines: +## Usage overview 🔧 +- Pipelines: chain cmdlets with `|`, e.g., `download-media | add-file -storage local`. +- Selections: search cmdlets populate a selectable ResultTable; refer to entries with `@`. +- Tagging & metadata: `add-tag` mutates piped results (temporary path items) or writes to a configured store when `-store` is provided. -1. **Simple download with metadata (tags and URL registration)**: -``` +## Common examples 💡 + +Simple download with metadata (tags and URL registration): +```bash download-media "https://www.youtube.com/watch?v=dQw4w9WgXcQ" | add-file -storage local | add-url ``` -2. **Download playlist item with tags**: -``` +Download a playlist item: +```bash download-media "https://www.youtube.com/playlist?list=PLxxxxx" -item 2 | add-file -storage local | add-url ``` -3. **Download with merge (e.g., Bandcamp albums)**: -``` -download-data "https://altrusiangrace.bandcamp.com/album/ancient-egyptian-legends-full-audiobook" | merge-file | add-file -storage local | add-url +Take a website screenshot, tag it, and store locally: +```bash +screen-shot "https://example.com/page" | add-tag "title:Example Page,source:web" | add-file -store local ``` -4. **Download direct file (PDF, document)**: -``` -download-file "https://example.com/file.pdf" | add-file -storage local | add-url +OpenLibrary ingestion (book metadata & PDF/ebook handling is automatically enriched when `add-file` detects an OpenLibrary URL): +```bash +add-file "https://openlibrary.org/books/OLxxxxxM/Book_Title" -storage local ``` -Search examples: +Search & download flow (select with `@`): +```bash +search-file -provider youtube "my favourite track" +@1 +download-media [URL] | add-file -store hydrus +``` -1. search-file -provider youtube "something in the way" +## Providers & stores +- **HydrusNetwork**: use for database-backed media storage and advanced tagging (requires running Hydrus client/server). +- **Local folder**: copy files to a configured directory (fast and simple). +- **YouTube / yt-dlp**: robust media downloader for YouTube and many hosts. +- **OpenLibrary / Archive.org**: scripted metadata scraping and optional downloads. +- **Soulseek, LibGen, All-Debrid, Others**: provider support is modular—add or configure providers in `config.conf`. -2. @1 +## Troubleshooting & tips 🛠️ +- If a cmdlet complains about an unknown store, ensure the piped item has a valid local `path` or use `-store ` to target a configured backend. +- For Playwright screenshots, run `playwright install` after installing the package to download browser binaries. +- Use `--debug` to enable verbose logs when tracking down an error. -3. download-media [URL] | add-file -storage local | add-url \ No newline at end of file +## Contributing & docs ✨ +- Developer docs are generated under `docs/` and tests live alongside the code; please run the test suite before submitting changes. +- Contributions welcome—open issues or pull requests with clear descriptions and small, focused diffs. + +--- + +If you'd like, I can add a short _Quick Reference_ section listing the most-used cmdlets and flags, or add badges and a table of contents. What would you like me to add next? 🚀 \ No newline at end of file diff --git a/scripts/install_playwright.py b/scripts/install_playwright.py new file mode 100644 index 0000000..60ef0a6 --- /dev/null +++ b/scripts/install_playwright.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python3 +"""Install Playwright browser binaries after dependencies are installed. + +This script will attempt to install the 'playwright' package if it's missing, +then run the Playwright browser installer. +""" + +import sys +import subprocess + + +def run(cmd: list[str]) -> None: + print("Running:", " ".join(cmd)) + subprocess.check_call(cmd) + + +def main() -> None: + # Ensure 'playwright' package is present; if not, install it. + try: + import playwright # type: ignore + except Exception: + print("'playwright' package not found; installing via pip...") + run([sys.executable, "-m", "pip", "install", "playwright"]) + + print("Installing Playwright browsers (this may download several hundred MB)...") + run([sys.executable, "-m", "playwright", "install"]) + + print("Playwright browsers installed successfully.") + + +if __name__ == "__main__": + main() diff --git a/scripts/setup.ps1 b/scripts/setup.ps1 new file mode 100644 index 0000000..2d4794c --- /dev/null +++ b/scripts/setup.ps1 @@ -0,0 +1,18 @@ +# scripts/setup.ps1 - DEPRECATED wrapper that calls the Python setup script +$ErrorActionPreference = 'Stop' + +# Determine repository root (one level up from script directory) +$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path +$repoRoot = Resolve-Path (Join-Path $scriptDir '..') + +Push-Location $repoRoot + +try { + Write-Host "Calling Python setup script (scripts/setup.py)..." + python ./scripts/setup.py @args +} catch { + Write-Error "Failed to run python ./scripts/setup.py: $_" + exit 1 +} finally { + Pop-Location +} diff --git a/scripts/setup.py b/scripts/setup.py new file mode 100644 index 0000000..f61227a --- /dev/null +++ b/scripts/setup.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python3 +"""scripts/setup.py + +Unified project setup helper (Python-only). + +This script installs Python dependencies from `requirements.txt` and then +downloads Playwright browser binaries by running `python -m playwright install`. + +Usage: + python ./scripts/setup.py # install deps and playwright browsers + python ./scripts/setup.py --skip-deps + python ./scripts/setup.py --playwright-only + +Optional flags: + --skip-deps Skip `pip install -r requirements.txt` step + --no-playwright Skip running `python -m playwright install` (still installs deps) + --playwright-only Install only Playwright browsers (installs playwright package if missing) + --upgrade-pip Upgrade pip, setuptools, and wheel before installing deps +""" + +from __future__ import annotations + +import argparse +import subprocess +import sys +from pathlib import Path + + +def run(cmd: list[str]) -> None: + print(f"> {' '.join(cmd)}") + subprocess.check_call(cmd) + + +def playwright_package_installed() -> bool: + try: + import playwright # type: ignore + + return True + except Exception: + return False + + +def main() -> int: + parser = argparse.ArgumentParser(description="Setup Medios-Macina: install deps and Playwright browsers") + parser.add_argument("--skip-deps", action="store_true", help="Skip installing Python dependencies from requirements.txt") + parser.add_argument("--no-playwright", action="store_true", help="Skip running 'playwright install' (only install packages)") + parser.add_argument("--playwright-only", action="store_true", help="Only run 'playwright install' (skips dependency installation)") + parser.add_argument("--upgrade-pip", action="store_true", help="Upgrade pip/setuptools/wheel before installing requirements") + args = parser.parse_args() + + repo_root = Path(__file__).resolve().parent.parent + + if sys.version_info < (3, 8): + print("Warning: Python 3.8+ is recommended.", file=sys.stderr) + + try: + if args.playwright_only: + if not playwright_package_installed(): + print("'playwright' package not found; installing it via pip...") + run([sys.executable, "-m", "pip", "install", "playwright"]) + + print("Installing Playwright browsers (this may download several hundred MB)...") + run([sys.executable, "-m", "playwright", "install"]) + print("Playwright browsers installed successfully.") + return 0 + + if args.upgrade_pip: + print("Upgrading pip, setuptools, and wheel...") + run([sys.executable, "-m", "pip", "install", "--upgrade", "pip", "setuptools", "wheel"]) + + if not args.skip_deps: + req_file = repo_root / "requirements.txt" + if not req_file.exists(): + print(f"requirements.txt not found at {req_file}; skipping dependency installation.", file=sys.stderr) + else: + print(f"Installing Python dependencies from {req_file}...") + run([sys.executable, "-m", "pip", "install", "-r", str(req_file)]) + + if not args.no_playwright: + if not playwright_package_installed(): + print("'playwright' package not installed; installing it...") + run([sys.executable, "-m", "pip", "install", "playwright"]) + + print("Installing Playwright browsers (this may download several hundred MB)...") + run([sys.executable, "-m", "playwright", "install"]) + + print("Setup complete.") + return 0 + + except subprocess.CalledProcessError as exc: + print(f"Error: command failed with exit {exc.returncode}: {exc}", file=sys.stderr) + return int(exc.returncode or 1) + except Exception as exc: # pragma: no cover - defensive + print(f"Unexpected error: {exc}", file=sys.stderr) + return 2 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/setup.sh b/scripts/setup.sh new file mode 100644 index 0000000..0fa7340 --- /dev/null +++ b/scripts/setup.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +cd "$SCRIPT_DIR" + +echo "Calling Python setup script (scripts/setup.py)..." +python ./scripts/setup.py "$@"