[Bf-blender-cvs] [037e761] asset-engine: Claude: more WIP work towards listing content on Cloud repository.
Bastien Montagne
noreply at git.blender.org
Thu Sep 8 15:27:16 CEST 2016
Commit: 037e761f1f2cfc175665557713903919af50dfaa
Author: Bastien Montagne
Date: Thu Sep 8 15:26:36 2016 +0200
Branches: asset-engine
https://developer.blender.org/rB037e761f1f2cfc175665557713903919af50dfaa
Claude: more WIP work towards listing content on Cloud repository.
===================================================================
M release/scripts/startup/bl_operators/claude/__init__.py
===================================================================
diff --git a/release/scripts/startup/bl_operators/claude/__init__.py b/release/scripts/startup/bl_operators/claude/__init__.py
index 2205c02..b5e14b1 100644
--- a/release/scripts/startup/bl_operators/claude/__init__.py
+++ b/release/scripts/startup/bl_operators/claude/__init__.py
@@ -61,11 +61,14 @@ import binascii
import hashlib
import json
import os
+import pathlib
import stat
import struct
import time
import random
+from collections import OrderedDict
+
import pillarsdk
REQUIRED_ROLES_FOR_CLAUDE = {'subscriber', 'demo'}
@@ -73,6 +76,67 @@ REQUIRED_ROLES_FOR_CLAUDE = {'subscriber', 'demo'}
##########
# Helpers.
+class SpecialFolderNode(pillarsdk.Node):
+ pass
+
+
+class UpNode(SpecialFolderNode):
+ def __init__(self):
+ super().__init__()
+ self['_id'] = 'UP'
+ self['node_type'] = 'UP'
+ self['name'] = ".."
+
+
+class ProjectNode(SpecialFolderNode):
+ def __init__(self, project):
+ super().__init__()
+
+ assert isinstance(project, pillarsdk.Project), "wrong type for project: %r" % type(project)
+
+ self.merge(project.to_dict())
+ self['node_type'] = 'PROJECT'
+
+
+class ClaudeRepository:
+ def __init__(self):
+ self.path_map = {} # Mapping names->uuid of Cloud nodes (so that user gets friendly 'named' paths in browser).
+ self.curr_path = pillar.CloudPath("/") # Using node names.
+ self.curr_path_real = pillar.CloudPath("/") # Using node uuid's.
+ self.pending_path = [] # Defined when we get a path from browser (e.g. user input) that we don't know of...
+
+ self.nodes = OrderedDict() # uuid's to nodes mapping, for currently browsed area...
+ self.is_ready = False
+
+ def check_dir_do(self, root_path, do_change, do_update_intern):
+ if self.curr_path == root_path:
+ return True, root_path
+ parts = root_path.parts
+ if do_update_intern:
+ self.pending_path = []
+ self.is_ready = False
+ self.nodes.clear()
+ if parts and parts[0] == "/":
+ nids = [parts[0]]
+ paths = self.path_map
+ for i, p in enumerate(parts[1:]):
+ nid, paths = paths.get(p, (None, None))
+ if nid is None:
+ if do_update_intern:
+ self.pending_path = parts[i + 1:]
+ self.curr_path = pillar.CloudPath("/".join(parts[:i + 1]))
+ self.curr_path_real = pillar.CloudPath("/".join(nids))
+ break
+ else:
+ nids.append(nid)
+ return True, root_path
+ elif do_change:
+ if do_update_intern:
+ self.curr_path = pillar.CloudPath("/")
+ self.curr_path_real = pillar.CloudPath("/")
+ return True, pillar.CloudPath("/")
+ else:
+ return False, root_path
#############
@@ -82,13 +146,12 @@ class ClaudeJob:
def async_looper(func):
def wrapper(self, *args, **kwargs):
loop = self.loop
- assert(not self.loop.is_running())
+ assert(not loop.is_running())
print("proceed....")
ret = func(self, *args, **kwargs)
if not self.evt_cancel.is_set():
print("kickstep")
# This forces loop to only do 'one step', and return (hopefully!) very soon.
- # Note: both calls below work essentially the same way, we could also use call_later with 0.1ms delay...
#~ loop.stop()
loop.call_soon(loop.stop)
loop.run_forever()
@@ -97,16 +160,33 @@ class ClaudeJob:
return ret
return wrapper
+ def add_task(self, coro):
+ task = asyncio.ensure_future(coro)
+ self._tasks.append(task)
+ return task
+
+ def remove_task(self, task):
+ self._tasks.remove(task)
+ return None
+
def cancel(self):
print("Cancelling ", self)
self.evt_cancel.set()
+ for task in self._tasks:
+ task.cancel()
+ self._tasks[:] = []
+ self.status = {'VALID'}
assert(not self.loop.is_running())
+ self.loop.call_soon(self.loop.stop)
+ self.loop.run_forever()
def __init__(self, job_id):
self.job_id = job_id
self.status = {'VALID'}
self.progress = 0.0
+ self._tasks = []
+
self.evt_cancel = threading.Event()
self.loop = asyncio.get_event_loop()
@@ -155,7 +235,7 @@ class ClaudeJobCheckCredentials(ClaudeJob):
@ClaudeJob.async_looper
def start(self):
- self.check_task = asyncio.ensure_future(self.check())
+ self.check_task = self.add_task(self.check())
self.progress = 0.0
self.status = {'VALID', 'RUNNING'}
@@ -163,24 +243,25 @@ class ClaudeJobCheckCredentials(ClaudeJob):
def update(self):
self.status = {'VALID', 'RUNNING'}
user_id = ...
+
+ self.progress += 0.05
+ if (self.progress > 1.0):
+ self.progress = 0.0
+
print("Updating credential status, ", self.check_task, " | Done: ", self.check_task.done() if self.check_task else "")
if self.check_task is not None:
if not self.check_task.done():
return ...
print("Cred check finished, we should have cloud access...")
user_id = self.check_task.result()
- print(user_id)
- self.check_task = None
+ self.check_task = self.remove_task(self.check_task)
self.progress = 1.0
if self.check_task is None:
+ self.progress = 1.0
self.status = {'VALID'}
return user_id
- def cancel(self):
- super().cancel()
- self.status = {'VALID'}
-
def __init__(self, job_id):
super().__init__(job_id)
@@ -191,21 +272,38 @@ class ClaudeJobCheckCredentials(ClaudeJob):
class ClaudeJobList(ClaudeJob):
@staticmethod
- async def ls(node):
- print("we should be listing Cloud content from Node ", node, "...")
- await asyncio.sleep(1)
+ async def ls(repo):
+ print("we should be listing Cloud content from %s..." % repo.curr_path_real)
+
+ project_uuid = repo.curr_path_real.project_uuid
+ node_uuid = repo.curr_path_real.node_uuid
+
+ if node_uuid:
+ # Query for sub-nodes of this node.
+ print("Getting subnodes for parent node %r" % node_uuid)
+ children = await pillar.get_nodes(parent_node_uuid=node_uuid, node_type='group_texture')
+ print(children)
+ elif project_uuid:
+ # Query for top-level nodes.
+ print("Getting subnodes for project node %r" % project_uuid)
+ children = await pillar.get_nodes(project_uuid=project_uuid, parent_node_uuid='', node_type='group_texture')
+ print(children)
+ else:
+ # Query for projects
+ print("No node UUID and no project UUID, listing available projects")
+ children = await pillar.get_texture_projects()
+ print(children)
- return ["..", "a", "b"]
+ repo.pending_path = []
+ repo.is_ready = True
@ClaudeJob.async_looper
- def start(self):
- self.nbr = 0
- self.tot = 0
- self.ls_task = asyncio.ensure_future(self.ls(self.curr_node))
+ def start(self, user_id):
+ self.ls_task = self.add_task(self.ls(self.repo))
self.status = {'VALID', 'RUNNING'}
@ClaudeJob.async_looper
- def update(self, user_id, dirs):
+ def update(self, user_id):
self.status = {'VALID', 'RUNNING'}
if user_id is None:
@@ -217,31 +315,32 @@ class ClaudeJobList(ClaudeJob):
print("Awaiting a valid user ID...")
return
+ self.progress += 0.05
+ if (self.progress > 1.0):
+ self.progress = 0.0
+
if self.ls_task is not None:
- if not self.ls_task.done():
- dirs[:] = [".."]
- return
- print("ls finished, we should have our children nodes now!")
- dirs[:] = self.ls_task.result()
- print(dirs)
- self.ls_task = None
-
- self.progress = self.nbr / self.tot if self.tot else 0.0
+ if self.ls_task.done():
+ print("ls finished, we should have our children nodes now!")
+ self.ls_task = self.remove_task(self.ls_task)
+
if self.ls_task is None:
+ self.progress = 1.0
self.status = {'VALID'}
def cancel(self):
- print("CANCELLING...")
+ if self.ls_task:
+ self.ls_task.cancel()
super().cancel()
- self.status = {'VALID'}
- def __init__(self, job_id, user_id, curr_node):
+ def __init__(self, job_id, user_id, repo):
super().__init__(job_id)
- self.curr_node = curr_node
+ self.repo = repo
+ self.curr_path = repo.curr_path_real
self.ls_task = None
- self.start()
+ self.start(user_id)
"""
@@ -322,20 +421,12 @@ class AssetEngineClaude(AssetEngine):
self.job_id_check_credentials = ...
self.check_credentials()
- self.reset()
+ self.repo = ClaudeRepository()
def __del__(self):
pass
########## Various helpers ##########
- def reset(self):
- print("Claude Reset!")
- self.jobs = {jid: j for jid, j in self.jobs.items() if jid == self.job_id_check_credentials}
- self.root = ""
- self.dirs = []
-
- self.sortedfiltered = []
-
def check_credentials(self):
if self.job_id_check_credentials is None:
return self.user_id
@@ -418,7 +509,7 @@ class AssetEngineClaude(AssetEngine):
if 'RUNNING' in job.status:
nbr_jobs += 1
progress += job.progress
- return progress / nbr_jobs if nbr_jobs else 0.0
+ return (progress / nbr_jobs) if nbr_jobs else 0.0
def kill(self, job_id):
if job_id:
@@ -429,27 +520,32 @@ class AssetEngineCl
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list