Skip to content

Commit a666619

Browse files
authored
Merge pull request #31 from karilaa-dev/feature/inline-mode
Add ability to download videos in inline mode
2 parents e0db6fa + 9874d15 commit a666619

File tree

7 files changed

+244
-137
lines changed

7 files changed

+244
-137
lines changed

data/db_service.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,11 +134,11 @@ async def get_user_settings(user_id: int) -> Optional[Tuple[str, bool]]:
134134
return None
135135

136136

137-
async def add_video(user_id: int, video_link: str, is_images: bool, is_processed: bool = False) -> None:
137+
async def add_video(user_id: int, video_link: str, is_images: bool, is_processed: bool = False, is_inline: bool = False) -> None:
138138
async with await get_session() as db:
139139
# Add the video
140140
video = Video(user_id=user_id, downloaded_at=int(datetime.now().timestamp()), video_link=video_link,
141-
is_images=is_images, is_processed=is_processed)
141+
is_images=is_images, is_processed=is_processed, is_inline=is_inline)
142142
db.add(video)
143143

144144
# Increment ad message counter

data/models/video.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ class Video(Base):
1212
video_link = Column(String, nullable=False)
1313
is_images = Column(Boolean, default=False, nullable=False)
1414
is_processed = Column(Boolean, default=False, nullable=False)
15+
is_inline = Column(Boolean, default=False, nullable=False)

