perodic check sub

This commit is contained in:
BennyThink 2022-02-03 20:41:57 +08:00
parent 835feef5c9
commit 42354b6eed
No known key found for this signature in database
GPG Key ID: 6CD0DBDA5235D481
2 changed files with 48 additions and 8 deletions

View File

@ -87,6 +87,7 @@ class VIP(Redis, MySQL):
self.cur.execute("select count(user_id) from subscribe where user_id=%s", (user_id,)) self.cur.execute("select count(user_id) from subscribe where user_id=%s", (user_id,))
usage = int(self.cur.fetchone()[0]) usage = int(self.cur.fetchone()[0])
if usage >= 3 and not self.check_vip(user_id): if usage >= 3 and not self.check_vip(user_id):
logging.warning("User %s is not VIP but has subscribed %s channels", user_id, usage)
return "You have subscribed too many channels. Please upgrade to VIP to subscribe more channels." return "You have subscribed too many channels. Please upgrade to VIP to subscribe more channels."
data = self.get_channel_info(share_link) data = self.get_channel_info(share_link)
@ -94,19 +95,21 @@ class VIP(Redis, MySQL):
"%(link)s,%(title)s,%(description)s,%(channel_id)s,%(playlist)s,%(last_video)s)", data) "%(link)s,%(title)s,%(description)s,%(channel_id)s,%(playlist)s,%(last_video)s)", data)
self.cur.execute("INSERT INTO subscribe values(%s,%s)", (user_id, data["channel_id"])) self.cur.execute("INSERT INTO subscribe values(%s,%s)", (user_id, data["channel_id"]))
self.con.commit() self.con.commit()
logging.info("User %s subscribed channel %s", user_id, data["title"])
return "Subscribed to {}".format(data["title"]) return "Subscribed to {}".format(data["title"])
def unsubscribe_channel(self, user_id: "int", channel_id: "str"): def unsubscribe_channel(self, user_id: "int", channel_id: "str"):
affected_rows = self.cur.execute("DELETE FROM subscribe WHERE user_id=%s AND channel_id=%s", affected_rows = self.cur.execute("DELETE FROM subscribe WHERE user_id=%s AND channel_id=%s",
(user_id, channel_id)) (user_id, channel_id))
self.con.commit() self.con.commit()
logging.info("User %s unsubscribed channel %s", user_id, channel_id)
return affected_rows return affected_rows
@staticmethod @staticmethod
def get_channel_info(url: "str"): def get_channel_info(url: "str"):
api_key = os.getenv("GOOGLE_API_KEY") api_key = os.getenv("GOOGLE_API_KEY")
html_doc = requests.get(url).text html_doc = requests.get(url).text
soup = BeautifulSoup(html_doc, 'html.parser') soup = BeautifulSoup(html_doc, "html.parser")
element = soup.find("link", rel="canonical") element = soup.find("link", rel="canonical")
channel_id = element['href'].split("https://www.youtube.com/channel/")[1] channel_id = element['href'].split("https://www.youtube.com/channel/")[1]
channel_api = f"https://www.googleapis.com/youtube/v3/channels?part=snippet,contentDetails&" \ channel_api = f"https://www.googleapis.com/youtube/v3/channels?part=snippet,contentDetails&" \
@ -133,13 +136,19 @@ class VIP(Redis, MySQL):
f"playlistId={playlist_id}&key={api_key}" f"playlistId={playlist_id}&key={api_key}"
data = requests.get(video_api).json() data = requests.get(video_api).json()
video_id = data['items'][0]['snippet']['resourceId']['videoId'] video_id = data['items'][0]['snippet']['resourceId']['videoId']
logging.info(f"Latest video %s from %s", video_id, data['items'][0]['snippet']['channelTitle'])
return f"https://www.youtube.com/watch?v={video_id}" return f"https://www.youtube.com/watch?v={video_id}"
def has_newer_update(self, playlist_id: "str"): def has_newer_update(self, channel_id: "str"):
self.cur.execute("SELECT last_video FROM channel WHERE playlist=%s", (playlist_id,)) self.cur.execute("SELECT playlist,latest_video FROM channel WHERE channel_id=%s", (channel_id,))
old_video = self.cur.fetchone()[0] data = self.cur.fetchone()
playlist_id = data[0]
old_video = data[1]
newest_video = VIP.get_latest_video(playlist_id) newest_video = VIP.get_latest_video(playlist_id)
if old_video != newest_video: if old_video != newest_video:
logging.info("Newer update found for %s %s", channel_id, newest_video)
self.cur.execute("UPDATE channel SET latest_video=%s WHERE channel_id=%s", (newest_video, channel_id))
self.con.commit()
return newest_video return newest_video
def get_user_subscription(self, user_id: "int"): def get_user_subscription(self, user_id: "int"):
@ -154,6 +163,16 @@ class VIP(Redis, MySQL):
text += "[{}]({}) `{}\n`".format(*item) text += "[{}]({}) `{}\n`".format(*item)
return text return text
def group_subscriber(self):
# {"channel_id": [user_id, user_id, ...]}
self.cur.execute("select * from subscribe")
data = self.cur.fetchall()
group = {}
for item in data:
group.setdefault(item[1], []).append(item[0])
logging.info("Checking peroidic subscriber...")
return group
class BuyMeACoffee: class BuyMeACoffee:
def __init__(self): def __init__(self):
@ -254,6 +273,13 @@ def verify_payment(user_id, unique) -> "str":
return message return message
def subscribe_query():
vip = VIP()
for cid, uid in vip.group_subscriber().items():
has = vip.has_newer_update(cid)
if has:
print(f"{has} - {uid}")
if __name__ == '__main__': if __name__ == '__main__':
res = Redis().generate_file() subscribe_query()
print(res.getvalue().decode())

