Exemple #1
0
def fast_post(
        api: object,
        board: str,
        title: str,
        content: str,
        post_type: int,
        sign_file) -> None:
    api._goto_board(board)

    cmd_list = list()
    cmd_list.append(command.Ctrl_P)
    cmd_list.append(str(post_type))
    cmd_list.append(command.Enter)
    cmd_list.append(str(title))
    cmd_list.append(command.Enter)
    cmd_list.append(str(content))
    cmd_list.append(command.Ctrl_X)
    cmd = ''.join(cmd_list)

    target_list = [
        connect_core.TargetUnit(
            i18n.HasPostPermission,
            '發表文章於【',
            break_detect=True,
        ),
        connect_core.TargetUnit(
            i18n.NoPermission,
            '使用者不可發言',
            break_detect=True,
        ),
        connect_core.TargetUnit(
            i18n.NoPermission,
            '無法發文: 未達看板要求權限',
            break_detect=True
        ),
        connect_core.TargetUnit(
            i18n.AnyKeyContinue,
            '任意鍵繼續',
            break_detect=True,
        ),
        connect_core.TargetUnit(
            i18n.SaveFile,
            '確定要儲存檔案嗎',
            response='s' + command.Enter,
        ),
        connect_core.TargetUnit(
            i18n.SelectSignature,
            'x=隨機',
            response=str(sign_file) + command.Enter,
        ),
    ]
    index = api.connect_core.fast_send(cmd, target_list)
    if index < 0:
        screens.show(api.config, api.connect_core.get_screen_queue())
        raise exceptions.UnknownError(i18n.UnknownError)
    if index == 1 or index == 2:
        raise exceptions.NoPermission(i18n.NoPermission)
Exemple #2
0
def fast_post_step1(api: object, sign_file) -> None:
    cmd = '\r'

    target_list = [
        connect_core.TargetUnit(
            i18n.HasPostPermission,
            '發表文章於【',
            break_detect=True,
        ),
        connect_core.TargetUnit(
            i18n.NoPermission,
            '使用者不可發言',
            break_detect=True,
        ),
        connect_core.TargetUnit(
            i18n.NoPermission,
            '無法發文: 未達看板要求權限',
            break_detect=True
        ),
        connect_core.TargetUnit(
            i18n.AnyKeyContinue,
            '任意鍵繼續',
            break_detect=True,
        ),
        connect_core.TargetUnit(
            i18n.SaveFile,
            '確定要儲存檔案嗎',
            break_detect=True,
        ),
        connect_core.TargetUnit(
            i18n.SelectSignature,
            'x=隨機',
            response=str(sign_file) + '\r',
        ),
    ]
    index = api.connect_core.fast_send(cmd, target_list)
    if index < 0:
        screens.show(api.config, api.connect_core.get_screen_queue())
        raise exceptions.UnknownError(i18n.UnknownError)
