155 lines
5.7 KiB
Python
155 lines
5.7 KiB
Python
#!/usr/bin/env python3
|
|
"""bookshelf — 图书阅读管理 CLI。"""
|
|
|
|
import argparse
|
|
import sys
|
|
import db
|
|
import web
|
|
|
|
|
|
STATUS_CHOICES = ["to-read", "reading", "read"]
|
|
FORMAT_CHOICES = ["paper", "ebook"]
|
|
|
|
|
|
def cmd_add(args):
|
|
db.init_db()
|
|
book_id = db.add_book(
|
|
args.title,
|
|
author=args.author,
|
|
translator=args.translator,
|
|
publisher=args.publisher,
|
|
pub_date=args.pub_date,
|
|
cover_url=args.cover_url,
|
|
format=args.format,
|
|
status=args.status,
|
|
rating=args.rating,
|
|
douban_score=args.douban_score,
|
|
goodreads_score=args.goodreads_score,
|
|
tags=args.tags or "",
|
|
notes=args.notes,
|
|
start_date=args.start_date,
|
|
finish_date=args.finish_date,
|
|
)
|
|
print(f"✅ 已添加:《{args.title}》(ID: {book_id})")
|
|
|
|
|
|
def cmd_list(args):
|
|
db.init_db()
|
|
books = db.list_books(status=args.status, format=args.format, tag=args.tag)
|
|
if not books:
|
|
print("📚 暂无书目。")
|
|
return
|
|
for b in books:
|
|
status_icon = {"to-read": "📖", "reading": "📗", "read": "✅"}.get(b["status"], "📕")
|
|
fmt_icon = "📱" if b["format"] == "ebook" else "📕"
|
|
rating_str = f" ⭐{b['rating']}" if b["rating"] else ""
|
|
tags_str = f" [{b['tags']}]" if b["tags"] else ""
|
|
print(f" {status_icon} [{b['id']:>3}] 《{b['title']}》— {b['author'] or '未知'}"
|
|
f" {fmt_icon}{rating_str}{tags_str}")
|
|
|
|
|
|
def cmd_update(args):
|
|
db.init_db()
|
|
book = db.get_book(args.id)
|
|
if not book:
|
|
print(f"❌ 未找到 ID 为 {args.id} 的书目。")
|
|
sys.exit(1)
|
|
updates = {}
|
|
for field in ["title", "author", "translator", "publisher", "pub_date",
|
|
"cover_url", "format", "status", "rating", "douban_score",
|
|
"goodreads_score", "tags", "notes", "start_date", "finish_date"]:
|
|
val = getattr(args, field.replace("-", "_"), None)
|
|
if val is not None:
|
|
updates[field] = val
|
|
if not updates:
|
|
print("⚠️ 未指定任何要更新的字段。")
|
|
return
|
|
db.update_book(args.id, **updates)
|
|
print(f"✅ 已更新:《{book['title']}》(ID: {args.id})")
|
|
|
|
|
|
def cmd_delete(args):
|
|
db.init_db()
|
|
book = db.get_book(args.id)
|
|
if not book:
|
|
print(f"❌ 未找到 ID 为 {args.id} 的书目。")
|
|
sys.exit(1)
|
|
db.delete_book(args.id)
|
|
print(f"🗑️ 已删除:《{book['title']}》(ID: {args.id})")
|
|
|
|
|
|
def cmd_build(args):
|
|
db.init_db()
|
|
output_path = web.build()
|
|
print(f"🌐 网页已生成:{output_path}")
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(
|
|
prog="bookshelf",
|
|
description="📚 个人图书阅读管理工具",
|
|
)
|
|
sub = parser.add_subparsers(dest="command", required=True)
|
|
|
|
# --- add ---
|
|
p_add = sub.add_parser("add", help="添加书目")
|
|
p_add.add_argument("title", help="书名")
|
|
p_add.add_argument("--author", help="作者")
|
|
p_add.add_argument("--translator", help="译者")
|
|
p_add.add_argument("--publisher", help="出版社")
|
|
p_add.add_argument("--pub-date", help="出版日期")
|
|
p_add.add_argument("--cover-url", help="封面图片 URL")
|
|
p_add.add_argument("--format", choices=FORMAT_CHOICES, default="paper", help="格式")
|
|
p_add.add_argument("--status", choices=STATUS_CHOICES, default="to-read", help="阅读状态")
|
|
p_add.add_argument("--rating", type=int, choices=range(1, 6), help="个人评分 1-5")
|
|
p_add.add_argument("--douban-score", type=float, help="豆瓣评分")
|
|
p_add.add_argument("--goodreads-score", type=float, help="Goodreads 评分")
|
|
p_add.add_argument("--tags", help="阅读主题标签,逗号分隔")
|
|
p_add.add_argument("--notes", help="笔记/简评")
|
|
p_add.add_argument("--start-date", help="开始阅读日期")
|
|
p_add.add_argument("--finish-date", help="完成阅读日期")
|
|
p_add.set_defaults(func=cmd_add)
|
|
|
|
# --- list ---
|
|
p_list = sub.add_parser("list", help="列出书目")
|
|
p_list.add_argument("--status", choices=STATUS_CHOICES, help="按状态筛选")
|
|
p_list.add_argument("--format", choices=FORMAT_CHOICES, help="按格式筛选")
|
|
p_list.add_argument("--tag", help="按标签筛选")
|
|
p_list.set_defaults(func=cmd_list)
|
|
|
|
# --- update ---
|
|
p_upd = sub.add_parser("update", help="更新书目")
|
|
p_upd.add_argument("id", type=int, help="书目 ID")
|
|
p_upd.add_argument("--title", help="书名")
|
|
p_upd.add_argument("--author", help="作者")
|
|
p_upd.add_argument("--translator", help="译者")
|
|
p_upd.add_argument("--publisher", help="出版社")
|
|
p_upd.add_argument("--pub-date", help="出版日期")
|
|
p_upd.add_argument("--cover-url", help="封面图片 URL")
|
|
p_upd.add_argument("--format", choices=FORMAT_CHOICES, help="格式")
|
|
p_upd.add_argument("--status", choices=STATUS_CHOICES, help="阅读状态")
|
|
p_upd.add_argument("--rating", type=int, choices=range(1, 6), help="个人评分 1-5")
|
|
p_upd.add_argument("--douban-score", type=float, help="豆瓣评分")
|
|
p_upd.add_argument("--goodreads-score", type=float, help="Goodreads 评分")
|
|
p_upd.add_argument("--tags", help="阅读主题标签,逗号分隔")
|
|
p_upd.add_argument("--notes", help="笔记/简评")
|
|
p_upd.add_argument("--start-date", help="开始阅读日期")
|
|
p_upd.add_argument("--finish-date", help="完成阅读日期")
|
|
p_upd.set_defaults(func=cmd_update)
|
|
|
|
# --- delete ---
|
|
p_del = sub.add_parser("delete", help="删除书目")
|
|
p_del.add_argument("id", type=int, help="书目 ID")
|
|
p_del.set_defaults(func=cmd_delete)
|
|
|
|
# --- build ---
|
|
p_build = sub.add_parser("build", help="生成展示网页")
|
|
p_build.set_defaults(func=cmd_build)
|
|
|
|
args = parser.parse_args()
|
|
args.func(args)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|