예제 #1
0
 def _on_cw_msg(self, message):
     print(str(datetime.now()) + ': ' + 'Получили сообщение от ChatWars')
     if self._character.status == CharacterStatus.PAUSED:
         return
     if re.search(regexp.main_hero, message.message):
         self._tgClient.invoke(
             ForwardMessageRequest(get_input_peer(self._dataBot),
                                   message.id,
                                   utils.generate_random_long()))
     if '/fight_' in message.message:
         self._tgClient.invoke(
             ForwardMessageRequest(get_input_peer(self._dataBot),
                                   message.id,
                                   utils.generate_random_long()))
     if 'Ты вернулся со стройки:' in message.message or 'Здание отремонтировано:' in message.message:
         self._tgClient.invoke(
             ForwardMessageRequest(get_input_peer(self._dataBot),
                                   message.id,
                                   utils.generate_random_long()))
         print(str(datetime.now()) + ': ' + 'Вернулись из стройки')
         self._next_build_try = datetime.now() + timedelta(
             minutes=random.randint(0, 2), seconds=random.randint(0, 59))
         self._character.status = CharacterStatus.REST
     if 'В казне недостаточно ресурсов' in message.message:
         print(str(datetime.now()) + ': ' + 'Стройка не удалась')
         self._character.status = CharacterStatus.REST
         self._next_build_try = datetime.now() + timedelta(
             minutes=random.randint(1, 4), seconds=random.randint(0, 59))
     if 'Твои результаты в бою:' in message.message:
         self._tgClient.invoke(
             ForwardMessageRequest(get_input_peer(self._dataBot),
                                   message.id,
                                   utils.generate_random_long()))
     self.parse_message(message.message)
예제 #2
0
async def _internal_transfer_to_telegram(
        client: TelegramClient,
        response: BinaryIO,
        file_size,
        file_name,
        progress_callback: callable,
        max_connection=None) -> Tuple[TypeInputFile, int]:
    file_id = helpers.generate_random_long()
    # file_size = os.path.getsize(response.name)

    hash_md5 = hashlib.md5()
    uploader = ParallelTransferrer(client)
    part_size, part_count, is_large = await uploader.init_upload(
        file_id, file_size, max_connection=max_connection)
    buffer = bytearray()
    part_index = 0
    async for data in stream_file(response, chunk_size=part_size):
        part_index += 1
        if len(data) == 0:
            part_index -= 1
            break
        # if len(data) != part_size and part_index != part_count:
        #     dat = b'\0' * (part_size - len(data))
        #     data += dat
        if not is_large:
            hash_md5.update(data)
        if len(buffer) == 0:
            await uploader.upload(data)
            if part_index >= part_count:
                break
            else:
                continue
        new_len = len(buffer) + len(data)
        if new_len >= part_size:
            cutoff = part_size - len(buffer)
            buffer.extend(data[:cutoff])
            await uploader.upload(bytes(buffer))
            buffer.clear()
            buffer.extend(data[cutoff:])
        else:
            buffer.extend(data)

        if part_index >= part_count:
            break
        else:
            continue

    for u in uploader.senders:
        u.request.file_total_parts = part_index
        u.part_count = part_index
    part_count = part_index

    if len(buffer) > 0:
        await uploader.upload(bytes(buffer))
    await uploader.finish_upload()
    if is_large:
        return InputFileBig(file_id, part_count, file_name), file_size
    else:
        return InputFile(file_id, part_count, file_name,
                         hash_md5.hexdigest()), file_size
예제 #3
0
 def send_message(self,
                  peer,
                  message,
                  no_web_page=False,
                  PM=False,
                  access_hash=None):
     msg_id = utils.generate_random_long()
     if not (PM is True):
         self.invoke(
             SendMessageRequest(peer=InputPeerChat(peer),
                                message=message,
                                random_id=msg_id,
                                no_webpage=no_web_page))
     else:
         if access_hash:
             self.invoke(
                 SendMessageRequest(peer=InputPeerUser(peer, access_hash),
                                    message=message,
                                    random_id=msg_id,
                                    no_webpage=no_web_page))
         else:
             print(
                 "Access hash not provided. Could send message to InputPeerUser."
             )
     return msg_id
