こちらの続きです。
jsTree - C#ATIA
jsTreeの階層を作る為の方法が幾つかあるのですが、
alternative JSON formatと言う方法にしました。
jsTree
正式なjsonフォーマットでは無く、辞書のリストを作り、
辞書内に親のIDを付けておくことで階層表現するものの様です。
本当はAJAXでやりたかったのですが、サンプルすら表示されな
かった為、自分の力量では解決出来なさそうなと判断しました。
作りたいのは指定したフォルダ内のFusion360スクリプトの
名前のTreeです。こんな感じです。
# Fusion360API Python script import traceback import adsk.fusion import adsk.core import pathlib import json import re from typing import List from dataclasses import dataclass from dataclasses import field @dataclass class ScriptContainer: id: int path: pathlib.WindowsPath def __post_init__(self): pass def toJson( self, parent: str = '#'): stem = self.path.stem # ここでアイコン読み込みたい return { 'id' : self.id, 'parent' : parent, 'text' : stem, # 'icon' : None, } @dataclass class ScriptsContainer: count: int = field(default=0, compare=False) # patterns: List[str] = field(default_factory=list) items: List[pathlib.WindowsPath] = field(default_factory=list) def add( self, path: str) -> bool: pathObj: pathlib.WindowsPath = pathlib.Path(path) if not self.isFusionScript(pathObj): return False item: dataclass = ScriptContainer( self.count, pathObj ) self.count += 1 self.items.append(item) return True def addInsideFolder( self, path: str) -> bool: pathlib_obj: pathlib.WindowsPath = pathlib.Path(path) files = list(pathlib_obj.glob("*")) for file in files: if file.is_dir() and self.isFusionScript(file): self.add(file) return True def isFusionScript( self, pathObj: pathlib.Path) -> bool: # check filesS stem = pathObj.stem requiredList = [ f'{stem}.manifest', f'{stem}.py' ] files = [f.name for f in list(pathObj.glob("*"))] if len(set(requiredList) & set(files)) != len(requiredList): return False # check manifest manifest = pathObj / requiredList[0] with open(str(manifest),'r', encoding='utf-8') as f: data = f.read() data_json = json.loads(data) if not 'type' in data_json: return False if data_json['type'] != 'script': return False # # check py # manifest = pathObj / requiredList[1] # with open(str(manifest),'r', encoding='utf-8') as f: # data = f.read() # word = 'def run(context):' # if not word in data: # return False return True def getItemById( self, id: int) -> dataclass: for item in self.items: if item.id == id: return item return None def groupBy( self) -> list: # sort items = sorted(self.items, key = lambda x:x.path.stem.lower()) # key # コンストラクタにキーを入れるべき patterns = [ # 'a1', ['A-E', '^[a-e]'], ['F-J', '^[f-j]'], ['K-O', '^[k-o]'], ['P-T', '^[p-t]'], ['U-Z', '^[u-z]'], ] otherKey = ['other', 'other'] group = {key[0]: [] for key in patterns} group[otherKey[0]] = [] for item in items: stem = item.path.stem hitFg = False for pattern in patterns: match = re.search(pattern[1], stem.lower()) if match: group[pattern[0]].append(item) hitFg = True break if not hitFg: group[otherKey[0]].append(item) return group def getJstreeJson( self): # https://www.jstree.com/ groups = self.groupBy() treeContent = [] groupCount = self.count + 1 for key in groups: if len(groups[key]) < 1: continue treeContent.append( { 'id' : groupCount, 'parent' : '#', 'text' : key, } ) for item in groups[key]: treeContent.append(item.toJson(groupCount)) groupCount += 1 return treeContent def run(context): ui = adsk.core.UserInterface.cast(None) try: app: adsk.core.Application = adsk.core.Application.get() ui = app.userInterface path = r'C:\temp\Script' scripts: dataclass = ScriptsContainer() scripts.addInsideFolder(path) jstreeJson = scripts.getJstreeJson() print(json.dumps(jstreeJson, indent=2)) except: if ui: ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
実行するとこんな感じです。
[ { "id": 59, "parent": "#", "text": "A-E" }, { "id": 0, "parent": 59, "text": "a1" }, { "id": 1, "parent": 59, "text": "a2" }, { "id": 4, "parent": 59, "text": "a_clone" }, ・・・
未完成なのですが、これをjsTreeに読み込ませると・・・
ハメコミ画像ですが、こんな感じです。
何故、こんな中途半端なコードを載せるかと言うと、
一度作りかかっていたものを紛失し、最初から作り直したためです。
(相変わらず管理が悪い)