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:
195
tools/MarkBaseInstallerMinimal/Sources/main.swift
Normal file
195
tools/MarkBaseInstallerMinimal/Sources/main.swift
Normal file
@@ -0,0 +1,195 @@
|
||||
import Cocoa
|
||||
import SystemExtensions
|
||||
import OSLog
|
||||
|
||||
@main
|
||||
struct MarkBaseInstallerApp {
|
||||
static func main() {
|
||||
let app = NSApplication.shared
|
||||
let delegate = AppDelegate()
|
||||
app.delegate = delegate
|
||||
app.run()
|
||||
}
|
||||
}
|
||||
|
||||
class AppDelegate: NSObject, NSApplicationDelegate {
|
||||
let logger = Logger(subsystem: "com.momentry.markbase.installer", category: "AppDelegate")
|
||||
var window: NSWindow!
|
||||
var statusLabel: NSTextField!
|
||||
var installButton: NSButton!
|
||||
var activityIndicator: NSProgressIndicator!
|
||||
|
||||
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!
|
||||
|
||||
// Title
|
||||
let titleLabel = NSTextField(labelWithString: "MarkBase System Extension Installer")
|
||||
titleLabel.font = NSFont.systemFont(ofSize: 18, weight: .bold)
|
||||
titleLabel.alignment = .center
|
||||
contentView.addSubview(titleLabel)
|
||||
|
||||
// Status Label
|
||||
statusLabel = NSTextField(wrappingLabelWithString: "Ready to install MarkBaseFS System Extension")
|
||||
statusLabel.font = NSFont.systemFont(ofSize: 14)
|
||||
statusLabel.alignment = .center
|
||||
statusLabel.textColor = NSColor.controlTextColor
|
||||
contentView.addSubview(statusLabel)
|
||||
|
||||
// Install Button
|
||||
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)
|
||||
|
||||
// Activity Indicator
|
||||
activityIndicator = NSProgressIndicator()
|
||||
activityIndicator.style = .spinning
|
||||
activityIndicator.controlSize = .small
|
||||
activityIndicator.isHidden = true
|
||||
contentView.addSubview(activityIndicator)
|
||||
|
||||
// Instructions
|
||||
let instructionsLabel = NSTextField(wrappingLabelWithString: "Instructions:\n1. Click Install button\n2. Approve in System Settings → Privacy & Security → System Extensions\n3. Wait for activation")
|
||||
instructionsLabel.font = NSFont.systemFont(ofSize: 12)
|
||||
instructionsLabel.alignment = .left
|
||||
instructionsLabel.textColor = NSColor.secondaryLabelColor
|
||||
contentView.addSubview(instructionsLabel)
|
||||
|
||||
// Layout
|
||||
titleLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
statusLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
installButton.translatesAutoresizingMaskIntoConstraints = false
|
||||
activityIndicator.translatesAutoresizingMaskIntoConstraints = false
|
||||
instructionsLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
NSLayoutConstraint.activate([
|
||||
// Title
|
||||
titleLabel.centerXAnchor.constraint(equalTo: contentView.centerXAnchor),
|
||||
titleLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 40),
|
||||
|
||||
// Status Label
|
||||
statusLabel.centerXAnchor.constraint(equalTo: contentView.centerXAnchor),
|
||||
statusLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 30),
|
||||
statusLabel.widthAnchor.constraint(equalTo: contentView.widthAnchor, multiplier: 0.8),
|
||||
|
||||
// Install Button
|
||||
installButton.centerXAnchor.constraint(equalTo: contentView.centerXAnchor),
|
||||
installButton.topAnchor.constraint(equalTo: statusLabel.bottomAnchor, constant: 30),
|
||||
installButton.widthAnchor.constraint(equalToConstant: 200),
|
||||
installButton.heightAnchor.constraint(equalToConstant: 30),
|
||||
|
||||
// Activity Indicator
|
||||
activityIndicator.centerXAnchor.constraint(equalTo: contentView.centerXAnchor),
|
||||
activityIndicator.topAnchor.constraint(equalTo: installButton.bottomAnchor, constant: 20),
|
||||
|
||||
// Instructions
|
||||
instructionsLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 30),
|
||||
instructionsLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -30),
|
||||
instructionsLabel.topAnchor.constraint(equalTo: activityIndicator.bottomAnchor, constant: 30),
|
||||
instructionsLabel.bottomAnchor.constraint(lessThanOrEqualTo: contentView.bottomAnchor, constant: -30)
|
||||
])
|
||||
}
|
||||
|
||||
@objc func installExtension(_ sender: NSButton) {
|
||||
logger.info("Install button clicked")
|
||||
|
||||
let extensionID = "com.momentry.markbase.fskit"
|
||||
logger.info("Requesting activation for extension: \(extensionID)")
|
||||
|
||||
updateStatus("Requesting installation...")
|
||||
installButton.isEnabled = false
|
||||
activityIndicator.isHidden = false
|
||||
activityIndicator.startAnimation(nil)
|
||||
|
||||
let request = OSSystemExtensionRequest.activationRequest(
|
||||
forExtensionWithIdentifier: extensionID,
|
||||
queue: .main
|
||||
)
|
||||
request.delegate = ExtensionDelegate(
|
||||
onSuccess: {
|
||||
self.logger.info("Extension activated successfully")
|
||||
self.updateStatus("✅ Installation successful!\nSystem Extension is now active.")
|
||||
self.activityIndicator.stopAnimation(nil)
|
||||
self.activityIndicator.isHidden = true
|
||||
self.installButton.isEnabled = true
|
||||
},
|
||||
onError: { error in
|
||||
self.logger.error("Extension activation failed: \(error.localizedDescription)")
|
||||
self.updateStatus("❌ Installation failed: \(error.localizedDescription)")
|
||||
self.activityIndicator.stopAnimation(nil)
|
||||
self.activityIndicator.isHidden = true
|
||||
self.installButton.isEnabled = true
|
||||
},
|
||||
onNeedsApproval: {
|
||||
self.logger.info("Extension needs user approval")
|
||||
self.updateStatus("⏳ Waiting for approval...\nOpen System Settings → Privacy & Security → System Extensions")
|
||||
self.activityIndicator.stopAnimation(nil)
|
||||
self.activityIndicator.isHidden = true
|
||||
}
|
||||
)
|
||||
|
||||
OSSystemExtensionManager.shared.submitRequest(request)
|
||||
}
|
||||
|
||||
func updateStatus(_ message: String) {
|
||||
DispatchQueue.main.async {
|
||||
self.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: \(String(describing: 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 \(existing.bundleIdentifier) with \(ext.bundleIdentifier)")
|
||||
return .replace
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user