artdam-cli 0.2.4__tar.gz → 0.2.6__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.
Files changed (37) hide show
  1. artdam_cli-0.2.6/PKG-INFO +235 -0
  2. artdam_cli-0.2.6/README.md +225 -0
  3. artdam_cli-0.2.6/artdam_cli/__init__.py +6 -0
  4. {artdam_cli-0.2.4 → artdam_cli-0.2.6}/artdam_cli/commands/login.py +1 -1
  5. {artdam_cli-0.2.4 → artdam_cli-0.2.6}/artdam_cli/main.py +69 -52
  6. artdam_cli-0.2.6/artdam_cli/update_check.py +71 -0
  7. artdam_cli-0.2.6/artdam_cli.egg-info/PKG-INFO +235 -0
  8. {artdam_cli-0.2.4 → artdam_cli-0.2.6}/artdam_cli.egg-info/SOURCES.txt +1 -0
  9. {artdam_cli-0.2.4 → artdam_cli-0.2.6}/pyproject.toml +1 -1
  10. artdam_cli-0.2.4/PKG-INFO +0 -292
  11. artdam_cli-0.2.4/README.md +0 -282
  12. artdam_cli-0.2.4/artdam_cli/__init__.py +0 -1
  13. artdam_cli-0.2.4/artdam_cli.egg-info/PKG-INFO +0 -292
  14. {artdam_cli-0.2.4 → artdam_cli-0.2.6}/artdam_cli/client.py +0 -0
  15. {artdam_cli-0.2.4 → artdam_cli-0.2.6}/artdam_cli/commands/__init__.py +0 -0
  16. {artdam_cli-0.2.4 → artdam_cli-0.2.6}/artdam_cli/commands/comment.py +0 -0
  17. {artdam_cli-0.2.4 → artdam_cli-0.2.6}/artdam_cli/commands/delete_cmd.py +0 -0
  18. {artdam_cli-0.2.4 → artdam_cli-0.2.6}/artdam_cli/commands/download.py +0 -0
  19. {artdam_cli-0.2.4 → artdam_cli-0.2.6}/artdam_cli/commands/favorite.py +0 -0
  20. {artdam_cli-0.2.4 → artdam_cli-0.2.6}/artdam_cli/commands/folder_cmd.py +0 -0
  21. {artdam_cli-0.2.4 → artdam_cli-0.2.6}/artdam_cli/commands/folders.py +0 -0
  22. {artdam_cli-0.2.4 → artdam_cli-0.2.6}/artdam_cli/commands/get.py +0 -0
  23. {artdam_cli-0.2.4 → artdam_cli-0.2.6}/artdam_cli/commands/project.py +0 -0
  24. {artdam_cli-0.2.4 → artdam_cli-0.2.6}/artdam_cli/commands/projects.py +0 -0
  25. {artdam_cli-0.2.4 → artdam_cli-0.2.6}/artdam_cli/commands/rate.py +0 -0
  26. {artdam_cli-0.2.4 → artdam_cli-0.2.6}/artdam_cli/commands/restore.py +0 -0
  27. {artdam_cli-0.2.4 → artdam_cli-0.2.6}/artdam_cli/commands/search.py +0 -0
  28. {artdam_cli-0.2.4 → artdam_cli-0.2.6}/artdam_cli/commands/tag_cmd.py +0 -0
  29. {artdam_cli-0.2.4 → artdam_cli-0.2.6}/artdam_cli/commands/tags.py +0 -0
  30. {artdam_cli-0.2.4 → artdam_cli-0.2.6}/artdam_cli/commands/update.py +0 -0
  31. {artdam_cli-0.2.4 → artdam_cli-0.2.6}/artdam_cli/commands/upload.py +0 -0
  32. {artdam_cli-0.2.4 → artdam_cli-0.2.6}/artdam_cli/config.py +0 -0
  33. {artdam_cli-0.2.4 → artdam_cli-0.2.6}/artdam_cli.egg-info/dependency_links.txt +0 -0
  34. {artdam_cli-0.2.4 → artdam_cli-0.2.6}/artdam_cli.egg-info/entry_points.txt +0 -0
  35. {artdam_cli-0.2.4 → artdam_cli-0.2.6}/artdam_cli.egg-info/requires.txt +0 -0
  36. {artdam_cli-0.2.4 → artdam_cli-0.2.6}/artdam_cli.egg-info/top_level.txt +0 -0
  37. {artdam_cli-0.2.4 → artdam_cli-0.2.6}/setup.cfg +0 -0
