GmailTrust commited on
Commit
f5f5cca
·
verified ·
1 Parent(s): 2b18568

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +99 -166
app.py CHANGED
@@ -2,27 +2,24 @@ import os
2
  import re
3
  import gradio as gr
4
  import pandas as pd
5
- from mega import Mega
6
- from io import StringIO
7
- import logging
8
-
9
- # Cấu hình logging để debug
10
- logging.basicConfig(level=logging.DEBUG)
11
- logger = logging.getLogger(__name__)
12
-
13
- # Lấy thông tin từ biến môi trường
14
- MEGA_EMAIL = os.getenv("MEGA_EMAIL", "your_mega_email@example.com")
15
- MEGA_PASSWORD = os.getenv("MEGA_PASSWORD", "your_mega_password")
16
- MEGA_FOLDER = os.getenv("MEGA_FOLDER", "/EmailProcessor")
17
-
18
- # Khởi tạo Mega client
19
- try:
20
- logger.debug(f"Đang đăng nhập với email: {MEGA_EMAIL}")
21
- mega = Mega().login(MEGA_EMAIL, MEGA_PASSWORD)
22
- logger.debug("Đăng nhập thành công!")
23
- except Exception as e:
24
- logger.error(f"Lỗi đăng nhập Mega: {str(e)}")
25
- raise
26
 
27
  def count_emails(data):
28
  if not data or isinstance(data, str) and data.startswith("Lỗi"):
@@ -31,10 +28,9 @@ def count_emails(data):
31
  return len(lines)
32
 
33
  def split_emails(input_data, uploaded_file):
34
- global TEMP_FILE_CONTENT
35
  data = input_data if input_data else read_file(uploaded_file)
36
  if not data:
37
- return "Cảnh báo: Không có dữ liệu.", gr.update(label="Input Text (Total: 0)"), gr.update(value="", label="Output Text (Total: 0)"), None, None
38
 
39
  lines = data.splitlines()
40
  gmail_addresses = []
@@ -42,45 +38,30 @@ def split_emails(input_data, uploaded_file):
42
  for line in lines:
43
  if not line.strip():
44
  continue
 
45
  match = re.search(r'([a-zA-Z0-9._%+-]+@gmail\.com)', line)
46
  if match:
47
  gmail_addresses.append(match.group(1) + '\n')
48
 
49
- # Lưu dữ liệu tạm
50
- TEMP_FILE_CONTENT = "\n".join(lines) + "\n"
 
51
  output_data = "".join(gmail_addresses)
52
  input_total = count_emails(data)
53
  output_total = count_emails(output_data)
54
-
55
- # Upload lên Mega
56
- file_name = "private_output.txt"
57
- try:
58
- with open(file_name, "w", encoding="utf-8") as f:
59
- f.writelines(gmail_addresses)
60
- m = mega.get_root()
61
- m = mega.find(m, MEGA_FOLDER)
62
- if not m:
63
- logger.debug(f"Tạo thư mục {MEGA_FOLDER} trên Mega")
64
- m = mega.create_folder(MEGA_FOLDER)
65
- mega.upload(file_name, m)
66
- os.remove(file_name)
67
- logger.debug(f"Đã upload {file_name} lên {MEGA_FOLDER}")
68
- except Exception as e:
69
- logger.error(f"Lỗi upload lên Mega: {str(e)}")
70
- return f"Lỗi khi upload lên Mega: {str(e)}. Vui lòng kiểm tra email/mật khẩu hoặc kết nối.", gr.update(value=data, label=f"Input Text (Total: {input_total})"), gr.update(value=output_data, label=f"Output Text (Total: {output_total})"), None, None
71
-
72
- return f"Đã lưu kết quả lên Mega tại {MEGA_FOLDER}/{file_name}.", gr.update(value=data, label=f"Input Text (Total: {input_total})"), gr.update(value=output_data, label=f"Output Text (Total: {output_total})"), download_output(data, output_data), None
73
 
