asset_library/common/template.py

87 lines
2.4 KiB
Python
Raw Normal View History

2022-12-24 15:30:32 +01:00
import re
import os
from pathlib import Path
from fnmatch import fnmatch
from glob import glob
class Template:
field_pattern = re.compile(r'{(\w+)\*{0,2}}')
field_pattern_recursive = re.compile(r'{(\w+)\*{2}}')
def __init__(self, template):
#asset_data_path = Path(lib_path) / ASSETLIB_FILENAME
self.template = template
@property
def glob_pattern(self):
pattern = self.field_pattern_recursive.sub('**', self.template)
pattern = self.field_pattern.sub('*', pattern)
return pattern
@property
def re_pattern(self):
pattern = self.field_pattern_recursive.sub('([\\\w -_.\/]+)', self.template)
pattern = self.field_pattern.sub('([\\\w -_.]+)', pattern)
pattern = pattern.replace('?', '.')
pattern = pattern.replace('*', '.*')
return re.compile(pattern)
@property
def fields(self):
return self.field_pattern.findall(self.template)
#return [f or '0' for f in fields]
def parse(self, path):
path = Path(path).as_posix()
res = self.re_pattern.findall(path)
if not res:
print('Could not parse {path} with {self.re_pattern}')
return {}
fields = self.fields
if len(fields) == 1:
field_values = res
else:
field_values = res[0]
return {k:v for k,v in zip(fields, field_values)}
def format(self, data=None, **kargs):
data = {**(data or {}), **kargs}
try:
path = self.template.format(**data)
2022-12-27 23:49:57 +01:00
except KeyError as e:
print(f'Cannot format {self.template} with {data}, field {e} is missing')
2022-12-24 15:30:32 +01:00
return
path = os.path.expandvars(path)
return Path(path)
def glob(self, directory, pattern=None):
'''If pattern is given it need to be absolute'''
if pattern is None:
pattern = Path(directory, self.glob_pattern).as_posix()
for entry in os.scandir(directory):
entry_path = Path(entry.path)
if entry.is_file() and fnmatch(entry_path.as_posix(), pattern):
yield entry_path
elif entry.is_dir():
yield from self.glob(entry.path, pattern)
def find(self, data, **kargs):
pattern = self.format(data, **kargs)
paths = glob(pattern.as_posix())
if paths:
return Path(paths[0])
def __repr__(self):
return f'Template({self.template})'