Exemple #3
0
    def send(self,
             msg: str,
             target_list: list,
             screen_timeout: int = 0,
             refresh: bool = True,
             secret: bool = False) -> int:
        def clean_screen(recv_screen: str, NoColor: bool = True) -> str:

            if not recv_screen:
                return recv_screen
            # http://asf.atmel.com/docs/latest/uc3l/html/group__group__avr32__lib_utils__print__funcs.html#ga024c3e2852fe509450ebc363df52ae73

            # screen = re.sub('\[[\d+;]*m', '', screen)

            recv_screen = re.sub(r'[\r]', '', recv_screen)
            # recv_screen = re.sub(r'[\x00-\x08]', '', recv_screen)
            recv_screen = re.sub(r'[\x00-\x07]', '', recv_screen)
            # print(recv_screen)
            recv_screen = re.sub(r'[\x0b\x0c]', '', recv_screen)
            # screen = re.sub(r'[\x0e-\x1f]', '', screen)

            recv_screen = re.sub(r'[\x0e-\x1A]', '', recv_screen)
            recv_screen = re.sub(r'[\x1C-\x1F]', '', recv_screen)
            recv_screen = re.sub(r'[\x7f-\xff]', '', recv_screen)

            recv_screen = screens.vt100(recv_screen)

            return recv_screen

        if not all(isinstance(T, TargetUnit) for T in target_list):
            raise ValueError('Item of TargetList must be TargetUnit')

        if self._UseTooManyResources not in target_list:
            target_list.append(self._UseTooManyResources)

        if screen_timeout == 0:
            current_screen_timeout = self.config.screen_timeout
        else:
            current_screen_timeout = screen_timeout

        break_detect_after_send = False
        break_index = -1
        is_secret = secret

        use_too_many_res = False
        while True:

            if refresh and not msg.endswith(command.Refresh):
                msg = msg + command.Refresh
            try:
                msg = msg.encode('big5uao', 'replace')

            except AttributeError:
                pass
            except Exception as e:
                traceback.print_tb(e.__traceback__)
                print(e)
                msg = msg.encode('big5', 'replace')

            if is_secret:
                log.show_value(self.config, log.level.DEBUG, [i18n.SendMsg],
                               i18n.HideSensitiveInfor)
            else:
                log.show_value(self.config, log.level.DEBUG, [i18n.SendMsg],
                               msg)
            if self.config.connect_mode == connect_mode.TELNET:
                try:
                    self._core.read_very_eager()
                    self._core.write(msg)
                except EOFError:
                    raise exceptions.ConnectionClosed()
            else:
                try:
                    asyncio.get_event_loop().run_until_complete(
                        self._core.send(msg))
                except websockets.exceptions.ConnectionClosedError:
                    raise exceptions.ConnectionClosed()
                except RuntimeError:
                    raise exceptions.ConnectionClosed()
                except websockets.exceptions.ConnectionClosedOK:
                    raise exceptions.ConnectionClosed()

                if break_detect_after_send:
                    return break_index

            msg = ''
            receive_data_buffer = bytes()

            # print(f'0 {use_too_many_res}')
            start_time = time.time()
            mid_time = time.time()
            while mid_time - start_time < current_screen_timeout:

                recv_data_obj = RecvData()

                if self.config.connect_mode == connect_mode.TELNET:
                    try:
                        recv_data_obj.data = self._core.read_very_eager()
                    except EOFError:
                        return -1

                else:
                    try:

                        asyncio.get_event_loop().run_until_complete(
                            websocket_receiver(self._core,
                                               current_screen_timeout,
                                               recv_data_obj))

                    except websockets.exceptions.ConnectionClosed:
                        # print(f'0.1 {use_too_many_res}')
                        if use_too_many_res:
                            # print(f'0.2 {use_too_many_res}')
                            raise exceptions.UseTooManyResources()
                        # print(f'0.3 {use_too_many_res}')
                        raise exceptions.ConnectionClosed()
                    except websockets.exceptions.ConnectionClosedOK:
                        raise exceptions.ConnectionClosed()
                    except asyncio.TimeoutError:
                        return -1
                    except RuntimeError:
                        raise exceptions.ConnectionClosed()

                receive_data_buffer += recv_data_obj.data
                receive_data_temp = receive_data_buffer.decode(
                    'big5uao', errors='replace')
                screen = clean_screen(receive_data_temp)

                # qq = receive_data_temp.encode('utf-8')
                # b = None
                # for q in qq:
                #     if not b:
                #         b = f'bytes([{q}'
                #     else:
                #         b += f', {q}'
                # b += f'])'
                # print(b)

                find_target = False
                for Target in target_list:
                    condition = Target.is_match(screen)
                    if condition:
                        if Target._Handler is not None:
                            Target._Handler(screen)
                        if len(screen) > 0:
                            screens.show(self.config, screen)
                            self._RDQ.add(screen)
                            # self._ReceiveDataQueue.append(screen)
                            if Target == self._UseTooManyResources:
                                # print('!!!!!!!!!!!!!!!')
                                use_too_many_res = True
                                # print(f'1 {use_too_many_res}')
                                break
                            Target.raise_exception()

                        find_target = True

                        log.show_value(self.config, Target.get_log_level(),
                                       [i18n.PTT, i18n.Msg],
                                       Target.get_display_msg())

                        end_time = time.time()
                        log.show_value(self.config, log.level.DEBUG, [
                            i18n.SpendTime,
                        ], round(end_time - start_time, 3))

                        if Target.is_break():
                            return target_list.index(Target)

                        msg = Target.get_response(screen)

                        add_refresh = False
                        if Target.is_refresh():
                            add_refresh = True
                        elif refresh:
                            add_refresh = True

                        if add_refresh:
                            if not msg.endswith(command.Refresh):
                                msg = msg + command.Refresh

                        is_secret = Target.is_secret()

                        if Target.is_break_after_send():
                            break_index = target_list.index(Target)
                            break_detect_after_send = True
                        break

                # print(f'2 {use_too_many_res}')
                if use_too_many_res:
                    # print(f'3 {use_too_many_res}')
                    continue
                # print(f'4 {use_too_many_res}')

                if find_target:
                    break
                if len(screen) > 0:
                    screens.show(self.config, screen)
                    self._RDQ.add(screen)
                    # self._ReceiveDataQueue.append(screen)

                mid_time = time.time()

            if not find_target:
                # raise exceptions.NoMatchTargetError(self._RDQ)
                return -1
        # raise exceptions.NoMatchTargetError(self._RDQ)
        return -1