74
  def fill_missing_parts(input_data, uploaded_file):
75
- global TEMP_FILE_CONTENT
76
  data = input_data if input_data else read_file(uploaded_file)
77
  if not data:
78
- return "Cảnh báo: Không có dữ liệu.", gr.update(label="Input Text (Total: 0)"), gr.update(value="", label="Output Text (Total: 0)"), None, None
 
 
 
79
 
80
- if not TEMP_FILE_CONTENT:
81
- return "Lỗi: Không tìm thấy dữ liệu tạm. Vui lòng chạy Split Emails trước.", gr.update(label="Input Text (Total: 0)"), gr.update(value="", label="Output Text (Total: 0)"), None, None
82
 
83
- temp_lines = {line.strip() for line in TEMP_FILE_CONTENT.splitlines() if line.strip()}
84
  input_emails = [line.strip() for line in data.splitlines() if line.strip()]
85
  output_lines = []
86
 
@@ -92,139 +73,91 @@ def fill_missing_parts(input_data, uploaded_file):
92
  output_data = "".join(output_lines)
93
  input_total = count_emails(data)
94
  output_total = count_emails(output_data)
95
- return f"Đã xử lý.", gr.update(value=data, label=f"Input Text (Total: {input_total})"), gr.update(value=output_data, label=f"Output Text (Total: {output_total})"), download_output(data, output_data), None
96
 
97
- def clear_files():
98
- # Không xóa dữ liệu tạm theo yêu cầu
99
- return "Nút xóa không có tác dụng. Dữ liệu tạm được giữ nguyên.", gr.update(value="", label="Input Text (Total: 0)"), gr.update(value="", label="Output Text (Total: 0)"), None, None
100
 
101
- def read_file(file):
102
- if file is None:
103
- return ""
104
- try:
105
- with open(file, 'r', encoding='utf-8') as f:
106
- return f.read()
107
- except Exception as e:
108
- return f"Lỗi khi đọc file: {str(e)}"
 
 
 
 
 
109
 
110
- def download_output(input_data, output_data):
111
  if not output_data:
112
- return None
113
- return gr.File(value=StringIO(output_data), label="Download Output", file_type="text/plain", file_name="private_output.txt")
114
-
115
- # Biến toàn cục để lưu dữ liệu tạm
116
- TEMP_FILE_CONTENT = ""
117
-
118
- custom_css = """
119
- :root {
120
- --primary-color: #6e48aa;
121
- --dark-color: #121212;
122
- --darker-color: #0a0a0a;
123
- --light-color: #e0e0e0;
124
- --text-color: #f5f5f5;
125
- --border-color: #333;
126
- --card-bg: #1e1e1e;
127
- --input-bg: #252525;
128
- }
129
-
130
- body {
131
- font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
132
- background-color: var(--darker-color) !important;
133
- color: var(--text-color) !important;
134
- margin: 0;
135
- padding: 20px;
136
- }
137
-
138
- .gr-block {
139
- border-radius: 8px !important;
140
- box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3) !important;
141
- background-color: var(--card-bg) !important;
142
- border: 1px solid var(--border-color) !important;
143
- margin-bottom: 15px !important;
144
- }
145
-
146
- .gr-box {
147
- border: 1px solid var(--border-color) !important;
148
- border-radius: 6px !important;
149
- padding: 12px !important;
150
- background-color: var(--input-bg) !important;
151
- }
152
-
153
- .textbox-fixed-height textarea {
154
- height: 250px !important;
155
- overflow-y: auto !important;
156
- resize: none !important;
157
- font-family: monospace !important;
158
- background-color: var(--input-bg) !important;
159
- color: var(--light-color) !important;
160
- border: 1px solid var(--border-color) !important;
161
- }
162
-
163
- button {
164
- border-radius: 6px !important;
165
- font-weight: 500 !important;
166
- transition: all 0.3s ease !important;
167
- padding: 8px 16px !important;
168
- margin: 4px !important;
169
- border: none !important;
170
- }
171
-
172
- button:hover {
173
- transform: translateY(-2px) !important;
174
- box-shadow: 0 6px 12px rgba(0,0,0,0.2) !important;
175
- opacity: 0.9 !important;
176
- }
177
-
178
- .primary-btn {
179
- background: linear-gradient(135deg, var(--primary-color), #9d50bb) !important;
180
- color: white !important;
181
- }
182
-
183
- .danger-btn {
184
- background: linear-gradient(135deg, #f85032, #e73827) !important;
185
- color: white !important;
186
- }
187
-
188
- .status-box {
189
- background-color: var(--card-bg) !important;
190
- border-left: 4px solid var(--primary-color) !important;
191
- padding: 14px !important;
192
- margin-top: 15px !important;
193
- color: var(--light-color) !important;
194
- }
195
- """
196
-
197
- with gr.Blocks(title="Email Processor", theme=gr.themes.Soft(), css=custom_css) as demo:
198
  with gr.Row(equal_height=True):
