Use a separate function to validate IP address

CURA-6483
This commit is contained in:
Lipu Fei 2019-04-29 15:52:21 +02:00
parent defcba6927
commit c8872cb4a1
4 changed files with 79 additions and 1 deletions

View file

@ -117,6 +117,8 @@ from cura.UI.AddPrinterPagesModel import AddPrinterPagesModel
from cura.UI.WelcomePagesModel import WelcomePagesModel from cura.UI.WelcomePagesModel import WelcomePagesModel
from cura.UI.WhatsNewPagesModel import WhatsNewPagesModel from cura.UI.WhatsNewPagesModel import WhatsNewPagesModel
from cura.Utils.QtUtil import QtUtil
from .SingleInstance import SingleInstance from .SingleInstance import SingleInstance
from .AutoSave import AutoSave from .AutoSave import AutoSave
from . import PlatformPhysics from . import PlatformPhysics
@ -1028,6 +1030,8 @@ class CuraApplication(QtApplication):
qmlRegisterSingletonType(SimpleModeSettingsManager, "Cura", 1, 0, "SimpleModeSettingsManager", self.getSimpleModeSettingsManager) qmlRegisterSingletonType(SimpleModeSettingsManager, "Cura", 1, 0, "SimpleModeSettingsManager", self.getSimpleModeSettingsManager)
qmlRegisterSingletonType(MachineActionManager.MachineActionManager, "Cura", 1, 0, "MachineActionManager", self.getMachineActionManager) qmlRegisterSingletonType(MachineActionManager.MachineActionManager, "Cura", 1, 0, "MachineActionManager", self.getMachineActionManager)
qmlRegisterType(QtUtil, "Cura", 1, 0, "QtUtil")
qmlRegisterType(WelcomePagesModel, "Cura", 1, 0, "WelcomePagesModel") qmlRegisterType(WelcomePagesModel, "Cura", 1, 0, "WelcomePagesModel")
qmlRegisterType(WhatsNewPagesModel, "Cura", 1, 0, "WhatsNewPagesModel") qmlRegisterType(WhatsNewPagesModel, "Cura", 1, 0, "WhatsNewPagesModel")
qmlRegisterType(AddPrinterPagesModel, "Cura", 1, 0, "AddPrinterPagesModel") qmlRegisterType(AddPrinterPagesModel, "Cura", 1, 0, "AddPrinterPagesModel")

21
cura/Utils/QtUtil.py Normal file
View file

@ -0,0 +1,21 @@
# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from typing import Optional
from PyQt5.QtCore import QObject, pyqtSlot
from . import networking
#
# Exposes the util functions to QML using a QObject.
#
class QtUtil(QObject):
def __init__(self, parent: Optional["QObject"] = None) -> None:
super().__init__(parent = parent)
@pyqtSlot(str, result = bool)
def isValidIP(self, address: str) -> bool:
return networking.isValidIP(address)

26
cura/Utils/networking.py Normal file
View file

@ -0,0 +1,26 @@
# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
import re
_REGEX_IPV4 = re.compile(r"^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$")
_REGEX_IPV6 = re.compile(r"^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$")
# Checks if the given string is a valid IPv4 address.
def isIPv4(address: str) -> bool:
return _REGEX_IPV4.fullmatch(address) is not None
# Checks if the given string is a valid IPv6 address.
def isIPv6(address: str) -> bool:
return _REGEX_IPV6.fullmatch(address) is not None
# Checks if the given string is a valid IPv4 or IPv6 address.
def isValidIP(address: str) -> bool:
return isIPv4(address) or isIPv6(address)
__all__ = ["isIPv4", "isIPv6", "isValidIP"]

View file

@ -26,6 +26,9 @@ Item
property var discoveredPrinter: null property var discoveredPrinter: null
property var isPrinterDiscovered: discoveredPrinter != null property var isPrinterDiscovered: discoveredPrinter != null
// For validating IP address
property var util: Cura.QtUtil{}
// Make sure to cancel the current request when this page closes. // Make sure to cancel the current request when this page closes.
onVisibleChanged: onVisibleChanged:
{ {
@ -93,17 +96,36 @@ Item
anchors.verticalCenter: addPrinterButton.verticalCenter anchors.verticalCenter: addPrinterButton.verticalCenter
anchors.left: parent.left anchors.left: parent.left
signal invalidInputDetected()
onInvalidInputDetected: invalidInputLabel.visible = true
validator: RegExpValidator validator: RegExpValidator
{ {
regExp: /((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$))?/ regExp: /([a-zA-Z0-9.:]+)?/
} }
onTextEdited: invalidInputLabel.visible = false
placeholderText: catalog.i18nc("@text", "Place enter your printer's IP address.") placeholderText: catalog.i18nc("@text", "Place enter your printer's IP address.")
enabled: { ! (addPrinterByIpScreen.hasRequestInProgress || addPrinterByIpScreen.isPrinterDiscovered) } enabled: { ! (addPrinterByIpScreen.hasRequestInProgress || addPrinterByIpScreen.isPrinterDiscovered) }
onAccepted: addPrinterButton.clicked() onAccepted: addPrinterButton.clicked()
} }
Label
{
id: invalidInputLabel
anchors.top: hostnameField.bottom
anchors.topMargin: UM.Theme.getSize("default_margin").height
anchors.left: parent.left
visible: false
text: catalog.i18nc("@text", "Place enter a valid IP address.")
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text")
renderType: Text.NativeRendering
}
Cura.SecondaryButton Cura.SecondaryButton
{ {
id: addPrinterButton id: addPrinterButton
@ -115,6 +137,11 @@ Item
onClicked: onClicked:
{ {
const address = hostnameField.text const address = hostnameField.text
if (!util.isValidIP(address))
{
hostnameField.invalidInputDetected()
return
}
// This address is already in the discovered printer model, no need to add a manual discovery. // This address is already in the discovered printer model, no need to add a manual discovery.
if (CuraApplication.getDiscoveredPrintersModel().discoveredPrintersByAddress[address]) if (CuraApplication.getDiscoveredPrintersModel().discoveredPrintersByAddress[address])