View File

@ -9,9 +9,10 @@ __author__ = "Benny <benny.think@gmail.com>"
import logging import logging
import os import os
import random
import re import re
import time
import typing import typing
from io import BytesIO, StringIO
from apscheduler.schedulers.background import BackgroundScheduler from apscheduler.schedulers.background import BackgroundScheduler
from pyrogram import Client, filters, types from pyrogram import Client, filters, types
from pyrogram.errors.exceptions.bad_request_400 import UserNotParticipant from pyrogram.errors.exceptions.bad_request_400 import UserNotParticipant
@ -102,7 +103,7 @@ def subscribe_handler(client: "Client", message: "types.Message"):
else: else:
link = message.text.split(" ")[1] link = message.text.split(" ")[1]
result = vip.subscribe_channel(chat_id, link) result = vip.subscribe_channel(chat_id, link)
client.send_message(chat_id, result, disable_web_page_preview=True) client.send_message(chat_id, result or "You have no subscription.", disable_web_page_preview=True)
@app.on_message(filters.command(["unsub"])) @app.on_message(filters.command(["unsub"]))
@ -266,12 +267,25 @@ def audio_callback(client: "Client", callback_query: types.CallbackQuery):
audio_entrance(msg) audio_entrance(msg)
def periodic_sub_check():
vip = VIP()
for cid, uids in vip.group_subscriber().items():
video_url = vip.has_newer_update(cid)
if video_url:
logging.info(f"periodic update:{video_url} - {uids}")
for uid in uids:
# TODO can we send and forward?
app.send_message(uid, video_url)
time.sleep(random.random())
if __name__ == '__main__': if __name__ == '__main__':
MySQL() MySQL()
scheduler = BackgroundScheduler(timezone="Asia/Shanghai") scheduler = BackgroundScheduler(timezone="Asia/Shanghai")
scheduler.add_job(Redis().reset_today, 'cron', hour=0, minute=0) scheduler.add_job(Redis().reset_today, 'cron', hour=0, minute=0)
scheduler.add_job(auto_restart, 'interval', seconds=5) scheduler.add_job(auto_restart, 'interval', seconds=5)
scheduler.add_job(InfluxDB().collect_data, 'interval', seconds=60) scheduler.add_job(InfluxDB().collect_data, 'interval', seconds=60)
scheduler.add_job(periodic_sub_check, 'interval', seconds=60)
scheduler.start() scheduler.start()
banner = f""" banner = f"""