199
  with gr.Column(scale=1):
200
  input_text = gr.Textbox(label="Input Text", lines=10,
201
- placeholder="Nhập dữ liệu hoặc tải file .txt lên...\nĐịnh dạng hỗ trợ: email|data hoặc email;data hoặc email:data hoặc email<tab>data",
202
- elem_classes="textbox-fixed-height")
 
203
  with gr.Row():
204
- upload_file = gr.File(label="📤 Upload File (.txt)", file_types=[".txt"], elem_classes="file-upload")
205
 
206
  with gr.Column(scale=1):
207
- output_text = gr.Textbox(label="Output Text", lines=10, interactive=False,
208
- elem_classes="textbox-fixed-height")
209
- download_file = gr.File(label="📥 Download Output", interactive=False)
 
 
 
210
 
211
- status = gr.Textbox(label="🔄 Status", interactive=False, elem_classes="status-box")
212
 
213
  with gr.Tabs():
214
  with gr.Tab("🔧 Email Tools"):
215
  with gr.Row():
216
- with gr.Column():
217
- split_btn = gr.Button("✂️ Split Emails", elem_classes="primary-btn")
218
-
219
- with gr.Column():
220
- fill_btn = gr.Button("🔍 Fill Missing", elem_classes="primary-btn")
221
-
222
  with gr.Row():
223
- clear_files_btn = gr.Button("🧹 Clear All Data", elem_classes="danger-btn", size="lg")
224
 
225
- # Kết nối các sự kiện
226
- split_btn.click(split_emails, inputs=[input_text, upload_file], outputs=[status, input_text, output_text, download_file, upload_file])
227
- fill_btn.click(fill_missing_parts, inputs=[input_text, upload_file], outputs=[status, input_text, output_text, download_file, upload_file])
228
  clear_files_btn.click(clear_files, outputs=[status, input_text, output_text, download_file, upload_file])
 
 
 
229
 
230
- demo.launch()
 
2
  import re
3
  import gradio as gr
4
  import pandas as pd
5
+
6
+ # Các biến toàn cục
7
+ OUTPUT_FILE_TXT = "output.txt"
8
+ OUTPUT_FILE_XLSX = "output.xlsx"
9
+ TEMP_FILE = "temp.txt" # Biến tạm lưu dữ liệu sau split
10
+
11
+ def write_file(file_path, data):
12
+ with open(file_path, 'w', encoding='utf-8') as file:
13
+ file.writelines(data)
14
+
15
+ def read_file(file):
16
+ if file is None:
17
+ return ""
18
+ try:
19
+ with open(file, 'r', encoding='utf-8') as f:
20
+ return f.read()
21
+ except Exception as e:
22
+ return f"Lỗi khi đọc file: {str(e)}"
 
 
 
23
 
24
  def count_emails(data):
25
  if not data or isinstance(data, str) and data.startswith("Lỗi"):
 
28
  return len(lines)