예제 #4
0
async def _internal_transfer_to_telegram(
        client: MautrixTelegramClient,
        response: ClientResponse) -> tuple[TypeInputFile, int]:
    file_id = helpers.generate_random_long()
    file_size = response.content_length

    hash_md5 = hashlib.md5()
    uploader = ParallelTransferrer(client)
    part_size, part_count, is_large = await uploader.init_upload(
        file_id, file_size)
    buffer = bytearray()
    async for data in response.content:
        if not is_large:
            hash_md5.update(data)
        if len(buffer) == 0 and len(data) == part_size:
            await uploader.upload(data)
            continue
        new_len = len(buffer) + len(data)
        if new_len >= part_size:
            cutoff = part_size - len(buffer)
            buffer.extend(data[:cutoff])
            await uploader.upload(bytes(buffer))
            buffer.clear()
            buffer.extend(data[cutoff:])
        else:
            buffer.extend(data)
    if len(buffer) > 0:
        await uploader.upload(bytes(buffer))
    await uploader.finish_upload()
    if is_large:
        return InputFileBig(file_id, part_count, "upload"), file_size
    else:
        return InputFile(file_id, part_count, "upload",
                         hash_md5.hexdigest()), file_size
예제 #5
0
 def send_media_file(self, input_media, entity):
     """Sends any input_media (contact, document, photo...) to the given entiy"""
     self.invoke(
         SendMediaRequest(
             peer=get_input_peer(entity),
             media=input_media,
             random_id=utils.generate_random_long()))
예제 #6
0
async def _internal_transfer_to_telegram(
        client: TelegramClient,
        response: BinaryIO,
        file_size,
        file_name,
        progress_callback: callable,
        max_connection=None) -> Tuple[TypeInputFile, int]:
    file_id = helpers.generate_random_long()
    # file_size = os.path.getsize(response.name)

    # hash_md5 = hashlib.md5()
    uploader = ParallelTransferrer(client)
    part_size, part_count, is_large = await uploader.init_upload(
        file_id, file_size, max_connection=max_connection)
    buffer = bytearray()
    # part_index = 0
    # complete = False
    for part_index in range(part_count):
        # async for data in stream_file(response, chunk_size=part_size):
        data = await response.read(part_size)
        # part_index += 1
        len_data = len(data)
        if len_data == 0:
            # data was read fully
            # emulate last piece
            # (for zip files)
            data = b'\0'
        if len_data != part_size and part_index != part_count - 1:
            dat = b'\0' * (part_size - len_data)
            data += dat

        # if not is_large:
        #     hash_md5.update(data)
        if len(buffer) == 0 and len(data) == part_size:
            await uploader.upload(data)
            # if complete:
            #     break
            continue
        new_len = len(buffer) + len(data)
        if new_len >= part_size:
            cutoff = part_size - len(buffer)
            buffer.extend(data[:cutoff])
            await uploader.upload(bytes(buffer))
            buffer.clear()
            buffer.extend(data[cutoff:])
        else:
            buffer.extend(data)
        # if complete:
        #     break
    # if complete:
    #     part_count = part_index
    if len(buffer) > 0:
        await uploader.upload(bytes(buffer))
    await uploader.finish_upload()
    # if is_large:
    return InputFileBig(file_id, part_count, file_name), file_size
예제 #7
0
파일: session.py 프로젝트: yuna-98/Telethon
 def __init__(self, session_user_id):
     self.session_user_id = session_user_id
     self.server_address = '91.108.56.165'
     self.port = 443
     self.auth_key = None
     self.id = utils.generate_random_long(signed=False)
     self.sequence = 0
     self.salt = 0  # Unsigned long
     self.time_offset = 0
     self.last_message_id = 0  # Long
     self.user = None
