diff --git a/app/core/_utils/share_links.py b/app/core/_utils/share_links.py index fb3a279..aa3d92a 100644 --- a/app/core/_utils/share_links.py +++ b/app/core/_utils/share_links.py @@ -1,18 +1,14 @@ from typing import Optional from urllib.parse import urlencode -STARTAPP_SEPARATOR = '!' STARTAPP_LIMIT = 64 def build_content_links(content_token: str, ref_id: Optional[str], *, project_host: str, bot_username: str): """Return tuple of (startapp_payload, telegram_url, web_url).""" - payload = content_token - short_ref = (ref_id or '').strip()[:3] - if short_ref: - candidate = f"{content_token}{STARTAPP_SEPARATOR}{short_ref}" - if len(candidate) <= STARTAPP_LIMIT: - payload = candidate + payload = (content_token or '').strip() + if len(payload) > STARTAPP_LIMIT: + payload = payload[:STARTAPP_LIMIT] telegram_url = f"https://t.me/{bot_username}/content?startapp={payload}" diff --git a/app/core/background/indexer_service.py b/app/core/background/indexer_service.py index 3178c7b..53b6acd 100644 --- a/app/core/background/indexer_service.py +++ b/app/core/background/indexer_service.py @@ -17,9 +17,7 @@ from app.core.models.user import User from app.core.models.node_storage import StoredContent from app.core._utils.resolve_content import resolve_content from app.core.models.wallet_connection import WalletConnection -from app.core._keyboards import get_inline_keyboard from app.core.models._telegram import Wrapped_CBotChat -from app.core._utils.share_links import build_content_links MIN_ONCHAIN_INDEX = int(os.getenv("MIN_ONCHAIN_INDEX", "8")) @@ -243,28 +241,19 @@ async def indexer_loop(memory, platform_found: bool, seqno: int) -> [bool, int]: ref_id = user.ensure_ref_id() await session.commit() - _, startapp_url, web_url = build_content_links( - encrypted_stored_content.cid.serialize_v2(), - ref_id, - project_host=PROJECT_HOST, - bot_username=CLIENT_TELEGRAM_BOT_USERNAME - ) - message_text = user.translated('p_contentWasIndexed').format( item_address=item_address.to_string(1, 1, 1), item_index=item_index, ) - message_text += f"\n\n🔗 Открыть контент" await user_uploader_wrapper.send_message( message_text, - message_type='notification', - reply_markup=get_inline_keyboard([ - [{ - 'text': user.translated('viewTrackAsClient_button'), - 'url': startapp_url - }] - ]) + message_type='notification' + ) + + await user_uploader_wrapper.send_content( + session, + encrypted_stored_content ) try: diff --git a/app/core/models/_telegram/templates/player.py b/app/core/models/_telegram/templates/player.py index ca74726..dfddc9c 100644 --- a/app/core/models/_telegram/templates/player.py +++ b/app/core/models/_telegram/templates/player.py @@ -22,6 +22,9 @@ class PlayerTemplates: template_kwargs = {} inline_keyboard_array = [] text = "" + content_metadata_json = {} + description_block = "" + status_hint = "" if content: assert content.type.startswith('onchain/content'), "Invalid nodeStorage content type" cd_log = f"Content (SHA256: {content.hash}), Encrypted: {content.encrypted}, TelegramCID: {content.telegram_cid}. " @@ -34,74 +37,74 @@ class PlayerTemplates: cd_log += f"Decrypted: {local_content.hash}. " else: cd_log += "Can't decrypt content. " - user_wallet_address = await self.user.wallet_address_async(self.db_session) user_existing_license = (await self.db_session.execute(select(UserContent).where( and_(UserContent.user_id == self.user.id, UserContent.content_id == content.id) ))).scalars().first() + content_meta = content.json_format() if content else {} if local_content: - content_meta = content.json_format() - local_content_meta = local_content.json_format() - make_log("TG-Player", f"Content meta: {content_meta}. Local content meta: {local_content_meta}. ") + make_log("TG-Player", f"Content meta: {content_meta}. Local content meta: {local_content.json_format()}. ") try: content_type, content_encoding = "audio", "aac" except: content_type, content_encoding = 'application', 'x-binary' - content_metadata = await StoredContent.from_cid_async(db_session, content_meta.get('metadata_cid') or None) - with open(content_metadata.filepath, 'r') as f: - content_metadata_json = json.loads(f.read()) - + metadata_cid = content_meta.get('metadata_cid') if content_meta else None + if metadata_cid: try: - cover_content = await StoredContent.from_cid_async(self.db_session, content_meta.get('cover_cid') or None) - cd_log += f"Cover content: {cover_content.cid.serialize_v2()}. " + content_metadata = await StoredContent.from_cid_async(db_session, metadata_cid) + with open(content_metadata.filepath, 'r') as f: + content_metadata_json = json.loads(f.read()) except BaseException as e: - cd_log += f"Can't get cover content: {e}. " - cover_content = None - - share_target = user_existing_license.onchain_address if user_existing_license else content.cid.serialize_v2() - ref_id = (self.user.meta or {}).get('ref_id') - if not ref_id: - ref_id = self.user.ensure_ref_id() - if self.db_session: - await self.db_session.commit() + make_log("TG-Player", f"Can't get metadata content: {e}", level='warning') - _, startapp_url, web_app_url = build_content_links( - share_target, - ref_id, - project_host=PROJECT_HOST, - bot_username=CLIENT_TELEGRAM_BOT_USERNAME - ) + try: + cover_content = await StoredContent.from_cid_async(self.db_session, content_meta.get('cover_cid') if content_meta else None) + cd_log += f"Cover content: {cover_content.cid.serialize_v2()}. " + except BaseException as e: + cd_log += f"Can't get cover content: {e}. " + cover_content = None - content_share_link = { - 'text': self.user.translated('p_shareLinkContext').format(title=content_metadata_json.get('name', "")), - 'url': startapp_url, - 'web_url': web_app_url, - 'ref_id': ref_id - } + share_target = user_existing_license.onchain_address if user_existing_license else content.cid.serialize_v2() + ref_id = (self.user.meta or {}).get('ref_id') + if not ref_id: + ref_id = self.user.ensure_ref_id() + if self.db_session: + await self.db_session.commit() - if cover_content: - template_kwargs['photo'] = URLInputFile(cover_content.web_url) + _, startapp_url, web_app_url = build_content_links( + share_target, + ref_id, + project_host=PROJECT_HOST, + bot_username=CLIENT_TELEGRAM_BOT_USERNAME + ) + + content_share_link = { + 'text': self.user.translated('p_shareLinkContext').format(title=content_metadata_json.get('name', "")), + 'url': startapp_url, + 'web_url': web_app_url, + 'ref_id': ref_id + } + + if cover_content: + template_kwargs['photo'] = URLInputFile(cover_content.web_url) if not local_content: - text = self.user.translated('p_playerContext_unsupportedContent').format( - content_type=content_type, - content_encoding=content_encoding - ) - inline_keyboard_array = [] - extra_buttons = [] - else: - content_hashtags = content_metadata_json.get('description').strip() - if content_hashtags: - content_hashtags += '\n' + status_hint = self.user.translated('p_playerContext_contentNotReady') - text = f"""{content_metadata_json.get('name', 'Unnamed')} -{content_hashtags} -Этот контент был загружен в MY + description = (content_metadata_json.get('description') or '').strip() + if description: + description_block = f"{description}\n" + + title = content_metadata_json.get('name') or (local_content.filename if local_content else None) or (content.filename if content else None) or content.cid.serialize_v2() + + status_block = f"{status_hint}\n" if status_hint else "" + + text = f"""{title} +{description_block}{status_block}Этот контент был загружен в MY \t/ p2p content market / -
🔴 «открыть в MY»-
🌐 «открыть в браузере»""" +
🔴 «открыть в MY»""" make_log("TG-Player", f"Send content {content_type} ({content_encoding}) to chat {self._chat_id}. {cd_log}") kmsgs = (await self.db_session.execute(select(KnownTelegramMessage).where(