Metadata-Version: 2.4
Name: zefoy-client
Version: 0.1.5
Summary: Python client for zefoy.com — JSON-only API (login, services, send views/hearts/...)
Author: zefoy-client contributors
License-Expression: MIT
Project-URL: Homepage, https://github.com/deno4908/zefoy_lib
Project-URL: Repository, https://github.com/deno4908/zefoy_lib
Project-URL: Issues, https://github.com/deno4908/zefoy_lib/issues
Keywords: zefoy,tiktok,automation,api,client
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: cloudscraper>=1.2.71
Requires-Dist: beautifulsoup4>=4.12.0
Requires-Dist: Pillow>=10.0.0
Requires-Dist: numpy>=1.24.0
Requires-Dist: ddddocr>=1.4.11
Requires-Dist: pyspellchecker>=0.8.3
Requires-Dist: pycryptodome>=3.19.0
Requires-Dist: brotli>=1.1.0
Requires-Dist: requests>=2.31.0
Provides-Extra: ocr
Requires-Dist: pytesseract>=0.3.10; extra == "ocr"
Provides-Extra: socks
Requires-Dist: PySocks>=1.7.1; extra == "socks"
Requires-Dist: requests[socks]>=2.31.0; extra == "socks"
Provides-Extra: dev
Requires-Dist: build; extra == "dev"
Requires-Dist: twine; extra == "dev"
Requires-Dist: pytest; extra == "dev"
Dynamic: license-file

# zefoy-client

