Cura/plugins/DigitalLibrary/src/DigitalFactoryFileModel.py
Jaime van Kessel 6dd62f9024
Add tests for DFFileModel
CURA-7959
2021-04-26 14:34:30 +02:00

117 lines
4.2 KiB
Python

# Copyright (c) 2021 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from typing import List, Dict, Callable
from PyQt5.QtCore import Qt, pyqtSignal
from UM.Logger import Logger
from UM.Qt.ListModel import ListModel
from .DigitalFactoryFileResponse import DigitalFactoryFileResponse
DIGITAL_FACTORY_DISPLAY_DATETIME_FORMAT = "%d-%m-%Y %H:%M"
class DigitalFactoryFileModel(ListModel):
FileNameRole = Qt.UserRole + 1
FileIdRole = Qt.UserRole + 2
FileSizeRole = Qt.UserRole + 3
LibraryProjectIdRole = Qt.UserRole + 4
DownloadUrlRole = Qt.UserRole + 5
UsernameRole = Qt.UserRole + 6
UploadedAtRole = Qt.UserRole + 7
dfFileModelChanged = pyqtSignal()
def __init__(self, parent = None):
super().__init__(parent)
self.addRoleName(self.FileNameRole, "fileName")
self.addRoleName(self.FileIdRole, "fileId")
self.addRoleName(self.FileSizeRole, "fileSize")
self.addRoleName(self.LibraryProjectIdRole, "libraryProjectId")
self.addRoleName(self.DownloadUrlRole, "downloadUrl")
self.addRoleName(self.UsernameRole, "username")
self.addRoleName(self.UploadedAtRole, "uploadedAt")
self._files = [] # type: List[DigitalFactoryFileResponse]
self._filters = {} # type: Dict[str, Callable]
def setFiles(self, df_files_in_project: List[DigitalFactoryFileResponse]) -> None:
if self._files == df_files_in_project:
return
self.clear()
self._files = df_files_in_project
self._update()
def clearFiles(self) -> None:
self.clear()
self._files.clear()
self.dfFileModelChanged.emit()
def _update(self) -> None:
filtered_files_list = self.getFilteredFilesList()
for file in filtered_files_list:
self.appendItem({
"fileName" : file.file_name,
"fileId" : file.file_id,
"fileSize": file.file_size,
"libraryProjectId": file.library_project_id,
"downloadUrl": file.download_url,
"username": file.username,
"uploadedAt": file.uploaded_at.strftime(DIGITAL_FACTORY_DISPLAY_DATETIME_FORMAT)
})
self.dfFileModelChanged.emit()
def setFilters(self, filters: Dict[str, Callable]) -> None:
"""
Sets the filters and updates the files model to contain only the files that meet all of the filters.
:param filters: The filters to be applied
example:
{
"attribute_name1": function_to_be_applied_on_DigitalFactoryFileResponse_attribute1,
"attribute_name2": function_to_be_applied_on_DigitalFactoryFileResponse_attribute2
}
"""
self.clear()
self._filters = filters
self._update()
def clearFilters(self) -> None:
"""
Clears all the model filters
"""
self.setFilters({})
def getFilteredFilesList(self) -> List[DigitalFactoryFileResponse]:
"""
Lists the files that meet all the filters specified in the self._filters. This is achieved by applying each
filter function on the corresponding attribute for all the filters in the self._filters. If all of them are
true, the file is added to the filtered files list.
In order for this to work, the self._filters should be in the format:
{
"attribute_name": function_to_be_applied_on_the_DigitalFactoryFileResponse_attribute
}
:return: The list of files that meet all the specified filters
"""
if not self._filters:
return self._files
filtered_files_list = []
for file in self._files:
filter_results = []
for attribute, filter_func in self._filters.items():
try:
filter_results.append(filter_func(getattr(file, attribute)))
except AttributeError:
Logger.log("w", "Attribute '{}' doesn't exist in objects of type '{}'".format(attribute, type(file)))
all_filters_met = all(filter_results)
if all_filters_met:
filtered_files_list.append(file)
return filtered_files_list