MarkBase架构升级:Multi-Volume Virtual Tree + Dual-View Management + Git Remote修正
核心功能: - ✅ Categories/Series双视图管理(category_view.rs + import_markdown.rs) - ✅ FUSE Multi-Volume支持(tree_type参数) - ✅ SSH/SFTP/SCP/rsync协议完整实现(4042行) - ✅ NFS/SMB Module Phase 1-3完成 - ✅ Archive Module Phase 1-4完成(2916行) - ✅ Download Center API完整实现 - ✅ S3兼容API实现(560行) Git配置修正: - ✅ 删除错误origin(gitea.momentry.ddns.net) - ✅ 删除m5max128(指向机器名) - ✅ 设置origin = m5max128gitea.momentry.ddns.net/admin/markbase - ✅ 设置m4minigitea = m4minigitea.momentry.ddns.net/warren/markbase 数据清理: - ✅ 删除38个临时SQLite(保留accusys.sqlite、demo.sqlite) - ✅ 删除.bak、test_*.bin、调试脚本等临时文件 - ✅ 删除临时目录(build/、download files/、raid_test/等) - ✅ 更新.gitignore排除临时文件 架构优化: - 52个文件修改,2434行新增,4739行删除 - Workspace成员整合(16个crate) - 数据库状态:accusys.sqlite保留(主demo测试) 远程同步: - ✅ 准备推送到m5max128gitea(远程Gitea) - ✅ 准备推送到m4minigitea(本地Gitea)
This commit is contained in:
24
tools/MarkBaseInstaller/Info.plist
Normal file
24
tools/MarkBaseInstaller/Info.plist
Normal file
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.momentry.markbase.installer</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>MarkBase Installer</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0.0</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0.0</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>MarkBaseInstaller</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>26.0</string>
|
||||
<key>NSHighResolutionCapable</key>
|
||||
<true/>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
</dict>
|
||||
</plist>
|
||||
8
tools/MarkBaseInstaller/MarkBaseInstaller.entitlements
Normal file
8
tools/MarkBaseInstaller/MarkBaseInstaller.entitlements
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.developer.system-extension.install</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
</dict>
|
||||
</plist>
|
||||
1
tools/MarkBaseInstaller/Resources/.gitkeep
Normal file
1
tools/MarkBaseInstaller/Resources/.gitkeep
Normal file
@@ -0,0 +1 @@
|
||||
Placeholder
|
||||
147
tools/MarkBaseInstaller/Sources/AppDelegate.swift
Normal file
147
tools/MarkBaseInstaller/Sources/AppDelegate.swift
Normal file
@@ -0,0 +1,147 @@
|
||||
import Cocoa
|
||||
import SystemExtensions
|
||||
import OSLog
|
||||
|
||||
@MainActor
|
||||
@main
|
||||
class AppDelegate: NSObject, NSApplicationDelegate {
|
||||
let logger = Logger(subsystem: "com.momentry.markbase.installer", category: "AppDelegate")
|
||||
var window: NSWindow!
|
||||
var statusLabel: NSTextField!
|
||||
var installButton: NSButton!
|
||||
var extensionDelegate: ExtensionDelegate?
|
||||
|
||||
func applicationDidFinishLaunching(_ aNotification: Notification) {
|
||||
logger.info("MarkBase Installer started")
|
||||
createWindow()
|
||||
setupUI()
|
||||
window.makeKeyAndOrderFront(nil)
|
||||
}
|
||||
|
||||
func createWindow() {
|
||||
window = NSWindow(
|
||||
contentRect: NSRect(x: 0, y: 0, width: 500, height: 400),
|
||||
styleMask: [.titled, .closable, .miniaturizable],
|
||||
backing: .buffered,
|
||||
defer: false
|
||||
)
|
||||
window.title = "MarkBase Installer"
|
||||
window.center()
|
||||
window.isReleasedWhenClosed = false
|
||||
}
|
||||
|
||||
func setupUI() {
|
||||
let contentView = window.contentView!
|
||||
|
||||
let titleLabel = NSTextField(labelWithString: "MarkBase System Extension Installer")
|
||||
titleLabel.font = NSFont.systemFont(ofSize: 18, weight: .bold)
|
||||
titleLabel.alignment = .center
|
||||
contentView.addSubview(titleLabel)
|
||||
|
||||
statusLabel = NSTextField(wrappingLabelWithString: "Ready to install MarkBaseFS System Extension")
|
||||
statusLabel.font = NSFont.systemFont(ofSize: 14)
|
||||
statusLabel.alignment = .center
|
||||
contentView.addSubview(statusLabel)
|
||||
|
||||
installButton = NSButton(title: "Install System Extension", target: self, action: #selector(installExtension))
|
||||
installButton.bezelStyle = .rounded
|
||||
installButton.font = NSFont.systemFont(ofSize: 13, weight: .medium)
|
||||
contentView.addSubview(installButton)
|
||||
|
||||
titleLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
statusLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
installButton.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
NSLayoutConstraint.activate([
|
||||
titleLabel.centerXAnchor.constraint(equalTo: contentView.centerXAnchor),
|
||||
titleLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 50),
|
||||
|
||||
statusLabel.centerXAnchor.constraint(equalTo: contentView.centerXAnchor),
|
||||
statusLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 40),
|
||||
statusLabel.widthAnchor.constraint(equalTo: contentView.widthAnchor, multiplier: 0.8),
|
||||
|
||||
installButton.centerXAnchor.constraint(equalTo: contentView.centerXAnchor),
|
||||
installButton.topAnchor.constraint(equalTo: statusLabel.bottomAnchor, constant: 40),
|
||||
installButton.widthAnchor.constraint(equalToConstant: 200),
|
||||
installButton.heightAnchor.constraint(equalToConstant: 30),
|
||||
])
|
||||
}
|
||||
|
||||
@objc func installExtension() {
|
||||
logger.info("Install button clicked")
|
||||
|
||||
let extensionID = "com.momentry.markbase.fskit"
|
||||
logger.info("Requesting activation for extension: \(extensionID)")
|
||||
|
||||
updateStatus("Requesting installation...")
|
||||
installButton.isEnabled = false
|
||||
|
||||
let request = OSSystemExtensionRequest.activationRequest(
|
||||
forExtensionWithIdentifier: extensionID,
|
||||
queue: .main
|
||||
)
|
||||
|
||||
extensionDelegate = ExtensionDelegate(
|
||||
onSuccess: {
|
||||
self.logger.info("Extension activated successfully")
|
||||
self.updateStatus("✅ Installation successful!")
|
||||
self.installButton.isEnabled = true
|
||||
self.extensionDelegate = nil
|
||||
},
|
||||
onError: { error in
|
||||
self.logger.error("Extension activation failed: \(error.localizedDescription)")
|
||||
self.updateStatus("❌ Installation failed: \(error.localizedDescription)")
|
||||
self.installButton.isEnabled = true
|
||||
self.extensionDelegate = nil
|
||||
},
|
||||
onNeedsApproval: {
|
||||
self.logger.info("Extension needs user approval")
|
||||
self.updateStatus("⏳ Waiting for approval in System Settings")
|
||||
}
|
||||
)
|
||||
|
||||
request.delegate = extensionDelegate
|
||||
OSSystemExtensionManager.shared.submitRequest(request)
|
||||
}
|
||||
|
||||
func updateStatus(_ message: String) {
|
||||
statusLabel.stringValue = message
|
||||
}
|
||||
}
|
||||
|
||||
class ExtensionDelegate: NSObject, OSSystemExtensionRequestDelegate {
|
||||
let onSuccess: () -> Void
|
||||
let onError: (Error) -> Void
|
||||
let onNeedsApproval: () -> Void
|
||||
|
||||
init(onSuccess: @escaping () -> Void, onError: @escaping (Error) -> Void, onNeedsApproval: @escaping () -> Void) {
|
||||
self.onSuccess = onSuccess
|
||||
self.onError = onError
|
||||
self.onNeedsApproval = onNeedsApproval
|
||||
super.init()
|
||||
}
|
||||
|
||||
func request(_ request: OSSystemExtensionRequest, didFinishWithResult result: OSSystemExtensionRequest.Result) {
|
||||
Logger(subsystem: "com.momentry.markbase.installer", category: "ExtensionDelegate")
|
||||
.info("Request finished with result")
|
||||
onSuccess()
|
||||
}
|
||||
|
||||
func request(_ request: OSSystemExtensionRequest, didFailWithError error: Error) {
|
||||
Logger(subsystem: "com.momentry.markbase.installer", category: "ExtensionDelegate")
|
||||
.error("Request failed with error: \(error.localizedDescription)")
|
||||
onError(error)
|
||||
}
|
||||
|
||||
func requestNeedsUserApproval(_ request: OSSystemExtensionRequest) {
|
||||
Logger(subsystem: "com.momentry.markbase.installer", category: "ExtensionDelegate")
|
||||
.info("Request needs user approval")
|
||||
onNeedsApproval()
|
||||
}
|
||||
|
||||
func request(_ request: OSSystemExtensionRequest, actionForReplacingExtension existing: OSSystemExtensionProperties, withExtension ext: OSSystemExtensionProperties) -> OSSystemExtensionRequest.ReplacementAction {
|
||||
Logger(subsystem: "com.momentry.markbase.installer", category: "ExtensionDelegate")
|
||||
.info("Replacing extension")
|
||||
return .replace
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user