feat: Auto-Aufnahme fuer Top-Filme (Score>=95), Vorschlaege mit Buttons fuer den Rest

This commit is contained in:
root 2026-03-16 22:23:35 +07:00
parent 0dcb0fd35a
commit 847b120172
2 changed files with 68 additions and 18 deletions

View file

@ -759,7 +759,7 @@ async def handle_callback(update: Update, ctx: ContextTypes.DEFAULT_TYPE):
async def _send_daily_filmtipps(context):
"""Täglicher Cronjob: Filmtipps via Telegram senden.
"""Täglicher Cronjob: EPG scannen, Top-Filme auto-aufnehmen, Rest vorschlagen.
context kann ein CallbackContext (JobQueue) oder eine Application (asyncio-Loop) sein.
"""
@ -768,28 +768,50 @@ async def _send_daily_filmtipps(context):
bot = getattr(context, "bot", None) or context
try:
from tools import savetv
telecasts = savetv._scrape_epg()
if not telecasts:
return
films = savetv._filter_films(telecasts)
if not films:
auto_recorded, suggestions = savetv.get_new_films()
if not auto_recorded and not suggestions:
log.info("Filmtipp-Scan: keine neuen Filme")
return
header = f"🎬 TV-Filmtipps für heute ({datetime.now().strftime('%d.%m.%Y')})\n"
await bot.send_message(chat_id=CHAT_ID, text=header)
if auto_recorded:
lines = [f"✅ *{len(auto_recorded)} Filme automatisch aufgenommen:*\n"]
for f in auto_recorded:
title = f.get("STITLE", "?")
station = f.get("STVSTATIONNAME", "?")
start = f.get("DSTARTDATE", "?")[:16]
subcat = f.get("SSUBCATEGORYNAME", "")
try:
start_dt = datetime.strptime(f.get("DSTARTDATE", ""), "%Y-%m-%d %H:%M:%S")
delta = (start_dt.date() - datetime.now().date()).days
when = f" (in {delta}d)" if delta > 1 else " (morgen)" if delta == 1 else " (heute)"
except (ValueError, TypeError):
when = ""
lines.append(f"🎬 {title}{when}\n 📺 {station} | ⏰ {start} | 🎭 {subcat}")
await bot.send_message(chat_id=CHAT_ID, text="\n".join(lines), parse_mode="Markdown")
for f in films[:6]:
for f in suggestions[:6]:
tid = int(f.get("ITELECASTID", 0))
title = f.get("STITLE", "?")
station = f.get("STVSTATIONNAME", "?")
start = f.get("DSTARTDATE", "?")[:16]
subcat = f.get("SSUBCATEGORYNAME", "")
desc = (f.get("STHEMA") or f.get("SFULLSUBTITLE") or "")[:150]
recorded = " ✅ Bereits geplant" if f.get("BEXISTRECORD") else ""
text = f"🎬 *{title}*{recorded}\n📺 {station} | ⏰ {start}\n🎭 {subcat}"
try:
start_dt = datetime.strptime(f.get("DSTARTDATE", ""), "%Y-%m-%d %H:%M:%S")
delta = (start_dt.date() - datetime.now().date()).days
when = f"in {delta}d" if delta > 1 else "morgen" if delta == 1 else "heute"
except (ValueError, TypeError):
when = ""
text = f"🤔 *{title}*"
if when:
text += f" ({when})"
text += f"\n📺 {station} | ⏰ {start}\n🎭 {subcat}"
if desc:
text += f"\n_{desc}_"
desc_escaped = desc.replace("_", "\\_").replace("*", "\\*")
text += f"\n_{desc_escaped}_"
keyboard = InlineKeyboardMarkup([
[
@ -804,7 +826,7 @@ async def _send_daily_filmtipps(context):
parse_mode="Markdown",
)
log.info("Tägliche Filmtipps gesendet: %d Filme", min(len(films), 6))
log.info("Filmtipps: %d auto-aufgenommen, %d Vorschlaege", len(auto_recorded), len(suggestions))
except Exception:
log.exception("Fehler beim Senden der Filmtipps")

View file

@ -34,6 +34,9 @@ EPG_PAGES = [
SEEN_CACHE = Path("/tmp/savetv_seen_ids.json")
SEEN_MAX_AGE_DAYS = 30
AUTO_RECORD_SCORE = 95
SUGGEST_SCORE = 60
SPAM_SUBCATEGORIES = {
"teleshop", "shopping", "dauerwerbesendung", "volksmusik",
"casting", "reality", "quiz/spiel", "comic", "zeichentrick",
@ -404,16 +407,41 @@ def handle_get_savetv_tipps(**kw):
def get_new_films():
"""Fuer den Cronjob: Nur NEUE Filme seit dem letzten Scan."""
"""Fuer den Cronjob: Neue Filme scannen, Top-Filme automatisch aufnehmen.
Returns: (auto_recorded, suggestions)
auto_recorded: Filme die automatisch aufgenommen wurden (Score >= 85)
suggestions: Filme die dem User vorgeschlagen werden (Score 60-84)
"""
telecasts = _scrape_epg()
if not telecasts:
return []
return [], []
films = _filter_films(telecasts, only_new=True)
good_films = [f for f in films if f["_score"] >= 60]
_mark_seen(films)
return good_films
auto_recorded = []
suggestions = []
for f in films:
score = f["_score"]
if score < SUGGEST_SCORE:
continue
if f.get("BEXISTRECORD"):
continue
if score >= AUTO_RECORD_SCORE:
tid = int(f.get("ITELECASTID", 0))
result = _record_telecast(tid)
f["_record_result"] = result
auto_recorded.append(f)
log.info("Auto-Aufnahme: %s (Score %d) -> %s",
f.get("STITLE"), score, result)
else:
suggestions.append(f)
return auto_recorded, suggestions
def handle_savetv_record(telecast_id=0, **kw):