handlers/get_inline.py

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
from aiogram import Router
2+
from aiogram.types import (
3+
InlineQuery,
4+
ChosenInlineResult,
5+
InlineQueryResultArticle,
6+
InputTextMessageContent,
7+
InlineKeyboardMarkup,
8+
InlineKeyboardButton,
9+
InlineQueryResultsButton
10+
)
11+
12+
import logging
13+
14+
from data.config import locale, api_alt_mode
15+
from data.loader import bot
16+
from misc.utils import lang_func
17+
from data.db_service import add_video, get_user, get_user_settings, increment_ad_msgs
18+
from misc.tiktok_api import ttapi
19+
from misc.video_types import send_video_result
20+
21+
inline_router = Router(name=__name__)
22+
23+
def please_wait_button(lang):
24+
return InlineKeyboardMarkup(
25+
inline_keyboard=[
26+
[
27+
InlineKeyboardButton(text=locale[lang]['inline_download_video_wait'], callback_data=f"wait")
28+
]
29+
]
30+
)
31+
32+
33+
@inline_router.inline_query()
34+
async def handle_inline_query(inline_query: InlineQuery):
35+
"""Handle inline queries and return example results"""
36+
api = ttapi()
37+
query_text = inline_query.query.strip()
38+
user_id = inline_query.from_user.id
39+
lang = await lang_func(user_id, inline_query.from_user.language_code)
40+
user_info = await get_user(user_id)
41+
results = []
42+
43+
if user_info is None:
44+
start_bot_button = InlineQueryResultsButton(
45+
text=locale[lang]['inline_start_bot'],
46+
start_parameter="inline")
47+
return await inline_query.answer(results, cache_time=0, button=start_bot_button, is_personal=True)
48+
49+
if len(query_text) < 12:
50+
return await inline_query.answer(results, cache_time=0)
51+
52+
video_link, is_mobile = await api.regex_check(query_text)
53+
if video_link is None:
54+
results.append(
55+
InlineQueryResultArticle(
56+
id="wrong_link",
57+
title=locale[lang]['inline_wrong_link_title'],
58+
description=locale[lang]['inline_wrong_link_description'],
59+
input_message_content=InputTextMessageContent(
60+
message_text=locale[lang]['inline_wrong_link'],
61+
parse_mode="HTML"
62+
),
63+
thumbnail_url="https://em-content.zobj.net/source/apple/419/cross-mark_274c.png"
64+
)
65+
)
66+
return await inline_query.answer(results, cache_time=0)
67+
else:
68+
results.append(
69+
InlineQueryResultArticle(
70+
id=f"download/{query_text}",
71+
title=locale[lang]['inline_download_video'],
72+
description=locale[lang]['inline_download_video_description'],
73+
input_message_content=InputTextMessageContent(
74+
message_text=locale[lang]['inline_download_video_text']
75+
),
76+
thumbnail_url="https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/png/tiktok-light.png",
77+
reply_markup=please_wait_button(lang)
78+
)
79+
)
80+
81+
82+
await inline_query.answer(results, cache_time=0)
83+
84+
85+
@inline_router.chosen_inline_result()
86+
async def handle_chosen_inline_result(chosen_result: ChosenInlineResult):
87+
"""Handle when user selects an inline result"""
88+
api = ttapi()
89+
user_id = chosen_result.from_user.id
90+
message_id = chosen_result.inline_message_id
91+
video_link = chosen_result.query
92+
settings = await get_user_settings(user_id)
93+
was_processed = False
94+
if not settings:
95+
return
96+
lang, file_mode = settings
97+
98+
try:
99+
if api_alt_mode:
100+
video_info = await api.rapid_video(video_link)
101+
else:
102+
video_info = await api.video(video_link)
103+
104+
if video_info is False:
105+
return await bot.edit_message_text(inline_message_id=message_id, text=locale[lang]['bugged_error'])
106+
elif video_info is None:
107+
return await bot.edit_message_text(inline_message_id=message_id, text=locale[lang]['error'])
108+
109+
if video_info['type'] == 'images': # Process image
110+
return await bot.edit_message_text(inline_message_id=message_id, text=locale[lang]['only_video_supported'])
111+
# await bot.edit_message_text(inline_message_id=message_id, text="⬆️ <code>Sending image...</code>\n\n")
112+
# try:
113+
# was_processed = await send_image_result(message_id, video_info, lang, file_mode, 1)
114+
# except:
115+
# await bot.edit_message_text(inline_message_id=message_id, text=locale[lang]['error'])
116+
else: # Process video
117+
await bot.edit_message_text(inline_message_id=message_id, text=locale[lang]['sending_inline_video'])
118+
# try:
119+
await send_video_result(message_id, video_info, lang, file_mode, api_alt_mode, True)
120+
# except:
121+
# return await bot.edit_message_text(inline_message_id=message_id, text=locale[lang]['error'])
122+
123+
await increment_ad_msgs(user_id)
124+
125+
try: # Try to write log into database
126+
# Write log into database
127+
await add_video(user_id, video_link, video_info['type'] == 'images', was_processed, True)
128+
# Log into console
129+
logging.info(f'Video Download: INLINE {user_id} - VIDEO {video_link}')
130+
# If cant write log into database or log into console
131+
except Exception as e:
132+
logging.error('Cant write into database')
133+
logging.error(e)
134+
except Exception as e: # If something went wrong
135+
logging.error(e)
136+
try:
137+
await bot.edit_message_text(inline_message_id=message_id, text=locale[lang]['error'])
138+
except:
139+
pass

handlers/get_video.py

Lines changed: 2 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from misc.adsgram import show_ad
1010
from misc.tiktok_api import ttapi
1111
from misc.utils import start_manager, error_catch, lang_func
12-
from misc.video_types import send_video_result, send_image_result, image_ask_button
12+
from misc.video_types import send_video_result, send_image_result
1313

1414
video_router = Router(name=__name__)
1515

