Merge branch 'master' of github.com:Ultimaker/Cura into CURA-7090-addition

This commit is contained in:
Dimitriovski 2020-01-21 15:08:24 +01:00
commit 369329c476
No known key found for this signature in database
GPG key ID: 4E62757E2B0D304D
10 changed files with 120 additions and 15 deletions

View file

@ -56,6 +56,13 @@ function(cura_add_test)
endif()
endfunction()
#Add test for import statements which are not compatible with all builds
add_test(
NAME "invalid-imports"
COMMAND ${Python3_EXECUTABLE} scripts/check_invalid_imports.py
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
cura_add_test(NAME pytest-main DIRECTORY ${CMAKE_SOURCE_DIR}/tests PYTHONPATH "${CMAKE_SOURCE_DIR}|${URANIUM_DIR}")
file(GLOB_RECURSE _plugins plugins/*/__init__.py)

View file

@ -13,6 +13,8 @@ export PKG_CONFIG_PATH="${CURA_BUILD_ENV_PATH}/lib/pkgconfig:${PKG_CONFIG_PATH}"
cd "${PROJECT_DIR}"
#
# Clone Uranium and set PYTHONPATH first
#

View file

@ -152,7 +152,7 @@ UM.Dialog{
} // End of ScrollView
Cura.ActionButton
Cura.PrimaryButton
{
id: nextButton
anchors.bottom: parent.bottom
@ -160,6 +160,8 @@ UM.Dialog{
anchors.margins: UM.Theme.getSize("default_margin").height
text: catalog.i18nc("@button", "Next")
onClicked: accept()
leftPadding: UM.Theme.getSize("dialog_primary_button_padding").width
rightPadding: UM.Theme.getSize("dialog_primary_button_padding").width
}
}
}

View file

@ -10,6 +10,7 @@ import QtQuick.Controls.Styles 1.4
// TODO: Switch to QtQuick.Controls 2.x and remove QtQuick.Controls.Styles
import UM 1.1 as UM
import Cura 1.6 as Cura
UM.Dialog
{
@ -51,18 +52,22 @@ UM.Dialog
}
rightButtons:
[
Button
Cura.PrimaryButton
{
id: acceptButton
anchors.margins: UM.Theme.getSize("default_margin").width
text: catalog.i18nc("@action:button", "Accept")
leftPadding: UM.Theme.getSize("dialog_primary_button_padding").width
rightPadding: UM.Theme.getSize("dialog_primary_button_padding").width
text: catalog.i18nc("@button", "Agree")
onClicked: { handler.onLicenseAccepted() }
},
Button
}
]
leftButtons:
[
Cura.SecondaryButton
{
id: declineButton
anchors.margins: UM.Theme.getSize("default_margin").width
text: catalog.i18nc("@action:button", "Decline")
text: catalog.i18nc("@button", "Decline and remove from account")
onClicked: { handler.onLicenseDeclined() }
}
]

View file

@ -18,3 +18,11 @@ class CloudApiModel:
cloud_api_root=cloud_api_root,
cloud_api_version=cloud_api_version,
)
## https://api.ultimaker.com/cura-packages/v1/user/packages/{package_id}
@classmethod
def userPackageUrl(cls, package_id: str) -> str:
return (CloudApiModel.api_url_user_packages + "/{package_id}").format(
package_id=package_id
)

View file

@ -16,3 +16,8 @@ class CloudPackageManager:
data=data.encode(),
scope=self._scope
)
def unsubscribe(self, package_id: str) -> None:
url = CloudApiModel.userPackageUrl(package_id)
self._request_manager.delete(url=url, scope=self._scope)

View file

@ -1,8 +1,10 @@
import os
from typing import List, Dict, Any, cast
from UM import i18n_catalog
from UM.Extension import Extension
from UM.Logger import Logger
from UM.Message import Message
from UM.PluginRegistry import PluginRegistry
from cura.CuraApplication import CuraApplication
from .CloudPackageChecker import CloudPackageChecker
@ -64,7 +66,10 @@ class SyncOrchestrator(Extension):
# \param success_items: Dict[package_id, file_path]
# \param error_items: List[package_id]
def _onDownloadFinished(self, success_items: Dict[str, str], error_items: List[str]) -> None:
# todo handle error items
if error_items:
message = i18n_catalog.i18nc("@info:generic", "{} plugins failed to download".format(len(error_items)))
self._showErrorMessage(message)
plugin_path = cast(str, PluginRegistry.getInstance().getPluginPath(self.getPluginId()))
self._license_presenter.present(plugin_path, success_items)
@ -78,15 +83,20 @@ class SyncOrchestrator(Extension):
if item["accepted"]:
# install and subscribe packages
if not self._package_manager.installPackage(item["package_path"]):
Logger.error("could not install {}".format(item["package_id"]))
message = "Could not install {}".format(item["package_id"])
self._showErrorMessage(message)
continue
self._cloud_package_manager.subscribe(item["package_id"])
has_changes = True
else:
# todo unsubscribe declined packages
pass
self._cloud_package_manager.unsubscribe(item["package_id"])
# delete temp file
os.remove(item["package_path"])
if has_changes:
self._restart_presenter.present()
## Logs an error and shows it to the user
def _showErrorMessage(self, text: str):
Logger.error(text)
Message(text, lifetime=0).show()

View file

@ -5688,7 +5688,7 @@
"unit": "mm",
"enabled": "resolveOrValue('prime_tower_enable')",
"default_value": 200,
"value": "machine_width - max(extruderValue(adhesion_extruder_nr, 'brim_width') * extruderValue(adhesion_extruder_nr, 'initial_layer_line_width_factor') / 100 if adhesion_type == 'brim' or (prime_tower_brim_enable and adhesion_type != 'raft') else (extruderValue(adhesion_extruder_nr, 'raft_margin') if adhesion_type == 'raft' else (extruderValue(adhesion_extruder_nr, 'skirt_gap') if adhesion_type == 'skirt' else 0)), max(extruderValues('travel_avoid_distance'))) - max(extruderValues('support_offset')) - sum(extruderValues('skirt_brim_line_width')) * extruderValue(adhesion_extruder_nr, 'initial_layer_line_width_factor') / 100 - (resolveOrValue('draft_shield_dist') if resolveOrValue('draft_shield_enabled') else 0) - 1",
"value": "machine_width - max(extruderValue(adhesion_extruder_nr, 'brim_width') * extruderValue(adhesion_extruder_nr, 'initial_layer_line_width_factor') / 100 if adhesion_type == 'brim' or (prime_tower_brim_enable and adhesion_type != 'raft') else (extruderValue(adhesion_extruder_nr, 'raft_margin') if adhesion_type == 'raft' else (extruderValue(adhesion_extruder_nr, 'skirt_gap') if adhesion_type == 'skirt' else 0)), max(extruderValues('travel_avoid_distance'))) - max(extruderValues('support_offset')) - sum(extruderValues('skirt_brim_line_width')) * extruderValue(adhesion_extruder_nr, 'initial_layer_line_width_factor') / 100 - (resolveOrValue('draft_shield_dist') if resolveOrValue('draft_shield_enabled') else 0) - max(map(abs, extruderValues('machine_nozzle_offset_x'))) - 1",
"maximum_value": "machine_width / 2 if machine_center_is_zero else machine_width",
"minimum_value": "resolveOrValue('prime_tower_size') - machine_width / 2 if machine_center_is_zero else resolveOrValue('prime_tower_size')",
"settable_per_mesh": false,
@ -5702,7 +5702,7 @@
"unit": "mm",
"enabled": "resolveOrValue('prime_tower_enable')",
"default_value": 200,
"value": "machine_depth - prime_tower_size - max(extruderValue(adhesion_extruder_nr, 'brim_width') * extruderValue(adhesion_extruder_nr, 'initial_layer_line_width_factor') / 100 if adhesion_type == 'brim' or (prime_tower_brim_enable and adhesion_type != 'raft') else (extruderValue(adhesion_extruder_nr, 'raft_margin') if adhesion_type == 'raft' else (extruderValue(adhesion_extruder_nr, 'skirt_gap') if adhesion_type == 'skirt' else 0)), max(extruderValues('travel_avoid_distance'))) - max(extruderValues('support_offset')) - sum(extruderValues('skirt_brim_line_width')) * extruderValue(adhesion_extruder_nr, 'initial_layer_line_width_factor') / 100 - (resolveOrValue('draft_shield_dist') if resolveOrValue('draft_shield_enabled') else 0) - 1",
"value": "machine_depth - prime_tower_size - max(extruderValue(adhesion_extruder_nr, 'brim_width') * extruderValue(adhesion_extruder_nr, 'initial_layer_line_width_factor') / 100 if adhesion_type == 'brim' or (prime_tower_brim_enable and adhesion_type != 'raft') else (extruderValue(adhesion_extruder_nr, 'raft_margin') if adhesion_type == 'raft' else (extruderValue(adhesion_extruder_nr, 'skirt_gap') if adhesion_type == 'skirt' else 0)), max(extruderValues('travel_avoid_distance'))) - max(extruderValues('support_offset')) - sum(extruderValues('skirt_brim_line_width')) * extruderValue(adhesion_extruder_nr, 'initial_layer_line_width_factor') / 100 - (resolveOrValue('draft_shield_dist') if resolveOrValue('draft_shield_enabled') else 0) - max(map(abs, extruderValues('machine_nozzle_offset_y'))) - 1",
"maximum_value": "machine_depth / 2 - resolveOrValue('prime_tower_size') if machine_center_is_zero else machine_depth - resolveOrValue('prime_tower_size')",
"minimum_value": "machine_depth / -2 if machine_center_is_zero else 0",
"settable_per_mesh": false,

View file

@ -520,6 +520,7 @@
"action_button": [15.0, 2.5],
"action_button_icon": [1.0, 1.0],
"action_button_radius": [0.15, 0.15],
"dialog_primary_button_padding": [3.0, 0],
"radio_button": [1.3, 1.3],

View file

@ -0,0 +1,65 @@
import os
import re
import sys
from pathlib import Path
"""
Run this file with the Cura project root as the working directory
Checks for invalid imports. When importing from plugins, there will be no problems when running from source,
but for some build types the plugins dir is not on the path, so relative imports should be used instead. eg:
from ..UltimakerCloudScope import UltimakerCloudScope <-- OK
import plugins.Toolbox.src ... <-- NOT OK
"""
class InvalidImportsChecker:
# compile regex
REGEX = re.compile(r"^\s*(from plugins|import plugins)")
def check(self):
""" Checks for invalid imports
:return: True if checks passed, False when the test fails
"""
cwd = os.getcwd()
cura_result = checker.check_dir(os.path.join(cwd, "cura"))
plugins_result = checker.check_dir(os.path.join(cwd, "plugins"))
result = cura_result and plugins_result
if not result:
print("error: sources contain invalid imports. Use relative imports when referencing plugin source files")
return result
def check_dir(self, root_dir: str) -> bool:
""" Checks a directory for invalid imports
:return: True if checks passed, False when the test fails
"""
passed = True
for path_like in Path(root_dir).rglob('*.py'):
if not self.check_file(str(path_like)):
passed = False
return passed
def check_file(self, file_path):
""" Checks a file for invalid imports
:return: True if checks passed, False when the test fails
"""
passed = True
with open(file_path, 'r', encoding = "utf-8") as inputFile:
# loop through each line in file
for line_i, line in enumerate(inputFile, 1):
# check if we have a regex match
match = self.REGEX.search(line)
if match:
path = os.path.relpath(file_path)
print("{path}:{line_i}:{match}".format(path=path, line_i=line_i, match=match.group(1)))
passed = False
return passed
if __name__ == "__main__":
checker = InvalidImportsChecker()
sys.exit(0 if checker.check() else 1)