# dsora-gen

Công cụ tự động tạo video Sora theo batch với nhiều Chrome profile: chạy **round-robin** (mỗi profile làm 1 sản phẩm rồi đóng, xoay vòng), hỗ trợ Telegram và theo dõi tiến trình. Khi chạy bạn chọn profile bằng checkbox/select. Chrome chạy thu nhỏ và **không kéo focus** khỏi app bạn đang dùng (trên macOS tự đưa focus về Cursor/Terminal).

---

## 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 (số profile chọn từ danh sách) |
| `dsg setup --retry` | Đăng nhập lại profile — chọn profile bằng checkbox |
| `dsg check` | Kiểm tra setup hiện tại (config, profiles, sẵn sàng chạy) |
| `dsg run` | Chạy tự động: chọn profile (checkbox), round-robin 1 SP/profile rồi đóng, xoay vòng đến hết SP hoặc limit |
| `dsg share` | Tạo share link cho các video mới (badge NEW) trong ngày và lưu vào hệ thống |
| `dsg fix-mp4` | Cập nhật mp4 link cho các video đã có share link nhưng chưa có mp4 |
| `dsg open` | Mở Chrome cho một profile (chọn từ danh sách) |
| `dsg update` | Cập nhật dsora-gen lên phiên bản mới nhất |
| `dsg uninstall` | Gỡ cài dsora-gen và xóa toàn bộ dữ liệu trong `~/.sora-tool/` |
| `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 (số lượng profile chọn từ danh sách 1–10, không cần gõ tay):

| Thông tin | Bắt buộc | Mô tả |
|---|:---:|---|
| Số lượng profile | ✅ | Chọn từ danh sách (1–10); mỗi profile = 1 tài khoản Sora |
| 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 | ❌ | (Không dùng khi round-robin; giữ để tương thích cấu hình cũ) |

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 (lần lượt từng profile), 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
```

Khi chạy:

1. Tool hiển thị **danh sách profile** — bạn chọn (checkbox) các profile tham gia session (Space: chọn/bỏ, Enter: xác nhận). Nếu chỉ có 1 profile thì dùng luôn.
2. Tool chạy **round-robin**: mỗi lần chỉ mở **1 profile**. Profile 1: mở Chrome → làm **1 sản phẩm** (submit xong) → đóng Chrome → profile 2: mở → 1 sản phẩm → đóng → … Xoay vòng đến khi hết sản phẩm pending hoặc tất cả profile đạt limit.
3. **Chrome không làm phiền:** Cửa sổ Chrome mở thu nhỏ; trên macOS tool tự đưa focus về app bạn đang dùng (Cursor, Terminal…) nên bạn vẫn code/làm việc bình thường.
4. Profile đạt **giới hạn tạo video trong ngày** ("You're out of video gens"): thông báo, đóng Chrome, profile đó bị loại khỏi vòng tiếp theo.
5. Hiển thị tổng kết khi hoàn tất.

---

### Tạo share link cho video mới

Chạy sau khi `dsg run` đã tạo xong video trong ngày:

```bash
dsg share
```

Khi chạy:

1. Tool hiển thị **danh sách profile** dạng checkbox (mặc định không chọn) — bạn chọn profile cần lấy share link.
2. Với mỗi profile, tool mở Chrome, vào `sora.chatgpt.com/drafts` và chờ video load (5–30 giây).
3. Tự động tìm các video có badge **NEW** (chưa được share) bằng cách đọc raw HTML — bỏ qua video đã có nhãn "Shared".
4. Với từng video: vào trang video → click menu 3 chấm → click **Copy link** → xác nhận modal → đọc link từ clipboard.
5. Gọi API lưu share link vào hệ thống (`POST /sora-videos`).
6. Đóng Chrome, chuyển sang profile tiếp theo.

---

### Cập nhật mp4 link cho video đã share

Dùng khi video đã có share link trong hệ thống nhưng chưa có mp4 link (ví dụ do chạy `dsg share` ở phiên bản cũ):

```bash
dsg fix-mp4
```

Khi chạy:

1. Chọn profile (checkbox, mặc định không chọn).
2. Mở Chrome, vào `sora.chatgpt.com/drafts`, chờ trang load (tối đa 30 giây).
3. Đọc raw HTML, lấy tất cả card đã share (href `/p/s_...`) — không quan tâm badge NEW.
4. Hiển thị tổng số card tìm được và khoảng index.
5. Hỏi: **"Bắt đầu từ index nào?"** và **"Xử lý bao nhiêu card?"**.
6. Với mỗi card trong range: lấy `share_link` từ href + `video_src` từ thẻ `<video src>` (tự unescape HTML entity) → gọi `PATCH /sora-videos/update-mp4-by-share-link`.
7. Log số bản ghi đã cập nhật từ response.

---

### Đă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 dạng **checkbox** — chọn profile cần đăng nhập lại (Space: chọn/bỏ, Enter: xác nhận), rồi mở Chrome cho từng profile đã chọn.

---

### Mở Chrome cho một profile

```bash
dsg open
```

Tool hiển thị **danh sách profile** (dạng select) — chọn một profile để mở Chrome.

---

### 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/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 gửi thông báo (Telegram + console), đóng Chrome; profile đó bị **loại khỏi vòng** (các profile khác tiếp tục round-robin). Sản phẩm chưa xử lý vẫn trên API.

**Chrome cứ kéo focus / che Cursor**
> Trên macOS, tool ghi nhận app đang focus trước khi mở Chrome và sau đó dùng AppleScript đưa focus về lại. Nếu vẫn bị, thử cho phép Terminal/Cursor quyền "Accessibility" trong System Settings.

---

## 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/*
```
