Compare commits

...
9 Commits
Author SHA1 Message Date
YoursFunny 91cad86325 use http2 in httpx 2024-06-20 02:11:39 +08:00
YoursFunny cfdb05e476 add use uvloop 2024-06-20 01:41:40 +08:00
YoursFunny 6df6a950c8 update to httpx 2024-06-19 23:19:42 +08:00
YoursFunny 78d185723b add type checking import 2024-06-19 22:47:10 +08:00
YoursFunny 1252ec8804 fix import logger 2024-06-19 01:42:50 +08:00
YoursFunny cde1091c85 update call concurrently 2024-06-19 01:39:59 +08:00
YoursFunny 8b2b6b49ab update regex pattern 2024-06-19 01:03:16 +08:00
YoursFunny 86b4a972c9 bump version 2024-06-19 00:58:23 +08:00
YoursFunny 483a3de649 fix edit message caption 2024-05-13 00:55:49 +08:00
4 changed files with 58 additions and 43 deletions
+12 -2
View File
@@ -2,6 +2,13 @@ import logging
import os
import re
try:
import uvloop, asyncio
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
except ImportError:
uvloop = None
BOT_TOKEN = os.getenv("BOT_TOKEN")
ADMIN = [int(i) for i in os.getenv("BOT_ADMIN").split(",")]
@@ -14,7 +21,7 @@ if WEBHOOK:
WEBHOOK_CERT = os.getenv("WEBHOOK_CERT", "cert/cert.pem")
WEBHOOK_SECRET_TOKEN = os.getenv("WEBHOOK_SECRET_TOKEN")
x_url_regex = re.compile(r"^(?:https?://)(?:www\.|mobile\.|)(?:x|twitter)\.com/(.+)/status/(\d+)")
x_url_regex = re.compile(r"^(?:https?://)(?:www\.|mobile\.|)(?:x|twitter|fixvx|vxtwitter)\.com/(.+)/status/(\d+)")
x_media_regex = re.compile(r"^(?:https?://)(pbs|video)\.twimg\.com/(.*)")
x_tco_regex = re.compile(r"(?:https?://)t\.co/.+$", re.M)
message_url_regex = re.compile(r"\[.+]", re.S)
@@ -23,4 +30,7 @@ logging.basicConfig(
level=os.getenv("LOG_LEVEL", "WARNING"),
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
def get_logger(name: str) -> logging.Logger:
return logging.getLogger(name)
+18 -20
View File
@@ -1,24 +1,21 @@
import html
from functools import wraps
from typing import TYPE_CHECKING
from aiohttp import ClientSession
from telegram import Update, Chat, InlineKeyboardMarkup, InlineKeyboardButton, Message
from telegram.constants import ParseMode, ChatAction, ChatType
from telegram.ext import (
Application,
ApplicationBuilder,
ContextTypes,
Defaults,
filters,
InlineQueryHandler,
PicklePersistence,
MessageHandler,
CommandHandler, CallbackQueryHandler
)
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
from telegram.constants import ChatAction, ChatType, ParseMode
from telegram.ext import (ApplicationBuilder, CallbackQueryHandler, CommandHandler, Defaults,
InlineQueryHandler, MessageHandler, PicklePersistence, filters)
import common
from tweet import TGTweet
if TYPE_CHECKING:
from telegram import Chat, Message, Update
from telegram.ext import Application, ContextTypes
logger = common.get_logger(__name__)
def send_action(action):
def decorator(func):
@@ -36,7 +33,7 @@ async def inline_query(update: Update, context: ContextTypes.DEFAULT_TYPE) -> No
query = update.inline_query.query
if query == "":
return
common.logger.info(f"Query: {query}")
logger.info(f"Query: {query}")
async with TGTweet(query) as tweet:
result = list(tweet.inline_query_generator)
await update.inline_query.answer(result)
@@ -45,7 +42,7 @@ async def inline_query(update: Update, context: ContextTypes.DEFAULT_TYPE) -> No
@send_action(ChatAction.UPLOAD_PHOTO)
async def url_media(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
url = update.message.text
common.logger.info(f"Receiving url: {url}")
logger.info(f"Receiving url: {url}")
async with TGTweet(url) as tweet:
media = list(tweet.pm_media_generator)
message_to_send = await update.effective_message.reply_media_group(
@@ -114,7 +111,7 @@ async def edit_message(update: Update, context: ContextTypes.DEFAULT_TYPE) -> No
update_text[match[0] + 1:match[1] - 1]
) + update_text[match[1]:]
message_to_send = context.user_data['message_to_send']
await message_to_send[0].edit_text(update_text)
await message_to_send[0].edit_caption(update_text)
async def query_forward_message(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
@@ -205,7 +202,7 @@ async def post_init(application: Application) -> None:
DESCRIPTION = "A bot to fetch tweets from Twitter."
await application.bot.set_my_description(DESCRIPTION)
await application.bot.set_my_short_description(DESCRIPTION)
TGTweet.set_session(ClientSession())
TGTweet.init_client()
async def post_stop(application: Application) -> None:
@@ -213,7 +210,7 @@ async def post_stop(application: Application) -> None:
async def post_shutdown(application: Application) -> None:
await TGTweet.close_session()
await TGTweet.close_client()
def main():
@@ -226,6 +223,7 @@ def main():
.post_init(post_init)
.post_stop(post_stop)
.post_shutdown(post_shutdown)
.concurrent_updates(True)
.build()
)
@@ -233,8 +231,8 @@ def main():
user_filter.add_user_ids(common.ADMIN)
handlers = [
MessageHandler(filters.Regex(common.x_url_regex) & filters.ChatType.PRIVATE, url_media),
InlineQueryHandler(inline_query, common.x_url_regex),
MessageHandler(filters.Regex(common.x_url_regex) & filters.ChatType.PRIVATE, url_media),
CommandHandler("set_forward_channel", cmd_set_forward_channel),
CommandHandler("remove_forward_channel", cmd_remove_forward_channel),
CommandHandler("edit_before_forward", cmd_edit_before_forward),
+3 -2
View File
@@ -1,2 +1,3 @@
python-telegram-bot[webhooks]~=21.1.1
aiohttp[speedups]~=3.9.3
python-telegram-bot[webhooks]~=21.3
httpx[http2]~=0.27.0
uvloop~=0.19.0; sys_platform != 'win32'
+25 -19
View File
@@ -1,16 +1,14 @@
import html
from typing import Generator
from aiohttp import ClientSession
from telegram import (
InlineQueryResultPhoto,
InlineQueryResultVideo,
InlineQueryResultMpeg4Gif,
InputMediaPhoto,
InputMediaVideo
)
from httpx import AsyncClient
from telegram import (InlineQueryResultMpeg4Gif, InlineQueryResultPhoto, InlineQueryResultVideo, InputMediaPhoto,
InputMediaVideo)
from common import get_logger, x_media_regex, x_tco_regex, x_url_regex
logger = get_logger(__name__)
from common import x_url_regex, x_media_regex, x_tco_regex, logger
twimg_url = 'https://pbs.twimg.com/'
vx_api_url = 'https://api.vxtwitter.com/{0}/status/{1}'
@@ -20,11 +18,19 @@ message_raw_text = """{url}
"""
async def fetch_json(session: ClientSession, url: str) -> dict:
def create_client() -> 'AsyncClient':
return AsyncClient(http2=True)
async def close_client(_client: 'AsyncClient') -> None:
await _client.aclose()
async def fetch_json(_client: 'AsyncClient', url: str) -> dict:
logger.info(f"Fetching {url}")
async with session.get(url) as response:
assert response.status == 200, f"Failed to fetch {url}, status code {response.status}"
return await response.json()
response = await _client.get(url)
assert response.status_code == response.is_success, f"Failed to fetch {url}, status code {response.status_code}"
return response.json()
class TweetMedia:
@@ -119,7 +125,7 @@ class Tweet:
class TGTweet(Tweet):
_session: ClientSession
_httpx_client: AsyncClient
def __init__(self, url: str):
self._url: str = url
@@ -136,15 +142,15 @@ class TGTweet(Tweet):
pass
@classmethod
def set_session(cls, session: ClientSession) -> None:
cls._session = session
def init_client(cls) -> None:
cls._httpx_client = create_client()
@classmethod
async def close_session(cls) -> None:
await cls._session.close()
async def close_client(cls) -> None:
await close_client(cls._httpx_client)
async def _fetch_tweet(self, api_param: tuple[str]) -> dict:
return await fetch_json(self._session, vx_api_url.format(*api_param))
return await fetch_json(self._httpx_client, vx_api_url.format(*api_param))
@property
def _tweet_id(self) -> tuple[str] | None: