iBook/booklist_parse.py

95 lines
3.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
booklist_parse.py
-----------------
功能:
- 解析iBooks的Books.plist提取所有书籍元数据书名、作者、路径、时间等
- 解析BKLibrary.sqlite获取每本书的最近打开时间苹果时间戳基准2001-01-01
依赖config.py 统一管理路径和配置项。
主要接口:
- 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(config.LOCAL_BOOKS_PLIST)
books_open = get_books_last_open(config.LOCAL_LIBRARY_DB)
"""
import config
import plistlib
from collections import defaultdict
def parse_books_plist(plist_path=config.LOCAL_BOOKS_PLIST):
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=config.LOCAL_LIBRARY_DB):
"""
从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(config.LOCAL_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})")