29
 
30
  def split_emails(input_data, uploaded_file):
 
31
  data = input_data if input_data else read_file(uploaded_file)
32
  if not data:
33
+ return "Cảnh báo: Không có dữ liệu.", gr.update(label="Input Text (Total: 0)"), gr.update(value="", label="Output Text (Total: 0)"), None
34
 
35
  lines = data.splitlines()
36
  gmail_addresses = []
 
38
  for line in lines:
39
  if not line.strip():
40
  continue
41
+
42
  match = re.search(r'([a-zA-Z0-9._%+-]+@gmail\.com)', line)
43
  if match:
44
  gmail_addresses.append(match.group(1) + '\n')
45
 
46
+ # Lưu dữ liệu gốc vào biến tạm (không tự xóa)
47
+ write_file(TEMP_FILE, [line + '\n' for line in lines])
48
+
49
  output_data = "".join(gmail_addresses)
50
  input_total = count_emails(data)
51
  output_total = count_emails(output_data)
52
+ return f"Đã lưu kết quả.", gr.update(value=data, label=f"Input Text (Total: {input_total})"), gr.update(value=output_data, label=f"Output Text (Total: {output_total})"), None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
 
54
  def fill_missing_parts(input_data, uploaded_file):
 
55
  data = input_data if input_data else read_file(uploaded_file)
56
  if not data:
57
+ return "Cảnh báo: Không có dữ liệu.", gr.update(label="Input Text (Total: 0)"), gr.update(value="", label="Output Text (Total: 0)"), None
58
+
59
+ if not os.path.exists(TEMP_FILE):
60
+ return "Lỗi: Không tìm thấy file tạm. Vui lòng chạy Split Emails trước.", gr.update(label="Input Text (Total: 0)"), gr.update(value="", label="Output Text (Total: 0)"), None
61
 
62
+ with open(TEMP_FILE, 'r', encoding='utf-8') as file:
63
+ temp_lines = {line.strip() for line in file}
64
 
 
65
  input_emails = [line.strip() for line in data.splitlines() if line.strip()]
66
  output_lines = []
67
 
 
73
  output_data = "".join(output_lines)
74
  input_total = count_emails(data)
75
  output_total = count_emails(output_data)
76
+ return f"Đã lưu kết quả.", gr.update(value=data, label=f"Input Text (Total: {input_total})"), gr.update(value=output_data, label=f"Output Text (Total: {output_total})"), None
77
 
78
+ def clear_input(input_data, output_data, uploaded_file):
79
+ return "", gr.update(value="", label="Input Text (Total: 0)"), gr.update(value=output_data, label=f"Output Text (Total: {count_emails(output_data)})"), None, "Đã xóa input."
 
80
 
81
+ def clear_output(input_data, output_data, uploaded_file):
82
+ if os.path.exists(OUTPUT_FILE_TXT):
83
+ os.remove(OUTPUT_FILE_TXT)
84
+ if os.path.exists(OUTPUT_FILE_XLSX):
85
+ os.remove(OUTPUT_FILE_XLSX)
86
+ return "Đã xóa output.", gr.update(value=input_data, label=f"Input Text (Total: {count_emails(input_data)})"), gr.update(value="", label="Output Text (Total: 0)"), None
87
+
88
+ def clear_files():
89
+ # Chỉ xóa output files, không xóa TEMP_FILE
90
+ for file_path in [OUTPUT_FILE_TXT, OUTPUT_FILE_XLSX]:
91
+ if os.path.exists(file_path):
92
+ os.remove(file_path)
93
+ return "Đã xóa các file output.", gr.update(value="", label="Input Text (Total: 0)"), gr.update(value="", label="Output Text (Total: 0)"), None, None
94
 
95
+ def download_output(input_data, output_data, uploaded_file):
96
  if not output_data:
