async def managed_project( project_id: str, make_copy: bool = False ) -> AsyncGenerator[UpdateableCachedProject, None]: save_back = False if glob.PROJECT and glob.PROJECT.id == project_id: if make_copy: project = copy.deepcopy(glob.PROJECT) save_back = True else: project = glob.PROJECT else: save_back = True project = UpdateableCachedProject(await storage.get_project(project_id)) if make_copy: project.id = common.Project.uid() try: yield project finally: if save_back: asyncio.ensure_future(storage.update_project(project.project))
def test_project_unfinished_logic_with_loop(scene: Scene, project: UpdateableCachedProject) -> None: project.upsert_logic_item(LogicItem(ac1.id, ac2.id)) project.upsert_logic_item(LogicItem(ac2.id, ac1.id)) with pytest.raises(Arcor2Exception): check_for_loops(project, ac1.id)
def test_project_wo_loop_branched_logic(scene: Scene, project: UpdateableCachedProject) -> None: project.upsert_logic_item(LogicItem(LogicItem.START, ac1.id)) project.upsert_logic_item(LogicItem(ac1.id, ac2.id, ProjectLogicIf(f"{ac1.id}/default/0", json.dumps(True)))) project.upsert_logic_item(LogicItem(ac1.id, ac3.id, ProjectLogicIf(f"{ac1.id}/default/0", json.dumps(False)))) project.upsert_logic_item(LogicItem(ac2.id, ac4.id)) project.upsert_logic_item(LogicItem(ac3.id, ac4.id)) project.upsert_logic_item(LogicItem(ac4.id, LogicItem.END)) check_for_loops(project)
def lock() -> Lock: """Creates lock with initialized scene and project.""" test = "test" lock = Lock({}) scene = UpdateableCachedScene(cmn.Scene(test, description=test)) lock.scene = scene project = UpdateableCachedProject(cmn.Project(test, lock.scene.id, description=test, has_logic=True)) lock.project = project assert lock.scene == scene assert lock.scene_or_exception() == scene assert lock.project == project assert lock.project_or_exception() == project # add some scene and project objects test_object = cmn.SceneObject(test, "TestType") lock.scene.upsert_object(test_object) ap = lock.project.upsert_action_point(cmn.BareActionPoint.uid(), "ap", cmn.Position(0, 0, 0)) ap_ap = lock.project.upsert_action_point(cmn.BareActionPoint.uid(), "ap_ap", cmn.Position(0, 0, 1), ap.id) ap_ap_ap = lock.project.upsert_action_point(cmn.BareActionPoint.uid(), "ap_ap_ap", cmn.Position(0, 0, 2), ap_ap.id) lock.project.upsert_action_point(cmn.BareActionPoint.uid(), "ap2", cmn.Position(0, 1, 0)) ori = cmn.NamedOrientation("ori", cmn.Orientation()) lock.project.upsert_orientation(ap_ap_ap.id, ori) action = cmn.Action("action", "test/type", parameters=[], flows=[]) lock.project.upsert_action(ap_ap_ap.id, action) return lock
def test_project_wo_loop(scene: Scene, project: UpdateableCachedProject) -> None: project.upsert_logic_item(LogicItem(LogicItem.START, ac1.id)) project.upsert_logic_item(LogicItem(ac1.id, ac2.id)) project.upsert_logic_item(LogicItem(ac2.id, ac3.id)) project.upsert_logic_item(LogicItem(ac3.id, ac4.id)) project.upsert_logic_item(LogicItem(ac4.id, LogicItem.END)) check_for_loops(project)
async def projects(scene_id: str) -> AsyncIterator[UpdateableCachedProject]: for project_meta in await storage.get_projects(): project = await storage.get_project(project_meta.id) if project.scene_id != scene_id: continue yield UpdateableCachedProject(project)
def test_slots() -> None: """Tests whether classes from cached module uses __slots__.""" s = Scene("") p = Project("", s.id) assert not hasattr(CachedScene(s), "__dict__") assert not hasattr(CachedProject(p), "__dict__") assert not hasattr(UpdateableCachedScene(s), "__dict__") assert not hasattr(UpdateableCachedProject(p), "__dict__")
async def delete_project_cb(req: srpc.p.DeleteProject.Request, ui: WsClient) -> None: project = UpdateableCachedProject(await storage.get_project(req.args.id)) await storage.delete_project(req.args.id) evt = sevts.p.ProjectChanged(project.bare) evt.change_type = Event.Type.REMOVE asyncio.ensure_future(notif.broadcast_event(evt)) return None
def project() -> UpdateableCachedProject: project = Project("p1", "s1") ap1 = ActionPoint("ap1", Position()) project.action_points.append(ap1) ap1.actions.append(ac1) ap1.actions.append(ac2) ap1.actions.append(ac3) ap1.actions.append(ac4) return UpdateableCachedProject(project)
async def project_info( project_id: str, scenes_lock: asyncio.Lock, scenes: Dict[str, CachedScene]) -> srpc.p.ListProjects.Response.Data: project = await storage.get_project(project_id) assert project.modified is not None pd = srpc.p.ListProjects.Response.Data(id=project.id, desc=project.desc, name=project.name, scene_id=project.scene_id, modified=project.modified) try: cached_project = UpdateableCachedProject(project) except CachedProjectException as e: pd.problems.append(str(e)) return pd try: async with scenes_lock: if project.scene_id not in scenes: scenes[project.scene_id] = CachedScene(await storage.get_scene( project.scene_id)) except storage.ProjectServiceException: pd.problems.append("Scene does not exist.") return pd pd.problems = project_problems(scenes[project.scene_id], cached_project) pd.valid = not pd.problems if not pd.valid: return pd try: # TODO call build service!!! pd.executable = True except Arcor2Exception as e: pd.problems.append(str(e)) return pd
async def open_project(project_id: str) -> None: project = UpdateableCachedProject(await storage.get_project(project_id)) if glob.SCENE: if glob.SCENE.id != project.scene_id: raise Arcor2Exception("Required project is associated to another scene.") else: await open_scene(project.scene_id) assert glob.SCENE for ap in project.action_points_with_parent: assert ap.parent if ap.parent not in glob.SCENE.object_ids | project.action_points_ids: glob.SCENE = None raise Arcor2Exception(f"Action point's {ap.name} parent not available.") glob.PROJECT = project
async def new_project_cb(req: srpc.p.NewProject.Request, ui: WsClient) -> None: if glob.PACKAGE_STATE.state in PackageState.RUN_STATES: raise Arcor2Exception("Can't create project while package runs.") unique_name(req.args.name, (await project_names())) if req.dry_run: return None if glob.SCENE: if glob.SCENE.id != req.args.scene_id: raise Arcor2Exception("Another scene is opened.") if glob.SCENE.has_changes(): glob.SCENE.modified = await storage.update_scene(glob.SCENE.scene) else: if req.args.scene_id not in { scene.id for scene in (await storage.get_scenes()).items }: raise Arcor2Exception("Unknown scene id.") await open_scene(req.args.scene_id) project.PREV_RESULTS.clear() glob.PROJECT = UpdateableCachedProject( common.Project(req.args.name, req.args.scene_id, desc=req.args.desc, has_logic=req.args.has_logic)) assert glob.SCENE asyncio.ensure_future( notif.broadcast_event( sevts.p.OpenProject( sevts.p.OpenProject.Data(glob.SCENE.scene, glob.PROJECT.project)))) return None
async def test_ctx_read_lock() -> None: test = "test" user = "******" glob.LOCK = Lock({}) assert await glob.LOCK.get_locked_roots_count() == 0 glob.LOCK.scene = UpdateableCachedScene(cmn.Scene(test, description=test)) glob.LOCK.project = UpdateableCachedProject(cmn.Project(test, glob.LOCK.scene.id, description=test, has_logic=True)) async def patch() -> set[str]: return {glob.LOCK.project_or_exception().id, glob.LOCK.scene_or_exception().id} storage.get_project_ids = storage.get_scene_ids = patch # add some scene and project objects test_object = cmn.SceneObject(test, "TestType") glob.LOCK.scene.upsert_object(test_object) ap = glob.LOCK.project.upsert_action_point(cmn.BareActionPoint.uid(), "ap", cmn.Position(0, 0, 0), test_object.id) ap_ap = glob.LOCK.project.upsert_action_point(cmn.BareActionPoint.uid(), "ap_ap", cmn.Position(0, 0, 1), ap.id) assert await glob.LOCK.get_locked_roots_count() == 0 await glob.LOCK.write_lock(ap_ap.id, user, True) assert await glob.LOCK.is_write_locked(test_object.id, user) assert await glob.LOCK.is_write_locked(ap.id, user) assert await glob.LOCK.is_write_locked(ap_ap.id, user) async with ctx_read_lock(test_object.id, user): pass assert await glob.LOCK.is_write_locked(test_object.id, user) assert await glob.LOCK.is_write_locked(ap.id, user) assert await glob.LOCK.is_write_locked(ap_ap.id, user)
return # type: ignore # action could be cancelled during its execution glob.RUNNING_ACTION = None glob.RUNNING_ACTION_PARAMS = None await notif.broadcast_event(evt) async def open_project(project_id: str) -> None: project = await storage.get_project(project_id) if glob.LOCK.scene: if glob.LOCK.scene.id != project.scene_id: raise Arcor2Exception( "Required project is associated to another scene.") else: await open_scene(project.scene_id) assert glob.LOCK.scene if pp := await get_project_problems(glob.LOCK.scene, project): glob.LOCK.scene = None logger.warning( f"Project {project.name} can't be opened due to the following problem(s)..." ) for ppp in pp: logger.warning(ppp) raise Arcor2Exception("Project has some problems.") glob.LOCK.project = UpdateableCachedProject(project)
def test_project_unfinished_logic_wo_loop(scene: Scene, project: UpdateableCachedProject) -> None: project.upsert_logic_item(LogicItem(ac1.id, ac2.id)) check_for_loops(project, ac1.id)