Docker Build and Push / check-secrets (push) Successful in 30s
Docker Build and Push / build-and-push (cuda, 12.6) (push) Has been skipped
Docker Build and Push / build-and-push (cuda, 12.8) (push) Has been skipped
Docker Build and Push / build-and-push (directml, latest) (push) Has been skipped
Docker Build and Push / build-and-push (cpu, latest) (push) Has been skipped
Docker Build and Push / build-and-push (cuda, 11.8) (push) Has been skipped
Build Windows CPU / build (push) Has been cancelled
Build Windows CUDA 11.8 / build (push) Has been cancelled
Build Windows CUDA 12.6 / build (push) Has been cancelled
Build Windows CUDA 12.8 / build (push) Has been cancelled
Build Windows DirectML / build (push) Has been cancelled
- Add gpu_id parameter to SubtitleDetect for GPU acceleration - Implement multi-threaded frame scanning with thread-safe CUDA context - Add smart_detect module and web application components - Update .gitignore to exclude web cache Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
156 lines
4.1 KiB
Python
156 lines
4.1 KiB
Python
"""
|
|
Minimal qfluentwidgets stub for headless/server use — no Qt required.
|
|
Provides just enough for backend/config.py to import and function correctly.
|
|
"""
|
|
|
|
import json
|
|
import os
|
|
|
|
|
|
class _Signal:
|
|
def connect(self, fn): pass
|
|
def disconnect(self, fn=None): pass
|
|
def emit(self, *args): pass
|
|
|
|
|
|
class ConfigValidator:
|
|
def validate(self, v): return True
|
|
def correct(self, v): return v
|
|
|
|
|
|
class BoolValidator(ConfigValidator):
|
|
def validate(self, v): return isinstance(v, bool)
|
|
def correct(self, v): return bool(v)
|
|
|
|
|
|
class OptionsValidator(ConfigValidator):
|
|
def __init__(self, options):
|
|
try:
|
|
self._opts = [e for e in options]
|
|
except TypeError:
|
|
self._opts = []
|
|
|
|
def validate(self, v): return v in self._opts
|
|
def correct(self, v): return v if v in self._opts else (self._opts[0] if self._opts else v)
|
|
|
|
|
|
class RangeValidator(ConfigValidator):
|
|
def __init__(self, min_val, max_val):
|
|
self.min_val = min_val
|
|
self.max_val = max_val
|
|
|
|
def validate(self, v): return self.min_val <= v <= self.max_val
|
|
def correct(self, v): return max(self.min_val, min(self.max_val, v))
|
|
|
|
|
|
class EnumSerializer:
|
|
def __init__(self, enum_cls):
|
|
self.enum_cls = enum_cls
|
|
|
|
def serialize(self, v):
|
|
return v.value if hasattr(v, 'value') else str(v)
|
|
|
|
def deserialize(self, s):
|
|
for e in self.enum_cls:
|
|
if e.value == s:
|
|
return e
|
|
return s
|
|
|
|
|
|
class ConfigItem:
|
|
def __init__(self, section, key, default, validator=None, restart=False):
|
|
self.section = section
|
|
self.key = key
|
|
self.value = default
|
|
self.validator = validator or ConfigValidator()
|
|
self.restart = restart
|
|
self.valueChanged = _Signal()
|
|
|
|
|
|
class OptionsConfigItem(ConfigItem):
|
|
def __init__(self, section, key, default, validator=None, serializer=None, restart=False):
|
|
super().__init__(section, key, default, validator, restart)
|
|
self.serializer = serializer
|
|
|
|
|
|
class RangeConfigItem(ConfigItem):
|
|
def __init__(self, section, key, default, validator=None):
|
|
super().__init__(section, key, default, validator)
|
|
|
|
|
|
class QConfig:
|
|
appRestartSig = _Signal()
|
|
|
|
def set(self, item, value):
|
|
item.value = value
|
|
try:
|
|
item.valueChanged.emit(value)
|
|
except Exception:
|
|
pass
|
|
|
|
|
|
class _QConfigLoader:
|
|
def load(self, filepath, config_obj):
|
|
if not os.path.exists(filepath):
|
|
return
|
|
try:
|
|
with open(filepath, 'r', encoding='utf-8') as f:
|
|
data = json.load(f)
|
|
except Exception:
|
|
return
|
|
|
|
cls = type(config_obj)
|
|
for attr_name in dir(cls):
|
|
if attr_name.startswith('_'):
|
|
continue
|
|
item = getattr(cls, attr_name, None)
|
|
if not isinstance(item, ConfigItem):
|
|
continue
|
|
section_data = data.get(item.section, {})
|
|
if item.key not in section_data:
|
|
continue
|
|
raw = section_data[item.key]
|
|
if isinstance(item, OptionsConfigItem) and item.serializer:
|
|
try:
|
|
raw = item.serializer.deserialize(raw)
|
|
except Exception:
|
|
pass
|
|
if item.validator.validate(raw):
|
|
item.value = raw
|
|
|
|
|
|
qconfig = _QConfigLoader()
|
|
|
|
# ── additional symbols referenced by gui code (safe no-ops) ──────────────
|
|
class FluentIcon:
|
|
HOME = None; SETTING = None; FOLDER = None; PLAY = None
|
|
|
|
class Theme:
|
|
DARK = 'dark'; LIGHT = 'light'
|
|
|
|
class NavigationItemPosition:
|
|
BOTTOM = 'bottom'
|
|
|
|
def setTheme(*a, **k): pass
|
|
def setThemeColor(*a, **k): pass
|
|
def isDarkTheme(): return True
|
|
|
|
# Fluent widget stubs — only imported by GUI code, never used by backend
|
|
class _Widget:
|
|
def __init__(self, *a, **k): pass
|
|
|
|
CardWidget = _Widget
|
|
PushButton = _Widget
|
|
Slider = _Widget
|
|
ProgressBar = _Widget
|
|
PlainTextEdit = _Widget
|
|
TextEdit = _Widget
|
|
SubtitleLabel = _Widget
|
|
HollowHandleStyle = _Widget
|
|
InfoBar = _Widget
|
|
SettingCardGroup = _Widget
|
|
ComboBoxSettingCard = _Widget
|
|
SwitchSettingCard = _Widget
|
|
FluentWindow = _Widget
|
|
NavigationWidget = _Widget
|