Files
LorenEteval_Furious/Furious/Utility/Utility.py
T
2023-07-24 19:49:17 +08:00

205 lines
4.7 KiB
Python

from Furious.Gui.Icon import Icon
from Furious.Utility.Constants import PLATFORM, ROOT_DIR
from PySide6.QtWidgets import QApplication
import os
import copy
import ujson
import logging
import pybase64
import functools
import subprocess
logger = logging.getLogger(__name__)
class Base64Encoder:
@staticmethod
def encode(text):
return pybase64.b64encode(text)
@staticmethod
def decode(text):
return pybase64.b64decode(text, validate=True)
class StateContext:
def __init__(self, ob, *args, **kwargs):
super().__init__(*args, **kwargs)
assert hasattr(ob, 'setDisabled')
self._ob = ob
def __enter__(self):
self._ob.setDisabled(True)
def __exit__(self, exceptionType, exceptionValue, tb):
self._ob.setDisabled(False)
class Storage:
EMPTY_OBJECT = {'model': []}
@staticmethod
def init():
return copy.deepcopy(Storage.EMPTY_OBJECT)
@staticmethod
def sync(ob=None):
if ob is None:
# Object is up-to-date
QApplication.instance().Configuration = Storage.toStorage(
QApplication.instance().MainWidget.StorageObj
)
else:
# Object is up-to-date
QApplication.instance().Configuration = Storage.toStorage(ob)
@staticmethod
def toObject(st):
if not st:
# Storage does not exist, or is empty
return Storage.init()
return ujson.loads(Base64Encoder.decode(st))
@staticmethod
def toStorage(ob):
return Base64Encoder.encode(
ujson.dumps(ob, ensure_ascii=False, escape_forward_slashes=False).encode()
)
@staticmethod
def clear():
QApplication.instance().Configuration = ''
QApplication.instance().ActivatedItemIndex = str(-1)
class Switch:
OFF = '0'
ON_ = '1'
RANGE = [OFF, ON_]
class SupportConnectedCallback:
Object = list()
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
SupportConnectedCallback.Object.append(self)
def disconnectedCallback(self):
raise NotImplementedError
def connectedCallback(self):
raise NotImplementedError
@staticmethod
def callConnectedCallback():
for ob in SupportConnectedCallback.Object:
assert isinstance(ob, SupportConnectedCallback)
ob.connectedCallback()
@staticmethod
def callDisconnectedCallback():
for ob in SupportConnectedCallback.Object:
assert isinstance(ob, SupportConnectedCallback)
ob.disconnectedCallback()
class SupportThemeChangedCallback:
Object = list()
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
SupportThemeChangedCallback.Object.append(self)
def themeChangedCallback(self, theme):
raise NotImplementedError
@staticmethod
def callThemeChangedCallback(theme):
logger.info(f'system theme changed to {theme}')
for ob in SupportThemeChangedCallback.Object:
assert isinstance(ob, SupportThemeChangedCallback)
ob.themeChangedCallback(theme)
def icon(prefix, name):
if name.startswith('rocket-takeoff'):
# Colorful. Use default
return Icon(f':/Icons/bootstrap/{name}')
else:
return Icon(f':/Icons/{prefix}/{name}')
bootstrapIcon = functools.partial(icon, 'bootstrap')
bootstrapIconWhite = functools.partial(icon, 'bootstrap/white')
def protocolRepr(protocol):
if protocol.lower() == 'vmess':
return 'VMess'
if protocol.lower() == 'vless':
return 'VLESS'
return ''
def getAbsolutePath(path):
return path if os.path.isabs(path) else str(ROOT_DIR / path)
def swapListItem(listOrTuple, index0, index1):
swap = listOrTuple[index0]
listOrTuple[index0] = listOrTuple[index1]
listOrTuple[index1] = swap
def moveToCenter(widget, parent=None):
geometry = widget.geometry()
if parent is None:
center = QApplication.primaryScreen().availableGeometry().center()
else:
center = parent.geometry().center()
geometry.moveCenter(center)
widget.move(geometry.topLeft())
def getUbuntuRelease():
try:
result = subprocess.run(
['cat', '/etc/lsb-release'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
check=True,
)
values = dict(
list(line.split('='))
for line in filter(lambda x: x != '', result.stdout.decode().split('\n'))
)
if values['DISTRIB_ID'] == 'Ubuntu':
return values['DISTRIB_RELEASE']
else:
return ''
except Exception:
# Any non-exit exceptions
return ''