@@ -0,0 +1,235 @@
1
+ Metadata-Version: 2.4
2
+ Name: artdam-cli
3
+ Version: 0.2.6
4
+ Summary: ArtDAM 数字资产管理平台命令行工具
5
+ Requires-Python: >=3.10
6
+ Description-Content-Type: text/markdown
7
+ Requires-Dist: click>=8.1
8
+ Requires-Dist: httpx>=0.27
9
+ Requires-Dist: rich>=13.0
10
+
11
+ # artdam-cli
12
+
13
+ ArtDAM 数字资产管理平台命令行工具,支持所有主流 AI Agent工具接入
14
+
15
+ ## 安装
16
+
17
+ ```bash
18
+ # 推荐(无需 Python 环境)
19
+ uv tool install artdam-cli
20
+
21
+ # 或使用 pip
22
+ pip install artdam-cli
23
+ ```
24
+
25
+ ## 快速开始
26
+
27
+ ```bash
28
+ # 登录(首次使用,服务器地址已内置)
29
+ artdam login --username <用户名> --password <密码>
30
+
31
+ # 搜索资产
32
+ artdam search "关键词" --project 1
33
+
34
+ # 查看资产详情
35
+ artdam get 123
36
+
37
+ # 下载资产
38
+ artdam download 123 --out ./downloads
39
+ ```
40
+
41
+ ## 命令说明
42
+
43
+ ### 查询命令(viewer 及以上)
44
+
45
+ #### `artdam login`
46
+
47
+ 登录 ArtDAM,保存 token 到本地 `~/.artdam/config.json`。
48
+
49
+ ```bash
50
+ artdam login --username <用户名> --password <密码>
51
+ ```
52
+
53
+ #### `artdam search`
54
+
55
+ 搜索资产,返回匹配列表。
56
+
57
+ ```bash
58
+ artdam search "头盔" --project 1
59
+ artdam search "头盔" --project 1 --limit 50
60
+ artdam search "头盔" --project 1 --type image/png
61
+ artdam search "头盔" --project 1 --folder 10
62
+ artdam search "头盔" --project 1 --json # 输出原始 JSON(AI Agent 用)
63
+ ```
64
+
65
+ | 参数 | 说明 |
66
+ |---|---|
67
+ | `KEYWORD` | 搜索关键词 |
68
+ | `-p, --project` | 项目 ID(必填) |
69
+ | `-n, --limit` | 返回数量上限(默认 20) |
70
+ | `--type` | 文件类型,如 `image/png` |
71
+ | `--folder` | 限定文件夹 ID |
72
+ | `--json` | 输出原始 JSON |
73
+
74
+ #### `artdam get`
75
+
76
+ 查看单个资产详情(含预览链接)。
77
+
78
+ ```bash
79
+ artdam get 123
80
+ artdam get 123 --json # 输出原始 JSON(AI Agent 用)
81
+ ```
82
+
83
+ #### `artdam download`
84
+
85
+ 下载资产文件到本地。
86
+
87
+ ```bash
88
+ artdam download 123
89
+ artdam download 123 --out ./downloads
90
+ ```
91
+
92
+ #### `artdam tags`
93
+
94
+ 列出项目标签。
95
+
96
+ ```bash
97
+ artdam tags --project 1
98
+ artdam tags --project 1 --search "角色"
99
+ artdam tags --project 1 --json
100
+ ```
101
+
102
+ #### `artdam folders`
103
+
104
+ 查看文件夹结构。
105
+
106
+ ```bash
107
+ artdam folders --project 1
108
+ artdam folders --project 1 --json
109
+ ```
110
+
111
+ ### 资产管理(member 及以上)
112
+
113
+ #### `artdam upload`
114
+
115
+ 上传文件到指定项目和文件夹。
116
+
117
+ ```bash
118
+ artdam upload ./image.jpg --project 1
119
+ artdam upload ./image.jpg --project 1 --folder 10
120
+ ```
121
+
122
+ #### `artdam update`
123
+
124
+ 更新资产信息(可同时传多个选项)。
125
+
126
+ ```bash
127
+ artdam update 123 --name "新文件名"
128
+ artdam update 123 --description "新描述"
129
+ artdam update 123 --folder 10
130
+ ```
131
+
132
+ #### `artdam delete`
133
+
134
+ 软删除资产(可通过 `restore` 恢复)。
135
+
136
+ ```bash
137
+ artdam delete 123
138
+ ```
139
+
140
+ #### `artdam restore`
141
+
142
+ 恢复已删除的资产。
143
+
144
+ ```bash
145
+ artdam restore 123
146
+ ```
147
+
148
+ ### 标签管理(member 及以上)
149
+
150
+ ```bash
151
+ # 给资产添加标签
152
+ artdam tag add 123 5
153
+
154
+ # 从资产移除标签
155
+ artdam tag remove 123 5
156
+
157
+ # 创建新标签
158
+ artdam tag create "标签名" --project 1
159
+ ```
160
+
161
+ ### 文件夹管理(member 及以上)
162
+
163
+ ```bash
164
+ # 创建文件夹
165
+ artdam folder create "文件夹名" --project 1
166
+ artdam folder create "子文件夹" --project 1 --parent 10
167
+
168
+ # 删除文件夹
169
+ artdam folder delete 10
170
+ ```
171
+
172
+ ### 互动操作(member 及以上)
173
+
174
+ ```bash
175
+ # 评论
176
+ artdam comment 123 "评论内容"
177
+
178
+ # 评分(1-5 星)
179
+ artdam rate 123 4
180
+
181
+ # 收藏 / 取消收藏
182
+ artdam favorite 123
183
+ artdam favorite 123 --remove
184
+ ```
185
+
186
+ ## AI Agent 使用指南
187
+
188
+ 所有查询命令支持 `--json` 输出原始 JSON,适合 Agent 解析:
189
+
190
+ ```bash
191
+ artdam search "安妮" --project 1 --json
192
+ artdam get 123 --json
193
+ artdam tags --project 1 --json
194
+ artdam folders --project 1 --json
195
+ ```
196
+
197
+ ### 典型 Agent 工作流
198
+
199
+ ```bash
200
+ # 1. 登录(向用户获取用户名密码后执行)
201
+ artdam login --username <用户名> --password <密码>
202
+
203
+ # 2. 搜索 → 确认 → 下载
204
+ artdam search "头盔" --project 1 --json
205
+ artdam get 50707 --json
206
+ artdam download 50707 --out ./assets
207
+
208
+ # 3. 搜索 → 批量打标签
209
+ artdam search "安妮" --project 1 --json
210
+ artdam tag add 50707 5
211
+ artdam tag add 50708 5
212
+
213
+ # 4. 上传并更新描述
214
+ artdam upload ./new_asset.jpg --project 1 --folder 10
215
+ artdam update <asset_id> --description "AI 生成的场景描述"
216
+ ```
217
+
218
+ ## 注意事项
219
+
220
+ - `--project` 参数为**数字 ID**,不是项目名称
221
+ - `--json` 返回原始 JSON,适合程序解析
222
+ - token 保存在 `~/.artdam/config.json`,登录一次长期有效
223
+ - `artdam delete` 是软删除,可用 `artdam restore` 恢复
224
+ - Windows CMD 下中文乱码时,在命令前加 `PYTHONUTF8=1`
225
+
226
+ ## 配置文件
227
+
228
+ 登录信息保存在 `~/.artdam/config.json`:
229
+
230
+ ```json
231
+ {
232
+ "base_url": "https://artdam.xindong.com",
233
+ "token": "eyJ..."
234
+ }
235
+ ```
@@ -0,0 +1,225 @@
1
+ # artdam-cli
2
+
3
+ ArtDAM 数字资产管理平台命令行工具,支持所有主流 AI Agent工具接入
4
+
5
+ ## 安装
6
+
7
+ ```bash
8
+ # 推荐(无需 Python 环境)
9
+ uv tool install artdam-cli
10
+
11
+ # 或使用 pip
12
+ pip install artdam-cli
13
+ ```
14
+
15
+ ## 快速开始
16
+
17
+ ```bash
18
+ # 登录(首次使用,服务器地址已内置)
19
+ artdam login --username <用户名> --password <密码>
20
+
21
+ # 搜索资产
22
+ artdam search "关键词" --project 1
23
+
24
+ # 查看资产详情
25
+ artdam get 123
26
+
27
+ # 下载资产
28
+ artdam download 123 --out ./downloads
29
+ ```
30
+
31
+ ## 命令说明
32
+
33
+ ### 查询命令(viewer 及以上)
34
+
35
+ #### `artdam login`
36
+
37
+ 登录 ArtDAM,保存 token 到本地 `~/.artdam/config.json`。
38
+
39
+ ```bash
40
+ artdam login --username <用户名> --password <密码>
41
+ ```
42
+
43
+ #### `artdam search`
44
+
45
+ 搜索资产,返回匹配列表。
46
+
47
+ ```bash
48
+ artdam search "头盔" --project 1
49
+ artdam search "头盔" --project 1 --limit 50
50
+ artdam search "头盔" --project 1 --type image/png
51
+ artdam search "头盔" --project 1 --folder 10
52
+ artdam search "头盔" --project 1 --json # 输出原始 JSON(AI Agent 用)
53
+ ```
54
+
55
+ | 参数 | 说明 |
56
+ |---|---|
57
+ | `KEYWORD` | 搜索关键词 |
58
+ | `-p, --project` | 项目 ID(必填) |
59
+ | `-n, --limit` | 返回数量上限(默认 20) |
60
+ | `--type` | 文件类型,如 `image/png` |
61
+ | `--folder` | 限定文件夹 ID |
62
+ | `--json` | 输出原始 JSON |
63
+
64
+ #### `artdam get`
65
+
66
+ 查看单个资产详情(含预览链接)。
67
+
68
+ ```bash
69
+ artdam get 123
70
+ artdam get 123 --json # 输出原始 JSON(AI Agent 用)
71
+ ```
72
+
73
+ #### `artdam download`
74
+
75
+ 下载资产文件到本地。
76
+
77
+ ```bash
78
+ artdam download 123
79
+ artdam download 123 --out ./downloads
80
+ ```
81
+
82
+ #### `artdam tags`
83
+
84
+ 列出项目标签。
85
+
86
+ ```bash
87
+ artdam tags --project 1
88
+ artdam tags --project 1 --search "角色"
89
+ artdam tags --project 1 --json
90
+ ```
91
+
92
+ #### `artdam folders`
93
+
94
+ 查看文件夹结构。
95
+
96
+ ```bash
97
+ artdam folders --project 1
98
+ artdam folders --project 1 --json
99
+ ```
100
+
101
+ ### 资产管理(member 及以上)
102
+
103
+ #### `artdam upload`
104
+
105
+ 上传文件到指定项目和文件夹。
106
+
107
+ ```bash
108
+ artdam upload ./image.jpg --project 1
109
+ artdam upload ./image.jpg --project 1 --folder 10
110
+ ```
111
+
112
+ #### `artdam update`
113
+
114
+ 更新资产信息(可同时传多个选项)。
115
+
116
+ ```bash
117
+ artdam update 123 --name "新文件名"
118
+ artdam update 123 --description "新描述"
119
+ artdam update 123 --folder 10
120
+ ```
121
+
122
+ #### `artdam delete`
123
+
124
+ 软删除资产(可通过 `restore` 恢复)。
125
+
126
+ ```bash
127
+ artdam delete 123
128
+ ```
129
+
130
+ #### `artdam restore`
131
+
132
+ 恢复已删除的资产。
133
+
134
+ ```bash
135
+ artdam restore 123
136
+ ```
137
+
138
+ ### 标签管理(member 及以上)
139
+
140
+ ```bash
141
+ # 给资产添加标签
142
+ artdam tag add 123 5
143
+
144
+ # 从资产移除标签
145
+ artdam tag remove 123 5
146
+
147
+ # 创建新标签
148
+ artdam tag create "标签名" --project 1
149
+ ```
150
+
151
+ ### 文件夹管理(member 及以上)
152
+
153
+ ```bash
154
+ # 创建文件夹
155
+ artdam folder create "文件夹名" --project 1
156
+ artdam folder create "子文件夹" --project 1 --parent 10
157
+
158
+ # 删除文件夹
159
+ artdam folder delete 10
160
+ ```
161
+
162
+ ### 互动操作(member 及以上)
163
+
164
+ ```bash
165
+ # 评论
166
+ artdam comment 123 "评论内容"
167
+
168
+ # 评分(1-5 星)
169
+ artdam rate 123 4
170
+
171
+ # 收藏 / 取消收藏
172
+ artdam favorite 123
173
+ artdam favorite 123 --remove
174
+ ```
175
+
176
+ ## AI Agent 使用指南
177
+
178
+ 所有查询命令支持 `--json` 输出原始 JSON,适合 Agent 解析:
179
+
180
+ ```bash
181
+ artdam search "安妮" --project 1 --json
182
+ artdam get 123 --json
183
+ artdam tags --project 1 --json
184
+ artdam folders --project 1 --json
185
+ ```
186
+
187
+ ### 典型 Agent 工作流
188
+
189
+ ```bash
190
+ # 1. 登录(向用户获取用户名密码后执行)
191
+ artdam login --username <用户名> --password <密码>
192
+
193
+ # 2. 搜索 → 确认 → 下载
194
+ artdam search "头盔" --project 1 --json
195
+ artdam get 50707 --json
196
+ artdam download 50707 --out ./assets
197
+
198
+ # 3. 搜索 → 批量打标签
199
+ artdam search "安妮" --project 1 --json
200
+ artdam tag add 50707 5
201
+ artdam tag add 50708 5
202
+
203
+ # 4. 上传并更新描述
204
+ artdam upload ./new_asset.jpg --project 1 --folder 10
205
+ artdam update <asset_id> --description "AI 生成的场景描述"
206
+ ```
207
+
208
+ ## 注意事项
209
+
210
+ - `--project` 参数为**数字 ID**,不是项目名称
211
+ - `--json` 返回原始 JSON,适合程序解析
212
+ - token 保存在 `~/.artdam/config.json`,登录一次长期有效
213
+ - `artdam delete` 是软删除,可用 `artdam restore` 恢复
214
+ - Windows CMD 下中文乱码时,在命令前加 `PYTHONUTF8=1`
215
+
216
+ ## 配置文件
217
+
218
+ 登录信息保存在 `~/.artdam/config.json`:
219
+
220
+ ```json
221
+ {
222
+ "base_url": "https://artdam.xindong.com",
223
+ "token": "eyJ..."
224
+ }
225
+ ```
@@ -0,0 +1,6 @@
1
+ from importlib.metadata import version, PackageNotFoundError
2
+
3
+ try:
4
+ __version__ = version("artdam-cli")
5
+ except PackageNotFoundError:
6
+ __version__ = "0.0.0"
@@ -104,7 +104,7 @@ def _password_login(url: str, username: str | None, passwd: str | None) -> None:
104
104
  def login(
105
105
  url: str, use_password: bool, username: str | None, passwd: str | None
106
106
  ) -> None:
