def load_module(app, msg): doc = msg.reply_to_message.document chars = "abcdefghijklmnopqrstuvwxyz" try: name = msg.text.split(maxsplit=1)[1] name = name.replace(" ", "_") except: name = "" for i in range(7): name += random.choice(chars) if doc: if doc.mime_type == "text/x-python": file_id = doc.file_id if name not in modules_list(): msg.edit("Скачиваем...") app.download_media(file_id, f"modules/{name}.py") msg.edit("Перезагрузка бота...") app.restart(False) msg.edit( f"Модуль **{name}** установлен и готов к использованию") else: msg.edit("Модуль с таким именем существует!") else: msg.edit("Файл не имеет нужный формат (`.py`)") else: msg.edit("Это не файл...")
def load(app, message): name = message.reply_to_message.document.file_name doc = message.reply_to_message.document.file_id message.edit("**Установка модуля...**") app.download_media(message=doc, file_name=f"modules/{name}") message.edit("**Модуль установлен**") app.restart(False) time.sleep(1.5) message.delete()
def download_media(client: Client, file_id: str, file_ref: str, file_path: str) -> Optional[str]: # Download a media file result = None try: result = client.download_media(message=file_id, file_ref=file_ref, file_name=file_path) except FloodWait as e: raise e except Exception as e: logger.warning(f"Download media {file_id} to {file_path} error: {e}", exc_info=True) return result
def download_media(client: Client, file_id: str, file_ref: str, file_path: str): # Download a media file result = None try: flood_wait = True while flood_wait: flood_wait = False try: result = client.download_media(message=file_id, file_ref=file_ref, file_name=file_path) except FloodWait as e: flood_wait = True wait_flood(e) except Exception as e: logger.warning(f"Download media {file_id} to {file_path} error: {e}", exc_info=True) return result
class TelegramDownloadHelper(DownloadHelper): def __init__(self, listener): super().__init__() self.__listener = listener self.__resource_lock = threading.RLock() self.__name = "" self.__gid = '' self.__start_time = time.time() self.__user_bot = Client(api_id=TELEGRAM_API, api_hash=TELEGRAM_HASH, session_name=USER_SESSION_STRING) self.__user_bot.start() self.__is_cancelled = False @property def gid(self): with self.__resource_lock: return self.__gid @property def download_speed(self): with self.__resource_lock: return self.downloaded_bytes / (time.time() - self.__start_time) def __onDownloadStart(self, name, size, file_id): with download_dict_lock: download_dict[self.__listener.uid] = TelegramDownloadStatus( self, self.__listener) with global_lock: GLOBAL_GID.add(file_id) with self.__resource_lock: self.name = name self.size = size self.__gid = file_id self.__listener.onDownloadStarted() def __onDownloadProgress(self, current, total): if self.__is_cancelled: self.__onDownloadError('Cancelled by user!') self.__user_bot.stop_transmission() return with self.__resource_lock: self.downloaded_bytes = current try: self.progress = current / self.size * 100 except ZeroDivisionError: self.progress = 0 def __onDownloadError(self, error): with global_lock: try: GLOBAL_GID.remove(self.gid) except KeyError: pass self.__listener.onDownloadError(error) def __onDownloadComplete(self): with global_lock: GLOBAL_GID.remove(self.gid) self.__listener.onDownloadComplete() def __download(self, message, path): download = self.__user_bot.download_media( message, progress=self.__onDownloadProgress, file_name=path) if download is not None: self.__onDownloadComplete() elif not self.__is_cancelled: self.__onDownloadError('Internal error occurred') def add_download(self, message, path): _message = self.__user_bot.get_messages(message.chat.id, message.message_id) media = None media_array = [_message.document, _message.video, _message.audio] for i in media_array: if i is not None: media = i break if media is not None: with global_lock: # For avoiding locking the thread lock for long time unnecessarily download = media.file_id not in GLOBAL_GID if download: self.__onDownloadStart(media.file_name, media.file_size, media.file_id) LOGGER.info( f'Downloading telegram file with id: {media.file_id}') threading.Thread(target=self.__download, args=(_message, path)).start() else: self.__onDownloadError('File already being downloaded!') else: self.__onDownloadError('No document in the replied message') def cancel_download(self): LOGGER.info(f'Cancelling download on user request: {self.gid}') self.__is_cancelled = True
# Download all profile photos of a specified user. # Just in case you want them, or something. from pyrogram import Client app = Client("my_account") user = "******" with app: all_pics = app.iter_profile_photos(user) for i, pic in enumerate(all_pics, 1): path = app.download_media( message=pic.file_id, file_name=f"profile_pics/{user}/{i}.jpg", ) print(path.split("\\")[-1])
shutil.copyfile("./283058260.session", workdir + '/283058260.session') ###ACTUAL WORK app = Client(session_name=bot_api_key, workers=1, workdir=workdir, config_file="./config.ini") app.start() print(sys.argv) method = str(sys.argv[1]) chat_id = int(sys.argv[2]) try: if method == "DOWNLOAD": ffile = str(sys.argv[3]) file_path = str(sys.argv[4]).replace('\\"', '"') text = str(sys.argv[5] if len(sys.argv) >= 6 else "").replace('\\"', '"') if file_path == "": file_path = "" app.download_media(message=ffile, file_name=file_path) if text != "": app.send_chat_action(chat_id=chat_id, action=ChatAction.TYPING) app.send_message(chat_id=chat_id, text=text) elif method == "UPLOAD": media_type = str(sys.argv[3]) ffile = str(sys.argv[4]).replace('\\"', '"') reply_id = str(sys.argv[5] if len(sys.argv) >= 6 else "") caption = str(sys.argv[6] if len(sys.argv) >= 7 else "").replace('\\"', '"') error_string = str(sys.argv[7] if len(sys.argv) >= 8 else "") if reply_id == "": reply_id = -1 else: reply_id = int(reply_id) if caption == "": caption = ""
class Tracker: def __init__(self, api_id, api_hash, phone): self.client = Client(session_name='session', api_id=api_id, api_hash=api_hash, phone_number=phone) self.flush_queue = Queue() @timer def update_user_info(self): all_users = self.client.get_contacts() user_info_changed_count = 0 for user in all_users: user_row_dict = { 'user_id': user.id, 'first_name': user.first_name, 'last_name': user.last_name, 'user_name': user.username, 'bio': get_user_bio(user.username), 'trackable_online': any([user.status.online, user.status.date]), 'last_modified': datetime.now() } db_user: UserInfo = tracker_session.query(UserInfo).filter( UserInfo.user_id == user.id).scalar() if db_user is None: # if there are no such user in db tracker_session.add(UserInfo(**user_row_dict)) elif not rows_equal( # if there are such user in db db_user, # but the info has changed UserInfo(**user_row_dict), skip_fields=('last_modified', )): user_info_changed_count += 1 diffs = get_rows_difference(db_user, UserInfo(**user_row_dict), skip_fields=('last_modified', )) for diff in diffs: # find what changed and write difference tracker_session.add( UserInfoHistory(user_id=user.id, time=datetime.now(), changed_field=diff[0], old_value=diff[1], new_value=user_row_dict[diff[0]])) for k, v in user_row_dict.items(): setattr(db_user, k, v) tracker_session.flush() if user_info_changed_count: log.warn( f'While updating user info {user_info_changed_count} users' f' changed info') def on_changed_status(self, _: Client, user_status: UserStatus): user = tracker_session.query(LastOnline).filter( LastOnline.user_id == user_status.user_id).scalar() new_status = parse_user_status(user_status) if user is None: tracker_session.add( LastOnline(user_id=user_status.user_id, time=datetime.now(), last_status=new_status)) tracker_session.flush() elif user.last_status == new_status: log.warn('User online status was doubled, skipping' f' uid: {user_status.user_id}') # TODO: sometimes we dont get a message about someone going offline # TODO: make sure we dont leave someone hanging online for 100 hours # TODO: because of unclosed online status # Hint: if we get doubled message just save that online sess as # 300 secs sess else: log.warn(f'User {user_status.user_id} is now {new_status}') user.last_status = new_status self.flush_queue.put( OnlineHistory(user_id=user_status.user_id, time=datetime.now(), new_status=new_status)) tracker_session.flush() @staticmethod def flush_worker(queue: Queue): while True: q_contents = queue.get() tracker_session.add(q_contents) tracker_session.flush() @timer def update_user_photos(self): for contact in self.client.get_contacts(): photos = self.client.get_user_profile_photos(contact.id).photos if not len(photos): continue st = photos[0] self.client.download_media( message=st, file_name=f'pics/{contact.id}-{str(datetime.now())}.jpg') def start(self): self.client.add_handler(UserStatusHandler(self.on_changed_status)) flush_worker = Process(target=self.flush_worker, args=(self.flush_queue, )) flush_worker.start() sch.every(1).minute.do(self.update_user_info) sch.every(1).hours.do(self.update_user_photos) self.client.start() while True: sch.run_pending() sleep(0.5)