DeepFaceLive/xlib/mp/csw/Paths.py
2021-08-26 09:08:15 +04:00

145 lines
4.5 KiB
Python

from collections import Iterable
from enum import IntEnum
from pathlib import Path
from typing import List, Union
from ...python import EventListener
from .CSWBase import ControlClient, ControlHost
class _PathBase:
def __init__(self):
self._paths = []
self._on_paths_evl = EventListener()
self._call_on_msg('paths', self._on_msg_paths)
def _on_msg_paths(self, path):
self._set_paths(path)
def _send_paths(self):
self._send_msg('paths', self._paths)
def _set_paths(self, path_or_list, block_event=False):
if isinstance(path_or_list, Iterable) and \
not isinstance(path_or_list, str):
path_or_list = list(path_or_list)
else:
path_or_list = [path_or_list]
for i,path in enumerate(path_or_list):
if isinstance(path, str):
path_or_list[i] = Path(path)
elif not isinstance(path, Path):
raise ValueError(f'value {path} must be an instance of str or Path')
if self._paths != path_or_list:
prev_paths = self._paths
self._paths = path_or_list
if not block_event:
self._on_paths_evl.call(path_or_list, prev_paths)
return True
return False
def call_on_paths(self, func_or_list):
"""
Call when the path is changed
func(path_list, prev_path_list)
"""
self._on_paths_evl.add(func_or_list)
def set_paths(self, path_or_list, block_event=False):
"""
path_or_list Path/str or list of Paths/str or []
or None which is same as []
"""
if path_or_list is None:
path_or_list = []
if self._set_paths(path_or_list, block_event=block_event):
self._send_paths()
def get_paths(self): return self._paths
class Paths:
"""
Paths control.
Values: [] not set
list of [1+] Paths
"""
class Config:
class Type(IntEnum):
NONE = 0
ANY_FILE = 1
EXISTING_FILE = 2
EXISTING_FILES = 3
DIRECTORY = 4
def __init__(self, type = None, is_save = False, caption = None, suffixes = None, directory_path = None):
if type is None:
type = Paths.Config.Type.NONE
self._type = type
self._is_save = is_save
self._caption = caption
self._suffixes = suffixes
self._directory_path = directory_path
def get_type(self) -> 'Paths.Config.Type': return self._type
def is_save(self) -> bool: return self._is_save
def get_caption(self) -> Union[str, None]: return self._caption
def get_suffixes(self) -> Union[List[str], None]: return self._suffixes
def get_directory_path(self) -> Union[Path, None]: return self._directory_path
@staticmethod
def AnyFile(is_save=False, caption=None, suffixes=None):
return Paths.Config(Paths.Config.Type.ANY_FILE, is_save, caption, suffixes)
@staticmethod
def ExistingFile(is_save=False, caption=None, suffixes=None):
return Paths.Config(Paths.Config.Type.EXISTING_FILE, is_save, caption, suffixes)
@staticmethod
def ExistingFiles(caption=None, suffixes=None):
return Paths.Config(Paths.Config.Type.EXISTING_FILES, False, caption, suffixes)
@staticmethod
def Directory(caption=None, directory_path=None):
return Paths.Config(Paths.Config.Type.DIRECTORY, False, caption, None, directory_path=directory_path)
class Host(ControlHost, _PathBase):
def __init__(self):
ControlHost.__init__(self)
_PathBase.__init__(self)
self._config = Paths.Config()
def _on_msg_paths(self, path):
if self.is_enabled():
_PathBase._on_msg_paths(self, path)
self._send_paths()
def set_config(self, config : 'Paths.Config'):
self._config = config
self._send_msg('config', config)
class Client(ControlClient, _PathBase):
def __init__(self):
ControlClient.__init__(self)
_PathBase.__init__(self)
self._on_config_evl = EventListener()
self._call_on_msg('config', self._on_msg_config)
def _on_msg_config(self, config : 'Paths.Config'):
self._on_config_evl.call(config)
def call_on_config(self, func): self._on_config_evl.add(func)
def _on_reset(self):
self._set_paths([])