Metadata-Version: 2.4
Name: shitnovel-cli
Version: 0.1.3
Summary: CLI tool for the ShitNovel API built on snsdk
Author-email: ShitNovel <shitnovel@163.com>
License-Expression: MIT
Keywords: shitnovel,cli,novel,snsdk
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: click>=8.1.0
Requires-Dist: rich>=13.0.0
Requires-Dist: snsdk>=1.1.0

# sncli

[![Python](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)
[![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)

`sncli` 是基于 `snsdk` 开发的 ShitNovel 命令行工具，支持浏览小说、阅读章节、管理评论、作者创作等全部功能。

## 安装

```bash
# 方式一：从 PyPI 安装
pip install sncli

# 方式二：本地开发安装
cd sncli
pip install -e .
```

依赖：
- `click >= 8.1.0` — CLI 框架
- `rich >= 13.0.0` — 终端美化输出
- `snsdk >= 1.0.0` — ShitNovel SDK

## 快速开始

```bash
# 1. 初始化配置
sncli config init

# 2. 浏览小说列表
sncli novels list

# 3. 搜索小说
sncli novels search "斗破苍穹"

# 4. 阅读章节
sncli chapters get 100

# 5. 以 JSON 格式输出
sncli --output json novels get 1
```

## 认证

sncli 使用 **PAT（Personal Access Token）** 进行认证。

### 获取 Token

1. 登录 ShitNovel Web 端
2. 进入「个人设置 → API Tokens」
3. 创建新的 PAT，选择所需 Scopes
4. 复制 Token（仅显示一次）

### 配置 Token

```bash
# 方式一：交互式配置
sncli config init

# 方式二：直接设置
sncli pat use snp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

# 方式三：环境变量
export SNCLI_TOKEN=snp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```

### Scopes 权限

| Scope | 说明 |
|-------|------|
| `novels:read` | 读取小说等公开数据（默认） |
| `user:read` | 读取个人信息、书架、阅读历史 |
| `user:write` | 修改书架、阅读历史、个人资料 |
| `comments:read` | 读取评论 |
| `comments:write` | 发表/删除/点赞评论 |
| `author:read` | 读取创作数据 |
| `author:write` | 创作小说章节 |

## 全局选项

```
sncli [OPTIONS] COMMAND [ARGS]...

Options:
  --base-url TEXT               API base URL (默认从配置读取)
  --token TEXT                  PAT token (覆盖配置)
  --output [table|json|pretty]  输出格式 (覆盖配置)
  --version                     显示版本
  -h, --help                    显示帮助
```

### 输出格式

| 格式 | 说明 |
|------|------|
| `table` | 表格形式，仅显示关键字段（默认） |
| `json` | 原始 JSON 输出，适合脚本处理 |
| `pretty` | 美化的 JSON，适合调试 |

```bash
# 全局设置输出格式
sncli config set --output json

# 单次覆盖
sncli --output pretty novels get 1
sncli novels get 1 --json
```

## 命令一览

### 配置管理

```bash
sncli config show                          # 显示当前配置
sncli config init                          # 交互式初始化
sncli config set --token xxx --output json  # 更新配置
```

### 小说浏览

```bash
sncli novels list [OPTIONS]                # 列出小说
  --channel [MALE|FEMALE]                  # 频道筛选
  --category-id INT                        # 分类 ID
  --status [SERIALIZING|COMPLETED|HIATUS]  # 状态筛选
  --sort TEXT                              # 排序方式
  --page INT                               # 页码（0 开始）
  --size INT                               # 每页数量（默认 20）

sncli novels get <novel_id>                # 获取小说详情
sncli novels search <query>                # 搜索小说
sncli novels rank [hot|favorite|new|complete|word]  # 排行榜
sncli novels categories                    # 获取分类列表
sncli novels tags                          # 获取热门标签
sncli novels author <author_id>            # 获取作者信息
```

### 章节阅读

```bash
sncli chapters list <novel_id>             # 列出章节
  --volume-id INT                          # 分卷筛选
  --page INT                               # 页码
  --size INT                               # 每页数量（默认 50）

sncli chapters get <chapter_id>             # 获取章节内容
sncli chapters read <chapter_id>           # 阅读章节（显示上下章导航）
sncli chapters catalog <novel_id>          # 获取小说目录（分卷结构）
sncli chapters volumes <novel_id>          # 获取分卷列表
```

### 评论管理

```bash
sncli comments list <target_type> <target_id>   # 列出评论
  target_type: novel | chapter
  --root-only / --all                        # 仅显示根评论
  --parent-id INT                            # 父评论 ID（查看回复）
  --sort [new|hot]                           # 排序方式
  --page INT                                 # 页码
  --size INT                                 # 每页数量（默认 10）

sncli comments get <comment_id>             # 获取单条评论
sncli comments create <target_type> <target_id> <content>  # 创建评论
  --parent-id INT                            # 父评论 ID（回复用）

sncli comments like <comment_id>            # 点赞
sncli comments unlike <comment_id>          # 取消点赞
sncli comments delete <comment_id>          # 删除评论
```

### 用户功能

```bash
sncli user me                              # 获取当前用户信息
sncli user stats                           # 获取用户统计
sncli user update                          # 更新个人资料
  --nickname TEXT                          # 昵称
  --avatar TEXT                            # 头像 URL
  --bio TEXT                               # 简介

sncli user bookshelf                       # 书架列表
  --sort TEXT                              # 排序
  --page INT                               # 页码
  --size INT                               # 每页数量

sncli user bookshelf-add <novel_id>        # 添加到书架
sncli user bookshelf-remove <novel_id>     # 从书架移除
sncli user history                         # 阅读历史
sncli user record <novel_id> <chapter_id>  # 记录阅读进度
```

### 作者工具

```bash
sncli author novels                        # 我的小说列表
  --status [DRAFT|SERIALIZING|COMPLETED|HIATUS]
  --page INT
  --size INT

sncli author chapters                       # 我的章节列表
  --novel-id INT                           # 小说筛选
  --status [DRAFT|PUBLISHED|SCHEDULED]
  --page INT
  --size INT

sncli author create-novel                   # 创建小说
  --title TEXT                             # 标题（必填）
  --channel [MALE|FEMALE]                  # 频道（必填）
  --category-id INT                        # 分类 ID（必填）
  --description TEXT                       # 简介
  --cover TEXT                             # 封面 URL

sncli author update-novel <novel_id>        # 更新小说
  --title TEXT
  --channel [MALE|FEMALE]
  --category-id INT
  --description TEXT
  --status [DRAFT|SERIALIZING|COMPLETED|HIATUS]

sncli author create-chapter                # 创建章节
  --novel-id INT                           # 小说 ID（必填）
  --title TEXT                             # 标题（必填）
  --content TEXT                           # 内容（必填）
  --volume-id INT                          # 分卷 ID
  --sort INT                               # 排序
  --status [DRAFT|PUBLISHED]               # 状态

sncli author update-chapter <chapter_id>   # 更新章节
  --title TEXT
  --content TEXT
  --volume-id INT
  --sort INT

sncli author publish-chapter <chapter_id>  # 发布草稿章节
sncli author schedule-chapter <chapter_id> # 定时发布
  --publish-time TEXT                      # 发布时间（ISO 8601）

sncli author delete-novel <novel_id>       # 删除小说
sncli author delete-chapter <chapter_id>   # 删除章节
```

### PAT 管理

```bash
sncli pat list                             # 列出所有 PAT（需 Session）
sncli pat create                           # 创建 PAT（需 Session）
  --name TEXT                              # 名称（必填）
  --scope TEXT                             # Scope（可重复，必填）
  --expires-at TEXT                        # 过期时间（ISO 8601）

sncli pat revoke <pat_id>                  # 撤销指定 PAT（需 Session）
sncli pat revoke-self                      # 撤销当前 Token（PAT 可调用）
sncli pat use <token>                      # 保存 Token 到配置
sncli pat current                          # 查看当前 Token（脱敏）
```

> **注意**：`pat list`、`pat create`、`pat revoke` 仅支持 **Session Cookie** 鉴权，PAT 无法调用。只有 `pat revoke-self` 支持 PAT 鉴权。

## 环境变量

| 变量 | 说明 |
|------|------|
| `SNCLI_BASE_URL` | API 基础 URL，覆盖配置文件 |
| `SNCLI_TOKEN` | PAT Token，覆盖配置文件 |
| `SNCLI_OUTPUT` | 默认输出格式 |
| `SNSDK_BASE_URL` | snsdk 的 API 基础 URL |
| `SNSDK_TOKEN` | snsdk 的 Token |

## 配置文件

配置文件路径：`~/.sncli/config.json`

```json
{
  "base_url": "https://www.shitnovel.org",
  "token": "snp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "output": "table"
}
```

## 错误处理

sncli 会将 API 错误以彩色消息显示：

```
Error [20002]: Token is invalid, expired, or revoked
Error [20005]: Scope insufficient
Error [403]: Permission denied
```

常见错误码：

| 错误码 | 说明 |
|--------|------|
| 10001 | 参数校验失败 |
| 10002 | 资源不存在 |
| 20001 | 未认证 |
| 20002 | Token 无效或过期 |
| 20003 | Token 已撤销 |
| 20005 | Scope 权限不足 |
| 20006 | 仅支持 Session Cookie 鉴权 |

## 代码示例

### 脚本化调用

```bash
# 批量导出小说列表为 JSON
sncli --output json novels list --size 100 > novels.json

# 使用 jq 解析
sncli --output json novels search "玄幻" | jq '.items[] | .title'

# 获取所有作者的小说
for author_id in 1 2 3; do
  sncli --output json novels author $author_id
done
```

### Shell 别名

```bash
# 添加到 ~/.bashrc 或 ~/.zshrc
alias sncli-novels="sncli --output pretty novels"
alias sncli-read="sncli chapters read"
alias sncli-mine="sncli user me --pretty"
```

## 开发

```bash
# 克隆仓库
git clone https://github.com/shitnovel/sncli.git
cd sncli

# 安装开发依赖
pip install -e ".[dev]"

# 运行测试
pytest

# 本地调试
python -m sncli.cli --help
```

## 许可证

MIT License
