mirror of
https://github.com/LorenEteval/Furious.git
synced 2026-10-04 21:08:04 +03:00
Added support for customizing proxy bypass address & network test URL
Signed-off-by: Loren Eteval <loren.eteval@proton.me>
This commit is contained in:
@@ -73,7 +73,15 @@ class NetworkStateManager(Mixins.ConnectionAware, WebGETManager):
|
||||
self.jobArrangeTimer.start(self.recalculateJobInterval(jobStatus=False))
|
||||
|
||||
def startSingleTest(self):
|
||||
networkReply = self.webGET(NETWORK_STATE_TEST_URL)
|
||||
# Use custom network state test URL if possible
|
||||
settings = AppSettings.get('CustomNetworkStateTestURL')
|
||||
|
||||
if settings is None:
|
||||
url = NETWORK_SPEED_TEST_URL
|
||||
else:
|
||||
url = settings
|
||||
|
||||
networkReply = self.webGET(url)
|
||||
|
||||
def abort(_networkReply):
|
||||
if isinstance(_networkReply, QNetworkReply):
|
||||
|
||||
@@ -253,21 +253,44 @@ class ConnectAction(AppQAction):
|
||||
|
||||
if self.actionQueue.empty():
|
||||
if success:
|
||||
SystemProxy.set(httpProxy, PROXY_SERVER_BYPASS)
|
||||
# Use custom proxy bypass address if possible
|
||||
settings = AppSettings.get('CustomProxyBypass')
|
||||
|
||||
self.doConnected()
|
||||
|
||||
APP().systemTray.showMessage(
|
||||
f'{config.coreName()}: ' + _('Connected')
|
||||
)
|
||||
|
||||
if AppSettings.isStateON_('PowerSaveMode'):
|
||||
# Power optimization
|
||||
self.actionTimer.start(CORE_CHECK_ALIVE_INTERVAL * 2)
|
||||
if settings is None:
|
||||
proxyServerBypass = PROXY_SERVER_BYPASS
|
||||
else:
|
||||
self.actionTimer.start(CORE_CHECK_ALIVE_INTERVAL)
|
||||
proxyServerBypass = settings
|
||||
|
||||
self.doConnectedCallOnceOnly()
|
||||
try:
|
||||
SystemProxy.set(httpProxy, proxyServerBypass)
|
||||
except Exception as ex:
|
||||
# Any non-exit exceptions
|
||||
|
||||
logger.error(f'error while setting http proxy: {ex}')
|
||||
logger.error(
|
||||
f'failed to connect successfully. '
|
||||
f'This may be due to improper proxy '
|
||||
f'server bypass settings: {proxyServerBypass}'
|
||||
)
|
||||
|
||||
self.coreManager.stopAll()
|
||||
self.doDisconnectWithTrayMessage(
|
||||
f'{config.coreName()}: ' + _('Unknown error')
|
||||
)
|
||||
else:
|
||||
self.doConnected()
|
||||
|
||||
APP().systemTray.showMessage(
|
||||
f'{config.coreName()}: ' + _('Connected')
|
||||
)
|
||||
|
||||
if AppSettings.isStateON_('PowerSaveMode'):
|
||||
# Power optimization
|
||||
self.actionTimer.start(CORE_CHECK_ALIVE_INTERVAL * 2)
|
||||
else:
|
||||
self.actionTimer.start(CORE_CHECK_ALIVE_INTERVAL)
|
||||
|
||||
self.doConnectedCallOnceOnly()
|
||||
else:
|
||||
logger.error('failed to start core manager')
|
||||
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
# 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/>.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from Furious.Frozenlib import *
|
||||
from Furious.Qt import *
|
||||
from Furious.Qt import gettext as _
|
||||
|
||||
from PySide6 import QtCore
|
||||
from PySide6.QtWidgets import *
|
||||
|
||||
import logging
|
||||
import functools
|
||||
|
||||
__all__ = ['GuiCustomizeNetworkTestDialog']
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
registerAppSettings('CustomNetworkSpeedTestURL')
|
||||
registerAppSettings('CustomNetworkStateTestURL')
|
||||
|
||||
|
||||
class GuiCustomizeNetworkTestDialog(AppQDialog):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.setWindowTitle(_('Customize Network Test URL'))
|
||||
self.setWindowModality(QtCore.Qt.WindowModality.WindowModal)
|
||||
|
||||
self.speedTestURLText = AppQLabel(_('Enter network speed test URL:'))
|
||||
self.speedTestURLEdit = QLineEdit()
|
||||
|
||||
speedTestSettings = AppSettings.get('CustomNetworkSpeedTestURL')
|
||||
|
||||
if speedTestSettings is None:
|
||||
self.speedTestURLEdit.setText(NETWORK_SPEED_TEST_URL)
|
||||
else:
|
||||
self.speedTestURLEdit.setText(speedTestSettings)
|
||||
|
||||
self.stateTestURLText = AppQLabel(_('Enter network state test URL:'))
|
||||
self.stateTestURLEdit = QLineEdit()
|
||||
|
||||
stateTestSettings = AppSettings.get('CustomNetworkStateTestURL')
|
||||
|
||||
if stateTestSettings is None:
|
||||
self.stateTestURLEdit.setText(NETWORK_STATE_TEST_URL)
|
||||
else:
|
||||
self.stateTestURLEdit.setText(stateTestSettings)
|
||||
|
||||
self.dialogBtns = AppQDialogButtonBox(QtCore.Qt.Orientation.Horizontal)
|
||||
self.dialogBtns.addButton(_('OK'), AppQDialogButtonBox.ButtonRole.AcceptRole)
|
||||
self.dialogBtns.addButton(
|
||||
_('Cancel'), AppQDialogButtonBox.ButtonRole.RejectRole
|
||||
)
|
||||
self.dialogBtns.accepted.connect(self.accept)
|
||||
self.dialogBtns.rejected.connect(self.reject)
|
||||
|
||||
self.speedTestResetBtn = AppQPushButton(_('Reset'))
|
||||
self.speedTestResetBtn.clicked.connect(
|
||||
lambda: self.speedTestURLEdit.setText(NETWORK_SPEED_TEST_URL)
|
||||
)
|
||||
self.stateTestResetBtn = AppQPushButton(_('Reset'))
|
||||
self.stateTestResetBtn.clicked.connect(
|
||||
lambda: self.stateTestURLEdit.setText(NETWORK_STATE_TEST_URL)
|
||||
)
|
||||
|
||||
self.speedTestHboxLayout = QHBoxLayout()
|
||||
self.speedTestHboxLayout.addWidget(self.speedTestURLEdit)
|
||||
self.speedTestHboxLayout.addWidget(self.speedTestResetBtn)
|
||||
|
||||
self.stateTestHboxLayout = QHBoxLayout()
|
||||
self.stateTestHboxLayout.addWidget(self.stateTestURLEdit)
|
||||
self.stateTestHboxLayout.addWidget(self.stateTestResetBtn)
|
||||
|
||||
layout = QFormLayout()
|
||||
layout.addRow(self.speedTestURLText)
|
||||
layout.addRow(self.speedTestHboxLayout)
|
||||
layout.addRow(self.stateTestURLText)
|
||||
layout.addRow(self.stateTestHboxLayout)
|
||||
layout.addRow(self.dialogBtns)
|
||||
layout.setFormAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
|
||||
|
||||
self.setLayout(layout)
|
||||
|
||||
self.finished.connect(functools.partial(self.handleResultCode))
|
||||
|
||||
def setWidthAndHeight(self):
|
||||
self.resize(656, 180)
|
||||
|
||||
def handleResultCode(self, code):
|
||||
for widget, info, settingsName, reset in [
|
||||
(
|
||||
self.speedTestURLEdit,
|
||||
'speed test URL',
|
||||
'CustomNetworkSpeedTestURL',
|
||||
NETWORK_SPEED_TEST_URL,
|
||||
),
|
||||
(
|
||||
self.stateTestURLEdit,
|
||||
'state test URL',
|
||||
'CustomNetworkStateTestURL',
|
||||
NETWORK_STATE_TEST_URL,
|
||||
),
|
||||
]:
|
||||
if code == PySide6Legacy.enumValueWrapper(AppQDialog.DialogCode.Accepted):
|
||||
value = widget.text()
|
||||
|
||||
logger.info(f'setting {info} to \'{value}\'')
|
||||
|
||||
AppSettings.set(settingsName, value)
|
||||
else:
|
||||
try:
|
||||
settings = AppSettings.get(settingsName)
|
||||
|
||||
if settings is not None:
|
||||
widget.setText(str(settings))
|
||||
else:
|
||||
widget.setText(reset)
|
||||
except Exception as ex:
|
||||
# Any non-exit exceptions
|
||||
|
||||
logger.error(f'error restoring {info}: {ex}')
|
||||
@@ -0,0 +1,107 @@
|
||||
# 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/>.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from Furious.Frozenlib import *
|
||||
from Furious.Qt import *
|
||||
from Furious.Qt import gettext as _
|
||||
|
||||
from PySide6 import QtCore
|
||||
from PySide6.QtWidgets import *
|
||||
|
||||
import logging
|
||||
import functools
|
||||
|
||||
__all__ = ['GuiCustomizeProxyBypassDialog']
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
registerAppSettings('CustomProxyBypass')
|
||||
|
||||
|
||||
class GuiCustomizeProxyBypassDialog(AppQDialog):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.setWindowTitle(_('Customize Proxy Bypass Address'))
|
||||
self.setWindowModality(QtCore.Qt.WindowModality.WindowModal)
|
||||
|
||||
self.proxyBypassText = AppQLabel(
|
||||
_('Enter proxy bypass address (separated by semicolons):')
|
||||
)
|
||||
self.proxyBypassEdit = QLineEdit()
|
||||
|
||||
settings = AppSettings.get('CustomProxyBypass')
|
||||
|
||||
if settings is None:
|
||||
self.proxyBypassEdit.setText(PROXY_SERVER_BYPASS)
|
||||
else:
|
||||
self.proxyBypassEdit.setText(settings)
|
||||
|
||||
self.dialogBtns = AppQDialogButtonBox(QtCore.Qt.Orientation.Horizontal)
|
||||
self.dialogBtns.addButton(_('OK'), AppQDialogButtonBox.ButtonRole.AcceptRole)
|
||||
self.dialogBtns.addButton(
|
||||
_('Cancel'), AppQDialogButtonBox.ButtonRole.RejectRole
|
||||
)
|
||||
self.dialogBtns.accepted.connect(self.accept)
|
||||
self.dialogBtns.rejected.connect(self.reject)
|
||||
|
||||
self.resetBtn = AppQPushButton(_('Reset'))
|
||||
self.resetBtn.clicked.connect(functools.partial(self.handleResetButtonClicked))
|
||||
|
||||
self.hboxLayout = QHBoxLayout()
|
||||
self.hboxLayout.addWidget(self.resetBtn)
|
||||
self.hboxLayout.addWidget(self.dialogBtns)
|
||||
|
||||
layout = QFormLayout()
|
||||
layout.addRow(self.proxyBypassText)
|
||||
layout.addRow(self.proxyBypassEdit)
|
||||
layout.addRow(self.hboxLayout)
|
||||
layout.setFormAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
|
||||
|
||||
self.setLayout(layout)
|
||||
|
||||
self.finished.connect(functools.partial(self.handleResultCode))
|
||||
|
||||
def setWidthAndHeight(self):
|
||||
self.resize(656, 125)
|
||||
|
||||
def handleResultCode(self, code):
|
||||
if code == PySide6Legacy.enumValueWrapper(AppQDialog.DialogCode.Accepted):
|
||||
value = self.proxyBypassEdit.text()
|
||||
|
||||
logger.info(f'setting custom proxy bypass address to \'{value}\'')
|
||||
|
||||
AppSettings.set('CustomProxyBypass', value)
|
||||
|
||||
showMBoxNewChangesNextTime()
|
||||
else:
|
||||
try:
|
||||
settings = AppSettings.get('CustomProxyBypass')
|
||||
|
||||
if settings is not None:
|
||||
self.proxyBypassEdit.setText(str(settings))
|
||||
else:
|
||||
self.proxyBypassEdit.setText(PROXY_SERVER_BYPASS)
|
||||
except Exception as ex:
|
||||
# Any non-exit exceptions
|
||||
|
||||
logger.error(f'error restoring proxy bypass address: {ex}')
|
||||
|
||||
def handleResetButtonClicked(self):
|
||||
self.proxyBypassEdit.setText(PROXY_SERVER_BYPASS)
|
||||
@@ -596,9 +596,15 @@ class TestDownloadSpeedWorker(WebGETManager):
|
||||
|
||||
self.configureHttpProxy(f'127.0.0.1:{self.port}')
|
||||
|
||||
self.networkReply = self.webGET(
|
||||
NETWORK_SPEED_TEST_URL, **self.kwargs
|
||||
)
|
||||
# Use custom network speed test URL if possible
|
||||
settings = AppSettings.get('CustomNetworkSpeedTestURL')
|
||||
|
||||
if settings is None:
|
||||
url = NETWORK_SPEED_TEST_URL
|
||||
else:
|
||||
url = settings
|
||||
|
||||
self.networkReply = self.webGET(url, **self.kwargs)
|
||||
|
||||
self.elapsedTimer.start()
|
||||
self.timeoutTimer.start(self.timeout)
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
from .Application import *
|
||||
from .ConnectProgressBar import *
|
||||
from .GuiCustomizeNetworkTest import *
|
||||
from .GuiCustomizeProxyBypass import *
|
||||
from .GuiHysteria1 import *
|
||||
from .GuiHysteria2 import *
|
||||
from .GuiShadowsocks import *
|
||||
|
||||
@@ -23,6 +23,8 @@ from Furious.Library import *
|
||||
from Furious.Qt import *
|
||||
from Furious.Qt import gettext as _
|
||||
from Furious.Widget.UserServersQTableWidget import *
|
||||
from Furious.Widget.GuiCustomizeNetworkTest import *
|
||||
from Furious.Widget.GuiCustomizeProxyBypass import *
|
||||
from Furious.Widget.GuiTUNSettings import *
|
||||
from Furious.Window.UserSubsWindow import *
|
||||
from Furious.Window.XrayAssetViewerWindow import *
|
||||
@@ -129,6 +131,8 @@ class AppMainWindow(AppQMainWindow):
|
||||
),
|
||||
)
|
||||
self.xrayAssetViewerWindow = XrayAssetViewerWindow(parent=self)
|
||||
self.customizeProxyBypassDialog = GuiCustomizeProxyBypassDialog(parent=self)
|
||||
self.customizeNetworkTestDialog = GuiCustomizeNetworkTestDialog(parent=self)
|
||||
|
||||
self.mainTab = AppQTabWidget()
|
||||
self.mainTab.addTab(self.userServersQTableWidget, _('Server'))
|
||||
@@ -248,7 +252,6 @@ class AppMainWindow(AppQMainWindow):
|
||||
checkable=False,
|
||||
callback=lambda: self.getGuiTUNSettings().open(),
|
||||
),
|
||||
AppQSeperator(),
|
||||
]
|
||||
|
||||
if PLATFORM == 'Windows' or PLATFORM == 'Darwin':
|
||||
@@ -285,6 +288,18 @@ class AppMainWindow(AppQMainWindow):
|
||||
|
||||
toolsActions = [
|
||||
*customizeTUNSettingsAction,
|
||||
AppQAction(
|
||||
_('Customize Proxy Bypass Address...'),
|
||||
checkable=False,
|
||||
callback=lambda: self.customizeProxyBypassDialog.open(),
|
||||
),
|
||||
AppQAction(
|
||||
_('Customize Network Test URL...'),
|
||||
icon=bootstrapIcon('speedometer2.svg'),
|
||||
checkable=False,
|
||||
callback=lambda: self.customizeNetworkTestDialog.open(),
|
||||
),
|
||||
AppQSeperator(),
|
||||
*restartAsAdminAction,
|
||||
*openAppFolderAction,
|
||||
AppQAction(
|
||||
|
||||
Reference in New Issue
Block a user