#!/usr/bin/env python3 """ Generate repo assets (README, promo text, tracklist) using Ollama. Input: - teaser_report.json from dj_teaser_v3.py Output: - README.md - PROMO.txt - TRACKLIST.md Requirements: pip install requests """ import argparse import json from pathlib import Path from typing import Dict, Any, List import requests def ollama_generate(base_url: str, model: str, prompt: str) -> str: url = base_url.rstrip("/") + "/api/generate" payload = {"model": model, "prompt": prompt, "stream": False} r = requests.post(url, json=payload, timeout=120) r.raise_for_status() return r.json().get("response", "").strip() def format_timestamps(tracks: List[Dict[str, Any]], crossfade_seconds: float) -> List[Dict[str, Any]]: """ Approximate teaser timestamps by accumulating clip durations minus crossfades. timestamp[i] = sum(durs[0..i-1]) - i*crossfade """ out = [] t = 0.0 for i, tr in enumerate(tracks): out.append({ **tr, "teaser_timestamp_seconds": round(t, 2) }) dur = float(tr.get("clip_duration_seconds", 0.0)) t += max(0.0, dur - crossfade_seconds) return out def seconds_to_mmss(sec: float) -> str: sec = max(0.0, float(sec)) m = int(sec // 60) s = int(round(sec - (m * 60))) return f"{m:02d}:{s:02d}" def main(): ap = argparse.ArgumentParser(description="Generate README/promo/tracklist via Ollama") ap.add_argument("--report", default="./out/teaser_report.json", help="Path to teaser_report.json") ap.add_argument("--out-dir", default="./out", help="Output directory for generated assets") ap.add_argument("--ollama", default="http://192.168.2.60:11434", help="Ollama base URL") ap.add_argument("--model", default="llama3.1:8b-instruct-q4_0", help="Ollama model name") ap.add_argument("--project-name", default="DJ Teaser Builder", help="Project/repo name") ap.add_argument("--artist", default="DjGulvBasS", help="Artist/DJ name") ap.add_argument("--genre", default="old school trance", help="Genre") args = ap.parse_args() report_path = Path(args.report) out_dir = Path(args.out_dir) out_dir.mkdir(parents=True, exist_ok=True) data = json.loads(report_path.read_text(encoding="utf-8")) tracks = data.get("tracks", []) settings = data.get("settings", {}) crossfade = float(settings.get("crossfade_seconds", 0.25)) tracks_ts = format_timestamps(tracks, crossfade_seconds=crossfade) # Build TRACKLIST.md ourselves (deterministic) lines = [f"# Tracklist (approx.) — {args.artist}\n"] for tr in tracks_ts: ts = seconds_to_mmss(tr["teaser_timestamp_seconds"]) fname = tr.get("filename", "Unknown") bpm = tr.get("tempo_bpm_est", "?") camelot = tr.get("camelot", "??") key = tr.get("key", "") lines.append(f"- **{ts}** — {fname} _(BPM ~ {bpm}, {camelot}, {key})_") (out_dir / "TRACKLIST.md").write_text("\n".join(lines) + "\n", encoding="utf-8") # README prompt readme_prompt = f""" You are writing a GitHub README in English for a small local audio tool. Project: {args.project_name} Artist use-case: {args.artist} — {args.genre} The tool scans a folder of tracks and builds a DJ-style teaser by: - detecting highlight segments - snapping cuts to bar grid (DJ phrasing) - optional harmonic ordering using Camelot keys - rendering clips and acrossfading them with FFmpeg - exporting WAV + MP3 It produces a JSON report and a tracklist with timestamps. Please write a README with these sections: 1) What it does 2) Requirements (ffmpeg + Python) 3) Install (venv) 4) Usage examples (include: select all, select by indices, auto best-of) 5) Trance/DJ tips (avoid-intro, bars, preroll-bars, harmonic) 6) Troubleshooting (ffmpeg not found, weird beat detection, key detection limitations) Keep it concise and practical. These settings were used in an example run: {json.dumps(settings, indent=2)} Do NOT invent features beyond what is described. """ readme_text = ollama_generate(args.ollama, args.model, readme_prompt) (out_dir / "README.md").write_text(readme_text + "\n", encoding="utf-8") # Promo prompt promo_prompt = f""" Write 3 short promo text variants (English) for a DJ album teaser for {args.artist} ({args.genre}). Constraints: - Each variant should be 2–4 lines max - Include 4–8 hashtags (trance/electronic) - Tone: energetic, DJ/club vibe - Do not mention "AI" or "tool" or "script" - Do not include any URLs """ promo_text = ollama_generate(args.ollama, args.model, promo_prompt) (out_dir / "PROMO.txt").write_text(promo_text + "\n", encoding="utf-8") print(f"✅ Generated: {out_dir / 'README.md'}") print(f"✅ Generated: {out_dir / 'TRACKLIST.md'}") print(f"✅ Generated: {out_dir / 'PROMO.txt'}") if __name__ == "__main__": main()