This commit is contained in:
2025-12-31 22:58:54 -08:00
parent 977381b636
commit 7002075947
9 changed files with 344 additions and 17 deletions

42
.gitattributes vendored Normal file
View File

@@ -0,0 +1,42 @@
# Auto detect text files and normalize line endings to LF
* text=auto
# Python files
*.py text eol=lf
*.pyx text eol=lf
*.pyi text eol=lf
# Shell scripts
*.sh text eol=lf
*.bash text eol=lf
# Windows batch files
*.bat text eol=crlf
*.cmd text eol=crlf
*.ps1 text eol=crlf
# Config files
*.json text eol=lf
*.toml text eol=lf
*.yaml text eol=lf
*.yml text eol=lf
*.ini text eol=lf
*.cfg text eol=lf
# Documentation
*.md text eol=lf
README text eol=lf
LICENSE text eol=lf
# Binary files
*.db binary
*.sqlite binary
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.webp binary
*.mov binary
*.mp4 binary
*.webm binary
*.pdf binary

32
.github/workflows/smoke-mm.yml vendored Normal file
View File

@@ -0,0 +1,32 @@
name: smoke-mm
on:
pull_request:
push:
branches:
- main
jobs:
smoke:
name: Install & smoke test mm --help
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Create venv and install
run: |
python -m venv venv
. venv/bin/activate
python -m pip install -U pip
python -m pip install -e ./scripts
- name: Run smoke test (mm --help)
run: |
. venv/bin/activate
mm --help

240
.gitignore vendored Normal file
View File

