v3.0.0: Docker-Migration mit CI-Pipeline und neuen Features
Build Release Docker Image / build-arm64 (release) Successful in 1m0s
Build Release Docker Image / build-amd64 (release) Successful in 2m50s
Build Release Docker Image / publish-release-manifest (release) Successful in 7s

- Gitea CI-Workflows fuer Multi-Arch Docker Builds (amd64 + arm64)
- Beschreibungsfeld und mehrtaegige Zeitplanung fuer Jobs
- Benachrichtigungen auf Deutsch
- docker-compose nutzt Registry-Image

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Patrick Asmus
2026-09-16 09:40:40 +02:00
co-authored by Claude Opus 4.6
parent 9fa589789e
commit b446ce9b3e
9 changed files with 298 additions and 28 deletions
+24 -1
View File
@@ -97,6 +97,8 @@ class JobCreate(BaseModel):
schedule_days: str = "*"
schedule_start: str = ""
schedule_stop: str = ""
schedule_end_date: str = ""
description: str = ""
ntfy_enabled: bool = False
plik_enabled: bool = False
delete_after_upload: bool = False
@@ -136,6 +138,8 @@ async def list_jobs():
"schedule_days": j.schedule_days,
"schedule_start": j.schedule_start,
"schedule_stop": j.schedule_stop,
"schedule_end_date": j.schedule_end_date,
"description": j.description,
"ntfy_enabled": j.ntfy_enabled,
"plik_enabled": j.plik_enabled,
"delete_after_upload": j.delete_after_upload,
@@ -178,6 +182,7 @@ async def get_job(job_id: int):
"schedule_enabled": job.schedule_enabled, "schedule_once": job.schedule_once,
"schedule_date": job.schedule_date, "schedule_days": job.schedule_days,
"schedule_start": job.schedule_start, "schedule_stop": job.schedule_stop,
"schedule_end_date": job.schedule_end_date, "description": job.description,
"ntfy_enabled": job.ntfy_enabled,
"plik_enabled": job.plik_enabled, "delete_after_upload": job.delete_after_upload,
"metadata_monitor_enabled": job.metadata_monitor_enabled,
@@ -226,11 +231,29 @@ async def start_job_recording(job_id: int):
job = session.query(Job).filter_by(id=job_id).first()
if not job:
raise HTTPException(404, "Job nicht gefunden")
duration = job.max_duration
if not duration and job.schedule_start and job.schedule_stop:
if job.schedule_end_date and job.schedule_date:
start_dt = datetime.datetime.strptime(f"{job.schedule_date} {job.schedule_start}", "%Y-%m-%d %H:%M")
end_dt = datetime.datetime.strptime(f"{job.schedule_end_date} {job.schedule_stop}", "%Y-%m-%d %H:%M")
duration = max(0, int((end_dt - start_dt).total_seconds()))
else:
def _time_to_minutes(t: str) -> int:
parts = t.split(":")
return int(parts[0]) * 60 + int(parts[1])
start_min = _time_to_minutes(job.schedule_start)
stop_min = _time_to_minutes(job.schedule_stop)
if stop_min > start_min:
duration = (stop_min - start_min) * 60
else:
duration = (1440 - start_min + stop_min) * 60
job_data = {
"name": job.name, "stream_url": job.stream_url,
"stream_type": job.stream_type, "output_format": job.output_format,
"max_duration": job.max_duration, "extra_ffmpeg_args": job.extra_ffmpeg_args,
"max_duration": duration, "extra_ffmpeg_args": job.extra_ffmpeg_args,
"segment_duration": job.segment_duration,
"description": job.description,
"metadata_monitor_enabled": job.metadata_monitor_enabled,
"metadata_pattern": job.metadata_pattern,
"metadata_grace_period": job.metadata_grace_period or 300,