""" booklist_parse.py ----------------- 功能: - 解析iBooks的Books.plist,提取所有书籍元数据(书名、作者、路径、时间等)。 - 解析BKLibrary.sqlite,获取每本书的最近打开时间(苹果时间戳,基准2001-01-01)。 主要接口: - parse_books_plist(plist_path):返回所有书籍元数据,结构为{bk_id: {...}} - get_books_last_open(db_path):返回所有书籍最近打开时间,结构为{bk_id: {'last_open': 时间戳}} 依赖:plistlib, collections, sqlite3, os, datetime 典型用法: booksinfo = parse_books_plist('./data/Books.plist') books_open = get_books_last_open('data/BKLibrary.sqlite') """ import plistlib from collections import defaultdict def parse_books_plist(plist_path): booksinfo = defaultdict(dict) with open(plist_path, 'rb') as f: plist_data = plistlib.load(f) for book in plist_data.get('Books', []): bk_id = book.get('BKGeneratedItemId') if not bk_id: continue booksinfo[bk_id] = { 'displayname': book.get('BKDisplayName', ''), 'author': book.get('artistName', ''), 'type': book.get('BKBookType', ''), 'bookid': bk_id, 'itemname': book.get('itemName', ''), 'path': book.get('path', ''), 'date': book.get('BKInsertionDate',''), 'updatedate': book.get('updateDate','') } return booksinfo import sqlite3 import os def get_books_last_open(db_path='data/BKLibrary.sqlite'): """ 从BKLibrary.sqlite获取书籍最近打开时间 返回:defaultdict(dict),bk_id为索引,包含最近打开时间 """ books_open = defaultdict(dict) if not os.path.exists(db_path): return books_open try: conn = sqlite3.connect(db_path) cursor = conn.cursor() # ZBKLIBRARYASSET表包含书籍信息 cursor.execute(''' SELECT ZASSETID, zlastopendate FROM ZBKLIBRARYASSET WHERE zlastopendate IS NOT NULL ''') rows = cursor.fetchall() for row in rows: asset_id, last_open = row if asset_id: books_open[asset_id] = { 'last_open': last_open # 苹果时间戳,基准时间为2001-01-01 } conn.close() except Exception as e: print(f'警告: 读取BKLibrary.sqlite失败: {e}') return books_open if __name__ == '__main__': booksinfo = parse_books_plist('./data/Books.plist') from pprint import pprint print("\n【前三条示例】") for k, v in list(booksinfo.items())[:3]: print(f"{k}:") pprint(v, sort_dicts=False, indent=2) print('-' * 60) ''' print("\n【全部内容】") for k, v in booksinfo.items(): print(f"{k}:") pprint(v, sort_dicts=False, indent=2) print('-' * 60) ''' # 测试最近打开时间 print("\n【最近打开时间示例】") books_open = get_books_last_open() import datetime for k, v in list(books_open.items())[:3]: ts = v['last_open'] # 苹果时间戳,基准2001-01-01 dt = datetime.datetime(2001, 1, 1) + datetime.timedelta(seconds=ts) print(f"{k}: {dt} (timestamp: {ts})")