# dsora-gen

Công cụ tự động tạo video Sora theo batch với nhiều Chrome profile, hỗ trợ thông báo Telegram và theo dõi tiến trình.

---

## Yêu cầu

- **Python 3.11+** — kiểm tra bằng `python3 --version`
- **Google Chrome** đã được cài đặt trên máy
- Tài khoản [Sora](https://sora.com) đã đăng ký và được cấp quyền

---

## Cài đặt

### Khuyến khích — dùng `pipx` (macOS)

[pipx](https://pipx.pypa.io) cài CLI tool vào môi trường **riêng biệt**, tránh xung đột với các package Python khác trên hệ thống. Đây là cách được khuyến khích nhất trên macOS.

```bash
# Cài pipx nếu chưa có
brew install pipx
pipx ensurepath

# Cài dsora-gen
pipx install dsora-gen
```

Sau đó dùng lệnh `dsg` bình thường ở bất kỳ đâu trong terminal.

---

### Cài bằng pip (thay thế)

**macOS / Linux:**
```bash
pip3 install dsora-gen
```

**Windows:**
```bash
pip install dsora-gen
```

> Nếu lệnh `dsg` không nhận sau khi cài bằng `pip3`, thêm dòng sau vào `~/.zshrc`:
> ```bash
> export PATH="$HOME/Library/Python/3.x/bin:$PATH"
> ```
> Thay `3.x` bằng phiên bản Python bạn đang dùng (ví dụ `3.11`), sau đó chạy `source ~/.zshrc`.

---

> Lần đầu chạy lệnh `dsg` bất kỳ, tool sẽ **tự động cài Playwright Chromium** — bạn không cần thêm bước nào.

---

## Hướng dẫn sử dụng

| Lệnh | Mô tả |
|------|-------|
| `dsg setup` | Thiết lập profiles, thông tin API, Telegram; mở Chrome để đăng nhập |
| `dsg setup --retry` | Đăng nhập lại profile (khi bị đăng xuất) |
| `dsg check` | Kiểm tra setup hiện tại (config, profiles, sẵn sàng chạy) |
| `dsg run` | Chạy tự động tạo video (đồng bộ API, phân bổ theo profiles) |
| `dsg open <alias>` | Mở Chrome cho một profile |
| `dsg update` | Cập nhật dsora-gen lên phiên bản mới nhất |
| `dsg help` | Xem danh sách lệnh |

---

### Bước 1 — Thiết lập ban đầu

```bash
dsg setup
```

Tool sẽ hỏi lần lượt các thông tin sau:

| Thông tin | Bắt buộc | Mô tả |
|---|:---:|---|
| Số lượng profile | ✅ | Mỗi profile = 1 tài khoản Sora, xử lý tối đa 5 sản phẩm |
| Tên alias cho từng profile | ❌ | Tên gợi nhớ, ví dụ: `tai_khoan_1` |
| Username dsora | ✅ | Dùng để lấy danh sách sản phẩm từ API |
| Backend key | ✅ | Key xác thực để cập nhật trạng thái sản phẩm |
| Telegram Bot Token | ❌ | Nhận thông báo tự động qua Telegram |
| Telegram Channel ID | ❌ | ID kênh hoặc nhóm nhận thông báo |
| Số phút chờ giữa mỗi sản phẩm | ❌ | Mặc định 10 phút; có retry nếu đang có 3 jobs chạy |

Sau khi nhập xong, Chrome sẽ tự mở từng cửa sổ. Bạn cần thao tác thủ công trong mỗi cửa sổ:

1. Đăng nhập tài khoản **Google**
2. Truy cập [sora.com](https://sora.com) và **đăng nhập**
3. Đóng Chrome khi hoàn tất — session đăng nhập sẽ được lưu lại tự động

---

### Bước 2 — Kiểm tra setup (tùy chọn)

Trước khi chạy, có thể kiểm tra cấu hình và trạng thái profiles:

```bash
dsg check
```

Lệnh này hiển thị: file cấu hình, username, Telegram, chế độ chạy, danh sách profile (và thư mục đã tạo hay chưa), và có sẵn sàng chạy `dsg run` hay không.

---

### Bước 3 — Chạy tự động

```bash
dsg run
```

Mỗi lần chạy, tool sẽ:

1. **Đồng bộ với API** — gọi `GET /products/pending` để lấy danh sách sản phẩm chưa xử lý (luôn dùng API làm nguồn đúng, không dùng session cũ)
2. **Phân bổ sản phẩm** — chia đều cho **tất cả** profile (round-robin), mỗi profile tối đa 5 sản phẩm
3. Với mỗi profile (chạy song song tùy cấu hình):
   - Mở Chrome với session đã đăng nhập
   - Lần lượt xử lý từng sản phẩm: điền prompt → upload ảnh → chọn cài đặt → tạo video
   - Sau mỗi sản phẩm: gọi API cập nhật trạng thái, gửi thông báo Telegram, chờ **N phút** (cấu hình lúc setup, mặc định 10 phút)
   - Nếu profile đạt **giới hạn tạo video trong ngày** (tooltip "You're out of video gens"): gửi thông báo, đóng Chrome profile đó, **các profile khác vẫn tiếp tục chạy**
   - Sau khi xử lý xong batch: đóng Chrome, gửi thông báo tổng kết profile
4. Hiển thị tổng kết toàn bộ khi hoàn tất

---

### Đăng nhập lại một profile

Dùng khi một profile bị đăng xuất khỏi Google hoặc Sora:

```bash
dsg setup --retry
```

Tool sẽ hiển thị danh sách profile hiện có, nhập số thứ tự để mở Chrome đăng nhập lại.

---

### Mở Chrome cho một profile cụ thể

```bash
dsg open <alias>

# Ví dụ:
dsg open tai_khoan_1
```

---

### Cập nhật lên phiên bản mới nhất

```bash
dsg update
```

Tool tự động nhận biết bạn cài qua `pipx` hay `pip` và chạy lệnh nâng cấp phù hợp.

---

### Xem danh sách lệnh

```bash
dsg help
dsg --help
```

---

## Dữ liệu lưu trữ

Toàn bộ dữ liệu lưu tại `~/.sora-tool/` — **không** nằm trong thư mục cài đặt Python:

| Đường dẫn | Nội dung |
|---|---|
| `~/.sora-tool/settings.json` | Cấu hình: username, backend key, telegram, danh sách profiles |
| `~/.sora-tool/session.json` | Session hiện tại (batch đang chạy; mỗi lần `dsg run` được tạo lại từ API) |
| `~/.sora-tool/run_log.json` | Lịch sử chạy từng profile theo ngày |
| `~/.sora-tool/profiles/profile_1/` | Chrome session & cookies của profile 1 |
| `~/.sora-tool/profiles/profile_N/` | Chrome session & cookies của profile N |

> ⚠️ **Không xóa thư mục `profiles/`** — đây là nơi lưu session đăng nhập. Nếu xóa, bạn phải đăng nhập lại toàn bộ.

---

## Gỡ lỗi thường gặp

**`dsg: command not found`**
> Thêm pip bin vào PATH. Trên macOS: thêm dòng sau vào `~/.zshrc` rồi chạy `source ~/.zshrc`:
> ```bash
> export PATH="$HOME/Library/Python/3.x/bin:$PATH"
> ```

**Chrome không khởi động được**
> Đảm bảo Google Chrome đã được cài tại đường dẫn mặc định:
> - macOS: `/Applications/Google Chrome.app/Contents/MacOS/Google Chrome`
> - Linux: `/usr/bin/google-chrome`
> - Windows: `C:\Program Files\Google\Chrome\Application\chrome.exe`

**Không tìm thấy nút tạo video / bị timeout**
> Profile có thể đã bị đăng xuất. Chạy `dsg setup --retry` để đăng nhập lại profile đó.

**API trả về lỗi 401**
> Backend key không hợp lệ hoặc đã hết hạn. Chạy `dsg setup` và nhập lại backend key mới.

**Lỗi `Only 3 jobs can run at a time`**
> Tool sẽ tự động chờ 5 phút rồi thử lại — không cần làm gì thêm.

**Thông báo "You're out of video gens" (đạt tối đa video trong ngày)**
> Tool sẽ gửi thông báo (Telegram + console), đóng Chrome profile đó và **tiếp tục chạy các profile khác**. Sản phẩm chưa xử lý của profile bị limit có thể được phân bổ lại ở lần chạy sau (khi gọi API đồng bộ).

---

## Phát hành phiên bản mới (dành cho developer)

```bash
# Bump version trong pyproject.toml và __init__.py, sau đó:
rm -rf dist/
python3 -m build
twine upload dist/*
```
