diff --git a/post_parser.py b/post_parser.py index 4987218..9c7dbb6 100644 --- a/post_parser.py +++ b/post_parser.py @@ -88,7 +88,7 @@ class PostParser: def _format_json(self, message: Message, naked: bool = False) -> Dict[Any, Any]: html_content = self._format_html(message, naked=naked) result = { - 'channel': message.chat.username, + 'channel': self.get_channel_username(message), 'message_id': message.id, 'date': datetime.timestamp(message.date), 'text': message.text or message.caption or '', @@ -230,11 +230,12 @@ class PostParser: if file_unique_id is None: logger.debug(f"File unique id not found for message {message.id}") elif file_unique_id: - file = f"{message.chat.username}/{message.id}/{file_unique_id}" + channel_username = self.get_channel_username(message) + file = f"{channel_username}/{message.id}/{file_unique_id}" digest = generate_media_digest(file) url = f"{base_url}/media/{file}/{digest}" - logger.debug(f"Collected media file: {message.chat.username}/{message.id}/{file_unique_id}") + logger.debug(f"Collected media file: {channel_username}/{message.id}/{file_unique_id}") html_content.append(f'
') if message.media in [MessageMediaType.PHOTO, MessageMediaType.DOCUMENT]: html_content.append(f'') @@ -310,7 +311,8 @@ class PostParser: if photo := getattr(webpage, "photo", None): logger.debug(f"Processing webpage with photo: message_id={message.id}, photo={photo}") if file_unique_id := getattr(photo, "file_unique_id", None): - url = f"{base_url}/media/{message.chat.username}/{message.id}/{file_unique_id}" + channel_username = self.get_channel_username(message) + url = f"{base_url}/media/{channel_username}/{message.id}/{file_unique_id}" logger.debug(f"Generated media URL: {url}") return ( f'
' @@ -349,10 +351,11 @@ class PostParser: views_html = f'{views} views' parts.append(views_html) - if message.chat.username: + channel_username = self.get_channel_username(message) + if channel_username: links = [] - links.append(f'Open in Telegram') - links.append(f'Open in Web') + links.append(f'Open in Telegram') + links.append(f'Open in Web') parts.append('     '.join(links)) html = '     '.join(parts) if parts else None @@ -427,7 +430,7 @@ class PostParser: 'file_id': None, } - channel_username = getattr(message.chat, 'username', None) + channel_username = self.get_channel_username(message) if not channel_username: logger.error(f"channel_username_error: no username found for chat in message {message.id}") return @@ -491,17 +494,21 @@ class PostParser: def get_channel_username(self, message): """Extract channel username from message""" - if not message.chat: + chat = message.chat if hasattr(message, 'chat') else message + if not chat: return None - - if hasattr(message.chat, 'username'): - return message.chat.username - elif hasattr(message.chat, 'usernames') and message.chat.usernames: + + # Check for usernames + if hasattr(chat, 'usernames') and chat.usernames: # Return first active username from the list - active_usernames = [u.username for u in message.chat.usernames if u.active] + active_usernames = [u.username for u in chat.usernames if u.active] if active_usernames: return active_usernames[0] - + + # Check for single username as fallback + if hasattr(chat, 'username') and chat.username: + return chat.username + # If no username found in any form - logger.error(f"channel_username_error: no username found for chat in message {message.id}") + logger.error(f"channel_username_error: no username found for chat in message {getattr(message, 'id', 'unknown')}") return None diff --git a/rss_generator.py b/rss_generator.py index 655e922..37398b8 100644 --- a/rss_generator.py +++ b/rss_generator.py @@ -44,6 +44,9 @@ async def generate_channel_rss(channel: str, post_parser: Optional[PostParser] = try: channel_info = await post_parser.client.get_chat(channel) channel_title = channel_info.title or f"Telegram: {channel}" + channel_username = post_parser.get_channel_username(channel_info) + if not channel_username: + return create_error_feed(channel, base_url) except Exception as e: # raise error if channel not found if "USERNAME_INVALID" in str(e) or "USERNAME_NOT_OCCUPIED" in str(e): return create_error_feed(channel, base_url) @@ -51,10 +54,10 @@ async def generate_channel_rss(channel: str, post_parser: Optional[PostParser] = raise # Set feed metadata - main_name = f"{channel_title} (@{channel})" + main_name = f"{channel_title} (@{channel_username})" fg.title(main_name) - fg.link(href=f"https://t.me/{channel}", rel='alternate') - fg.description(f'Telegram channel {channel} RSS feed') + fg.link(href=f"https://t.me/{channel_username}", rel='alternate') + fg.description(f'Telegram channel {channel_username} RSS feed') fg.language('ru') fg.id(f"{base_url}/rss/{channel}") @@ -119,7 +122,7 @@ async def generate_channel_rss(channel: str, post_parser: Optional[PostParser] = fe = fg.add_entry() fe.title(post.get('title', 'Untitled post')) - post_link = f"https://t.me/{channel}/{post['message_id']}" + post_link = f"https://t.me/{channel_username}/{post['message_id']}" fe.link(href=post_link) html_content = post.get('html', '')