예제 #8
0
async def _internal_transfer_to_telegram(client: TelegramClient,
                                         response: Union[BinaryIO, BytesIO, BufferedReader],
                                         progress_callback: callable,
                                         name: str = None
                                         ) -> Tuple[TypeInputFile, int]:
    file_id = helpers.generate_random_long()

    if isinstance(response, BytesIO):
        file_size = len(response.getvalue())
    else:
        file_size = os.path.getsize(name or response.name)

    hash_md5 = hashlib.md5()
    uploader = ParallelTransferrer(client)
    part_size, part_count, is_large = await uploader.init_upload(file_id, file_size)
    buffer = bytearray()

    for data in stream_file(response):
        if progress_callback:
            r = progress_callback(response.tell(), file_size)

            if inspect.isawaitable(r):
                await r

        if not is_large:
            hash_md5.update(data)

        if len(buffer) == 0 and len(data) == part_size:
            await uploader.upload(data)
            continue

        new_len = len(buffer) + len(data)

        if new_len >= part_size:
            cutoff = part_size - len(buffer)
            buffer.extend(data[:cutoff])
            await uploader.upload(bytes(buffer))
            buffer.clear()
            buffer.extend(data[cutoff:])
        else:
            buffer.extend(data)

    if len(buffer) > 0:
        await uploader.upload(bytes(buffer))

    await uploader.finish_upload()

    if is_large:
        return InputFileBig(file_id, part_count, name or "upload"), file_size

    return InputFile(file_id, part_count, name or "upload", hash_md5.hexdigest()), file_size
예제 #9
0
    def send_message(self, input_peer, message, markdown=False, no_web_page=False):
        """Sends a message to the given input peer and returns the sent message ID"""
        if markdown:
            msg, entities = parse_message_entities(message)
        else:
            msg, entities = message, []

        msg_id = utils.generate_random_long()
        self.invoke(SendMessageRequest(peer=input_peer,
                                       message=msg,
                                       random_id=msg_id,
                                       entities=entities,
                                       no_webpage=no_web_page))
        return msg_id
