mirror of
https://github.com/LorenEteval/Furious.git
synced 2026-09-22 23:08:08 +03:00
Refactor package architecture
Signed-off-by: Loren Eteval <loren.eteval@proton.me>
This commit is contained in:
@@ -21,12 +21,13 @@ from __future__ import annotations
|
||||
|
||||
from Furious.Frozenlib import *
|
||||
from Furious.Interface import *
|
||||
from Furious.Library import *
|
||||
from Furious.Domain import *
|
||||
from Furious.Repository import *
|
||||
from Furious.Plugins import getPluginRegistry
|
||||
from Furious.Qt import *
|
||||
from Furious.Qt import gettext as _
|
||||
from Furious.Service import CoreManager
|
||||
from Furious.TrayActions.ConnectProgressBar import ConnectProgressBar
|
||||
from Furious.Service import ConnectionManager, UpdateManager
|
||||
from Furious.Widget.ConnectionProgressWidget import ConnectionProgressWidget
|
||||
|
||||
from PySide6 import QtCore
|
||||
|
||||
@@ -69,13 +70,13 @@ class ConnectAction(AppQAction):
|
||||
)
|
||||
|
||||
self.actionQueue = queue.Queue()
|
||||
self.coreManager = CoreManager()
|
||||
self.progressBar = ConnectProgressBar()
|
||||
self.coreManager = ConnectionManager()
|
||||
self.progressBar = ConnectionProgressWidget()
|
||||
|
||||
self.actionTimer = QtCore.QTimer()
|
||||
self.actionTimer.timeout.connect(lambda: self.callActionFromQueue())
|
||||
|
||||
self.updatesManager = UpdatesManager()
|
||||
self.updatesManager = UpdateManager()
|
||||
|
||||
def reset(self):
|
||||
"""Restore the connect action to its initial state."""
|
||||
@@ -358,7 +359,7 @@ class ConnectAction(AppQAction):
|
||||
if callable(action):
|
||||
action()
|
||||
|
||||
def coreExitCallback(self, core: CoreProcessFactory, exitcode: int):
|
||||
def coreExitCallback(self, core: CoreProcess, exitcode: int):
|
||||
"""Handle the core exit callback."""
|
||||
|
||||
def putItem(item):
|
||||
@@ -370,11 +371,11 @@ class ConnectAction(AppQAction):
|
||||
|
||||
pass
|
||||
|
||||
if exitcode == CoreProcessFactory.ExitCode.SystemShuttingDown.value:
|
||||
if exitcode == CoreProcess.ExitCode.SystemShuttingDown.value:
|
||||
# System shutting down. Do nothing
|
||||
return None
|
||||
|
||||
if exitcode == CoreProcessFactory.ExitCode.ConfigurationError.value:
|
||||
if exitcode == CoreProcess.ExitCode.ConfigurationError.value:
|
||||
putItem(
|
||||
functools.partial(
|
||||
self.doDisconnectWithTrayMessage,
|
||||
@@ -384,7 +385,7 @@ class ConnectAction(AppQAction):
|
||||
|
||||
return None
|
||||
|
||||
if exitcode == CoreProcessFactory.ExitCode.ServerStartFailure.value:
|
||||
if exitcode == CoreProcess.ExitCode.ServerStartFailure.value:
|
||||
putItem(
|
||||
functools.partial(
|
||||
self.doDisconnectWithTrayMessage,
|
||||
@@ -20,10 +20,11 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from Furious.Frozenlib import *
|
||||
from Furious.Library import *
|
||||
from Furious.Domain import *
|
||||
from Furious.Repository import *
|
||||
from Furious.Qt import *
|
||||
from Furious.Qt import gettext as _
|
||||
from Furious.Qt.WaitingSpinner import *
|
||||
from Furious.Widget.WaitingSpinner import *
|
||||
|
||||
from PySide6 import QtCore
|
||||
from PySide6.QtGui import QColor
|
||||
@@ -20,7 +20,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from Furious.Frozenlib import *
|
||||
from Furious.Library import *
|
||||
from Furious.Repository import *
|
||||
from Furious.Plugins import getPluginRegistry
|
||||
from Furious.Qt import *
|
||||
from Furious.Qt import gettext as _
|
||||
@@ -15,13 +15,12 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
"""Expose system-tray actions used by the application."""
|
||||
"""Expose reusable application actions and action menus."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .Connect import ConnectAction
|
||||
from .ConnectProgressBar import ConnectProgressBar
|
||||
from .EditConfiguration import EditConfigurationAction
|
||||
from .Configuration import EditConfigurationAction
|
||||
from .Connection import ConnectAction
|
||||
from .Exit import ExitAction
|
||||
from .Import import (
|
||||
ImportAction,
|
||||
@@ -37,7 +36,6 @@ from .SystemProxy import SystemProxyAction
|
||||
|
||||
__all__ = [
|
||||
'ConnectAction',
|
||||
'ConnectProgressBar',
|
||||
'EditConfigurationAction',
|
||||
'ExitAction',
|
||||
'ImportAction',
|
||||
@@ -22,14 +22,15 @@ from __future__ import annotations
|
||||
from Furious.Frozenlib import *
|
||||
from Furious.Interface import *
|
||||
from Furious.Core import Tun2socks
|
||||
from Furious.Plugins import getPluginRegistry
|
||||
from Furious.Backends import OFFICIAL_PLUGIN_TYPES
|
||||
from Furious.Plugins import initializePluginRegistry
|
||||
from Furious.Qt import AppStyleSheet
|
||||
from Furious.Qt.TextEditorTheme import configureEditorLogMetadata
|
||||
from Furious.Qt import gettext as _
|
||||
from Furious.Library import *
|
||||
from Furious.Application.SystemTrayIcon import *
|
||||
from Furious.Window.AppMainWindow import *
|
||||
from Furious.Window.LogViewerWindow import *
|
||||
from Furious.Repository import *
|
||||
from Furious.Application.TrayIcon import *
|
||||
from Furious.Window.LogWindow import *
|
||||
from Furious.Window.MainWindow import *
|
||||
|
||||
from PySide6 import QtCore
|
||||
from PySide6.QtGui import *
|
||||
@@ -168,11 +169,11 @@ class ApplicationThemeDetector(QtCore.QObject):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
|
||||
class Application(ApplicationFactory, SingletonApplication):
|
||||
class DesktopApplication(ApplicationRunner, SingletonApplication):
|
||||
"""Represent application."""
|
||||
|
||||
def __init__(self, argv):
|
||||
"""Initialize the Application."""
|
||||
"""Initialize the desktop application."""
|
||||
super().__init__(argv)
|
||||
|
||||
self.setApplicationName(APPLICATION_NAME)
|
||||
@@ -229,7 +230,7 @@ class Application(ApplicationFactory, SingletonApplication):
|
||||
datastr = str(data)
|
||||
|
||||
if datastr == AppBuiltinCommand.Empty.value:
|
||||
if isinstance(self.systemTray, SystemTrayIcon):
|
||||
if isinstance(self.systemTray, TrayIcon):
|
||||
logger.info('attempting to start multiple instance. Show tray message')
|
||||
|
||||
self.systemTray.showMessage(_('Already started'))
|
||||
@@ -246,17 +247,17 @@ class Application(ApplicationFactory, SingletonApplication):
|
||||
|
||||
def configureLogging(self):
|
||||
"""Configure logging."""
|
||||
self.logViewerWindowSelf = LogViewerWindow(
|
||||
self.logViewerWindowSelf = LogWindow(
|
||||
tabTitle=_('Furious Log'),
|
||||
fontFamily=self.customFontName,
|
||||
pointSizeSettingsName='LogViewerWidgetPointSizeSelf',
|
||||
)
|
||||
self.logViewerWindowCore = LogViewerWindow(
|
||||
self.logViewerWindowCore = LogWindow(
|
||||
tabTitle=_('Core Log'),
|
||||
fontFamily=self.customFontName,
|
||||
pointSizeSettingsName='LogViewerWidgetPointSizeCore',
|
||||
)
|
||||
self.logViewerWindowTun_ = LogViewerWindow(
|
||||
self.logViewerWindowTun_ = LogWindow(
|
||||
tabTitle=_('Tun2socks Log'),
|
||||
fontFamily=self.customFontName,
|
||||
pointSizeSettingsName='LogViewerWidgetPointSizeTun_',
|
||||
@@ -298,7 +299,7 @@ class Application(ApplicationFactory, SingletonApplication):
|
||||
@staticmethod
|
||||
def addEnviron():
|
||||
"""Add environ."""
|
||||
pluginRegistry = getPluginRegistry()
|
||||
pluginRegistry = initializePluginRegistry(OFFICIAL_PLUGIN_TYPES)
|
||||
configureEditorLogMetadata(
|
||||
lambda: (*pluginRegistry.coreVersions(), Tun2socks.version()),
|
||||
pluginRegistry.logTimestampPatterns,
|
||||
@@ -321,7 +322,7 @@ class Application(ApplicationFactory, SingletonApplication):
|
||||
|
||||
def isSystemTrayConnected(self):
|
||||
"""Return whether system tray connected."""
|
||||
if isinstance(self.systemTray, SystemTrayIcon):
|
||||
if isinstance(self.systemTray, TrayIcon):
|
||||
return self.systemTray.ConnectAction.isConnected()
|
||||
else:
|
||||
return False
|
||||
@@ -467,11 +468,11 @@ class Application(ApplicationFactory, SingletonApplication):
|
||||
# sys.exit(None) in multiprocessing will produce
|
||||
# exitcode 1 in some Python version, which is
|
||||
# not what we want.
|
||||
return ApplicationFactory.ExitCode.ExitSuccess.value
|
||||
return ApplicationRunner.ExitCode.ExitSuccess.value
|
||||
|
||||
if not SystemTrayIcon.isSystemTrayAvailable():
|
||||
if not TrayIcon.isSystemTrayAvailable():
|
||||
raise SystemTrayUnavailable(
|
||||
'SystemTrayIcon is not available on this platform'
|
||||
'TrayIcon is not available on this platform'
|
||||
)
|
||||
|
||||
self.addEnviron()
|
||||
@@ -560,9 +561,9 @@ class Application(ApplicationFactory, SingletonApplication):
|
||||
# Mandatory
|
||||
self.setQuitOnLastWindowClosed(False)
|
||||
|
||||
self.aboutToQuit.connect(Application.cleanup)
|
||||
self.aboutToQuit.connect(DesktopApplication.cleanup)
|
||||
|
||||
Win32Session.set(Application.cleanup)
|
||||
Win32Session.set(DesktopApplication.cleanup)
|
||||
Win32Session.run()
|
||||
|
||||
if AppSettings.get('SystemProxyMode') == AppBuiltinProxyMode.Auto.value:
|
||||
@@ -570,8 +571,8 @@ class Application(ApplicationFactory, SingletonApplication):
|
||||
SystemProxy.off()
|
||||
SystemProxy.daemonOn_()
|
||||
|
||||
self.mainWindow = AppMainWindow()
|
||||
self.systemTray = SystemTrayIcon()
|
||||
self.mainWindow = MainWindow()
|
||||
self.systemTray = TrayIcon()
|
||||
|
||||
if PLATFORM == 'Darwin':
|
||||
if AppSettings.isStateON_('HideDockIcon'):
|
||||
@@ -601,10 +602,10 @@ class Application(ApplicationFactory, SingletonApplication):
|
||||
|
||||
return self.exec()
|
||||
except SystemTrayUnavailable:
|
||||
return ApplicationFactory.ExitCode.PlatformNotSupported.value
|
||||
return ApplicationRunner.ExitCode.PlatformNotSupported.value
|
||||
except Exception:
|
||||
# Any non-exit exceptions
|
||||
|
||||
traceback.print_exc()
|
||||
|
||||
return ApplicationFactory.ExitCode.UnknownException.value
|
||||
return ApplicationRunner.ExitCode.UnknownException.value
|
||||
@@ -22,7 +22,7 @@ from __future__ import annotations
|
||||
from Furious.Frozenlib import *
|
||||
from Furious.Qt import *
|
||||
from Furious.Qt import gettext as _
|
||||
from Furious.TrayActions import *
|
||||
from Furious.Actions import *
|
||||
|
||||
from PySide6 import QtCore
|
||||
from PySide6.QtWidgets import QSystemTrayIcon
|
||||
@@ -32,7 +32,7 @@ import platform
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
__all__ = ['SystemTrayIcon']
|
||||
__all__ = ['TrayIcon']
|
||||
|
||||
_MACOS_DISCONNECTED_MONOCHROME_OPACITY = 0.55
|
||||
|
||||
@@ -41,7 +41,7 @@ _TRANSLATABLE_ADMIN = [
|
||||
]
|
||||
|
||||
|
||||
class SystemTrayIcon(
|
||||
class TrayIcon(
|
||||
Mixins.QTranslatable,
|
||||
Mixins.ConnectionAware,
|
||||
Mixins.ThemeAware,
|
||||
@@ -50,7 +50,7 @@ class SystemTrayIcon(
|
||||
"""Represent system tray icon."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the SystemTrayIcon."""
|
||||
"""Initialize the tray icon."""
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
actions = [
|
||||
@@ -71,7 +71,7 @@ class SystemTrayIcon(
|
||||
self._dynamicMenuRefs = []
|
||||
|
||||
# Some old version PySide6 does not have setMenu method
|
||||
# for QAction. Protect it. Currently only used in SystemTrayIcon
|
||||
# for QAction. Protect it. Currently only used in TrayIcon
|
||||
if hasattr(AppQAction, 'setMenu'):
|
||||
logger.info('contextMenu uses setMenu implementation')
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .Application import Application
|
||||
from .SystemTrayIcon import SystemTrayIcon
|
||||
from .DesktopApplication import DesktopApplication
|
||||
from .TrayIcon import TrayIcon
|
||||
|
||||
__all__ = ['Application', 'SystemTrayIcon']
|
||||
__all__ = ['DesktopApplication', 'TrayIcon']
|
||||
|
||||
@@ -21,8 +21,8 @@ from __future__ import annotations
|
||||
|
||||
from Furious.Frozenlib import *
|
||||
from Furious.Interface import *
|
||||
from Furious.Library.Configuration import ConfigFactory
|
||||
from Furious.Library.Encoder import *
|
||||
from Furious.Domain.Configuration import ConfigFactory
|
||||
from Furious.Domain.Encoding import *
|
||||
|
||||
from typing import Union, Tuple
|
||||
|
||||
+5
-5
@@ -21,7 +21,7 @@ from __future__ import annotations
|
||||
|
||||
from Furious.Frozenlib import *
|
||||
from Furious.Interface import *
|
||||
from Furious.Library import ConfigFactory
|
||||
from Furious.Domain import ConfigFactory
|
||||
from Furious.Qt import *
|
||||
from Furious.Qt import gettext as _
|
||||
|
||||
@@ -32,7 +32,7 @@ from PySide6.QtWidgets import *
|
||||
import logging
|
||||
import functools
|
||||
|
||||
__all__ = ['GuiHysteria1']
|
||||
__all__ = ['Hysteria1Editor']
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -343,7 +343,7 @@ class GuiHy1GroupBoxTLS(GuiEditorWidgetQGroupBox):
|
||||
]
|
||||
|
||||
|
||||
class GuiHy1GroupBoxOther(GuiEditorItemFactory, AppQGroupBox):
|
||||
class GuiHy1GroupBoxOther(EditorBinding, AppQGroupBox):
|
||||
"""Represent GUI hy1 group box other."""
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
@@ -366,11 +366,11 @@ class GuiHy1GroupBoxOther(GuiEditorItemFactory, AppQGroupBox):
|
||||
pass
|
||||
|
||||
|
||||
class GuiHysteria1(GuiEditorWidgetQDialog):
|
||||
class Hysteria1Editor(GuiEditorWidgetQDialog):
|
||||
"""Represent GUI hysteria1."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the GuiHysteria1."""
|
||||
"""Initialize the Hysteria 1 configuration editor."""
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.setTabText(Protocol.Hysteria1.value)
|
||||
@@ -22,9 +22,9 @@ from __future__ import annotations
|
||||
from Furious.Frozenlib import *
|
||||
from Furious.Qt.DynamicTranslate import gettext as _
|
||||
from Furious.Plugins.API import *
|
||||
from Furious.Plugins.Official.Configuration import *
|
||||
from Furious.Backends.Configuration import *
|
||||
|
||||
from .Core import *
|
||||
from .Process import *
|
||||
|
||||
import copy
|
||||
import logging
|
||||
@@ -94,9 +94,9 @@ class Hysteria1Plugin(FuriousPlugin):
|
||||
def createEditorForProtocol(self, protocol, parent=None, **kwargs):
|
||||
"""Create the Hysteria 1 editor."""
|
||||
# Plugin discovery can occur while the Furious.Qt package is initializing.
|
||||
from .GuiHysteria1 import GuiHysteria1
|
||||
from .Editor import Hysteria1Editor
|
||||
|
||||
return GuiHysteria1(parent=parent, **kwargs)
|
||||
return Hysteria1Editor(parent=parent, **kwargs)
|
||||
|
||||
def routingOptions(self, config=None):
|
||||
"""Return the routing modes supported by Hysteria 1."""
|
||||
+6
-6
@@ -21,7 +21,7 @@ from __future__ import annotations
|
||||
|
||||
from Furious.Frozenlib import *
|
||||
from Furious.Interface import *
|
||||
from Furious.Library import ConfigFactory
|
||||
from Furious.Domain import ConfigFactory
|
||||
from Furious.Qt import *
|
||||
from Furious.Qt import gettext as _
|
||||
|
||||
@@ -32,7 +32,7 @@ from PySide6.QtWidgets import *
|
||||
import logging
|
||||
import functools
|
||||
|
||||
__all__ = ['GuiHysteria2']
|
||||
__all__ = ['Hysteria2Editor']
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -699,7 +699,7 @@ class GuiHy2GroupBoxProxy(GuiEditorWidgetQGroupBox):
|
||||
]
|
||||
|
||||
|
||||
class GuiHy2GroupBoxObfs(GuiEditorItemFactory, AppQGroupBox):
|
||||
class GuiHy2GroupBoxObfs(EditorBinding, AppQGroupBox):
|
||||
"""Represent GUI hy2 group box obfs."""
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
@@ -848,7 +848,7 @@ class GuiHy2ProjectWebsiteURL(AppQLabel):
|
||||
self.setWebsiteURL()
|
||||
|
||||
|
||||
class GuiHy2GroupBoxOther(GuiEditorItemFactory, AppQGroupBox):
|
||||
class GuiHy2GroupBoxOther(EditorBinding, AppQGroupBox):
|
||||
"""Represent GUI hy2 group box other."""
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
@@ -871,11 +871,11 @@ class GuiHy2GroupBoxOther(GuiEditorItemFactory, AppQGroupBox):
|
||||
pass
|
||||
|
||||
|
||||
class GuiHysteria2(GuiEditorWidgetQDialog):
|
||||
class Hysteria2Editor(GuiEditorWidgetQDialog):
|
||||
"""Represent GUI hysteria2."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the GuiHysteria2."""
|
||||
"""Initialize the Hysteria 2 configuration editor."""
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.setTabText(Protocol.Hysteria2.value)
|
||||
@@ -22,9 +22,9 @@ from __future__ import annotations
|
||||
from Furious.Frozenlib import *
|
||||
from Furious.Qt.DynamicTranslate import gettext as _
|
||||
from Furious.Plugins.API import *
|
||||
from Furious.Plugins.Official.Configuration import *
|
||||
from Furious.Backends.Configuration import *
|
||||
|
||||
from .Core import Hysteria2
|
||||
from .Process import Hysteria2
|
||||
from .TUN import *
|
||||
|
||||
import copy
|
||||
@@ -103,9 +103,9 @@ class Hysteria2Plugin(FuriousPlugin):
|
||||
def createEditorForProtocol(self, protocol, parent=None, **kwargs):
|
||||
"""Create the Hysteria 2 editor."""
|
||||
# Plugin discovery can occur while the Furious.Qt package is initializing.
|
||||
from .GuiHysteria2 import GuiHysteria2
|
||||
from .Editor import Hysteria2Editor
|
||||
|
||||
return GuiHysteria2(parent=parent, **kwargs)
|
||||
return Hysteria2Editor(parent=parent, **kwargs)
|
||||
|
||||
def createManagementActions(self, parent=None, **kwargs):
|
||||
"""Create Hysteria 2 native TUN management actions."""
|
||||
@@ -115,7 +115,7 @@ class Hysteria2Plugin(FuriousPlugin):
|
||||
from Furious.Qt import AppQAction, showMBoxNewChangesNextTime
|
||||
from Furious.Qt import gettext as _
|
||||
|
||||
from .GuiTUNSettings import GuiHysteria2TUNSettings
|
||||
from .TunSettingsDialog import Hysteria2TunSettingsDialog
|
||||
|
||||
useHysteria2TUNAction = AppQAction(
|
||||
_('Use Hysteria2 TUN'),
|
||||
@@ -136,7 +136,7 @@ class Hysteria2Plugin(FuriousPlugin):
|
||||
useHysteria2TUNAction,
|
||||
AppQAction(
|
||||
_('Customize Hysteria2 TUN Settings...'),
|
||||
callback=lambda: GuiHysteria2TUNSettings(
|
||||
callback=lambda: Hysteria2TunSettingsDialog(
|
||||
parent=parent,
|
||||
isConnectionActive=lambda: isCoreActive(Hysteria2),
|
||||
).open(),
|
||||
@@ -146,7 +146,7 @@ class Hysteria2Plugin(FuriousPlugin):
|
||||
def prepareTUN(self, config) -> bool:
|
||||
"""Add Hysteria 2 native TUN mode when enabled and safe to route."""
|
||||
if not isHysteria2TUNEnabled():
|
||||
# Work on CoreManager's connection copy so a stored native TUN block
|
||||
# Work on ConnectionManager's copy so a stored native TUN block
|
||||
# cannot run alongside the external tun2socks implementation.
|
||||
config.pop('tun', None)
|
||||
|
||||
@@ -154,7 +154,7 @@ class Hysteria2Plugin(FuriousPlugin):
|
||||
|
||||
if PLATFORM == 'Linux' and not SystemRuntime.isAdmin():
|
||||
# Native Hysteria 2 creates the interface and routing table in its
|
||||
# own process, so it cannot use CoreManager's privileged helper.
|
||||
# own process, so it cannot use ConnectionManager's privileged helper.
|
||||
# Keep the existing external tun2socks path available instead.
|
||||
config.pop('tun', None)
|
||||
|
||||
+2
-2
@@ -34,7 +34,7 @@ import copy
|
||||
import logging
|
||||
import functools
|
||||
|
||||
__all__ = ['GuiHysteria2TUNSettings']
|
||||
__all__ = ['Hysteria2TunSettingsDialog']
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -262,7 +262,7 @@ class Hysteria2TUNDocumentationURL(AppQLabel):
|
||||
self.setWebsiteURL()
|
||||
|
||||
|
||||
class GuiHysteria2TUNSettings(GuiEditorWidgetQDialog):
|
||||
class Hysteria2TunSettingsDialog(GuiEditorWidgetQDialog):
|
||||
"""Edit and persist Hysteria 2 native TUN settings."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
+3
-3
@@ -33,7 +33,7 @@ import logging
|
||||
import datetime
|
||||
import functools
|
||||
|
||||
__all__ = ['XrayAssetViewerQListWidget']
|
||||
__all__ = ['XrayAssetListWidget']
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -59,11 +59,11 @@ class MBoxAssetExists(AppQMessageBox):
|
||||
self.moveToCenter()
|
||||
|
||||
|
||||
class XrayAssetViewerQListWidget(Mixins.ThemeAware, AppQListWidget):
|
||||
class XrayAssetListWidget(Mixins.ThemeAware, AppQListWidget):
|
||||
"""Provide the Xray asset viewer Qt list widget."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the XrayAssetViewerQListWidget."""
|
||||
"""Initialize the Xray asset list widget."""
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.setAlternatingRowColors(True)
|
||||
+5
-5
@@ -23,7 +23,7 @@ from Furious.Frozenlib import *
|
||||
from Furious.Qt import *
|
||||
from Furious.Qt import gettext as _
|
||||
|
||||
from .XrayAssetViewerQListWidget import *
|
||||
from .AssetListWidget import *
|
||||
|
||||
from PySide6 import QtCore
|
||||
from PySide6.QtGui import *
|
||||
@@ -31,21 +31,21 @@ from PySide6.QtWidgets import *
|
||||
|
||||
import logging
|
||||
|
||||
__all__ = ['XrayAssetViewerWindow']
|
||||
__all__ = ['XrayAssetWindow']
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class XrayAssetViewerWindow(AppQMainWindow):
|
||||
class XrayAssetWindow(AppQMainWindow):
|
||||
"""Present the Xray asset viewer window."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the XrayAssetViewerWindow."""
|
||||
"""Initialize the Xray asset window."""
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.setWindowTitle(_('Xray-core Asset File'))
|
||||
|
||||
self.xrayAssetViewerWidget = XrayAssetViewerQListWidget(parent=self)
|
||||
self.xrayAssetViewerWidget = XrayAssetListWidget(parent=self)
|
||||
self.setCentralWidget(self.xrayAssetViewerWidget)
|
||||
|
||||
if versionToValue(PYSIDE6_VERSION) <= versionToValue('6.1.3'):
|
||||
@@ -22,11 +22,11 @@ from __future__ import annotations
|
||||
from Furious.Frozenlib import *
|
||||
from Furious.Qt.DynamicTranslate import gettext as _
|
||||
from Furious.Core import *
|
||||
from Furious.Library import *
|
||||
from Furious.Repository import *
|
||||
from Furious.Plugins.API import *
|
||||
from Furious.Plugins.Official.Configuration import *
|
||||
from Furious.Backends.Configuration import *
|
||||
|
||||
from .Core import *
|
||||
from .Process import *
|
||||
from .Routing import *
|
||||
from .TUN import *
|
||||
|
||||
@@ -161,18 +161,18 @@ class XrayPlugin(FuriousPlugin):
|
||||
def createEditorForProtocol(self, protocol, parent=None, **kwargs):
|
||||
"""Create the Xray editor matching a protocol identifier."""
|
||||
# Plugin discovery can occur while the Furious.Qt package is initializing.
|
||||
from .GuiShadowsocks import GuiShadowsocks
|
||||
from .GuiSocks import GuiSocks
|
||||
from .GuiTrojan import GuiTrojan
|
||||
from .GuiVLESS import GuiVLESS
|
||||
from .GuiVMess import GuiVMess
|
||||
from .ShadowsocksEditor import ShadowsocksEditor
|
||||
from .SocksEditor import SocksEditor
|
||||
from .TrojanEditor import TrojanEditor
|
||||
from .VlessEditor import VlessEditor
|
||||
from .VmessEditor import VmessEditor
|
||||
|
||||
editors = {
|
||||
'vmess': GuiVMess,
|
||||
'vless': GuiVLESS,
|
||||
'shadowsocks': GuiShadowsocks,
|
||||
'socks': GuiSocks,
|
||||
'trojan': GuiTrojan,
|
||||
'vmess': VmessEditor,
|
||||
'vless': VlessEditor,
|
||||
'shadowsocks': ShadowsocksEditor,
|
||||
'socks': SocksEditor,
|
||||
'trojan': TrojanEditor,
|
||||
}
|
||||
editorType = editors.get(_protocolId(protocol))
|
||||
|
||||
@@ -195,12 +195,12 @@ class XrayPlugin(FuriousPlugin):
|
||||
)
|
||||
from Furious.Qt import gettext as _
|
||||
|
||||
from .GuiTUNSettings import GuiXrayTUNSettings
|
||||
from .UserRoutingWindow import UserRoutingWindow
|
||||
from .XrayAssetViewerWindow import XrayAssetViewerWindow
|
||||
from .AssetWindow import XrayAssetWindow
|
||||
from .RoutingWindow import XrayRoutingWindow
|
||||
from .TunSettingsDialog import XrayTunSettingsDialog
|
||||
|
||||
routingEditor = UserRoutingWindow(parent=parent, **kwargs)
|
||||
assetViewer = XrayAssetViewerWindow(parent=parent)
|
||||
routingEditor = XrayRoutingWindow(parent=parent, **kwargs)
|
||||
assetViewer = XrayAssetWindow(parent=parent)
|
||||
|
||||
def showRoutingDialog():
|
||||
"""Restore and foreground the persistent routing editor window."""
|
||||
@@ -237,7 +237,7 @@ class XrayPlugin(FuriousPlugin):
|
||||
useXrayTUNAction,
|
||||
AppQAction(
|
||||
_('Customize Xray-core TUN Settings...'),
|
||||
callback=lambda: GuiXrayTUNSettings(
|
||||
callback=lambda: XrayTunSettingsDialog(
|
||||
parent=parent,
|
||||
isConnectionActive=lambda: isCoreActive(XrayCore),
|
||||
).open(),
|
||||
@@ -443,7 +443,7 @@ class XrayPlugin(FuriousPlugin):
|
||||
return
|
||||
|
||||
# The download manager is Qt-based and is not needed until this hook runs.
|
||||
from .XrayAssetDownloadManager import XrayAssetDownloadManager
|
||||
from .AssetDownloadManager import XrayAssetDownloadManager
|
||||
|
||||
try:
|
||||
assetDownloadManager = self._assetDownloadManager
|
||||
@@ -21,7 +21,7 @@ from __future__ import annotations
|
||||
|
||||
from Furious.Frozenlib import *
|
||||
from Furious.Interface import *
|
||||
from Furious.Library import *
|
||||
from Furious.Domain import *
|
||||
from Furious.Core import *
|
||||
|
||||
from enum import Enum
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from Furious.Library import *
|
||||
from Furious.Repository import *
|
||||
|
||||
__all__ = ['cleanRoutingRule', 'customRoutingObjectFromSettings']
|
||||
|
||||
+8
-7
@@ -20,7 +20,8 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from Furious.Frozenlib import *
|
||||
from Furious.Library import *
|
||||
from Furious.Domain import *
|
||||
from Furious.Repository import *
|
||||
from Furious.Qt import *
|
||||
from Furious.Qt import gettext as _
|
||||
|
||||
@@ -35,7 +36,7 @@ import functools
|
||||
|
||||
from .Routing import cleanRoutingRule
|
||||
|
||||
__all__ = ['UserRoutingWindow']
|
||||
__all__ = ['XrayRoutingWindow']
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -1187,13 +1188,13 @@ class UserRoutingTableView(Mixins.QTranslatable, AppQTableView):
|
||||
dialog.open()
|
||||
|
||||
|
||||
class UserRoutingWindow(AppQMainWindow):
|
||||
class XrayRoutingWindow(AppQMainWindow):
|
||||
"""Present the user routing window."""
|
||||
|
||||
DEFAULT_WINDOW_SIZE = QtCore.QSize(980, 560)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the UserRoutingWindow."""
|
||||
"""Initialize the Xray routing editor window."""
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.setWindowTitle(_('Edit Routing'))
|
||||
@@ -1225,17 +1226,17 @@ class UserRoutingWindow(AppQMainWindow):
|
||||
def setWidthAndHeight(self):
|
||||
"""Apply the default size for the user routing window."""
|
||||
if AppSettings.get('UserRoutingWindowGeometry') is None:
|
||||
self.resize(UserRoutingWindow.DEFAULT_WINDOW_SIZE)
|
||||
self.resize(XrayRoutingWindow.DEFAULT_WINDOW_SIZE)
|
||||
else:
|
||||
if PLATFORM == 'Darwin':
|
||||
self.resize(UserRoutingWindow.DEFAULT_WINDOW_SIZE)
|
||||
self.resize(XrayRoutingWindow.DEFAULT_WINDOW_SIZE)
|
||||
else:
|
||||
try:
|
||||
self.restoreGeometry(AppSettings.get('UserRoutingWindowGeometry'))
|
||||
except Exception:
|
||||
# Any non-exit exceptions
|
||||
|
||||
self.resize(UserRoutingWindow.DEFAULT_WINDOW_SIZE)
|
||||
self.resize(XrayRoutingWindow.DEFAULT_WINDOW_SIZE)
|
||||
|
||||
try:
|
||||
self.restoreState(AppSettings.get('UserRoutingWindowState'))
|
||||
+7
-7
@@ -21,16 +21,16 @@ from __future__ import annotations
|
||||
|
||||
from Furious.Frozenlib import *
|
||||
from Furious.Interface import *
|
||||
from Furious.Library import *
|
||||
from Furious.Domain import *
|
||||
from Furious.Qt import *
|
||||
from Furious.Qt import gettext as _
|
||||
from Furious.Plugins.Official.Configuration import *
|
||||
from Furious.Plugins.Official.Xray.GuiVTransport import *
|
||||
from Furious.Plugins.Official.Xray.GuiVTLS import *
|
||||
from Furious.Backends.Configuration import *
|
||||
from Furious.Backends.Xray.TlsEditor import *
|
||||
from Furious.Backends.Xray.TransportEditor import *
|
||||
|
||||
import functools
|
||||
|
||||
__all__ = ['GuiShadowsocks']
|
||||
__all__ = ['ShadowsocksEditor']
|
||||
|
||||
getProxyOutboundServer = functools.partial(
|
||||
ConfigXray.getProxyOutboundServer,
|
||||
@@ -214,11 +214,11 @@ class GuiSSGroupBoxProxy(GuiEditorWidgetQGroupBox):
|
||||
]
|
||||
|
||||
|
||||
class GuiShadowsocks(GuiEditorWidgetQDialog):
|
||||
class ShadowsocksEditor(GuiEditorWidgetQDialog):
|
||||
"""Represent GUI shadowsocks."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the GuiShadowsocks."""
|
||||
"""Initialize the Shadowsocks configuration editor."""
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.setTabText(Protocol.Shadowsocks.value)
|
||||
@@ -21,16 +21,16 @@ from __future__ import annotations
|
||||
|
||||
from Furious.Frozenlib import *
|
||||
from Furious.Interface import *
|
||||
from Furious.Library import *
|
||||
from Furious.Domain import *
|
||||
from Furious.Qt import *
|
||||
from Furious.Qt import gettext as _
|
||||
from Furious.Plugins.Official.Configuration import *
|
||||
from Furious.Plugins.Official.Xray.GuiVTransport import *
|
||||
from Furious.Plugins.Official.Xray.GuiVTLS import *
|
||||
from Furious.Backends.Configuration import *
|
||||
from Furious.Backends.Xray.TlsEditor import *
|
||||
from Furious.Backends.Xray.TransportEditor import *
|
||||
|
||||
import functools
|
||||
|
||||
__all__ = ['GuiSocks']
|
||||
__all__ = ['SocksEditor']
|
||||
|
||||
getProxyOutboundServer = functools.partial(
|
||||
ConfigXray.getProxyOutboundServer,
|
||||
@@ -157,11 +157,11 @@ class GuiSocksGroupBoxProxy(GuiEditorWidgetQGroupBox):
|
||||
]
|
||||
|
||||
|
||||
class GuiSocks(GuiEditorWidgetQDialog):
|
||||
class SocksEditor(GuiEditorWidgetQDialog):
|
||||
"""Represent GUI SOCKS."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the GuiSocks."""
|
||||
"""Initialize the SOCKS configuration editor."""
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.setTabText(Protocol.Socks.value)
|
||||
@@ -20,9 +20,9 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from Furious.Interface import *
|
||||
from Furious.Library import *
|
||||
from Furious.Domain import *
|
||||
from Furious.Qt import *
|
||||
from Furious.Plugins.Official.Configuration import *
|
||||
from Furious.Backends.Configuration import *
|
||||
|
||||
from PySide6 import QtCore
|
||||
from PySide6.QtWidgets import *
|
||||
@@ -738,7 +738,7 @@ class GuiVTLSPageStackedWidget(QStackedWidget):
|
||||
page.connectActivated(func)
|
||||
|
||||
|
||||
class GuiVTLSQGroupBox(GuiEditorItemFactory, AppQGroupBox):
|
||||
class GuiVTLSQGroupBox(EditorBinding, AppQGroupBox):
|
||||
"""Group the GUI vtlsq editor controls."""
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
+3
-3
@@ -20,10 +20,10 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from Furious.Interface import *
|
||||
from Furious.Library import *
|
||||
from Furious.Domain import *
|
||||
from Furious.Qt import *
|
||||
from Furious.Qt import gettext as _
|
||||
from Furious.Plugins.Official.Configuration import *
|
||||
from Furious.Backends.Configuration import *
|
||||
|
||||
from PySide6.QtWidgets import *
|
||||
|
||||
@@ -1923,7 +1923,7 @@ class GuiVTransportPageStackedWidget(QStackedWidget):
|
||||
page.connectActivated(func)
|
||||
|
||||
|
||||
class GuiVTransportQGroupBox(GuiEditorItemFactory, AppQGroupBox):
|
||||
class GuiVTransportQGroupBox(EditorBinding, AppQGroupBox):
|
||||
"""Group the GUI v transport q editor controls."""
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
@@ -21,16 +21,16 @@ from __future__ import annotations
|
||||
|
||||
from Furious.Frozenlib import *
|
||||
from Furious.Interface import *
|
||||
from Furious.Library import *
|
||||
from Furious.Domain import *
|
||||
from Furious.Qt import *
|
||||
from Furious.Qt import gettext as _
|
||||
from Furious.Plugins.Official.Configuration import *
|
||||
from Furious.Plugins.Official.Xray.GuiVTransport import *
|
||||
from Furious.Plugins.Official.Xray.GuiVTLS import *
|
||||
from Furious.Backends.Configuration import *
|
||||
from Furious.Backends.Xray.TlsEditor import *
|
||||
from Furious.Backends.Xray.TransportEditor import *
|
||||
|
||||
import functools
|
||||
|
||||
__all__ = ['GuiTrojan']
|
||||
__all__ = ['TrojanEditor']
|
||||
|
||||
getProxyOutboundServer = functools.partial(
|
||||
ConfigXray.getProxyOutboundServer,
|
||||
@@ -158,11 +158,11 @@ class GuiTrojanGroupBoxProxy(GuiEditorWidgetQGroupBox):
|
||||
]
|
||||
|
||||
|
||||
class GuiTrojan(GuiEditorWidgetQDialog):
|
||||
class TrojanEditor(GuiEditorWidgetQDialog):
|
||||
"""Represent GUI trojan."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the GuiTrojan."""
|
||||
"""Initialize the Trojan configuration editor."""
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.setTabText(Protocol.Trojan.value)
|
||||
+2
-2
@@ -34,7 +34,7 @@ import copy
|
||||
import logging
|
||||
import functools
|
||||
|
||||
__all__ = ['GuiXrayTUNSettings']
|
||||
__all__ = ['XrayTunSettingsDialog']
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -227,7 +227,7 @@ class GuiXrayTUNSettingsGroupBoxNetwork(GuiEditorWidgetQGroupBox):
|
||||
]
|
||||
|
||||
|
||||
class GuiXrayTUNSettings(GuiEditorWidgetQDialog):
|
||||
class XrayTunSettingsDialog(GuiEditorWidgetQDialog):
|
||||
"""Edit and persist Xray-core native TUN settings."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
@@ -21,19 +21,19 @@ from __future__ import annotations
|
||||
|
||||
from Furious.Frozenlib import *
|
||||
from Furious.Interface import *
|
||||
from Furious.Library import *
|
||||
from Furious.Domain import *
|
||||
from Furious.Qt import *
|
||||
from Furious.Qt import gettext as _
|
||||
from Furious.Plugins.Official.Configuration import *
|
||||
from Furious.Plugins.Official.Xray.GuiVTransport import *
|
||||
from Furious.Plugins.Official.Xray.GuiVTLS import *
|
||||
from Furious.Backends.Configuration import *
|
||||
from Furious.Backends.Xray.TlsEditor import *
|
||||
from Furious.Backends.Xray.TransportEditor import *
|
||||
|
||||
from PySide6.QtWidgets import *
|
||||
|
||||
import uuid
|
||||
import functools
|
||||
|
||||
__all__ = ['GuiVLESS']
|
||||
__all__ = ['VlessEditor']
|
||||
|
||||
getProxyOutboundServer = functools.partial(
|
||||
ConfigXray.getProxyOutboundServer,
|
||||
@@ -357,11 +357,11 @@ class GuiVLESSGroupBoxProxy(GuiEditorWidgetQGroupBox):
|
||||
]
|
||||
|
||||
|
||||
class GuiVLESS(GuiEditorWidgetQDialog):
|
||||
class VlessEditor(GuiEditorWidgetQDialog):
|
||||
"""Represent GUI VLESS."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the GuiVLESS."""
|
||||
"""Initialize the VLESS configuration editor."""
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.setTabText(Protocol.VLESS.value)
|
||||
@@ -21,19 +21,19 @@ from __future__ import annotations
|
||||
|
||||
from Furious.Frozenlib import *
|
||||
from Furious.Interface import *
|
||||
from Furious.Library import *
|
||||
from Furious.Domain import *
|
||||
from Furious.Qt import *
|
||||
from Furious.Qt import gettext as _
|
||||
from Furious.Plugins.Official.Configuration import *
|
||||
from Furious.Plugins.Official.Xray.GuiVTransport import *
|
||||
from Furious.Plugins.Official.Xray.GuiVTLS import *
|
||||
from Furious.Backends.Configuration import *
|
||||
from Furious.Backends.Xray.TlsEditor import *
|
||||
from Furious.Backends.Xray.TransportEditor import *
|
||||
|
||||
from PySide6.QtWidgets import *
|
||||
|
||||
import uuid
|
||||
import functools
|
||||
|
||||
__all__ = ['GuiVMess']
|
||||
__all__ = ['VmessEditor']
|
||||
|
||||
getProxyOutboundServer = functools.partial(
|
||||
ConfigXray.getProxyOutboundServer,
|
||||
@@ -366,11 +366,11 @@ class GuiVMessGroupBoxProxy(GuiEditorWidgetQGroupBox):
|
||||
]
|
||||
|
||||
|
||||
class GuiVMess(GuiEditorWidgetQDialog):
|
||||
class VmessEditor(GuiEditorWidgetQDialog):
|
||||
"""Represent GUI v mess."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the GuiVMess."""
|
||||
"""Initialize the VMess configuration editor."""
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.setTabText(Protocol.VMess.value)
|
||||
@@ -15,7 +15,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
"""Register the core plugins maintained with Furious itself."""
|
||||
"""Expose the official proxy backend implementations bundled with Furious."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -208,7 +208,7 @@ class MsgQueue(multiprocessing.queues.Queue):
|
||||
self.startTimer()
|
||||
|
||||
|
||||
class CoreProcessMonitor(CoreProcessFactory, ABC):
|
||||
class CoreProcessMonitor(CoreProcess, ABC):
|
||||
"""Track the state and lifetime of a proxy-core child process."""
|
||||
|
||||
StopJoinTimeout = 3
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from Furious.Interface.UserServersTableItem import UserServersTableItem
|
||||
from Furious.Interface.Server import ServerTableItem
|
||||
|
||||
from typing import Union
|
||||
|
||||
@@ -39,7 +39,7 @@ __all__ = [
|
||||
]
|
||||
|
||||
|
||||
class ConfigFactory(UserServersTableItem, dict):
|
||||
class ConfigFactory(ServerTableItem, dict):
|
||||
"""
|
||||
ConfigurationFactory is how Furious sees the core config.
|
||||
|
||||
@@ -36,7 +36,7 @@ __all__ = [
|
||||
]
|
||||
|
||||
|
||||
class JSONEncoder(EncoderFactory):
|
||||
class JSONEncoder(Codec):
|
||||
"""Encode and decode data using JSON."""
|
||||
|
||||
@staticmethod
|
||||
@@ -52,7 +52,7 @@ class JSONEncoder(EncoderFactory):
|
||||
return json.loads(data, **kwargs)
|
||||
|
||||
|
||||
class UJSONEncoder(EncoderFactory):
|
||||
class UJSONEncoder(Codec):
|
||||
"""Encode and decode data using ujson."""
|
||||
|
||||
@staticmethod
|
||||
@@ -74,7 +74,7 @@ class UJSONEncoder(EncoderFactory):
|
||||
return ujson.loads(data, **kwargs)
|
||||
|
||||
|
||||
class Base64Encoder(EncoderFactory):
|
||||
class Base64Encoder(Codec):
|
||||
"""Encode and decode data using base64."""
|
||||
|
||||
@staticmethod
|
||||
@@ -90,7 +90,7 @@ class Base64Encoder(EncoderFactory):
|
||||
return base64.b64decode(data, validate=validate, **kwargs)
|
||||
|
||||
|
||||
class PyBase64Encoder(EncoderFactory):
|
||||
class PyBase64Encoder(Codec):
|
||||
"""Encode and decode data using py base64."""
|
||||
|
||||
@staticmethod
|
||||
@@ -15,7 +15,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
"""Expose domain configuration, encoding, and persistent storage services."""
|
||||
"""Expose configuration models, provider registration, and data encoding."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -28,8 +28,7 @@ from .Configuration import (
|
||||
configurationRegistry,
|
||||
registerConfigurationProvider,
|
||||
)
|
||||
from .Encoder import Base64Encoder, JSONEncoder, PyBase64Encoder, UJSONEncoder
|
||||
from .Storage import Storage
|
||||
from .Encoding import Base64Encoder, JSONEncoder, PyBase64Encoder, UJSONEncoder
|
||||
|
||||
__all__ = [
|
||||
'Base64Encoder',
|
||||
@@ -37,7 +36,6 @@ __all__ = [
|
||||
'ConfigurationRegistry',
|
||||
'JSONEncoder',
|
||||
'PyBase64Encoder',
|
||||
'Storage',
|
||||
'UJSONEncoder',
|
||||
'configFactoryBlank',
|
||||
'configFactoryFromAny',
|
||||
Vendored
+356
-356
File diff suppressed because it is too large
Load Diff
@@ -21,10 +21,10 @@ from __future__ import annotations
|
||||
|
||||
from enum import Enum
|
||||
|
||||
__all__ = ['ApplicationFactory']
|
||||
__all__ = ['ApplicationRunner']
|
||||
|
||||
|
||||
class ApplicationFactory:
|
||||
class ApplicationRunner:
|
||||
"""Define the lifecycle contract for the top-level application runner."""
|
||||
|
||||
class ExitCode(Enum):
|
||||
@@ -36,7 +36,7 @@ class ApplicationFactory:
|
||||
AssertionError = 63
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the ApplicationFactory."""
|
||||
"""Initialize the application runner."""
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def run(self):
|
||||
@@ -22,10 +22,10 @@ from __future__ import annotations
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Any
|
||||
|
||||
__all__ = ['EncoderFactory']
|
||||
__all__ = ['Codec']
|
||||
|
||||
|
||||
class EncoderFactory(ABC):
|
||||
class Codec(ABC):
|
||||
"""Define the interface and shared behavior for encoder objects."""
|
||||
|
||||
@abstractmethod
|
||||
@@ -21,14 +21,14 @@ from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
__all__ = ['GuiEditorItemFactory', 'GuiEditorItemWidgetContainer']
|
||||
__all__ = ['EditorBinding', 'EditorWidgetBinding']
|
||||
|
||||
|
||||
class GuiEditorItemFactory:
|
||||
class EditorBinding:
|
||||
"""Define the interface and shared behavior for GUI editor item objects."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the GuiEditorItemFactory."""
|
||||
"""Initialize the editor binding."""
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def inputToFactory(self, *args, **kwargs) -> Any:
|
||||
@@ -40,11 +40,11 @@ class GuiEditorItemFactory:
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class GuiEditorItemWidgetContainer(GuiEditorItemFactory):
|
||||
class EditorWidgetBinding(EditorBinding):
|
||||
"""Bind one or more editor widgets to configuration data."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the GuiEditorItemWidgetContainer."""
|
||||
"""Initialize the editor widget binding."""
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def widgets(self) -> Any:
|
||||
@@ -28,10 +28,10 @@ from typing import Callable, Union
|
||||
import ujson
|
||||
import functools
|
||||
|
||||
__all__ = ['CoreProcessFactory']
|
||||
__all__ = ['CoreProcess']
|
||||
|
||||
|
||||
class CoreProcessFactory(ABC):
|
||||
class CoreProcess(ABC):
|
||||
"""Define the interface and shared behavior for core process objects."""
|
||||
|
||||
class ExitCode(Enum):
|
||||
@@ -45,9 +45,9 @@ class CoreProcessFactory(ABC):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
exitCallback: Union[Callable[[CoreProcessFactory, int], None], None] = None,
|
||||
exitCallback: Union[Callable[[CoreProcess, int], None], None] = None,
|
||||
):
|
||||
"""Initialize the CoreProcessFactory."""
|
||||
"""Initialize the core process."""
|
||||
super().__init__()
|
||||
|
||||
self._exitCallback = exitCallback
|
||||
@@ -19,14 +19,14 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
__all__ = ['UserServersTableItem']
|
||||
__all__ = ['ServerTableItem']
|
||||
|
||||
|
||||
class UserServersTableItem:
|
||||
class ServerTableItem:
|
||||
"""Define the display fields required by a server-table row."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the UserServersTableItem."""
|
||||
"""Initialize the server table item."""
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
@property
|
||||
@@ -22,10 +22,10 @@ from __future__ import annotations
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Any
|
||||
|
||||
__all__ = ['StorageFactory']
|
||||
__all__ = ['StorageBackend']
|
||||
|
||||
|
||||
class StorageFactory(ABC):
|
||||
class StorageBackend(ABC):
|
||||
"""Define the interface and shared behavior for storage objects."""
|
||||
|
||||
@abstractmethod
|
||||
@@ -19,19 +19,19 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .ApplicationFactory import ApplicationFactory
|
||||
from .CoreProcessFactory import CoreProcessFactory
|
||||
from .EncoderFactory import EncoderFactory
|
||||
from .GuiEditorItemFactory import GuiEditorItemFactory, GuiEditorItemWidgetContainer
|
||||
from .StorageFactory import StorageFactory
|
||||
from .UserServersTableItem import UserServersTableItem
|
||||
from .Application import ApplicationRunner
|
||||
from .Codec import Codec
|
||||
from .Editor import EditorBinding, EditorWidgetBinding
|
||||
from .Process import CoreProcess
|
||||
from .Server import ServerTableItem
|
||||
from .Storage import StorageBackend
|
||||
|
||||
__all__ = [
|
||||
'ApplicationFactory',
|
||||
'CoreProcessFactory',
|
||||
'EncoderFactory',
|
||||
'GuiEditorItemFactory',
|
||||
'GuiEditorItemWidgetContainer',
|
||||
'StorageFactory',
|
||||
'UserServersTableItem',
|
||||
'ApplicationRunner',
|
||||
'Codec',
|
||||
'CoreProcess',
|
||||
'EditorBinding',
|
||||
'EditorWidgetBinding',
|
||||
'ServerTableItem',
|
||||
'StorageBackend',
|
||||
]
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from Furious.Library.Configuration import configurationRegistry
|
||||
from Furious.Domain.Configuration import configurationRegistry
|
||||
|
||||
from importlib import metadata
|
||||
|
||||
@@ -32,6 +32,7 @@ __all__ = [
|
||||
'PLUGIN_ENTRY_POINT_GROUP',
|
||||
'PluginRegistry',
|
||||
'getPluginRegistry',
|
||||
'initializePluginRegistry',
|
||||
'registerPlugin',
|
||||
]
|
||||
|
||||
@@ -160,6 +161,10 @@ class PluginRegistry:
|
||||
"""Return registered plugins in registration order."""
|
||||
return tuple(self._plugins.values())
|
||||
|
||||
def plugin(self, pluginId: str):
|
||||
"""Return the plugin registered with ``pluginId``, if any."""
|
||||
return self._plugins.get(pluginId)
|
||||
|
||||
def protocolDescriptors(self):
|
||||
"""Return contributed protocols in their requested menu order."""
|
||||
descriptors = list(
|
||||
@@ -443,29 +448,41 @@ _registryLock = threading.RLock()
|
||||
_registryInitialized = False
|
||||
|
||||
|
||||
def getPluginRegistry() -> PluginRegistry:
|
||||
"""Return the process-wide registry after lazy official/external discovery."""
|
||||
def initializePluginRegistry(pluginTypes=()) -> PluginRegistry:
|
||||
"""Initialize discovery and register host-provided plugin implementations."""
|
||||
global _registry, _registryInitialized
|
||||
|
||||
with _registryLock:
|
||||
if not _registryInitialized:
|
||||
# Importing official plugins is an intentional extension-loading
|
||||
# boundary. Keeping it here prevents package initialization from
|
||||
# eagerly importing GUI and core implementations.
|
||||
from .Official import OFFICIAL_PLUGIN_TYPES
|
||||
|
||||
registry = PluginRegistry(configurationRegistry)
|
||||
|
||||
for pluginType in OFFICIAL_PLUGIN_TYPES:
|
||||
for pluginType in pluginTypes:
|
||||
registry.register(pluginType())
|
||||
|
||||
registry.discover()
|
||||
_registry = registry
|
||||
_registryInitialized = True
|
||||
else:
|
||||
for pluginType in pluginTypes:
|
||||
plugin = pluginType()
|
||||
registered = _registry.plugin(plugin.pluginId)
|
||||
|
||||
if registered is None:
|
||||
_registry.register(plugin)
|
||||
elif not isinstance(registered, pluginType):
|
||||
raise ValueError(
|
||||
f'plugin {plugin.pluginId!r} is already registered by '
|
||||
f'{type(registered).__name__}'
|
||||
)
|
||||
|
||||
return _registry
|
||||
|
||||
|
||||
def getPluginRegistry() -> PluginRegistry:
|
||||
"""Return the process-wide registry, discovering external plugins lazily."""
|
||||
return initializePluginRegistry()
|
||||
|
||||
|
||||
def registerPlugin(plugin: FuriousPlugin):
|
||||
"""Register a plugin programmatically and return it."""
|
||||
return getPluginRegistry().register(plugin)
|
||||
|
||||
@@ -24,6 +24,7 @@ from .Registry import (
|
||||
PLUGIN_ENTRY_POINT_GROUP,
|
||||
PluginRegistry,
|
||||
getPluginRegistry,
|
||||
initializePluginRegistry,
|
||||
registerPlugin,
|
||||
)
|
||||
|
||||
@@ -35,5 +36,6 @@ __all__ = [
|
||||
'PluginRegistry',
|
||||
'PluginRouting',
|
||||
'getPluginRegistry',
|
||||
'initializePluginRegistry',
|
||||
'registerPlugin',
|
||||
]
|
||||
|
||||
@@ -21,7 +21,7 @@ from __future__ import annotations
|
||||
|
||||
from Furious.Frozenlib import *
|
||||
from Furious.Interface import *
|
||||
from Furious.Library import ConfigFactory
|
||||
from Furious.Domain import ConfigFactory
|
||||
from Furious.Qt.DynamicTranslate import gettext as _
|
||||
from Furious.Qt.QtWidgets import *
|
||||
|
||||
@@ -46,7 +46,7 @@ __all__ = [
|
||||
]
|
||||
|
||||
|
||||
class GuiEditorItemTextInput(GuiEditorItemWidgetContainer):
|
||||
class GuiEditorItemTextInput(EditorWidgetBinding):
|
||||
"""Represent GUI editor item text input."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
@@ -76,7 +76,7 @@ class GuiEditorItemTextInput(GuiEditorItemWidgetContainer):
|
||||
return self._title, self._input
|
||||
|
||||
|
||||
class GuiEditorItemTextSpinBox(GuiEditorItemWidgetContainer):
|
||||
class GuiEditorItemTextSpinBox(EditorWidgetBinding):
|
||||
"""Represent GUI editor item text spin box."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
@@ -110,7 +110,7 @@ class GuiEditorItemTextSpinBox(GuiEditorItemWidgetContainer):
|
||||
return self._title, self._input
|
||||
|
||||
|
||||
class GuiEditorItemTextComboBox(GuiEditorItemWidgetContainer):
|
||||
class GuiEditorItemTextComboBox(EditorWidgetBinding):
|
||||
"""Represent GUI editor item text combo box."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
@@ -148,7 +148,7 @@ class GuiEditorItemTextComboBox(GuiEditorItemWidgetContainer):
|
||||
return self._title, self._input
|
||||
|
||||
|
||||
class GuiEditorItemTextCheckBox(GuiEditorItemWidgetContainer):
|
||||
class GuiEditorItemTextCheckBox(EditorWidgetBinding):
|
||||
"""Represent GUI editor item text check box."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
@@ -284,7 +284,7 @@ class GuiEditorItemProxySocks(GuiEditorItemTextInput):
|
||||
self.setText('')
|
||||
|
||||
|
||||
class GuiEditorWidget(GuiEditorItemFactory):
|
||||
class GuiEditorWidget(EditorBinding):
|
||||
"""Provide the GUI editor widget."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
@@ -293,7 +293,7 @@ class GuiEditorWidget(GuiEditorItemFactory):
|
||||
|
||||
self._containers = self.containerSequence()
|
||||
|
||||
def containerSequence(self) -> Sequence[GuiEditorItemWidgetContainer]:
|
||||
def containerSequence(self) -> Sequence[EditorWidgetBinding]:
|
||||
"""Return the editor item containers in display order."""
|
||||
raise NotImplementedError
|
||||
|
||||
@@ -374,7 +374,7 @@ class GuiEditorWidgetQGroupBox(GuiEditorWidget, AppQGroupBox):
|
||||
return layout
|
||||
|
||||
|
||||
class GuiEditorWidgetQDialog(GuiEditorItemFactory, AppQDialog):
|
||||
class GuiEditorWidgetQDialog(EditorBinding, AppQDialog):
|
||||
"""Present the GUI editor widget Qt dialog."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
+1
-1
@@ -147,7 +147,7 @@ class AppQAction(Mixins.QTranslatable, Mixins.ThemeAware, QAction):
|
||||
self._menu = menu
|
||||
|
||||
# Some old version PySide6 does not have setMenu method
|
||||
# for QAction. Protect it. Currently only used in SystemTrayIcon
|
||||
# for QAction. Protect it. Currently only used in TrayIcon
|
||||
if hasattr(self, 'setMenu') and useSetMenu:
|
||||
self.setMenu(menu)
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from Furious.Frozenlib import *
|
||||
from Furious.Library import *
|
||||
from Furious.Domain import *
|
||||
from Furious.Qt.AppStyleSheet import *
|
||||
from Furious.Qt.DynamicTheme import *
|
||||
from Furious.Qt.DynamicTranslate import gettext as _
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from .AppStyleSheet import AppStyleSheet
|
||||
from .DNSResolver import DNSResolver
|
||||
from .DynamicTheme import AppHue
|
||||
from .DynamicTranslate import (
|
||||
ABBR_TO_LANGUAGE,
|
||||
@@ -28,7 +27,7 @@ from .DynamicTranslate import (
|
||||
SUPPORTED_LANGUAGE,
|
||||
gettext,
|
||||
)
|
||||
from .GuiEditorXXX import (
|
||||
from .EditorWidgets import (
|
||||
GuiEditorItemBasicRemark,
|
||||
GuiEditorItemProxyHttp,
|
||||
GuiEditorItemProxySocks,
|
||||
@@ -40,7 +39,6 @@ from .GuiEditorXXX import (
|
||||
GuiEditorWidgetQGroupBox,
|
||||
GuiEditorWidgetQWidget,
|
||||
)
|
||||
from .NetworkConnectivityManager import NetworkConnectivityManager
|
||||
from .QtGui import (
|
||||
AppQAction,
|
||||
AppQActionGroup,
|
||||
@@ -94,8 +92,6 @@ from .TextEditorTheme import (
|
||||
DraculaLoggerSyntaxHighlighter,
|
||||
configureEditorLogMetadata,
|
||||
)
|
||||
from .UpdatesManager import UpdatesManager
|
||||
from .WaitingSpinner import WaitingSpinner
|
||||
from .WebGETManager import WebGETManager
|
||||
|
||||
__all__ = [
|
||||
@@ -128,7 +124,6 @@ __all__ = [
|
||||
'AppQTextBrowser',
|
||||
'AppQToolBar',
|
||||
'AppStyleSheet',
|
||||
'DNSResolver',
|
||||
'DraculaEditorTheme',
|
||||
'DraculaJSONSyntaxHighlighter',
|
||||
'DraculaJSONTextEditor',
|
||||
@@ -150,10 +145,7 @@ __all__ = [
|
||||
'MBoxNewChangesNextTime',
|
||||
'MBoxQuestionDelete',
|
||||
'MBoxUnrecognizedConfig',
|
||||
'NetworkConnectivityManager',
|
||||
'SUPPORTED_LANGUAGE',
|
||||
'UpdatesManager',
|
||||
'WaitingSpinner',
|
||||
'WebGETManager',
|
||||
'bootstrapIcon',
|
||||
'bootstrapIconMask',
|
||||
|
||||
@@ -21,14 +21,14 @@ from __future__ import annotations
|
||||
|
||||
from Furious.Frozenlib import *
|
||||
from Furious.Interface import *
|
||||
from Furious.Library.Encoder import *
|
||||
from Furious.Domain.Encoding import *
|
||||
|
||||
__all__ = ['UserRoutings']
|
||||
|
||||
registerAppSettings('CustomRouting')
|
||||
|
||||
|
||||
class UserRoutings(Mixins.CleanupOnExit, StorageFactory):
|
||||
class UserRoutings(Mixins.CleanupOnExit, StorageBackend):
|
||||
"""Manage the persisted custom-routing collection."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
@@ -21,8 +21,8 @@ from __future__ import annotations
|
||||
|
||||
from Furious.Frozenlib import *
|
||||
from Furious.Interface import *
|
||||
from Furious.Library.Configuration import ConfigFactory, configFactoryFromAny
|
||||
from Furious.Library.Encoder import *
|
||||
from Furious.Domain.Configuration import ConfigFactory, configFactoryFromAny
|
||||
from Furious.Domain.Encoding import *
|
||||
|
||||
__all__ = ['UserServers']
|
||||
|
||||
@@ -37,7 +37,7 @@ class UserServer:
|
||||
subsId: str
|
||||
|
||||
|
||||
class UserServers(Mixins.CleanupOnExit, StorageFactory):
|
||||
class UserServers(Mixins.CleanupOnExit, StorageBackend):
|
||||
# remark, config, subsId. (subsId corresponds to unique in user subscription)
|
||||
"""Manage the persisted list of server configurations."""
|
||||
|
||||
@@ -21,10 +21,10 @@ from __future__ import annotations
|
||||
|
||||
from Furious.Frozenlib import *
|
||||
from Furious.Interface import *
|
||||
from Furious.Library.UserServers import UserServers
|
||||
from Furious.Library.UserSubs import UserSubs
|
||||
from Furious.Library.UserRoutings import UserRoutings
|
||||
from Furious.Library.UserTUNSettings import UserTUNSettings
|
||||
from Furious.Repository.Routings import UserRoutings
|
||||
from Furious.Repository.Servers import UserServers
|
||||
from Furious.Repository.Subscriptions import UserSubs
|
||||
from Furious.Repository.TunSettings import UserTUNSettings
|
||||
|
||||
from typing import Union
|
||||
|
||||
@@ -21,7 +21,7 @@ from __future__ import annotations
|
||||
|
||||
from Furious.Frozenlib import *
|
||||
from Furious.Interface import *
|
||||
from Furious.Library.Encoder import *
|
||||
from Furious.Domain.Encoding import *
|
||||
|
||||
__all__ = ['UserSubs']
|
||||
|
||||
@@ -43,7 +43,7 @@ class UserSub:
|
||||
unique: dict[str, dict]
|
||||
|
||||
|
||||
class UserSubs(Mixins.CleanupOnExit, StorageFactory):
|
||||
class UserSubs(Mixins.CleanupOnExit, StorageBackend):
|
||||
# unique: { remark, webURL }
|
||||
"""Manage the persisted subscription collection."""
|
||||
|
||||
@@ -21,14 +21,14 @@ from __future__ import annotations
|
||||
|
||||
from Furious.Frozenlib import *
|
||||
from Furious.Interface import *
|
||||
from Furious.Library.Encoder import *
|
||||
from Furious.Domain.Encoding import *
|
||||
|
||||
__all__ = ['UserTUNSettings']
|
||||
|
||||
registerAppSettings('CustomTUNSettings')
|
||||
|
||||
|
||||
class UserTUNSettings(Mixins.CleanupOnExit, StorageFactory):
|
||||
class UserTUNSettings(Mixins.CleanupOnExit, StorageBackend):
|
||||
"""Manage persisted TUN customization values."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
@@ -0,0 +1,24 @@
|
||||
# Copyright (C) 2024–present Loren Eteval & contributors <loren.eteval@proton.me>
|
||||
#
|
||||
# This file is part of Furious.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
"""Expose persisted user-state repositories through the storage facade."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .Storage import Storage
|
||||
|
||||
__all__ = ['Storage']
|
||||
@@ -21,9 +21,11 @@ from __future__ import annotations
|
||||
|
||||
from Furious.Frozenlib import *
|
||||
from Furious.Interface import *
|
||||
from Furious.Library import *
|
||||
from Furious.Domain import *
|
||||
from Furious.Repository import *
|
||||
from Furious.Plugins import *
|
||||
from Furious.Qt import *
|
||||
from Furious.Service.DnsResolver import DnsResolver
|
||||
from Furious.Core.CoreProcessWorker import *
|
||||
from Furious.Core.Tun2socks import *
|
||||
|
||||
@@ -34,7 +36,7 @@ import logging
|
||||
import tempfile
|
||||
import functools
|
||||
|
||||
__all__ = ['CoreManager']
|
||||
__all__ = ['ConnectionManager']
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -67,11 +69,11 @@ def getUserTUNSettings(*args, **kwargs):
|
||||
)
|
||||
|
||||
|
||||
class CoreManager(Mixins.CleanupOnExit):
|
||||
class ConnectionManager(Mixins.CleanupOnExit):
|
||||
"""Coordinate proxy cores, TUN setup, DNS changes, and routing cleanup."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the CoreManager."""
|
||||
"""Initialize the connection manager."""
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.uniqueCleanup = False
|
||||
@@ -317,9 +319,9 @@ class CoreManager(Mixins.CleanupOnExit):
|
||||
address = configcopy.itemAddress
|
||||
|
||||
if not isValidIPAddress(address):
|
||||
DNSResolver.configureHttpProxy(configcopy.httpProxy())
|
||||
DnsResolver.configureHttpProxy(configcopy.httpProxy())
|
||||
|
||||
error, resolved = DNSResolver.resolve(address)
|
||||
error, resolved = DnsResolver.resolve(address)
|
||||
|
||||
if error:
|
||||
SystemRoutingTable.Relations.clear()
|
||||
@@ -543,7 +545,7 @@ class CoreManager(Mixins.CleanupOnExit):
|
||||
"""Stop every managed proxy and TUN process."""
|
||||
try:
|
||||
for process in list(self.processesPool):
|
||||
if not isinstance(process, CoreProcessFactory):
|
||||
if not isinstance(process, CoreProcess):
|
||||
continue
|
||||
|
||||
try:
|
||||
@@ -28,25 +28,25 @@ from PySide6.QtNetwork import *
|
||||
import logging
|
||||
import functools
|
||||
|
||||
__all__ = ['NetworkConnectivityManager']
|
||||
__all__ = ['ConnectivityManager']
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class NetworkConnectivityManager(Mixins.ConnectionAware, WebGETManager):
|
||||
class ConnectivityManager(Mixins.ConnectionAware, WebGETManager):
|
||||
"""Coordinate network connectivity operations."""
|
||||
|
||||
MIN_JOB_INTERVAL = 2500
|
||||
MAX_JOB_INTERVAL = 2000000000
|
||||
|
||||
def __init__(self, parent=None, **kwargs):
|
||||
"""Initialize the NetworkConnectivityManager."""
|
||||
"""Initialize the connectivity manager."""
|
||||
actionMessage = kwargs.pop('actionMessage', 'test network connectivity')
|
||||
|
||||
super().__init__(parent, actionMessage=actionMessage)
|
||||
|
||||
self.jobStatus = False
|
||||
self.jobInterval = NetworkConnectivityManager.MIN_JOB_INTERVAL
|
||||
self.jobInterval = ConnectivityManager.MIN_JOB_INTERVAL
|
||||
|
||||
self.jobTimeoutTimer = QtCore.QTimer()
|
||||
self.jobArrangeTimer = QtCore.QTimer()
|
||||
@@ -60,13 +60,13 @@ class NetworkConnectivityManager(Mixins.ConnectionAware, WebGETManager):
|
||||
if self.jobStatus is jobStatus:
|
||||
self.jobInterval *= 2
|
||||
else:
|
||||
self.jobInterval = NetworkConnectivityManager.MIN_JOB_INTERVAL
|
||||
self.jobInterval = ConnectivityManager.MIN_JOB_INTERVAL
|
||||
|
||||
self.jobStatus = jobStatus
|
||||
|
||||
if self.jobInterval >= NetworkConnectivityManager.MAX_JOB_INTERVAL:
|
||||
if self.jobInterval >= ConnectivityManager.MAX_JOB_INTERVAL:
|
||||
# Limited
|
||||
self.jobInterval = NetworkConnectivityManager.MAX_JOB_INTERVAL
|
||||
self.jobInterval = ConnectivityManager.MAX_JOB_INTERVAL
|
||||
|
||||
return self.jobInterval
|
||||
|
||||
@@ -98,7 +98,7 @@ class NetworkConnectivityManager(Mixins.ConnectionAware, WebGETManager):
|
||||
_networkReply.abort()
|
||||
|
||||
self.jobTimeoutTimer.timeout.connect(functools.partial(abort, networkReply))
|
||||
self.jobTimeoutTimer.start(NetworkConnectivityManager.MIN_JOB_INTERVAL - 500)
|
||||
self.jobTimeoutTimer.start(ConnectivityManager.MIN_JOB_INTERVAL - 500)
|
||||
|
||||
def stopTest(self):
|
||||
"""Stop test."""
|
||||
@@ -113,7 +113,7 @@ class NetworkConnectivityManager(Mixins.ConnectionAware, WebGETManager):
|
||||
|
||||
self.stopTest()
|
||||
else:
|
||||
self.jobInterval = NetworkConnectivityManager.MIN_JOB_INTERVAL
|
||||
self.jobInterval = ConnectivityManager.MIN_JOB_INTERVAL
|
||||
|
||||
self.jobArrangeTimer.start(self.jobInterval)
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from Furious.Frozenlib import *
|
||||
from Furious.Library import *
|
||||
from Furious.Domain import *
|
||||
from Furious.Qt.WebGETManager import *
|
||||
|
||||
from PySide6 import QtCore
|
||||
@@ -30,16 +30,16 @@ from typing import Tuple
|
||||
|
||||
import logging
|
||||
|
||||
__all__ = ['DNSResolver']
|
||||
__all__ = ['DnsResolver']
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class _DNSResolver(WebGETManager):
|
||||
class _DnsResolver(WebGETManager):
|
||||
"""Represent DNS resolver."""
|
||||
|
||||
def __init__(self, parent=None, **kwargs):
|
||||
"""Initialize the _DNSResolver."""
|
||||
"""Initialize the DNS resolver."""
|
||||
actionMessage = kwargs.pop('actionMessage', 'DNS resolution')
|
||||
|
||||
super().__init__(parent, actionMessage=actionMessage)
|
||||
@@ -161,4 +161,4 @@ class _DNSResolver(WebGETManager):
|
||||
networkReply.abort()
|
||||
|
||||
|
||||
DNSResolver = _DNSResolver()
|
||||
DnsResolver = _DnsResolver()
|
||||
@@ -20,7 +20,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from Furious.Frozenlib import *
|
||||
from Furious.Library import *
|
||||
from Furious.Domain import *
|
||||
from Furious.Qt.QtWidgets import *
|
||||
from Furious.Qt.DynamicTranslate import gettext as _
|
||||
from Furious.Qt.WebGETManager import *
|
||||
@@ -33,7 +33,7 @@ from typing import Callable
|
||||
import logging
|
||||
import functools
|
||||
|
||||
__all__ = ['UpdatesManager']
|
||||
__all__ = ['UpdateManager']
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -66,7 +66,7 @@ class MBoxQuestionUpdate(AppQMessageBox):
|
||||
self.moveToCenter()
|
||||
|
||||
|
||||
class UpdatesManager(WebGETManager):
|
||||
class UpdateManager(WebGETManager):
|
||||
"""Coordinate updates operations."""
|
||||
|
||||
API_URL = (
|
||||
@@ -75,7 +75,7 @@ class UpdatesManager(WebGETManager):
|
||||
)
|
||||
|
||||
def __init__(self, parent=None, **kwargs):
|
||||
"""Initialize the UpdatesManager."""
|
||||
"""Initialize the update manager."""
|
||||
actionMessage = kwargs.pop('actionMessage', 'check for updates')
|
||||
|
||||
super().__init__(parent, actionMessage=actionMessage)
|
||||
@@ -19,6 +19,14 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .CoreManager import CoreManager
|
||||
from .ConnectionManager import ConnectionManager
|
||||
from .ConnectivityManager import ConnectivityManager
|
||||
from .DnsResolver import DnsResolver
|
||||
from .UpdateManager import UpdateManager
|
||||
|
||||
__all__ = ['CoreManager']
|
||||
__all__ = [
|
||||
'ConnectionManager',
|
||||
'ConnectivityManager',
|
||||
'DnsResolver',
|
||||
'UpdateManager',
|
||||
]
|
||||
|
||||
@@ -47,7 +47,7 @@ else:
|
||||
class AppMainProcess(ProcessContext.Process):
|
||||
"""Represent app main process."""
|
||||
|
||||
def __init__(self, func: Callable[[], ApplicationFactory], **kwargs):
|
||||
def __init__(self, func: Callable[[], ApplicationRunner], **kwargs):
|
||||
"""Initialize the AppMainProcess."""
|
||||
super().__init__(**kwargs)
|
||||
|
||||
@@ -64,9 +64,9 @@ class AppMainProcess(ProcessContext.Process):
|
||||
traceback.print_exception(exceptionType, exceptionValue, tb)
|
||||
|
||||
if isinstance(exceptionValue, AssertionError):
|
||||
exitcode = ApplicationFactory.ExitCode.AssertionError.value
|
||||
exitcode = ApplicationRunner.ExitCode.AssertionError.value
|
||||
else:
|
||||
exitcode = ApplicationFactory.ExitCode.UnknownException.value
|
||||
exitcode = ApplicationRunner.ExitCode.UnknownException.value
|
||||
|
||||
logger.error(f'stopped with exitcode {exitcode}')
|
||||
|
||||
|
||||
+6
-6
@@ -26,14 +26,14 @@ from Furious.Qt import gettext as _
|
||||
from PySide6 import QtCore
|
||||
from PySide6.QtWidgets import *
|
||||
|
||||
__all__ = ['ConnectProgressBar']
|
||||
__all__ = ['ConnectionProgressWidget']
|
||||
|
||||
|
||||
class AutoUpdateProgressBar(Mixins.ConnectionAware, QProgressBar):
|
||||
class ConnectionProgressBar(Mixins.ConnectionAware, QProgressBar):
|
||||
"""Represent auto update progress bar."""
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
"""Initialize the AutoUpdateProgressBar."""
|
||||
"""Initialize the connection progress bar."""
|
||||
super().__init__(**kwargs)
|
||||
|
||||
self.setRange(0, 100)
|
||||
@@ -97,11 +97,11 @@ class AutoUpdateProgressBar(Mixins.ConnectionAware, QProgressBar):
|
||||
self._setConnectionState('connected')
|
||||
|
||||
|
||||
class ConnectProgressBar(Mixins.QTranslatable, Mixins.ConnectionAware, QWidget):
|
||||
class ConnectionProgressWidget(Mixins.QTranslatable, Mixins.ConnectionAware, QWidget):
|
||||
"""Provide the connect progress bar widget."""
|
||||
|
||||
def __init__(self, parent=None):
|
||||
"""Initialize the ConnectProgressBar."""
|
||||
"""Initialize the connection progress widget."""
|
||||
super().__init__(parent)
|
||||
|
||||
self.setWindowTitle(_(APPLICATION_NAME))
|
||||
@@ -109,7 +109,7 @@ class ConnectProgressBar(Mixins.QTranslatable, Mixins.ConnectionAware, QWidget):
|
||||
self.setFixedSize(280, 61)
|
||||
|
||||
# Create a progress bar widget
|
||||
self._widget = AutoUpdateProgressBar(parent=self)
|
||||
self._widget = ConnectionProgressBar(parent=self)
|
||||
self._widget.setRange(0, 100)
|
||||
|
||||
self._layout = QVBoxLayout()
|
||||
@@ -21,15 +21,13 @@ from __future__ import annotations
|
||||
|
||||
from Furious.Frozenlib import *
|
||||
from Furious.Interface import *
|
||||
from Furious.Library import *
|
||||
from Furious.Domain import *
|
||||
from Furious.Repository import *
|
||||
from Furious.Plugins import getPluginRegistry
|
||||
from Furious.Qt import *
|
||||
from Furious.Qt import gettext as _
|
||||
from Furious.Service import CoreManager
|
||||
from Furious.TrayActions.Import import *
|
||||
from Furious.Qt.WaitingSpinner import *
|
||||
from Furious.Widget.QRCodeWindow import *
|
||||
from Furious.Widget.TextEditorWindow import *
|
||||
from Furious.Service import ConnectionManager
|
||||
from Furious.Widget.WaitingSpinner import *
|
||||
|
||||
from PySide6 import QtCore
|
||||
from PySide6.QtGui import *
|
||||
@@ -44,7 +42,7 @@ import icmplib
|
||||
import functools
|
||||
import collections
|
||||
|
||||
__all__ = ['UserServersQTableView']
|
||||
__all__ = ['ServerTableView']
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -160,7 +158,7 @@ class SubscriptionManager(WebGETManager):
|
||||
|
||||
parent = self.parent()
|
||||
|
||||
if isinstance(parent, UserServersQTableView):
|
||||
if isinstance(parent, ServerTableView):
|
||||
isConnected = APP().isSystemTrayConnected()
|
||||
|
||||
subsIndexes = list(
|
||||
@@ -471,7 +469,7 @@ class TestDownloadSpeedWorker(WebGETManager):
|
||||
|
||||
self.hasDataCounter = 0
|
||||
|
||||
self.coreManager = CoreManager()
|
||||
self.coreManager = ConnectionManager()
|
||||
|
||||
self.networkReply = None
|
||||
self.elapsedTimer = QtCore.QElapsedTimer()
|
||||
@@ -514,13 +512,13 @@ class TestDownloadSpeedWorker(WebGETManager):
|
||||
def coreExitCallback(self, config: ConfigFactory, exitcode: int):
|
||||
"""Handle the core exit callback."""
|
||||
try:
|
||||
if exitcode == CoreProcessFactory.ExitCode.ConfigurationError.value:
|
||||
if exitcode == CoreProcess.ExitCode.ConfigurationError.value:
|
||||
self.factory.setExtras('speedResult', f'Invalid')
|
||||
self.sync()
|
||||
elif exitcode == CoreProcessFactory.ExitCode.ServerStartFailure.value:
|
||||
elif exitcode == CoreProcess.ExitCode.ServerStartFailure.value:
|
||||
self.factory.setExtras('speedResult', f'Core start failed')
|
||||
self.sync()
|
||||
elif exitcode == CoreProcessFactory.ExitCode.SystemShuttingDown.value:
|
||||
elif exitcode == CoreProcess.ExitCode.SystemShuttingDown.value:
|
||||
pass
|
||||
else:
|
||||
self.factory.setExtras('speedResult', f'Core exited {exitcode}')
|
||||
@@ -1026,27 +1024,27 @@ class DeleteServersProgressDialog(AppQDialog):
|
||||
self.updateStatus()
|
||||
|
||||
|
||||
class UserServersQTableViewHorizontalHeader(AppQHeaderView):
|
||||
class ServerTableHorizontalHeader(AppQHeaderView):
|
||||
"""Provide the user servers Qt table view horizontal table header."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the UserServersQTableViewHorizontalHeader."""
|
||||
"""Initialize the ServerTableHorizontalHeader."""
|
||||
super().__init__(QtCore.Qt.Orientation.Horizontal, *args, **kwargs)
|
||||
|
||||
|
||||
class UserServersQTableViewVerticalHeader(AppQHeaderView):
|
||||
class ServerTableVerticalHeader(AppQHeaderView):
|
||||
"""Provide the user servers Qt table view vertical table header."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the UserServersQTableViewVerticalHeader."""
|
||||
"""Initialize the ServerTableVerticalHeader."""
|
||||
super().__init__(QtCore.Qt.Orientation.Vertical, *args, **kwargs)
|
||||
|
||||
|
||||
class UserServersQTableViewHeaders:
|
||||
class ServerTableColumn:
|
||||
"""Describe and render user servers Qt table view table columns."""
|
||||
|
||||
def __init__(self, name: str, func: Callable[[ConfigFactory], str] = None):
|
||||
"""Initialize the UserServersQTableViewHeaders."""
|
||||
"""Initialize the ServerTableColumn."""
|
||||
self.name = name
|
||||
self.func = func
|
||||
|
||||
@@ -1078,7 +1076,7 @@ class UserServersTableModel(QtCore.QAbstractTableModel):
|
||||
|
||||
SortRole = QtCore.Qt.ItemDataRole.UserRole + 1
|
||||
|
||||
def __init__(self, headers: list[UserServersQTableViewHeaders], parent=None):
|
||||
def __init__(self, headers: list[ServerTableColumn], parent=None):
|
||||
"""Initialize the UserServersTableModel."""
|
||||
super().__init__(parent)
|
||||
|
||||
@@ -1395,7 +1393,7 @@ _TRANSLATABLE_HEADERS = [
|
||||
]
|
||||
|
||||
|
||||
class UserServersQTableView(
|
||||
class ServerTableView(
|
||||
Mixins.QTranslatable,
|
||||
Mixins.CleanupOnExit,
|
||||
AppQTableView,
|
||||
@@ -1405,19 +1403,23 @@ class UserServersQTableView(
|
||||
RowHeight = 42
|
||||
|
||||
Headers = [
|
||||
UserServersQTableViewHeaders('Remark'),
|
||||
UserServersQTableViewHeaders('Protocol'),
|
||||
UserServersQTableViewHeaders('Address'),
|
||||
UserServersQTableViewHeaders('Port'),
|
||||
UserServersQTableViewHeaders('Transport'),
|
||||
UserServersQTableViewHeaders('TLS'),
|
||||
UserServersQTableViewHeaders('Subscription', _subscriptionRemark),
|
||||
UserServersQTableViewHeaders('Latency'),
|
||||
UserServersQTableViewHeaders('Speed'),
|
||||
ServerTableColumn('Remark'),
|
||||
ServerTableColumn('Protocol'),
|
||||
ServerTableColumn('Address'),
|
||||
ServerTableColumn('Port'),
|
||||
ServerTableColumn('Transport'),
|
||||
ServerTableColumn('TLS'),
|
||||
ServerTableColumn('Subscription', _subscriptionRemark),
|
||||
ServerTableColumn('Latency'),
|
||||
ServerTableColumn('Speed'),
|
||||
]
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the UserServersQTableView."""
|
||||
"""Initialize the server table view."""
|
||||
configurationEditorFactory = kwargs.pop('configurationEditorFactory')
|
||||
self.qrCodeWindowFactory = kwargs.pop('qrCodeWindowFactory')
|
||||
importActionsFactory = kwargs.pop('importActionsFactory')
|
||||
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.sourceModel = UserServersTableModel(self.Headers, parent=self)
|
||||
@@ -1438,18 +1440,17 @@ class UserServersQTableView(
|
||||
parent=self,
|
||||
)
|
||||
|
||||
# Text Editor Window
|
||||
self.textEditorWindow = TextEditorWindow(parent=self.parent())
|
||||
self.configurationEditor = configurationEditorFactory()
|
||||
|
||||
# Install custom header
|
||||
self.setHorizontalHeader(
|
||||
UserServersQTableViewHorizontalHeader(
|
||||
ServerTableHorizontalHeader(
|
||||
parent=self,
|
||||
legacySectionSizeSettingsName='ServerWidgetSectionSizeTable',
|
||||
sectionSizeSettingsName='UserServersHeaderViewState',
|
||||
)
|
||||
)
|
||||
self.setVerticalHeader(UserServersQTableViewVerticalHeader(self))
|
||||
self.setVerticalHeader(ServerTableVerticalHeader(self))
|
||||
self.setDefaultRowHeight(self.RowHeight)
|
||||
|
||||
self.horizontalHeader().setCustomSectionResizeMode()
|
||||
@@ -1625,21 +1626,7 @@ class UserServersQTableView(
|
||||
QtCore.Qt.Key.Key_N,
|
||||
),
|
||||
),
|
||||
ImportFromFileAction(),
|
||||
ImportURIFromClipboardAction(
|
||||
shortcut=QtCore.QKeyCombination(
|
||||
QtCore.Qt.KeyboardModifier.ControlModifier,
|
||||
QtCore.Qt.Key.Key_V,
|
||||
),
|
||||
),
|
||||
ImportJSONFromClipboardAction(
|
||||
shortcut=QtCore.QKeyCombination(
|
||||
QtCore.Qt.KeyboardModifier.ControlModifier
|
||||
| QtCore.Qt.KeyboardModifier.ShiftModifier,
|
||||
QtCore.Qt.Key.Key_J,
|
||||
),
|
||||
),
|
||||
ImportQRCodeOnTheScreenAction(),
|
||||
*importActionsFactory(),
|
||||
AppQSeperator(),
|
||||
AppQAction(
|
||||
_('Export Share Link To Clipboard'),
|
||||
@@ -2287,13 +2274,13 @@ class UserServersQTableView(
|
||||
index = indexes[0]
|
||||
title = f'{index + 1} - ' + Storage.UserServers()[index].getExtras('remark')
|
||||
|
||||
self.textEditorWindow.currentIndex = index
|
||||
self.textEditorWindow.customWindowTitle = title
|
||||
self.textEditorWindow.setWindowTitle(title)
|
||||
self.textEditorWindow.setPlainText(
|
||||
self.configurationEditor.currentIndex = index
|
||||
self.configurationEditor.customWindowTitle = title
|
||||
self.configurationEditor.setWindowTitle(title)
|
||||
self.configurationEditor.setPlainText(
|
||||
Storage.UserServers()[index].toJSONString(), True
|
||||
)
|
||||
self.textEditorWindow.show()
|
||||
self.configurationEditor.show()
|
||||
|
||||
def activateSelectedServer(self):
|
||||
"""Activate selected server."""
|
||||
@@ -2586,7 +2573,7 @@ class UserServersQTableView(
|
||||
# Nothing selected. Do nothing
|
||||
return
|
||||
|
||||
window = QRCodeWindow()
|
||||
window = self.qrCodeWindowFactory()
|
||||
window.initTabByIndex(indexes)
|
||||
|
||||
if window.tabCount() > 0:
|
||||
@@ -2609,11 +2596,11 @@ class UserServersQTableView(
|
||||
|
||||
def showTabAndSpaces(self):
|
||||
"""Show tab and spaces."""
|
||||
self.textEditorWindow.showTabAndSpaces()
|
||||
self.configurationEditor.showTabAndSpaces()
|
||||
|
||||
def hideTabAndSpaces(self):
|
||||
"""Hide tab and spaces."""
|
||||
self.textEditorWindow.hideTabAndSpaces()
|
||||
self.configurationEditor.hideTabAndSpaces()
|
||||
|
||||
def keyPressEvent(self, event):
|
||||
"""Handle a key press for the user servers Qt table view."""
|
||||
@@ -20,7 +20,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from Furious.Frozenlib import *
|
||||
from Furious.Library import *
|
||||
from Furious.Repository import *
|
||||
from Furious.Qt import *
|
||||
from Furious.Qt import gettext as _
|
||||
|
||||
@@ -35,34 +35,34 @@ import functools
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
__all__ = ['UserSubsQTableView']
|
||||
__all__ = ['SubscriptionTableView']
|
||||
|
||||
# Migrate legacy settings
|
||||
registerAppSettings('SubscriptionWidgetSectionSizeTable')
|
||||
registerAppSettings('UserSubsHeaderViewState')
|
||||
|
||||
|
||||
class UserSubsQTableViewHorizontalHeader(AppQHeaderView):
|
||||
class SubscriptionTableHorizontalHeader(AppQHeaderView):
|
||||
"""Provide the user subs Qt table view horizontal table header."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the UserSubsQTableViewHorizontalHeader."""
|
||||
"""Initialize the SubscriptionTableHorizontalHeader."""
|
||||
super().__init__(QtCore.Qt.Orientation.Horizontal, *args, **kwargs)
|
||||
|
||||
|
||||
class UserSubsQTableViewVerticalHeader(AppQHeaderView):
|
||||
class SubscriptionTableVerticalHeader(AppQHeaderView):
|
||||
"""Provide the user subs Qt table view vertical table header."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the UserSubsQTableViewVerticalHeader."""
|
||||
"""Initialize the SubscriptionTableVerticalHeader."""
|
||||
super().__init__(QtCore.Qt.Orientation.Vertical, *args, **kwargs)
|
||||
|
||||
|
||||
class UserSubsQTableViewHeaders:
|
||||
class SubscriptionTableColumn:
|
||||
"""Describe and render user subs Qt table view table columns."""
|
||||
|
||||
def __init__(self, name: str, func: Callable[[dict], str] = None):
|
||||
"""Initialize the UserSubsQTableViewHeaders."""
|
||||
"""Initialize the SubscriptionTableColumn."""
|
||||
self.name = name
|
||||
self.func = func
|
||||
|
||||
@@ -101,7 +101,7 @@ class UserSubsTableModel(QtCore.QAbstractTableModel):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
headers: list[UserSubsQTableViewHeaders],
|
||||
headers: list[SubscriptionTableColumn],
|
||||
itemKey: list[str],
|
||||
parent=None,
|
||||
):
|
||||
@@ -271,7 +271,7 @@ _TRANSLATABLE_HEADERS = [
|
||||
]
|
||||
|
||||
|
||||
class UserSubsQTableView(Mixins.QTranslatable, AppQTableView):
|
||||
class SubscriptionTableView(Mixins.QTranslatable, AppQTableView):
|
||||
"""Represent user subs Qt table view."""
|
||||
|
||||
RowHeight = 42
|
||||
@@ -302,12 +302,10 @@ class UserSubsQTableView(Mixins.QTranslatable, AppQTableView):
|
||||
}
|
||||
|
||||
Headers = [
|
||||
UserSubsQTableViewHeaders('Remark', lambda item: item.get('remark', '')),
|
||||
UserSubsQTableViewHeaders('URL', lambda item: item.get('webURL', '')),
|
||||
UserSubsQTableViewHeaders(
|
||||
'Auto Update', lambda item: item.get('autoupdate', '')
|
||||
),
|
||||
UserSubsQTableViewHeaders(
|
||||
SubscriptionTableColumn('Remark', lambda item: item.get('remark', '')),
|
||||
SubscriptionTableColumn('URL', lambda item: item.get('webURL', '')),
|
||||
SubscriptionTableColumn('Auto Update', lambda item: item.get('autoupdate', '')),
|
||||
SubscriptionTableColumn(
|
||||
'Auto Update Use Proxy', lambda item: item.get('proxy', '')
|
||||
),
|
||||
]
|
||||
@@ -316,7 +314,7 @@ class UserSubsQTableView(Mixins.QTranslatable, AppQTableView):
|
||||
ItemKey = ['remark', 'webURL', 'autoupdate', 'proxy']
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the UserSubsQTableView."""
|
||||
"""Initialize the subscription table view."""
|
||||
self.deleteUniqueCallback = kwargs.pop('deleteUniqueCallback', None)
|
||||
|
||||
super().__init__(*args, **kwargs)
|
||||
@@ -328,13 +326,13 @@ class UserSubsQTableView(Mixins.QTranslatable, AppQTableView):
|
||||
|
||||
# Install custom header
|
||||
self.setHorizontalHeader(
|
||||
UserSubsQTableViewHorizontalHeader(
|
||||
SubscriptionTableHorizontalHeader(
|
||||
parent=self,
|
||||
legacySectionSizeSettingsName='SubscriptionWidgetSectionSizeTable',
|
||||
sectionSizeSettingsName='UserSubsHeaderViewState',
|
||||
)
|
||||
)
|
||||
self.setVerticalHeader(UserSubsQTableViewVerticalHeader(self))
|
||||
self.setVerticalHeader(SubscriptionTableVerticalHeader(self))
|
||||
self.setDefaultRowHeight(self.RowHeight)
|
||||
|
||||
self.horizontalHeader().setCustomSectionResizeMode()
|
||||
@@ -15,26 +15,18 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
"""Expose reusable application widgets and configuration editors."""
|
||||
"""Expose reusable visual components that do not own application windows."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .GuiCustomizeNetworkTest import GuiCustomizeNetworkTestDialog
|
||||
from .GuiCustomizeProxyBypass import GuiCustomizeProxyBypassDialog
|
||||
from .GuiTUNSettings import GuiTUNSettings
|
||||
from .IndentSpinBox import IndentSpinBox
|
||||
from .QRCodeWindow import QRCodeWindow
|
||||
from .TextEditorWindow import TextEditorWindow
|
||||
from .UserServersQTableView import UserServersQTableView
|
||||
from .UserSubsQTableView import UserSubsQTableView
|
||||
from .ConnectionProgressWidget import ConnectionProgressWidget
|
||||
from .ServerTableView import ServerTableView
|
||||
from .SubscriptionTableView import SubscriptionTableView
|
||||
from .WaitingSpinner import WaitingSpinner
|
||||
|
||||
__all__ = [
|
||||
'GuiCustomizeNetworkTestDialog',
|
||||
'GuiCustomizeProxyBypassDialog',
|
||||
'GuiTUNSettings',
|
||||
'IndentSpinBox',
|
||||
'QRCodeWindow',
|
||||
'TextEditorWindow',
|
||||
'UserServersQTableView',
|
||||
'UserSubsQTableView',
|
||||
'ConnectionProgressWidget',
|
||||
'ServerTableView',
|
||||
'SubscriptionTableView',
|
||||
'WaitingSpinner',
|
||||
]
|
||||
|
||||
@@ -25,14 +25,14 @@ from Furious.Qt import gettext as _
|
||||
from PySide6 import QtCore
|
||||
from PySide6.QtWidgets import *
|
||||
|
||||
__all__ = ['IndentSpinBox']
|
||||
__all__ = ['IndentDialog']
|
||||
|
||||
|
||||
class IndentSpinBox(AppQDialog):
|
||||
class IndentDialog(AppQDialog):
|
||||
"""Represent indent spin box."""
|
||||
|
||||
def __init__(self, parent=None):
|
||||
"""Initialize the IndentSpinBox."""
|
||||
"""Initialize the indentation dialog."""
|
||||
super().__init__(parent)
|
||||
|
||||
self.setWindowTitle(_('Set Indent'))
|
||||
@@ -25,7 +25,7 @@ from Furious.Qt import gettext as _
|
||||
from PySide6 import QtCore
|
||||
from PySide6.QtWidgets import *
|
||||
|
||||
__all__ = ['LogViewerWindow']
|
||||
__all__ = ['LogWindow']
|
||||
|
||||
|
||||
class MBoxSaveError(AppQMessageBox):
|
||||
@@ -76,11 +76,11 @@ def saveAsFile(content: str):
|
||||
mbox.open()
|
||||
|
||||
|
||||
class LogViewerWindow(AppQMainWindow):
|
||||
class LogWindow(AppQMainWindow):
|
||||
"""Present the log viewer window."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the LogViewerWindow."""
|
||||
"""Initialize the log window."""
|
||||
tabTitle = kwargs.pop('tabTitle', '')
|
||||
fontFamily = kwargs.pop('fontFamily', '')
|
||||
pointSizeSettingsName = kwargs.pop('pointSizeSettingsName', '')
|
||||
@@ -21,15 +21,25 @@ from __future__ import annotations
|
||||
|
||||
from Furious.Frozenlib import *
|
||||
from Furious.Interface import *
|
||||
from Furious.Library import *
|
||||
from Furious.Domain import *
|
||||
from Furious.Repository import *
|
||||
from Furious.Plugins import getPluginRegistry
|
||||
from Furious.Qt import *
|
||||
from Furious.Qt import gettext as _
|
||||
from Furious.Widget.UserServersQTableView import *
|
||||
from Furious.Widget.GuiCustomizeNetworkTest import *
|
||||
from Furious.Widget.GuiCustomizeProxyBypass import *
|
||||
from Furious.Widget.GuiTUNSettings import *
|
||||
from Furious.Window.UserSubsWindow import *
|
||||
from Furious.Service import ConnectivityManager, UpdateManager
|
||||
from Furious.Actions.Import import (
|
||||
ImportFromFileAction,
|
||||
ImportJSONFromClipboardAction,
|
||||
ImportQRCodeOnTheScreenAction,
|
||||
ImportURIFromClipboardAction,
|
||||
)
|
||||
from Furious.Widget.ServerTableView import *
|
||||
from Furious.Window.NetworkTestDialog import *
|
||||
from Furious.Window.ProxyBypassDialog import *
|
||||
from Furious.Window.QRCodeWindow import QRCodeWindow
|
||||
from Furious.Window.SubscriptionWindow import *
|
||||
from Furious.Window.TextEditorWindow import TextEditorWindow
|
||||
from Furious.Window.TunSettingsDialog import *
|
||||
|
||||
from PySide6 import QtCore
|
||||
from PySide6.QtGui import *
|
||||
@@ -41,7 +51,7 @@ import os
|
||||
import logging
|
||||
import functools
|
||||
|
||||
__all__ = ['AppMainWindow']
|
||||
__all__ = ['MainWindow']
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -66,18 +76,18 @@ registerAppSettings('AppMainWindowGeometry')
|
||||
registerAppSettings('AppMainWindowState')
|
||||
|
||||
|
||||
class AppNetworkConnectivityManager(NetworkConnectivityManager):
|
||||
class AppConnectivityManager(ConnectivityManager):
|
||||
"""Coordinate app network connectivity operations."""
|
||||
|
||||
def __init__(self, parent=None):
|
||||
"""Initialize the AppNetworkConnectivityManager."""
|
||||
"""Initialize the application connectivity manager."""
|
||||
super().__init__(parent)
|
||||
|
||||
def successCallback(self, networkReply, **kwargs):
|
||||
"""Handle a successful network operation."""
|
||||
parent = self.parent()
|
||||
|
||||
if isinstance(parent, AppMainWindow):
|
||||
if isinstance(parent, MainWindow):
|
||||
parent.setNetworkState(True)
|
||||
|
||||
super().successCallback(networkReply, **kwargs)
|
||||
@@ -86,7 +96,7 @@ class AppNetworkConnectivityManager(NetworkConnectivityManager):
|
||||
"""Handle a failed network operation."""
|
||||
parent = self.parent()
|
||||
|
||||
if isinstance(parent, AppMainWindow):
|
||||
if isinstance(parent, MainWindow):
|
||||
parent.setNetworkState(False, errorString=networkReply.errorString())
|
||||
|
||||
super().failureCallback(networkReply, **kwargs)
|
||||
@@ -96,7 +106,7 @@ class AppNetworkConnectivityManager(NetworkConnectivityManager):
|
||||
if not APP().isSystemTrayConnected():
|
||||
parent = self.parent()
|
||||
|
||||
if isinstance(parent, AppMainWindow):
|
||||
if isinstance(parent, MainWindow):
|
||||
parent.resetNetworkState()
|
||||
|
||||
self.stopTest()
|
||||
@@ -106,7 +116,7 @@ class AppNetworkConnectivityManager(NetworkConnectivityManager):
|
||||
if connectedHttpProxy is None:
|
||||
parent = self.parent()
|
||||
|
||||
if isinstance(parent, AppMainWindow):
|
||||
if isinstance(parent, MainWindow):
|
||||
parent.resetNetworkState()
|
||||
else:
|
||||
self.configureHttpProxy(connectedHttpProxy)
|
||||
@@ -117,7 +127,7 @@ class AppNetworkConnectivityManager(NetworkConnectivityManager):
|
||||
"""Update the app network connectivity manager for a disconnected state."""
|
||||
parent = self.parent()
|
||||
|
||||
if isinstance(parent, AppMainWindow):
|
||||
if isinstance(parent, MainWindow):
|
||||
parent.resetNetworkState()
|
||||
|
||||
super().disconnectedCallback()
|
||||
@@ -263,7 +273,7 @@ class SearchButton(AppQPushButton):
|
||||
self.setText(self.customText())
|
||||
|
||||
|
||||
class AppMainWindow(AppQMainWindow):
|
||||
class MainWindow(AppQMainWindow):
|
||||
"""Present the app main window."""
|
||||
|
||||
DEFAULT_WINDOW_SIZE_DARWIN = QtCore.QSize(1500, 780)
|
||||
@@ -271,8 +281,29 @@ class AppMainWindow(AppQMainWindow):
|
||||
QtCore.QSize(1800, 960) if PLATFORM != 'Darwin' else DEFAULT_WINDOW_SIZE_DARWIN
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def serverImportActions():
|
||||
"""Build import actions contributed to the server table context menu."""
|
||||
return (
|
||||
ImportFromFileAction(),
|
||||
ImportURIFromClipboardAction(
|
||||
shortcut=QtCore.QKeyCombination(
|
||||
QtCore.Qt.KeyboardModifier.ControlModifier,
|
||||
QtCore.Qt.Key.Key_V,
|
||||
),
|
||||
),
|
||||
ImportJSONFromClipboardAction(
|
||||
shortcut=QtCore.QKeyCombination(
|
||||
QtCore.Qt.KeyboardModifier.ControlModifier
|
||||
| QtCore.Qt.KeyboardModifier.ShiftModifier,
|
||||
QtCore.Qt.Key.Key_J,
|
||||
),
|
||||
),
|
||||
ImportQRCodeOnTheScreenAction(),
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the AppMainWindow."""
|
||||
"""Initialize the main window."""
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
if SystemRuntime.isAdmin():
|
||||
@@ -283,11 +314,16 @@ class AppMainWindow(AppQMainWindow):
|
||||
# TODO: Need this?
|
||||
# self.setAttribute(QtCore.Qt.WidgetAttribute.WA_ShowWithoutActivating)
|
||||
|
||||
self.updatesManager = UpdatesManager(parent=self)
|
||||
self.networkConnectivityManager = AppNetworkConnectivityManager(parent=self)
|
||||
self.updatesManager = UpdateManager(parent=self)
|
||||
self.networkConnectivityManager = AppConnectivityManager(parent=self)
|
||||
|
||||
self.userServersQTableWidget = UserServersQTableView(parent=self)
|
||||
self.userSubsWindow = UserSubsWindow(
|
||||
self.userServersQTableWidget = ServerTableView(
|
||||
parent=self,
|
||||
configurationEditorFactory=lambda: TextEditorWindow(parent=self),
|
||||
qrCodeWindowFactory=QRCodeWindow,
|
||||
importActionsFactory=self.serverImportActions,
|
||||
)
|
||||
self.userSubsWindow = SubscriptionWindow(
|
||||
parent=self,
|
||||
deleteUniqueCallback=lambda unique: self.userServersQTableWidget.deleteItemByIndex(
|
||||
list(
|
||||
@@ -299,8 +335,8 @@ class AppMainWindow(AppQMainWindow):
|
||||
),
|
||||
)
|
||||
pluginRegistry = getPluginRegistry()
|
||||
self.customizeProxyBypassDialog = GuiCustomizeProxyBypassDialog(parent=self)
|
||||
self.customizeNetworkTestDialog = GuiCustomizeNetworkTestDialog(parent=self)
|
||||
self.customizeProxyBypassDialog = ProxyBypassDialog(parent=self)
|
||||
self.customizeNetworkTestDialog = NetworkTestDialog(parent=self)
|
||||
|
||||
self.mainTab = AppQTabWidget()
|
||||
self.mainTab.addTab(self.userServersQTableWidget, _('Server'))
|
||||
@@ -702,7 +738,7 @@ class AppMainWindow(AppQMainWindow):
|
||||
"""Return the cached GUI TUN settings value used by the app main window."""
|
||||
parent = kwargs.pop('parent', self)
|
||||
|
||||
return GuiTUNSettings(parent=parent, **kwargs)
|
||||
return TunSettingsDialog(parent=parent, **kwargs)
|
||||
|
||||
guiTUNSettings = cachedGuiTUNSettings()
|
||||
guiTUNSettings.factoryToInput(Storage.UserTUNSettings())
|
||||
@@ -808,20 +844,20 @@ class AppMainWindow(AppQMainWindow):
|
||||
width, height = tuple(int(size) for size in windowSize)
|
||||
|
||||
if (width, height) == (640, 480):
|
||||
self.resize(AppMainWindow.DEFAULT_WINDOW_SIZE)
|
||||
self.resize(MainWindow.DEFAULT_WINDOW_SIZE)
|
||||
else:
|
||||
self.resize(width, height)
|
||||
except Exception:
|
||||
# Any non-exit exceptions
|
||||
|
||||
self.resize(AppMainWindow.DEFAULT_WINDOW_SIZE)
|
||||
self.resize(MainWindow.DEFAULT_WINDOW_SIZE)
|
||||
else:
|
||||
try:
|
||||
self.restoreGeometry(AppSettings.get('AppMainWindowGeometry'))
|
||||
except Exception:
|
||||
# Any non-exit exceptions
|
||||
|
||||
self.resize(AppMainWindow.DEFAULT_WINDOW_SIZE)
|
||||
self.resize(MainWindow.DEFAULT_WINDOW_SIZE)
|
||||
|
||||
try:
|
||||
self.restoreState(AppSettings.get('AppMainWindowState'))
|
||||
@@ -839,9 +875,9 @@ class AppMainWindow(AppQMainWindow):
|
||||
logger.error(
|
||||
f'detected unresolve Qt bug on macOS. '
|
||||
f'Resizing main window to default '
|
||||
f'{AppMainWindow.DEFAULT_WINDOW_SIZE.toTuple()}'
|
||||
f'{MainWindow.DEFAULT_WINDOW_SIZE.toTuple()}'
|
||||
)
|
||||
self.resize(AppMainWindow.DEFAULT_WINDOW_SIZE)
|
||||
self.resize(MainWindow.DEFAULT_WINDOW_SIZE)
|
||||
else:
|
||||
logger.info(
|
||||
f'restore main window size on macOS success: '
|
||||
@@ -29,7 +29,7 @@ from PySide6.QtWidgets import *
|
||||
import logging
|
||||
import functools
|
||||
|
||||
__all__ = ['GuiCustomizeNetworkTestDialog']
|
||||
__all__ = ['NetworkTestDialog']
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -37,11 +37,11 @@ registerAppSettings('CustomNetworkSpeedTestURL')
|
||||
registerAppSettings('CustomNetworkConnectivityTestURL')
|
||||
|
||||
|
||||
class GuiCustomizeNetworkTestDialog(AppQDialog):
|
||||
class NetworkTestDialog(AppQDialog):
|
||||
"""Present the GUI customize network test dialog."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the GuiCustomizeNetworkTestDialog."""
|
||||
"""Initialize the network test settings dialog."""
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.setWindowTitle(_('Customize Network Test URL'))
|
||||
@@ -29,18 +29,18 @@ from PySide6.QtWidgets import *
|
||||
import logging
|
||||
import functools
|
||||
|
||||
__all__ = ['GuiCustomizeProxyBypassDialog']
|
||||
__all__ = ['ProxyBypassDialog']
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
registerAppSettings('CustomProxyBypass')
|
||||
|
||||
|
||||
class GuiCustomizeProxyBypassDialog(AppQDialog):
|
||||
class ProxyBypassDialog(AppQDialog):
|
||||
"""Present the GUI customize proxy bypass dialog."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the GuiCustomizeProxyBypassDialog."""
|
||||
"""Initialize the proxy bypass settings dialog."""
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.setWindowTitle(_('Customize System Proxy Bypass Address'))
|
||||
@@ -20,7 +20,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from Furious.Frozenlib import *
|
||||
from Furious.Library import *
|
||||
from Furious.Repository import *
|
||||
from Furious.Qt import *
|
||||
from Furious.Qt import gettext as _
|
||||
|
||||
@@ -22,7 +22,7 @@ from __future__ import annotations
|
||||
from Furious.Frozenlib import *
|
||||
from Furious.Qt import *
|
||||
from Furious.Qt import gettext as _
|
||||
from Furious.Widget.UserSubsQTableView import *
|
||||
from Furious.Widget.SubscriptionTableView import *
|
||||
|
||||
from PySide6 import QtCore
|
||||
from PySide6.QtWidgets import *
|
||||
@@ -30,7 +30,7 @@ from PySide6.QtWidgets import *
|
||||
import uuid
|
||||
import functools
|
||||
|
||||
__all__ = ['UserSubsWindow']
|
||||
__all__ = ['SubscriptionWindow']
|
||||
|
||||
# Migrate legacy settings
|
||||
registerAppSettings('SubscriptionWidgetWindowSize')
|
||||
@@ -84,20 +84,20 @@ class AddSubsDialog(AppQDialog):
|
||||
return self.webURLEdit.text()
|
||||
|
||||
|
||||
class UserSubsWindow(AppQMainWindow):
|
||||
class SubscriptionWindow(AppQMainWindow):
|
||||
"""Present the user subs window."""
|
||||
|
||||
DEFAULT_WINDOW_SIZE = QtCore.QSize(1120, 600)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the UserSubsWindow."""
|
||||
"""Initialize the subscription window."""
|
||||
callback = kwargs.pop('deleteUniqueCallback', None)
|
||||
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.setWindowTitle(_('Edit Subscription'))
|
||||
|
||||
self.userSubsQTableWidget = UserSubsQTableView(
|
||||
self.userSubsQTableWidget = SubscriptionTableView(
|
||||
deleteUniqueCallback=callback, parent=self
|
||||
)
|
||||
|
||||
@@ -176,23 +176,23 @@ class UserSubsWindow(AppQMainWindow):
|
||||
width, height = tuple(int(size) for size in windowSize)
|
||||
|
||||
if (width, height) == (640, 480):
|
||||
self.resize(UserSubsWindow.DEFAULT_WINDOW_SIZE)
|
||||
self.resize(SubscriptionWindow.DEFAULT_WINDOW_SIZE)
|
||||
else:
|
||||
self.resize(width, height)
|
||||
except Exception:
|
||||
# Any non-exit exceptions
|
||||
|
||||
self.resize(UserSubsWindow.DEFAULT_WINDOW_SIZE)
|
||||
self.resize(SubscriptionWindow.DEFAULT_WINDOW_SIZE)
|
||||
else:
|
||||
if PLATFORM == 'Darwin':
|
||||
self.resize(UserSubsWindow.DEFAULT_WINDOW_SIZE)
|
||||
self.resize(SubscriptionWindow.DEFAULT_WINDOW_SIZE)
|
||||
else:
|
||||
try:
|
||||
self.restoreGeometry(AppSettings.get('UserSubsWindowGeometry'))
|
||||
except Exception:
|
||||
# Any non-exit exceptions
|
||||
|
||||
self.resize(UserSubsWindow.DEFAULT_WINDOW_SIZE)
|
||||
self.resize(SubscriptionWindow.DEFAULT_WINDOW_SIZE)
|
||||
|
||||
try:
|
||||
self.restoreState(AppSettings.get('UserSubsWindowState'))
|
||||
@@ -20,10 +20,11 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from Furious.Frozenlib import *
|
||||
from Furious.Library import *
|
||||
from Furious.Domain import *
|
||||
from Furious.Repository import *
|
||||
from Furious.Qt import *
|
||||
from Furious.Qt import gettext as _
|
||||
from Furious.Widget.IndentSpinBox import *
|
||||
from Furious.Window.IndentDialog import *
|
||||
|
||||
from PySide6 import QtCore
|
||||
from PySide6.QtGui import *
|
||||
@@ -367,7 +368,7 @@ class TextEditorWindow(AppQMainWindow):
|
||||
# Do nothing
|
||||
pass
|
||||
|
||||
indentSpinBox = IndentSpinBox(parent=self)
|
||||
indentSpinBox = IndentDialog(parent=self)
|
||||
indentSpinBox.finished.connect(
|
||||
functools.partial(handleResultCode, indentSpinBox)
|
||||
)
|
||||
@@ -21,7 +21,7 @@ from __future__ import annotations
|
||||
|
||||
from Furious.Frozenlib import *
|
||||
from Furious.Interface import *
|
||||
from Furious.Library import *
|
||||
from Furious.Repository import *
|
||||
from Furious.Qt import *
|
||||
from Furious.Qt import gettext as _
|
||||
|
||||
@@ -32,7 +32,7 @@ from PySide6.QtWidgets import *
|
||||
import logging
|
||||
import functools
|
||||
|
||||
__all__ = ['GuiTUNSettings']
|
||||
__all__ = ['TunSettingsDialog']
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -173,7 +173,7 @@ class AppQLabelHelpPage(AppQLabel):
|
||||
self.setWebsiteURL()
|
||||
|
||||
|
||||
class GuiTUNSettingsItemHelpPage(GuiEditorItemWidgetContainer):
|
||||
class GuiTUNSettingsItemHelpPage(EditorWidgetBinding):
|
||||
"""Provide the TUN settings item help configuration editor page."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
@@ -289,11 +289,11 @@ class GuiTUNSettingsGroupBoxMemory(GuiEditorWidgetQGroupBox):
|
||||
]
|
||||
|
||||
|
||||
class GuiTUNSettings(GuiEditorWidgetQDialog):
|
||||
class TunSettingsDialog(GuiEditorWidgetQDialog):
|
||||
"""Store and validate GUI TUN settings."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the GuiTUNSettings."""
|
||||
"""Initialize the tun2socks settings dialog."""
|
||||
tabTranslatable = kwargs.pop('tabTranslatable', True)
|
||||
style = kwargs.pop('style', 'portrait')
|
||||
|
||||
@@ -15,12 +15,28 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
"""Expose the application window classes."""
|
||||
"""Expose application windows and complete dialog compositions."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .AppMainWindow import AppMainWindow
|
||||
from .LogViewerWindow import LogViewerWindow
|
||||
from .UserSubsWindow import UserSubsWindow
|
||||
from .IndentDialog import IndentDialog
|
||||
from .LogWindow import LogWindow
|
||||
from .MainWindow import MainWindow
|
||||
from .NetworkTestDialog import NetworkTestDialog
|
||||
from .ProxyBypassDialog import ProxyBypassDialog
|
||||
from .QRCodeWindow import QRCodeWindow
|
||||
from .SubscriptionWindow import SubscriptionWindow
|
||||
from .TextEditorWindow import TextEditorWindow
|
||||
from .TunSettingsDialog import TunSettingsDialog
|
||||
|
||||
__all__ = ['AppMainWindow', 'LogViewerWindow', 'UserSubsWindow']
|
||||
__all__ = [
|
||||
'IndentDialog',
|
||||
'LogWindow',
|
||||
'MainWindow',
|
||||
'NetworkTestDialog',
|
||||
'ProxyBypassDialog',
|
||||
'QRCodeWindow',
|
||||
'SubscriptionWindow',
|
||||
'TextEditorWindow',
|
||||
'TunSettingsDialog',
|
||||
]
|
||||
|
||||
+5
-5
@@ -24,7 +24,7 @@ from Furious.Interface import *
|
||||
from Furious.Qt import *
|
||||
from Furious.Qt import gettext as _
|
||||
from Furious.Utility import *
|
||||
from Furious.Application import Application
|
||||
from Furious.Application import DesktopApplication
|
||||
|
||||
from PySide6 import QtCore
|
||||
from PySide6.QtGui import QDesktopServices
|
||||
@@ -59,7 +59,7 @@ def runClearSettings():
|
||||
|
||||
def runAppMain():
|
||||
"""Run app main."""
|
||||
process = AppMainProcess(functools.partial(Application, sys.argv))
|
||||
process = AppMainProcess(functools.partial(DesktopApplication, sys.argv))
|
||||
|
||||
process.start()
|
||||
process.join()
|
||||
@@ -70,9 +70,9 @@ def runAppMain():
|
||||
sys.exit(exitcode)
|
||||
|
||||
# For Qt runtime. Not used
|
||||
_app = Application(sys.argv)
|
||||
_app = DesktopApplication(sys.argv)
|
||||
|
||||
if exitcode == ApplicationFactory.ExitCode.PlatformNotSupported.value:
|
||||
if exitcode == ApplicationRunner.ExitCode.PlatformNotSupported.value:
|
||||
mbox = AppQMessageBox(icon=AppQMessageBox.Icon.Critical)
|
||||
|
||||
mbox.setWindowIcon(bootstrapIcon('rocket-takeoff-window.svg'))
|
||||
@@ -102,7 +102,7 @@ def runAppMain():
|
||||
# Show the MessageBox and wait for the user to close it
|
||||
mbox.exec()
|
||||
else:
|
||||
if exitcode == ApplicationFactory.ExitCode.AssertionError.value:
|
||||
if exitcode == ApplicationRunner.ExitCode.AssertionError.value:
|
||||
# Assertion error
|
||||
text = _(
|
||||
f'{APPLICATION_NAME} encountered an internal error and needs to be stopped'
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ from __future__ import annotations
|
||||
|
||||
from Furious.Frozenlib import *
|
||||
from Furious.Externals import *
|
||||
from Furious.Library import *
|
||||
from Furious.Domain import *
|
||||
|
||||
import os
|
||||
import re
|
||||
|
||||
Reference in New Issue
Block a user