mirror of
https://github.com/LorenEteval/Furious.git
synced 2026-09-27 09:27:55 +03:00
205 lines
4.7 KiB
Python
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 ''
|