gofile-tool 0.1.0__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.
- gofile_tool-0.1.0/LICENSE +21 -0
- gofile_tool-0.1.0/PKG-INFO +136 -0
- gofile_tool-0.1.0/README.md +123 -0
- gofile_tool-0.1.0/README_PYPI.md +108 -0
- gofile_tool-0.1.0/pyproject.toml +45 -0
- gofile_tool-0.1.0/setup.cfg +4 -0
- gofile_tool-0.1.0/src/gofile_tool/__init__.py +7 -0
- gofile_tool-0.1.0/src/gofile_tool/__main__.py +3 -0
- gofile_tool-0.1.0/src/gofile_tool/cli.py +85 -0
- gofile_tool-0.1.0/src/gofile_tool/core.py +547 -0
- gofile_tool-0.1.0/src/gofile_tool.egg-info/PKG-INFO +136 -0
- gofile_tool-0.1.0/src/gofile_tool.egg-info/SOURCES.txt +14 -0
- gofile_tool-0.1.0/src/gofile_tool.egg-info/dependency_links.txt +1 -0
- gofile_tool-0.1.0/src/gofile_tool.egg-info/entry_points.txt +3 -0
- gofile_tool-0.1.0/src/gofile_tool.egg-info/requires.txt +6 -0
- gofile_tool-0.1.0/src/gofile_tool.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 gofile-tool contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: gofile-tool
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Tải / upload Gofile.io tốc độ tối đa — tự động vượt chặn IP (Tor + chữ ký web X-Website-Token)
|
|
5
|
+
Author: gofile-tool contributors
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://pypi.org/project/gofile-tool/
|
|
8
|
+
Project-URL: Source, https://pypi.org/project/gofile-tool/
|
|
9
|
+
Keywords: gofile,downloader,uploader,tor,cli,bypass,download
|
|
10
|
+
Classifier: Environment :: Console
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
17
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
18
|
+
Classifier: Topic :: Utilities
|
|
19
|
+
Requires-Python: >=3.8
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Requires-Dist: requests>=2.25.0
|
|
23
|
+
Requires-Dist: pysocks>=1.7.1
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: build; extra == "dev"
|
|
26
|
+
Requires-Dist: twine; extra == "dev"
|
|
27
|
+
Dynamic: license-file
|
|
28
|
+
|
|
29
|
+
# 🧰 gofile-tool
|
|
30
|
+
|
|
31
|
+
**Tải / upload Gofile.io ở tốc độ tối đa — tự động vượt chặn IP của datacenter/VPS.**
|
|
32
|
+
|
|
33
|
+
Gofile hay drop kết nối TLS với IP máy ảo (báo `error-rateLimit`, treo TLS handshake).
|
|
34
|
+
`gofile-tool` tự xử lý: thử đường thẳng → nếu bị chặn thì tự bật **Tor**, xoay IP, tạo tài
|
|
35
|
+
khoản guest và ký đúng header `X-Website-Token` mà Gofile đòi. Dữ liệu lớn vẫn tải/upload
|
|
36
|
+
**thẳng** qua `store*.gofile.io` / `upload.gofile.io` nên tốc độ nguyên bản.
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
pip install gofile-tool
|
|
40
|
+
gofile-tool download Uc4c9oyJ -o ./tai-ve
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## ⚡ Cài đặt
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pip install gofile-tool # hoặc: pipx install gofile-tool
|
|
49
|
+
|
|
50
|
+
# chỉ cần khi IP của bạn bị Gofile chặn (tool tự bật Tor):
|
|
51
|
+
sudo apt install -y tor # Debian/Ubuntu
|
|
52
|
+
brew install tor # macOS
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Yêu cầu: Python ≥ 3.8.
|
|
56
|
+
|
|
57
|
+
## 🚀 Lệnh
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
gofile-tool info <CODE> # xem metadata file/folder
|
|
61
|
+
gofile-tool download <CODE> -o ./tai-ve # tải file hoặc cả folder
|
|
62
|
+
gofile-tool upload ./file.zip # up + tự set public + in link
|
|
63
|
+
gofile-tool public <CODE> # mở public cho nội dung đã có
|
|
64
|
+
gofile-tool delete <FILE_ID> --token <TK> # xoá file
|
|
65
|
+
gofile-tool stop-tor # tắt Tor
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
| Cờ | Ý nghĩa |
|
|
69
|
+
|---|---|
|
|
70
|
+
| `--json` | Output JSON (cho AI agent / script). Luôn kèm `_token` để quản lý sau |
|
|
71
|
+
| `-o DIR` | Thư mục lưu file tải về (mặc định `.`) |
|
|
72
|
+
| `--workers N` | Số luồng khi tải folder (mặc định 4) |
|
|
73
|
+
| `--token TOKEN` | Dùng tài khoản Gofile của bạn (mặc định tự tạo guest) |
|
|
74
|
+
| `--proxy URL` | Dùng proxy/VPN riêng: `--proxy socks5h://127.0.0.1:1080` |
|
|
75
|
+
| `--no-tor` | Không dùng Tor |
|
|
76
|
+
| `--no-verify` | Bỏ qua kiểm tra MD5 |
|
|
77
|
+
|
|
78
|
+
**Ví dụ JSON (`gofile-tool upload ./file.zip --json`):**
|
|
79
|
+
|
|
80
|
+
```json
|
|
81
|
+
{
|
|
82
|
+
"ok": true, "name": "file.zip", "size": 577188003, "md5": "912175…",
|
|
83
|
+
"code": "UGqKJoFZ", "page": "https://gofile.io/d/nAF2ydFc",
|
|
84
|
+
"file_id": "783e9f12-…", "speed_MBps": 83.0,
|
|
85
|
+
"public": true, "link": "https://gofile.io/d/UGqKJoFZ",
|
|
86
|
+
"_token": "Q23LICkojSBdNVgRjhbx7z72ZqVBldGw"
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## 🤖 Dành cho AI agent
|
|
91
|
+
|
|
92
|
+
Không cần agent thông minh — chỉ cần bảo nó chạy:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
pip install gofile-tool
|
|
96
|
+
gofile-tool download <CODE> -o <DIR> --json # hoặc: gofile-tool upload <FILE> --json
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Mọi lệnh đều có `--json`; output gồm `link`, `md5`, `size`, `ok`, `_token`.
|
|
100
|
+
Tool tự lo: tài khoản, chữ ký, đổi IP, resume, kiểm tra MD5.
|
|
101
|
+
|
|
102
|
+
## 🔍 Nguyên lý (3 mánh)
|
|
103
|
+
|
|
104
|
+
1. **Ký đúng chữ ký web.** Gofile đòi
|
|
105
|
+
`X-Website-Token = sha256(UA :: ngôn ngữ :: accountToken :: floor(epoch/14400) :: secret)`.
|
|
106
|
+
`secret` nằm trong `/js/wt.obf.js` và **bị xoay định kỳ** → tool tự tải, tự bóc
|
|
107
|
+
(và đối chiếu chéo bằng `node` nếu có), cache 6 giờ.
|
|
108
|
+
2. **Đổi IP bằng Tor khi bị chặn.** Tự cài/khởi động Tor (SOCKS5 `9050`, control `9051`),
|
|
109
|
+
gặp `error-rateLimit` thì gửi `SIGNAL NEWNYM` đổi exit node, thử lại tối đa 6 lần.
|
|
110
|
+
3. **Tách đường điều khiển / đường dữ liệu.** Chỉ vài KB metadata đi qua Tor/chậm;
|
|
111
|
+
còn dữ liệu lớn đi **thẳng** `store*` / `upload` → tốc độ tối đa
|
|
112
|
+
(đo thực tế: **tải 36 MB/s**, **upload 83 MB/s**).
|
|
113
|
+
|
|
114
|
+
Không vượt quyền truy cập: tool chỉ gửi đúng header mà trình duyệt vẫn gửi;
|
|
115
|
+
file private thì vẫn không mở được.
|
|
116
|
+
|
|
117
|
+
## 🩺 Sự cố thường gặp
|
|
118
|
+
|
|
119
|
+
| Thông báo | Cách sửa |
|
|
120
|
+
|---|---|
|
|
121
|
+
| `error-notPremium` | Secret đã xoay → tool tự nạp lại; nếu kẹt: xoá `~/.cache/gofile_secret.json` |
|
|
122
|
+
| `error-rateLimit` | Tool tự đổi mạch Tor; chờ vài giây |
|
|
123
|
+
| `API thất bại (direct: ConnectTimeout)` | Thiếu Tor → `sudo apt install -y tor`, hoặc `--proxy socks5h://…` |
|
|
124
|
+
| Folder tải chậm | Gofile chỉ cho ZIP folder ở gói Premium → tool tải từng file, đa luồng |
|
|
125
|
+
| `Permission denied …/control_auth_cookie` | `sudo rm -rf ~/.cache/gofile-tor` rồi chạy lại |
|
|
126
|
+
| Upload xong bị "Protected content" | Phải set public cho **cả thư mục cha** — tool đã làm sẵn |
|
|
127
|
+
|
|
128
|
+
## ⚠️ Giới hạn
|
|
129
|
+
|
|
130
|
+
- Mặc định dùng tài khoản **guest** (tự tạo). Muốn giữ file lâu: truyền `--token <token của bạn>` hoặc set `GOFILE_TOKEN`.
|
|
131
|
+
- Gofile miễn phí dọn file sau ~10 ngày không có lượt tải.
|
|
132
|
+
- Cần `tor` (hoặc proxy riêng) **chỉ khi** IP của bạn bị chặn; IP nhà thường không cần.
|
|
133
|
+
|
|
134
|
+
## Giấy phép
|
|
135
|
+
|
|
136
|
+
MIT
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# 🧰 gofile_tool — toolkit Gofile.io "miễn nhiễm chặn IP"
|
|
2
|
+
|
|
3
|
+
Một file Python duy nhất, tự lo hết: **tạo tài khoản, ký chữ ký web, đổi IP bằng Tor khi bị chặn, tải/upload tốc độ tối đa**.
|
|
4
|
+
Dùng được bởi người thật lẫn **AI agent** (mọi lệnh đều có `--json`).
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## ⚡ Cài đặt (1 lần)
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
pip install requests pysocks # tool cũng tự cài nếu thiếu
|
|
12
|
+
sudo apt install -y tor # hoặc: brew install tor (chỉ cần khi IP bị chặn)
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## 🚀 Dùng ngay (copy-paste)
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
cd /home/user/gofile-toolkit
|
|
19
|
+
|
|
20
|
+
python3 gofile_tool.py info Uc4c9oyJ # xem metadata file/folder
|
|
21
|
+
python3 gofile_tool.py download Uc4c9oyJ -o ./tai-ve # tải (file hoặc cả folder)
|
|
22
|
+
python3 gofile_tool.py upload file.zip # up + tự set public + in link
|
|
23
|
+
python3 gofile_tool.py public <code|contentId> # set public cho nội dung đã có
|
|
24
|
+
python3 gofile_tool.py delete <id1,id2> --token <tk> # xoá file
|
|
25
|
+
python3 gofile_tool.py stop-tor # tắt Tor
|
|
26
|
+
|
|
27
|
+
python3 gofile_tool.py info Uc4c9oyJ --json # output JSON cho agent
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Tuỳ chọn hay dùng:
|
|
31
|
+
|
|
32
|
+
| Cờ | Ý nghĩa |
|
|
33
|
+
|---|---|
|
|
34
|
+
| `--json` | Output JSON (máy đọc). Luôn kèm `_token` để quản lý/xoá sau |
|
|
35
|
+
| `-o DIR` | Thư mục lưu file tải về (mặc định `.`) |
|
|
36
|
+
| `--workers N` | Số luồng tải khi gặp folder (mặc định 4) |
|
|
37
|
+
| `--token TOKEN` | Dùng tài khoản Gofile có sẵn (để file vào tài khoản của bạn) |
|
|
38
|
+
| `--no-tor` | Không dùng Tor (dùng khi IP của bạn sạch) |
|
|
39
|
+
|
|
40
|
+
**Gợi ý:** `alias gf='python3 /home/user/gofile-toolkit/gofile_tool.py'` rồi `gf info <code>`.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## 🤖 DÀNH CHO AI AGENT — đọc 5 dòng này rồi chạy
|
|
45
|
+
|
|
46
|
+
1. Đừng tự viết lại code gọi API Gofile. Cứ gọi tool này.
|
|
47
|
+
2. Lấy metadata / tải file:
|
|
48
|
+
```bash
|
|
49
|
+
python3 /home/user/gofile-toolkit/gofile_tool.py download <CODE> -o <THU_MUC> --json
|
|
50
|
+
```
|
|
51
|
+
3. Upload và lấy link chia sẻ:
|
|
52
|
+
```bash
|
|
53
|
+
python3 /home/user/gofile-toolkit/gofile_tool.py upload <DUONG_DAN_FILE> --json
|
|
54
|
+
```
|
|
55
|
+
→ trong JSON có `link` (dạng `https://gofile.io/d/XXXXXXXX`), `md5`, `size`, `_token`.
|
|
56
|
+
4. Nếu lệnh báo lỗi: chạy lại với `--json`, đọc trường `error`; 90% là do chưa cài `tor` (`sudo apt install -y tor`).
|
|
57
|
+
5. **Không** tự brute-force / đập liên tục vào `api.gofile.io` — sẽ bị block IP cả ngày. Tool đã tự giới hạn và tự đổi mạch.
|
|
58
|
+
|
|
59
|
+
**Output mẫu (`upload --json`):**
|
|
60
|
+
```json
|
|
61
|
+
{
|
|
62
|
+
"ok": true, "name": "x.7z", "size": 577188003, "md5": "912175...",
|
|
63
|
+
"code": "UGqKJoFZ", "page": "https://gofile.io/d/nAF2ydFc",
|
|
64
|
+
"file_id": "783e9f12-...", "speed_MBps": 83.0,
|
|
65
|
+
"public": true, "link": "https://gofile.io/d/UGqKJoFZ",
|
|
66
|
+
"_token": "Q23LICkojSBdNVgRjhbx7z72ZqVBldGw"
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## 🔍 Vì sao cần tool này (kiến trúc Gofile)
|
|
73
|
+
|
|
74
|
+
| Cụm máy chủ | Ví dụ | Bị chặn IP datacenter? |
|
|
75
|
+
|---|---|---|
|
|
76
|
+
| Web + API | `gofile.io`, `api.gofile.io` (94.139.32.3) | ☠️ Có (drop TLS sau vài chục request bot) |
|
|
77
|
+
| Lưu trữ | `store1…store5.gofile.io` (45.112.123.x) | ✅ Không |
|
|
78
|
+
| Upload | `upload.gofile.io` (94.139.32.15-25) | ✅ Không |
|
|
79
|
+
|
|
80
|
+
**Ba mánh khoá mà tool cài sẵn:**
|
|
81
|
+
|
|
82
|
+
1. **Ký đúng chữ ký web** — Gofile đòi header
|
|
83
|
+
`X-Website-Token = sha256(UserAgent :: ngôn ngữ :: accountToken :: floor(epoch/14400) :: secret)`.
|
|
84
|
+
`secret` nằm trong `/js/wt.obf.js`, **bị xoay định kỳ** → tool tự tải file JS, bóc secret, và có `node` thì đối chiếu chéo với hàm `generateWT()` gốc của Gofile. Cache 6 giờ, hết hạn tự nạp lại.
|
|
85
|
+
2. **Đổi IP bằng Tor khi bị chặn** — tự cài/khởi động Tor (SOCKS5 `9050`, control `9051`), mỗi lần gặp `error-rateLimit` thì gửi `SIGNAL NEWNYM` đổi exit node rồi thử lại (tối đa 6 lần).
|
|
86
|
+
3. **Tách đường điều khiển / đường dữ liệu** — chỉ vài KB metadata đi qua Tor (chậm cũng được); còn **dữ liệu lớn đi thẳng** vào `store*` / `upload` → tốc độ nguyên bản (đo được: tải 36 MB/s, up 83 MB/s).
|
|
87
|
+
|
|
88
|
+
Không vượt quyền truy cập: tool chỉ gửi đúng những header mà trình duyệt của bạn vẫn gửi; file private thì tool vẫn không mở được.
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## 🧪 Đã test thật (18/09/2026)
|
|
93
|
+
|
|
94
|
+
| Tình huống | Kết quả |
|
|
95
|
+
|---|---|
|
|
96
|
+
| IP máy ảo bị Gofile drop TLS | `info` qua Tor → OK (exit IP 67.215.237.232) |
|
|
97
|
+
| Tải 608 MB | 16,9 s @ 36 MB/s, MD5 khớp |
|
|
98
|
+
| Upload 551 MB | 7 s @ 83 MB/s |
|
|
99
|
+
| Upload → set public → tài khoản **khác** tải lại | MD5 khớp (`md5_ok: true`) |
|
|
100
|
+
| Resume khi đứt giữa chừng | Có (ghi `.part`, gửi `Range`) |
|
|
101
|
+
| Xoá file bằng token | `status: ok` |
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## 🩺 Xử lý sự cố
|
|
106
|
+
|
|
107
|
+
| Thông báo | Nguyên nhân | Cách sửa |
|
|
108
|
+
|---|---|---|
|
|
109
|
+
| `error-notPremium` | Chữ ký sai / secret đã xoay | Tool tự nạp lại secret; nếu vẫn lỗi → xoá `~/.cache/gofile_secret.json` |
|
|
110
|
+
| `error-rateLimit` | IP hoặc exit node bị xài chung | Tool tự `NEWNYM` đổi mạch; kiên nhẫn vài giây |
|
|
111
|
+
| `API thất bại (direct: ConnectTimeout)` mà không bật được Tor | Thiếu `tor` | `sudo apt install -y tor` (hoặc `brew install tor`) |
|
|
112
|
+
| Tải folder bị chậm | Folder ZIP cần Premium | Tool tải từng file (đa luồng), không cần Premium |
|
|
113
|
+
| `Permission denied …/control_auth_cookie` | Tor từng chạy bằng root | Tool đã tự xử lý; nếu còn: `sudo rm -rf ~/.cache/gofile-tor` |
|
|
114
|
+
| File up lên bị "Protected content" | Chưa set public cho **thư mục cha** | Tool đã set cả 2 cấp; nếu tự làm: set `public` trên `parentFolder` với `recursive: true` |
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## ⚠️ Giới hạn cần biết
|
|
119
|
+
|
|
120
|
+
- Tài khoản mặc định là **guest** (tool tự tạo). Muốn giữ file lâu: đăng nhập Gofile, lấy token rồi truyền `--token` (hoặc set `GOFILE_TOKEN`).
|
|
121
|
+
- Gofile miễn phí **dọn file sau ~10 ngày không có lượt tải**.
|
|
122
|
+
- Folder ZIP / bulk download là tính năng Premium — tool tải từng file thay thế.
|
|
123
|
+
- Tool chỉ gửi vài chục request, không quét, không dò — đủ để không bị block oan.
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# 🧰 gofile-tool
|
|
2
|
+
|
|
3
|
+
**Tải / upload Gofile.io ở tốc độ tối đa — tự động vượt chặn IP của datacenter/VPS.**
|
|
4
|
+
|
|
5
|
+
Gofile hay drop kết nối TLS với IP máy ảo (báo `error-rateLimit`, treo TLS handshake).
|
|
6
|
+
`gofile-tool` tự xử lý: thử đường thẳng → nếu bị chặn thì tự bật **Tor**, xoay IP, tạo tài
|
|
7
|
+
khoản guest và ký đúng header `X-Website-Token` mà Gofile đòi. Dữ liệu lớn vẫn tải/upload
|
|
8
|
+
**thẳng** qua `store*.gofile.io` / `upload.gofile.io` nên tốc độ nguyên bản.
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
pip install gofile-tool
|
|
12
|
+
gofile-tool download Uc4c9oyJ -o ./tai-ve
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## ⚡ Cài đặt
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pip install gofile-tool # hoặc: pipx install gofile-tool
|
|
21
|
+
|
|
22
|
+
# chỉ cần khi IP của bạn bị Gofile chặn (tool tự bật Tor):
|
|
23
|
+
sudo apt install -y tor # Debian/Ubuntu
|
|
24
|
+
brew install tor # macOS
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Yêu cầu: Python ≥ 3.8.
|
|
28
|
+
|
|
29
|
+
## 🚀 Lệnh
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
gofile-tool info <CODE> # xem metadata file/folder
|
|
33
|
+
gofile-tool download <CODE> -o ./tai-ve # tải file hoặc cả folder
|
|
34
|
+
gofile-tool upload ./file.zip # up + tự set public + in link
|
|
35
|
+
gofile-tool public <CODE> # mở public cho nội dung đã có
|
|
36
|
+
gofile-tool delete <FILE_ID> --token <TK> # xoá file
|
|
37
|
+
gofile-tool stop-tor # tắt Tor
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
| Cờ | Ý nghĩa |
|
|
41
|
+
|---|---|
|
|
42
|
+
| `--json` | Output JSON (cho AI agent / script). Luôn kèm `_token` để quản lý sau |
|
|
43
|
+
| `-o DIR` | Thư mục lưu file tải về (mặc định `.`) |
|
|
44
|
+
| `--workers N` | Số luồng khi tải folder (mặc định 4) |
|
|
45
|
+
| `--token TOKEN` | Dùng tài khoản Gofile của bạn (mặc định tự tạo guest) |
|
|
46
|
+
| `--proxy URL` | Dùng proxy/VPN riêng: `--proxy socks5h://127.0.0.1:1080` |
|
|
47
|
+
| `--no-tor` | Không dùng Tor |
|
|
48
|
+
| `--no-verify` | Bỏ qua kiểm tra MD5 |
|
|
49
|
+
|
|
50
|
+
**Ví dụ JSON (`gofile-tool upload ./file.zip --json`):**
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
{
|
|
54
|
+
"ok": true, "name": "file.zip", "size": 577188003, "md5": "912175…",
|
|
55
|
+
"code": "UGqKJoFZ", "page": "https://gofile.io/d/nAF2ydFc",
|
|
56
|
+
"file_id": "783e9f12-…", "speed_MBps": 83.0,
|
|
57
|
+
"public": true, "link": "https://gofile.io/d/UGqKJoFZ",
|
|
58
|
+
"_token": "Q23LICkojSBdNVgRjhbx7z72ZqVBldGw"
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## 🤖 Dành cho AI agent
|
|
63
|
+
|
|
64
|
+
Không cần agent thông minh — chỉ cần bảo nó chạy:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
pip install gofile-tool
|
|
68
|
+
gofile-tool download <CODE> -o <DIR> --json # hoặc: gofile-tool upload <FILE> --json
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Mọi lệnh đều có `--json`; output gồm `link`, `md5`, `size`, `ok`, `_token`.
|
|
72
|
+
Tool tự lo: tài khoản, chữ ký, đổi IP, resume, kiểm tra MD5.
|
|
73
|
+
|
|
74
|
+
## 🔍 Nguyên lý (3 mánh)
|
|
75
|
+
|
|
76
|
+
1. **Ký đúng chữ ký web.** Gofile đòi
|
|
77
|
+
`X-Website-Token = sha256(UA :: ngôn ngữ :: accountToken :: floor(epoch/14400) :: secret)`.
|
|
78
|
+
`secret` nằm trong `/js/wt.obf.js` và **bị xoay định kỳ** → tool tự tải, tự bóc
|
|
79
|
+
(và đối chiếu chéo bằng `node` nếu có), cache 6 giờ.
|
|
80
|
+
2. **Đổi IP bằng Tor khi bị chặn.** Tự cài/khởi động Tor (SOCKS5 `9050`, control `9051`),
|
|
81
|
+
gặp `error-rateLimit` thì gửi `SIGNAL NEWNYM` đổi exit node, thử lại tối đa 6 lần.
|
|
82
|
+
3. **Tách đường điều khiển / đường dữ liệu.** Chỉ vài KB metadata đi qua Tor/chậm;
|
|
83
|
+
còn dữ liệu lớn đi **thẳng** `store*` / `upload` → tốc độ tối đa
|
|
84
|
+
(đo thực tế: **tải 36 MB/s**, **upload 83 MB/s**).
|
|
85
|
+
|
|
86
|
+
Không vượt quyền truy cập: tool chỉ gửi đúng header mà trình duyệt vẫn gửi;
|
|
87
|
+
file private thì vẫn không mở được.
|
|
88
|
+
|
|
89
|
+
## 🩺 Sự cố thường gặp
|
|
90
|
+
|
|
91
|
+
| Thông báo | Cách sửa |
|
|
92
|
+
|---|---|
|
|
93
|
+
| `error-notPremium` | Secret đã xoay → tool tự nạp lại; nếu kẹt: xoá `~/.cache/gofile_secret.json` |
|
|
94
|
+
| `error-rateLimit` | Tool tự đổi mạch Tor; chờ vài giây |
|
|
95
|
+
| `API thất bại (direct: ConnectTimeout)` | Thiếu Tor → `sudo apt install -y tor`, hoặc `--proxy socks5h://…` |
|
|
96
|
+
| Folder tải chậm | Gofile chỉ cho ZIP folder ở gói Premium → tool tải từng file, đa luồng |
|
|
97
|
+
| `Permission denied …/control_auth_cookie` | `sudo rm -rf ~/.cache/gofile-tor` rồi chạy lại |
|
|
98
|
+
| Upload xong bị "Protected content" | Phải set public cho **cả thư mục cha** — tool đã làm sẵn |
|
|
99
|
+
|
|
100
|
+
## ⚠️ Giới hạn
|
|
101
|
+
|
|
102
|
+
- Mặc định dùng tài khoản **guest** (tự tạo). Muốn giữ file lâu: truyền `--token <token của bạn>` hoặc set `GOFILE_TOKEN`.
|
|
103
|
+
- Gofile miễn phí dọn file sau ~10 ngày không có lượt tải.
|
|
104
|
+
- Cần `tor` (hoặc proxy riêng) **chỉ khi** IP của bạn bị chặn; IP nhà thường không cần.
|
|
105
|
+
|
|
106
|
+
## Giấy phép
|
|
107
|
+
|
|
108
|
+
MIT
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "gofile-tool"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Tải / upload Gofile.io tốc độ tối đa — tự động vượt chặn IP (Tor + chữ ký web X-Website-Token)"
|
|
9
|
+
readme = {file = "README_PYPI.md", content-type = "text/markdown"}
|
|
10
|
+
requires-python = ">=3.8"
|
|
11
|
+
license = {text = "MIT"}
|
|
12
|
+
authors = [{name = "gofile-tool contributors"}]
|
|
13
|
+
keywords = ["gofile", "downloader", "uploader", "tor", "cli", "bypass", "download"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Environment :: Console",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"Intended Audience :: End Users/Desktop",
|
|
18
|
+
"License :: OSI Approved :: MIT License",
|
|
19
|
+
"Operating System :: OS Independent",
|
|
20
|
+
"Programming Language :: Python :: 3",
|
|
21
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
22
|
+
"Topic :: Internet :: WWW/HTTP",
|
|
23
|
+
"Topic :: Utilities",
|
|
24
|
+
]
|
|
25
|
+
dependencies = [
|
|
26
|
+
"requests>=2.25.0",
|
|
27
|
+
"pysocks>=1.7.1",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
[project.optional-dependencies]
|
|
31
|
+
dev = ["build", "twine"]
|
|
32
|
+
|
|
33
|
+
[project.scripts]
|
|
34
|
+
gofile-tool = "gofile_tool.cli:main"
|
|
35
|
+
gf = "gofile_tool.cli:main"
|
|
36
|
+
|
|
37
|
+
[project.urls]
|
|
38
|
+
Homepage = "https://pypi.org/project/gofile-tool/"
|
|
39
|
+
Source = "https://pypi.org/project/gofile-tool/"
|
|
40
|
+
|
|
41
|
+
[tool.setuptools.packages.find]
|
|
42
|
+
where = ["src"]
|
|
43
|
+
|
|
44
|
+
[tool.setuptools]
|
|
45
|
+
include-package-data = true
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""gofile_tool.cli — giao diện dòng lệnh: gofile-tool / gf"""
|
|
3
|
+
import argparse
|
|
4
|
+
import json
|
|
5
|
+
import sys
|
|
6
|
+
|
|
7
|
+
from . import __version__
|
|
8
|
+
from .core import Gofile, Tor
|
|
9
|
+
|
|
10
|
+
EPILOG = """
|
|
11
|
+
vi du:
|
|
12
|
+
gofile-tool info Uc4c9oyJ
|
|
13
|
+
gofile-tool download Uc4c9oyJ -o ./tai-ve
|
|
14
|
+
gofile-tool upload file.zip
|
|
15
|
+
gofile-tool public <code>
|
|
16
|
+
gofile-tool delete <file_id> --token <token>
|
|
17
|
+
gofile-tool stop-tor
|
|
18
|
+
|
|
19
|
+
Them --json vao bat ky lenh nao de nhan output may doc duoc (cho AI agent).
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def build_parser():
|
|
24
|
+
ap = argparse.ArgumentParser(
|
|
25
|
+
prog="gofile-tool",
|
|
26
|
+
description="Tai / upload Gofile.io toc do toi da, tu dong vuot chan IP.",
|
|
27
|
+
epilog=EPILOG,
|
|
28
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
29
|
+
)
|
|
30
|
+
ap.add_argument("--version", action="version", version=f"gofile-tool {__version__}")
|
|
31
|
+
ap.add_argument("cmd", nargs="?",
|
|
32
|
+
choices=["info", "download", "upload", "public", "delete", "stop-tor"])
|
|
33
|
+
ap.add_argument("target", nargs="?", help="ma Gofile (vd: Uc4c9oyJ) hoac duong dan file")
|
|
34
|
+
ap.add_argument("-o", "--out", default=".", help="thu muc luu file tai ve (mac dinh: .)")
|
|
35
|
+
ap.add_argument("--token", default=None, help="tai khoan Gofile (mac dinh: tu tao guest)")
|
|
36
|
+
ap.add_argument("--proxy", default=None,
|
|
37
|
+
help="proxy rieng, vd socks5h://127.0.0.1:9050 hoac http://host:port "
|
|
38
|
+
"(mac dinh: tu bat Tor)")
|
|
39
|
+
ap.add_argument("--no-tor", action="store_true", help="khong dung Tor")
|
|
40
|
+
ap.add_argument("--workers", type=int, default=4, help="so luong tai folder (mac dinh 4)")
|
|
41
|
+
ap.add_argument("--no-verify", action="store_true", help="bo qua kiem tra MD5")
|
|
42
|
+
ap.add_argument("--json", dest="as_json", action="store_true", help="output JSON")
|
|
43
|
+
return ap
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def main(argv=None):
|
|
47
|
+
ap = build_parser()
|
|
48
|
+
a = ap.parse_args(argv)
|
|
49
|
+
if not a.cmd:
|
|
50
|
+
ap.print_help()
|
|
51
|
+
return 1
|
|
52
|
+
|
|
53
|
+
if a.cmd == "stop-tor":
|
|
54
|
+
Tor().stop()
|
|
55
|
+
print("da tat Tor")
|
|
56
|
+
return 0
|
|
57
|
+
|
|
58
|
+
g = Gofile(token=a.token, use_tor=not a.no_tor, verbose=not a.as_json, proxy=a.proxy)
|
|
59
|
+
out = {}
|
|
60
|
+
try:
|
|
61
|
+
if a.cmd == "info":
|
|
62
|
+
j = g.info(a.target)
|
|
63
|
+
out = j.get("data") if j.get("status") == "ok" else {"error": j}
|
|
64
|
+
elif a.cmd == "download":
|
|
65
|
+
out = {"files": g.download(a.target, a.out, workers=a.workers,
|
|
66
|
+
verify=not a.no_verify)}
|
|
67
|
+
elif a.cmd == "upload":
|
|
68
|
+
out = g.upload(a.target)
|
|
69
|
+
elif a.cmd == "public":
|
|
70
|
+
out = {"ok": g.set_public(code=a.target)}
|
|
71
|
+
elif a.cmd == "delete":
|
|
72
|
+
if not a.target:
|
|
73
|
+
ap.error("thieu id")
|
|
74
|
+
out = g.delete(*a.target.split(","))
|
|
75
|
+
except Exception as e:
|
|
76
|
+
out = {"ok": False, "error": str(e)}
|
|
77
|
+
|
|
78
|
+
if isinstance(out, dict):
|
|
79
|
+
out.setdefault("_token", g.token)
|
|
80
|
+
print(json.dumps(out, ensure_ascii=False, indent=1))
|
|
81
|
+
return 0 if out.get("ok", True) else 1
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
if __name__ == "__main__":
|
|
85
|
+
sys.exit(main())
|
|
@@ -0,0 +1,547 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
gofile_tool.core — lõi: Tor, chữ ký web X-Website-Token, API Gofile, tải/upload.
|
|
4
|
+
|
|
5
|
+
Nguyên lý:
|
|
6
|
+
* Gofile tách hạ tầng: [web+api] bảo vệ gắt (hay drop TLS với IP datacenter),
|
|
7
|
+
còn [store*] lưu trữ và [upload] thì thoáng.
|
|
8
|
+
* Tool thử gọi API trực tiếp; nếu bị chặn -> tự bật Tor, xoay IP, tạo tài khoản
|
|
9
|
+
guest và ký header đúng chuẩn.
|
|
10
|
+
* Dữ liệu lớn luôn đi THẲNG tới store*/upload (không qua Tor) -> tốc độ tối đa.
|
|
11
|
+
"""
|
|
12
|
+
#!/usr/bin/env python3
|
|
13
|
+
# -*- coding: utf-8 -*-
|
|
14
|
+
"""
|
|
15
|
+
=============================================================================
|
|
16
|
+
gofile_tool.py — Tải / upload Gofile.io, kể cả khi IP máy bị Gofile chặn.
|
|
17
|
+
=============================================================================
|
|
18
|
+
|
|
19
|
+
NGUYÊN LÝ (đọc README.md để biết chi tiết):
|
|
20
|
+
* Gofile chia hạ tầng: [web+api] bị bảo vệ gắt, [store*] lưu trữ và
|
|
21
|
+
[upload] thì thoáng hơn. IP datacenter gọi API kiểu bot sẽ bị drop TLS.
|
|
22
|
+
* Tool này: (1) thử gọi API trực tiếp; nếu bị chặn → tự bật Tor, xoay IP,
|
|
23
|
+
tạo tài khoản guest, ký header X-Website-Token đúng chuẩn của Gofile;
|
|
24
|
+
(2) lấy metadata (vài KB) qua đường nào cũng được;
|
|
25
|
+
(3) TẢI/UPLOAD DỮ LIỆU LỚN thì đi THẲNG tới store*/upload (không qua Tor)
|
|
26
|
+
→ tốc độ tối đa.
|
|
27
|
+
|
|
28
|
+
LỆNH (copy-paste được ngay):
|
|
29
|
+
python3 gofile_tool.py info Uc4c9oyJ # xem metadata (JSON)
|
|
30
|
+
python3 gofile_tool.py download Uc4c9oyJ -o ./tai # tải file/folder
|
|
31
|
+
python3 gofile_tool.py upload file.zip # up + tự public + in link
|
|
32
|
+
python3 gofile_tool.py public <contentId|code> # set public
|
|
33
|
+
python3 gofile_tool.py stop-tor # tắt Tor
|
|
34
|
+
|
|
35
|
+
Thêm --json ở bất kỳ lệnh nào để nhận output máy đọc được (dành cho agent).
|
|
36
|
+
|
|
37
|
+
YÊU CẦU: python3 + requests + pysocks (tool tự pip cài nếu thiếu)
|
|
38
|
+
tor (chỉ cần khi IP bị chặn — tool tự apt/brew cài nếu có sudo)
|
|
39
|
+
node (tuỳ chọn, dùng để kiểm tra chéo chữ ký)
|
|
40
|
+
=============================================================================
|
|
41
|
+
"""
|
|
42
|
+
import hashlib
|
|
43
|
+
import json
|
|
44
|
+
import os
|
|
45
|
+
import re
|
|
46
|
+
import shutil
|
|
47
|
+
import socket
|
|
48
|
+
import subprocess
|
|
49
|
+
import sys
|
|
50
|
+
import time
|
|
51
|
+
from concurrent.futures import ThreadPoolExecutor
|
|
52
|
+
|
|
53
|
+
API = "https://api.gofile.io"
|
|
54
|
+
UPLOAD_URL = "https://upload.gofile.io/uploadfile"
|
|
55
|
+
UA = ("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
|
|
56
|
+
"(KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36")
|
|
57
|
+
LANG = "en-US"
|
|
58
|
+
TOR_DIR = os.path.expanduser("~/.cache/gofile-tor")
|
|
59
|
+
SECRET_CACHE = os.path.expanduser("~/.cache/gofile_secret.json")
|
|
60
|
+
SOCKS = "socks5h://127.0.0.1:9050"
|
|
61
|
+
CTRL = ("127.0.0.1", 9051)
|
|
62
|
+
|
|
63
|
+
# ---------------------------------------------------------------- deps ----
|
|
64
|
+
def ensure_deps():
|
|
65
|
+
try:
|
|
66
|
+
import requests # noqa
|
|
67
|
+
import socks # noqa
|
|
68
|
+
return True
|
|
69
|
+
except Exception:
|
|
70
|
+
pass
|
|
71
|
+
print("[deps] đang cài requests + pysocks…", file=sys.stderr)
|
|
72
|
+
for cmd in ([sys.executable, "-m", "pip", "install", "-q", "--disable-pip-version-check",
|
|
73
|
+
"requests", "pysocks"],
|
|
74
|
+
[sys.executable, "-m", "pip", "install", "-q", "--break-system-packages",
|
|
75
|
+
"--disable-pip-version-check", "requests", "pysocks"]):
|
|
76
|
+
try:
|
|
77
|
+
if subprocess.run(cmd, capture_output=True, timeout=300).returncode == 0:
|
|
78
|
+
return True
|
|
79
|
+
except Exception:
|
|
80
|
+
continue
|
|
81
|
+
print("[deps] KHÔNG cài được requests/pysocks — hãy chạy: "
|
|
82
|
+
"pip install requests pysocks", file=sys.stderr)
|
|
83
|
+
return False
|
|
84
|
+
|
|
85
|
+
ensure_deps()
|
|
86
|
+
import requests # noqa: E402
|
|
87
|
+
try:
|
|
88
|
+
import socks # noqa: F401
|
|
89
|
+
except Exception:
|
|
90
|
+
pass
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def log(*a):
|
|
94
|
+
print(*a, file=sys.stderr, flush=True)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
# ----------------------------------------------------------------- tor ----
|
|
98
|
+
class Tor:
|
|
99
|
+
"""Quản lý Tor: tự cài (nếu có sudo), tự chạy, tự xoay mạch (NEWNYM)."""
|
|
100
|
+
|
|
101
|
+
def __init__(self):
|
|
102
|
+
self.proc = None
|
|
103
|
+
self.cookie = None
|
|
104
|
+
|
|
105
|
+
@staticmethod
|
|
106
|
+
def binary():
|
|
107
|
+
return shutil.which("tor")
|
|
108
|
+
|
|
109
|
+
def install(self):
|
|
110
|
+
if self.binary():
|
|
111
|
+
return True
|
|
112
|
+
log("[tor] chưa có tor, thử cài…")
|
|
113
|
+
for cmd in (["sudo", "-n", "apt-get", "install", "-y", "-q", "tor"],
|
|
114
|
+
["apt-get", "install", "-y", "-q", "tor"],
|
|
115
|
+
["brew", "install", "tor"]):
|
|
116
|
+
try:
|
|
117
|
+
subprocess.run(cmd, capture_output=True, timeout=900)
|
|
118
|
+
if self.binary():
|
|
119
|
+
log("[tor] cài xong:", self.binary())
|
|
120
|
+
return True
|
|
121
|
+
except Exception:
|
|
122
|
+
continue
|
|
123
|
+
log("[tor] không tự cài được. Cài thủ công: sudo apt install tor | brew install tor")
|
|
124
|
+
return False
|
|
125
|
+
|
|
126
|
+
def running(self):
|
|
127
|
+
try:
|
|
128
|
+
s = socket.create_connection(("127.0.0.1", 9050), timeout=3)
|
|
129
|
+
s.close()
|
|
130
|
+
return True
|
|
131
|
+
except Exception:
|
|
132
|
+
return False
|
|
133
|
+
|
|
134
|
+
def start(self, wait=90):
|
|
135
|
+
"""Chạy tor: ưu tiên chạy ở user thường (đơn giản, không cần root);
|
|
136
|
+
nếu không được mới dùng sudo với thư mục riêng."""
|
|
137
|
+
if self.running():
|
|
138
|
+
return True
|
|
139
|
+
if not self.install():
|
|
140
|
+
return False
|
|
141
|
+
for prefix, d in (([], TOR_DIR), (["sudo", "-n"], "/tmp/gofile-tor-root")):
|
|
142
|
+
cfg_text = ("SocksPort 127.0.0.1:9050\n"
|
|
143
|
+
"ControlPort 127.0.0.1:9051\n"
|
|
144
|
+
"CookieAuthentication 1\n"
|
|
145
|
+
f"DataDirectory {d}\n"
|
|
146
|
+
f"Log notice file {d}/tor.log\n")
|
|
147
|
+
try:
|
|
148
|
+
if prefix: # chạy bằng root: dựng dir + file qua sudo
|
|
149
|
+
subprocess.run(["sudo", "-n", "rm", "-rf", d], capture_output=True, timeout=60)
|
|
150
|
+
subprocess.run(["sudo", "-n", "mkdir", "-p", d], capture_output=True, timeout=60)
|
|
151
|
+
subprocess.run(["sudo", "-n", "chmod", "700", d], capture_output=True, timeout=60)
|
|
152
|
+
cfg = "/tmp/gofile-torrc-root"
|
|
153
|
+
subprocess.run(["sudo", "-n", "tee", cfg], input=cfg_text.encode(),
|
|
154
|
+
capture_output=True, timeout=60)
|
|
155
|
+
else: # chạy bình thường
|
|
156
|
+
os.makedirs(d, exist_ok=True)
|
|
157
|
+
cfg = os.path.join(d, "torrc")
|
|
158
|
+
with open(cfg, "w") as fh:
|
|
159
|
+
fh.write(cfg_text)
|
|
160
|
+
self.proc = subprocess.Popen(prefix + ["tor", "-f", cfg],
|
|
161
|
+
stdout=subprocess.DEVNULL,
|
|
162
|
+
stderr=subprocess.DEVNULL)
|
|
163
|
+
for _ in range(wait):
|
|
164
|
+
time.sleep(1)
|
|
165
|
+
if self.running():
|
|
166
|
+
self.cookie = os.path.join(d, "control_auth_cookie")
|
|
167
|
+
log(f"[tor] sẵn sàng, IP ra ngoài: {self.exit_ip()}")
|
|
168
|
+
return True
|
|
169
|
+
try:
|
|
170
|
+
self.proc.terminate()
|
|
171
|
+
except Exception:
|
|
172
|
+
pass
|
|
173
|
+
except Exception as e:
|
|
174
|
+
log("[tor] lỗi khởi động:", type(e).__name__, e)
|
|
175
|
+
continue
|
|
176
|
+
log("[tor] không khởi động được Tor — kiểm tra: sudo apt install tor")
|
|
177
|
+
return False
|
|
178
|
+
|
|
179
|
+
@staticmethod
|
|
180
|
+
def exit_ip():
|
|
181
|
+
try:
|
|
182
|
+
return requests.get("https://api.ipify.org",
|
|
183
|
+
proxies={"http": SOCKS, "https": SOCKS}, timeout=25).text
|
|
184
|
+
except Exception as e:
|
|
185
|
+
return f"?({type(e).__name__})"
|
|
186
|
+
|
|
187
|
+
def newnym(self):
|
|
188
|
+
"""Đổi exit node (SIGNAL NEWNYM) qua control port + cookie auth."""
|
|
189
|
+
cookie = getattr(self, "cookie", None) or os.path.join(TOR_DIR, "control_auth_cookie")
|
|
190
|
+
try:
|
|
191
|
+
data = open(cookie, "rb").read().hex()
|
|
192
|
+
except Exception:
|
|
193
|
+
try:
|
|
194
|
+
data = subprocess.run(["sudo", "-n", "cat", cookie],
|
|
195
|
+
capture_output=True, timeout=30).stdout.decode().strip()
|
|
196
|
+
except Exception:
|
|
197
|
+
return False
|
|
198
|
+
try:
|
|
199
|
+
s = socket.create_connection(CTRL, timeout=10)
|
|
200
|
+
s.sendall(f"AUTHENTICATE {data}\r\n".encode())
|
|
201
|
+
time.sleep(0.3)
|
|
202
|
+
s.sendall(b"SIGNAL NEWNYM\r\n")
|
|
203
|
+
time.sleep(0.3)
|
|
204
|
+
s.close()
|
|
205
|
+
return True
|
|
206
|
+
except Exception:
|
|
207
|
+
return False
|
|
208
|
+
|
|
209
|
+
def stop(self):
|
|
210
|
+
try:
|
|
211
|
+
subprocess.run(["pkill", "-f", f"tor -f {TOR_DIR}"], capture_output=True, timeout=30)
|
|
212
|
+
except Exception:
|
|
213
|
+
pass
|
|
214
|
+
if self.proc:
|
|
215
|
+
try:
|
|
216
|
+
self.proc.terminate()
|
|
217
|
+
except Exception:
|
|
218
|
+
pass
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
# --------------------------------------------------------------- secret ----
|
|
222
|
+
def extract_secret(js_text):
|
|
223
|
+
"""Bóc secret chữ ký web từ wt.obf.js (không cần node)."""
|
|
224
|
+
cands = set()
|
|
225
|
+
for m in re.finditer(r"'((?:\\x[0-9a-fA-F]{2})+)'", js_text):
|
|
226
|
+
try:
|
|
227
|
+
s = bytes(int(h, 16) for h in re.findall(r"\\x([0-9a-fA-F]{2})", m.group(1)))
|
|
228
|
+
s = s.decode("latin1")
|
|
229
|
+
except Exception:
|
|
230
|
+
continue
|
|
231
|
+
if re.fullmatch(r"[0-9a-f]{12,24}", s):
|
|
232
|
+
cands.add(s)
|
|
233
|
+
if not cands:
|
|
234
|
+
return None
|
|
235
|
+
return sorted(cands, key=len)[-1]
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def node_secret(js_path):
|
|
239
|
+
"""Kiểm tra chéo bằng node (nếu có): chạy generateWT() của chính Gofile."""
|
|
240
|
+
if not shutil.which("node"):
|
|
241
|
+
return None
|
|
242
|
+
code = r"""
|
|
243
|
+
const fs=require('fs'),vm=require('vm');
|
|
244
|
+
const src=fs.readFileSync(process.argv[2],'utf8');
|
|
245
|
+
const sandbox={console,setTimeout,setInterval};sandbox.globalThis=sandbox;
|
|
246
|
+
sandbox.navigator={userAgent:process.argv[3]||'x',language:'en-US'};
|
|
247
|
+
sandbox.document={querySelector:()=>null,getElementById:()=>null,addEventListener:()=>{},
|
|
248
|
+
createElement:()=>({style:{},setAttribute:()=>{},appendChild:()=>{}}),body:{appendChild:()=>{}},currentScript:null};
|
|
249
|
+
sandbox.location={href:'https://gofile.io/',hostname:'gofile.io'};
|
|
250
|
+
sandbox.performance={timeOrigin:Date.now()};sandbox.addEventListener=()=>{};
|
|
251
|
+
vm.createContext(sandbox);vm.runInContext(src,sandbox,{timeout:20000});
|
|
252
|
+
console.log(sandbox.generateWT('TOKEN'));
|
|
253
|
+
"""
|
|
254
|
+
try:
|
|
255
|
+
out = subprocess.run(["node", "-e", code, js_path, UA],
|
|
256
|
+
capture_output=True, timeout=60, text=True)
|
|
257
|
+
return out.stdout.strip() or None
|
|
258
|
+
except Exception:
|
|
259
|
+
return None
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
# ------------------------------------------------------------------ api ----
|
|
263
|
+
class Gofile:
|
|
264
|
+
def __init__(self, token=None, use_tor=True, verbose=True, proxy=None):
|
|
265
|
+
self.verbose = verbose
|
|
266
|
+
self.token = token or os.environ.get("GOFILE_TOKEN")
|
|
267
|
+
self.use_tor = use_tor
|
|
268
|
+
self.proxy = proxy or os.environ.get("GOFILE_PROXY")
|
|
269
|
+
self.tor = Tor()
|
|
270
|
+
self.secret = self._load_secret()
|
|
271
|
+
self.direct_ok = None # None = chưa biết
|
|
272
|
+
self.last_ip = None
|
|
273
|
+
|
|
274
|
+
# ---- hạ tầng ---------------------------------------------------------
|
|
275
|
+
def _load_secret(self):
|
|
276
|
+
try:
|
|
277
|
+
d = json.load(open(SECRET_CACHE))
|
|
278
|
+
if time.time() - d["at"] < 6 * 3600:
|
|
279
|
+
return d["secret"]
|
|
280
|
+
except Exception:
|
|
281
|
+
pass
|
|
282
|
+
return None
|
|
283
|
+
|
|
284
|
+
def _save_secret(self, s):
|
|
285
|
+
try:
|
|
286
|
+
os.makedirs(os.path.dirname(SECRET_CACHE), exist_ok=True)
|
|
287
|
+
json.dump({"secret": s, "at": time.time()}, open(SECRET_CACHE, "w"))
|
|
288
|
+
except Exception:
|
|
289
|
+
pass
|
|
290
|
+
|
|
291
|
+
def fetch_secret(self, force=False):
|
|
292
|
+
if self.secret and not force:
|
|
293
|
+
return self.secret
|
|
294
|
+
js = self.raw_get("https://gofile.io/js/wt.obf.js")
|
|
295
|
+
if not js:
|
|
296
|
+
return None
|
|
297
|
+
p = os.path.join(TOR_DIR, "wt.obf.js")
|
|
298
|
+
try:
|
|
299
|
+
os.makedirs(TOR_DIR, exist_ok=True)
|
|
300
|
+
open(p, "w").write(js)
|
|
301
|
+
except Exception:
|
|
302
|
+
p = None
|
|
303
|
+
s = extract_secret(js)
|
|
304
|
+
if s and p:
|
|
305
|
+
n = node_secret(p)
|
|
306
|
+
if n: # đối chiếu với hàm gốc của Gofile
|
|
307
|
+
expect = hashlib.sha256(
|
|
308
|
+
f"{UA}::{LANG}::TOKEN::{int(time.time() // 14400)}::{s}".encode()
|
|
309
|
+
).hexdigest()
|
|
310
|
+
if n != expect:
|
|
311
|
+
log("[wt] node báo khác secret, thử lại…")
|
|
312
|
+
s = None
|
|
313
|
+
if s:
|
|
314
|
+
self.secret = s
|
|
315
|
+
self._save_secret(s)
|
|
316
|
+
return s
|
|
317
|
+
|
|
318
|
+
def proxy_chain(self):
|
|
319
|
+
"""Danh sách đường ra theo thứ tự ưu tiên: thẳng -> proxy riêng -> Tor."""
|
|
320
|
+
chain = [("direct", None)]
|
|
321
|
+
if self.proxy:
|
|
322
|
+
chain.append((self.proxy, {"http": self.proxy, "https": self.proxy}))
|
|
323
|
+
if self.use_tor:
|
|
324
|
+
chain.append((SOCKS, {"http": SOCKS, "https": SOCKS}))
|
|
325
|
+
return chain
|
|
326
|
+
|
|
327
|
+
def raw_get(self, url, timeout=40):
|
|
328
|
+
"""GET thô: thẳng trước, hỏng thì qua Tor."""
|
|
329
|
+
for label, proxies in self.proxy_chain():
|
|
330
|
+
if label == SOCKS and not self.tor.start():
|
|
331
|
+
continue
|
|
332
|
+
try:
|
|
333
|
+
r = requests.get(url, headers={"User-Agent": UA},
|
|
334
|
+
proxies=proxies, timeout=timeout)
|
|
335
|
+
if r.status_code == 200:
|
|
336
|
+
return r.text
|
|
337
|
+
except Exception:
|
|
338
|
+
continue
|
|
339
|
+
return None
|
|
340
|
+
|
|
341
|
+
def wt(self):
|
|
342
|
+
s = self.fetch_secret()
|
|
343
|
+
if not s:
|
|
344
|
+
return None
|
|
345
|
+
bucket = int(time.time() // 14400)
|
|
346
|
+
raw = f"{UA}::{LANG}::{self.token}::{bucket}::{s}"
|
|
347
|
+
return hashlib.sha256(raw.encode()).hexdigest()
|
|
348
|
+
|
|
349
|
+
def headers(self):
|
|
350
|
+
h = {"User-Agent": UA, "Accept-Language": "en-US,en;q=0.9",
|
|
351
|
+
"Authorization": f"Bearer {self.token}", "X-BL": LANG,
|
|
352
|
+
"Referer": "https://gofile.io/"}
|
|
353
|
+
w = self.wt()
|
|
354
|
+
if w:
|
|
355
|
+
h["X-Website-Token"] = w
|
|
356
|
+
return h
|
|
357
|
+
|
|
358
|
+
# ---- lõi gọi API: thẳng → proxy riêng → Tor (xoay IP) -----------------
|
|
359
|
+
def api(self, method, path, *, tries=6, **kw):
|
|
360
|
+
timeout = kw.pop("timeout", 60)
|
|
361
|
+
last = None
|
|
362
|
+
for i in range(1, tries + 1):
|
|
363
|
+
if not self.token and not self.new_account():
|
|
364
|
+
last = "không tạo được tài khoản guest"
|
|
365
|
+
continue
|
|
366
|
+
for label, proxies in self.proxy_chain():
|
|
367
|
+
if label == SOCKS:
|
|
368
|
+
if not self.tor.start():
|
|
369
|
+
continue
|
|
370
|
+
if i > 1: # đổi exit node rồi thử lại
|
|
371
|
+
self.tor.newnym()
|
|
372
|
+
time.sleep(5)
|
|
373
|
+
self.last_ip = self.tor.exit_ip()
|
|
374
|
+
try:
|
|
375
|
+
r = requests.request(method, API + path, headers=self.headers(),
|
|
376
|
+
proxies=proxies, timeout=timeout, **kw)
|
|
377
|
+
if r.status_code == 200:
|
|
378
|
+
return r
|
|
379
|
+
last = f"{label or 'direct'}: HTTP {r.status_code} {r.text[:120]}"
|
|
380
|
+
if b"notPremium" in r.content: # secret đã xoay → nạp lại
|
|
381
|
+
self.secret = None
|
|
382
|
+
self.fetch_secret(force=True)
|
|
383
|
+
elif b"rateLimit" in r.content: # IP/exit node bị xài chung → đổi mạch
|
|
384
|
+
continue
|
|
385
|
+
except Exception as e:
|
|
386
|
+
last = f"{label or 'direct'}: {type(e).__name__}"
|
|
387
|
+
continue
|
|
388
|
+
if self.use_tor and self.tor.running():
|
|
389
|
+
self.tor.newnym()
|
|
390
|
+
time.sleep(5)
|
|
391
|
+
raise RuntimeError(
|
|
392
|
+
f"API thất bại ({last or 'không rõ'}). IP có thể bị Gofile chặn. "
|
|
393
|
+
f"Thử: sudo apt install -y tor | hoặc --proxy socks5h://127.0.0.1:1080")
|
|
394
|
+
|
|
395
|
+
def new_account(self):
|
|
396
|
+
for label, proxies in self.proxy_chain():
|
|
397
|
+
if label == SOCKS and not self.tor.start():
|
|
398
|
+
continue
|
|
399
|
+
try:
|
|
400
|
+
r = requests.post(API + "/accounts", data=b"{}",
|
|
401
|
+
headers={"Content-Type": "application/json",
|
|
402
|
+
"User-Agent": UA},
|
|
403
|
+
proxies=proxies, timeout=45)
|
|
404
|
+
j = r.json()
|
|
405
|
+
if j.get("status") == "ok":
|
|
406
|
+
self.token = j["data"]["token"]
|
|
407
|
+
self.root = j["data"]["rootFolder"]
|
|
408
|
+
if self.verbose:
|
|
409
|
+
log(f"[acct] guest token: {self.token}")
|
|
410
|
+
return True
|
|
411
|
+
except Exception:
|
|
412
|
+
continue
|
|
413
|
+
return False
|
|
414
|
+
|
|
415
|
+
# ---- tác vụ -----------------------------------------------------------
|
|
416
|
+
def info(self, code, page=1, page_size=1000):
|
|
417
|
+
if not self.token:
|
|
418
|
+
self.new_account()
|
|
419
|
+
r = self.api("GET", f"/contents/{code}",
|
|
420
|
+
params={"page": page, "pageSize": page_size,
|
|
421
|
+
"sortField": "name", "sortDirection": 1}, timeout=60)
|
|
422
|
+
return r.json()
|
|
423
|
+
|
|
424
|
+
def walk(self, code):
|
|
425
|
+
"""Trả về danh sách file (đệ quy nếu là folder)."""
|
|
426
|
+
out = []
|
|
427
|
+
|
|
428
|
+
def rec(cid, path=""):
|
|
429
|
+
j = self.info(cid)
|
|
430
|
+
d = j.get("data") or {}
|
|
431
|
+
if d.get("type") == "file":
|
|
432
|
+
out.append({**d, "_path": path})
|
|
433
|
+
return
|
|
434
|
+
for child in (d.get("children") or {}).values():
|
|
435
|
+
if child.get("type") == "folder":
|
|
436
|
+
rec(child["id"], os.path.join(path, child["name"]))
|
|
437
|
+
else:
|
|
438
|
+
out.append({**child, "_path": path})
|
|
439
|
+
rec(code)
|
|
440
|
+
return out
|
|
441
|
+
|
|
442
|
+
def download(self, code, outdir=".", workers=4, verify=True):
|
|
443
|
+
meta = self.info(code)
|
|
444
|
+
d = meta.get("data") or {}
|
|
445
|
+
os.makedirs(outdir, exist_ok=True)
|
|
446
|
+
files = self.walk(code) if d.get("type") == "folder" else [{**d, "_path": ""}]
|
|
447
|
+
log(f"[dl] {len(files)} file, tổng "
|
|
448
|
+
f"{sum(f.get('size', 0) for f in files) / 1048576:.0f} MB")
|
|
449
|
+
res = []
|
|
450
|
+
with ThreadPoolExecutor(max_workers=max(1, workers)) as ex:
|
|
451
|
+
for r in ex.map(lambda f: self._get_one(f, outdir, verify), files):
|
|
452
|
+
res.append(r)
|
|
453
|
+
return res
|
|
454
|
+
|
|
455
|
+
def _get_one(self, f, outdir, verify):
|
|
456
|
+
sub = os.path.join(outdir, f.get("_path", ""))
|
|
457
|
+
os.makedirs(sub, exist_ok=True)
|
|
458
|
+
dst = os.path.join(sub, f["name"])
|
|
459
|
+
url = f.get("link") or f"https://{f.get('serverSelected', 'store1')}.gofile.io" \
|
|
460
|
+
f"/download/web/{f['id']}/{f['name']}"
|
|
461
|
+
tmp = dst + ".part"
|
|
462
|
+
done = os.path.getsize(tmp) if os.path.exists(tmp) else 0
|
|
463
|
+
head = {"User-Agent": UA, "Cookie": f"accountToken={self.token}"}
|
|
464
|
+
if done and done < f.get("size", 1):
|
|
465
|
+
head["Range"] = f"bytes={done}-"
|
|
466
|
+
mode = "ab" if done else "wb"
|
|
467
|
+
t0 = time.time()
|
|
468
|
+
try:
|
|
469
|
+
r = requests.get(url, headers=head, stream=True, timeout=120)
|
|
470
|
+
if r.status_code not in (200, 206):
|
|
471
|
+
return {"file": f["name"], "ok": False, "err": f"HTTP {r.status_code}"}
|
|
472
|
+
total = int(r.headers.get("Content-Length", 0)) + done
|
|
473
|
+
with open(tmp, mode) as fh:
|
|
474
|
+
for chunk in r.iter_content(1 << 20):
|
|
475
|
+
if chunk:
|
|
476
|
+
fh.write(chunk)
|
|
477
|
+
done += len(chunk)
|
|
478
|
+
os.replace(tmp, dst)
|
|
479
|
+
except Exception as e:
|
|
480
|
+
return {"file": f["name"], "ok": False, "err": type(e).__name__,
|
|
481
|
+
"partial": tmp}
|
|
482
|
+
sz = os.path.getsize(dst)
|
|
483
|
+
ok = (sz == f.get("size", sz))
|
|
484
|
+
md5ok = None
|
|
485
|
+
if verify and f.get("md5"):
|
|
486
|
+
h = hashlib.md5()
|
|
487
|
+
with open(dst, "rb") as fh:
|
|
488
|
+
for c in iter(lambda: fh.read(1 << 20), b""):
|
|
489
|
+
h.update(c)
|
|
490
|
+
md5ok = (h.hexdigest() == f["md5"])
|
|
491
|
+
sp = sz / max(0.001, (time.time() - t0)) / 1048576
|
|
492
|
+
log(f"[dl] xong {f['name'][:70]} {sz/1048576:.1f} MB {sp:.1f} MB/s"
|
|
493
|
+
f" md5={'OK' if md5ok else ('SAI' if md5ok is False else '-')}")
|
|
494
|
+
return {"file": f["name"], "path": dst, "size": sz, "ok": ok, "md5_ok": md5ok}
|
|
495
|
+
|
|
496
|
+
def upload(self, path, folder_id=None, public=True, timeout=3600):
|
|
497
|
+
if not self.token:
|
|
498
|
+
self.new_account()
|
|
499
|
+
fid = folder_id or getattr(self, "root", None)
|
|
500
|
+
data = {"folderId": fid or "", "token": self.token}
|
|
501
|
+
t0 = time.time()
|
|
502
|
+
with open(path, "rb") as fh:
|
|
503
|
+
r = requests.post(UPLOAD_URL, files={"file": (os.path.basename(path), fh)},
|
|
504
|
+
data=data, timeout=timeout)
|
|
505
|
+
j = r.json()
|
|
506
|
+
if j.get("status") != "ok":
|
|
507
|
+
return {"ok": False, "raw": j}
|
|
508
|
+
d = j["data"]
|
|
509
|
+
out = {"ok": True, "name": d["name"], "size": d["size"], "md5": d.get("md5"),
|
|
510
|
+
"code": d.get("code"), "page": d.get("downloadPage"),
|
|
511
|
+
"file_id": d.get("id"),
|
|
512
|
+
"speed_MBps": round(d["size"] / max(0.001, time.time() - t0) / 1048576, 1)}
|
|
513
|
+
if public:
|
|
514
|
+
pub = self.set_public(d.get("id"), d.get("code"), d.get("parentFolder"))
|
|
515
|
+
out["public"] = pub
|
|
516
|
+
if pub:
|
|
517
|
+
out["link"] = f"https://gofile.io/d/{d.get('code')}"
|
|
518
|
+
log(f"[up] xong {d['name']} — {out['speed_MBps']} MB/s")
|
|
519
|
+
return out
|
|
520
|
+
|
|
521
|
+
def delete(self, *ids):
|
|
522
|
+
"""Xoá file/thư mục (cần token chủ sở hữu)."""
|
|
523
|
+
try:
|
|
524
|
+
r = self.api("DELETE", "/contents", json={"contentsId": ",".join(ids)}, timeout=60)
|
|
525
|
+
return r.json()
|
|
526
|
+
except Exception as e:
|
|
527
|
+
return {"ok": False, "error": str(e)}
|
|
528
|
+
|
|
529
|
+
def set_public(self, content_id=None, code=None, parent_id=None):
|
|
530
|
+
"""Bắt buộc set public cho THƯ MỤC CHA (recursive) trước, rồi mới tới file
|
|
531
|
+
— nếu chỉ set file thì khách vẫn thấy 'Protected content'."""
|
|
532
|
+
ids = [parent_id, content_id or code]
|
|
533
|
+
ok_all = False
|
|
534
|
+
for cid in ids:
|
|
535
|
+
if not cid:
|
|
536
|
+
continue
|
|
537
|
+
try:
|
|
538
|
+
r = self.api("PUT", f"/contents/{cid}/update",
|
|
539
|
+
json={"attribute": "public", "attributeValue": True,
|
|
540
|
+
"recursive": True}, timeout=60)
|
|
541
|
+
ok_all = r.json().get("status") == "ok"
|
|
542
|
+
except Exception as e:
|
|
543
|
+
log("[public] lỗi:", e)
|
|
544
|
+
ok_all = False
|
|
545
|
+
return ok_all
|
|
546
|
+
|
|
547
|
+
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: gofile-tool
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Tải / upload Gofile.io tốc độ tối đa — tự động vượt chặn IP (Tor + chữ ký web X-Website-Token)
|
|
5
|
+
Author: gofile-tool contributors
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://pypi.org/project/gofile-tool/
|
|
8
|
+
Project-URL: Source, https://pypi.org/project/gofile-tool/
|
|
9
|
+
Keywords: gofile,downloader,uploader,tor,cli,bypass,download
|
|
10
|
+
Classifier: Environment :: Console
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
17
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
18
|
+
Classifier: Topic :: Utilities
|
|
19
|
+
Requires-Python: >=3.8
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Requires-Dist: requests>=2.25.0
|
|
23
|
+
Requires-Dist: pysocks>=1.7.1
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: build; extra == "dev"
|
|
26
|
+
Requires-Dist: twine; extra == "dev"
|
|
27
|
+
Dynamic: license-file
|
|
28
|
+
|
|
29
|
+
# 🧰 gofile-tool
|
|
30
|
+
|
|
31
|
+
**Tải / upload Gofile.io ở tốc độ tối đa — tự động vượt chặn IP của datacenter/VPS.**
|
|
32
|
+
|
|
33
|
+
Gofile hay drop kết nối TLS với IP máy ảo (báo `error-rateLimit`, treo TLS handshake).
|
|
34
|
+
`gofile-tool` tự xử lý: thử đường thẳng → nếu bị chặn thì tự bật **Tor**, xoay IP, tạo tài
|
|
35
|
+
khoản guest và ký đúng header `X-Website-Token` mà Gofile đòi. Dữ liệu lớn vẫn tải/upload
|
|
36
|
+
**thẳng** qua `store*.gofile.io` / `upload.gofile.io` nên tốc độ nguyên bản.
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
pip install gofile-tool
|
|
40
|
+
gofile-tool download Uc4c9oyJ -o ./tai-ve
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## ⚡ Cài đặt
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pip install gofile-tool # hoặc: pipx install gofile-tool
|
|
49
|
+
|
|
50
|
+
# chỉ cần khi IP của bạn bị Gofile chặn (tool tự bật Tor):
|
|
51
|
+
sudo apt install -y tor # Debian/Ubuntu
|
|
52
|
+
brew install tor # macOS
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Yêu cầu: Python ≥ 3.8.
|
|
56
|
+
|
|
57
|
+
## 🚀 Lệnh
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
gofile-tool info <CODE> # xem metadata file/folder
|
|
61
|
+
gofile-tool download <CODE> -o ./tai-ve # tải file hoặc cả folder
|
|
62
|
+
gofile-tool upload ./file.zip # up + tự set public + in link
|
|
63
|
+
gofile-tool public <CODE> # mở public cho nội dung đã có
|
|
64
|
+
gofile-tool delete <FILE_ID> --token <TK> # xoá file
|
|
65
|
+
gofile-tool stop-tor # tắt Tor
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
| Cờ | Ý nghĩa |
|
|
69
|
+
|---|---|
|
|
70
|
+
| `--json` | Output JSON (cho AI agent / script). Luôn kèm `_token` để quản lý sau |
|
|
71
|
+
| `-o DIR` | Thư mục lưu file tải về (mặc định `.`) |
|
|
72
|
+
| `--workers N` | Số luồng khi tải folder (mặc định 4) |
|
|
73
|
+
| `--token TOKEN` | Dùng tài khoản Gofile của bạn (mặc định tự tạo guest) |
|
|
74
|
+
| `--proxy URL` | Dùng proxy/VPN riêng: `--proxy socks5h://127.0.0.1:1080` |
|
|
75
|
+
| `--no-tor` | Không dùng Tor |
|
|
76
|
+
| `--no-verify` | Bỏ qua kiểm tra MD5 |
|
|
77
|
+
|
|
78
|
+
**Ví dụ JSON (`gofile-tool upload ./file.zip --json`):**
|
|
79
|
+
|
|
80
|
+
```json
|
|
81
|
+
{
|
|
82
|
+
"ok": true, "name": "file.zip", "size": 577188003, "md5": "912175…",
|
|
83
|
+
"code": "UGqKJoFZ", "page": "https://gofile.io/d/nAF2ydFc",
|
|
84
|
+
"file_id": "783e9f12-…", "speed_MBps": 83.0,
|
|
85
|
+
"public": true, "link": "https://gofile.io/d/UGqKJoFZ",
|
|
86
|
+
"_token": "Q23LICkojSBdNVgRjhbx7z72ZqVBldGw"
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## 🤖 Dành cho AI agent
|
|
91
|
+
|
|
92
|
+
Không cần agent thông minh — chỉ cần bảo nó chạy:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
pip install gofile-tool
|
|
96
|
+
gofile-tool download <CODE> -o <DIR> --json # hoặc: gofile-tool upload <FILE> --json
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Mọi lệnh đều có `--json`; output gồm `link`, `md5`, `size`, `ok`, `_token`.
|
|
100
|
+
Tool tự lo: tài khoản, chữ ký, đổi IP, resume, kiểm tra MD5.
|
|
101
|
+
|
|
102
|
+
## 🔍 Nguyên lý (3 mánh)
|
|
103
|
+
|
|
104
|
+
1. **Ký đúng chữ ký web.** Gofile đòi
|
|
105
|
+
`X-Website-Token = sha256(UA :: ngôn ngữ :: accountToken :: floor(epoch/14400) :: secret)`.
|
|
106
|
+
`secret` nằm trong `/js/wt.obf.js` và **bị xoay định kỳ** → tool tự tải, tự bóc
|
|
107
|
+
(và đối chiếu chéo bằng `node` nếu có), cache 6 giờ.
|
|
108
|
+
2. **Đổi IP bằng Tor khi bị chặn.** Tự cài/khởi động Tor (SOCKS5 `9050`, control `9051`),
|
|
109
|
+
gặp `error-rateLimit` thì gửi `SIGNAL NEWNYM` đổi exit node, thử lại tối đa 6 lần.
|
|
110
|
+
3. **Tách đường điều khiển / đường dữ liệu.** Chỉ vài KB metadata đi qua Tor/chậm;
|
|
111
|
+
còn dữ liệu lớn đi **thẳng** `store*` / `upload` → tốc độ tối đa
|
|
112
|
+
(đo thực tế: **tải 36 MB/s**, **upload 83 MB/s**).
|
|
113
|
+
|
|
114
|
+
Không vượt quyền truy cập: tool chỉ gửi đúng header mà trình duyệt vẫn gửi;
|
|
115
|
+
file private thì vẫn không mở được.
|
|
116
|
+
|
|
117
|
+
## 🩺 Sự cố thường gặp
|
|
118
|
+
|
|
119
|
+
| Thông báo | Cách sửa |
|
|
120
|
+
|---|---|
|
|
121
|
+
| `error-notPremium` | Secret đã xoay → tool tự nạp lại; nếu kẹt: xoá `~/.cache/gofile_secret.json` |
|
|
122
|
+
| `error-rateLimit` | Tool tự đổi mạch Tor; chờ vài giây |
|
|
123
|
+
| `API thất bại (direct: ConnectTimeout)` | Thiếu Tor → `sudo apt install -y tor`, hoặc `--proxy socks5h://…` |
|
|
124
|
+
| Folder tải chậm | Gofile chỉ cho ZIP folder ở gói Premium → tool tải từng file, đa luồng |
|
|
125
|
+
| `Permission denied …/control_auth_cookie` | `sudo rm -rf ~/.cache/gofile-tor` rồi chạy lại |
|
|
126
|
+
| Upload xong bị "Protected content" | Phải set public cho **cả thư mục cha** — tool đã làm sẵn |
|
|
127
|
+
|
|
128
|
+
## ⚠️ Giới hạn
|
|
129
|
+
|
|
130
|
+
- Mặc định dùng tài khoản **guest** (tự tạo). Muốn giữ file lâu: truyền `--token <token của bạn>` hoặc set `GOFILE_TOKEN`.
|
|
131
|
+
- Gofile miễn phí dọn file sau ~10 ngày không có lượt tải.
|
|
132
|
+
- Cần `tor` (hoặc proxy riêng) **chỉ khi** IP của bạn bị chặn; IP nhà thường không cần.
|
|
133
|
+
|
|
134
|
+
## Giấy phép
|
|
135
|
+
|
|
136
|
+
MIT
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
README_PYPI.md
|
|
4
|
+
pyproject.toml
|
|
5
|
+
src/gofile_tool/__init__.py
|
|
6
|
+
src/gofile_tool/__main__.py
|
|
7
|
+
src/gofile_tool/cli.py
|
|
8
|
+
src/gofile_tool/core.py
|
|
9
|
+
src/gofile_tool.egg-info/PKG-INFO
|
|
10
|
+
src/gofile_tool.egg-info/SOURCES.txt
|
|
11
|
+
src/gofile_tool.egg-info/dependency_links.txt
|
|
12
|
+
src/gofile_tool.egg-info/entry_points.txt
|
|
13
|
+
src/gofile_tool.egg-info/requires.txt
|
|
14
|
+
src/gofile_tool.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
gofile_tool
|