Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
50908f237f
@ -59,60 +59,8 @@ if admin is None or not admin.is_admin:
|
||||
Users.register(username="ADMIN", password="123123", roles=["admin"])
|
||||
# register or reset user
|
||||
Users.register(username="USER", password="user")
|
||||
# # register test steps
|
||||
# Steps.replace(
|
||||
# id=0,
|
||||
# name="TEST_LEAK_TEST",
|
||||
# type="leak",
|
||||
# spec={
|
||||
# "pre_filling_time": 5,
|
||||
# "pre_filling_pressure": 1000,
|
||||
# "filling_time": 5,
|
||||
# "settling_time": 10,
|
||||
# "settling_pressure_min_percent": 50,
|
||||
# "settling_pressure_max_percent": 50,
|
||||
# "test_time": 10,
|
||||
# "test_pressure_min_delta": 500,
|
||||
# "test_pressure": 1000,
|
||||
# "test_pressure_max_delta": 500,
|
||||
# "flush_time": 2,
|
||||
# "flush_pressure": 5,
|
||||
# },
|
||||
# description="TEST_DESCRIPTION",
|
||||
# archived=False,
|
||||
# ).execute()
|
||||
# Steps.replace(
|
||||
# id=1,
|
||||
# name="TEST_LEAK_TEST",
|
||||
# type="leak",
|
||||
# spec={
|
||||
# "pre_filling_time": 5,
|
||||
# "pre_filling_pressure": 1000,
|
||||
# "filling_time": 5,
|
||||
# "settling_time": 10,
|
||||
# "settling_pressure_min_percent": 50,
|
||||
# "settling_pressure_max_percent": 50,
|
||||
# "test_time": 10,
|
||||
# "test_pressure_min_delta": 500,
|
||||
# "test_pressure": 1000,
|
||||
# "test_pressure_max_delta": 500,
|
||||
# "flush_time": 2,
|
||||
# "flush_pressure": 5,
|
||||
# },
|
||||
# description="TEST_DESCRIPTION",
|
||||
# archived=False,
|
||||
# ).execute()
|
||||
# Steps.replace(
|
||||
# id=2,
|
||||
# name="TEST_VISION_TEST",
|
||||
# type="vision",
|
||||
# spec={
|
||||
# "recipe": "1.ini",
|
||||
# },
|
||||
# description="TEST_DESCRIPTION VISION_RECIPE: 1",
|
||||
# archived=False,
|
||||
# ).execute()
|
||||
# register test recipe
|
||||
|
||||
|
||||
Recipes.replace(
|
||||
id=0,
|
||||
name="Ferrari 923578",
|
||||
@ -122,7 +70,6 @@ Recipes.replace(
|
||||
description="Tubo plastica doppia biforcazione con termorestringente centrale",
|
||||
archived=False,
|
||||
).execute()
|
||||
|
||||
Recipes.replace(
|
||||
id=1,
|
||||
name="BLOW-BY 5802814210",
|
||||
|
||||
@ -7,11 +7,11 @@ from .steps import Steps
|
||||
|
||||
class Recipes(BaseModel):
|
||||
id = AutoField(primary_key=True, unique=True, null=False)
|
||||
name = TextField(null=False)
|
||||
client = TextField(null=False)
|
||||
name = TextField(null=True)
|
||||
client = TextField(null=True)
|
||||
part_number = TextField(null=False)
|
||||
spec = JSONField(null=False) # keys inside spec must not overlap withthe model
|
||||
description = TextField(null=False)
|
||||
description = TextField(null=True)
|
||||
archived = BooleanField(null=False, default=False)
|
||||
|
||||
def get_steps(self):
|
||||
|
||||
@ -329,6 +329,20 @@ class Crud(Widget):
|
||||
self._modified = self._modified or is_modified
|
||||
self.modified.emit(self._modified)
|
||||
|
||||
def parse_row(self, rn, fail=False):
|
||||
r = {}
|
||||
fails = []
|
||||
for fn, cn in self.select_index.items():
|
||||
w = self.db_tw.cellWidget(rn, cn)
|
||||
try:
|
||||
r[fn] = w._parse(row_number=rn, crud=self)
|
||||
except Exception as e:
|
||||
self.log.exception(traceback.format_exc())
|
||||
self.set_row_color(rn, "red")
|
||||
fail = True
|
||||
fails.append(str(e))
|
||||
return r, fail, fails
|
||||
|
||||
def refresh(self, action=None, page=0):
|
||||
# IGNORE SIGNALS WHILE UPDATING
|
||||
self.db_tw.blockSignals(True)
|
||||
@ -340,12 +354,6 @@ class Crud(Widget):
|
||||
self.db_tw.setColumnCount(len(self.select))
|
||||
self.db_tw.setHorizontalHeaderLabels(self.fields_aliases.values())
|
||||
self.db_tw.setRowCount(1)
|
||||
self.db_tw.setColumnWidth(0, 25)
|
||||
self.db_tw.setColumnWidth(1, 200)
|
||||
self.db_tw.setColumnWidth(2, 200)
|
||||
self.db_tw.setColumnWidth(3, 200)
|
||||
self.db_tw.setColumnWidth(4, 200)
|
||||
self.db_tw.setColumnWidth(5, 400)
|
||||
if self.readonly is None or self.readonly is True:
|
||||
self.db_tw.verticalHeader().setHidden(True)
|
||||
else:
|
||||
@ -368,16 +376,8 @@ class Crud(Widget):
|
||||
fails = []
|
||||
data = []
|
||||
for rn in range(1, self.db_tw.rowCount()): # start=1 because rn starts from 1 (filters line)
|
||||
r = {}
|
||||
for fn, cn in self.select_index.items():
|
||||
w = self.db_tw.cellWidget(rn, cn)
|
||||
try:
|
||||
r[fn] = w._parse(row_number=rn, crud=self)
|
||||
except Exception as e:
|
||||
self.log.exception(traceback.format_exc())
|
||||
self.set_row_color(rn, "red")
|
||||
fail = True
|
||||
fails.append(str(e))
|
||||
r, fail, r_fails = self.parse_row(rn, fail=fail)
|
||||
fails += r_fails
|
||||
add_row, r, filter_fail = self.row_filter(r, rn, self)
|
||||
if filter_fail:
|
||||
fail = True
|
||||
@ -436,6 +436,7 @@ class Crud(Widget):
|
||||
self.db_tw.setCellWidget(rn, cn, w)
|
||||
# REENABLE EVENTS AFTER UPDATE
|
||||
self.db_tw.blockSignals(False)
|
||||
self.show_selection()
|
||||
return True
|
||||
|
||||
def cancel(self):
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import sys
|
||||
from glob import iglob
|
||||
|
||||
from lib.db import Recipes, Users
|
||||
from PyQt5.QtCore import QTimer, pyqtSignal
|
||||
@ -47,6 +48,14 @@ class Recipe_Selection(Widget):
|
||||
filters=filters,
|
||||
fields_aliases=crud_aliases,
|
||||
autocomplete={
|
||||
"spec": {
|
||||
"step_editors": {
|
||||
"vision": {
|
||||
# "recipe": iglob("*.ini", root_dir="./config/vision/recipes/"), # only in python3.10
|
||||
"recipe": list(iglob("./config/vision/recipes/*.ini")),
|
||||
},
|
||||
},
|
||||
},
|
||||
"archived": False,
|
||||
},
|
||||
widget_classes={"spec": lambda *args, **kwargs: Json_External_Dialog_Editor_Cell_Widget(Recipe_Spec_And_Step_Editor, *args, **kwargs), },
|
||||
@ -60,6 +69,12 @@ class Recipe_Selection(Widget):
|
||||
self.crud.modified.connect(self.check_modified)
|
||||
self.crud.selected.connect(self.check_selected)
|
||||
self.crud.emit()
|
||||
self.crud.db_tw.setColumnWidth(0, 25)
|
||||
self.crud.db_tw.setColumnWidth(1, 200)
|
||||
self.crud.db_tw.setColumnWidth(2, 200)
|
||||
self.crud.db_tw.setColumnWidth(3, 200)
|
||||
self.crud.db_tw.setColumnWidth(4, 200)
|
||||
self.crud.db_tw.setColumnWidth(5, 400)
|
||||
# TESTING
|
||||
if "--auto-select" in sys.argv or "--test" in sys.argv:
|
||||
drawing = "TEST"
|
||||
@ -79,13 +94,13 @@ class Recipe_Selection(Widget):
|
||||
self.crud_modified = modified
|
||||
self.check(self.crud_modified, self.selected)
|
||||
|
||||
def check_selected(self, selected):
|
||||
if len(selected) == 1:
|
||||
def check_selected(self, selected=None):
|
||||
if selected is not None and len(selected) == 1:
|
||||
selected = selected[0] - 1 # - 1 because rn starts from 1 (filters line)
|
||||
if selected >= 0 and selected < len(self.crud.data_index):
|
||||
selected = self.crud.data_index[selected]
|
||||
if selected is not None:
|
||||
self.selected = self.crud.db.table_model.get_by_id(selected)
|
||||
self.selected = selected
|
||||
else:
|
||||
self.selected = None
|
||||
else:
|
||||
@ -97,4 +112,4 @@ class Recipe_Selection(Widget):
|
||||
|
||||
def select(self):
|
||||
if self.selected is not None:
|
||||
self.ok.emit(self.selected)
|
||||
self.ok.emit(self.crud.db.table_model.get_by_id(self.selected))
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
from lib.db import Steps
|
||||
from lib.db import Recipes, Steps
|
||||
from playhouse.shortcuts import model_to_dict
|
||||
from ui.editor import Editor
|
||||
from ui.helpers import replace_widget
|
||||
@ -41,21 +41,18 @@ class Recipe_Spec_And_Step_Editor(Editor):
|
||||
# "editor": _Editor,
|
||||
},
|
||||
}
|
||||
if len(self.map) > 1024:
|
||||
raise NotImplementedError("self.map must contain at most 1024 steps")
|
||||
self.spec.update({editor_name: map["enable"] for editor_name, map in self.map.items()})
|
||||
for editor_name, map in self.map.items():
|
||||
self.spec.update({step_name: map["enable"] for step_name, map in self.map.items()})
|
||||
for map in self.map.values():
|
||||
editor = map.get("editor", None)
|
||||
if editor is not None:
|
||||
replace_widget(self, map["widget"], editor)
|
||||
self.save_steps_b.clicked.connect(self.save_steps)
|
||||
self.reset_steps_b.clicked.connect(self.reset_steps)
|
||||
self.recipe_id = None
|
||||
self.step_editors_autocomplete = {}
|
||||
|
||||
def set_readonly(self, readonly=True):
|
||||
super().set_readonly(readonly=readonly)
|
||||
for editor_name, map in self.map.items():
|
||||
for map in self.map.values():
|
||||
editor = map.get("editor", None)
|
||||
if editor is not None:
|
||||
editor.set_readonly(readonly=readonly)
|
||||
@ -64,16 +61,15 @@ class Recipe_Spec_And_Step_Editor(Editor):
|
||||
def do_autocomplete(self, autocomplete):
|
||||
if autocomplete is None:
|
||||
return
|
||||
self.step_editors_autocomplete = autocomplete.pop("step_editors", None)
|
||||
step_editors_autocomplete = autocomplete.pop("step_editors", None)
|
||||
super().do_autocomplete(autocomplete)
|
||||
if self.step_editors_autocomplete is not None:
|
||||
for editor_name, map in self.map.items():
|
||||
if step_editors_autocomplete is not None:
|
||||
for step_name, map in self.map.items():
|
||||
editor = map.get("editor", None)
|
||||
if editor is not None:
|
||||
editor.do_autocomplete(self.step_editors_autocomplete.get(editor_name, None))
|
||||
editor.do_autocomplete(step_editors_autocomplete.get(step_name, None))
|
||||
|
||||
def init(self):
|
||||
self.recipe_id = self.cell_widget.crud.data_index[self.cell_widget.row_number - 1] # - 1 because row_number starts from 1 (filters line)
|
||||
self.get_steps()
|
||||
|
||||
def showing_dialog(self):
|
||||
@ -88,52 +84,51 @@ class Recipe_Spec_And_Step_Editor(Editor):
|
||||
|
||||
def render(self, data, field_name=None, row_number=None, crud=None):
|
||||
super().render(data, field_name=field_name, row_number=row_number, crud=crud)
|
||||
self.get_steps(available_steps=data.get("available_steps", {}))
|
||||
steps = set(data.get("steps", set()))
|
||||
for map in self.map.values():
|
||||
map["enable"].setChecked(map["step"]["id"] in steps)
|
||||
step = map.get("step", None)
|
||||
if step is not None:
|
||||
map["enable"].setChecked(step.id in steps)
|
||||
self.render_steps()
|
||||
|
||||
def parse(self, row_number=None, crud=None):
|
||||
ret = super().parse(row_number=row_number, crud=crud)
|
||||
ret["steps"] = []
|
||||
for map in self.map.values():
|
||||
ret["available_steps"] = {}
|
||||
for step_name, map in self.map.items():
|
||||
ret["available_steps"][step_name] = map["step"].id
|
||||
if map["enable"].isChecked():
|
||||
ret["steps"].append(map["step"]["id"])
|
||||
ret["steps"].append(map["step"].id)
|
||||
return ret
|
||||
|
||||
@staticmethod
|
||||
def get_step_id(recipe_id, step_n):
|
||||
return recipe_id * 1024 + step_n
|
||||
|
||||
def get_steps(self):
|
||||
for n, [editor_name, map] in enumerate(self.map.items()):
|
||||
id = self.get_step_id(self.recipe_id, n)
|
||||
try:
|
||||
step = model_to_dict(Steps.get_by_id(id))
|
||||
except Steps.DoesNotExist:
|
||||
step = {
|
||||
"id": id,
|
||||
"type": map["type"],
|
||||
"spec": {},
|
||||
}
|
||||
map["step"] = step
|
||||
def get_steps(self, available_steps=None):
|
||||
if available_steps is None:
|
||||
available_steps = {}
|
||||
for step_name, map in self.map.items():
|
||||
if step_name in available_steps:
|
||||
map["step"] = Steps.get_by_id(available_steps[step_name])
|
||||
elif map.get("step", None) is None:
|
||||
map["step"] = Steps(type=map["type"], spec={})
|
||||
|
||||
def render_steps(self):
|
||||
for n, [editor_name, map] in enumerate(self.map.items()):
|
||||
editor = map.get("editor", None)
|
||||
step = map["step"]
|
||||
if editor is not None:
|
||||
editor.render(step["spec"])
|
||||
for step_name, map in self.map.items():
|
||||
step = map.get("step", None)
|
||||
if step is not None:
|
||||
editor = map.get("editor", None)
|
||||
if editor is not None:
|
||||
editor.render(step.spec)
|
||||
|
||||
def reset_steps(self):
|
||||
self.get_steps()
|
||||
self.render_steps()
|
||||
|
||||
def save_steps(self):
|
||||
steps = []
|
||||
for map in self.map.values():
|
||||
editor = map.get("editor", None)
|
||||
if editor is not None:
|
||||
map["step"]["spec"] = editor.parse()
|
||||
steps.append(map["step"])
|
||||
Steps.replace_many(steps).execute()
|
||||
step = map.get("step", None)
|
||||
if step is not None:
|
||||
editor = map.get("editor", None)
|
||||
if editor is not None:
|
||||
step.spec = editor.parse()
|
||||
step.save()
|
||||
self.reset_steps()
|
||||
|
||||
@ -17,6 +17,7 @@ class Test_Barcodes(Test_Test):
|
||||
def start(self, recipe=None, step=None):
|
||||
super().start(recipe=recipe, step=step)
|
||||
self.barcodes = {}
|
||||
self.visualize()
|
||||
self.barcodes_le.setPalette(self.status_palettes[None])
|
||||
self.barcodes_le.setText("")
|
||||
self.barcodes_le.setFocus()
|
||||
|
||||
Loading…
Reference in New Issue
Block a user