PyPtt 2.1.0__tar.gz → 2.1.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pyptt-2.1.0 → pyptt-2.1.2}/PKG-INFO +4 -4
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt/PTT.py +5 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt/__init__.py +1 -1
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt/_api_get_board_list.py +4 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt/_api_get_favourite_board.py +1 -0
- pyptt-2.1.2/PyPtt/_api_get_post_list.py +111 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt/_api_get_waterball.py +45 -44
- pyptt-2.1.2/PyPtt/_api_has_new_mail.py +77 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt/_api_util.py +167 -136
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt/config.py +5 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt/connect_core.py +23 -2
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt/screens.py +2 -2
- pyptt-2.1.2/PyPtt/ssl_config.py +24 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt.egg-info/PKG-INFO +4 -4
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt.egg-info/SOURCES.txt +1 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt.egg-info/requires.txt +3 -3
- {pyptt-2.1.0 → pyptt-2.1.2}/pyproject.toml +3 -3
- pyptt-2.1.2/tests/test_get_content_formula.py +431 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/tests/test_get_post_list_parser.py +54 -0
- pyptt-2.1.0/PyPtt/_api_get_post_list.py +0 -104
- pyptt-2.1.0/PyPtt/_api_has_new_mail.py +0 -76
- pyptt-2.1.0/PyPtt/ssl_config.py +0 -24
- {pyptt-2.1.0 → pyptt-2.1.2}/LICENSE +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt/_api_bucket.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt/_api_call_status.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt/_api_change_pw.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt/_api_comment.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt/_api_del_post.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt/_api_get_board_info.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt/_api_get_bottom_post_list.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt/_api_get_newest_index.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt/_api_get_post.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt/_api_get_post_index.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt/_api_get_time.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt/_api_get_user.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt/_api_give_money.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt/_api_loginout.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt/_api_mail.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt/_api_mark_post.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt/_api_post.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt/_api_reply_post.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt/_api_search_user.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt/_api_set_board_title.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt/api_server.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt/check_value.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt/command.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt/data_type.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt/exceptions.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt/i18n.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt/lang_en_US.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt/lang_zh_TW.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt/lib_util.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt/log.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt/service.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt.egg-info/dependency_links.txt +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/PyPtt.egg-info/top_level.txt +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/README.md +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/setup.cfg +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/setup.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/tests/test_bucket.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/tests/test_change_pw.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/tests/test_comment.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/tests/test_del_post.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/tests/test_exceptions.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/tests/test_fast_post.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/tests/test_get_board_info.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/tests/test_get_board_list.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/tests/test_get_bottom_post_list.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/tests/test_get_favourite_boards.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/tests/test_get_mail.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/tests/test_get_newest_index.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/tests/test_get_post.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/tests/test_get_post_list.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/tests/test_get_post_parser.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/tests/test_get_time.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/tests/test_get_user.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/tests/test_get_waterball.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/tests/test_give_money.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/tests/test_i18n.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/tests/test_init.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/tests/test_logger.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/tests/test_mail_send_and_del.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/tests/test_mark_post.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/tests/test_parse_query_post.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/tests/test_post.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/tests/test_pyte_parity.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/tests/test_reply_post.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/tests/test_search_user.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/tests/test_service.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/tests/test_set_board_title.py +0 -0
- {pyptt-2.1.0 → pyptt-2.1.2}/tests/test_vt100_parser.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PyPtt
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.2
|
|
4
4
|
Summary: PyPtt github: https://github.com/PyPtt/PyPtt
|
|
5
5
|
Author-email: CodingMan <pttcodingman@gmail.com>
|
|
6
6
|
License: GNU Lesser General Public License v3 (LGPLv3)
|
|
@@ -26,9 +26,9 @@ Requires-Python: >=3.11
|
|
|
26
26
|
Description-Content-Type: text/markdown
|
|
27
27
|
License-File: LICENSE
|
|
28
28
|
Requires-Dist: progressbar2
|
|
29
|
-
Requires-Dist: websockets
|
|
29
|
+
Requires-Dist: websockets>=12
|
|
30
30
|
Requires-Dist: uao
|
|
31
|
-
Requires-Dist: requests
|
|
31
|
+
Requires-Dist: requests>=2.32
|
|
32
32
|
Requires-Dist: AutoStrEnum
|
|
33
33
|
Requires-Dist: PyYAML
|
|
34
34
|
Provides-Extra: api
|
|
@@ -41,7 +41,7 @@ Requires-Dist: flake8; extra == "dev"
|
|
|
41
41
|
Requires-Dist: pyte; extra == "dev"
|
|
42
42
|
Requires-Dist: sphinx; extra == "dev"
|
|
43
43
|
Requires-Dist: sphinx-copybutton; extra == "dev"
|
|
44
|
-
Requires-Dist: pygments
|
|
44
|
+
Requires-Dist: pygments>=2.15; extra == "dev"
|
|
45
45
|
Requires-Dist: Furo; extra == "dev"
|
|
46
46
|
Requires-Dist: sphinx-sitemap; extra == "dev"
|
|
47
47
|
Dynamic: license-file
|
|
@@ -150,6 +150,11 @@ class API:
|
|
|
150
150
|
check_value.check_type(verify_ssl, bool, 'verify_ssl')
|
|
151
151
|
self.config.verify_ssl = verify_ssl
|
|
152
152
|
|
|
153
|
+
screen_height = kwargs.get('screen_height', 24)
|
|
154
|
+
check_value.check_type(screen_height, int, 'screen_height')
|
|
155
|
+
check_value.check_range(screen_height, 24, 254, 'screen_height')
|
|
156
|
+
self.config.screen_height = screen_height
|
|
157
|
+
|
|
153
158
|
self.connect_core = connect_core.API(self)
|
|
154
159
|
self._exist_board_list = set()
|
|
155
160
|
self._exist_user_list = set()
|
|
@@ -65,6 +65,10 @@ def get_board_list(api) -> list:
|
|
|
65
65
|
cmd = ''.join(cmd_list)
|
|
66
66
|
|
|
67
67
|
board_list = []
|
|
68
|
+
# NOTE: expanded_screen is intentionally NOT used here.
|
|
69
|
+
# get_board_list traverses all boards sequentially; a mid-session NAWS resize
|
|
70
|
+
# causes PTT to render the first page at the old size before the resize takes
|
|
71
|
+
# effect, producing inconsistent page boundaries and skipping boards.
|
|
68
72
|
while True:
|
|
69
73
|
|
|
70
74
|
api.connect_core.send(
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
from typing import Dict, List
|
|
2
|
+
|
|
3
|
+
from . import _api_util
|
|
4
|
+
from . import check_value
|
|
5
|
+
from . import command
|
|
6
|
+
from . import connect_core
|
|
7
|
+
from . import data_type
|
|
8
|
+
from . import exceptions
|
|
9
|
+
from . import i18n
|
|
10
|
+
from . import log
|
|
11
|
+
from . import screens
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def get_post_list(api, board: str, limit: int = 20, offset: int = 0) -> List[Dict]:
|
|
15
|
+
_api_util.one_thread(api)
|
|
16
|
+
|
|
17
|
+
if not api._is_login:
|
|
18
|
+
raise exceptions.RequireLogin(i18n.require_login)
|
|
19
|
+
|
|
20
|
+
check_value.check_type(board, str, 'board')
|
|
21
|
+
if limit is not None:
|
|
22
|
+
check_value.check_type(limit, int, 'limit')
|
|
23
|
+
if offset is not None:
|
|
24
|
+
check_value.check_type(offset, int, 'offset')
|
|
25
|
+
|
|
26
|
+
max_index = api.get_newest_index(data_type.NewIndex.BOARD, board=board)
|
|
27
|
+
|
|
28
|
+
check_value.check_range(limit, min_value=1, max_value=max_index, name='limit')
|
|
29
|
+
check_value.check_range(offset, min_value=0, max_value=max_index - 1, name='offset')
|
|
30
|
+
|
|
31
|
+
start_index = max_index - limit - offset + 1
|
|
32
|
+
end_index = start_index + limit - 1
|
|
33
|
+
|
|
34
|
+
# the first page shows 10 posts, each next page shows 20 posts
|
|
35
|
+
if limit <= 10:
|
|
36
|
+
max_round = 1
|
|
37
|
+
else:
|
|
38
|
+
# 1 is for the first page, +1 is for rounding up
|
|
39
|
+
# so +2
|
|
40
|
+
max_round = (limit - 10) // 20 + 2
|
|
41
|
+
|
|
42
|
+
cmd_list = []
|
|
43
|
+
|
|
44
|
+
cmd_list.append(str(max(1, start_index - 100)))
|
|
45
|
+
cmd_list.append(command.enter)
|
|
46
|
+
cmd_list.append(str(start_index))
|
|
47
|
+
cmd_list.append(command.enter)
|
|
48
|
+
|
|
49
|
+
cmd = ''.join(cmd_list)
|
|
50
|
+
|
|
51
|
+
target_list = [
|
|
52
|
+
connect_core.TargetUnit(screens.Target.InBoard, log_level=log.DEBUG, break_detect=True)
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
post_list = []
|
|
56
|
+
|
|
57
|
+
with _api_util.expanded_screen(api):
|
|
58
|
+
for _ in range(max_round):
|
|
59
|
+
|
|
60
|
+
index = api.connect_core.send(cmd, target_list)
|
|
61
|
+
cmd = command.page_down
|
|
62
|
+
last_screen = api.connect_core.get_screen_queue()[-1]
|
|
63
|
+
|
|
64
|
+
is_parse_area = False
|
|
65
|
+
|
|
66
|
+
for line in last_screen.splitlines()[3:-1]:
|
|
67
|
+
|
|
68
|
+
if not line.startswith(api.cursor) and not is_parse_area:
|
|
69
|
+
continue
|
|
70
|
+
is_parse_area = True
|
|
71
|
+
|
|
72
|
+
if line.strip().startswith(api.cursor):
|
|
73
|
+
# replace the first cursor in the line
|
|
74
|
+
line = line.replace(api.cursor, ' ' * len(api.cursor.encode('big5uao')), 1)
|
|
75
|
+
|
|
76
|
+
if api.cursor == data_type.Cursor.NEW:
|
|
77
|
+
# Pad one leading space so the fixed-column offsets below
|
|
78
|
+
# apply equally to cursor and non-cursor rows. Before the
|
|
79
|
+
# VT100Parser cell-tracking fix, the parser inserted this
|
|
80
|
+
# padding implicitly via its off-by-one column quirk; the
|
|
81
|
+
# offsets here were tuned to that padded layout.
|
|
82
|
+
line = f' {line}'
|
|
83
|
+
|
|
84
|
+
try:
|
|
85
|
+
cur_index = int(line[:8].strip())
|
|
86
|
+
except ValueError:
|
|
87
|
+
# Pinned/announcement posts use '★' instead of a numeric
|
|
88
|
+
# index — they have no sequential index and cannot be
|
|
89
|
+
# fetched by index, so skip them.
|
|
90
|
+
continue
|
|
91
|
+
status = line[8:10].strip()
|
|
92
|
+
comment = line[10:12].strip()
|
|
93
|
+
list_date = line[12:17].strip()
|
|
94
|
+
author = line[18:31].strip()
|
|
95
|
+
title = line[31:]
|
|
96
|
+
|
|
97
|
+
cur_post = {
|
|
98
|
+
data_type.PostField.board: board,
|
|
99
|
+
data_type.PostField.index: cur_index,
|
|
100
|
+
data_type.PostField.list_date: list_date,
|
|
101
|
+
data_type.PostField.author: author,
|
|
102
|
+
data_type.PostField.title: title,
|
|
103
|
+
data_type.PostField.push_number: comment
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
post_list.append(cur_post)
|
|
107
|
+
|
|
108
|
+
if cur_index >= end_index:
|
|
109
|
+
return post_list
|
|
110
|
+
|
|
111
|
+
raise exceptions.UnknownError(i18n.unknown_error)
|
|
@@ -101,51 +101,52 @@ def get_waterball(api, post_action: WaterballPostAction = WaterballPostAction.KE
|
|
|
101
101
|
seen_lines = set()
|
|
102
102
|
all_content_parts = []
|
|
103
103
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
index = api.connect_core.send(cmd, target_list)
|
|
112
|
-
|
|
113
|
-
if index == 0:
|
|
114
|
-
# no waterball records
|
|
115
|
-
api.connect_core.send('q' + command.go_main_menu, [
|
|
116
|
-
connect_core.TargetUnit(screens.Target.MainMenu, log_level=log.DEBUG, break_detect=True),
|
|
117
|
-
])
|
|
118
|
-
log.logger.info(i18n.get_waterball, '...', i18n.success)
|
|
119
|
-
return []
|
|
120
|
-
|
|
121
|
-
if index < 0:
|
|
122
|
-
break
|
|
123
|
-
|
|
124
|
-
screen = api.connect_core.get_screen_queue()[-1]
|
|
125
|
-
for line in screen.split('\n'):
|
|
126
|
-
line = line.strip()
|
|
127
|
-
if line and line not in seen_lines:
|
|
128
|
-
seen_lines.add(line)
|
|
129
|
-
all_content_parts.append(line)
|
|
130
|
-
|
|
131
|
-
if index == 1:
|
|
132
|
-
# WaterBallListEnd — collect done, exit viewer; handle post-action prompt
|
|
133
|
-
action_cmd = _post_action_cmd[post_action]
|
|
134
|
-
target_list_exit = [
|
|
135
|
-
connect_core.TargetUnit(screens.Target.WaterBallPostAction, log_level=log.DEBUG,
|
|
136
|
-
response=action_cmd + command.enter),
|
|
137
|
-
connect_core.TargetUnit(screens.Target.WaterballCleanup, log_level=log.DEBUG,
|
|
138
|
-
response='y' + command.enter),
|
|
139
|
-
connect_core.TargetUnit(screens.Target.MainMenu, log_level=log.DEBUG, break_detect=True),
|
|
104
|
+
with _api_util.expanded_screen(api):
|
|
105
|
+
while True:
|
|
106
|
+
target_list = [
|
|
107
|
+
connect_core.TargetUnit('◆ 暫無訊息記錄', log_level=log.DEBUG, break_detect=True),
|
|
108
|
+
connect_core.TargetUnit(screens.Target.WaterBallListEnd, log_level=log.DEBUG, break_detect=True),
|
|
109
|
+
connect_core.TargetUnit(screens.Target.InWaterBallList, log_level=log.DEBUG, break_detect=True),
|
|
140
110
|
]
|
|
141
|
-
|
|
142
|
-
api.connect_core.send(
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
111
|
+
|
|
112
|
+
index = api.connect_core.send(cmd, target_list)
|
|
113
|
+
|
|
114
|
+
if index == 0:
|
|
115
|
+
# no waterball records
|
|
116
|
+
api.connect_core.send('q' + command.go_main_menu, [
|
|
117
|
+
connect_core.TargetUnit(screens.Target.MainMenu, log_level=log.DEBUG, break_detect=True),
|
|
118
|
+
])
|
|
119
|
+
log.logger.info(i18n.get_waterball, '...', i18n.success)
|
|
120
|
+
return []
|
|
121
|
+
|
|
122
|
+
if index < 0:
|
|
123
|
+
break
|
|
124
|
+
|
|
125
|
+
screen = api.connect_core.get_screen_queue()[-1]
|
|
126
|
+
for line in screen.split('\n'):
|
|
127
|
+
line = line.strip()
|
|
128
|
+
if line and line not in seen_lines:
|
|
129
|
+
seen_lines.add(line)
|
|
130
|
+
all_content_parts.append(line)
|
|
131
|
+
|
|
132
|
+
if index == 1:
|
|
133
|
+
# WaterBallListEnd — collect done, exit viewer; handle post-action prompt
|
|
134
|
+
action_cmd = _post_action_cmd[post_action]
|
|
135
|
+
target_list_exit = [
|
|
136
|
+
connect_core.TargetUnit(screens.Target.WaterBallPostAction, log_level=log.DEBUG,
|
|
137
|
+
response=action_cmd + command.enter),
|
|
138
|
+
connect_core.TargetUnit(screens.Target.WaterballCleanup, log_level=log.DEBUG,
|
|
139
|
+
response='y' + command.enter),
|
|
140
|
+
connect_core.TargetUnit(screens.Target.MainMenu, log_level=log.DEBUG, break_detect=True),
|
|
141
|
+
]
|
|
142
|
+
api.connect_core.send('q', target_list_exit)
|
|
143
|
+
api.connect_core.send(command.go_main_menu, [
|
|
144
|
+
connect_core.TargetUnit(screens.Target.MainMenu, log_level=log.DEBUG, break_detect=True),
|
|
145
|
+
])
|
|
146
|
+
break
|
|
147
|
+
|
|
148
|
+
# index == 2: InWaterBallList — next page
|
|
149
|
+
cmd = command.ctrl_f
|
|
149
150
|
|
|
150
151
|
result = []
|
|
151
152
|
for line in _merge_continuation_lines(all_content_parts):
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import re
|
|
2
|
+
|
|
3
|
+
from . import _api_util
|
|
4
|
+
from . import command
|
|
5
|
+
from . import connect_core
|
|
6
|
+
from . import log
|
|
7
|
+
from . import screens
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def has_new_mail(api) -> int:
|
|
11
|
+
cmd_list = []
|
|
12
|
+
cmd_list.append(command.go_main_menu)
|
|
13
|
+
cmd_list.append(command.ctrl_z)
|
|
14
|
+
cmd_list.append('m')
|
|
15
|
+
# cmd_list.append('1')
|
|
16
|
+
# cmd_list.append(command.enter)
|
|
17
|
+
cmd = ''.join(cmd_list)
|
|
18
|
+
current_capacity = None
|
|
19
|
+
plus_count = 0
|
|
20
|
+
index_pattern = re.compile(r'(\d+)')
|
|
21
|
+
checked_index_list = []
|
|
22
|
+
break_detect = False
|
|
23
|
+
|
|
24
|
+
target_list = [
|
|
25
|
+
connect_core.TargetUnit(screens.Target.InMailBox, log_level=log.DEBUG, break_detect=True)
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
api.connect_core.send(
|
|
29
|
+
cmd,
|
|
30
|
+
target_list,
|
|
31
|
+
)
|
|
32
|
+
current_capacity, _ = _api_util.get_mailbox_capacity(api)
|
|
33
|
+
if current_capacity > 20:
|
|
34
|
+
cmd_list = []
|
|
35
|
+
cmd_list.append(command.go_main_menu)
|
|
36
|
+
cmd_list.append(command.ctrl_z)
|
|
37
|
+
cmd_list.append('m')
|
|
38
|
+
cmd_list.append('1')
|
|
39
|
+
cmd_list.append(command.enter)
|
|
40
|
+
cmd = ''.join(cmd_list)
|
|
41
|
+
|
|
42
|
+
with _api_util.expanded_screen(api):
|
|
43
|
+
while True:
|
|
44
|
+
if current_capacity > 20:
|
|
45
|
+
api.connect_core.send(
|
|
46
|
+
cmd,
|
|
47
|
+
target_list,
|
|
48
|
+
)
|
|
49
|
+
last_screen = api.connect_core.get_screen_queue()[-1]
|
|
50
|
+
|
|
51
|
+
last_screen_list = last_screen.split('\n')
|
|
52
|
+
last_screen_list = last_screen_list[3:-1]
|
|
53
|
+
last_screen_list = [x[:10] for x in last_screen_list]
|
|
54
|
+
|
|
55
|
+
current_plus_count = 0
|
|
56
|
+
for line in last_screen_list:
|
|
57
|
+
if str(current_capacity) in line:
|
|
58
|
+
break_detect = True
|
|
59
|
+
|
|
60
|
+
index_result = index_pattern.search(line)
|
|
61
|
+
if index_result is None:
|
|
62
|
+
continue
|
|
63
|
+
current_index = index_result.group(0)
|
|
64
|
+
if current_index in checked_index_list:
|
|
65
|
+
continue
|
|
66
|
+
checked_index_list.append(current_index)
|
|
67
|
+
if '+' not in line:
|
|
68
|
+
continue
|
|
69
|
+
|
|
70
|
+
current_plus_count += 1
|
|
71
|
+
|
|
72
|
+
plus_count += current_plus_count
|
|
73
|
+
if break_detect:
|
|
74
|
+
break
|
|
75
|
+
cmd = command.ctrl_f
|
|
76
|
+
|
|
77
|
+
return plus_count
|