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):
|
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.
|
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
|
bot = getattr(context, "bot", None) or context
|
||||||
try:
|
try:
|
||||||
from tools import savetv
|
from tools import savetv
|
||||||
telecasts = savetv._scrape_epg()
|
auto_recorded, suggestions = savetv.get_new_films()
|
||||||
if not telecasts:
|
|
||||||
return
|
if not auto_recorded and not suggestions:
|
||||||
films = savetv._filter_films(telecasts)
|
log.info("Filmtipp-Scan: keine neuen Filme")
|
||||||
if not films:
|
|
||||||
return
|
return
|
||||||
|
|
||||||
header = f"🎬 TV-Filmtipps für heute ({datetime.now().strftime('%d.%m.%Y')})\n"
|
if auto_recorded:
|
||||||
await bot.send_message(chat_id=CHAT_ID, text=header)
|
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))
|
tid = int(f.get("ITELECASTID", 0))
|
||||||
title = f.get("STITLE", "?")
|
title = f.get("STITLE", "?")
|
||||||
station = f.get("STVSTATIONNAME", "?")
|
station = f.get("STVSTATIONNAME", "?")
|
||||||
start = f.get("DSTARTDATE", "?")[:16]
|
start = f.get("DSTARTDATE", "?")[:16]
|
||||||
subcat = f.get("SSUBCATEGORYNAME", "")
|
subcat = f.get("SSUBCATEGORYNAME", "")
|
||||||
desc = (f.get("STHEMA") or f.get("SFULLSUBTITLE") or "")[:150]
|
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:
|
if desc:
|
||||||
text += f"\n_{desc}_"
|
desc_escaped = desc.replace("_", "\\_").replace("*", "\\*")
|
||||||
|
text += f"\n_{desc_escaped}_"
|
||||||
|
|
||||||
keyboard = InlineKeyboardMarkup([
|
keyboard = InlineKeyboardMarkup([
|
||||||
[
|
[
|
||||||
|
|
@ -804,7 +826,7 @@ async def _send_daily_filmtipps(context):
|
||||||
parse_mode="Markdown",
|
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:
|
except Exception:
|
||||||
log.exception("Fehler beim Senden der Filmtipps")
|
log.exception("Fehler beim Senden der Filmtipps")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,9 @@ EPG_PAGES = [
|
||||||
SEEN_CACHE = Path("/tmp/savetv_seen_ids.json")
|
SEEN_CACHE = Path("/tmp/savetv_seen_ids.json")
|
||||||
SEEN_MAX_AGE_DAYS = 30
|
SEEN_MAX_AGE_DAYS = 30
|
||||||
|
|
||||||
|
AUTO_RECORD_SCORE = 95
|
||||||
|
SUGGEST_SCORE = 60
|
||||||
|
|
||||||
SPAM_SUBCATEGORIES = {
|
SPAM_SUBCATEGORIES = {
|
||||||
"teleshop", "shopping", "dauerwerbesendung", "volksmusik",
|
"teleshop", "shopping", "dauerwerbesendung", "volksmusik",
|
||||||
"casting", "reality", "quiz/spiel", "comic", "zeichentrick",
|
"casting", "reality", "quiz/spiel", "comic", "zeichentrick",
|
||||||
|
|
@ -404,16 +407,41 @@ def handle_get_savetv_tipps(**kw):
|
||||||
|
|
||||||
|
|
||||||
def get_new_films():
|
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()
|
telecasts = _scrape_epg()
|
||||||
if not telecasts:
|
if not telecasts:
|
||||||
return []
|
return [], []
|
||||||
|
|
||||||
films = _filter_films(telecasts, only_new=True)
|
films = _filter_films(telecasts, only_new=True)
|
||||||
good_films = [f for f in films if f["_score"] >= 60]
|
|
||||||
|
|
||||||
_mark_seen(films)
|
_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):
|
def handle_savetv_record(telecast_id=0, **kw):
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue