def eval_template(template, sobject=None, parent=None, snapshot=None): ''' generic method to values an sobject template expression''' # parse the pattern string expression = re.compile(r'{([\w|\.|\#]+\[?\d?\]?)}') temp_list = expression.findall(template) # if nothing is found, then just return parse through an expression if not temp_list: #return template # put in the ability to add expressions env_sobjects = { 'snapshot': snapshot } xp = ExpressionParser() result = xp.eval(template, sobject, mode='string', env_sobjects=env_sobjects) test = template test = test.replace("{", "") test = test.replace("}", "") if test != result: return result # if nothing is found, temp_list is empty if not temp_list: temp_list = [] # the main sobject if sobject: project = sobject.get_project() else: project = Project.get() result = template for part in temp_list: if part.find(".") != -1: # explict declarasions object, attr = part.split(".") index = -1 if attr.endswith(']'): # ugly, but it works attr, index = attr.split("[") index = int(index.rstrip("]")) if object == "sobject": value = sobject.get_value(attr) elif object == "parent": if not parent: parent = sobject.get_parent() if parent: value = parent.get_value(attr) else: value = '' elif object in ["login", "user"]: login = Environment.get_security().get_login() value = login.get_value(attr) else: raise NamingException("Can't parse part [%s] in template" % part) if index != -1: value = re.split("[/._]", value) value = value[index] else: value = part result = result.replace("{%s}" % part, str(value)) return result
def _test_schema(my): # prod type test prod_proj_code = "sample3d" if Project.get_by_code(prod_proj_code): prod_schema = Schema.get_by_project_code(prod_proj_code) parent_type = prod_schema.get_parent_type('prod/asset') my.assertEquals('prod/asset_library', parent_type) parent_type = prod_schema.get_parent_type('prod/sequence') my.assertEquals('prod/episode', parent_type) parent_type = prod_schema.get_parent_type('prod/shot') my.assertEquals('prod/sequence', parent_type) parent_type = prod_schema.get_parent_type('sthpw/task') my.assertEquals('*', parent_type) parent_type = prod_schema.get_parent_type('sthpw/note') my.assertEquals('*', parent_type) parent_type = prod_schema.get_parent_type('prod/render') my.assertEquals('*', parent_type) parent_type = prod_schema.get_parent_type('prod/submission') my.assertEquals('*', parent_type) schema = Schema.get_by_project_code("unittest") # create a new search_type schema.add_search_type("unittest/car", parent_type='unittest/person', commit=False) schema.add_search_type("unittest/house", parent_type='unittest/person', commit=False) parent_type = schema.get_parent_type('unittest/city') my.assertEquals('unittest/country', parent_type) # get all of the child types child_types = schema.get_child_types('unittest/person') #print "CHILD TYPES ", child_types expected = ['unittest/person_in_car', 'unittest/house'] my.assertEquals(True, expected[0] in child_types) my.assertEquals(True, expected[1] in child_types) # create a new schema that has the unittest as the parent new_schema = SearchType.create(Schema.SEARCH_TYPE) new_schema.set_value("code", "unittest/custom") new_schema_xml = ''' <schema parent='unittest'> <search_type name='unittest/account'/> <connect from='unittest/person' to='unittest/account' type='hierarchy'/> <connect from='*' to='unittest/poof' type='hierarchy'/> </schema> ''' new_schema.set_xml(new_schema_xml) # get search_types defined in this schema search_types = new_schema.get_search_types(hierarchy=False) my.assertEquals(1, len(search_types) ) # get all search_types search_types = new_schema.get_search_types() # add bunch of dummy initial tasks to the person initial_tasks = Task.add_initial_tasks(my.person, 'task') # check status_log static trigger single_task = initial_tasks[0] from pyasm.search import Search to_status = Search.eval('@GET(sthpw/status_log.to_status)', sobjects=[single_task], single=True) my.assertEquals(to_status, "Assignment") single_task.set_value('status', "Test Done") single_task.commit(triggers=True) ExpressionParser.clear_cache() to_status = Search.eval("@GET(sthpw/status_log['@ORDER_BY','id desc'].to_status)", sobjects=[single_task], single=True) my.assertEquals(to_status, "Test Done") # get tasks with get_all_children() tasks = my.person.get_all_children("sthpw/task") my.assertEquals(len(initial_tasks), len(tasks) ) # get notes with get_all_children() Note.create(my.person, "test note", context='default') Note.create(my.person, "test note2", context='default2') notes = my.person.get_all_children("sthpw/note") my.assertEquals(2, len(notes) ) #relationship schema = Schema.get() if Project.get_by_code('sample3d'): relationship = schema.get_relationship('prod/asset','sthpw/snapshot') my.assertEquals(relationship, 'search_code') #my.assertEquals(relationship, 'search_type') relationship = schema.get_relationship('prod/asset','sthpw/task') my.assertEquals(relationship, 'search_code') #my.assertEquals(relationship, 'search_type') relationship = schema.get_relationship('prod/shot','sthpw/note') my.assertEquals(relationship, 'search_code') #my.assertEquals(relationship, 'search_type') relationship = schema.get_relationship('sthpw/file','sthpw/snapshot') my.assertEquals(relationship, 'code') relationship = schema.get_relationship('sthpw/project_type','sthpw/project') my.assertEquals(relationship, 'code') relationship = schema.get_relationship('unittest/car','unittest/house') my.assertEquals(relationship, None) # test parent filter search in sample3d if Project.get_by_code('sample3d'): from pyasm.prod.biz import * Project.set_project('sample3d') shot = Shot.get_by_code('RC_001_001') if not shot: shot = Shot.create('RC_001_001', 'Some test shot') asset = SearchType.create('prod/asset') asset.set_value('code','unittest010') asset.set_value('name','unittest010') asset.commit() for x in xrange(3): ShotInstance.create(shot, asset, 'unittest_veh_001', unique=False) instances = ShotInstance.get_by_shot_and_asset(shot, asset) parent_type = 'prod/shot' parent_search = Search(parent_type) parent_search.add_filter('code','RC_001_001') search = Search('prod/shot_instance') search.add_filter('asset_code', asset.get_code()) # we want the base here sobject_type = search.get_search_type_obj().get_base_key() schema = Schema.get() relationship = schema.get_relationship(sobject_type, parent_type) parents = parent_search.get_sobjects() if parents: if relationship in ["code", "id", "search_type"]: search.add_relationship_filters(parents) sobjects = search.get_sobjects() my.assertEquals(len(instances), len(sobjects)) relationship_attrs = schema.get_relationship_attrs('sthpw/transaction_log','sthpw/sobject_log') rev_relationship_attrs = schema.get_relationship_attrs('sthpw/sobject_log','sthpw/transaction_log') for attrs in [ relationship_attrs, rev_relationship_attrs]: my.assertEquals(attrs.get('from_col'), 'transaction_log_id') my.assertEquals(attrs.get('to_col'), 'id') my.assertEquals(attrs.get('from'), 'sthpw/sobject_log') my.assertEquals(attrs.get('to'), 'sthpw/transaction_log') my.assertEquals(attrs.get('relationship'), 'id') my.assertEquals(attrs.get('disabled'), None) Project.set_project('unittest')
def naming_to_file(my, template, sobject, snapshot, file=None, ext=None, file_type=None): ''' # chr001_model_v004_00001.ext ''' version_padding = Config.get_value("checkin", "version_padding") if version_padding: version_padding = int(version_padding) else: version_padding = 3 version_expr = "%%0.%dd" % version_padding # the main sobject project = sobject.get_project() # parse the pattern string expression = re.compile(r'{([\w|\.|\#]+\[?\d?\]?)}') temp_list = expression.findall(template) # if nothing is found, then just return parse through an expression if not temp_list: #return template # put in the ability to add expressions from pyasm.biz import ExpressionParser xp = ExpressionParser() env_sobjects = { 'snapshot': snapshot, 'file': file } file_name = file.get_value("file_name") base_type = file.get_value("base_type") if base_type =='directory': base = file_name ext = None else: base, ext = os.path.splitext(file_name) if not ext: value = None else: # external ext starts with a . ext = ext.lstrip(".") value = ext vars = {'EXT': value, 'BASEFILE': base} result = xp.eval(template, sobject, mode='string', env_sobjects=env_sobjects, vars=vars) test = template test = test.replace("{", "") test = test.replace("}", "") # don't allow / in filename test = test.replace("/", "_") if test != result: return result result = template for part in temp_list: index = -1 if part.find(".") != -1: # explict declarations object, attr = part.split(".") if attr.endswith(']'): # ugly, but it works attr, index = attr.split("[") index = int(index.rstrip("]")) if object == "sobject": value = sobject.get_value(attr) elif object == "snapshot": if not snapshot: continue value = snapshot.get_value(attr) if attr in ['version', 'revision']: if value: value = version_expr % int(value) else: value = "0"*version_padding #value = snapshot.get_value(attr) elif object == "file": if attr == 'file_type': if file_type: value = file_type else: value = 'main' else: value = file.get_value(attr) elif object == "parent": parent = sobject.get_parent() if not parent: value = "NO_PARENT" else: value = parent.get_value(attr) elif object in ["login","user"]: login = Environment.get_login() value = login.get_value(attr) elif object == "project": project = Project.get() value = project.get_value(attr) else: raise NamingException("Can't parse part [%s] in template" % part) else: # use implicit declarations attr = part if attr.endswith(']'): # ugly, but it works attr, index = attr.split("[") index = int(index.rstrip("]")) if attr == "context": value = snapshot.get_value(attr) elif attr == "snapshot_type": value = snapshot.get_value(attr) elif attr == "version": value = snapshot.get_value(attr) if value: value = version_expr % int(value) else: value = "0"*version_padding elif attr == "revision": value = snapshot.get_value(attr) if value: value = version_expr % int(value) else: value = "0"*version_padding elif attr.startswith("#"): if not snapshot: continue value = snapshot.get_value("version") expr = "%%0.%sd" % len(attr) if value: value = expr % int(value) else: value = "0" * len(attr) elif attr == "basefile": file_name = file.get_value("file_name") base_type = file.get_value("base_type") if base_type =='directory': value = file_name else: base, ext = os.path.splitext(file_name) value = base elif attr == "ext": if not ext: file_name = file.get_value("file_name") base_type = file.get_value("base_type") if base_type =='directory': value = '' else: base, ext = os.path.splitext(file_name) value = ext.lstrip(".") else: # external ext starts with a . ext = ext.lstrip(".") value = ext elif attr in ["login","user"]: login = Environment.get_login() value = login.get_value("login") elif attr == "file_type": if file_type: value = file_type else: value = 'main' elif attr.startswith('date'): # {date,%Y-%m-%d_%H-%M-%S]} import time parts = attr.split(",", 1) if len(parts) == 2: format = parts[1] else: format = "%Y%m%d" value = time.strftime(format, time.localtime()) else: value = sobject.get_value(attr) # tbis applies to context for now if index != -1: value = re.split("[/]", value) if len(value) <= index: value = '!' else: value = value[index] #if not value: # raise NamingException("Value for part [%s] is empty" % part) if isinstance(value, int): value = str(value) result = result.replace("{%s}" % part, value) # don't allow / in filename, # FIXME: it's not put in get_filesystem_name since it # is used for directory name also, need to modify that result = result.replace("/", "_") # post process result so that it looks good result = Common.get_filesystem_name(result) return result
def naming_to_dir(my, template, sobject, snapshot, file=None, file_type=None): ''' # shot/SEQ001/shot_001 ''' # the main sobject project = sobject.get_project() # parse the pattern string expression = re.compile(r'{([\w|\.|\#]+\[?\d?\]?)}') temp_list = expression.findall(template) # if nothing is found, then just return parse through an expression if not temp_list: #return template # put in the ability to add expressions from pyasm.biz import ExpressionParser xp = ExpressionParser() env_sobjects = { 'snapshot': snapshot, 'file': file } result = xp.eval(template, sobject, mode='string', env_sobjects=env_sobjects) test = template test = test.replace("{", "") test = test.replace("}", "") if test != result: return result # version padding defaults version_padding = Config.get_value("checkin", "version_padding") if version_padding: version_padding = int(version_padding) else: version_padding = 3 version_expr = "%%0.%dd" % version_padding # use simplified expressions result = template for part in temp_list: index = -1 if part.find(".") != -1: # explict declarasions object, attr = part.split(".") if attr.endswith(']'): # ugly, but it works attr, index = attr.split("[") index = int(index.rstrip("]")) if object == "sobject": if attr == "timestamp": value = my._get_timestamp(sobject) else: value = sobject.get_value(attr) elif object == "snapshot": if not snapshot: continue if attr == "timestamp": value = my._get_timestamp(snapshot) else: value = snapshot.get_value(attr) if attr in ['version', 'revision']: if value: value = version_expr % int(value) else: value = "0"*version_padding elif object == "search_type": search_type_obj = sobject.get_search_type_obj() value = search_type_obj.get_value(attr) elif object == "parent": parent = sobject.get_parent() if not parent: value = "NO_PARENT" else: if attr == 'timestamp': value = my._get_timestamp(parent) else: value = parent.get_value(attr) elif object == "project": project = Project.get() value = project.get_value(attr) elif object in ["login","user"]: login = Environment.get_login() value = login.get_value(attr) elif object == "file": if attr == 'file_type': if file_type: value = file_type else: value = 'main' else: value = file.get_value(attr) else: raise NamingException("Can't parse part [%s] in template" % part) else: # use implicit declarations attr = part if attr.endswith(']'): # ugly, but it works attr, index = attr.split("[") index = int(index.rstrip("]")) if attr in ['context','snapshot_type','version','revision'] \ and not snapshot: continue if attr == "context": value = snapshot.get_value(attr) elif attr == "snapshot_type": value = snapshot.get_value(attr) elif attr == "version": value = snapshot.get_value(attr) if value: value = version_expr % int(value) else: value = "0"*version_padding elif attr == "revision": value = snapshot.get_value(attr) if value: value = version_expr % int(value) else: value = "0"*version_padding elif attr.startswith("#"): if not snapshot: continue value = snapshot.get_value("version") expr = "%%0.%sd" % len(attr) if value: value = expr % int(value) else: value = "0" * len(attr) elif attr.startswith("id"): value = "%0.5d" % sobject.get_id() elif attr in ["login","user"]: login = Environment.get_login() value = login.get_value("login") elif attr == "file_type": if file_type: value = file_type else: value = 'main' else: if attr == "timestamp": value = my._get_timestamp(sobject) else: value = sobject.get_value(attr) if index != -1: value = re.split("[/]", value) if len(value) <= index: value = '!' else: try: value = value[index] except IndexError, e: value = "" if not sobject.is_insert() and not value: value = "" #raise NamingException("Naming convention error: Value for part [%s] is empty" % part) if isinstance(value, int): value = str(value) result = result.replace("{%s}" % part, value)
def _test_schema(my): # prod type test prod_proj_code = "sample3d" if Project.get_by_code(prod_proj_code): prod_schema = Schema.get_by_project_code(prod_proj_code) parent_type = prod_schema.get_parent_type('prod/asset') my.assertEquals('prod/asset_library', parent_type) parent_type = prod_schema.get_parent_type('prod/sequence') my.assertEquals('prod/episode', parent_type) parent_type = prod_schema.get_parent_type('prod/shot') my.assertEquals('prod/sequence', parent_type) parent_type = prod_schema.get_parent_type('sthpw/task') my.assertEquals('*', parent_type) parent_type = prod_schema.get_parent_type('sthpw/note') my.assertEquals('*', parent_type) parent_type = prod_schema.get_parent_type('prod/render') my.assertEquals('*', parent_type) parent_type = prod_schema.get_parent_type('prod/submission') my.assertEquals('*', parent_type) schema = Schema.get_by_project_code("unittest") # create a new search_type schema.add_search_type("unittest/car", parent_type='unittest/person', commit=False) schema.add_search_type("unittest/house", parent_type='unittest/person', commit=False) parent_type = schema.get_parent_type('unittest/city') my.assertEquals('unittest/country', parent_type) # get all of the child types child_types = schema.get_child_types('unittest/person') expected = ['unittest/person_in_car', 'unittest/house'] my.assertEquals(True, expected[0] in child_types) my.assertEquals(True, expected[1] in child_types) # create a new schema that has the unittest as the parent new_schema = SearchType.create(Schema.SEARCH_TYPE) new_schema.set_value("code", "unittest/custom") new_schema_xml = ''' <schema parent='unittest'> <search_type name='unittest/account'/> <connect from='unittest/person' to='unittest/account' type='hierarchy'/> <connect from='*' to='unittest/poof' type='hierarchy'/> </schema> ''' new_schema.set_xml(new_schema_xml) # get search_types defined in this schema search_types = new_schema.get_search_types(hierarchy=False) my.assertEquals(1, len(search_types)) # get all search_types search_types = new_schema.get_search_types() # add bunch of dummy initial tasks to the person initial_tasks = Task.add_initial_tasks(my.person, 'task') # check status_log static trigger single_task = initial_tasks[0] from pyasm.search import Search to_status = Search.eval('@GET(sthpw/status_log.to_status)', sobjects=[single_task], single=True) my.assertEquals(to_status, "Assignment") single_task.set_value('status', "Test Done") single_task.commit(triggers=True) ExpressionParser.clear_cache() to_status = Search.eval( "@GET(sthpw/status_log['@ORDER_BY','id desc'].to_status)", sobjects=[single_task], single=True) my.assertEquals(to_status, "Test Done") # get tasks with get_all_children() tasks = my.person.get_all_children("sthpw/task") my.assertEquals(len(initial_tasks), len(tasks)) # get notes with get_all_children() Note.create(my.person, "test note", context='default') Note.create(my.person, "test note2", context='default2') notes = my.person.get_all_children("sthpw/note") my.assertEquals(2, len(notes)) #relationship schema = Schema.get() if Project.get_by_code('sample3d'): relationship = schema.get_relationship('prod/asset', 'sthpw/snapshot') my.assertEquals(relationship, 'search_code') #my.assertEquals(relationship, 'search_type') relationship = schema.get_relationship('prod/asset', 'sthpw/task') my.assertEquals(relationship, 'search_code') #my.assertEquals(relationship, 'search_type') relationship = schema.get_relationship('prod/shot', 'sthpw/note') my.assertEquals(relationship, 'search_code') #my.assertEquals(relationship, 'search_type') relationship = schema.get_relationship('sthpw/file', 'sthpw/snapshot') my.assertEquals(relationship, 'code') relationship = schema.get_relationship('sthpw/project_type', 'sthpw/project') my.assertEquals(relationship, 'code') relationship = schema.get_relationship('unittest/car', 'unittest/house') my.assertEquals(relationship, None) # test parent filter search in sample3d if Project.get_by_code('sample3d'): from pyasm.prod.biz import * Project.set_project('sample3d') shot = Shot.get_by_code('RC_001_001') if not shot: shot = Shot.create('RC_001_001', 'Some test shot') asset = SearchType.create('prod/asset') asset.set_value('code', 'unittest010') asset.set_value('name', 'unittest010') asset.commit() for x in xrange(3): ShotInstance.create(shot, asset, 'unittest_veh_001', unique=False) instances = ShotInstance.get_by_shot_and_asset(shot, asset) parent_type = 'prod/shot' parent_search = Search(parent_type) parent_search.add_filter('code', 'RC_001_001') search = Search('prod/shot_instance') search.add_filter('asset_code', asset.get_code()) # we want the base here sobject_type = search.get_search_type_obj().get_base_key() schema = Schema.get() relationship = schema.get_relationship(sobject_type, parent_type) parents = parent_search.get_sobjects() if parents: if relationship in ["code", "id", "search_type"]: search.add_relationship_filters(parents) sobjects = search.get_sobjects() my.assertEquals(len(instances), len(sobjects)) relationship_attrs = schema.get_relationship_attrs( 'sthpw/transaction_log', 'sthpw/sobject_log') rev_relationship_attrs = schema.get_relationship_attrs( 'sthpw/sobject_log', 'sthpw/transaction_log') for attrs in [relationship_attrs, rev_relationship_attrs]: my.assertEquals(attrs.get('from_col'), 'transaction_log_id') my.assertEquals(attrs.get('to_col'), 'id') my.assertEquals(attrs.get('from'), 'sthpw/sobject_log') my.assertEquals(attrs.get('to'), 'sthpw/transaction_log') my.assertEquals(attrs.get('relationship'), 'id') my.assertEquals(attrs.get('disabled'), None) Project.set_project('unittest')
def eval_template(template, sobject=None, parent=None, snapshot=None): ''' generic method to values an sobject template expression. ''' #NOTE: no file kwarg # parse the pattern string #expression = re.compile(r'{([\w|\.|\#]+\[?\d?\]?)}') expression = re.compile(r'{(.*?)}') temp_list = expression.findall(template) # if nothing is found, then just return parse through an expression xp = ExpressionParser() if not temp_list: #return template # put in the ability to add expressions env_sobjects = { 'snapshot': snapshot } result = xp.eval(template, sobject, mode='string', env_sobjects=env_sobjects) test = template test = test.replace("{", "") test = test.replace("}", "") if test != result: return result # if nothing is found, temp_list is empty if not temp_list: temp_list = [] # the main sobject if sobject: project = sobject.get_project() else: project = Project.get() result = template for part in temp_list: index = -1 if part.startswith(("@","$")): env_sobjects = { 'snapshot': snapshot, } value = xp.eval("{%s}" % part, sobject, env_sobjects=env_sobjects, vars=vars, single=True) elif part.find(".") != -1: # explict declarasions object, attr = part.split(".") if attr.endswith(']'): # ugly, but it works attr, index = attr.split("[") index = int(index.rstrip("]")) if object == "sobject": value = sobject.get_value(attr) elif object == "parent": if not parent: parent = sobject.get_parent() if parent: value = parent.get_value(attr) else: value = '' elif object in ["login", "user"]: login = Environment.get_security().get_login() value = login.get_value(attr) else: raise NamingException("Can't parse part [%s] in template" % part) if index != -1: value = re.split("[/._]", value) value = value[index] else: value = part result = result.replace("{%s}" % part, str(value)) return result
def naming_to_dir(my, template, sobject, snapshot, file=None, file_type=None): ''' # shot/SEQ001/shot_001 ''' # the main sobject project = sobject.get_project() # parse the pattern string expression = re.compile(r'{(.*?)}') temp_list = expression.findall(template) from pyasm.biz import ExpressionParser xp = ExpressionParser() ''' # if nothing is found, then just return parse through an expression if not temp_list: #return template # put in the ability to add expressions env_sobjects = { 'snapshot': snapshot, 'file': file } result = xp.eval(template, sobject, mode='string', env_sobjects=env_sobjects) test = template test = test.replace("{", "") test = test.replace("}", "") if test != result: return result ''' # version padding defaults version_padding = Config.get_value("checkin", "version_padding") if version_padding: version_padding = int(version_padding) else: version_padding = 3 version_expr = "%%0.%dd" % version_padding # use simplified expressions result = template for part in temp_list: index = -1 if part.startswith(("@","$")): env_sobjects = { 'snapshot': snapshot, 'file': file } value = xp.eval("{%s}" % part, sobject, env_sobjects=env_sobjects, single=True) elif part.find(".") != -1: # explict declarasions object, attr = part.split(".") if attr.endswith(']'): # ugly, but it works attr, index = attr.split("[") index = int(index.rstrip("]")) if object == "sobject": if attr == "timestamp": value = my._get_timestamp(sobject) else: value = sobject.get_value(attr) elif object == "snapshot": if not snapshot: continue if attr == "timestamp": value = my._get_timestamp(snapshot) else: value = snapshot.get_value(attr) if attr in ['version', 'revision']: if value: value = version_expr % int(value) else: value = "0"*version_padding elif object == "search_type": search_type_obj = sobject.get_search_type_obj() value = search_type_obj.get_value(attr) elif object == "parent": parent = sobject.get_parent() if not parent: value = "NO_PARENT" else: if attr == 'timestamp': value = my._get_timestamp(parent) else: value = parent.get_value(attr) elif object == "project": project = Project.get() value = project.get_value(attr) elif object in ["login","user"]: login = Environment.get_login() value = login.get_value(attr) elif object == "file": if attr == 'file_type': if file_type: value = file_type else: value = 'main' else: value = file.get_value(attr) else: raise NamingException("Can't parse part [%s] in template" % part) else: # use implicit declarations attr = part if attr.endswith(']'): # ugly, but it works attr, index = attr.split("[") index = int(index.rstrip("]")) if attr in ['context','process','snapshot_type','version','revision'] \ and not snapshot: continue if attr in ["context","process","snapshot_type"]: value = snapshot.get_value(attr) elif attr == "version": value = snapshot.get_value(attr) if value: value = version_expr % int(value) else: value = "0"*version_padding elif attr == "revision": value = snapshot.get_value(attr) if value: value = version_expr % int(value) else: value = "0"*version_padding elif attr.startswith("#"): if not snapshot: continue value = snapshot.get_value("version") expr = "%%0.%sd" % len(attr) if value: value = expr % int(value) else: value = "0" * len(attr) elif attr.startswith("id"): value = "%0.5d" % sobject.get_id() elif attr in ["login","user"]: login = Environment.get_login() value = login.get_value("login") elif attr == "file_type": if file_type: value = file_type else: value = 'main' else: if attr == "timestamp": value = my._get_timestamp(sobject) else: value = sobject.get_value(attr) if index != -1: value = re.split("[/]", value) if len(value) <= index: value = '!' else: try: value = value[index] except IndexError, e: value = "" if not sobject.is_insert() and not value: value = "" #raise NamingException("Naming convention error: Value for part [%s] is empty" % part) if isinstance(value, int): value = str(value) result = result.replace("{%s}" % part, value)
def naming_to_file(my, template, sobject, snapshot, file=None, ext=None, file_type=None): ''' # chr001_model_v004_00001.ext ''' version_padding = Config.get_value("checkin", "version_padding") if version_padding: version_padding = int(version_padding) else: version_padding = 3 version_expr = "%%0.%dd" % version_padding # the main sobject project = sobject.get_project() # parse the pattern string expression = re.compile(r'{(.*?)}') #expression = re.compile(r'{([\w|\.|\#]+\[?\d?\]?)}') temp_list = expression.findall(template) result = template from pyasm.biz import ExpressionParser xp = ExpressionParser() # if nothing is found, then just return parse through an expression ''' if not temp_list: #return template # put in the ability to add expressions env_sobjects = { 'snapshot': snapshot, 'file': file } file_name = file.get_value("file_name") base_type = file.get_value("base_type") if base_type =='directory': base = file_name ext = None else: base, ext = os.path.splitext(file_name) if not ext: value = None else: # external ext starts with a . ext = ext.lstrip(".") value = ext vars = {'EXT': value, 'BASEFILE': base} result = xp.eval(template, sobject, mode='string', env_sobjects=env_sobjects, vars=vars) test = template test = test.replace("{", "") test = test.replace("}", "") # don't allow / in filename test = test.replace("/", "_") if test != result: return result ''' base = None if file: file_name = file.get_value("file_name") base_type = file.get_value("base_type") if base_type =='directory': base = file_name ext = None else: base, file_ext = os.path.splitext(file_name) # passed in ext takes prescedence if not ext: ext = file_ext if not ext: value = None else: # external ext starts with a . ext = ext.lstrip(".") value = ext vars = {'EXT': value, 'BASEFILE': base} for part in temp_list: index = -1 if part.startswith(("@","$")): env_sobjects = { 'snapshot': snapshot, 'file': file } value = xp.eval("{%s}" % part, sobject, env_sobjects=env_sobjects, vars=vars, single=True) elif part.find(".") != -1: # explict declarations object, attr = part.split(".") if attr.endswith(']'): # ugly, but it works attr, index = attr.split("[") index = int(index.rstrip("]")) if object == "sobject": value = sobject.get_value(attr) elif object == "snapshot": if not snapshot: continue value = snapshot.get_value(attr) if attr in ['version', 'revision']: if value: value = version_expr % int(value) else: value = "0"*version_padding #value = snapshot.get_value(attr) elif object == "file": if attr == 'file_type': if file_type: value = file_type else: value = 'main' else: value = file.get_value(attr) elif object == "parent": parent = sobject.get_parent() if not parent: value = "NO_PARENT" else: value = parent.get_value(attr) elif object in ["login","user"]: login = Environment.get_login() value = login.get_value(attr) elif object == "project": project = Project.get() value = project.get_value(attr) else: raise NamingException("Can't parse part [%s] in template" % part) else: # use implicit declarations attr = part if attr.endswith(']'): # ugly, but it works attr, index = attr.split("[") index = int(index.rstrip("]")) if attr in ["context","process","snapshot_type"]: value = snapshot.get_value(attr) elif attr == "version": value = snapshot.get_value(attr) if value: value = version_expr % int(value) else: value = "0"*version_padding elif attr == "revision": value = snapshot.get_value(attr) if value: value = version_expr % int(value) else: value = "0"*version_padding elif attr.startswith("#"): if not snapshot: continue value = snapshot.get_value("version") expr = "%%0.%sd" % len(attr) if value: value = expr % int(value) else: value = "0" * len(attr) elif attr == "basefile": file_name = file.get_value("file_name") base_type = file.get_value("base_type") if base_type =='directory': value = file_name else: base, ext = os.path.splitext(file_name) value = base elif attr == "ext": if not ext: file_name = file.get_value("file_name") base_type = file.get_value("base_type") if base_type =='directory': value = '' else: base, ext = os.path.splitext(file_name) value = ext.lstrip(".") else: # external ext starts with a . ext = ext.lstrip(".") value = ext elif attr in ["login","user"]: login = Environment.get_login() value = login.get_value("login") elif attr == "file_type": if file_type: value = file_type else: value = 'main' elif attr.startswith('date'): # {date,%Y-%m-%d_%H-%M-%S]} import time parts = attr.split(",", 1) if len(parts) == 2: format = parts[1] else: format = "%Y%m%d" value = time.strftime(format, time.localtime()) else: value = sobject.get_value(attr) # tbis applies to context for now if index != -1: value = re.split("[/]", value) if len(value) <= index: value = '!' else: value = value[index] #if not value: # raise NamingException("Value for part [%s] is empty" % part) if isinstance(value, int): value = str(value) elif value is None: value = "" result = result.replace("{%s}" % part, value) # don't allow / in filename, # FIXME: it's not put in get_filesystem_name since it # is used for directory name also, need to modify that result = result.replace("/", "_") # remove trailing . if any if result and result[-1] == '.': result = result[:-1] # post process result so that it looks good result = Common.get_filesystem_name(result) return result
class Naming(SObject): SEARCH_TYPE = "config/naming" # Commenting this out. File names can be anything. We cannot and should # not enforce what people think are correct file names for whatever # purpose they happen to need it for. def validate(my): sandbox_dir_naming = my.get_value('sandbox_dir_naming', no_exception=True) dir_naming = my.get_value('dir_naming', no_exception=True) if sandbox_dir_naming and sandbox_dir_naming.endswith('/'): raise TacticException('sandbox_dir_naming should not end with /') if dir_naming and dir_naming.endswith('/'): raise TacticException('dir_naming should not end with /') #file_name = my.get_value('file_naming') #p = re.compile('.*\.({ext}|\w+)$') #if not p.match(file_name): # raise TacticException('file_naming has to end with .{ext} or .xxx') def get_by_search_type(search_type): # if the project is in admin, then skip this step because there is # no database # FIXME: this should be handle more gracefully elsewhere if Project.get_project_name() == "admin": return "" naming_dict = Container.get("Naming:cache") if naming_dict == None: naming_dict = {} Container.put("Naming:cache", naming_dict) search = Search(Naming) namings = search.get_sobjects() for naming in namings: #value = naming.get_value("file_naming") naming_dict[naming.get_value("search_type")] = naming return naming_dict.get(search_type) get_by_search_type = staticmethod(get_by_search_type) def has_versionless(cls, sobject, snapshot, versionless=''): '''check to see if a naming is defined''' return cls.get(sobject, snapshot, versionless, mode='check') != None has_versionless = classmethod(has_versionless) def get(sobject, snapshot, versionless='', file_path='', mode='find'): ''' The special check mode is used in versionless to check whether a naming convention is defined. It should only be called by has_versionless() mode: find - find the naming check - check that a naming is defined ''' if not versionless and snapshot: version = snapshot.get_value("version") if version == -1: versionless = 'latest' elif version == 0: versionless = 'current' else: versionless = '' # get the project of the sobject project_code = sobject.get_project_code() if versionless: cache_key = "Naming:cache:%s:%s" % (project_code, versionless) else: cache_key = "Naming:cache:%s" % project_code naming_dict = Container.get(cache_key) if naming_dict == None: naming_dict = {} Container.put(cache_key, naming_dict) namings = Container.get("Naming:namings") if namings == None: try: search = Search(Naming) namings = search.get_sobjects() except SearchException, e: # it is possible that there is no naming table # in this project. This is possible if the datbase # is just a resource if str(e).find("does not exist for database"): namings = {} else: raise Container.put("Naming:namings", namings) for naming in namings: # depending on whether the snapshot is latest or current # switch which column we are looking at n_versionless = '' latest = naming.get_value("latest_versionless",no_exception=True) current = naming.get_value("current_versionless",no_exception=True) if versionless == 'latest': if latest == True: n_versionless = 'latest' elif versionless == 'current': if current == True: n_versionless = 'current' else: if latest == True or current == True: n_versionless = "XXX" n_search_type = naming.get_value("search_type") n_snapshot_type = naming.get_value("snapshot_type") n_context = naming.get_value("context") key = "|".join( [n_search_type.strip(), n_snapshot_type.strip(), n_context.strip(), str(n_versionless)]) #key = "|".join( [n_search_type.strip(), n_snapshot_type.strip(), n_context.strip()]) naming_list = naming_dict.get(key) if naming_list == None: naming_list = [] naming_dict[key] = naming_list naming_list.append(naming) #naming_dict[key] = naming # build the key search_type = sobject.get_base_search_type() snapshot_type = 'file' context = '' # supports */<subcontext> and <context>/* context_list = [] snapshot_version = None if snapshot: snapshot_type = snapshot.get_value("snapshot_type") snapshot_version = snapshot.get_value("version") context = snapshot.get_value("context") if context: context_list.append(context) if context.find('/') == -1: context_list.append('%s/*' %context) else: parts = context.split('/') cont = parts[0] subcontext = "/".join(parts[1:]) context_list.append('*/%s' %subcontext) context_list.append('%s/*' %cont) else: context_list.append('') # get the keys to look for keys = [] if mode == 'check' or snapshot_version in [-1, 0]: for context in context_list: keys.append("%s|%s|%s|%s" % (search_type, snapshot_type, context, versionless ) ) keys.append("%s||%s|%s" % (search_type, context, versionless ) ) keys.append("%s|%s||%s" % (search_type, snapshot_type, versionless ) ) keys.append("%s|||%s" % (search_type, versionless ) ) else: for context in context_list: keys.append("%s|%s|%s|%s" % (search_type, snapshot_type, context, versionless ) ) keys.append("%s||%s|%s" % (search_type, context, versionless ) ) keys.append("%s|%s|%s|" % (search_type, snapshot_type, context) ) keys.append("%s||%s|" % (search_type, context) ) keys.append("%s|%s||%s" % (search_type, snapshot_type, versionless ) ) keys.append("%s|%s||" % (search_type, snapshot_type) ) keys.append("%s|||%s" % (search_type, versionless ) ) keys.append("%s|||" % (search_type) ) # these 2 are questionable, we should always include search_type for context in context_list: keys.append("||%s|" % (context) ) keys.append("|%s||" % (snapshot_type) ) keys.append("") naming = None from pyasm.biz import ExpressionParser xp = ExpressionParser() base_name = os.path.basename(file_path) base, ext = os.path.splitext(base_name) if not ext: value = None else: # external ext starts with a . ext = ext.lstrip(".") value = ext vars = {'EXT': value, 'BASEFILE': base} env_sobjects = {'snapshot': snapshot } for key in keys: if naming: break naming_list = naming_dict.get(key) if naming_list: # now that we have the namings, evaluate the expression default_naming = None for tmp_naming in naming_list: expr = tmp_naming.get_value("condition", no_exception=True) # if there is no expression, then this is the default # for this match if not expr: default_naming = tmp_naming elif xp.eval(expr, sobject, env_sobjects=env_sobjects, vars=vars): naming = tmp_naming break else: # this extra check of not naming is for precaution if not naming and default_naming: naming = default_naming break return naming