MachineNameValidator.py 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. # Copyright (c) 2016 Ultimaker B.V.
  2. # Cura is released under the terms of the LGPLv3 or higher.
  3. from PyQt5.QtCore import pyqtSlot, pyqtProperty, QObject, pyqtSignal, QRegExp
  4. from PyQt5.QtGui import QValidator
  5. import os #For statvfs.
  6. import urllib #To escape machine names for how they're saved to file.
  7. from UM.Resources import Resources
  8. from UM.Settings.ContainerRegistry import ContainerRegistry
  9. from UM.Settings.InstanceContainer import InstanceContainer
  10. ## Are machine names valid?
  11. #
  12. # Performs checks based on the length of the name.
  13. class MachineNameValidator(QObject):
  14. def __init__(self, parent = None):
  15. super().__init__(parent)
  16. #Compute the validation regex for printer names. This is limited by the maximum file name length.
  17. try:
  18. filename_max_length = os.statvfs(Resources.getDataStoragePath()).f_namemax
  19. except AttributeError: #Doesn't support statvfs. Probably because it's not a Unix system.
  20. filename_max_length = 255 #Assume it's Windows on NTFS.
  21. machine_name_max_length = filename_max_length - len("_current_settings.") - len(ContainerRegistry.getMimeTypeForContainer(InstanceContainer).preferredSuffix)
  22. # Characters that urllib.parse.quote_plus escapes count for 12! So now
  23. # we must devise a regex that allows only 12 normal characters or 1
  24. # special character, and that up to [machine_name_max_length / 12] times.
  25. maximum_special_characters = int(machine_name_max_length / 12)
  26. unescaped = r"[a-zA-Z0-9_\-\.\/]"
  27. self.machine_name_regex = r"^((" + unescaped + "){0,12}|.){0," + str(maximum_special_characters) + r"}$"
  28. validationChanged = pyqtSignal()
  29. ## Check if a specified machine name is allowed.
  30. #
  31. # \param name The machine name to check.
  32. # \return ``QValidator.Invalid`` if it's disallowed, or
  33. # ``QValidator.Acceptable`` if it's allowed.
  34. def validate(self, name):
  35. #Check for file name length of the current settings container (which is the longest file we're saving with the name).
  36. try:
  37. filename_max_length = os.statvfs(Resources.getDataStoragePath()).f_namemax
  38. except AttributeError: #Doesn't support statvfs. Probably because it's not a Unix system.
  39. filename_max_length = 255 #Assume it's Windows on NTFS.
  40. escaped_name = urllib.parse.quote_plus(name)
  41. current_settings_filename = escaped_name + "_current_settings." + ContainerRegistry.getMimeTypeForContainer(InstanceContainer).preferredSuffix
  42. if len(current_settings_filename) > filename_max_length:
  43. return QValidator.Invalid
  44. return QValidator.Acceptable #All checks succeeded.
  45. ## Updates the validation state of a machine name text field.
  46. @pyqtSlot(str)
  47. def updateValidation(self, new_name):
  48. is_valid = self.validate(new_name)
  49. if is_valid == QValidator.Acceptable:
  50. self.validation_regex = "^.*$" #Matches anything.
  51. else:
  52. self.validation_regex = "a^" #Never matches (unless you manage to get "a" before the start of the string... good luck).
  53. self.validationChanged.emit()
  54. @pyqtProperty("QRegExp", notify=validationChanged)
  55. def machineNameRegex(self):
  56. return QRegExp(self.machine_name_regex)