Exemple #4
0
    def fast_send(self,
                  msg: str,
                  target_list: list,
                  refresh: bool = True) -> int:

        break_detect_after_send = False
        break_index = -1

        use_too_many_res = False
        while True:

            if refresh and not msg.endswith(command.Refresh):
                msg = msg + command.Refresh
            try:
                msg = msg.encode('big5uao', 'replace')

            except AttributeError:
                pass
            except Exception as e:
                traceback.print_tb(e.__traceback__)
                print(e)
                msg = msg.encode('big5', 'replace')

            try:
                asyncio.get_event_loop().run_until_complete(
                    self._core.send(msg))
            except websockets.exceptions.ConnectionClosedError:
                raise exceptions.ConnectionClosed()
            except RuntimeError:
                raise exceptions.ConnectionClosed()
            except websockets.exceptions.ConnectionClosedOK:
                raise exceptions.ConnectionClosed()

            if break_detect_after_send:
                return break_index

            msg = ''
            receive_data_buffer = bytes()

            # print(f'0 {use_too_many_res}')
            start_time = time.time()
            mid_time = time.time()
            while mid_time - start_time < self.config.screen_timeout:

                recv_data_obj = RecvData()

                try:

                    asyncio.get_event_loop().run_until_complete(
                        websocket_receiver(self._core,
                                           self.config.screen_timeout,
                                           recv_data_obj))

                except websockets.exceptions.ConnectionClosed:
                    # print(f'0.1 {use_too_many_res}')
                    if use_too_many_res:
                        # print(f'0.2 {use_too_many_res}')
                        raise exceptions.UseTooManyResources()
                    # print(f'0.3 {use_too_many_res}')
                    raise exceptions.ConnectionClosed()
                except websockets.exceptions.ConnectionClosedOK:
                    raise exceptions.ConnectionClosed()
                except asyncio.TimeoutError:
                    return -1
                except RuntimeError:
                    raise exceptions.ConnectionClosed()

                receive_data_buffer += recv_data_obj.data
                screen = receive_data_buffer.decode('big5uao',
                                                    errors='replace')

                find_target = False
                for Target in target_list:
                    condition = Target.is_match(screen)
                    if condition:
                        if len(screen) > 0:
                            screens.show(self.config, screen)
                            self._RDQ.add(screen)
                            # self._ReceiveDataQueue.append(screen)
                            if Target == self._UseTooManyResources:
                                # print('!!!!!!!!!!!!!!!')
                                use_too_many_res = True
                                # print(f'1 {use_too_many_res}')
                                break
                            Target.raise_exception()

                        find_target = True

                        if Target.is_break():
                            return target_list.index(Target)

                        msg = Target.get_response(screen)

                        add_refresh = False
                        if Target.is_refresh():
                            add_refresh = True
                        elif refresh:
                            add_refresh = True

                        if add_refresh:
                            if not msg.endswith(command.Refresh):
                                msg = msg + command.Refresh

                        if Target.is_break_after_send():
                            break_index = target_list.index(Target)
                            break_detect_after_send = True
                        break

                # print(f'2 {use_too_many_res}')
                if use_too_many_res:
                    # print(f'3 {use_too_many_res}')
                    continue
                # print(f'4 {use_too_many_res}')

                if find_target:
                    break
                if len(screen) > 0:
                    screens.show(self.config, screen)
                    self._RDQ.add(screen)
                    # self._ReceiveDataQueue.append(screen)

                mid_time = time.time()

            if not find_target:
                # raise exceptions.NoMatchTargetError(self._RDQ)
                return -1
        # raise exceptions.NoMatchTargetError(self._RDQ)
        return -1
