perf: support mipac v0.6.0

This commit is contained in:
xtaodada 2024-02-18 23:46:14 +08:00
parent e3146b44ba
commit 83b52128bf
Signed by: xtaodada
GPG Key ID: 4CBB3F4FA8C85659
9 changed files with 61 additions and 107 deletions

View File

@ -7,7 +7,7 @@ from typing import Optional, List
import aiofiles as aiofiles import aiofiles as aiofiles
from httpx import AsyncClient from httpx import AsyncClient
from mipac import Note, File from mipac import Note, File
from mipac.models.lite import LiteUser from mipac.models.lite import PartialUser
from pyrogram.enums import ParseMode from pyrogram.enums import ParseMode
from pyrogram.errors import MediaEmpty, FloodWait from pyrogram.errors import MediaEmpty, FloodWait
from pyrogram.types import ( from pyrogram.types import (
@ -59,15 +59,15 @@ def gen_button(host: str, note: Note, author: str, show_second: bool):
) )
def get_user_link(host: str, user: LiteUser) -> str: def get_user_link(host: str, user: PartialUser) -> str:
if user.host: if user.host:
return f"https://{host}/@{user.username}@{user.host}" return f"https://{host}/@{user.username}@{user.host}"
return f"https://{host}/@{user.username}" return f"https://{host}/@{user.username}"
def get_user_alink(host: str, user: LiteUser) -> str: def get_user_alink(host: str, user: PartialUser) -> str:
return '<a href="{}">{}</a>'.format( return '<a href="{}">{}</a>'.format(
get_user_link(host, user), user.nickname or f"@{user.username}" get_user_link(host, user), user.name or f"@{user.username}"
) )
@ -85,7 +85,7 @@ def format_at(host: str, content: str) -> str:
def get_content(host: str, note: Note) -> str: def get_content(host: str, note: Note) -> str:
content = note.content or "" content = note.text or ""
action = "发表" action = "发表"
origin = "" origin = ""
show_note = note show_note = note
@ -95,21 +95,21 @@ def get_content(host: str, note: Note) -> str:
if content: if content:
action = "引用" action = "引用"
content = ( content = (
f"> {note.renote.content or ''}\n\n=====================\n\n{content}" f"> {note.renote.text or ''}\n\n=====================\n\n{content}"
) )
else: else:
content = note.renote.content or "" content = note.renote.text or ""
origin = ( origin = (
f"\n{get_user_alink(host, note.renote.author)} " f"\n{get_user_alink(host, note.renote.user)} "
f"发表于 {get_post_time(note.renote.created_at)}" f"发表于 {get_post_time(note.renote.created_at)}"
) )
if note.reply: if note.reply:
show_note = note.reply show_note = note.reply
action = "回复" action = "回复"
if note.reply.content: if note.reply.text:
content = f"> {note.reply.content}\n\n=====================\n\n{content}" content = f"> {note.reply.text}\n\n=====================\n\n{content}"
origin = ( origin = (
f"\n{get_user_alink(host, note.reply.author)} " f"\n{get_user_alink(host, note.reply.user)} "
f"发表于 {get_post_time(note.reply.created_at)}" f"发表于 {get_post_time(note.reply.created_at)}"
) )
content = format_at(host, content[:768] + " ").strip() content = format_at(host, content[:768] + " ").strip()
@ -117,7 +117,7 @@ def get_content(host: str, note: Note) -> str:
{content} {content}
{get_user_alink(host, note.author)} {action} {get_post_time(note.created_at)}{origin} {get_user_alink(host, note.user)} {action} {get_post_time(note.created_at)}{origin}
点赞: {sum(show_note.reactions.values())} | 回复: {show_note.replies_count} | 转发: {show_note.renote_count}""" 点赞: {sum(show_note.reactions.values())} | 回复: {show_note.replies_count} | 转发: {show_note.renote_count}"""
@ -141,7 +141,7 @@ async def send_text(
get_content(host, note), get_content(host, note),
reply_to_message_id=reply_to_message_id, reply_to_message_id=reply_to_message_id,
reply_markup=gen_button( reply_markup=gen_button(
host, note, get_user_link(host, note.author), show_second host, note, get_user_link(host, note.user), show_second
), ),
disable_web_page_preview=True, disable_web_page_preview=True,
) )
@ -225,7 +225,7 @@ async def send_photo(
reply_to_message_id=reply_to_message_id, reply_to_message_id=reply_to_message_id,
caption=get_content(host, note), caption=get_content(host, note),
reply_markup=gen_button( reply_markup=gen_button(
host, note, get_user_link(host, note.author), show_second host, note, get_user_link(host, note.user), show_second
), ),
has_spoiler=spoiler, has_spoiler=spoiler,
) )
@ -250,7 +250,7 @@ async def send_gif(
reply_to_message_id=reply_to_message_id, reply_to_message_id=reply_to_message_id,
caption=get_content(host, note), caption=get_content(host, note),
reply_markup=gen_button( reply_markup=gen_button(
host, note, get_user_link(host, note.author), show_second host, note, get_user_link(host, note.user), show_second
), ),
has_spoiler=spoiler, has_spoiler=spoiler,
) )
@ -275,7 +275,7 @@ async def send_video(
reply_to_message_id=reply_to_message_id, reply_to_message_id=reply_to_message_id,
caption=get_content(host, note), caption=get_content(host, note),
reply_markup=gen_button( reply_markup=gen_button(
host, note, get_user_link(host, note.author), show_second host, note, get_user_link(host, note.user), show_second
), ),
has_spoiler=spoiler, has_spoiler=spoiler,
) )
@ -299,7 +299,7 @@ async def send_audio(
reply_to_message_id=reply_to_message_id, reply_to_message_id=reply_to_message_id,
caption=get_content(host, note), caption=get_content(host, note),
reply_markup=gen_button( reply_markup=gen_button(
host, note, get_user_link(host, note.author), show_second host, note, get_user_link(host, note.user), show_second
), ),
) )
@ -322,7 +322,7 @@ async def send_document(
reply_to_message_id=reply_to_message_id, reply_to_message_id=reply_to_message_id,
caption=get_content(host, note), caption=get_content(host, note),
reply_markup=gen_button( reply_markup=gen_button(
host, note, get_user_link(host, note.author), show_second host, note, get_user_link(host, note.user), show_second
), ),
) )
with contextlib.suppress(Exception): with contextlib.suppress(Exception):