@@ -71,10 +71,6 @@ async def send_tiktok_video(message: Message):
7171
except:
7272
pass
7373
if video_info['type'] == 'images': # Process images, if video is images
74-
if len(video_info['data']) > 50: # If images are more than 50, propose to download only last 10
75-
await message.reply(locale[lang]['to_much_images_warning'].format(video_link),
76-
reply_markup=image_ask_button(video_id, lang))
77-
return await message.react([])
7874
# Send upload image action
7975
await bot.send_chat_action(chat_id=message.chat.id, action='upload_photo')
8076
if group_chat:
@@ -87,7 +83,7 @@ async def send_tiktok_video(message: Message):
8783
await bot.send_chat_action(chat_id=message.chat.id, action='upload_video')
8884
# Send video
8985
try:
90-
await send_video_result(message, video_info, lang, file_mode, api_alt_mode)
86+
await send_video_result(message.chat.id, video_info, lang, file_mode, api_alt_mode, reply_to_message_id=message.message_id)
9187
except:
9288
if not group_chat:
9389
await message.reply(locale[lang]['error'])
@@ -135,87 +131,3 @@ async def send_tiktok_video(message: Message):
135131
await message.react([])
136132
except:
137133
pass
138-
139-
140-
@video_router.callback_query(F.data.startswith('images/'))
141-
async def send_images_custon(callback_query: CallbackQuery):
142-
# Api init
143-
api = ttapi()
144-
# Statys message var
145-
status_message = False
146-
# Get callback data
147-
data = callback_query.data.split('/')
148-
download_mode = data[1]
149-
video_id = int(data[2])
150-
# Get message info
151-
call_msg = callback_query.message
152-
group_chat = call_msg.chat.type != 'private'
153-
chat_id = call_msg.chat.id
154-
# Get chat db info
155-
settings = await get_user_settings(chat_id)
156-
if not settings:
157-
return
158-
lang, file_mode = settings
159-
# Remove buttons
160-
await call_msg.edit_reply_markup()
161-
try: # If reaction is allowed, send it
162-
await call_msg.react([ReactionTypeEmoji(emoji='👀')], disable_notification=True)
163-
except:
164-
status_message = await call_msg.reply('⏳', disable_notification=True)
165-
try:
166-
# Get video info
167-
video_info = await api.video(video_id)
168-
if video_info in [None, False]: # Return error if info is bad
169-
if not group_chat: # Send error message, if not group chat
170-
if video_info is False: # If api doesn't return info about video
171-
await call_msg.reply(locale[lang]['bugged_error_mobile'])
172-
else: # If something went wrong
173-
await call_msg.reply(locale[lang]['error'])
174-
elif video_info is False: # If api doesn't return info about video
175-
await call_msg.reply_markup(reply_markup=image_ask_button(video_id, lang))
176-
return
177-
# Send upload action
178-
await bot.send_chat_action(chat_id=chat_id, action='upload_photo')
179-
if not group_chat: # Send reaction if not group chat
180-
await call_msg.react([ReactionTypeEmoji(emoji='👨‍💻')], disable_notification=True)
181-
image_limit = None
182-
else:
183-
image_limit = 10
184-
# Generate link
185-
link = f'https://www.tiktok.com/@{video_info["author"]}/video/{video_info["id"]}'
186-
# Set the link in video_info for the result_caption function
187-
video_info['link'] = link
188-
if download_mode == 'last10': # Check download mode
189-
video_info['data'] = video_info['data'][-10:]
190-
# Send images
191-
was_processed = await send_image_result(call_msg, video_info, lang, file_mode, image_limit)
192-
if status_message:
193-
await status_message.delete()
194-
else:
195-
await call_msg.react([])
196-
try: # Try to write log into database
197-
# Write log into database
198-
await add_video(chat_id, link, video_info['type'] == 'images', was_processed)
199-
# Log into console
200-
logging.info(f'Video Download: CHAT {chat_id} - VIDEO {link}')
201-
# If cant write log into database or log into console
202-
except Exception as e:
203-
logging.error('Cant write into database')
204-
logging.error(e)
205-
except Exception as e: # If something went wrong
206-
error_text = error_catch(e)
207-
logging.error(error_text)
208-
if chat_id in second_ids:
209-
await call_msg.reply('<code>{0}</code>'.format(error_text))
210-
try:
211-
if status_message: # Remove status message if it exists
212-
await status_message.delete()
213-
if not group_chat:
214-
await call_msg.reply(locale[lang]['error'])
215-
if not status_message:
216-
await call_msg.react([ReactionTypeEmoji(emoji='😢')])
217-
else:
218-
if not status_message:
219-
await call_msg.react([])
220-
except:
221-
pass

0 commit comments

Comments
 (0)