예제 #10
0
    def upload_file(self,
                    file,
                    part_size_kb=None,
                    file_name=None,
                    use_cache=None,
                    progress_callback=None):
        """
        Uploads the specified file and returns a handle (an instance of
        InputFile or InputFileBig, as required) which can be later used
        before it expires (they are usable during less than a day).

        Uploading a file will simply return a "handle" to the file stored
        remotely in the Telegram servers, which can be later used on. This
        will **not** upload the file to your own chat or any chat at all.

        Args:
            file (`str` | `bytes` | `file`):
                The path of the file, byte array, or stream that will be sent.
                Note that if a byte array or a stream is given, a filename
                or its type won't be inferred, and it will be sent as an
                "unnamed application/octet-stream".

                Subsequent calls with the very same file will result in
                immediate uploads, unless ``.clear_file_cache()`` is called.

            part_size_kb (`int`, optional):
                Chunk size when uploading files. The larger, the less
                requests will be made (up to 512KB maximum).

            file_name (`str`, optional):
                The file name which will be used on the resulting InputFile.
                If not specified, the name will be taken from the ``file``
                and if this is not a ``str``, it will be ``"unnamed"``.

            use_cache (`type`, optional):
                The type of cache to use (currently either ``InputDocument``
                or ``InputPhoto``). If present and the file is small enough
                to need the MD5, it will be checked against the database,
                and if a match is found, the upload won't be made. Instead,
                an instance of type ``use_cache`` will be returned.

            progress_callback (`callable`, optional):
                A callback function accepting two parameters:
                ``(sent bytes, total)``.

        Returns:
            :tl:`InputFileBig` if the file size is larger than 10MB,
            ``InputSizedFile`` (subclass of :tl:`InputFile`) otherwise.
        """
        if isinstance(file, (InputFile, InputFileBig)):
            return file  # Already uploaded

        if isinstance(file, str):
            file_size = os.path.getsize(file)
        elif isinstance(file, bytes):
            file_size = len(file)
        else:
            file = file.read()
            file_size = len(file)

        # File will now either be a string or bytes
        if not part_size_kb:
            part_size_kb = utils.get_appropriated_part_size(file_size)

        if part_size_kb > 512:
            raise ValueError('The part size must be less or equal to 512KB')

        part_size = int(part_size_kb * 1024)
        if part_size % 1024 != 0:
            raise ValueError(
                'The part size must be evenly divisible by 1024')

        # Set a default file name if None was specified
        file_id = helpers.generate_random_long()
        if not file_name:
            if isinstance(file, str):
                file_name = os.path.basename(file)
            else:
                file_name = str(file_id)

        # Determine whether the file is too big (over 10MB) or not
        # Telegram does make a distinction between smaller or larger files
        is_large = file_size > 10 * 1024 * 1024
        hash_md5 = hashlib.md5()
        if not is_large:
            # Calculate the MD5 hash before anything else.
            # As this needs to be done always for small files,
            # might as well do it before anything else and
            # check the cache.
            if isinstance(file, str):
                with open(file, 'rb') as stream:
                    file = stream.read()
            hash_md5.update(file)
            if use_cache:
                cached = self.session.get_file(
                    hash_md5.digest(), file_size, cls=use_cache
                )
                if cached:
                    return cached

        part_count = (file_size + part_size - 1) // part_size
        __log__.info('Uploading file of %d bytes in %d chunks of %d',
                     file_size, part_count, part_size)

        with open(file, 'rb') if isinstance(file, str) else BytesIO(file) as stream:
            threads_count = 2 + int((self._upload_threads_count - 2) * float(file_size) / (1024 * 1024 * 10))
            threads_count = min(threads_count, self._upload_threads_count)
            threads_count = min(part_count, threads_count)
            upload_thread = []
            q_request = Queue()
            # spawn threads
            for i in range(threads_count):
                thread_dl = self.ProcessUpload('thread {0}'.format(i), self, q_request)
                thread_dl.start()
                upload_thread.append(thread_dl)
            for part_index in range(0, part_count, threads_count):
                # Read the file by in chunks of size part_size
                for part_thread_index in range(threads_count):
                    if part_index + part_thread_index >= part_count:
                        break
                    part = stream.read(part_size)
                    # The SavePartRequest is different depending on whether
                    # the file is too large or not (over or less than 10MB)
                    if is_large:
                        request = SaveBigFilePartRequest(file_id, part_index + part_thread_index, part_count, part)
                    else:
                        request = SaveFilePartRequest(file_id, part_index + part_thread_index, part)
                    q_request.put(request)
                # q_request.join()
                job_completed = False
                while not job_completed:
                    for th in upload_thread:
                        if th:
                            if th.result is True:
                                job_completed = True
                                __log__.debug('Uploaded %d/%d', part_index + 1, part_count)
                                if progress_callback:
                                    progress_callback(stream.tell(), file_size)
                            elif th.result is False:
                                raise RuntimeError('Failed to upload file part {}.'.format(part_index))
            q_request.join()
            for i in range(threads_count):
                q_request.put(None)
            for th in upload_thread:
                th.join()
        if is_large:
            return InputFileBig(file_id, part_count, file_name)
        else:
            return InputSizedFile(
                file_id, part_count, file_name, md5=hash_md5, size=file_size
            )
예제 #11
0
 def send_ping(self):
     """Sends PingRequest"""
     request = PingRequest(utils.generate_random_long())
     self.send(request)
     self.receive(request)
