Translsis commited on
Commit
c954dee
·
verified ·
1 Parent(s): 6a858db

Delete app.py

Browse files
Files changed (1) hide show
  1. app.py +0 -275
app.py DELETED
@@ -1,275 +0,0 @@
1
- import gradio as gr
2
- import asyncio
3
- import shutil
4
- import os
5
- import tempfile
6
- from pathlib import Path
7
- from huggingface_hub import HfApi, login, create_repo, upload_file
8
- import git
9
-
10
- # ========================== GLOBAL ==========================
11
- api = HfApi()
12
- temp_dir = Path(tempfile.mkdtemp())
13
- token = None
14
- current_user = None
15
- last_download_path = None
16
-
17
- # ====================== ĐĂNG NHẬP / ĐĂNG XUẤT ======================
18
- def login_hf(t):
19
- global token, current_user
20
- t = t.strip()
21
- if not t:
22
- return "Token không được để trống!", gr.update(value="Chưa đăng nhập")
23
-
24
- try:
25
- login(t)
26
- info = api.whoami(token=t)
27
- token = t
28
- current_user = info["name"]
29
-
30
- status = f"Đã đăng nhập: **{current_user}**"
31
- return "Đăng nhập thành công! Sẵn sàng sử dụng tất cả chức năng", gr.update(value=status)
32
- except Exception as e:
33
- current_user = None
34
- token = None
35
- return f"Login thất bại: {str(e)}", gr.update(value="Login thất bại")
36
-
37
- def logout_hf():
38
- global token, current_user
39
- from huggingface_hub import logout
40
- logout()
41
- token = None
42
- current_user = None
43
- return "Đã đăng xuất thành công!", gr.update(value="Chưa đăng nhập")
44
-
45
- # ====================== CÁC HÀM CHÍNH ======================
46
- async def download(url, type_, progress=gr.Progress()):
47
- global last_download_path
48
- if not url.strip():
49
- return "Vui lòng nhập URL!", None
50
-
51
- out = temp_dir / "downloaded"
52
- if out.exists():
53
- shutil.rmtree(out)
54
- out.mkdir(parents=True, exist_ok=True)
55
-
56
- try:
57
- progress(0, desc="Chuẩn bị...")
58
- if type_ == "git":
59
- progress(0.2, desc="Đang clone bằng git...")
60
- await asyncio.to_thread(git.Repo.clone_from, url.strip(), out, depth=1)
61
- else:
62
- progress(0.2, desc="Đang tải bằng wget...")
63
- proc = await asyncio.create_subprocess_exec(
64
- "wget", "-r", "-np", "-nH", "--cut-dirs=10", "-P", str(out), url.strip(),
65
- stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
66
- )
67
- await proc.communicate()
68
-
69
- count = len(list(out.rglob("*")))
70
- last_download_path = str(out)
71
- return f"Tải thành công! Tìm thấy {count} file/thư mục", last_download_path
72
- except Exception as e:
73
- shutil.rmtree(out, ignore_errors=True)
74
- return f"Lỗi tải xuống: {e}", None
75
-
76
- async def create_repo(name, rtype, private):
77
- if not token:
78
- return "Chưa đăng nhập Hugging Face!"
79
- name = name.strip()
80
- if "/" not in name:
81
- return "Tên repo phải có định dạng username/repo-name!"
82
-
83
- try:
84
- create_repo(repo_id=name, repo_type=rtype, private=private, token=token, exist_ok=True)
85
- return f"Tạo repo thành công!\nhttps://huggingface.co/{name}"
86
- except Exception as e:
87
- return f"Lỗi tạo repo: {e}"
88
-
89
- async def upload(folder, repo, rtype, zip_it, password, use_dl, dl_path, progress=gr.Progress()):
90
- if not token:
91
- return "Chưa đăng nhập!"
92
-
93
- repo = repo.strip()
94
- path = Path(dl_path if use_dl and dl_path else folder)
95
- if not path or not path.exists():
96
- return "Thư mục không tồn tại hoặc chưa tải!"
97
-
98
- # TỰ ĐỘNG PHÁT HIỆN LOẠI REPO THEO TÊN (ưu tiên hơn dropdown)
99
- try:
100
- repo_info = await asyncio.to_thread(api.repo_info, repo_id=repo, token=token)
101
- actual_type = repo_info.repo_type
102
- rtype = actual_type # ép dùng đúng loại repo thực tế
103
- progress(0, desc=f"Phát hiện repo loại: {actual_type}")
104
- except:
105
- # Nếu repo chưa tồn tại → dùng loại từ dropdown (giữ nguyên rtype người dùng chọn)
106
- pass
107
-
108
- try:
109
- if zip_it:
110
- git_dir = path / ".git"
111
- if git_dir.exists():
112
- shutil.rmtree(git_dir)
113
- progress(0.1, desc="Đã tự động xóa .git")
114
-
115
- progress(0.2, desc="Đang nén ZIP...")
116
- zip_name = f"{repo.split('/')[-1]}_archive.zip"
117
- zip_path = temp_dir / zip_name
118
- cmd = ["zip", "-r"] + (["-P", password] if password else []) + [str(zip_path), "."]
119
- proc = await asyncio.create_subprocess_exec(*cmd, cwd=str(path), stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE)
120
- await proc.wait()
121
-
122
- progress(0.7, desc="Upload ZIP...")
123
- await asyncio.to_thread(upload_file,
124
- path_or_fileobj=str(zip_path),
125
- path_in_repo=zip_name,
126
- repo_id=repo,
127
- repo_type=rtype,
128
- token=token)
129
- return f"Upload ZIP thành công!\nhttps://huggingface.co/{repo}/blob/main/{zip_name}"
130
-
131
- else:
132
- files = [
133
- f for f in path.rglob("*")
134
- if f.is_file() and not any(x in str(f.relative_to(path)) for x in ['.git/', '__pycache__', '.cache/', '.DS_Store'])
135
- ]
136
- if not files:
137
- return "Không có file nào hợp lệ để upload!"
138
-
139
- for i, f in enumerate(files):
140
- rel = f.relative_to(path)
141
- progress((i + 1) / len(files), desc=f"Upload {rel}")
142
- await asyncio.to_thread(upload_file,
143
- path_or_fileobj=str(f),
144
- path_in_repo=str(rel),
145
- repo_id=repo,
146
- repo_type=rtype,
147
- token=token)
148
-
149
- return f"Upload thành công {len(files)} file!\nhttps://huggingface.co/{repo}"
150
- except Exception as e:
151
- return f"Lỗi upload: {e}"
152
-
153
- async def delete_files(local, repo, rtype, dry, progress=gr.Progress()):
154
- if not token:
155
- return "Chưa đăng nhập!"
156
-
157
- try:
158
- local_path = Path(local)
159
- if not local_path.exists():
160
- return "Thư mục local không tồn tại!"
161
-
162
- repo_files = await asyncio.to_thread(api.list_repo_files, repo_id=repo, repo_type=rtype, token=token)
163
- to_del = [str(p.relative_to(local_path)) for p in local_path.rglob("*") if p.is_file() and str(p.relative_to(local_path)) in repo_files]
164
-
165
- if not to_del:
166
- return "Không tìm thấy file nào trùng để xóa trên repo."
167
-
168
- if dry:
169
- preview = "\n".join(f"- {f}" for f in to_del[:20])
170
- more = f"\n... và {len(to_del)-20} file khác" if len(to_del) > 20 else ""
171
- return f"**Dry-run**: Sẽ xóa {len(to_del)} file:\n{preview}{more}"
172
-
173
- for i, f in enumerate(to_del):
174
- progress((i + 1) / len(to_del), desc=f"Đang xóa {i+1}/{len(to_del)}")
175
- await asyncio.to_thread(api.delete_file, path_in_repo=f, repo_id=repo, repo_type=rtype, token=token)
176
-
177
- return f"Đã xóa thành công {len(to_del)} file trên repo!"
178
- except Exception as e:
179
- return f"Lỗi khi xóa: {e}"
180
-
181
- # ========================== GIAO DIỆN GRADIO ==========================
182
- with gr.Blocks(title="HF Manager Pro") as app:
183
- gr.Markdown("# HF Manager Pro\nTải • Tạo Repo • Upload • Xóa file trên HF - Siêu tiện & nhanh!")
184
-
185
- # ===== TRẠNG THÁI ĐĂNG NHẬP Ở ĐẦU =====
186
- with gr.Row():
187
- status_login = gr.Markdown("**Chưa đăng nhập**", elem_classes="status")
188
- logout_btn = gr.Button("Đăng xuất", variant="stop", visible=False, size="sm")
189
-
190
- with gr.Tabs():
191
- # ==================== TAB LOGIN ====================
192
- with gr.Tab("Đăng nhập HF"):
193
- gr.Markdown("Dán token từ: https://huggingface.co/settings/tokens")
194
- tk = gr.Textbox(label="Hugging Face Token", type="password", placeholder="hf_xxxxxxxxxxxxxxxxxxxxxx")
195
- login_btn = gr.Button("Đăng nhập", variant="primary")
196
- login_out = gr.Textbox(label="Kết quả")
197
-
198
- login_btn.click(
199
- login_hf,
200
- inputs=tk,
201
- outputs=[login_out, status_login]
202
- ).then(
203
- lambda: gr.update(visible=True),
204
- outputs=logout_btn
205
- )
206
-
207
- logout_btn.click(
208
- logout_hf,
209
- outputs=[login_out, status_login]
210
- ).then(
211
- lambda: gr.update(visible=False),
212
- outputs=logout_btn
213
- )
214
-
215
- # ==================== TAB TẢI XUỐNG ====================
216
- with gr.Tab("Tải xuống"):
217
- url = gr.Textbox(label="URL (GitHub, Google Drive public, git repo...)", placeholder="https://...")
218
- typ = gr.Radio(["wget", "git"], label="Phương thức tải", value="wget")
219
- dl_btn = gr.Button("Bắt đầu tải", variant="primary")
220
- dl_out = gr.Textbox(label="Trạng thái tải")
221
- dl_path = gr.Textbox(visible=False)
222
-
223
- dl_btn.click(download, [url, typ], [dl_out, dl_path])
224
-
225
- # ==================== TAB TẠO REPO ====================
226
- with gr.Tab("Tạo Repo mới"):
227
- name = gr.Textbox(label="Tên repo", placeholder="your-username/my-awesome-model")
228
- rt = gr.Dropdown(["model", "dataset", "space"], value="model", label="Loại repo")
229
- priv = gr.Checkbox(label="Repo riêng tư (Private)", value=True)
230
- create_out = gr.Textbox(label="Kết quả", lines=3)
231
- gr.Button("Tạo repo ngay", variant="primary").click(
232
- create_repo, [name, rt, priv], create_out
233
- )
234
-
235
- # ==================== TAB UPLOAD ====================
236
- with gr.Tab("Upload lên HF"):
237
- folder = gr.Textbox(label="Thư mục local (bỏ qua nếu dùng tải sẵn)", placeholder="/path/to/your/folder")
238
- use_dl = gr.Checkbox(label="Dùng thư mục vừa tải xuống (khuyên dùng)", value=True)
239
- repo = gr.Textbox(label="Repo đích", placeholder="your-username/my-awesome-model")
240
- rt2 = gr.Dropdown(["model", "dataset", "space"], value="model", label="Loại")
241
- zipc = gr.Checkbox(label="Nén thành ZIP (có thể đặt mật khẩu)")
242
- pw = gr.Textbox(label="Mật khẩu ZIP (nếu có)", type="password", visible=False)
243
- zipc.change(lambda x: gr.update(visible=x), zipc, pw)
244
-
245
- up_out = gr.Textbox(label="Kết quả upload", lines=5)
246
- gr.Button("Upload ngay", variant="primary").click(
247
- upload, [folder, repo, rt2, zipc, pw, use_dl, dl_path], up_out
248
- )
249
-
250
- # ==================== TAB XÓA FILE TRÊN REPO ====================
251
- with gr.Tab("Xóa file trên Repo"):
252
- gr.Markdown("So sánh thư mục local → xóa các file trùng trên repo")
253
- loc = gr.Textbox(label="Thư mục local để đối chiếu", placeholder="/path/to/local/folder")
254
- repo2 = gr.Textbox(label="Repo cần dọn dẹp", placeholder="username/repo")
255
- rt3 = gr.Dropdown(["model", "dataset", "space"], value="model")
256
- dry = gr.Checkbox(label="Chỉ xem trước (Dry-run) - an toàn", value=True)
257
- del_out = gr.Textbox(label="Kết quả", lines=8)
258
- gr.Button("Thực hiện xóa", variant="stop").click(
259
- delete_files, [loc, repo2, rt3, dry], del_out
260
- )
261
-
262
- gr.Markdown("**Mẹo:** Sau khi tải xong → tick “Dùng thư mục vừa tải xuống” → Upload ngay không cần nhập đường dẫn!")
263
-
264
- # CSS nhỏ cho đẹp
265
- app.css = """
266
- .status { font-size: 1.3em; font-weight: bold; margin: 10px 0; }
267
- """
268
-
269
- # ========================== KHỞI CHẠY ==========================
270
- app.queue(max_size=20).launch(
271
- share=True,
272
- debug=True,
273
- server_name="0.0.0.0",
274
- server_port=7860
275
- )