View File

@ -1,7 +1,7 @@
from json import load from json import load
from mipac import Note from mipac import Note
from mipac.models.lite.user import LiteUser from mipac.models.lite.user import PartialUser
from mipac.models.notification import ( from mipac.models.notification import (
NotificationFollow, NotificationFollow,
NotificationFollowRequest, NotificationFollowRequest,
@ -21,15 +21,15 @@ with open("gen/achievement.json", "r", encoding="utf-8") as f:
achievement_map = load(f) achievement_map = load(f)
def get_user_link(host: str, user: LiteUser) -> str: def get_user_link(host: str, user: PartialUser) -> str:
if user.host: if user.host:
return f"https://{host}/@{user.username}@{user.host}" return f"https://{host}/@{user.username}@{user.host}"
return f"https://{host}/@{user.username}" return f"https://{host}/@{user.username}"
def get_user_alink(host: str, user: LiteUser) -> str: def get_user_alink(host: str, user: PartialUser) -> str:
return '<a href="{}">{}</a>'.format( return '<a href="{}">{}</a>'.format(
get_user_link(host, user), user.nickname or f"@{user.username}" get_user_link(host, user), user.name or f"@{user.username}"
) )
@ -37,7 +37,7 @@ def get_note_link(host: str, note: Note) -> str:
return f"https://{host}/notes/{note.id}" return f"https://{host}/notes/{note.id}"
def gen_link_button(host: str, user: LiteUser = None, note: Note = None): def gen_link_button(host: str, user: PartialUser = None, note: Note = None):
return [ return [
InlineKeyboardButton( InlineKeyboardButton(
text="Link", text="Link",

View File

@ -1,10 +1,11 @@
from datetime import datetime, timedelta from datetime import datetime, timedelta
from typing import Optional from typing import Optional
from mipac import UserDetailed from mipac import UserDetailedNotMe
from mipac.errors import FailedToResolveRemoteUserError from mipac.errors import FailedToResolveRemoteUserError
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from defs.misskey import get_user_link
from misskey_init import MisskeyBot from misskey_init import MisskeyBot
template = """<b>Misskey User Info</b> template = """<b>Misskey User Info</b>
@ -18,18 +19,18 @@ Updated: <code>%s</code>
📤 %s 粉丝 %s 关注 %s""" 📤 %s 粉丝 %s 关注 %s"""
def gen_text(user: UserDetailed): def gen_text(host: str, user: UserDetailedNotMe):
def parse_time(time: str) -> str: def parse_time(time: datetime) -> str:
if not time: if not time:
return "Unknown" return "Unknown"
time = datetime.strptime(time, "%Y-%m-%dT%H:%M:%S.%fZ") + timedelta(hours=8) time = time + timedelta(hours=8)
return time.strftime("%Y-%m-%d %H:%M:%S") return time.strftime("%Y-%m-%d %H:%M:%S")
create_at = parse_time(user.created_at) create_at = parse_time(user.created_at)
update_at = parse_time(user.updated_at) update_at = parse_time(user.updated_at)
return template % ( return template % (
user.nickname, user.name,
user.api.action.get_profile_link(), get_user_link(host, user),
user.username, user.username,
user.description or "", user.description or "",
create_at, create_at,
@ -40,9 +41,9 @@ def gen_text(user: UserDetailed):
) )
def gen_button(user: UserDetailed): def gen_button(host: str, user: UserDetailedNotMe):
first_line = [ first_line = [
InlineKeyboardButton(text="Link", url=user.api.action.get_profile_link()), InlineKeyboardButton(text="Link", url=get_user_link(host, user)),
] ]
second_line = [ second_line = [
InlineKeyboardButton( InlineKeyboardButton(
@ -55,7 +56,7 @@ def gen_button(user: UserDetailed):
async def search_user( async def search_user(
misskey_bot: MisskeyBot, username: str, host: str = None misskey_bot: MisskeyBot, username: str, host: str = None
) -> Optional[UserDetailed]: ) -> Optional[UserDetailedNotMe]:
""" """
搜索用户 搜索用户
""" """

View File

@ -1,6 +1,25 @@
from configparser import RawConfigParser from configparser import RawConfigParser
from typing import Union from typing import Union
from distutils.util import strtobool
def strtobool(val, default=False):
"""Convert a string representation of truth to true (1) or false (0).
True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values
are 'n', 'no', 'f', 'false', 'off', and '0'. Raises ValueError if
'val' is anything else.
"""
if val is None:
return default
val = val.lower()
if val in ("y", "yes", "t", "true", "on", "1"):
return 1
elif val in ("n", "no", "f", "false", "off", "0"):
return 0
else:
print("[Degrade] invalid truth value %r" % (val,))
return default
# [pyrogram] # [pyrogram]
api_id: int = 0 api_id: int = 0

View File

@ -50,11 +50,11 @@ class MisskeyBot(commands.Bot):
async def fetch_offline_notes(self): async def fetch_offline_notes(self):
logs.info(f"{self.tg_user.user_id} 开始获取最近十条时间线") logs.info(f"{self.tg_user.user_id} 开始获取最近十条时间线")
data = {"withReplies": False, "limit": 10} data = {"withReplies": False, "limit": 1}
data = await self.core.http.request( data = await self.core.http.request(
Route("POST", "/api/notes/timeline"), auth=True, json=data Route("POST", "/api/notes/timeline"), auth=True, json=data
) )
for note in (Note(note=note, client=self.client) for note in data): for note in (Note(raw_note=note, client=self.client) for note in data):
await self.process_note(note, notice=False) await self.process_note(note, notice=False)
logs.info(f"{self.tg_user.user_id} 处理完成最近十条时间线") logs.info(f"{self.tg_user.user_id} 处理完成最近十条时间线")

View File

@ -18,7 +18,7 @@ class NoRepeatRenoteAction:
async def check(uid: int, note: Note): async def check(uid: int, note: Note):
if await NoRepeatRenoteAction.get(uid, note.id): if await NoRepeatRenoteAction.get(uid, note.id):
return False return False
if note.renote and (not note.content): if note.renote and (not note.text):
if await NoRepeatRenoteAction.get(uid, note.renote.id): if await NoRepeatRenoteAction.get(uid, note.renote.id):
return False return False
return True return True
@ -26,5 +26,5 @@ class NoRepeatRenoteAction:
@staticmethod @staticmethod
async def set(uid: int, note: Note): async def set(uid: int, note: Note):
await NoRepeatRenoteAction.push(uid, note.id) await NoRepeatRenoteAction.push(uid, note.id)
if note.renote and (not note.content): if note.renote and (not note.text):
await NoRepeatRenoteAction.push(uid, note.renote.id) await NoRepeatRenoteAction.push(uid, note.renote.id)

View File

@ -1,67 +0,0 @@
import contextlib
from os import remove
from typing import Tuple
from pyrogram import Client, filters, ContinuePropagation
from pyrogram.types import Message, CallbackQuery
from defs.confirm import ready_send, ReadySendMessage
from misskey_init import get_misskey_bot
from models.filters import notice_filter
def get_uid(message: Message) -> Tuple[bool, str]:
group, user, uid = False, None, None
if not message.reply_to_message or not message.reply_to_message.reply_markup:
raise ContinuePropagation
with contextlib.suppress(IndexError, AttributeError):
url = message.reply_to_message.reply_markup.inline_keyboard[0][0].url
user = url.split("/")[-1]
if "/my/messaging/group/" in url:
group = True
uid = user
else:
uid = user.split("?cid=")[1]
if not user:
raise ContinuePropagation
if not uid:
raise ContinuePropagation
return group, uid
@Client.on_message(filters.incoming & notice_filter & filters.text)
async def chat_command(_: Client, message: Message):
group, uid = get_uid(message)
text = message.text.strip()
if text.startswith("@"):
raise ContinuePropagation
need_send = ReadySendMessage(text, group, uid)
await need_send.confirm(message)
@Client.on_message(filters.incoming & notice_filter & filters.photo)
async def chat_photo_command(_: Client, message: Message):
group, uid = get_uid(message)
text = message.caption.strip() if message.caption else ""
photo = await message.download()
try:
misskey_bot = get_misskey_bot(message.from_user.id)
file_ = await misskey_bot.core.api.drive.file.action.upload_file(photo)
except Exception as e:
return await message.reply(f"上传文件失败:{e}", quote=True)
need_send = ReadySendMessage(text, group, uid, file_.id)
remove(photo)
await need_send.confirm(message)
@Client.on_callback_query(filters.regex("^chat_send$") & notice_filter)
async def chat_send_callback(_: Client, callback_query: CallbackQuery):
"""
发送
"""
msg = callback_query.message
if need_send := ready_send.get((msg.chat.id, msg.id), None):
await need_send.send(msg, callback_query.from_user.id)
return await callback_query.answer("发送成功")
else:
return await callback_query.answer("按钮已过期", show_alert=True)

View File

@ -28,7 +28,8 @@ async def search_user_command(_: Client, message: Message):
user = await search_user(misskey_bot, username, host) user = await search_user(misskey_bot, username, host)
if not user: if not user:
return await message.reply("没有找到用户", quote=True) return await message.reply("没有找到用户", quote=True)
text, button = gen_text(user), gen_button(user) host = misskey_bot.tg_user.host
text, button = gen_text(host, user), gen_button(host, user)
if user.avatar_url: if user.avatar_url:
try: try:
await message.reply_photo( await message.reply_photo(

View File

@ -1,5 +1,5 @@
Pyrogram==2.0.106 Pyrogram==2.0.106
tgCrypto==1.2.5 PyrotgCrypto==1.2.6
httpx==0.24.1 httpx==0.24.1
apscheduler==3.10.1 apscheduler==3.10.1
sqlalchemy==1.4.41 sqlalchemy==1.4.41
@ -7,7 +7,7 @@ sqlmodel==0.0.8
aiosqlite==0.19.0 aiosqlite==0.19.0
PyYAML==6.0.1 PyYAML==6.0.1
aiofiles==23.1.0 aiofiles==23.1.0
pillow==10.0.0 pillow==10.2.0
cashews[redis]==6.2.0 cashews[redis]==6.2.0
alembic==1.11.2 alembic==1.11.2
sentry-sdk==1.29.2 sentry-sdk==1.29.2