Initial commit

This commit is contained in:
kai
2026-03-25 13:20:39 +08:00
commit c1ecce9719
8 changed files with 992 additions and 0 deletions
+154
View File
@@ -0,0 +1,154 @@
#!/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()