107
- """登录 ArtDAM。默认走 SSO 浏览器授权,加 --password 使用账号密码(仅管理员)。"""
107
+ """登录 ArtDAM。默认走 SSO 浏览器授权,加 --password 使用账号密码。"""
108
108
  url = url.rstrip("/")
109
109
  if use_password:
110
110
  _password_login(url, username, passwd)
@@ -1,52 +1,69 @@
1
- import io
2
- import sys
3
-
4
- import click
5
-
6
- # Windows 终端默认 GBK,强制 UTF-8 避免中文乱码
7
- if hasattr(sys.stdout, "buffer") and sys.stdout.encoding.lower() not in ("utf-8", "utf-8-sig"):
8
- sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")
9
- sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding="utf-8", errors="replace")
10
-
11
- from artdam_cli.commands.login import login
12
- from artdam_cli.commands.search import search
13
- from artdam_cli.commands.get import get
14
- from artdam_cli.commands.tags import tags
15
- from artdam_cli.commands.folders import folders
16
- from artdam_cli.commands.download import download
17
- from artdam_cli.commands.update import update
18
- from artdam_cli.commands.delete_cmd import delete_cmd
19
- from artdam_cli.commands.restore import restore
20
- from artdam_cli.commands.upload import upload
21
- from artdam_cli.commands.tag_cmd import tag_group
22
- from artdam_cli.commands.folder_cmd import folder_group
23
- from artdam_cli.commands.comment import comment
24
- from artdam_cli.commands.rate import rate
25
- from artdam_cli.commands.favorite import favorite
26
- from artdam_cli.commands.project import project_group
27
- from artdam_cli.commands.projects import projects
28
-
29
-
30
- @click.group()
31
- @click.version_option(package_name="artdam-cli")
32
- def cli() -> None:
33
- """ArtDAM 命令行工具 搜索、查看、下载、管理数字资产。"""
34
-
35
-
36
- cli.add_command(login)
37
- cli.add_command(search)
38
- cli.add_command(get)
39
- cli.add_command(tags)
40
- cli.add_command(folders)
41
- cli.add_command(download)
42
- cli.add_command(update)
43
- cli.add_command(delete_cmd)
44
- cli.add_command(restore)
45
- cli.add_command(upload)
46
- cli.add_command(tag_group)
47
- cli.add_command(folder_group)
48
- cli.add_command(comment)
49
- cli.add_command(rate)
50
- cli.add_command(favorite)
51
- cli.add_command(project_group)
52
- cli.add_command(projects)
1
+ import io
2
+ import sys
3
+
4
+ import click
5
+
6
+ # Windows 终端默认 GBK,强制 UTF-8 避免中文乱码
7
+ if hasattr(sys.stdout, "buffer") and sys.stdout.encoding.lower() not in ("utf-8", "utf-8-sig"):
8
+ sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")
9
+ sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding="utf-8", errors="replace")
10
+
11
+ from artdam_cli.update_check import check_update
12
+ from artdam_cli.commands.login import login
13
+ from artdam_cli.commands.search import search
14
+ from artdam_cli.commands.get import get
15
+ from artdam_cli.commands.tags import tags
16
+ from artdam_cli.commands.folders import folders
17
+ from artdam_cli.commands.download import download
18
+ from artdam_cli.commands.update import update
19
+ from artdam_cli.commands.delete_cmd import delete_cmd
20
+ from artdam_cli.commands.restore import restore
21
+ from artdam_cli.commands.upload import upload
22
+ from artdam_cli.commands.tag_cmd import tag_group
23
+ from artdam_cli.commands.folder_cmd import folder_group
24
+ from artdam_cli.commands.comment import comment
25
+ from artdam_cli.commands.rate import rate
26
+ from artdam_cli.commands.favorite import favorite
27
+ from artdam_cli.commands.project import project_group
28
+ from artdam_cli.commands.projects import projects
29
+
30
+
31
+ @click.group()
32
+ @click.version_option(package_name="artdam-cli")
33
+ def cli() -> None:
34
+ """ArtDAM 命令行工具 — 搜索、查看、下载、管理数字资产。"""
35
+
36
+
37
+ @cli.result_callback()
38
+ def _after_command(*args: object, **kwargs: object) -> None:
39
+ result = check_update()
40
+ if result:
41
+ current, latest = result
42
+ click.echo(
43
+ f"\n[notice] A new release of artdam-cli is available: "
44
+ f"{click.style(current, fg='yellow')} -> {click.style(latest, fg='green')}",
45
+ err=True,
46
+ )
47
+ click.echo(
48
+ f"[notice] To update, run: {click.style('uv tool upgrade artdam-cli', fg='cyan')}",
49
+ err=True,
50
+ )
51
+
52
+
53
+ cli.add_command(login)
54
+ cli.add_command(search)
55
+ cli.add_command(get)
56
+ cli.add_command(tags)
57
+ cli.add_command(folders)
58
+ cli.add_command(download)
59
+ cli.add_command(update)
60
+ cli.add_command(delete_cmd)
61
+ cli.add_command(restore)
62
+ cli.add_command(upload)
63
+ cli.add_command(tag_group)
64
+ cli.add_command(folder_group)
65
+ cli.add_command(comment)
66
+ cli.add_command(rate)
67
+ cli.add_command(favorite)
68
+ cli.add_command(project_group)
69
+ cli.add_command(projects)
@@ -0,0 +1,71 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ import time
5
+ from importlib.metadata import PackageNotFoundError, version
6
+ from pathlib import Path
7
+
8
+ import httpx
9
+
10
+ _CACHE_PATH = Path.home() / ".artdam" / "version_check.json"
11
+ _CACHE_TTL = 86400 # 24 hours
12
+ _PYPI_URL = "https://pypi.org/pypi/artdam-cli/json"
13
+ _PACKAGE_NAME = "artdam-cli"
14
+
15
+
16
+ def get_current_version() -> str:
17
+ try:
18
+ return version(_PACKAGE_NAME)
19
+ except PackageNotFoundError:
20
+ return "0.0.0"
21
+
22
+
23
+ def _load_cache() -> dict:
24
+ try:
25
+ if _CACHE_PATH.exists():
26
+ return json.loads(_CACHE_PATH.read_text(encoding="utf-8"))
27
+ except Exception:
28
+ pass
29
+ return {}
30
+
31
+
32
+ def _save_cache(latest: str) -> None:
33
+ try:
34
+ _CACHE_PATH.parent.mkdir(parents=True, exist_ok=True)
35
+ _CACHE_PATH.write_text(
36
+ json.dumps({"latest": latest, "checked_at": time.time()}),
37
+ encoding="utf-8",
38
+ )
39
+ except Exception:
40
+ pass
41
+
42
+
43
+ def check_update() -> tuple[str, str] | None:
44
+ """Return (current, latest) if a newer version is available, else None.
45
+
46
+ Never raises — network/parse errors are silently swallowed.
47
+ """
48
+ current = get_current_version()
49
+
50
+ cache = _load_cache()
51
+ if time.time() - cache.get("checked_at", 0) < _CACHE_TTL:
52
+ latest = cache.get("latest", current)
53
+ else:
54
+ try:
55
+ resp = httpx.get(_PYPI_URL, timeout=3)
56
+ resp.raise_for_status()
57
+ latest = resp.json()["info"]["version"]
58
+ _save_cache(latest)
59
+ except Exception:
60
+ return None
61
+
62
+ try:
63
+ if _parse_version(latest) > _parse_version(current):
64
+ return current, latest
65
+ except Exception:
66
+ pass
67
+ return None
68
+
69
+
70
+ def _parse_version(v: str) -> tuple[int, ...]:
71
+ return tuple(int(x) for x in v.split(".") if x.isdigit())