feat: Auto-Aufnahme fuer Top-Filme (Score>=95), Vorschlaege mit Buttons fuer den Rest
This commit is contained in:
parent
0dcb0fd35a
commit
847b120172
2 changed files with 68 additions and 18 deletions
|
|
@ -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")
|
||||
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue