Files
maple/maple-py/src/sockseek.py
T
2026-06-21 10:50:46 +10:00

74 lines
2.1 KiB
Python

#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.14"
# dependencies = []
# ///
"""Thin binding around the `sockseek` CLI.
Creates the data directories and invokes sockseek with the CLI-argument
equivalents of etc/sldl.tpl.conf, so the two stay in sync without rendering a
config file. Reads SOCKSEEK_DATA / SOCKSEEK_USER / SOCKSEEK_PASS from the
environment (loaded from .env by just).
just sockseek <input> # csv path, url, search string, ...
just sockseek "tracks.csv -a" # extra flags pass through / override
Any args after the input are forwarded to sockseek verbatim, placed after the
defaults so they win on conflict.
"""
import os
import subprocess
import sys
from pathlib import Path
# Mirror of etc/sldl.tpl.conf. Keep these in sync with that file.
NAME_FORMAT = "{artist(/)album(/)track( )title|(_missing_tags/)slsk-foldername(/)slsk-filename}"
def env(key):
val = os.environ.get(key)
if not val:
sys.exit(f"missing env var: {key}")
return val
def config_args(data, user, password):
"""CLI equivalents of etc/sldl.tpl.conf (no-progress has no sockseek flag)."""
return [
"--path", data,
"--index-path", f"{data}/_metadata/index.sldl.csv",
"--user", user,
"--pass", password,
"--name-format", NAME_FORMAT,
"--pref-format", "flac,mp3",
"--pref-min-bitrate", "200",
"--pref-max-bitrate", "2500",
"--strict-conditions",
"--fast-search",
"--concurrent-jobs", "4",
]
def main():
if not sys.argv[1:]:
sys.exit("usage: sockseek.py <input> [extra sockseek args...]")
inp, *extra = sys.argv[1:]
data = env("SOCKSEEK_DATA")
user = env("SOCKSEEK_USER")
password = env("SOCKSEEK_PASS")
Path(data, "_metadata").mkdir(parents=True, exist_ok=True)
args = config_args(data, user, password)
cmd = ["sockseek", inp, *args, *extra]
masked = ["***" if a == password else a for a in cmd]
print(" ".join(masked), file=sys.stderr)
raise SystemExit(subprocess.run(cmd).returncode)
if __name__ == "__main__":
main()