From bd925418fdf37a5497ea56d6ef0b1772008a6fc9 Mon Sep 17 00:00:00 2001 From: profitroll Date: Thu, 12 Jan 2023 13:57:41 +0100 Subject: [PATCH] YouTube new videos on channels monitoring --- config_example.json | 5 +++++ locale/uk.json | 1 + modules/database.py | 3 ++- modules/scheduled.py | 34 ++++++++++++++++++++++++++++++++-- requirements.txt | 3 ++- 5 files changed, 42 insertions(+), 4 deletions(-) diff --git a/config_example.json b/config_example.json index a562bc3..c25b48d 100644 --- a/config_example.json +++ b/config_example.json @@ -75,6 +75,11 @@ "cache_admins": { "interval": 120, "enabled": true + }, + "channels_monitor": { + "interval": 5, + "enabled": true, + "channels": [] } }, "locations": { diff --git a/locale/uk.json b/locale/uk.json index 5be5fc5..c84a258 100644 --- a/locale/uk.json +++ b/locale/uk.json @@ -120,6 +120,7 @@ "spoiler_incorrect_content": "Бот не підтримує такий контент. Будь ласка, надішли текст, фото, відео, файл або анімацію (гіф).", "spoiler_incorrect_category": "Вказана категорія не є дійсною. Будь ласка, користуйся клавіатурою бота (кнопка біля 📎) для вибору категорії.", "spoiler_in_progress": "❌ **Дія неможлива**\nПерш ніж починати нову дію, треба завершити створення спойлера або перервати його командою /cancel.", + "youtube_video": "На каналі [{0}]({1}) нове відео!\n\n**[{2}]({3})**", "yes": "Так", "no": "Ні", "voice_message": [ diff --git a/modules/database.py b/modules/database.py index f518dc1..a7f3c67 100644 --- a/modules/database.py +++ b/modules/database.py @@ -28,13 +28,14 @@ db = db_client.get_database(name=db_config["name"]) collections = db.list_collection_names() -for collection in ["tmp", "users", "context", "spoilers", "messages", "warnings", "applications", "sponsorships"]: +for collection in ["tmp", "users", "context", "youtube", "spoilers", "messages", "warnings", "applications", "sponsorships"]: if not collection in collections: db.create_collection(collection) col_tmp = db.get_collection("tmp") col_users = db.get_collection("users") col_context = db.get_collection("context") +col_youtube = db.get_collection("youtube") col_spoilers = db.get_collection("spoilers") col_messages = db.get_collection("messages") col_warnings = db.get_collection("warnings") diff --git a/modules/scheduled.py b/modules/scheduled.py index f30f312..b972e31 100644 --- a/modules/scheduled.py +++ b/modules/scheduled.py @@ -1,7 +1,9 @@ """Automatically register commands and execute some scheduled tasks is the main idea of this module""" +from asyncio import sleep from os import listdir, makedirs, path, sep +from traceback import format_exc from apscheduler.schedulers.asyncio import AsyncIOScheduler from datetime import datetime, timedelta from ujson import dumps @@ -12,7 +14,9 @@ from pyrogram.enums.chat_members_filter import ChatMembersFilter from classes.holo_user import HoloUser from modules.utils import configGet, jsonSave, locale, logWrite from dateutil.relativedelta import relativedelta -from modules.database import col_applications, col_sponsorships +from modules.database import col_applications, col_sponsorships, col_youtube +from xmltodict import parse +from requests import get scheduler = AsyncIOScheduler() @@ -233,4 +237,30 @@ async def commands_register(): if configGet("debug") is True: print(commands, flush=True) - logWrite(f"Complete commands registration:\n{dumps(commands_raw, indent=4, ensure_ascii=False, encode_html_chars=False)}", debug=True) \ No newline at end of file + logWrite(f"Complete commands registration:\n{dumps(commands_raw, indent=4, ensure_ascii=False, encode_html_chars=False)}", debug=True) + + +if configGet("enabled", "scheduler", "channels_monitor"): + @scheduler.scheduled_job(trigger="interval", minutes=configGet("interval", "scheduler", "channels_monitor")) + async def channels_monitor(): + for channel in configGet("channels", "scheduler", "channels_monitor"): + if configGet("debug") is True: + logWrite(f'Processing videos of {channel["name"]} ({channel["id"]})', debug=True) + try: + req = get(f'https://www.youtube.com/feeds/videos.xml?channel_id={channel["id"]}') + parsed = parse(req.content) + if "feed" not in parsed: + continue + if "entry" not in parsed["feed"]: + continue + for entry in parsed["feed"]["entry"]: + if "yt:videoId" not in entry: + continue + if col_youtube.find_one( {"channel": channel["id"], "video": entry["yt:videoId"]} ) is None: + col_youtube.insert_one( {"channel": channel["id"], "video": entry["yt:videoId"], "date": datetime.fromisoformat(entry["published"])} ) + await app.send_message(configGet("users", "groups"), locale("youtube_video", "message").format(channel["name"], channel["link"], entry["title"], entry["link"]["@href"]), disable_web_page_preview=False) + await sleep(2) + except Exception as exp: + logWrite(f'Could not get last videos of {channel["name"]} ({channel["id"]}) due to {exp}: {format_exc()}') + if configGet("debug") is True: + logWrite("Admin group caching performed", debug=True) \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 8e2a18e..d851783 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,4 +8,5 @@ tgcrypto==1.2.5 python_dateutil==2.8.2 starlette~=0.22.0 ujson~=5.7.0 -ftfy~=6.1.1 \ No newline at end of file +ftfy~=6.1.1 +xmltodict~=0.13.0 \ No newline at end of file