This commit is contained in:
douboer
2025-09-06 12:25:42 +08:00
parent d7a0a53368
commit b214638aed
22 changed files with 9470 additions and 15 deletions

123
ibook_export_app.py Normal file
View File

@@ -0,0 +1,123 @@
import sys
import os
import re
import datetime
from PyQt6.QtWidgets import (
QApplication, QWidget, QVBoxLayout, QPushButton, QLabel, QListWidget,
QFileDialog, QMessageBox, QLineEdit, QFormLayout, QDialog, QDialogButtonBox
)
from PyQt6.QtGui import QIcon
import config
from exportbooknotes import BookNotesExporter
from booklist_parse import BookListManager
class ConfigDialog(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("配置参数")
layout = QFormLayout(self)
self.inputs = {}
for attr in dir(config):
if attr.isupper():
val = getattr(config, attr)
inp = QLineEdit(str(val))
layout.addRow(attr, inp)
self.inputs[attr] = inp
buttons = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel)
buttons.accepted.connect(self.accept)
buttons.rejected.connect(self.reject)
layout.addWidget(buttons)
def get_config(self):
return {k: v.text() for k, v in self.inputs.items()}
class IBookExportApp(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("iBooks 笔记导出工具")
self.resize(600, 400)
# 设置窗口图标
if os.path.exists(config.APP_ICON):
self.setWindowIcon(QIcon(config.APP_ICON))
self.exporter = BookNotesExporter(config)
self.manager = BookListManager(plist_path=config.LOCAL_BOOKS_PLIST, db_path=config.LOCAL_LIBRARY_DB)
self.booksinfo = self.manager.get_books_info()
self.last_open_times = self.manager.get_books_last_open()
self.assetid2name = {}
self.assetid2lastopen = {}
for assetid, info in self.booksinfo.items():
name = info.get('displayname') or info.get('itemname') or assetid
if '-' in name:
name = name.split('-', 1)[0].strip()
self.assetid2name[assetid] = name
ts = self.last_open_times.get(assetid, {}).get('last_open', 0)
self.assetid2lastopen[assetid] = ts
sorted_assetids = sorted(self.assetid2name.keys(), key=lambda aid: self.assetid2lastopen[aid], reverse=True)
self.sorted_assetids = sorted_assetids
layout = QVBoxLayout(self)
self.label = QLabel("请选择要导出的书籍:")
layout.addWidget(self.label)
self.listwidget = QListWidget()
for aid in sorted_assetids:
self.listwidget.addItem(f"{self.assetid2name[aid]} [{self.assetid2lastopen[aid]}]")
layout.addWidget(self.listwidget)
# 回车直接导出(使用事件过滤器)
self.listwidget.installEventFilter(self)
self.export_btn = QPushButton("导出")
self.export_btn.clicked.connect(self.export_notes)
self.config_btn = QPushButton("配置参数")
self.config_btn.clicked.connect(self.show_config)
layout.addWidget(self.export_btn)
layout.addWidget(self.config_btn)
def eventFilter(self, obj, event):
from PyQt6.QtCore import QEvent, Qt
if obj == self.listwidget and event.type() == QEvent.Type.KeyPress:
# 检查回车键Enter/Return
if event.key() in (0x01000004, 0x01000005): # Qt.Key_Return, Qt.Key_Enter
self.export_notes()
return True
return super().eventFilter(obj, event)
def show_config(self):
dlg = ConfigDialog(self)
if dlg.exec():
new_config = dlg.get_config()
# 这里只是演示实际可写入config.py或动态加载
QMessageBox.information(self, "提示", "配置已更新(仅本次运行有效)")
def export_notes(self):
from exportbooknotes import sync_source_files
sync_source_files(config)
idx = self.listwidget.currentRow()
if idx < 0:
QMessageBox.warning(self, "提示", "请先选择一本书")
return
assetid = self.sorted_assetids[idx]
selected_booksnote = self.exporter.build_booksnote(bookid=assetid)
selected_booksinfo = {assetid: self.booksinfo.get(assetid, {})}
bookname = selected_booksinfo[assetid].get("displayname") or selected_booksinfo[assetid].get("itemname") or assetid
ts = datetime.datetime.now().strftime('%m%d%H%M')
shortname = re.split(r'[.:_\\[\(]', bookname)[0].strip()
export_dir = getattr(config, "EXPORT_NOTES_DIR", os.getcwd())
if not os.path.exists(export_dir):
os.makedirs(export_dir)
out_path = os.path.join(export_dir, f"notes_{shortname}-{ts}.md")
self.exporter.export_booksnote_to_md(selected_booksnote, selected_booksinfo, out_path)
QMessageBox.information(self, "导出成功", f"已导出到:{out_path}")
if __name__ == "__main__":
app = QApplication(sys.argv)
# 设置应用程序图标
if os.path.exists(config.APP_ICON):
app.setWindowIcon(QIcon(config.APP_ICON))
win = IBookExportApp()
win.show()
sys.exit(app.exec())