sergey21000 commited on
Commit
c7c4ce5
·
verified ·
1 Parent(s): 87030e2

Update utils/components.py

Browse files
Files changed (1) hide show
  1. utils/components.py +270 -270
utils/components.py CHANGED
@@ -1,270 +1,270 @@
1
- import os
2
- from pathlib import Path
3
- from typing import Callable, Collection
4
-
5
- import gradio as gr
6
- from telethon.sessions import SQLiteSession, MemorySession
7
-
8
- from utils.auth import AuthState
9
- from utils.parser import Parser
10
- from utils.validation import Validator
11
-
12
-
13
- class Components:
14
-
15
- welcome_message_markdown = '''
16
- <h5 style='text-align: center'>
17
- Парсер сообщений Telegram
18
- </h5>
19
- <h6 style='text-align: center'>
20
- <a
21
- href="https://github.com/sergey21000/telegram-message-parser"
22
- target='_blank'>GitHub
23
- </a>
24
- проекта с инструкциями по получению `API_ID` и `API_HASH` приложения Telegram
25
- </h6>
26
- '''
27
-
28
- @staticmethod
29
- def _create_env_var_textbox(
30
- env_var: str | None = None,
31
- validator_method: Callable | None = None,
32
- **kwargs,
33
- ) -> gr.Textbox:
34
- value = None
35
- if env_var and validator_method:
36
- validation_result = validator_method()
37
- if validation_result.is_valid:
38
- value = os.getenv(env_var)
39
- curr_kwargs = dict(value=value)
40
- curr_kwargs.update(kwargs)
41
- return gr.Textbox(**curr_kwargs)
42
-
43
- @classmethod
44
- def api_id(cls) -> gr.Textbox:
45
- return cls._create_env_var_textbox(
46
- env_var='API_ID',
47
- validator_method=Validator.validate_env_id,
48
- label='API_ID Telegram app',
49
- placeholder='API_ID приложения Telegram',
50
- scale=1,
51
- )
52
-
53
- @classmethod
54
- def api_hash(cls) -> gr.Textbox:
55
- return cls._create_env_var_textbox(
56
- env_var='API_HASH',
57
- validator_method=Validator.validate_env_hash,
58
- label='API_HASH Telegram app',
59
- placeholder='API_HASH приложения Telegram',
60
- scale=1,
61
- )
62
-
63
- @classmethod
64
- def phone_number(cls) -> gr.Textbox:
65
- return cls._create_env_var_textbox(
66
- env_var='PHONE_NUMBER',
67
- validator_method=Validator.validate_env_phone_number,
68
- label='PHONE_NUMBER Telegram app',
69
- placeholder='PHONE_NUMBER приложения Telegram',
70
- scale=1,
71
- )
72
-
73
- @staticmethod
74
- def code(visible: str = False, render: bool = True) -> gr.Textbox:
75
- component = gr.Textbox(
76
- value=None,
77
- label='Проверочный код',
78
- visible=visible,
79
- render=render,
80
- placeholder=None,
81
- scale=1,
82
- )
83
- return component
84
-
85
- @staticmethod
86
- def password_2fa(visible: str = False, render: bool = True) -> gr.Textbox:
87
- component = gr.Textbox(
88
- type='password',
89
- value=None,
90
- label='Облачный пароль',
91
- visible=visible,
92
- render=render,
93
- placeholder=None,
94
- scale=1,
95
- )
96
- return component
97
-
98
- @staticmethod
99
- def auth_status(value: str | None = None) -> gr.Textbox:
100
- component = gr.Textbox(
101
- value=value,
102
- label='Статус авторизации',
103
- placeholder=None,
104
- interactive=False,
105
- scale=1,
106
- )
107
- return component
108
-
109
- @staticmethod
110
- def auth_btn(interactive: bool = True) -> gr.Button:
111
- component = gr.Button(
112
- value='Авторизация',
113
- interactive=interactive,
114
- scale=1,
115
- )
116
- return component
117
-
118
- @staticmethod
119
- def code_btn(visible: bool = False, render: bool = True) -> gr.Button:
120
- component = gr.Button(
121
- value='Подтвержение кода',
122
- visible=visible,
123
- render=render,
124
- scale=0,
125
- )
126
- return component
127
-
128
- @staticmethod
129
- def password_2fa_btn(visible: bool = False, render: bool = True) -> gr.Button:
130
- component = gr.Button(
131
- value='Подтверждение облачного пароля',
132
- visible=visible,
133
- render=render,
134
- scale=0,
135
- )
136
- return component
137
-
138
- @staticmethod
139
- def delete_session_btn(visible: bool = False, render: bool = True) -> gr.Button:
140
- component = gr.Button(
141
- value='Удаление сессии',
142
- visible=visible,
143
- render=render,
144
- scale=1,
145
- )
146
- return component
147
-
148
- @classmethod
149
- def session_type_radio(cls) -> gr.Radio:
150
- session_types = {'sqlite': SQLiteSession, 'memory': MemorySession}
151
- component = gr.Radio(
152
- choices=session_types,
153
- value='sqlite',
154
- label='Тип сессии',
155
- info=None, # cls.session_type_markdown
156
- )
157
- return component
158
-
159
- @staticmethod
160
- def chats_usernames() -> gr.Textbox:
161
- component = gr.Textbox(
162
- label='Адреса чатов',
163
- placeholder='Ссылки или ID чатов/каналов через пробел или перенос строки',
164
- scale=1,
165
- lines=2,
166
- )
167
- return component
168
-
169
- @staticmethod
170
- def add_chat_btn() -> gr.Button:
171
- component = gr.Button(
172
- value='Добавить чат/чаты',
173
- scale=0,
174
- )
175
- return component
176
-
177
- @staticmethod
178
- def chats_list_status() -> gr.Textbox:
179
- component = gr.Textbox(
180
- label='Добавленные чаты',
181
- placeholder='Здесь будет список чатов для парсинга',
182
- scale=1,
183
- lines=3,
184
- )
185
- return component
186
-
187
- @staticmethod
188
- def parse_status() -> gr.Textbox:
189
- component = gr.Textbox(
190
- label='Статус парсинга',
191
- placeholder='Здесь будет отчет о результатах парсинга',
192
- scale=1,
193
- lines=8,
194
- )
195
- return component
196
-
197
- @staticmethod
198
- def start_parse_btn() -> gr.Button:
199
- component = gr.Button(
200
- value='Начать парсинг',
201
- scale=0,
202
- )
203
- return component
204
-
205
- @staticmethod
206
- def download_btn(value: str | None = None) -> gr.Button:
207
- component = gr.DownloadButton(
208
- label='Загрузить csv результаты',
209
- value=value,
210
- visible=value is not None,
211
- scale=0,
212
- )
213
- return component
214
-
215
- @staticmethod
216
- def get_parse_args() -> list[gr.component]:
217
- limit = gr.Number(
218
- value=None,
219
- label='limit',
220
- info='Сколько сообщений парсить',
221
- )
222
- offset_date = gr.DateTime(
223
- value=None,
224
- label='offset_date',
225
- info='До какой даты парсить',
226
- timezone='Europe/Moscow',
227
- )
228
- reverse = gr.Checkbox(
229
- value=False,
230
- label='reverse',
231
- info='Парсить от сегодняшнего сообщения к самому раннему',
232
- )
233
- parse_args = [limit, offset_date, reverse]
234
- return parse_args
235
-
236
-
237
- class ComponentsFn(Components):
238
- @staticmethod
239
- def update_status(auth_state: AuthState) -> str | None:
240
- return auth_state.message
241
-
242
- @classmethod
243
- def get_dynamic_visible_components(cls, auth_state: AuthState, render: bool = True) -> tuple[gr.component]:
244
- code = cls.code(visible=auth_state.need_verify_code, render=render)
245
- code_btn = cls.code_btn(visible=auth_state.need_verify_code, render=render)
246
-
247
- password_2fa = cls.password_2fa(visible=auth_state.need_verify_2fa, render=render)
248
- password_2fa_btn = cls.password_2fa_btn(visible=auth_state.need_verify_2fa, render=render)
249
-
250
- delete_session_btn = cls.delete_session_btn(visible=auth_state.is_auth, render=render)
251
- return code, code_btn, password_2fa, password_2fa_btn, delete_session_btn
252
-
253
- @staticmethod
254
- def update_auth_state_session_type(auth_state: AuthState, session_type: str) -> None:
255
- auth_state.change_session_type(session_type)
256
-
257
- @staticmethod
258
- async def delete_session(auth_state: AuthState) -> None:
259
- await auth_state.delete_session()
260
-
261
- @classmethod
262
- def update_download_btn(cls, csv_paths: Collection[Path]) -> gr.Button | None:
263
- if len(csv_paths) == 0:
264
- return None
265
- elif len(csv_paths) == 1:
266
- filepath = csv_paths[0]
267
- else:
268
- filepath = Parser.zip_files(csv_paths)
269
- component = cls.download_btn(value=filepath)
270
- return component
 