예제 #12
0
 def send_media_file(self, input_media, input_peer):
     """Sends any input_media (contact, document, photo...) to an input_peer"""
     self.invoke(SendMediaRequest(peer=input_peer,
                                  media=input_media,
                                  random_id=utils.generate_random_long()))
예제 #13
0
    def upload_file(self,
                    file_path,
                    part_size_kb=None,
                    file_name=None,
                    progress_callback=None):
        """Uploads the specified file_path and returns a handle which can be later used

        :param file_path: The file path of the file that will be uploaded
        :param part_size_kb: The part size when uploading the file. None = Automatic
        :param file_name: The name of the uploaded file. None = Automatic
        :param progress_callback: A callback function which takes two parameters,
                                  uploaded size (in bytes) and total file size (in bytes)
                                  This is called every time a part is uploaded
        """
        file_size = path.getsize(file_path)
        if not part_size_kb:
            part_size_kb = get_appropiate_part_size(file_size)

        if part_size_kb > 512:
            raise ValueError('The part size must be less or equal to 512KB')

        part_size = int(part_size_kb * 1024)
        if part_size % 1024 != 0:
            raise ValueError('The part size must be evenly divisible by 1024')

        # Determine whether the file is too big (over 10MB) or not
        # Telegram does make a distinction between smaller or larger files
        is_large = file_size > 10 * 1024 * 1024
        part_count = (file_size + part_size - 1) // part_size

        # Multiply the datetime timestamp by 10^6 to get the ticks
        # This is high likely going to be unique
        file_id = utils.generate_random_long()
        hash_md5 = md5()

        with open(file_path, 'rb') as file:
            for part_index in range(part_count):
                # Read the file by in chunks of size part_size
                part = file.read(part_size)

                # The SavePartRequest is different depending on whether
                # the file is too large or not (over or less than 10MB)
                if is_large:
                    request = SaveBigFilePartRequest(file_id, part_index,
                                                     part_count, part)
                else:
                    request = SaveFilePartRequest(file_id, part_index, part)

                # Invoke the file upload and increment both the part index and MD5 checksum
                result = self.invoke(request)
                if result:
                    if not is_large:
                        # No need to update the hash if it's a large file
                        hash_md5.update(part)

                    if progress_callback:
                        progress_callback(file.tell(), file_size)
                else:
                    raise ValueError(
                        'Could not upload file part #{}'.format(part_index))

        # Set a default file name if None was specified
        if not file_name:
            file_name = path.basename(file_path)

        # After the file has been uploaded, we can return a handle pointing to it
        if is_large:
            return InputFileBig(id=file_id, parts=part_count, name=file_name)
        else:
            return InputFile(id=file_id,
                             parts=part_count,
                             name=file_name,
                             md5_checksum=hash_md5.hexdigest())
