Skip to content

Commit 028767b

Browse files
authored
Merge pull request #38 from OpenBuilders/fix/refresh-chat-fix
fix: Refresh chat logo
2 parents 1669399 + fcd1e3d commit 028767b

File tree

5 files changed

+46
-22
lines changed

5 files changed

+46
-22
lines changed

backend/community_manager/handlers/chat.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ async def handle_chat_action(event: events.ChatAction.Event):
3030
if not telegram_chat_service.check_exists(event.chat_id):
3131
logger.debug(
3232
"Chat doesn't exist, but bot was not added to the chat: %d. Skipping event...",
33+
event.chat_id,
3334
)
3435
return
3536

@@ -43,7 +44,9 @@ async def handle_chat_action(event: events.ChatAction.Event):
4344
session, telethon_client=event.client
4445
)
4546
logo_path = await telegram_chat_action.fetch_and_push_profile_photo(
46-
event.chat
47+
event.chat,
48+
# We definitely know here that the new photo was set - no need to fetch the current value
49+
current_logo_path=None,
4750
)
4851
if logo_path:
4952
logger.debug(

backend/core/actions/chat/__init__.py

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,9 @@ async def _load_participants(self, chat_identifier: int) -> None:
164164
last_name=participant_user.last_name,
165165
username=participant_user.username,
166166
is_premium=participant_user.premium or False,
167-
language_code=participant_user.lang_code
168-
or core_settings.default_language,
167+
language_code=(
168+
participant_user.lang_code or core_settings.default_language
169+
),
169170
)
170171
)
171172
self.telegram_chat_user_service.create_or_update(
@@ -192,26 +193,33 @@ async def index(self, chat: ChatPeerType) -> None:
192193
logger.info(f"Creating a new chat invite link for the chat {chat_id!r}...")
193194
invite_link = await self.telethon_service.get_invite_link(chat)
194195
self.telegram_chat_service.refresh_invite_link(chat_id, invite_link.link)
195-
logger.info(f"Chat {chat_id!r} created successfully")
196196
await self._load_participants(telegram_chat.id)
197197

198-
async def fetch_and_push_profile_photo(self, chat: ChatPeerType) -> Path | None:
198+
async def fetch_and_push_profile_photo(
199+
self,
200+
chat: ChatPeerType,
201+
current_logo_path: str | None,
202+
) -> Path | None:
199203
"""
200204
Fetches the profile photo of a chat and uploads it for hosting. This function
201205
handles the download of the profile photo from the given chat and then pushes
202206
it to a CDN service for further access. If the profile photo exists, it will
203207
be returned as a Path object; otherwise, None is returned.
204208
205209
:param chat: The chat from which the profile photo is to be fetched.
210+
:param current_logo_path: The current logo path in the database.
206211
:return: The local path of the fetched profile photo or None
207212
"""
208-
logo_path = await self.telethon_service.download_profile_photo(chat)
213+
logo_path = await self.telethon_service.download_profile_photo(
214+
entity=chat,
215+
current_logo_path=current_logo_path,
216+
)
209217
if logo_path:
210218
await self.cdn_service.upload_file(
211219
file_path=logo_path,
212220
object_name=logo_path.name,
213221
)
214-
logger.info(f"Profile photo for chat {chat.id!r} uploaded")
222+
logger.info(f"New profile photo for chat {chat.id!r} uploaded")
215223
return logo_path
216224

217225
async def _create(
@@ -230,7 +238,9 @@ async def _create(
230238
:return: A DTO containing the details of the created Telegram chat.
231239
:raises TelegramChatAlreadyExists: If the chat already exists in the database.
232240
"""
233-
logo_path = await self.fetch_and_push_profile_photo(chat)
241+
logo_path = await self.fetch_and_push_profile_photo(
242+
chat, current_logo_path=None
243+
)
234244
try:
235245
chat_id = get_peer_id(chat, add_mark=True)
236246
telegram_chat = self.telegram_chat_service.create(
@@ -325,7 +335,7 @@ async def _refresh(self, chat: TelegramChat) -> TelegramChat:
325335
:raises TelegramChatNotSufficientPrivileges: If the bot lacks functionality privileges within the chat
326336
"""
327337
try:
328-
chat_entity, logo_path = await self._get_chat_data(chat.id)
338+
chat_entity = await self._get_chat_data(chat.id)
329339

330340
except (
331341
TelegramChatNotSufficientPrivileges, # happens when bot has no rights to function in the chat
@@ -343,10 +353,16 @@ async def _refresh(self, chat: TelegramChat) -> TelegramChat:
343353
self.telegram_chat_service.delete(chat_id=chat.id)
344354
raise
345355

356+
logo_path = await self.fetch_and_push_profile_photo(
357+
chat_entity, current_logo_path=chat.logo_path
358+
)
359+
346360
chat = self.telegram_chat_service.update(
347361
chat=chat,
348362
entity=chat_entity,
349-
logo_path=logo_path.name,
363+
# If a new logo was downloaded - use it,
364+
# otherwise fallback to the current one
365+
logo_path=logo_path.name if logo_path else chat.logo_path,
350366
)
351367
await self.index(chat_entity)
352368
logger.info(f"Chat {chat.id!r} refreshed successfully")

backend/core/dtos/user.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ class UserInitDataPO(BaseModel):
2323

2424
class TelegramUserDTO(BaseModel):
2525
id: int
26-
first_name: str
26+
first_name: str = ""
2727
last_name: str | None = None
2828
username: str | None = None
29-
is_premium: bool
29+
is_premium: bool = False
3030
language_code: str
3131
photo_url: str | None = None
3232
allow_write_to_pm: bool = True

backend/core/services/supertelethon.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import datetime
21
import logging
32
from pathlib import Path
43
from typing import AsyncGenerator
@@ -94,23 +93,31 @@ async def revoke_chat_invite(self, chat_id: int, link: str) -> None:
9493
)
9594
)
9695

97-
async def download_profile_photo(self, entity: Channel) -> Path | None:
96+
async def download_profile_photo(
97+
self,
98+
entity: Channel,
99+
current_logo_path: str | None = None,
100+
) -> Path | None:
98101
if not entity.photo or isinstance(entity.photo, ChatPhotoEmpty):
99102
logger.debug(f"Chat {entity.id!r} does not have a logo. Skipping")
100103
return None
101104

102-
# Adding timestamp allows to bypass the cache of the image to reflect the change
103-
logo_path = f"{entity.id}-{int(datetime.datetime.now().timestamp())}.jpg"
105+
# Adding timestamp allows bypassing the cache of the image to reflect the change
106+
new_file_name = f"{entity.photo.photo_id}.png"
107+
108+
if current_logo_path and current_logo_path == new_file_name:
109+
logger.debug(f"Logo for chat {entity.id} is up-to-date. Skipping download.")
110+
return None
104111

105-
with open(CHAT_LOGO_PATH / logo_path, "wb") as f:
112+
with open(CHAT_LOGO_PATH / new_file_name, "wb") as f:
106113
await self.client.download_profile_photo(entity, f)
107114

108-
# To avoid redundant files, we clean the old versions of the logo
115+
# To avoid redundant files, we remove the previous file
109116
clean_old_versions(
110-
path=CHAT_LOGO_PATH, prefix=f"{entity.id}-", current_file=logo_path
117+
path=CHAT_LOGO_PATH, prefix=current_logo_path, current_file=new_file_name
111118
)
112119

113-
return CHAT_LOGO_PATH / logo_path
120+
return CHAT_LOGO_PATH / new_file_name
114121

115122
async def promote_user(
116123
self, chat_id: int, telegram_user_id: int, custom_title: str

backend/core/utils/custom_rules/telegram_usernames.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,6 @@ def _inner(nfts: list[NftItem]) -> list[NftItem]:
4242

4343
telegram_username = TelegramUsername(nft.blockchain_metadata.name)
4444

45-
print(telegram_username.username, target_length, len(telegram_username))
46-
4745
if len(telegram_username) <= target_length:
4846
valid_nfts.append(nft)
4947

0 commit comments

Comments
 (0)