Compare commits

..
9 Commits
Author SHA1 Message Date
YoursFunny 4083b09093 add gif support 2024-03-23 14:54:22 +08:00
YoursFunny 8fb53e8412 fix session 2024-03-23 00:17:59 +08:00
YoursFunny 5c0ee8b491 fix data 2024-03-22 23:06:21 +08:00
YoursFunny af561ed0a0 fix pers_data 2024-03-22 23:03:04 +08:00
YoursFunny 985fe3fbfe update api format and logger 2024-03-22 22:45:52 +08:00
YoursFunny 19fb5b9822 fix logger 2024-03-22 22:34:59 +08:00
YoursFunny 1185d4bc5f fix logger 2024-03-22 22:26:31 +08:00
YoursFunny c3faecf640 add logger 2024-03-22 22:18:43 +08:00
YoursFunny 76e0ffe58c fix image suffix 2024-03-22 21:32:32 +08:00
5 changed files with 45 additions and 19 deletions
+1 -1
View File
@@ -27,5 +27,5 @@
.python-version
LICENSE
README.md
pers_data
data/
cert/
+1 -1
View File
@@ -1,6 +1,6 @@
**/.idea
__pycache__/
cert/
pers_data
data/
docker-compose.yml
x.py
+1 -1
View File
@@ -16,6 +16,6 @@ services:
WEBHOOK_SECRET_TOKEN: 'secret-token'
# LOG_LEVEL: 'WARNING'
volumes:
- ./pers_data: /app/pers_data
- ./data: /app/data
# - ./cert:/app/cert
container_name: tgxmb
+7 -5
View File
@@ -21,7 +21,8 @@ async def inline_query(update: Update, context: ContextTypes.DEFAULT_TYPE) -> No
query = update.inline_query.query
if query == "":
return
async with TGTweet(context.bot_data['client'], query) as tweet:
common.logger.info(f"Query: {query}")
async with TGTweet(query) as tweet:
result = list(tweet.inline_query_generator)
await update.inline_query.answer(result)
@@ -30,7 +31,8 @@ async def reply_media(update: Update, context: ContextTypes.DEFAULT_TYPE) -> Non
await update.effective_chat.send_action(ChatAction.UPLOAD_PHOTO)
# url = update.message.text.split(" ")[0]
url = update.message.text
async with TGTweet(context.bot_data['client'], url) as tweet:
common.logger.info(f"Receiving url: {url}")
async with TGTweet(url) as tweet:
media = list(tweet.pm_media_generator)
message_sent = await update.effective_message.reply_media_group(
media,
@@ -90,7 +92,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)
application.bot_data['client'] = ClientSession()
TGTweet.set_session(ClientSession())
async def post_stop(application: Application) -> None:
@@ -98,12 +100,12 @@ async def post_stop(application: Application) -> None:
async def post_shutdown(application: Application) -> None:
await application.bot_data['client'].close()
await TGTweet.close_session()
def main():
defaults = Defaults(parse_mode=ParseMode.HTML, allow_sending_without_reply=True)
persistence = PicklePersistence(filepath='pers_data')
persistence = PicklePersistence(filepath='data/pers.pkl')
application = (ApplicationBuilder()
.token(common.BOT_TOKEN)
.defaults(defaults)
+35 -11
View File
@@ -5,13 +5,13 @@ from telegram import (
InlineQueryResultPhoto,
InlineQueryResultVideo,
InputMediaPhoto,
InputMediaVideo
InputMediaVideo, InputMediaAnimation, InlineQueryResultMpeg4Gif
)
from common import x_url_regex, x_media_regex, x_tco_regex
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/status/{0}/status/{1}'
vx_api_url = 'https://api.vxtwitter.com/{0}/status/{1}'
message_raw_text = """{url}
<a href="{author_url}">{author}</a>: {text}
@@ -19,6 +19,7 @@ message_raw_text = """{url}
async def fetch_json(session: ClientSession, 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()
@@ -30,18 +31,21 @@ class TweetMedia:
self._thumb: str = thumb
self._type: str = media_type
def __str__(self):
return f"Media[url: {self.url} thumb: {self.thumb} type: {self.type}]"
@property
def _uri(self) -> str | None:
match = x_media_regex.match(self._url)
if match:
return match.group(2).removesuffix('.jpg')
return match.group(2).removesuffix('.jpg').removesuffix('.png')
return None
@property
def url(self) -> str:
match self._type:
case "image":
return f"{twimg_url}{self._uri}?format=jpg&name=orig"
return f"{twimg_url}{self._uri}?format=jpg&name=4096x4096"
case "video":
return self._url
@@ -105,8 +109,9 @@ class Tweet:
class TGTweet(Tweet):
def __init__(self, session: ClientSession, url: str):
self._session: ClientSession = session
_session: ClientSession
def __init__(self, url: str):
self._url: str = url
self._api_param: tuple[str] = self._tweet_id
assert self._api_param
@@ -119,6 +124,14 @@ class TGTweet(Tweet):
async def __aexit__(self, exc_type, exc_val, exc_tb):
pass
@classmethod
def set_session(cls, session: ClientSession) -> None:
cls._session = session
@classmethod
async def close_session(cls) -> None:
await cls._session.close()
async def _fetch_tweet(self, api_param: tuple[str]) -> dict:
return await fetch_json(self._session, vx_api_url.format(*api_param))
@@ -167,13 +180,12 @@ class TGTweet(Tweet):
@property
def inline_query_generator(self) -> Generator[InlineQueryResultPhoto | InlineQueryResultVideo, None, None]:
for i, tweet_media in enumerate(self.media):
logger.info(str(tweet_media))
if tweet_media.type == "image":
yield InlineQueryResultPhoto(
id=str(i),
photo_url=tweet_media.url,
thumbnail_url=tweet_media.thumb,
title=self.url,
description=self.text,
caption=self.message_text if not i else None
)
elif tweet_media.type == "video":
@@ -182,14 +194,20 @@ class TGTweet(Tweet):
video_url=tweet_media.url,
mime_type="video/mp4",
thumbnail_url=tweet_media.thumb,
title=self.url,
description=self.text,
caption=self.message_text if not i else None
)
elif tweet_media.type == "gif":
yield InlineQueryResultMpeg4Gif(
id=str(i),
mpeg4_url=tweet_media.url,
thumbnail_url=tweet_media.thumb,
caption=self.message_text if not i else None
)
@property
def pm_media_generator(self) -> Generator[InputMediaPhoto | InputMediaVideo, None, None]:
for tweet_media in self.media:
logger.info(str(tweet_media))
if tweet_media.type == "image":
yield InputMediaPhoto(
media=tweet_media.url,
@@ -201,3 +219,9 @@ class TGTweet(Tweet):
has_spoiler=self.sensitive,
thumbnail=tweet_media.thumb
)
elif tweet_media.type == "gif":
yield InputMediaAnimation(
media=tweet_media.url,
has_spoiler=self.sensitive,
thumbnail=tweet_media.thumb
)