Python client library for [zefoy.com](https://zefoy.com).

- **JSON-only API** — every public method returns a `dict` (ready for `json.dumps`)
- No stdout noise from the library
- Captcha OCR ensemble via **ddddocr**, adaptive image preprocessing, and optional **Tesseract**
- Auto cooldown wait (IP-based server timer)
- Services: views, hearts, favorites, shares, followers, …

> **Disclaimer:** Unofficial. Use at your own risk. Respect site terms and local laws. For educational / automation research purposes.

---

## Install

Yêu cầu Python 3.9 trở lên. Nên cài trong môi trường ảo để không ảnh hưởng
những thư viện Python khác trên máy.

### Windows

```powershell
py -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
python -m pip install zefoy-client
```

Nếu PowerShell chặn script kích hoạt, chạy một lần trong cửa sổ hiện tại:

```powershell
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
.\.venv\Scripts\Activate.ps1
```

### Linux / macOS

```bash
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install zefoy-client
```

### PyPI

```bash
python -m pip install zefoy-client
```

Optional extras:

```bash
python -m pip install "zefoy-client[socks]"       # SOCKS4/5 proxy
python -m pip install "zefoy-client[ocr]"         # pytesseract helper
python -m pip install "zefoy-client[socks,ocr]"   # install both
```

`ddddocr`, `pyspellchecker` và phần xử lý ảnh mới được cài tự động cùng
package. Extra `ocr` cài Python wrapper `pytesseract`, nhưng muốn dùng được
Tesseract thì máy cũng phải có chương trình Tesseract OCR:

- Windows: cài Tesseract OCR, rồi thêm thư mục chứa `tesseract.exe` vào `PATH`.
- Ubuntu/Debian: `sudo apt update && sudo apt install tesseract-ocr`
- macOS (Homebrew): `brew install tesseract`

Kiểm tra:

```bash
tesseract --version
python -c "from zefoy import Zefoy, __version__; print(__version__)"
```

Tesseract là tùy chọn. Nếu chưa cài, thư viện vẫn chạy bằng `ddddocr`.

### GitHub

Repo: [https://github.com/deno4908/zefoy_lib](https://github.com/deno4908/zefoy_lib)

```bash
# latest main
pip install git+https://github.com/deno4908/zefoy_lib.git
```

---

## Quick start

```python
import json
from zefoy import Zefoy

bot = Zefoy(
    use_ocr=True,       # ensemble OCR: ddddocr + optional Tesseract
    auto_wait=True,     # sleep on server cooldown
    # proxy="http://user:pass@host:port",
)

print(json.dumps(bot.login(), ensure_ascii=False, indent=2))
print(json.dumps(bot.services(), ensure_ascii=False, indent=2))

url = "https://www.tiktok.com/@user/video/1234567890"
print(json.dumps(bot.send_views(url), ensure_ascii=False, indent=2))
```

### Proxy

`proxy` áp dụng cho **toàn session** (login + captcha + services + send).  
Hỗ trợ URL string hoặc dict kiểu `requests`.

| Loại | Ví dụ |
|------|--------|
| HTTP | `http://host:8080` |
| HTTP + auth | `http://user:pass@host:8080` |
| HTTPS proxy | `https://user:pass@host:8443` |
| SOCKS5 | `socks5://user:pass@host:1080` |
| SOCKS5h (DNS qua proxy) | `socks5h://user:pass@host:1080` |
| SOCKS4 | `socks4://host:1080` |

```bash
# SOCKS cần thêm dependency
python -m pip install "zefoy-client[socks]"
```

```python
from zefoy import Zefoy
import json

# 1) HTTP proxy (string — gán cả http & https)
bot = Zefoy(proxy="http://1.2.3.4:8080")

# 2) HTTP có user/pass
bot = Zefoy(proxy="http://myuser:mypass@1.2.3.4:8080")

# 3) SOCKS5
bot = Zefoy(proxy="socks5://user:pass@1.2.3.4:1080")

# 4) SOCKS5 + resolve DNS trên proxy
bot = Zefoy(proxy="socks5h://user:pass@1.2.3.4:1080")

# 5) Dict tách http / https (giống requests)
bot = Zefoy(proxy={
    "http": "http://user:pass@1.2.3.4:8080",
    "https": "http://user:pass@1.2.3.4:8080",
})

# 6) Dùng với send
url = "https://www.tiktok.com/@user/video/123"
print(json.dumps(bot.login(), ensure_ascii=False, indent=2))
print(json.dumps(bot.send_views(url), ensure_ascii=False, indent=2))
print(json.dumps(bot.send_hearts(url), ensure_ascii=False, indent=2))
```

CLI:

```bash
zefoy --proxy "http://user:pass@host:8080" send views "https://www.tiktok.com/@u/video/123"
zefoy --proxy "socks5h://user:pass@host:1080" send hearts "https://..."
```

> Proxy đổi IP → tránh / giảm cooldown theo IP của Zefoy. Proxy chết sẽ làm `login`/`send` trả `ok: false`.

### Manual captcha

```python
bot = Zefoy(use_ocr=False)
img = bot.get_captcha_image("captcha.png")  # open image yourself
print(bot.login(captcha_text="flower"))
```

### Custom captcha solver

```python
def my_solver(image):
    # image: PIL.Image
    return "answer"

bot = Zefoy(captcha_solver=my_solver)
bot.login()
```

---

## Changelog

### 0.1.5

- Sửa nhận dạng kiểu CAPTCHA có khoảng cách lớn giữa các ký tự.
- Tự phát hiện số ký tự và nén khoảng cách trước khi OCR.
- Kết hợp nhiều cấu hình xử lý ảnh để tăng độ chính xác.
- Bổ sung `pyspellchecker` để hiệu chỉnh kết quả theo từ tiếng Anh.
- Cải thiện nhận dạng các ký tự dễ nhầm như `a/d/q`, `i/l`, `o/c/q` và
  `v/w`.
- Giữ khả năng kết hợp Tesseract khi máy đã cài Tesseract OCR.
- Ví dụ `basic.py` dừng khi đăng nhập thất bại và không tự gửi request bằng
  URL TikTok mẫu.

### 0.1.4

- Bổ sung xử lý ảnh thích nghi bằng threshold Otsu.
- Tạo nhiều biến thể ảnh và phân tích các kênh màu RGB.
- Thay cách chọn chuỗi dài nhất bằng cơ chế biểu quyết kết quả OCR.
- Chuẩn hóa kết quả trả về từ custom CAPTCHA solver.

---

## API

### `Zefoy(...)`

| Arg | Type | Default | Description |
|-----|------|---------|-------------|
| `use_ocr` | `bool` | `True` | Auto-solve captcha |
| `auto_wait` | `bool` | `True` | Wait on IP cooldown |
| `max_cooldown_retries` | `int` | `5` | Max wait/retry loops |
| `proxy` | `str` \| `dict` | `None` | Proxy URL hoặc dict `requests` (HTTP/HTTPS/SOCKS) |
| `captcha_solver` | `callable` | `None` | `f(PIL.Image) -> str` |
| `user_agent` | `str` | Chrome 131 | Must stay consistent per session |
| `on_event` | `callable` | `None` | Optional debug hook `f(dict)` |

### Methods (all return `dict`)

| Method | Description |
|--------|-------------|
| `login(captcha_text=None, max_tries=5)` | Captcha + session |
| `submit_captcha(text)` | Submit captcha only |
| `services()` / `get_services()` | List available services |
| `send(service, url)` | Search + send order |
| `send_views(url)` | Shortcut |
| `send_hearts(url)` | Shortcut |
| `send_favorites(url)` | Shortcut |
| `send_shares(url)` | Shortcut |
| `send_followers(url)` | Shortcut |
| `Zefoy.to_json(data)` | `json.dumps` helper |

`service` name examples: `"views"`, `"t-views"`, `"hearts"`, `"favorites"`, …

---

## Response shape

Every call looks like:

```json
{
  "ok": true,
  "...": "..."
}
```

### `login()` success

```json
{
  "ok": true,
  "status": "logged_in",
  "captcha": "flower",
  "attempts": []
}
```

### `services()` success

```json
{
  "ok": true,
  "count": 8,
  "services": [
    {
      "name": "t-views",
      "disabled": false,
      "action": "https://zefoy.com/c2VuZC9mb2xeb3dlcnNfdGlrdG9V"
    }
  ]
}
```

### `send_views()` success

```json
{
  "ok": true,
  "status": "sent",
  "service": "t-views",
  "target": "https://www.tiktok.com/@u/video/123",
  "video_id": "123",
  "zefoy_amount": 1000,
  "zefoy_amount_label": "1000 views",
  "wait_seconds": 552,
  "summary": "sent 1000 views | next_wait 552s"
}
```

> **Note:** `zefoy_amount` is decided by Zefoy, not by the caller.

### Error

```json
{
  "ok": false,
  "error": "cooldown",
  "wait_seconds": 91,
  "message": "Please wait 91 seconds before trying again."
}
```

Common `error` codes: `login_failed`, `captcha_rejected`, `cooldown`, `service_not_found`, `no_send_form`, `send_failed`, `max_retries`.

---

## CLI

After install:

```bash
zefoy login
zefoy services
zefoy send views "https://www.tiktok.com/@u/video/123"
```

Or:

```bash
python -m zefoy send views "https://..."
```

---

## License

MIT