@@ -0,0 +1,240 @@
# ---> Python
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
config.conf
config.d/
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
test_*
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
cookies.txt
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
backup/
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
config.conf
config.d/
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# UV
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
#uv.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
.pdm.toml
.pdm-python
.pdm-build/
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
# Ruff stuff:
.ruff_cache/
# PyPI configuration file
.pypirc
# ---> Lua
# Compiled Lua sources
luac.out
# luarocks build files
*.src.rock
*.zip
*.tar.gz
# Object files
*.o
*.os
*.ko
*.obj
*.elf
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
*.def
*.exp
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
config.conf
config.d/
MPV/ffmpeg/*
Log/
Log/medeia_macina/telegram.session
*.session
example.py
test*
MPV/portable_config/watch_later*
hydrusnetwork
.style.yapf
.yapfignore
tests/
scripts/mm.ps1
scripts/mm
.style.yapf
.yapfignore

12
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,12 @@
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "ms-python.python",
"python.formatting.provider": "yapf",
"python.formatting.yapfArgs": ["--style", ".style.yapf"],
"[python]": {
"editor.defaultFormatter": "ms-python.python",
"editor.formatOnSave": true
}
}

View File

@@ -167,7 +167,7 @@ def _run_cli(clean_args: List[str]) -> int:
MedeiaCLI = _M MedeiaCLI = _M
except Exception: except Exception:
raise ImportError( raise ImportError(
"Could not import 'MedeiaCLI'. This often means the project is not available on sys.path (run 'pip install -e .' or re-run the bootstrap script)." "Could not import 'MedeiaCLI'. This often means the project is not available on sys.path (run 'pip install -e scripts' or re-run the bootstrap script)."
) )
try: try:

View File

@@ -121,6 +121,7 @@ try { $IsWindowsPlatform = [System.Runtime.InteropServices.RuntimeInformation]::
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path $scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$repoRoot = (Resolve-Path (Join-Path $scriptDir "..")).Path $repoRoot = (Resolve-Path (Join-Path $scriptDir "..")).Path
Set-Location $repoRoot Set-Location $repoRoot
$scriptsDir = Join-Path $repoRoot 'scripts'
$pythonExe = Find-Python -preferred $Python $pythonExe = Find-Python -preferred $Python
if (-not $pythonExe) { Write-Log "No Python interpreter found. Specify -Python <path> or install Python." "ERROR"; exit 2 } if (-not $pythonExe) { Write-Log "No Python interpreter found. Specify -Python <path> or install Python." "ERROR"; exit 2 }
@@ -217,7 +218,7 @@ if (-not $NoInstall) {
if ($Editable) { $editable_label = "(editable)" } else { $editable_label = "" } if ($Editable) { $editable_label = "(editable)" } else { $editable_label = "" }
Write-Log ("Installing project {0}" -f $editable_label) Write-Log ("Installing project {0}" -f $editable_label)
try { try {
if ($Editable) { & $venvPython -m pip install -e . } else { & $venvPython -m pip install . } if ($Editable) { & $venvPython -m pip install -e $scriptsDir } else { & $venvPython -m pip install $scriptsDir }
} catch { } catch {
Write-Log "pip install failed: $_" "ERROR"; exit 6 Write-Log "pip install failed: $_" "ERROR"; exit 6
} }

View File

@@ -34,7 +34,7 @@ Optional flags:
--no-playwright Skip running `python -m playwright install` (still installs deps) --no-playwright Skip running `python -m playwright install` (still installs deps)
--playwright-only Install only Playwright browsers (installs playwright package if missing) --playwright-only Install only Playwright browsers (installs playwright package if missing)
--browsers Comma-separated list of Playwright browsers to install (default: chromium) --browsers Comma-separated list of Playwright browsers to install (default: chromium)
--install-editable Install the project in editable mode (pip install -e .) for running tests --install-editable Install the project in editable mode (pip install -e scripts) for running tests
--install-deno Install the Deno runtime using the official installer --install-deno Install the Deno runtime using the official installer
--no-deno Skip installing the Deno runtime --no-deno Skip installing the Deno runtime
--deno-version Pin a specific Deno version to install (e.g., v1.34.3) --deno-version Pin a specific Deno version to install (e.g., v1.34.3)
@@ -256,7 +256,7 @@ def main() -> int:
parser.add_argument( parser.add_argument(
"--install-editable", "--install-editable",
action="store_true", action="store_true",
help="Install the project in editable mode (pip install -e .) for running tests", help="Install the project in editable mode (pip install -e scripts) for running tests",
) )
deno_group = parser.add_mutually_exclusive_group() deno_group = parser.add_mutually_exclusive_group()
deno_group.add_argument( deno_group.add_argument(
@@ -690,7 +690,7 @@ def main() -> int:
# Install the project into the local venv (editable mode is the default, opinionated) # Install the project into the local venv (editable mode is the default, opinionated)
if not args.quiet: if not args.quiet:
print("Installing project into local venv (editable mode)") print("Installing project into local venv (editable mode)")
run([str(venv_python), "-m", "pip", "install", "-e", "."]) run([str(venv_python), "-m", "pip", "install", "-e", str(repo_root / "scripts")])
# Verify top-level 'CLI' import and, if missing, attempt to make it available # Verify top-level 'CLI' import and, if missing, attempt to make it available
if not args.quiet: if not args.quiet:
@@ -890,10 +890,10 @@ python -m medeia_macina.cli_entry @args
" fi\n" " fi\n"
"fi\n" "fi\n"
"# If git not available or didn't resolve, walk up from CWD to find a project root.\n" "# If git not available or didn't resolve, walk up from CWD to find a project root.\n"
'if [ ! -f "$REPO/CLI.py" ] && [ ! -f "$REPO/pyproject.toml" ]; then\n' 'if [ ! -f "$REPO/CLI.py" ] && [ ! -f "$REPO/pyproject.toml" ] && [ ! -f "$REPO/scripts/pyproject.toml" ]; then\n'
' CUR="$(pwd -P)"\n' ' CUR="$(pwd -P)"\n'
' while [ "$CUR" != "/" ] && [ "$CUR" != "" ]; do\n' ' while [ "$CUR" != "/" ] && [ "$CUR" != "" ]; do\n'
' if [ -f "$CUR/CLI.py" ] || [ -f "$CUR/pyproject.toml" ]; then\n' ' if [ -f "$CUR/CLI.py" ] || [ -f "$CUR/pyproject.toml" ] || [ -f "$CUR/scripts/pyproject.toml" ]; then\n'
' REPO="$CUR"\n' ' REPO="$CUR"\n'
" break\n" " break\n"
" fi\n" " fi\n"

View File

@@ -236,7 +236,7 @@ if [[ "$EUID" -eq 0 ]]; then
fi fi
# Basic sanity check: ensure the detected repo root actually looks like the project # Basic sanity check: ensure the detected repo root actually looks like the project
if [[ ! -f "$REPO/pyproject.toml" && ! -f "$REPO/setup.py" && ! -f "$REPO/CLI.py" ]]; then if [[ ! -f "$REPO/pyproject.toml" && ! -f "$REPO/scripts/pyproject.toml" && ! -f "$REPO/setup.py" && ! -f "$REPO/CLI.py" ]]; then
echo "WARNING: Detected repo root ($REPO) does not contain pyproject.toml, setup.py, or CLI.py; attempting to locate project root via git or current working directory..." >&2 echo "WARNING: Detected repo root ($REPO) does not contain pyproject.toml, setup.py, or CLI.py; attempting to locate project root via git or current working directory..." >&2
if git -C "$SCRIPT_DIR/.." rev-parse --show-toplevel >/dev/null 2>&1; then if git -C "$SCRIPT_DIR/.." rev-parse --show-toplevel >/dev/null 2>&1; then
REPO="$(git -C "$SCRIPT_DIR/.." rev-parse --show-toplevel)" REPO="$(git -C "$SCRIPT_DIR/.." rev-parse --show-toplevel)"
@@ -323,10 +323,10 @@ if [[ "$NOINSTALL" != "true" ]]; then # If not explicitly requested, auto-selec
if [[ "$EDITABLE" == "true" ]]; then if [[ "$EDITABLE" == "true" ]]; then
echo "Installing project in editable mode..." echo "Installing project in editable mode..."
"$VENV_PY" -m pip install -e "$REPO" "$VENV_PY" -m pip install -e "$REPO/scripts"
else else
echo "Installing project..." echo "Installing project..."
"$VENV_PY" -m pip install "$REPO" "$VENV_PY" -m pip install "$REPO/scripts"
fi fi
# Verify the installed CLI module can be imported. This helps catch packaging # Verify the installed CLI module can be imported. This helps catch packaging
@@ -386,7 +386,7 @@ PY
else else
echo "WARNING: Could not import 'medeia_macina.cli_entry' from the venv." >&2 echo "WARNING: Could not import 'medeia_macina.cli_entry' from the venv." >&2
echo "Action: Try running: $VENV_PY -m pip install -e . or inspect the venv site-packages to verify the installation." >&2 echo "Action: Try running: $VENV_PY -m pip install -e \"$REPO/scripts\" or inspect the venv site-packages to verify the installation." >&2
fi fi
echo "Verifying environment for known issues (urllib3 compatibility)..." echo "Verifying environment for known issues (urllib3 compatibility)..."
@@ -578,7 +578,7 @@ set -e
# but prefer to discover a repo from the current working directory or git. # but prefer to discover a repo from the current working directory or git.
REPO="__REPO__" REPO="__REPO__"
# If the placeholder does not appear to point at a repo, attempt discovery. # If the placeholder does not appear to point at a repo, attempt discovery.
if [ ! -f "$REPO/CLI.py" ] && [ ! -f "$REPO/pyproject.toml" ]; then if [ ! -f "$REPO/CLI.py" ] && [ ! -f "$REPO/pyproject.toml" ] && [ ! -f "$REPO/scripts/pyproject.toml" ]; then
# First try to find a git toplevel from the current working directory. # First try to find a git toplevel from the current working directory.
if command -v git >/dev/null 2>&1; then if command -v git >/dev/null 2>&1; then
gitroot=$(git -C "$(pwd -P)" rev-parse --show-toplevel 2>/dev/null || true) gitroot=$(git -C "$(pwd -P)" rev-parse --show-toplevel 2>/dev/null || true)
@@ -588,10 +588,10 @@ if [ ! -f "$REPO/CLI.py" ] && [ ! -f "$REPO/pyproject.toml" ]; then
fi fi
fi fi
# If still unresolved, walk up from the CWD looking for signs of the project. # If still unresolved, walk up from the CWD looking for signs of the project.
if [ ! -f "$REPO/CLI.py" ] && [ ! -f "$REPO/pyproject.toml" ]; then if [ ! -f "$REPO/CLI.py" ] && [ ! -f "$REPO/pyproject.toml" ] && [ ! -f "$REPO/scripts/pyproject.toml" ]; then
CUR="$(pwd -P)" CUR="$(pwd -P)"
while [ "$CUR" != "/" ] && [ "$CUR" != "" ]; do while [ "$CUR" != "/" ] && [ "$CUR" != "" ]; do
if [ -f "$CUR/CLI.py" ] || [ -f "$CUR/pyproject.toml" ]; then if [ -f "$CUR/CLI.py" ] || [ -f "$CUR/pyproject.toml" ] || [ -f "$CUR/scripts/pyproject.toml" ]; then
REPO="$CUR" REPO="$CUR"
break break
fi fi

View File

@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
name = "medeia-macina" name = "medeia-macina"
version = "0.1.0" version = "0.1.0"
description = "Comprehensive media management and search platform with support for local files, Hydrus database, torrents, books, and P2P networks" description = "Comprehensive media management and search platform with support for local files, Hydrus database, torrents, books, and P2P networks"
readme = "README.md" readme = "../readme.md"
requires-python = ">=3.9,<3.14" requires-python = ">=3.9,<3.14"
license = {text = "MIT"} license = {text = "MIT"}
authors = [ authors = [
@@ -116,13 +116,13 @@ Issues = "https://github.com/yourusername/medeia-macina/issues"
[tool.setuptools] [tool.setuptools]
[tool.setuptools.packages.find] [tool.setuptools.packages.find]
where = ["."] where = [".."]
exclude = ["tests*", "docs*"] exclude = ["tests*", "docs*"]
[tool.black] [tool.black]
line-length = 100 line-length = 100
target-version = ['py39', 'py310', 'py311', 'py312'] target-version = ['py39', 'py310', 'py311', 'py312']
include = '\.pyi?$' include = '\\.pyi?$'
extend-exclude = ''' extend-exclude = '''
/( /(
# directories # directories