|
1 | 1 | """ |
2 | 2 | command-line usage |
3 | 3 |
|
4 | | -for example, download album 123 456, photo 333: |
| 4 | +1. jmcomic - download album/photo: |
5 | 5 |
|
6 | | -$ jmcomic 123 456 p333 --option="D:/option.yml" |
| 6 | + $ jmcomic 123 456 p333 --option="D:/option.yml" |
7 | 7 |
|
| 8 | +2. jmv - view album detail (extract digits from text as album id): |
| 9 | +
|
| 10 | + $ jmv 350234 |
| 11 | + $ jmv 350谁还没看过234 |
| 12 | + $ jmv abc123141 --option="D:/option.yml" |
8 | 13 |
|
9 | 14 | """ |
10 | 15 | import os.path |
@@ -119,3 +124,133 @@ def run(self, option): |
119 | 124 |
|
120 | 125 | def main(): |
121 | 126 | JmcomicUI().main() |
| 127 | + |
| 128 | + |
| 129 | +class JmViewUI: |
| 130 | + |
| 131 | + def __init__(self) -> None: |
| 132 | + self.raw_text: str = '' |
| 133 | + self.option_path: Optional[str] = None |
| 134 | + self.auto_exit: bool = False |
| 135 | + |
| 136 | + def parse_arg(self): |
| 137 | + import argparse |
| 138 | + parser = argparse.ArgumentParser( |
| 139 | + prog='jmv', |
| 140 | + description='JMComic Album Viewer - 从文本中提取数字作为album ID,查看本子详情', |
| 141 | + ) |
| 142 | + parser.add_argument( |
| 143 | + 'text', |
| 144 | + help='包含数字的禁漫车号,例如 "350谁还没看过234",会提取出 "350234" 作为 album ID', |
| 145 | + ) |
| 146 | + parser.add_argument( |
| 147 | + '--option', |
| 148 | + help='option 文件路径,也可通过环境变量 JM_OPTION_PATH 指定', |
| 149 | + type=str, |
| 150 | + default=get_env('JM_OPTION_PATH', ''), |
| 151 | + ) |
| 152 | + parser.add_argument( |
| 153 | + '-y', '--yes', |
| 154 | + action='store_true', |
| 155 | + help='执行完毕后直接退出,无需按回车确认', |
| 156 | + ) |
| 157 | + |
| 158 | + args = parser.parse_args() |
| 159 | + self.raw_text = args.text |
| 160 | + self.auto_exit = args.yes |
| 161 | + |
| 162 | + option_str = args.option |
| 163 | + if len(option_str) == 0 or option_str == "''": |
| 164 | + self.option_path = None |
| 165 | + else: |
| 166 | + self.option_path = os.path.abspath(option_str) |
| 167 | + |
| 168 | + def extract_album_id(self) -> str: |
| 169 | + import re |
| 170 | + numbers = re.findall(r'\d+', self.raw_text) |
| 171 | + if not numbers: |
| 172 | + from .api import jm_log |
| 173 | + jm_log('jmv', f'❌❌❌ 解析失败: 无法从 "{self.raw_text}" 中提取到任何数字 ❌❌❌') |
| 174 | + exit(1) |
| 175 | + album_id = ''.join(numbers) |
| 176 | + return album_id |
| 177 | + |
| 178 | + @staticmethod |
| 179 | + def _truncate_list(items, limit=10): |
| 180 | + if len(items) <= limit: |
| 181 | + return ', '.join(items) |
| 182 | + return ', '.join(items[:limit]) + f' ...等{len(items)}个' |
| 183 | + |
| 184 | + def print_album_detail(self, album): |
| 185 | + from jmcomic import JmcomicText |
| 186 | + |
| 187 | + sep = '─' * 50 |
| 188 | + |
| 189 | + print(f'\n{sep}') |
| 190 | + print(f' 📖 标题: {album.name}') |
| 191 | + print(f' 🆔 ID: JM{album.album_id}') |
| 192 | + print(f' 🔗 链接: {JmcomicText.format_album_url(album.album_id)}') |
| 193 | + print(f' 🎨 封面: {JmcomicText.get_album_cover_url(album.album_id)}') |
| 194 | + print(f' ✍️ 作者: {self._truncate_list(album.authors) if album.authors else "未知"}') |
| 195 | + print(sep) |
| 196 | + |
| 197 | + print(f' 📅 发布日期: {album.pub_date}') |
| 198 | + print(f' 📅 更新日期: {album.update_date}') |
| 199 | + print(f' 📄 总页数: {album.page_count}') |
| 200 | + print(f' 👀 观看: {album.views}') |
| 201 | + print(f' ❤️ 点赞: {album.likes}') |
| 202 | + print(f' 💬 评论: {album.comment_count}') |
| 203 | + print(sep) |
| 204 | + |
| 205 | + if album.tags: |
| 206 | + print(f' 🏷️ 标签: {self._truncate_list(album.tags)}') |
| 207 | + if album.actors: |
| 208 | + print(f' 🎭 人物: {self._truncate_list(album.actors)}') |
| 209 | + if album.works: |
| 210 | + print(f' 📚 作品: {self._truncate_list(album.works)}') |
| 211 | + |
| 212 | + if album.description: |
| 213 | + print(f' 📝 简介: {album.description}') |
| 214 | + |
| 215 | + print(sep) |
| 216 | + episode_count = len(album.episode_list) |
| 217 | + print(f' 📑 章节 ({episode_count}):') |
| 218 | + for pid, pindex, pname in album.episode_list: |
| 219 | + pname = pname.strip() |
| 220 | + print(f' 第{pindex}話 {pname} (id: {pid})') |
| 221 | + |
| 222 | + print(f'{sep}\n') |
| 223 | + |
| 224 | + def _pause(self): |
| 225 | + if not self.auto_exit: |
| 226 | + input('\n[运行结束] 请按回车键关闭窗口... (下次运行可附加 -y 参数跳过确认)') |
| 227 | + |
| 228 | + def main(self): |
| 229 | + self.parse_arg() |
| 230 | + |
| 231 | + import atexit |
| 232 | + atexit.register(self._pause) |
| 233 | + |
| 234 | + album_id = self.extract_album_id() |
| 235 | + |
| 236 | + from .api import jm_log |
| 237 | + jm_log('jmv', f'🔍 正在查询 禁漫车号 - [{album_id}] 的详情...') |
| 238 | + |
| 239 | + from .api import create_option, JmOption |
| 240 | + if self.option_path is not None: |
| 241 | + option = create_option(self.option_path) |
| 242 | + else: |
| 243 | + option = JmOption.default() |
| 244 | + |
| 245 | + client = option.new_jm_client() |
| 246 | + try: |
| 247 | + album = client.get_album_detail(album_id) |
| 248 | + except Exception as e: |
| 249 | + jm_log('jmv', f'❌❌❌ 获取失败: album {album_id} 详情请求出错, 原因: {e}', e) |
| 250 | + exit(1) |
| 251 | + |
| 252 | + self.print_album_detail(album) |
| 253 | + |
| 254 | + |
| 255 | +def view_main(): |
| 256 | + JmViewUI().main() |
0 commit comments