예제 #14
0
    def message(self, iq):
        """
        Обработчик входящих сообщений из XMPP
        :param iq:
        :return:
        """
        jid = iq['from'].bare

        if iq['to'] == self.config['jid'] and iq[
                'type'] == 'chat':  # Пишут транспорту
            if iq['body'].startswith('!'):
                self.process_command(iq)
            else:
                self.gate_reply_message(
                    iq, 'Only commands accepted. Try !help for more info.')
        else:  # Пишут в Telegram
            if jid in self.tg_connections and self.tg_connections[
                    jid].is_user_authorized():
                if iq['body'].startswith('!'):  # Команда из чата
                    print('command received')
                    if iq['to'].bare.startswith('u'):
                        self.process_chat_user_command(iq)
                    elif iq['to'].bare.startswith(
                            'g') or iq['to'].bare.startswith('s'):
                        self.process_chat_group_command(iq)
                    else:
                        self.gate_reply_message(iq, 'Error.')
                else:  # Обычное сообщение
                    print('sent message')
                    tg_id = int(iq['to'].node[1:])
                    tg_peer = None
                    msg = iq['body']
                    reply_mid = None

                    if msg.startswith('>'):  # Проверка на цитирование
                        msg_lines = msg.split('\n')
                        matched = re.match(r'>[ ]*(?P<mid>[\d]+)[ ]*',
                                           msg_lines[0]).groupdict()

                        if 'mid' in matched:  # Если нашли ID сообщения, то указываем ответ
                            reply_mid = int(matched['mid'])
                            msg = '\n'.join(msg_lines[1:])

                    if iq['to'].bare.startswith('u'):  # Обычный пользователь
                        tg_peer = InputPeerUser(
                            tg_id,
                            self.tg_dialogs[jid]['users'][tg_id].access_hash)
                    elif iq['to'].bare.startswith('g'):  # Обычная группа
                        tg_peer = InputPeerChat(tg_id)
                    elif iq['to'].bare.startswith('s') or iq[
                            'to'].bare.startswith('c'):  # Супергруппа
                        tg_peer = InputPeerChannel(
                            tg_id, self.tg_dialogs[jid]['supergroups']
                            [tg_id].access_hash)

                    if tg_peer:
                        # Отправляем сообщение и получаем новый апдейт
                        result = self.tg_connections[jid].invoke(
                            SendMessageRequest(tg_peer,
                                               msg,
                                               generate_random_long(),
                                               reply_to_msg_id=reply_mid))
                        msg_id = None

                        # Ищем ID отправленного сообщения
                        if type(result) is Updates:  # Супегруппа / канал
                            for upd in result.updates:
                                if type(upd) is UpdateMessageID:
                                    msg_id = upd.id
                        elif type(result
                                  ) is UpdateShortSentMessage:  # ЛС / Группа
                            msg_id = result.id
예제 #15
0
    def upload(self, file, file_name=None):
        entity = types.InputPeerSelf()

        # begin _file_to_media
        media = None
        file_handle = None

        # begin _upload_file
        file_id = helpers.generate_random_long()

        if not file_name and getattr(file, 'name', None):
            file_name = file.name
            if file_name is None:
                file_name = str(file_id)

        file = file.read()
        file_size = len(file)
        part_size = int(utils.get_appropriated_part_size(file_size) * 1024)

        is_large = file_size > 10 * 1024 * 1024
        hash_md5 = hashlib.md5()
        if not is_large:
            hash_md5.update(file)

        part_count = (file_size + part_size - 1) // part_size

        with BytesIO(file) as stream:
            for part_index in range(part_count):
                part = stream.read(part_size)

                if is_large:
                    request = functions.upload.SaveBigFilePartRequest(
                        file_id, part_index, part_count, part)
                else:
                    request = functions.upload.SaveFilePartRequest(
                        file_id, part_index, part)

                result = self.client(request)
                yield float(round(100.0 * (part_index / part_count), 2))
                if not result:
                    raise RuntimeError(
                        'Failed to upload file part {}.'.format(part_index))

        if is_large:
            file_handle = types.InputFileBig(file_id, part_count, file_name)
        else:
            file_handle = custom.InputSizedFile(file_id,
                                                part_count,
                                                file_name,
                                                md5=hash_md5,
                                                size=file_size)
        # end _upload_file

        attributes, mime_type = utils.get_attributes(file,
                                                     force_document=True,
                                                     voice_note=False,
                                                     video_note=False)
        attributes[0].file_name = file_name

        media = types.InputMediaUploadedDocument(file=file_handle,
                                                 mime_type=mime_type,
                                                 attributes=attributes)
        # end _file_to_media

        request = functions.messages.SendMediaRequest(entity,
                                                      media,
                                                      reply_to_msg_id=None,
                                                      message='',
                                                      entities=[],
                                                      reply_markup=None,
                                                      silent=None)
        t = self.client(request)
        if type(t) != types.Updates:
            t = self.client.loop.run_until_complete(t)
        msg = self.client._get_response_message(request, t, entity)
        yield msg