FEAT: cài đặt các thư viện để chuẩn bị build exe trên window

This commit is contained in:
2026-08-08 08:46:15 +07:00
parent 9ef622f29a
commit 029ed1c456
24 changed files with 575 additions and 13 deletions
+86
View File
@@ -0,0 +1,86 @@
import os
import platform
import logging
from typing import List, Dict, Any
logger = logging.getLogger(__name__)
class NativePluginScanner:
"""Quét thư mục custom chứa VST3 (.vst3) / Audio Unit (.component trên macOS)
— spec DESKTOP VST (2026-08-08): POST /api/v1/desktop/plugins/scan."""
def __init__(self):
self.os_type = platform.system() # 'Linux', 'Windows', 'Darwin'
def scan_directories(self, target_paths: List[str]) -> List[Dict[str, Any]]:
found_plugins = []
seen = set()
for base_path in target_paths:
if not base_path:
continue
if not os.path.exists(base_path):
logger.warning(f"Scan path does not exist: {base_path}")
continue
for root, dirs, files in os.walk(base_path):
for dir_name in dirs:
full_path = os.path.join(root, dir_name)
# VST3 = bundle directory *.vst3
if dir_name.endswith('.vst3'):
plugin_name = dir_name[:-5]
pid = f"vst3_{plugin_name.lower().replace(' ', '_')}"
if pid in seen:
continue
seen.add(pid)
found_plugins.append({
"id": pid,
"name": plugin_name,
"type": "VST3",
"format": "VST3",
"category": "Instrument",
"vendor": self._read_vendor(full_path) or None,
"path": full_path,
"is_instrument": True,
"has_native_gui": True
})
# Audio Unit = bundle *.component (macOS only)
elif dir_name.endswith('.component') and self.os_type == 'Darwin':
plugin_name = dir_name[:-10]
pid = f"au_{plugin_name.lower().replace(' ', '_')}"
if pid in seen:
continue
seen.add(pid)
found_plugins.append({
"id": pid,
"name": plugin_name,
"type": "AU",
"format": "AudioUnit",
"category": "Instrument",
"vendor": self._read_vendor(full_path) or None,
"path": full_path,
"is_instrument": True,
"has_native_gui": True
})
return found_plugins
@staticmethod
def _read_vendor(bundle_path: str) -> str:
"""Đọc vendor từ Info.plist nếu có (macOS) — best-effort."""
try:
plist = os.path.join(bundle_path, "Contents", "Info.plist")
if os.path.exists(plist):
with open(plist, "rb") as f:
raw = f.read(65536)
import plistlib
try:
data = plistlib.loads(raw)
return data.get("CFBundleManufacturer") or data.get("NSHumanReadableCopyright")
except Exception:
return None
except Exception:
return None
return None