97
+ if os.path.exists(OUTPUT_FILE_TXT):
98
+ os.remove(OUTPUT_FILE_TXT)
99
+ if os.path.exists(OUTPUT_FILE_XLSX):
100
+ os.remove(OUTPUT_FILE_XLSX)
101
+ return "Không có dữ liệu để tải.", gr.update(label=f"Input Text (Total: {count_emails(input_data)})"), gr.update(label=f"Output Text (Total: {count_emails(output_data)})"), None
102
+
103
+ write_file(OUTPUT_FILE_TXT, output_data.splitlines(keepends=True))
104
+
105
+ lines = output_data.splitlines()
106
+ data_rows = []
107
+ for line in lines:
108
+ if line.strip():
109
+ separator = re.search(r'[\t|;:]', line)
110
+ if separator:
111
+ sep_char = separator.group()
112
+ parts = line.strip().split(sep_char)
113
+ data_rows.append([part.strip() for part in parts])
114
+ else:
115
+ data_rows.append([line.strip()])
116
+
117
+ df = pd.DataFrame(data_rows)
118
+ df.to_excel(OUTPUT_FILE_XLSX, index=False, header=False)
119
+
120
+ return ("Đã tạo file output.txt và output.xlsx.",
121
+ gr.update(label=f"Input Text (Total: {count_emails(input_data)})"),
122
+ gr.update(label=f"Output Text (Total: {count_emails(output_data)})"),
123
+ [OUTPUT_FILE_TXT, OUTPUT_FILE_XLSX])
124
+
125
+ # Giao diện Gradio
126
+ with gr.Blocks(title="Email Processor Pro", theme=gr.themes.Soft()) as demo:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
127
  with gr.Row(equal_height=True):
128
  with gr.Column(scale=1):
129
  input_text = gr.Textbox(label="Input Text", lines=10,
130
+ placeholder="Nhập dữ liệu hoặc tải file .txt lên...\nĐịnh dạng hỗ trợ: email|data hoặc email;data hoặc email:data hoặc email<tab>data")
131
+ with gr.Row():
132
+ upload_file = gr.File(label="📤 Upload File (.txt)", file_types=[".txt"])
133
  with gr.Row():
134
+ clear_input_btn = gr.Button("🧹 Clear Input")
135
 
136
  with gr.Column(scale=1):
137
+ output_text = gr.Textbox(label="Output Text", lines=10, interactive=False)
138
+ with gr.Row():
139
+ download_file = gr.File(label="📥 Download Files", interactive=False, file_count="multiple")
140
+ with gr.Row():
141
+ clear_output_btn = gr.Button("🧹 Clear Output")
142
+ download_btn = gr.Button("💾 Download Output")
143
 
144
+ status = gr.Textbox(label="🔄 Status", interactive=False)
145
 
146
  with gr.Tabs():
147
  with gr.Tab("🔧 Email Tools"):
148
  with gr.Row():
149
+ split_btn = gr.Button("✂️ Split Emails")
150
+ fill_btn = gr.Button("🔍 Fill Missing")
151
+
 
 
 
152
  with gr.Row():
153
+ clear_files_btn = gr.Button("🧹 Clear All Data", size="lg")
154
 
155
+ # Kết nối sự kiện
156
+ split_btn.click(split_emails, inputs=[input_text, upload_file], outputs=[status, input_text, output_text, download_file])
157
+ fill_btn.click(fill_missing_parts, inputs=[input_text, upload_file], outputs=[status, input_text, output_text, download_file])
158
  clear_files_btn.click(clear_files, outputs=[status, input_text, output_text, download_file, upload_file])
159
+ clear_input_btn.click(clear_input, inputs=[input_text, output_text, upload_file], outputs=[input_text, input_text, output_text, upload_file, status])
160
+ clear_output_btn.click(clear_output, inputs=[input_text, output_text, upload_file], outputs=[status, input_text, output_text, download_file])
161
+ download_btn.click(download_output, inputs=[input_text, output_text, upload_file], outputs=[status, input_text, output_text, download_file])
162
 
163
+ demo.launch()