def get_newest_index(
        api,
        index_type: int,
        board: str = None,
        # BBS
        search_type: int = 0,
        search_condition: str = None) -> int:

    if index_type == data_type.index_type.BBS:

        api._check_board(board)

        check_value.check(api.config,
                          int,
                          'SearchType',
                          search_type,
                          value_class=data_type.post_search_type)
        if search_condition is not None:
            check_value.check(api.config, str, 'SearchCondition',
                              search_condition)
        check_value.check(api.config, int, 'SearchType', search_type)

        cmd_list = []
        cmd_list.append(command.GoMainMenu)
        cmd_list.append('qs')
        cmd_list.append(board)
        cmd_list.append(command.Enter)
        cmd_list.append(command.Ctrl_C * 2)
        cmd_list.append(command.Space)

        if search_condition is not None:
            if search_type == data_type.post_search_type.KEYWORD:
                cmd_list.append('/')
            elif search_type == data_type.post_search_type.AUTHOR:
                cmd_list.append('a')
            elif search_type == data_type.post_search_type.PUSH:
                cmd_list.append('Z')
            elif search_type == data_type.post_search_type.MARK:
                cmd_list.append('G')
            elif search_type == data_type.post_search_type.MONEY:
                cmd_list.append('A')

            cmd_list.append(search_condition)
            cmd_list.append(command.Enter)

        cmd_list.append('1')
        cmd_list.append(command.Enter)
        cmd_list.append('$')

        cmd = ''.join(cmd_list)

        target_list = [
            connect_core.TargetUnit(i18n.NoPost,
                                    '沒有文章...',
                                    break_detect=True,
                                    log_level=log.level.DEBUG),
            connect_core.TargetUnit(i18n.Success,
                                    screens.Target.InBoard,
                                    break_detect=True,
                                    log_level=log.level.DEBUG),
            connect_core.TargetUnit(i18n.Success,
                                    screens.Target.InBoardWithCursor,
                                    break_detect=True,
                                    log_level=log.level.DEBUG),
            connect_core.TargetUnit(i18n.NoSuchBoard,
                                    screens.Target.MainMenu_Exiting,
                                    exceptions_=exceptions.NoSuchBoard(
                                        api.config, board)),
        ]
        index = api.connect_core.send(cmd, target_list)
        if index < 0:
            # OriScreen = api.connect_core.getScreenQueue()[-1]
            # print(OriScreen)
            raise exceptions.NoSuchBoard(api.config, board)

        if index == 0:
            return 0

        last_screen = api.connect_core.get_screen_queue()[-1]
        all_index = re.findall(r'\d+ ', last_screen)

        if len(all_index) == 0:
            print(last_screen)
            raise exceptions.UnknownError(i18n.UnknownError)

        all_index = list(map(int, all_index))
        all_index.sort(reverse=True)

        max_check_range = 6
        newest_index = 0
        for IndexTemp in all_index:
            need_continue = True
            if IndexTemp > max_check_range:
                check_range = max_check_range
            else:
                check_range = IndexTemp
            for i in range(1, check_range):
                if str(IndexTemp - i) not in last_screen:
                    need_continue = False
                    break
            if need_continue:
                log.show_value(api.config, log.level.DEBUG,
                               i18n.FindNewestIndex, IndexTemp)
                newest_index = IndexTemp
                break

        if newest_index == 0:
            screens.show(api.config, api.connect_core.get_screen_queue())
            raise exceptions.UnknownError(i18n.UnknownError)

    elif data_type.index_type.WEB:
        # web
        _NewestIndex = None
        newest_index = 0
        _url = 'https://www.ptt.cc/bbs/'
        url = _url + board
        r = requests.get(url, cookies={'over18': '1'})

        if r.status_code != requests.codes.ok:
            raise exceptions.NoSuchBoard(api.config, board)
        soup = BeautifulSoup(r.text, 'html.parser')

        for index, data in enumerate(
                soup.select('div.btn-group.btn-group-paging a')):
            text = data.text
            herf = data.get('href')
            if '上頁' in text:
                _NewestIndex = herf.split('index')[1].split('.')[0]
                # print("_NewestIndex: " + _NewestIndex)
                _NewestIndex = int(_NewestIndex)

        if _NewestIndex is None:
            raise exceptions.UnknownError('')
        newest_index = (_NewestIndex) + 1
    return newest_index
