Compare commits

..
10 Commits
Author SHA1 Message Date
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
YoursFunny a38c1b05b4 fix twitter id 2024-03-22 21:11:19 +08:00
YoursFunny b3c9b1ace7 fix api request 2024-03-22 21:03:25 +08:00
YoursFunny 6a7ab11148 fix query id duplicate 2024-03-22 20:13:46 +08:00
6 changed files with 32 additions and 21 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
@@ -14,7 +14,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)\.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)
+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 -3
View File
@@ -9,7 +9,8 @@ from telegram.ext import (
filters,
InlineQueryHandler,
PicklePersistence,
MessageHandler, CommandHandler
MessageHandler,
CommandHandler
)
import common
@@ -20,6 +21,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}")
async with TGTweet(context.bot_data['client'], query) as tweet:
result = list(tweet.inline_query_generator)
await update.inline_query.answer(result)
@@ -29,10 +31,12 @@ 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
common.logger.info(f"Receiving url: {url}")
async with TGTweet(context.bot_data['client'], url) as tweet:
media = list(tweet.pm_media_generator)
message_sent = await update.effective_message.reply_media_group(
media, caption=tweet.message_text,
media,
caption=tweet.message_text,
reply_to_message_id=update.message.message_id
)
if 'forward_channel_id' in context.user_data:
@@ -101,7 +105,7 @@ async def post_shutdown(application: Application) -> None:
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)
+21 -14
View File
@@ -8,10 +8,10 @@ from telegram import (
InputMediaVideo
)
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/'
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
@@ -108,25 +112,25 @@ class TGTweet(Tweet):
def __init__(self, session: ClientSession, url: str):
self._session: ClientSession = session
self._url: str = url
self._id: str = self._tweet_id
assert self._id
self._api_param: tuple[str] = self._tweet_id
assert self._api_param
async def __aenter__(self):
self._tweet: dict = await self._fetch_tweet(self._id)
self._tweet: dict = await self._fetch_tweet(self._api_param)
super().__init__(*self._init_properties)
return self
async def __aexit__(self, exc_type, exc_val, exc_tb):
pass
async def _fetch_tweet(self, tweet_id: str) -> dict:
return await fetch_json(self._session, vx_api_url + tweet_id)
async def _fetch_tweet(self, api_param: tuple[str]) -> dict:
return await fetch_json(self._session, vx_api_url.format(*api_param))
@property
def _tweet_id(self) -> str | None:
def _tweet_id(self) -> tuple[str] | None:
match = x_url_regex.match(self._url)
if match:
return match.group(1).strip('/')
return match.groups()
return None
@property
@@ -147,12 +151,13 @@ class TGTweet(Tweet):
@property
def _init_properties(self) -> tuple:
id = self._tweet['tweetID']
author = self._tweet['user_name']
author_id = self._tweet['user_screen_name']
text = self._tweet_text
media = self._tweet_media
sensitive = self._tweet['possibly_sensitive']
return self._id, author, author_id, text, media, sensitive
return id, author, author_id, text, media, sensitive
@property
def message_text(self) -> str:
@@ -166,9 +171,10 @@ 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=self.id,
id=str(i),
photo_url=tweet_media.url,
thumbnail_url=tweet_media.thumb,
title=self.url,
@@ -177,7 +183,7 @@ class TGTweet(Tweet):
)
elif tweet_media.type == "video":
yield InlineQueryResultVideo(
id=self.id,
id=str(i),
video_url=tweet_media.url,
mime_type="video/mp4",
thumbnail_url=tweet_media.thumb,
@@ -189,6 +195,7 @@ class TGTweet(Tweet):
@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,