Files
python_scripts/package/utils.py
T
2026-09-21 18:51:13 +00:00

106 lines
3.8 KiB
Python
Executable File

#!/usr/bin/env python3
import csv
from pathlib import Path
import sys
import json
import shlex
import subprocess
def get_chapters(json_path):
"""Loads the JSON file and returns all chapters."""
with open(json_path, 'r', encoding='utf-8') as f:
data = json.load(f)
# The chapters are under video -> chapters
video = data.get('video', {})
chapters = video.get('chapters', [])
if not chapters:
print("No chapters found.")
return []
print(f"Found {len(chapters)} chapter(s) in video '{video.get('title')}':\n")
for i, chapter in enumerate(chapters, 1):
start_sec = chapter.get('startMilliseconds', 0) / 1000
length_sec = chapter.get('lengthMilliseconds', 0) / 1000
#print(f"{i}. {chapter.get('description', 'No Title')}")
#print(f" - Type: {chapter.get('type')}")
#print(f" - Start: {start_sec}s ({chapter.get('startMilliseconds')}ms)")
#print(f" - Length: {length_sec}s ({chapter.get('lengthMilliseconds')}ms)")
#print(f" - Game: {chapter.get('gameDisplayName')} (ID: {chapter.get('gameId')})")
#print()
return chapters
def get_video_id_from_chat(json_path: str | Path) -> str | None:
"""Gets the id inside video:{ } - from the chat json you download"""
try:
with open(json_path, 'r', encoding='utf-8') as f:
data = json.load(f)
return data.get("video", {}).get("id")
except Exception as e:
print(f"Could not read video.id from {json_path}: {e}")
return None
def write_csv(data: list, file_name: str):
# Open file with newline='' to prevent extra blank rows across platforms
with open(file_name, "w", newline="", encoding="utf-8") as file:
writer = csv.writer(file)
# Write all rows at once
writer.writerows(data)
def run_command(cmd_str: str, progress_prefix: str = "Progress", look_for: list = ["frame=", "time=", "fps=", "Rendering frame"]) -> bool:
"""Runs a system command, streams its output live, and reports errors on failure."""
args = shlex.split(cmd_str)
# Redirect stderr to stdout to catch all logging/progress in one stream
process = subprocess.Popen(
args,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True,
bufsize=1
)
print(f"Executing: {cmd_str[:90]}...")
# Maintain a small buffer history to display context if a crash occurs
output_history = []
# Stream the output live to the terminal
while True:
line = process.stdout.readline()
if not line and process.poll() is not None:
break
if line:
clean_line = line.strip()
output_history.append(clean_line) # Keep history for error reporting
# Keep history slim by only keeping the last 20 lines
if len(output_history) > 20:
output_history.pop(0)
# Only print updates that show progress metrics to keep terminal clean
if any(metric in clean_line for metric in look_for):
sys.stdout.write(f"\r[{progress_prefix}] {clean_line}")
sys.stdout.flush()
elif "Error" in clean_line or "failed" in clean_line:
print(f"\n[Alert] {clean_line}")
print("\n") # New line after process finishes
# Evaluate success status
success = (process.returncode == 0)
if not success:
print(f"❌ Command failed with exit code: {process.returncode}")
print("--- Technical Error Details (Last 5 lines of output) ---")
# Print the last 5 captured lines to show the exact point of failure
for error_line in output_history[-5:]:
print(f" > {error_line}")
print("---------------------------------------------------------")
return success