Skip to content

Commit

Permalink
Merge pull request #5 from Ultimaker/master
Browse files Browse the repository at this point in the history
Update from master CURA Repo
  • Loading branch information
kaleidoscopeit authored May 20, 2021
2 parents 01b9ada + cfb32bf commit 69beba4
Show file tree
Hide file tree
Showing 3,939 changed files with 99,361 additions and 83,927 deletions.
The diff you're trying to view is too large. We only load the first 3000 changed files.
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
name: Bug report
name: Old Bug report
about: Create a report to help us fix issues.
title: ''
labels: 'Type: Bug'
Expand Down
28 changes: 21 additions & 7 deletions .github/ISSUE_TEMPLATE/bugreport.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
name: Bug Report
description: Create a report to help us fix issues.
labels: "Type: Bug"
issue_body: true
body:
- type: markdown
attributes:
Expand All @@ -15,7 +14,7 @@ body:
attributes:
label: Application Version
description: The version of Cura this issue occurs with.
placeholder: 4.8.0
placeholder: 4.9.0
validations:
required: true
- type: input
Expand Down Expand Up @@ -56,13 +55,28 @@ body:
- type: markdown
attributes:
value: |
## Additional information & file uploads
Please be sure to add the following files:
* For slicing issues, upload a **project file** that clearly shows the bug.
To save a project file go to `File -> Save project`. Please make sure to .zip your project file. For big files you may need to use WeTransfer or similar file sharing sites.
G-code files are not project files!
* **Screenshots** of showing the problem, perhaps before/after images.
* A **log file**, see [here](https://github.com/Ultimaker/Cura#logging-issues) how to find the log file.
You can add these files and additional information that is relevant to the issue in the comments below.
* A **log file** for crashes and similar issues.
You can find your log file here:
Windows: `%APPDATA%\cura\<Cura version>\cura.log` or usually `C:\Users\\<your username>\AppData\Roaming\cura\<Cura version>\cura.log`
MacOS: `$USER/Library/Application Support/cura/<Cura version>/cura.log`
Ubuntu/Linus: `$USER/.local/share/cura/<Cura version>/cura.log`
If the Cura user interface still starts, you can also reach this directory from the application menu in Help -> Show settings folder
- type: checkboxes
attributes:
label: Checklist of files to include
options:
- label: Log file
- label: Project file
- type: textarea
attributes:
label: Additional information & file uploads
description: You can add these files and additional information that is relevant to the issue in the comments below.
validations:
required: true

5 changes: 5 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: Have questions or need support?
url: https://community.ultimaker.com/
about: Please get in touch on our Ultimaker Community Forum!
10 changes: 4 additions & 6 deletions .github/ISSUE_TEMPLATE/featurerequest.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
name: Feature Request
description: Suggest an idea for this project.
labels: "Type: New Feature"
issue_body: true
body:
- type: markdown
attributes:
Expand All @@ -28,7 +27,7 @@ body:
- type: textarea
attributes:
label: Describe alternatives you've considered
description: A clear and concise description of any alternative solutions or features you've considered. Again, if possible, think about why these alternatives are not working out.
description: A clear and concise description of any alternative solutions or features you've considered. If possible, think about why these alternatives are not working out.
placeholder: The alternatives I've considered are...
validations:
required: true
Expand All @@ -39,8 +38,7 @@ body:
placeholder: It will affect...
validations:
required: true
- type: markdown
- type: textarea
attributes:
value: |
## Additional information & file uploads
You can add pictures or files to visualize your feature request in the comments below.
label: Additional information & file uploads
description: You can add pictures or files to visualize your feature request in the comments below.
12 changes: 7 additions & 5 deletions cura/API/Account.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class Account(QObject):
"""

# The interval in which sync services are automatically triggered
SYNC_INTERVAL = 30.0 # seconds
SYNC_INTERVAL = 60.0 # seconds
Q_ENUMS(SyncState)

loginStateChanged = pyqtSignal(bool)
Expand All @@ -58,6 +58,11 @@ class Account(QObject):
manualSyncEnabledChanged = pyqtSignal(bool)
updatePackagesEnabledChanged = pyqtSignal(bool)

CLIENT_SCOPES = "account.user.read drive.backup.read drive.backup.write packages.download " \
"packages.rating.read packages.rating.write connect.cluster.read connect.cluster.write " \
"library.project.read library.project.write cura.printjob.read cura.printjob.write " \
"cura.mesh.read cura.mesh.write"

def __init__(self, application: "CuraApplication", parent = None) -> None:
super().__init__(parent)
self._application = application
Expand All @@ -79,10 +84,7 @@ def __init__(self, application: "CuraApplication", parent = None) -> None:
CALLBACK_PORT=self._callback_port,
CALLBACK_URL="http://localhost:{}/callback".format(self._callback_port),
CLIENT_ID="um----------------------------ultimaker_cura",
CLIENT_SCOPES="account.user.read drive.backup.read drive.backup.write packages.download "
"packages.rating.read packages.rating.write connect.cluster.read connect.cluster.write "
"library.project.read library.project.write cura.printjob.read cura.printjob.write "
"cura.mesh.read cura.mesh.write",
CLIENT_SCOPES=self.CLIENT_SCOPES,
AUTH_DATA_PREFERENCE_KEY="general/ultimaker_auth_data",
AUTH_SUCCESS_REDIRECT="{}/app/auth-success".format(self._oauth_root),
AUTH_FAILED_REDIRECT="{}/app/auth-error".format(self._oauth_root)
Expand Down
2 changes: 1 addition & 1 deletion cura/ApplicationMetadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
# Each release has a fixed SDK version coupled with it. It doesn't make sense to make it configurable because, for
# example Cura 3.2 with SDK version 6.1 will not work. So the SDK version is hard-coded here and left out of the
# CuraVersion.py.in template.
CuraSDKVersion = "7.4.0"
CuraSDKVersion = "7.5.0"

try:
from cura.CuraVersion import CuraAppName # type: ignore
Expand Down
7 changes: 4 additions & 3 deletions cura/Arranging/Nest2DArrange.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ def findNodePlacement(nodes_to_arrange: List["SceneNode"], build_volume: "BuildV
found_solution_for_all: Whether the algorithm found a place on the buildplate for all the objects
node_items: A list of the nodes return by libnest2d, which contain the new positions on the buildplate
"""
spacing = int(1.5 * factor) # 1.5mm spacing.

machine_width = build_volume.getWidth()
machine_depth = build_volume.getDepth()
Expand Down Expand Up @@ -75,7 +76,7 @@ def findNodePlacement(nodes_to_arrange: List["SceneNode"], build_volume: "BuildV
# Clip the disallowed areas so that they don't overlap the bounding box (The arranger chokes otherwise)
clipped_area = area.intersectionConvexHulls(build_plate_polygon)

if clipped_area.getPoints() is not None: # numpy array has to be explicitly checked against None
if clipped_area.getPoints() is not None and len(clipped_area.getPoints()) > 2: # numpy array has to be explicitly checked against None
for point in clipped_area.getPoints():
converted_points.append(Point(int(point[0] * factor), int(point[1] * factor)))

Expand All @@ -88,7 +89,7 @@ def findNodePlacement(nodes_to_arrange: List["SceneNode"], build_volume: "BuildV
converted_points = []
hull_polygon = node.callDecoration("getConvexHull")

if hull_polygon is not None and hull_polygon.getPoints() is not None: # numpy array has to be explicitly checked against None
if hull_polygon is not None and hull_polygon.getPoints() is not None and len(hull_polygon.getPoints()) > 2: # numpy array has to be explicitly checked against None
for point in hull_polygon.getPoints():
converted_points.append(Point(point[0] * factor, point[1] * factor))
item = Item(converted_points)
Expand All @@ -99,7 +100,7 @@ def findNodePlacement(nodes_to_arrange: List["SceneNode"], build_volume: "BuildV
config = NfpConfig()
config.accuracy = 1.0

num_bins = nest(node_items, build_plate_bounding_box, 10000, config)
num_bins = nest(node_items, build_plate_bounding_box, spacing, config)

# Strip the fixed items (previously placed) and the disallowed areas from the results again.
node_items = list(filter(lambda item: not item.isFixed(), node_items))
Expand Down
12 changes: 6 additions & 6 deletions cura/Arranging/ShapeArray.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import numpy
import copy
from typing import Optional, Tuple, TYPE_CHECKING
from typing import Optional, Tuple, TYPE_CHECKING, Union

from UM.Math.Polygon import Polygon

Expand All @@ -14,14 +14,14 @@
class ShapeArray:
"""Polygon representation as an array for use with :py:class:`cura.Arranging.Arrange.Arrange`"""

def __init__(self, arr: numpy.array, offset_x: float, offset_y: float, scale: float = 1) -> None:
def __init__(self, arr: numpy.ndarray, offset_x: float, offset_y: float, scale: float = 1) -> None:
self.arr = arr
self.offset_x = offset_x
self.offset_y = offset_y
self.scale = scale

@classmethod
def fromPolygon(cls, vertices: numpy.array, scale: float = 1) -> "ShapeArray":
def fromPolygon(cls, vertices: numpy.ndarray, scale: float = 1) -> "ShapeArray":
"""Instantiate from a bunch of vertices
:param vertices:
Expand Down Expand Up @@ -98,7 +98,7 @@ def fromNode(cls, node: "SceneNode", min_offset: float, scale: float = 0.5, incl
return offset_shape_arr, hull_shape_arr

@classmethod
def arrayFromPolygon(cls, shape: Tuple[int, int], vertices: numpy.array) -> numpy.array:
def arrayFromPolygon(cls, shape: Union[Tuple[int, int], numpy.ndarray], vertices: numpy.ndarray) -> numpy.ndarray:
"""Create :py:class:`numpy.ndarray` with dimensions defined by shape
Fills polygon defined by vertices with ones, all other values zero
Expand All @@ -110,7 +110,7 @@ def arrayFromPolygon(cls, shape: Tuple[int, int], vertices: numpy.array) -> nump
:return: numpy array with dimensions defined by shape
"""

base_array = numpy.zeros(shape, dtype = numpy.int32) # Initialize your array of zeros
base_array = numpy.zeros(shape, dtype = numpy.int32) # type: ignore # Initialize your array of zeros

fill = numpy.ones(base_array.shape) * True # Initialize boolean array defining shape fill

Expand All @@ -126,7 +126,7 @@ def arrayFromPolygon(cls, shape: Tuple[int, int], vertices: numpy.array) -> nump
return base_array

@classmethod
def _check(cls, p1: numpy.array, p2: numpy.array, base_array: numpy.array) -> Optional[numpy.array]:
def _check(cls, p1: numpy.ndarray, p2: numpy.ndarray, base_array: numpy.ndarray) -> Optional[numpy.ndarray]:
"""Return indices that mark one side of the line, used by arrayFromPolygon
Uses the line defined by p1 and p2 to check array of
Expand Down
8 changes: 5 additions & 3 deletions cura/AutoSave.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
# Copyright (c) 2019 Ultimaker B.V.
# Copyright (c) 2021 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.

from PyQt5.QtCore import QTimer
from typing import Any, TYPE_CHECKING

from UM.Logger import Logger

import time

if TYPE_CHECKING:
from cura.CuraApplication import CuraApplication

Expand Down Expand Up @@ -56,8 +58,8 @@ def _onGlobalStackChanged(self) -> None:

def _onTimeout(self) -> None:
self._saving = True # To prevent the save process from triggering another autosave.
Logger.log("d", "Autosaving preferences, instances and profiles")

save_start_time = time.time()
self._application.saveSettings()

Logger.log("d", "Autosaving preferences, instances and profiles took %s seconds", time.time() - save_start_time)
self._saving = False
47 changes: 46 additions & 1 deletion cura/Backups/Backup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import os
import re
import shutil
from copy import deepcopy
from zipfile import ZipFile, ZIP_DEFLATED, BadZipfile
from typing import Dict, Optional, TYPE_CHECKING

Expand All @@ -27,6 +28,9 @@ class Backup:
IGNORED_FILES = [r"cura\.log", r"plugins\.json", r"cache", r"__pycache__", r"\.qmlc", r"\.pyc"]
"""These files should be ignored when making a backup."""

SECRETS_SETTINGS = ["general/ultimaker_auth_data"]
"""Secret preferences that need to obfuscated when making a backup of Cura"""

catalog = i18nCatalog("cura")
"""Re-use translation catalog"""

Expand All @@ -43,6 +47,9 @@ def makeFromCurrent(self) -> None:

Logger.log("d", "Creating backup for Cura %s, using folder %s", cura_release, version_data_dir)

# obfuscate sensitive secrets
secrets = self._obfuscate()

# Ensure all current settings are saved.
self._application.saveSettings()

Expand Down Expand Up @@ -78,6 +85,8 @@ def makeFromCurrent(self) -> None:
"profile_count": str(profile_count),
"plugin_count": str(plugin_count)
}
# Restore the obfuscated settings
self._illuminate(**secrets)

def _makeArchive(self, buffer: "io.BytesIO", root_path: str) -> Optional[ZipFile]:
"""Make a full archive from the given root path with the given name.
Expand Down Expand Up @@ -134,8 +143,16 @@ def restore(self) -> bool:
"Tried to restore a Cura backup that is higher than the current version."))
return False

# Get the current secrets and store since the back-up doesn't contain those
secrets = self._obfuscate()

version_data_dir = Resources.getDataStoragePath()
archive = ZipFile(io.BytesIO(self.zip_file), "r")
try:
archive = ZipFile(io.BytesIO(self.zip_file), "r")
except LookupError as e:
Logger.log("d", f"The following error occurred while trying to restore a Cura backup: {str(e)}")
self._showMessage(self.catalog.i18nc("@info:backup_failed", "The following error occurred while trying to restore a Cura backup:") + str(e))
return False
extracted = self._extractArchive(archive, version_data_dir)

# Under Linux, preferences are stored elsewhere, so we copy the file to there.
Expand All @@ -146,6 +163,9 @@ def restore(self) -> bool:
Logger.log("d", "Moving preferences file from %s to %s", backup_preferences_file, preferences_file)
shutil.move(backup_preferences_file, preferences_file)

# Restore the obfuscated settings
self._illuminate(**secrets)

return extracted

@staticmethod
Expand Down Expand Up @@ -173,3 +193,28 @@ def _extractArchive(archive: "ZipFile", target_path: str) -> bool:
Logger.logException("e", "Unable to extract the backup due to permission or file system errors.")
return False
return True

def _obfuscate(self) -> Dict[str, str]:
"""
Obfuscate and remove the secret preferences that are specified in SECRETS_SETTINGS
:return: a dictionary of the removed secrets. Note: the '/' is replaced by '__'
"""
preferences = self._application.getPreferences()
secrets = {}
for secret in self.SECRETS_SETTINGS:
secrets[secret.replace("/", "__")] = deepcopy(preferences.getValue(secret))
preferences.setValue(secret, None)
self._application.savePreferences()
return secrets

def _illuminate(self, **kwargs) -> None:
"""
Restore the obfuscated settings
:param kwargs: a dict of obscured preferences. Note: the '__' of the keys will be replaced by '/'
"""
preferences = self._application.getPreferences()
for key, value in kwargs.items():
preferences.setValue(key.replace("__", "/"), value)
self._application.savePreferences()
Loading

0 comments on commit 69beba4

Please sign in to comment.