# meta developer: @trololo_1 from .. import utils, loader import re, asyncio, os from datetime import datetime default_chat = "@SaveAsBot" MODE_FORWARD = "forward" MODE_DOWNLOAD = "download" class TTsaveMod(loader.Module): """Save tiktok video""" strings = {'name': 'TTsaveMod'} async def client_ready(self, client, db): self.db = db self.default_chat = default_chat if not self.db.get('TTsaveMod', 'chat', False): self.db.set('TTsaveMod', 'chat', self.default_chat) def _send_mode(self): m = self.db.get('TTsaveMod', 'send_mode', MODE_FORWARD) return m if m in (MODE_FORWARD, MODE_DOWNLOAD) else MODE_FORWARD async def save_video(self, message, url=None): """save video from tiktok. url: ссылка; для .ttsave можно не передавать (берётся из аргументов команды).""" if url is not None: args = str(url).strip() else: args = utils.get_args_raw(message).strip() if not args: await utils.answer(message, "Нет ссылки.") return False dest = message.peer_id chat = self.db.get('TTsaveMod', 'chat') mode = self._send_mode() status_msg = await message.respond('Скачиваю...') async def erase_status(): try: await status_msg.delete() except Exception: pass try: async with message.client.conversation(chat) as conv: bot_send_link = await conv.send_message(args) response1 = await conv.get_response() response2 = await conv.get_response() # Определяем, в каком из response пришло видео video_response, other_response = None, None if hasattr(response1, "media") and response1.media is not None: if getattr(response1.media, "document", None) or getattr(response1.media, "video", None): video_response = response1 other_response = response2 if video_response is None and hasattr(response2, "media") and response2.media is not None: if getattr(response2.media, "document", None) or getattr(response2.media, "video", None): video_response = response2 other_response = response1 if video_response is None: await erase_status() await message.respond("Не удалось получить видео.") await response1.delete() await response2.delete() await bot_send_link.delete() return False if mode == MODE_FORWARD: await video_response.forward_to(dest) await response1.delete() await response2.delete() await bot_send_link.delete() await erase_status() return True now_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") filename = f"{now_time}.mp4" await video_response.download_media(filename) await response1.delete() await response2.delete() await bot_send_link.delete() await erase_status() await message.client.send_file(dest, filename) os.remove(filename) return True except Exception: await erase_status() raise async def setbotcmd(self, message): """use: .setbot чтобы установить бота для скачивания.""" args = utils.get_args_raw(message) try: bot = await message.client.get_entity(args) except: return await utils.answer(message, f"бот не найден.") self.db.set('TTsaveMod', 'bot', str(bot.id)) await utils.answer(message, f"бот {bot.username} установлен.") async def ttsendmodecmd(self, message): """.ttsendmode forward|download — пересылка с бота (по умолчанию) или скачивание и отправка. Без аргументов — текущий режим.""" raw = (utils.get_args_raw(message) or "").strip().lower() if not raw: cur = self._send_mode() tip = "пересылка с бота" if cur == MODE_FORWARD else "скачивание и отправка" return await utils.answer( message, f"Сейчас: {tip}\n.ttsendmode forward|download", ) if raw in ("forward", "пересылка", "fwd", "f"): self.db.set("TTsaveMod", "send_mode", MODE_FORWARD) return await utils.answer(message, "Режим: пересылка с бота.") if raw in ("download", "скачивание", "скачать", "dl", "d"): self.db.set("TTsaveMod", "send_mode", MODE_DOWNLOAD) return await utils.answer(message, "Режим: скачивание и отправка.") return await utils.answer(message, ".ttsendmode forward|download") async def ttsavecmd(self, message): """.ttsave {link}""" args = utils.get_args_raw(message) save_video = await self.save_video(message) if save_video: if self._send_mode() == MODE_FORWARD: await utils.answer(message, "видео переслано.") else: await utils.answer(message, "видео успешно отправлено.") else: await utils.answer(message, "не удалось скачать видео.") async def ttacceptcmd(self, message): """ .ttaccept {reply/id} для открытия в чате автоматического скачивания ссылок. без аргументов тоже работает.\n.ttaccept -l для показа открытых чатов """ args = utils.get_args_raw(message) reply = await message.get_reply_message() users_list = self.db.get('TTsaveMod', 'users', []) if args == '-l': if len(users_list) == 0: return await utils.answer(message, 'Список пуст.') return await utils.answer(message, '• '+'\n• '.join([''+str(i)+'' for i in users_list])) try: if not args and not reply: user = message.chat_id else: user = reply.sender_id if not args else int(args) except: return await utils.answer(message, 'Неверно введён ид.') if user in users_list: users_list.remove(user) await utils.answer(message, f'Ид {str(user)} исключен.') else: users_list.append(user) await utils.answer(message, f'Ид {str(user)} добавлен.') self.db.set('TTsaveMod', 'users', users_list) async def watcher(self, message): try: users = self.db.get('TTsaveMod', 'users', []) if message.chat_id not in users: return links = re.findall(r'((?:https?://)?v[mt]\.tiktok\.com/[A-Za-z0-9_]+/?)', message.raw_text) if len(links) == 0: return for link in links: await self.save_video(message, url=link) await asyncio.sleep(5) except Exception: pass