Exemple #6
0
def post(
        api: object,
        board: str,
        title: str,
        content: str,
        post_type: int,
        sign_file) -> None:
    cmd_list = []
    cmd_list.append(command.GoMainMenu)
    cmd_list.append('qs')
    cmd_list.append(board)
    cmd_list.append(command.Enter)
    cmd_list.append(command.Ctrl_C * 2)
    cmd_list.append(command.Space)
    cmd_list.append(command.Ctrl_P)

    cmd = ''.join(cmd_list)

    target_list = [
        connect_core.TargetUnit(
            i18n.HasPostPermission,
            '發表文章於【',
            break_detect=True,
        ),
        connect_core.TargetUnit(
            i18n.NoPermission,
            '使用者不可發言',
            break_detect=True,
        )
    ]
    index = api.connect_core.send(cmd, target_list)
    if index < 0:
        screens.show(api.config, api.connect_core.get_screen_queue())
        raise exceptions.UnknownError(i18n.UnknownError)
    if index == 1:
        raise exceptions.NoPermission(i18n.NoPermission)

    screens.show(api.config, api.connect_core.get_screen_queue())

    cmd_list = []
    cmd_list.append(str(post_type))
    cmd_list.append(command.Enter)
    cmd_list.append(str(title))
    cmd_list.append(command.Enter)
    cmd_list.append(command.Ctrl_Y * 40)
    cmd_list.append(str(content))
    cmd_list.append(command.Ctrl_X)
    cmd = ''.join(cmd_list)

    target_list = [
        connect_core.TargetUnit(
            i18n.AnyKeyContinue,
            '任意鍵繼續',
            break_detect=True,
        ),
        connect_core.TargetUnit(
            i18n.SaveFile,
            '確定要儲存檔案嗎',
            response='s' + command.Enter,
        ),
        connect_core.TargetUnit(
            i18n.SelectSignature,
            'x=隨機',
            response=str(sign_file) + command.Enter,
        ),
    ]
    index = api.connect_core.send(
        cmd,
        target_list,
        screen_timeout=api.config.screen_post_timeout
    )