stars
This commit is contained in:
parent
8647352d0f
commit
758defee99
|
|
@ -7,6 +7,7 @@ from aiogram import types, Router
|
||||||
from app.client_bot.routers.home import router as home_router
|
from app.client_bot.routers.home import router as home_router
|
||||||
from app.client_bot.routers.tonconnect import router as tonconnect_router
|
from app.client_bot.routers.tonconnect import router as tonconnect_router
|
||||||
from app.client_bot.routers.content import router as content_router
|
from app.client_bot.routers.content import router as content_router
|
||||||
|
from app.client_bot.routers.stars import router as stars_router
|
||||||
|
|
||||||
from app.core.logger import logger
|
from app.core.logger import logger
|
||||||
|
|
||||||
|
|
@ -14,6 +15,7 @@ main_router = Router()
|
||||||
main_router.include_routers(home_router)
|
main_router.include_routers(home_router)
|
||||||
main_router.include_routers(tonconnect_router)
|
main_router.include_routers(tonconnect_router)
|
||||||
main_router.include_routers(content_router)
|
main_router.include_routers(content_router)
|
||||||
|
main_router.include_routers(stars_router)
|
||||||
|
|
||||||
closing_router = Router()
|
closing_router = Router()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
from aiogram import types, Router, F
|
||||||
|
from app.core.logger import make_log
|
||||||
|
from app.core.models import StarsInvoice
|
||||||
|
|
||||||
|
router = Router()
|
||||||
|
|
||||||
|
|
||||||
|
async def t_pre_checkout_query_stars_processing(pre_checkout_query: types.PreCheckoutQuery, user=None, db_session=None,
|
||||||
|
chat_wrap=None, **extra):
|
||||||
|
invoice_id = pre_checkout_query.invoice_payload
|
||||||
|
|
||||||
|
existing_invoice = db_session.query(StarsInvoice).filter(
|
||||||
|
StarsInvoice.external_id == invoice_id
|
||||||
|
).first()
|
||||||
|
if not existing_invoice:
|
||||||
|
return await pre_checkout_query.answer(ok=False, error_message="Invoice not found")
|
||||||
|
|
||||||
|
if existing_invoice.paid:
|
||||||
|
return await pre_checkout_query.answer(ok=False, error_message="Invoice already paid")
|
||||||
|
|
||||||
|
return await pre_checkout_query.answer(ok=True)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
router.pre_checkout_query.register(t_pre_checkout_query_stars_processing)
|
||||||
|
|
@ -11,7 +11,7 @@ from app.core._blockchain.ton.platform import platform
|
||||||
from app.core._blockchain.ton.toncenter import toncenter
|
from app.core._blockchain.ton.toncenter import toncenter
|
||||||
from app.core._utils.send_status import send_status
|
from app.core._utils.send_status import send_status
|
||||||
from app.core.logger import make_log
|
from app.core.logger import make_log
|
||||||
from app.core.models import UserContent
|
from app.core.models import UserContent, KnownTelegramMessage
|
||||||
from app.core.models.node_storage import StoredContent
|
from app.core.models.node_storage import StoredContent
|
||||||
from app.core._utils.resolve_content import resolve_content
|
from app.core._utils.resolve_content import resolve_content
|
||||||
from app.core.models.wallet_connection import WalletConnection
|
from app.core.models.wallet_connection import WalletConnection
|
||||||
|
|
@ -212,6 +212,16 @@ async def indexer_loop(memory, platform_found: bool, seqno: int) -> [bool, int]:
|
||||||
}]
|
}]
|
||||||
])
|
])
|
||||||
)
|
)
|
||||||
|
|
||||||
|
user_uploader_wrapper = Wrapped_CBotChat(memory._telegram_bot, chat_id=user.telegram_id, user=user, db_session=session)
|
||||||
|
for hint_message in session.query(KnownTelegramMessage).filter(
|
||||||
|
and_(
|
||||||
|
KnownTelegramMessage.user_id == user.id,
|
||||||
|
KnownTelegramMessage.message_type == 'hint',
|
||||||
|
KnownTelegramMessage.meta.contains({'encrypted_content_hash': encrypted_stored_content.hash})
|
||||||
|
)
|
||||||
|
):
|
||||||
|
await user_uploader_wrapper.delete_message(hint_message.message_id)
|
||||||
elif encrypted_stored_content.type.startswith('onchain') and encrypted_stored_content.onchain_index == item_index:
|
elif encrypted_stored_content.type.startswith('onchain') and encrypted_stored_content.onchain_index == item_index:
|
||||||
encrypted_stored_content.type = "onchain/content" + ("_unknown" if (encrypted_stored_content.key_id is None) else "")
|
encrypted_stored_content.type = "onchain/content" + ("_unknown" if (encrypted_stored_content.key_id is None) else "")
|
||||||
encrypted_stored_content.owner_address = item_owner_address.to_string(1, 1, 1)
|
encrypted_stored_content.owner_address = item_owner_address.to_string(1, 1, 1)
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ from app.core.models._telegram import Wrapped_CBotChat
|
||||||
from app.core.storage import db_session
|
from app.core.storage import db_session
|
||||||
from app.core._config import CLIENT_TELEGRAM_API_KEY
|
from app.core._config import CLIENT_TELEGRAM_API_KEY
|
||||||
from app.core.models.user import User
|
from app.core.models.user import User
|
||||||
|
from app.core.models import StarsInvoice
|
||||||
import os
|
import os
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
|
|
@ -27,6 +28,51 @@ import traceback
|
||||||
async def license_index_loop(memory, platform_found: bool, seqno: int) -> [bool, int]:
|
async def license_index_loop(memory, platform_found: bool, seqno: int) -> [bool, int]:
|
||||||
make_log("LicenseIndex", "Service running", level="debug")
|
make_log("LicenseIndex", "Service running", level="debug")
|
||||||
with db_session() as session:
|
with db_session() as session:
|
||||||
|
async def check_telegram_stars_transactions():
|
||||||
|
# Проверка звездных telegram транзакций, обновление paid
|
||||||
|
offset = {'desc': 'Статичное число заранее известного количества транзакций, которое даже не знает наш бот', 'value': 1}['value'] + \
|
||||||
|
session.query(StarsInvoice).count()
|
||||||
|
limit = 100
|
||||||
|
while True:
|
||||||
|
make_log("StarsProcessing", f"Star payments: offset={offset}, limit={limit}", level="DEBUG")
|
||||||
|
star_payments = (await memory._client_telegram_bot.get_star_transactions(offset, limit)).transactions
|
||||||
|
if not star_payments:
|
||||||
|
make_log("StarsProcessing", "No more star payments", level="DEBUG")
|
||||||
|
return
|
||||||
|
|
||||||
|
for star_payment in star_payments:
|
||||||
|
if star_payment.receiver:
|
||||||
|
continue
|
||||||
|
|
||||||
|
try:
|
||||||
|
existing_invoice = session.query(StarsInvoice).filter(
|
||||||
|
StarsInvoice.external_id == star_payment.source.invoice_payload
|
||||||
|
).first()
|
||||||
|
if not existing_invoice:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if star_payment.amount == existing_invoice.amount:
|
||||||
|
if not existing_invoice.paid:
|
||||||
|
existing_invoice.paid = True
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
licensed_content = session.query(StoredContent).filter(StoredContent.hash == existing_invoice.content_hash).first()
|
||||||
|
user = session.query(User).filter(User.id == existing_invoice.user_id).first()
|
||||||
|
|
||||||
|
await (Wrapped_CBotChat(memory._client_telegram_bot, chat_id=user.telegram_id, user=user, db_session=session)).send_content(
|
||||||
|
session, licensed_content
|
||||||
|
)
|
||||||
|
except BaseException as e:
|
||||||
|
make_log("StarsProcessing", f"Local error: {e}" + '\n' + traceback.format_exc(), level="error")
|
||||||
|
|
||||||
|
offset += limit
|
||||||
|
|
||||||
|
try:
|
||||||
|
await check_telegram_stars_transactions()
|
||||||
|
except BaseException as e:
|
||||||
|
make_log("StarsProcessing", f"Error: {e}" + '\n' + traceback.format_exc(), level="error")
|
||||||
|
|
||||||
|
# Проверка кошельков пользователей на появление новых NFT, добавление их в базу как неопознанные
|
||||||
for user in session.query(User).filter(
|
for user in session.query(User).filter(
|
||||||
User.last_use > datetime.now() - timedelta(minutes=10)
|
User.last_use > datetime.now() - timedelta(minutes=10)
|
||||||
).all():
|
).all():
|
||||||
|
|
@ -47,6 +93,7 @@ async def license_index_loop(memory, platform_found: bool, seqno: int) -> [bool,
|
||||||
except BaseException as e:
|
except BaseException as e:
|
||||||
make_log("LicenseIndex", f"Error: {e}" + '\n' + traceback.format_exc(), level="error")
|
make_log("LicenseIndex", f"Error: {e}" + '\n' + traceback.format_exc(), level="error")
|
||||||
|
|
||||||
|
# Проверка NFT на актуальность данных, в том числе уже проверенные
|
||||||
process_content = session.query(UserContent).filter(
|
process_content = session.query(UserContent).filter(
|
||||||
and_(
|
and_(
|
||||||
UserContent.type.startswith('nft/'),
|
UserContent.type.startswith('nft/'),
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
from sqlalchemy import and_
|
||||||
from app.core.models.node_storage import StoredContent
|
from app.core.models.node_storage import StoredContent
|
||||||
from app.core.models.content.user_content import UserContent, UserAction
|
from app.core.models.content.user_content import UserContent, UserAction
|
||||||
from app.core.logger import make_log
|
from app.core.logger import make_log
|
||||||
|
|
@ -7,6 +8,9 @@ from app.core._keyboards import get_inline_keyboard
|
||||||
from app.core.models.messages import KnownTelegramMessage
|
from app.core.models.messages import KnownTelegramMessage
|
||||||
from aiogram.types import URLInputFile, Message
|
from aiogram.types import URLInputFile, Message
|
||||||
import json
|
import json
|
||||||
|
import urllib
|
||||||
|
|
||||||
|
from app.core.models.transaction import StarsInvoice
|
||||||
|
|
||||||
|
|
||||||
class PlayerTemplates:
|
class PlayerTemplates:
|
||||||
|
|
@ -55,8 +59,25 @@ class PlayerTemplates:
|
||||||
local_content.meta['cover_cid'] = cover_content.cid.serialize_v2() if cover_content else None
|
local_content.meta['cover_cid'] = cover_content.cid.serialize_v2() if cover_content else None
|
||||||
|
|
||||||
local_content_cid = local_content.cid
|
local_content_cid = local_content.cid
|
||||||
local_content_cid.content_type = 'audio/mpeg'
|
local_content_url = f"{PROJECT_HOST}/api/v1.5/storage/{local_content_cid.serialize_v2()}"
|
||||||
local_content_url = f"{PROJECT_HOST}/api/v1/storage/{local_content_cid.serialize_v2(include_accept_type=True)}"
|
converted_content = content.meta.get('converted_content')
|
||||||
|
if not converted_content:
|
||||||
|
r = await tg_process_template(
|
||||||
|
self, self.user.translated('p_playerContext_contentNotReady'),
|
||||||
|
message_id=message_id,
|
||||||
|
message_type='common'
|
||||||
|
)
|
||||||
|
return r
|
||||||
|
|
||||||
|
content_share_link = {
|
||||||
|
'text': self.user.translated('p_shareLinkContext').format(title=content_metadata_json.get('name', "")),
|
||||||
|
'url': f"https://t.me/{CLIENT_TELEGRAM_BOT_USERNAME}?start=C{content.cid.serialize_v2()}"
|
||||||
|
}
|
||||||
|
|
||||||
|
preview_content = db_session.query(StoredContent).filter(
|
||||||
|
StoredContent.hash == converted_content['low_preview']
|
||||||
|
).first()
|
||||||
|
local_content_preview_url = preview_content.web_url
|
||||||
if content_type == 'audio':
|
if content_type == 'audio':
|
||||||
audio_title = content_metadata_json.get('name', "").split(' - ')
|
audio_title = content_metadata_json.get('name', "").split(' - ')
|
||||||
if len(audio_title) > 1:
|
if len(audio_title) > 1:
|
||||||
|
|
@ -65,15 +86,21 @@ class PlayerTemplates:
|
||||||
|
|
||||||
template_kwargs['title'] = audio_title[0].strip()
|
template_kwargs['title'] = audio_title[0].strip()
|
||||||
template_kwargs['protect_content'] = True
|
template_kwargs['protect_content'] = True
|
||||||
template_kwargs['audio'] = URLInputFile(local_content_url)
|
template_kwargs['audio'] = URLInputFile(local_content_preview_url)
|
||||||
if cover_content:
|
if cover_content:
|
||||||
template_kwargs['thumbnail'] = URLInputFile(cover_content.web_url)
|
template_kwargs['thumbnail'] = URLInputFile(cover_content.web_url)
|
||||||
|
|
||||||
if self.bot_id == 1:
|
if self.bot_id == 1:
|
||||||
inline_keyboard_array.append([{
|
inline_keyboard_array.append([
|
||||||
'text': self.user.translated('shareTrack_button'),
|
{
|
||||||
'switch_inline_query': f"C{content.cid.serialize_v2()}",
|
'text': self.user.translated('shareTrack_button'),
|
||||||
}])
|
'switch_inline_query': f"C{content.cid.serialize_v2()}",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'text': self.user.translated('shareLink_button'),
|
||||||
|
'url': f"https://t.me/share/url?text={urllib.parse.quote(content_share_link['text'])}&url={urllib.parse.quote(content_share_link['url'])}"
|
||||||
|
}
|
||||||
|
])
|
||||||
inline_keyboard_array.append([{
|
inline_keyboard_array.append([{
|
||||||
'text': self.user.translated('openTrackInApp_button'),
|
'text': self.user.translated('openTrackInApp_button'),
|
||||||
'url': f"https://t.me/{CLIENT_TELEGRAM_BOT_USERNAME}/content?startapp={content.cid.serialize_v2()}"
|
'url': f"https://t.me/{CLIENT_TELEGRAM_BOT_USERNAME}/content?startapp={content.cid.serialize_v2()}"
|
||||||
|
|
@ -90,7 +117,7 @@ class PlayerTemplates:
|
||||||
elif content_type == 'video':
|
elif content_type == 'video':
|
||||||
# Processing video
|
# Processing video
|
||||||
video_title = content_metadata_json.get('name', "")
|
video_title = content_metadata_json.get('name', "")
|
||||||
template_kwargs['video'] = URLInputFile(local_content_url)
|
template_kwargs['video'] = URLInputFile(local_content_preview_url)
|
||||||
template_kwargs['protect_content'] = True
|
template_kwargs['protect_content'] = True
|
||||||
|
|
||||||
if cover_content:
|
if cover_content:
|
||||||
|
|
@ -99,10 +126,16 @@ class PlayerTemplates:
|
||||||
|
|
||||||
if self.bot_id == 1:
|
if self.bot_id == 1:
|
||||||
# Buttons for sharing and opening in app
|
# Buttons for sharing and opening in app
|
||||||
inline_keyboard_array.append([{
|
inline_keyboard_array.append([
|
||||||
'text': self.user.translated('shareVideo_button'),
|
{
|
||||||
'switch_inline_query': f"C{content.cid.serialize_v2()}",
|
'text': self.user.translated('shareVideo_button'),
|
||||||
}])
|
'switch_inline_query': f"C{content.cid.serialize_v2()}",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'text': self.user.translated('shareLink_button'),
|
||||||
|
'url': f"https://t.me/share/url?text={urllib.parse.quote(content_share_link['text'])}&url={urllib.parse.quote(content_share_link['url'])}"
|
||||||
|
}
|
||||||
|
])
|
||||||
inline_keyboard_array.append([{
|
inline_keyboard_array.append([{
|
||||||
'text': self.user.translated('openTrackInApp_button'),
|
'text': self.user.translated('openTrackInApp_button'),
|
||||||
'url': f"https://t.me/{CLIENT_TELEGRAM_BOT_USERNAME}/content?startapp={content.cid.serialize_v2()}"
|
'url': f"https://t.me/{CLIENT_TELEGRAM_BOT_USERNAME}/content?startapp={content.cid.serialize_v2()}"
|
||||||
|
|
@ -134,14 +167,24 @@ class PlayerTemplates:
|
||||||
have_access = (
|
have_access = (
|
||||||
(content.owner_address == user_wallet_address)
|
(content.owner_address == user_wallet_address)
|
||||||
or bool(self.db_session.query(UserContent).filter_by(owner_address=user_wallet_address, status='active', content_id=content.id).first())
|
or bool(self.db_session.query(UserContent).filter_by(owner_address=user_wallet_address, status='active', content_id=content.id).first())
|
||||||
|
or bool(self.db_session.query(UserContent).filter(
|
||||||
|
and_(
|
||||||
|
StarsInvoice.user_id == self.user,
|
||||||
|
StarsInvoice.content_hash == content['encrypted_content'].hash,
|
||||||
|
StarsInvoice.paid == True
|
||||||
|
)
|
||||||
|
))
|
||||||
)
|
)
|
||||||
if not have_access:
|
if have_access:
|
||||||
|
full_content = self.db_session.query(StoredContent).filter_by(
|
||||||
|
hash=content.meta.get('converted_content', {}).get('low') # TODO: support high quality
|
||||||
|
).first()
|
||||||
if content_type == 'audio':
|
if content_type == 'audio':
|
||||||
# Restrict audio to 30 seconds if user does not have access
|
# Restrict audio to 30 seconds if user does not have access
|
||||||
template_kwargs['audio'] = URLInputFile(local_content_url + '?seconds_limit=30')
|
template_kwargs['audio'] = URLInputFile(full_content.web_url)
|
||||||
elif content_type == 'video':
|
elif content_type == 'video':
|
||||||
# Restrict video to 30 seconds if user does not have access
|
# Restrict video to 30 seconds if user does not have access
|
||||||
template_kwargs['video'] = URLInputFile(local_content_url + '?seconds_limit=30')
|
template_kwargs['video'] = URLInputFile(full_content.web_url)
|
||||||
|
|
||||||
make_log("TG-Player", f"Send content {content_type} ({content_encoding}) to chat {self._chat_id}. {cd_log}")
|
make_log("TG-Player", f"Send content {content_type} ({content_encoding}) to chat {self._chat_id}. {cd_log}")
|
||||||
for kmsg in self.db_session.query(KnownTelegramMessage).filter_by(
|
for kmsg in self.db_session.query(KnownTelegramMessage).filter_by(
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -21,21 +21,21 @@ msgstr ""
|
||||||
#: app/client_bot/routers/home.py:15 app/client_bot/routers/home.py:17
|
#: app/client_bot/routers/home.py:15 app/client_bot/routers/home.py:17
|
||||||
msgid "home_menu"
|
msgid "home_menu"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Hi, <b>{name}</b>!\n"
|
"Hi, <b>{name}</b>! 😊\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Here you can upload your content to the blockchain and manage it.\n"
|
"Here you can upload your content to the blockchain and manage it 🚀.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"You logged as <code>{wallet_address}</code>"
|
"You're logged in as <code>{wallet_address}</code>"
|
||||||
|
|
||||||
#: app/bot/routers/home.py:20 app/client_bot/routers/home.py:20
|
#: app/bot/routers/home.py:20 app/client_bot/routers/home.py:20
|
||||||
#: app/client_bot/routers/home.py:22
|
#: app/client_bot/routers/home.py:22
|
||||||
msgid "ownedContent_button"
|
msgid "ownedContent_button"
|
||||||
msgstr "📊 My content"
|
msgstr "📊 My Content"
|
||||||
|
|
||||||
#: app/bot/routers/home.py:24 app/client_bot/routers/home.py:24
|
#: app/bot/routers/home.py:24 app/client_bot/routers/home.py:24
|
||||||
#: app/client_bot/routers/home.py:26
|
#: app/client_bot/routers/home.py:26
|
||||||
msgid "disconnectWallet_button"
|
msgid "disconnectWallet_button"
|
||||||
msgstr "🔌 Disconnect wallet"
|
msgstr "🔌 Disconnect Wallet"
|
||||||
|
|
||||||
#: app/bot/routers/home.py:35 app/client_bot/routers/home.py:35
|
#: app/bot/routers/home.py:35 app/client_bot/routers/home.py:35
|
||||||
#: app/client_bot/routers/home.py:37
|
#: app/client_bot/routers/home.py:37
|
||||||
|
|
@ -43,25 +43,25 @@ msgid "connectWalletsList_menu"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"<b>/</b> Welcome to MY [🔴]\n"
|
"<b>/</b> Welcome to MY [🔴]\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Please select the wallet you want to connect to the bot:"
|
"Please select the wallet you want to connect to the bot 😊:"
|
||||||
|
|
||||||
#: app/bot/routers/index.py:23 app/bot/routers/index.py:22
|
#: app/bot/routers/index.py:23 app/bot/routers/index.py:22
|
||||||
#: app/client_bot/routers/index.py:18 app/client_bot/routers/index.py:23
|
#: app/client_bot/routers/index.py:18 app/client_bot/routers/index.py:23
|
||||||
msgid "error_unknownCommand"
|
msgid "error_unknownCommand"
|
||||||
msgstr "Unknown command, please try again or press /start"
|
msgstr "❌ Unknown command, please try again or press /start"
|
||||||
|
|
||||||
#: app/bot/routers/content.py:16 app/bot/routers/content.py:12
|
#: app/bot/routers/content.py:16 app/bot/routers/content.py:12
|
||||||
#: app/bot/routers/content.py:21
|
#: app/bot/routers/content.py:21
|
||||||
msgid "ownedContent_menu"
|
msgid "ownedContent_menu"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"📊 <b>My content</b>\n"
|
"📊 <b>My Content</b>\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Here you can see the list of your content."
|
"Here you can view the list of your content 📋."
|
||||||
|
|
||||||
#: app/bot/routers/content.py:21 app/bot/routers/content.py:17
|
#: app/bot/routers/content.py:21 app/bot/routers/content.py:17
|
||||||
#: app/bot/routers/content.py:47
|
#: app/bot/routers/content.py:47
|
||||||
msgid "webApp_uploadContent_button"
|
msgid "webApp_uploadContent_button"
|
||||||
msgstr "📤 Upload content"
|
msgstr "📤 Upload Content"
|
||||||
|
|
||||||
#: app/bot/routers/content.py:27 app/bot/routers/content.py:23
|
#: app/bot/routers/content.py:27 app/bot/routers/content.py:23
|
||||||
#: app/bot/routers/content.py:53 app/bot/routers/content.py:68
|
#: app/bot/routers/content.py:53 app/bot/routers/content.py:68
|
||||||
|
|
@ -88,7 +88,7 @@ msgstr ""
|
||||||
#: app/core/models/_telegram/templates/player.py:108
|
#: app/core/models/_telegram/templates/player.py:108
|
||||||
#: app/api/routes/_blockchain.py:145
|
#: app/api/routes/_blockchain.py:145
|
||||||
msgid "gotoWallet_button"
|
msgid "gotoWallet_button"
|
||||||
msgstr "Open wallet"
|
msgstr "🔓 Open Wallet"
|
||||||
|
|
||||||
#: app/api/routes/_blockchain.py:150 app/bot/routers/tonconnect.py:90
|
#: app/api/routes/_blockchain.py:150 app/bot/routers/tonconnect.py:90
|
||||||
#: app/core/background/indexer_service.py:141 app/bot/routers/tonconnect.py:92
|
#: app/core/background/indexer_service.py:141 app/bot/routers/tonconnect.py:92
|
||||||
|
|
@ -99,78 +99,82 @@ msgstr "◀️ Back"
|
||||||
|
|
||||||
#: app/bot/routers/tonconnect.py:86 app/client_bot/routers/tonconnect.py:88
|
#: app/bot/routers/tonconnect.py:86 app/client_bot/routers/tonconnect.py:88
|
||||||
msgid "tonconnectOpenWallet_button"
|
msgid "tonconnectOpenWallet_button"
|
||||||
msgstr "[Connect wallet]"
|
msgstr "[Connect Wallet]"
|
||||||
|
|
||||||
#: app/core/background/indexer_service.py:134
|
#: app/core/background/indexer_service.py:134
|
||||||
#: app/core/background/indexer_service.py:149
|
#: app/core/background/indexer_service.py:149
|
||||||
msgid "p_contentWasIndexed"
|
msgid "p_contentWasIndexed"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"🎉 <b>Your new content was uploaded successfully!</b>\n"
|
"🎉 <b>Your new content has been uploaded successfully!</b>\n"
|
||||||
"\n"
|
"\n"
|
||||||
"🔗 <a href=\"https://tonviewer.com/{item_address}\">{item_address}</a> on "
|
"🔗 <a href=\"https://tonviewer.com/{item_address}\">{item_address}</a> on the blockchain\n"
|
||||||
"the blockchain\n"
|
|
||||||
"\n"
|
"\n"
|
||||||
"Now you can manage it in <b>My content</b> section"
|
"Now you can manage it in the <b>My Content</b> section"
|
||||||
|
|
||||||
#: app/core/models/_telegram/templates/player.py:74
|
#: app/core/models/_telegram/templates/player.py:74
|
||||||
#: app/client_bot/routers/content.py:129
|
#: app/client_bot/routers/content.py:129
|
||||||
msgid "shareTrack_button"
|
msgid "shareTrack_button"
|
||||||
msgstr "Share track"
|
msgstr "🎶 Share Track"
|
||||||
|
|
||||||
msgid "shareVideo_button"
|
msgid "shareVideo_button"
|
||||||
msgstr "Share video"
|
msgstr "🎬 Share Video"
|
||||||
|
|
||||||
#: app/core/models/_telegram/templates/player.py:79
|
#: app/core/models/_telegram/templates/player.py:79
|
||||||
msgid "viewTrackAsClient_button"
|
msgid "viewTrackAsClient_button"
|
||||||
msgstr "Open in player"
|
msgstr "▶️ Open in Player"
|
||||||
|
|
||||||
#: app/core/models/_telegram/templates/player.py:86
|
#: app/core/models/_telegram/templates/player.py:86
|
||||||
msgid "p_playerContext_unsupportedContent"
|
msgid "p_playerContext_unsupportedContent"
|
||||||
msgstr "⚠️ <b>Unsupported content</b>"
|
msgstr "⚠️ <b>Unsupported Content</b>"
|
||||||
|
|
||||||
#: app/core/models/_telegram/templates/player.py:111
|
#: app/core/models/_telegram/templates/player.py:111
|
||||||
msgid "p_playerContext_purchaseRequested"
|
msgid "p_playerContext_purchaseRequested"
|
||||||
msgstr "Confirm the purchase in your wallet. After that, you will be able to "
|
msgstr "💳 Please confirm the purchase in your wallet. After that, you'll be able to listen to the full version of the track.\n\n"
|
||||||
"listen to the full track version.\n\n"
|
"<b>This may take a few minutes ⏳</b>"
|
||||||
"<b>This can take up to few minutes</b>"
|
|
||||||
|
|
||||||
#: app/core/models/_telegram/templates/player.py:114
|
#: app/core/models/_telegram/templates/player.py:114
|
||||||
msgid "buyTrackListenLicense_button"
|
msgid "buyTrackListenLicense_button"
|
||||||
msgstr "Buy license ({price} TON)"
|
msgstr "💶 Buy License ({price} TON)"
|
||||||
|
|
||||||
#: app/core/models/_telegram/templates/player.py:117
|
#: app/core/models/_telegram/templates/player.py:117
|
||||||
msgid "p_playerContext_preview"
|
msgid "p_playerContext_preview"
|
||||||
msgstr "<i>It's a preview version of the track. To listen to the full version, "
|
msgstr "<i>This is a preview version of the track. To listen to the full version, you need to buy a license 🎧.</i>"
|
||||||
"you need to buy a license.</i>"
|
|
||||||
|
|
||||||
#: app/client_bot/routers/content.py:32
|
#: app/client_bot/routers/content.py:32
|
||||||
msgid "error_contentNotFound"
|
msgid "error_contentNotFound"
|
||||||
msgstr "Error: content not found"
|
msgstr "❗ Error: Content not found"
|
||||||
|
|
||||||
#: app/client_bot/routers/content.py:37
|
#: app/client_bot/routers/content.py:37
|
||||||
msgid "error_contentPrice"
|
msgid "error_contentPrice"
|
||||||
msgstr "Error: content price is not set"
|
msgstr "❗ Error: Content price is not set"
|
||||||
|
|
||||||
#: app/client_bot/routers/content.py:133
|
#: app/client_bot/routers/content.py:133
|
||||||
msgid "viewTrack_button"
|
msgid "viewTrack_button"
|
||||||
msgstr "Open in mini-app"
|
msgstr "▶️ Open in Mini-App"
|
||||||
|
|
||||||
#: app/client_bot/routers/content.py:138
|
#: app/client_bot/routers/content.py:138
|
||||||
msgid "cancelPurchase_button"
|
msgid "cancelPurchase_button"
|
||||||
msgstr "Cancel purchase"
|
msgstr "❌ Cancel Purchase"
|
||||||
|
|
||||||
msgid "openContractPage_button"
|
msgid "openContractPage_button"
|
||||||
msgstr "Open smartcontract"
|
msgstr "🔗 Open Smart Contract"
|
||||||
|
|
||||||
msgid "noWalletConnected"
|
msgid "noWalletConnected"
|
||||||
msgstr "No wallet connected"
|
msgstr "❗ No wallet connected"
|
||||||
|
|
||||||
msgid "openTrackInApp_button"
|
msgid "openTrackInApp_button"
|
||||||
msgstr "Open in app"
|
msgstr "📱 Open in App"
|
||||||
|
|
||||||
msgid "p_licenseWasBought"
|
msgid "p_licenseWasBought"
|
||||||
msgstr "💶 {username} just purchased a <a href={nft_address}>license</a> for <b>{content_title}</b>. "
|
msgstr ""
|
||||||
"👏 Your content is gaining more appreciation! Keep creating and inspiring! 🚀"
|
"💶 {username} just purchased a <a href={nft_address}>license</a> for <b>{content_title}</b>. 👏\n"
|
||||||
|
"Your content is gaining popularity! Keep creating and inspiring 🚀."
|
||||||
|
|
||||||
msgid "p_uploadContentTxRequested"
|
msgid "p_uploadContentTxRequested"
|
||||||
msgstr "Transaction for upload {title} requested. Confirm that and wait notification of transaction result. Convert content may be 20 min"
|
msgstr "⏳ Transaction for uploading {title} has been requested. Please confirm the transaction and wait for the notification. Content conversion may take up to 20 minutes."
|
||||||
|
|
||||||
|
msgid "shareLink_button"
|
||||||
|
msgstr "🔗 Share Link"
|
||||||
|
|
||||||
|
msgid "p_shareLinkContext"
|
||||||
|
msgstr "🎉 Enjoy {title} on MY!"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue