AuthorsModel.py 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. # Copyright (c) 2018 Ultimaker B.V.
  2. # Cura is released under the terms of the LGPLv3 or higher.
  3. import re
  4. from typing import Dict
  5. from PyQt5.QtCore import Qt, pyqtProperty, pyqtSignal
  6. from UM.Qt.ListModel import ListModel
  7. ## Model that holds cura packages. By setting the filter property the instances held by this model can be changed.
  8. class AuthorsModel(ListModel):
  9. def __init__(self, parent = None):
  10. super().__init__(parent)
  11. self._metadata = None
  12. self.addRoleName(Qt.UserRole + 1, "name")
  13. self.addRoleName(Qt.UserRole + 2, "email")
  14. self.addRoleName(Qt.UserRole + 3, "website")
  15. self.addRoleName(Qt.UserRole + 4, "type")
  16. self.addRoleName(Qt.UserRole + 5, "icon_url")
  17. self.addRoleName(Qt.UserRole + 6, "packages_count")
  18. self.addRoleName(Qt.UserRole + 7, "description")
  19. # List of filters for queries. The result is the union of the each list of results.
  20. self._filter = {} # type: Dict[str,str]
  21. def setMetadata(self, data):
  22. self._metadata = data
  23. self._update()
  24. def _update(self):
  25. items = []
  26. for author in self._metadata:
  27. items.append({
  28. "name": author["name"],
  29. "email": author["email"] if "email" in author else None,
  30. "website": author["website"],
  31. "type": author["type"] if "type" in author else None,
  32. "icon_url": author["icon_url"] if "icon_url" in author else None,
  33. "packages_count": author["packages_count"] if "packages_count" in author else 0,
  34. "description": "Material and quality profiles from {author_name}".format( author_name = author["name"])
  35. })
  36. # Filter on all the key-word arguments.
  37. for key, value in self._filter.items():
  38. if "*" in value:
  39. key_filter = lambda candidate, key = key, value = value: self._matchRegExp(candidate, key, value)
  40. else:
  41. key_filter = lambda candidate, key = key, value = value: self._matchString(candidate, key, value)
  42. items = filter(key_filter, items)
  43. # Execute all filters.
  44. filtered_items = list(items)
  45. filtered_items.sort(key = lambda k: k["name"])
  46. self.setItems(filtered_items)
  47. ## Set the filter of this model based on a string.
  48. # \param filter_dict \type{Dict} Dictionary to do the filtering by.
  49. def setFilter(self, filter_dict: Dict[str, str]) -> None:
  50. if filter_dict != self._filter:
  51. self._filter = filter_dict
  52. self._update()
  53. @pyqtProperty("QVariantMap", fset = setFilter, constant = True)
  54. def filter(self) -> Dict[str, str]:
  55. return self._filter
  56. # Check to see if a container matches with a regular expression
  57. def _matchRegExp(self, metadata, property_name, value):
  58. if property_name not in metadata:
  59. return False
  60. value = re.escape(value) #Escape for regex patterns.
  61. value = "^" + value.replace("\\*", ".*") + "$" #Instead of (now escaped) asterisks, match on any string. Also add anchors for a complete match.
  62. if self._ignore_case:
  63. value_pattern = re.compile(value, re.IGNORECASE)
  64. else:
  65. value_pattern = re.compile(value)
  66. return value_pattern.match(str(metadata[property_name]))
  67. # Check to see if a container matches with a string
  68. def _matchString(self, metadata, property_name, value):
  69. if property_name not in metadata:
  70. return False
  71. return value.lower() == str(metadata[property_name]).lower()