# ================================================================ # AMPP Framelight X — Nested Prefix Folder Organizer # Production v3.4.1 — Delimiter: -- # # Examples: # "BMG--Videos--File.mp4" → BMG / Videos / (asset linked) # "NEWS--PKG--Clip1.mxf" → NEWS / PKG / (asset linked) # "IMG--4709.jpg" → IMG / (asset linked) # "No-Delimiter.mp4" → skipped # # v3.3 Fix: Properly URL-encode folder paths including special # characters (apostrophes, ampersands, etc.) in hierarchy lookups. # # v3.4 Fix: Replace .NET-style hlist.Count with Python len(hlist). # hlist is a Python list (parsed JSON), not a .NET collection. # Using .Count caused a silent AttributeError (swallowed by bare # except), making every hierarchy lookup fail and causing duplicate # folders to be created on every run instead of reusing existing ones. # Also use .get() on hierarchy response to avoid KeyError when the # path doesn't exist yet. # # v3.4.1 Fix: Removed logger.log() call (unknown signature caused # TypeError). Hierarchy lookup failures now fall through silently # to folder creation, which is the correct recovery path anyway. # ================================================================ import json import urllib.parse PREFIX_DELIM = "--" asset_id = str(asset.Id) asset_name = str(job.AssetName) if PREFIX_DELIM not in asset_name: pass else: parts = asset_name.split(PREFIX_DELIM) if len(parts) < 2: pass else: folder_names = parts[:-1] parent_id = None current_path = "" for fname in folder_names: fname = fname.strip() if not fname: continue if current_path: current_path = current_path + "/" + fname else: current_path = fname folder_id = None try: # URL-encode the full path, preserving "/" as path separator encoded = urllib.parse.quote(current_path, safe="/") resp = httpClient.sendAsync( "GET", "api/v1/store/folder/folders/hierarchy?path=" + encoded ) # Use .get() in case the key is absent (path not found yet) # Use len() — hlist is a Python list, not a .NET collection (.Count doesn't exist) hlist = resp.get("hierarchy:list", []) if hlist and len(hlist) > 0: folder_id = str(hlist[-1]["folder:id"]) except: # Lookup failed — fall through to folder creation below folder_id = None if not folder_id: create_body = json.dumps({"name:text": fname}) if parent_id: create_body = json.dumps({ "name:text": fname, "parentFolders:tags": [parent_id] }) try: fresp = httpClient.sendAsync( "POST", "api/v1/store/folder/folders", create_body ) folder_id = str(fresp["folder:id"]) except Exception as ex: raise Exception( "Failed to create folder '" + fname + "' in '" + current_path + "': " + str(ex) ) parent_id = folder_id if parent_id: link_body = json.dumps( {"folder:id": parent_id, "asset:id": asset_id}, separators=(',', ':') ) try: httpClient.sendAsync( "POST", "api/v1/store/folder/references", link_body ) except: pass