90 lines
2.8 KiB
Python
90 lines
2.8 KiB
Python
from dataclasses import replace
|
|
|
|
from pyrogram import raw
|
|
|
|
from userbot.modules.avatars import capture_avatar
|
|
from userbot.modules.client import PyroClient
|
|
from userbot.modules.profiles import active_username, snapshot_from_user
|
|
from userbot.modules.profiles.parse import ProfileFields
|
|
from userbot.modules.profiles.repository import get_peer, write_profile
|
|
from userbot.modules.raw_json import raw_json
|
|
|
|
HANDLES = (raw.types.UpdateUserName, raw.types.UpdateUser, raw.types.UpdateUserPhone)
|
|
|
|
|
|
async def _handle_user(
|
|
client: PyroClient, update: raw.types.UpdateUser, users: dict
|
|
) -> None:
|
|
ctx = client.capture
|
|
if ctx is None:
|
|
return
|
|
raw_user = users.get(update.user_id)
|
|
if raw_user is None:
|
|
return
|
|
fields, photo_file_id, photo_unique_id = await snapshot_from_user(client, raw_user)
|
|
current = await get_peer(ctx.pool, ctx.account_id, update.user_id)
|
|
if current == fields:
|
|
return
|
|
is_bot = bool(getattr(raw_user, "bot", False))
|
|
await write_profile(
|
|
ctx.pool,
|
|
ctx.account_id,
|
|
update.user_id,
|
|
fields,
|
|
raw_json(raw_user),
|
|
history=ctx.resolve_peer(update.user_id, is_bot=is_bot).profile_history,
|
|
)
|
|
changed_photo = current is None or current.photo_unique_id != photo_unique_id
|
|
if photo_file_id and photo_unique_id and changed_photo:
|
|
await capture_avatar(
|
|
client,
|
|
ctx,
|
|
update.user_id,
|
|
"peer",
|
|
photo_file_id,
|
|
photo_unique_id,
|
|
raw_json(raw_user),
|
|
)
|
|
|
|
|
|
async def _merge_partial(
|
|
client: PyroClient, peer_id: int, overrides: dict, raw_str: str
|
|
) -> None:
|
|
ctx = client.capture
|
|
if ctx is None:
|
|
return
|
|
current = await get_peer(ctx.pool, ctx.account_id, peer_id)
|
|
merged = replace(current or ProfileFields(), **overrides)
|
|
if merged == current:
|
|
return
|
|
await write_profile(
|
|
ctx.pool,
|
|
ctx.account_id,
|
|
peer_id,
|
|
merged,
|
|
raw_str,
|
|
history=ctx.resolve_peer(peer_id).profile_history,
|
|
)
|
|
|
|
|
|
async def handle(
|
|
client: PyroClient, update: raw.base.Update, users: dict, _chats: dict
|
|
) -> None:
|
|
if isinstance(update, raw.types.UpdateUser):
|
|
await _handle_user(client, update, users)
|
|
elif isinstance(update, raw.types.UpdateUserName):
|
|
await _merge_partial(
|
|
client,
|
|
update.user_id,
|
|
{
|
|
"first_name": update.first_name or None,
|
|
"last_name": update.last_name or None,
|
|
"username": active_username(update.usernames),
|
|
},
|
|
raw_json(update),
|
|
)
|
|
elif isinstance(update, raw.types.UpdateUserPhone):
|
|
await _merge_partial(
|
|
client, update.user_id, {"phone": update.phone or None}, raw_json(update)
|
|
)
|