1
+ import os
2
+ from pathlib import Path
3
+ from typing import Callable, Collection
4
+
5
+ import gradio as gr
6
+ from telethon.sessions import SQLiteSession, MemorySession
7
+
8
+ from utils.auth import AuthState
9
+ from utils.parser import Parser
10
+ from utils.validation import Validator
11
+
12
+
13
+ class Components:
14
+
15
+ welcome_message_markdown = '''
16
+ <h5 style='text-align: center'>
17
+ Парсер сообщений Telegram
18
+ </h5>
19
+ <h6 style='text-align: center'>
20
+ <a
21
+ href="https://github.com/sergey21000/telegram-message-parser"
22
+ target='_blank'>GitHub
23
+ </a>
24
+ проекта с инструкциями по получению `API_ID` и `API_HASH` приложения Telegram
25
+ </h6>
26
+ '''
27
+
28
+ @staticmethod
29
+ def _create_env_var_textbox(
30
+ env_var: str | None = None,
31
+ validator_method: Callable | None = None,
32
+ **kwargs,
33
+ ) -> gr.Textbox:
34
+ value = None
35
+ if env_var and validator_method:
36
+ validation_result = validator_method()
37
+ if validation_result.is_valid:
38
+ value = os.getenv(env_var)
39
+ curr_kwargs = dict(value=value)
40
+ curr_kwargs.update(kwargs)
41
+ return gr.Textbox(**curr_kwargs)
42
+
43
+ @classmethod
44
+ def api_id(cls) -> gr.Textbox:
45
+ return cls._create_env_var_textbox(
46
+ env_var='API_ID',
47
+ validator_method=Validator.validate_env_id,
48
+ label='API_ID Telegram app',
49
+ placeholder='API_ID приложения Telegram',
50
+ scale=1,
51
+ )
52
+
53
+ @classmethod
54
+ def api_hash(cls) -> gr.Textbox:
55
+ return cls._create_env_var_textbox(
56
+ env_var='API_HASH',
57
+ validator_method=Validator.validate_env_hash,
58
+ label='API_HASH Telegram app',
59
+ placeholder='API_HASH приложения Telegram',
60
+ scale=1,
61
+ )
62
+
63
+ @classmethod
64
+ def phone_number(cls) -> gr.Textbox:
65
+ return cls._create_env_var_textbox(
66
+ env_var='PHONE_NUMBER',
67
+ validator_method=Validator.validate_env_phone_number,
68
+ label='PHONE_NUMBER Telegram app',
69
+ placeholder='PHONE_NUMBER приложения Telegram',
70
+ scale=1,
71
+ )
72
+
73
+ @staticmethod
74
+ def code(visible: str = False, render: bool = True) -> gr.Textbox:
75
+ component = gr.Textbox(
76
+ value=None,
77
+ label='Проверочный код',
78
+ visible=visible,
79
+ render=render,
80
+ placeholder=None,
81
+ scale=1,
82
+ )
83
+ return component
84
+
85
+ @staticmethod
86
+ def password_2fa(visible: str = False, render: bool = True) -> gr.Textbox:
87
+ component = gr.Textbox(
88
+ type='password',
89
+ value=None,
90
+ label='Облачный пароль',
91
+ visible=visible,
92
+ render=render,
93
+ placeholder=None,
94
+ scale=1,
95
+ )
96
+ return component
97
+
98
+ @staticmethod
99
+ def auth_status(value: str | None = None) -> gr.Textbox:
100
+ component = gr.Textbox(
101
+ value=value,
102
+ label='Статус авторизации',
103
+ placeholder=None,
104
+ interactive=False,
105
+ scale=1,
106
+ )
107
+ return component
108
+
109
+ @staticmethod
110
+ def auth_btn(interactive: bool = True) -> gr.Button:
111
+ component = gr.Button(
112
+ value='Авторизация',
113
+ interactive=interactive,
114
+ scale=1,
115
+ )
116
+ return component
117
+
118
+ @staticmethod
119
+ def code_btn(visible: bool = False, render: bool = True) -> gr.Button:
120
+ component = gr.Button(
121
+ value='Подтвержение кода',
122
+ visible=visible,
123
+ render=render,
124
+ scale=0,
125
+ )
126
+ return component
127
+
128
+ @staticmethod
129
+ def password_2fa_btn(visible: bool = False, render: bool = True) -> gr.Button:
130
+ component = gr.Button(
131
+ value='Подтверждение облачного пароля',
132
+ visible=visible,
133
+ render=render,
134
+ scale=0,
135
+ )
136
+ return component
137
+
138
+ @staticmethod
139
+ def delete_session_btn(visible: bool = False, render: bool = True) -> gr.Button:
140
+ component = gr.Button(
141
+ value='Удаление сессии',
142
+ visible=visible,
143
+ render=render,
144
+ scale=1,
145
+ )
146
+ return component
147
+
148
+ @classmethod
149
+ def session_type_radio(cls) -> gr.Radio:
150
+ session_types = {'sqlite': SQLiteSession, 'memory': MemorySession}
151
+ component = gr.Radio(
152
+ choices=session_types,
153
+ value='memory',
154
+ label='Тип сессии',
155
+ info=None, # cls.session_type_markdown
156
+ )
157
+ return component
158
+
159
+ @staticmethod
160
+ def chats_usernames() -> gr.Textbox:
161
+ component = gr.Textbox(
162
+ label='Адреса чатов',
163
+ placeholder='Ссылки или ID чатов/каналов через пробел или перенос строки',
164
+ scale=1,
165
+ lines=2,
166
+ )
167
+ return component
168
+
169
+ @staticmethod
170
+ def add_chat_btn() -> gr.Button:
171
+ component = gr.Button(
172
+ value='Добавить чат/чаты',
173
+ scale=0,
174
+ )
175
+ return component
176
+
177
+ @staticmethod
178
+ def chats_list_status() -> gr.Textbox:
179
+ component = gr.Textbox(
180
+ label='Добавленные чаты',
181
+ placeholder='Здесь будет список чатов для парсинга',
182
+ scale=1,
183
+ lines=3,
184
+ )
185
+ return component
186
+
187
+ @staticmethod
188
+ def parse_status() -> gr.Textbox:
189
+ component = gr.Textbox(
190
+ label='Статус парсинга',
191
+ placeholder='Здесь будет отчет о результатах парсинга',
192
+ scale=1,
193
+ lines=8,
194
+ )
195
+ return component
196
+
197
+ @staticmethod
198
+ def start_parse_btn() -> gr.Button:
199
+ component = gr.Button(
200
+ value='Начать парсинг',
201
+ scale=0,
202
+ )
203
+ return component
204
+
205
+ @staticmethod
206
+ def download_btn(value: str | None = None) -> gr.Button:
207
+ component = gr.DownloadButton(
208
+ label='Загрузить csv результаты',
209
+ value=value,
210
+ visible=value is not None,
211
+ scale=0,
212
+ )
213
+ return component
214
+
215
+ @staticmethod
216
+ def get_parse_args() -> list[gr.component]:
217
+ limit = gr.Number(
218
+ value=None,
219
+ label='limit',
220
+ info='Сколько сообщений парсить',
221
+ )
222
+ offset_date = gr.DateTime(
223
+ value=None,
224
+ label='offset_date',
225
+ info='До какой даты парсить',
226
+ timezone='Europe/Moscow',
227
+ )
228
+ reverse = gr.Checkbox(
229
+ value=False,
230
+ label='reverse',
231
+ info='Парсить от сегодняшнего сообщения к самому раннему',
232
+ )
233
+ parse_args = [limit, offset_date, reverse]
234
+ return parse_args
235
+
236
+
237
+ class ComponentsFn(Components):
238
+ @staticmethod
239
+ def update_status(auth_state: AuthState) -> str | None:
240
+ return auth_state.message
241
+
242
+ @classmethod
243
+ def get_dynamic_visible_components(cls, auth_state: AuthState, render: bool = True) -> tuple[gr.component]:
244
+ code = cls.code(visible=auth_state.need_verify_code, render=render)
245
+ code_btn = cls.code_btn(visible=auth_state.need_verify_code, render=render)
246
+
247
+ password_2fa = cls.password_2fa(visible=auth_state.need_verify_2fa, render=render)
248
+ password_2fa_btn = cls.password_2fa_btn(visible=auth_state.need_verify_2fa, render=render)
249
+
250
+ delete_session_btn = cls.delete_session_btn(visible=auth_state.is_auth, render=render)
251
+ return code, code_btn, password_2fa, password_2fa_btn, delete_session_btn
252
+
253
+ @staticmethod
254
+ def update_auth_state_session_type(auth_state: AuthState, session_type: str) -> None:
255
+ auth_state.change_session_type(session_type)
256
+
257
+ @staticmethod
258
+ async def delete_session(auth_state: AuthState) -> None:
259
+ await auth_state.delete_session()
260
+
261
+ @classmethod
262
+ def update_download_btn(cls, csv_paths: Collection[Path]) -> gr.Button | None:
263
+ if len(csv_paths) == 0:
264
+ return None
265
+ elif len(csv_paths) == 1:
266
+ filepath = csv_paths[0]
267
+ else:
268
+ filepath = Parser.zip_files(csv_paths)
269
+ component = cls.download_btn(value=filepath)
270
+ return component