def get_input_snapshots(my, sobject, process_name, input_name, version='latest'): '''gets the snapshots of the input''' assert version in ['latest', 'current'] process_node = my.xml.get_node( "pipeline/process[@name='%s']/input[@name='%s']" % (process_name, input_name)) search_type = Xml.get_attribute(process_node, "search_type") context = Xml.get_attribute(process_node, "context") filter = Xml.get_attribute(process_node, "filter") # get the sobjects sobjects = sobject.get_all_children(search_type) # get the snapshots search = Search("sthpw/snapshot") search.add_filter('context', context) #if version == 'latest': # search.add_filter("is_latest", 1) #elif version == 'current': # search.add_filter("is_current", 1) # build filters for search_type, search_id combinations filters = [] for sobject in sobjects: filter = "(\"search_type\" = '%s' and \"search_id\" = %s)" % (sobject.get_search_type(), sobject.get_id() ) filters.append(filter) search.add_where( "( %s )" % " or ".join(filters) ) snapshots = search.get_sobjects() return snapshots
def get_file_paths(my, transaction, mode='lib'): transaction_xml = transaction.get_xml_value("transaction") if not transaction_xml: return [] from pyasm.common import Xml, Environment if isinstance(transaction_xml, basestring): xml = Xml() xml.read_string(transaction_xml) else: xml = transaction_xml base_dir = Environment.get_asset_dir() paths = [] # get all of the file nodes nodes = xml.get_nodes("transaction/file") for node in nodes: if xml.get_attribute(node, "type") == 'create': src = xml.get_attribute(node, "src") if mode == 'relative': path = src else: path = "%s/%s" % (base_dir, src) paths.append(path) return paths
def get_child_types(self, search_type, relationship="hierarchy", hierarchy=True): if search_type.find("?") != -1: search_type, tmp = search_type.split("?", 1) child_types = [] # first get the child types defined in the admin schema if hierarchy and self.sthpw_schema: sthpw_child_types = self.sthpw_schema.get_child_types(search_type, relationship) child_types.extend(sthpw_child_types) # get the child types in the project type schema if hierarchy and self.parent_schema: parent_child_types = self.parent_schema.get_child_types(search_type, relationship) child_types.extend(parent_child_types) # add new style connects = self.xml.get_nodes("schema/connect[@to='%s'] | schema/connect[@to='*']" % search_type) for connect in connects: relationship = Xml.get_attribute(connect, "relationship") # skip old style if not relationship: continue child_type = Xml.get_attribute(connect, "from") # skip identical type if child_type == search_type: continue child_types.append(child_type) return child_types
def get_related_search_types(self, search_type, direction=None): related_types = [] if not direction or direction == "parent": xpath = "schema/connect[@from='%s']" %(search_type) connects = self.xml.get_nodes(xpath) for connect in connects: related_type = Xml.get_attribute(connect,"to") related_types.append(related_type) if not direction or direction == "children": xpath = "schema/connect[@to='%s']" %(search_type) connects = self.xml.get_nodes(xpath) for connect in connects: related_type = Xml.get_attribute(connect,"from") related_types.append(related_type) if self.parent_schema: search_types = self.parent_schema.get_related_search_types(search_type, direction=direction) related_types.extend(search_types) if self.sthpw_schema: search_types = self.sthpw_schema.get_related_search_types(search_type, direction=direction) related_types.extend(search_types) return related_types
def verify_dir(my, base): # ignore transactions that a derived from this server server_code = Config.get_value("install", "server") if base.startswith("%sTRANSACTION" % server_code): return False if base.find("TRANSACTION") == -1: return False if not os.path.isdir(base): if base.endswith(".zip.enc"): return True elif base.endswith(".zip"): return True else: return False asset_dir = Environment.get_asset_dir() transaction_path = "%s/_transaction.xml" % base if not os.path.exists(transaction_path): return False xml = Xml() xml.read_file(transaction_path) nodes = xml.get_nodes("transaction/file") # verify that all the files are present for node in nodes: code = xml.get_attribute(node, "code") file_sobj = Search.get_by_code("sthpw/file", code) src = xml.get_attribute(node, "src") rel_path = xml.get_attribute(node, "rel_path") src_path = "%s/%s" % (base, rel_path) if not os.path.exists(src_path): print "[%s] has not arrived" % src_path return False st_size = xml.get_attribute(node, "size") if st_size: st_size = int(st_size) else: st_size = -1 md5 = xml.get_attribute(node, "md5") if st_size != -1: # check that the size is the same if st_size != os.path.getsize(src_path): print "[%s] size does not match" % src_path return False # all the tests have passed return True
def get_file_info(xml, file_objects, sobject, snapshot, show_versionless=False, is_list=False): info = {} #TODO: {'file_type': [file_type]: [path], 'base_type': [base_type]: [file|directory|sequence]} if is_list: info = [] else: repo_info = {} info['_repo'] = repo_info nodes = xml.get_nodes("snapshot/file") for node in nodes: type = Xml.get_attribute(node, "type") file_code = Xml.get_attribute(node, "file_code") file_object = file_objects.get(file_code) if not file_object: if isinstance(info, dict): info[type] = ThumbWdg.get_no_image() else: info.append((type, ThumbWdg.get_no_image())) Environment.add_warning( "No file object", "No file object found for file code '%s'" % file_code) continue file_name = file_object.get_full_file_name() web_dir = sobject.get_web_dir(snapshot, file_object=file_object) # handle a range if it exists file_range = file_object.get_value("file_range") if file_range: from pyasm.biz import FileGroup, FileRange file_range = FileRange.get(file_range) file_names = FileGroup.expand_paths(file_name, file_range) # just check the first frame if file_names: file_name = file_names[0] path = "%s/%s" % (web_dir, file_name) if isinstance(info, dict): info[type] = path lib_dir = sobject.get_lib_dir(snapshot, file_object=file_object) repo_info[type] = "%s/%s" % (lib_dir, file_name) else: info.append((type, path)) return info
def get_parent_type(my, search_type, relationship=None): # NOTE: relationship arg is deprecated!! if search_type.find("?") != -1: search_type, tmp = search_type.split("?", 1) # make a provision for admin search_types passed in if my.get_code() != "admin" and search_type.startswith("sthpw/"): parent_type = Schema.get_admin_schema().get_parent_type(search_type, relationship) if parent_type: return parent_type parent_type = "" # look at new style connections first connects = my.xml.get_nodes("schema/connect[@from='%s']" % search_type ) for connect in connects: relationship_new = Xml.get_attribute(connect, "relationship") if relationship_new: type = Xml.get_attribute(connect, "type") if type == 'hierarchy': parent_type = Xml.get_attribute(connect, "to") break # NOTE: there could be multiple parents here. Hierarchy type # should be the one to resolve this. # if there is no "hierarchy" type, use the first one if not parent_type: for connect in connects: from_type = Xml.get_attribute(connect, "from") if from_type == search_type: parent_type = Xml.get_attribute(connect, "to") break """ # DEPRECATED: resort to old style if not parent_type: connects = my.xml.get_nodes("schema/connect[@to='%s']" % search_type ) # FIXME: you need to assign parent_type here for connect in connects: type = Xml.get_attribute(connect, "type") if type != relationship: continue parent_type = Xml.get_attribute(connect, "from") # FIXME: should we call break? """ if not parent_type and my.parent_schema: parent_type = my.parent_schema.get_parent_type(search_type, relationship) return parent_type
def get_task_pipeline(my, default=True): ''' assuming the child pipeline is task related ''' task_pipeline_code = Xml.get_attribute(my.node, "task_pipeline") node_type = Xml.get_attribute(my.node, "type") if node_type == "approval": return "approval" if not task_pipeline_code and default: return "task" else: return task_pipeline_code
def get_task_pipeline(my, default=True): ''' assuming the child pipeline is task related ''' task_pipeline_code = Xml.get_attribute( my.node, "task_pipeline" ) node_type = Xml.get_attribute(my.node, "type") if node_type == "approval": return "approval" if not task_pipeline_code and default: return "task" else: return task_pipeline_code
def get_sobjects_by_node(my, node): # get the sobjects search_type = my.xml.get_attribute(node, "search_type") expr = my.xml.get_attribute(node, "expression") code = my.xml.get_attribute(node, "code") if expr: sobjects = Search.eval(expr) elif search_type: search = Search(search_type) search.set_show_retired(True) if code: search.add_filter("code", code) # have some specific attributes for specific search types # can use wildcards like % and * if search_type == 'config/widget_config': view = Xml.get_attribute(node, "view") if view: ignore_columns = 'id,code' Xml.set_attribute(node, "ignore_columns", ignore_columns) if view.find("%") != -1 or view.find("*") != -1: view = view.replace("*", "%") view = view.replace("/", ".") search.add_filter("view", view, op="like") else: search.add_filter("view", view) elif search_type == 'config/url': url = Xml.get_attribute(node, "url") if url: ignore_columns = 'id,code' Xml.set_attribute(node, "ignore_columns", ignore_columns) if url.find("%") != -1: search.add_filter("url", url, op="like") else: search.add_filter("url", url) search.add_order_by("id") sobjects = search.get_sobjects() else: sobjects = [] return sobjects
def get_action_node(my, event_name, scope="dependent"): nodes = Xml.get_children(my.node) for node in nodes: node_name = Xml.get_node_name(node) if node_name == "action": node_event = Xml.get_attribute(node, "event") if node_event != event_name: continue node_scope = Xml.get_attribute(node, "scope") if scope and node_scope != scope: continue return node
def get_file_info(xml, file_objects, sobject, snapshot, show_versionless=False, is_list=False, protocol='http'): info = {} #TODO: {'file_type': [file_type]: [path], 'base_type': [base_type]: [file|directory|sequence]} if is_list: info = [] else: repo_info = {} info['_repo'] = repo_info nodes = xml.get_nodes("snapshot/file") for node in nodes: type = Xml.get_attribute(node, "type") file_code = Xml.get_attribute(node, "file_code") file_object = file_objects.get(file_code) if not file_object: if isinstance(info, dict): info[type] = ThumbWdg.get_no_image() else: info.append((type, ThumbWdg.get_no_image())) Environment.add_warning("No file object", "No file object found for file code '%s'" % file_code) continue file_name = file_object.get_full_file_name() web_dir = sobject.get_web_dir(snapshot, file_object=file_object) # handle a range if it exists file_range = file_object.get_value("file_range") if file_range: from pyasm.biz import FileGroup, FileRange file_range = FileRange.get(file_range) file_names = FileGroup.expand_paths(file_name, file_range) # just check the first frame if file_names: file_name = file_names[0] path = "%s/%s" % (web_dir, file_name) if protocol != "file": path = urllib.pathname2url(path) if isinstance(info, dict): info[type] = path lib_dir = sobject.get_lib_dir(snapshot, file_object=file_object) repo_info[type] = "%s/%s" % (lib_dir, file_name) else: info.append((type, path)) return info
def get_task_pipeline(self, default=True): ''' assuming the child pipeline is task related ''' task_pipeline_code = Xml.get_attribute(self.node, "task_pipeline") node_type = Xml.get_attribute(self.node, "type") if node_type == "approval": return "approval" elif node_type == "dependency": return "dependency" elif node_type == "progress": return "progress" if not task_pipeline_code and default: return "task" else: return task_pipeline_code
def get_type(self): node_type = Xml.get_attribute(self.node, "type") if node_type == "auto": node_type = "action" if not node_type: node_type = "manual" return node_type
def get_color(my): color = Xml.get_attribute( my.node, "color" ) from pyasm.web import Palette theme = Palette.get().get_theme() if theme == 'dark': color = Common.modify_color(color, -50) return color
def get_type(my): node_type = Xml.get_attribute(my.node, "type") if node_type == "auto": node_type = "action" if not node_type: node_type = "node" return node_type
def add_attr_access(my, search_type, attr, level): # find the group group_xpath = "rules/group[@key='%s']" % (search_type) group = my.xml.get_node(group_xpath) if group == None: # add the group (default to view) group_level = "view" group = my.add_sobject_access(search_type, group_level) # get the attr rule rule_xpath = "rules/group[@key='%s']/rule[@key='%s']" % (search_type, attr) rule = my.xml.get_node(rule_xpath) if rule != None: # if nothing has changed, continue access = Xml.get_attribute(rule, "access") if level == access: raise CommandExitException() else: rule = my.xml.create_element("rule") rule.setAttributeNS(None, "key", attr) #group.appendChild(rule) Xml.append_child(group, rule) #my.root.appendChild(group) Xml.append_child(my.root, group) # set the access level rule.setAttributeNS(None, "type", "attr") rule.setAttributeNS(None, "access", level)
def get_type(my): node_type = Xml.get_attribute( my.node, "type" ) if node_type == "auto": node_type = "action" if not node_type: node_type = "manual" return node_type
def add_attr_access(self, search_type, attr, level): # find the group group_xpath = "rules/group[@key='%s']" % (search_type) group = self.xml.get_node(group_xpath) if group == None: # add the group (default to view) group_level = "view" group = self.add_sobject_access(search_type,group_level) # get the attr rule rule_xpath = "rules/group[@key='%s']/rule[@key='%s']" % (search_type,attr) rule = self.xml.get_node(rule_xpath ) if rule != None: # if nothing has changed, continue access = Xml.get_attribute(rule,"access") if level == access: raise CommandExitException() else: rule = self.xml.create_element("rule") rule.setAttributeNS(None,"key",attr) #group.appendChild(rule) Xml.append_child(group, rule) #self.root.appendChild(group) Xml.append_child(self.root, group) # set the access level rule.setAttributeNS(None,"type","attr") rule.setAttributeNS(None,"access",level)
def get_instance_type(self, search_type, related_search_type): connect = self.xml.get_node("schema/connect[@to='%s' and @from='%s']" % \ (search_type, related_search_type) ) if connect == None: return "" # ensure that the connection is "many_to_many" type = Xml.get_attribute(connect, "type") if type != "many_to_many": return "" instance_type = Xml.get_attribute(connect, "instance_type") if not instance_type: raise Exception("No instance_type defined for [%s] to [%s]" % \ (search_type, related_search_type) ) return instance_type
def get_context(my, from_xml=False): # if the context is not specified, use the "from" process context = Xml.get_attribute(my.node, "context") if from_xml: return context if not context: process = Xml.get_attribute(my.node, "from") # if the from process contains a /, then use the main context if process.find("/") != -1: parts = process.split("/") process = parts[1] context = process return context
def handle_sobject(my, node): search_type = my.xml.get_attribute(node, "search_type") include_id = my.xml.get_attribute(node, "include_id") if include_id in [True, 'true']: include_id = True else: include_id = False ignore_columns = Xml.get_attribute(node, "ignore_columns") if ignore_columns: ignore_columns = ignore_columns.split(",") ignore_columns = [x.strip() for x in ignore_columns] else: ignore_columns = [] # FIXME: # it is possible that the manifest defines sobjects on search types # that don't exist. This is because it uses the manifest of # the new pipeline and not the original ... sobjects = my.get_sobjects_by_node(node) if not sobjects: print "Skipping as no sobjects found for [%s]" %search_type return [] # If there are no sobjects, then no file is created because # no path can be extracted. path = my.get_path_from_node(node) print "Writing: ", path fmode = 'w' if os.path.exists(path): fmode = 'a' if not sobjects: # write out an empty file #f = open(path, 'w') f = codecs.open(path, fmode, 'utf-8') f.close() return [] dumper = TableDataDumper() dumper.set_delimiter("#-- Start Entry --#", "#-- End Entry --#") if search_type == 'config/widget_config': dumper.set_ignore_columns(['code']) dumper.set_include_id(include_id) dumper.set_ignore_columns(ignore_columns) dumper.set_sobjects(sobjects) dumper.dump_tactic_inserts(path, mode='sobject') print "\t....dumped [%s] entries" % (len(sobjects)) return sobjects
def set_pipeline(self, pipeline_xml, cache=True): '''set the pipeline externally''' # cache according to pipeline code, which will share the same xml object if self.is_insert(): cache = False search_key = self.get_search_key() xml_dict = Container.get("Pipeline:xml") if xml_dict == None: xml_dict = {} Container.put("Pipeline:xml", xml_dict) self.xml = xml_dict.get(search_key) if self.xml == None: self.xml = Xml() if cache: xml_dict[search_key] = self.xml if not pipeline_xml: pipeline_xml = "<pipeline/>" try: self.xml.read_string(pipeline_xml) except XmlException as e: self.xml.read_string("<pipeline/>") # clear these again when set externally self.processes = [] self.recursive_processes = [] # create the process and pipelines process_nodes = self.xml.get_nodes( "pipeline/process | pipeline/pipeline") for node in process_nodes: node_name = self.xml.get_node_name(node) process = Process(node) process.set_parent_pipeline_code(self.get_code()) self.processes.append(process) if node_name == "pipeline": name = Xml.get_attribute(node, "name") # prevent infinite loop if name == self.get_code(): continue child = Pipeline.get_by_code(name) if not child: continue self.pipeline_dict[name] = child process.set_child_pipeline(child)
def get_action_nodes(my, scope="dependent"): action_nodes = [] nodes = Xml.get_children(my.node) for node in nodes: node_name = Xml.get_node_name(node) if node_name == "action": node_scope = Xml.get_attribute(node, "scope") if scope and node_scope != scope: continue action_nodes.append(node) return action_nodes
def _get_file_obj(my, snapshot, type='main'): if type: xpath = "snapshot/file[@type='%s']" %type else: xpath = "snapshot/file[@type]" xml = snapshot.get_xml_value('snapshot') node = xml.get_node(xpath) file = None if node is not None: file_code = Xml.get_attribute(node, "file_code") file = File.get_by_code(file_code) return file
def _get_file_obj(my, snapshot, type='main'): if type: xpath = "snapshot/file[@type='%s']" % type else: xpath = "snapshot/file[@type]" xml = snapshot.get_xml_value('snapshot') node = xml.get_node(xpath) file = None if node is not None: file_code = Xml.get_attribute(node, "file_code") file = File.get_by_code(file_code) return file
def _handle_ref_node(self, node, widget, upstream=False, recursive=True): # get the reference snapshot (should maybe use the loader or # at least share the code instance = Xml.get_attribute(node,"instance") search_type = Xml.get_attribute(node,"search_type") search_id = Xml.get_attribute(node,"search_id") context = Xml.get_attribute(node,"context") version = Xml.get_attribute(node,"version") # this is often the Maya file node name or XSI long clip name node_name = Xml.get_attribute(node, "node") my_name = Xml.get_node_name(node) # get the snapshot ref_snapshot = Snapshot.get_by_version(search_type, search_id,\ context, version) #ref_snapshot = Snapshot.get_latest(search_type,search_id, context) if ref_snapshot == None: widget.add("|---> <font color='red'>Error: No reference found for [%s, %s, %s]</font>" % \ (search_type, search_id, context) ) return toggle_id = self.generate_unique_id('toggle') widget.add(FloatDivWdg(), toggle_id) version = ref_snapshot.get_value("version") try: sobject = ref_snapshot.get_sobject() except SObjectNotFoundException, e: widget.add('[%s|%s] may have been deleted or is not viewable.' % (ref_snapshot.get_value('search_type'),\ ref_snapshot.get_value('search_id'))) return
def execute(self): mode = self.kwargs.get('mode') if not mode: mode = 'lib' transaction_xml = self.kwargs.get("transaction_xml") assert(transaction_xml) from pyasm.common import Xml, Environment if isinstance(transaction_xml, basestring): xml = Xml() xml.read_string(transaction_xml) else: xml = transaction_xml base_dir = Environment.get_asset_dir() paths = [] # get all of the file nodes nodes = xml.get_nodes("transaction/file") for node in nodes: if xml.get_attribute(node, "type") == 'create': src = xml.get_attribute(node, "src") if mode == 'relative': path = src else: if src.startswith(base_dir): path = src else: path = "%s/%s" % (base_dir, src) paths.append(path) return paths
def get_parent_type(self, search_type, relationship=None): # NOTE: relationship arg is deprecated!! if search_type.find("?") != -1: search_type, tmp = search_type.split("?", 1) # make a provision for admin search_types passed in if self.get_code() != "admin" and search_type.startswith("sthpw/"): parent_type = Schema.get_admin_schema().get_parent_type(search_type, relationship) if parent_type: return parent_type parent_type = "" # look at new style connections first connects = self.xml.get_nodes("schema/connect[@from='%s']" % search_type ) for connect in connects: relationship_new = Xml.get_attribute(connect, "relationship") if relationship_new == "instance": continue if relationship_new: type = Xml.get_attribute(connect, "type") if type == 'hierarchy': parent_type = Xml.get_attribute(connect, "to") break # NOTE: there could be multiple parents here. Hierarchy type # should be the one to resolve this. # if there is no "hierarchy" type, use the first one if not parent_type: for connect in connects: relationship_new = Xml.get_attribute(connect, "relationship") if relationship_new == "instance": continue from_type = Xml.get_attribute(connect, "from") if from_type == search_type: parent_type = Xml.get_attribute(connect, "to") break """ # DEPRECATED: resort to old style if not parent_type: connects = self.xml.get_nodes("schema/connect[@to='%s']" % search_type ) # FIXME: you need to assign parent_type here for connect in connects: type = Xml.get_attribute(connect, "type") if type != relationship: continue parent_type = Xml.get_attribute(connect, "from") # FIXME: should we call break? """ if not parent_type and self.parent_schema: parent_type = self.parent_schema.get_parent_type(search_type, relationship) return parent_type
class Package(Command): def __init__(self, search_key, context, package): self.search_key = search_key self.context = context self.package = package self.package_xml = Xml() self.package_xml.read_string(package) super(Package, self).__init__() def execute(self): from tactic_client_lib import TacticServerStub server = TacticServerStub.get(protocol='local') # create a new snapshot snapshot = server.create_snapshot(self.search_key, self.context) # get all of the file_types file_nodes = self.package_xml.get_nodes("package/file_type") count = 0 for file_node in file_nodes: name = self.package_xml.get_attribute(file_node, "name") values = self.package_xml.get_node_values_of_children(file_node) expression = values.get("expression") dir_naming = values.get("dir_naming") file_naming = values.get("file_naming") files = Search.eval(expression) for file in files: file_type = "%s%s" % (name, count) try: # FIXME: the assumed action is to checkin server.add_file(snapshot, file, file_type=file_type, mode='copy', dir_naming=dir_naming, file_naming=file_naming) # What if we just wished to copy? Can we run the files # through a naming convention filter? count += 1 except Exception as e: print "WARNING: ", str(e)
def get_default_task_xml(): global TASK_PIPELINE from pyasm.web import Palette palette = Palette.get() xml = Xml() xml.read_string(TASK_PIPELINE) nodes = Xml.get_nodes(xml, "pipeline/process") for node in nodes: process = Xml.get_attribute(node, "name") color = Task.get_default_color(process) Xml.set_attribute(node, "color", color) return xml.to_string()
def get_source_link(self, node): search_type = Xml.get_attribute(node, "search_type") search_id = Xml.get_attribute(node, "search_id") context = Xml.get_attribute(node, "context") version = Xml.get_attribute(node, "version") source_snapshot = Snapshot.get_by_version(search_type, search_id, \ context, version ) if not source_snapshot: Environment.add_warning("Snapshot not found", "Reference snapshot for [%s|%s] does not exist" \ % (search_type, search_id) ) return '' #raise WidgetException( "Reference snapshot in '%s' does not exist" \ # % snapshot.get_id() ) source = source_snapshot.get_sobject() # get the file link file_name = source_snapshot.get_name_by_type("main") path = "%s/%s" % (source_snapshot.get_web_dir(), file_name) return HtmlElement.href("Source: %s" %source.get_value("code"), \ ref=path )
def get_source_link(my, node): search_type = Xml.get_attribute(node, "search_type") search_id = Xml.get_attribute(node, "search_id") context = Xml.get_attribute(node, "context") version = Xml.get_attribute(node, "version") source_snapshot = Snapshot.get_by_version(search_type, search_id, \ context, version ) if not source_snapshot: Environment.add_warning("Snapshot not found", "Reference snapshot for [%s|%s] does not exist" \ % (search_type, search_id) ) return '' #raise WidgetException( "Reference snapshot in '%s' does not exist" \ # % snapshot.get_id() ) source = source_snapshot.get_sobject() # get the file link file_name = source_snapshot.get_name_by_type("main") path = "%s/%s" % (source_snapshot.get_web_dir(), file_name) return HtmlElement.href("Source: %s" %source.get_value("code"), \ ref=path )
def handle_search_type(my, node): search_type = my.xml.get_attribute(node, "code") if not search_type: raise TacticException("No code found for search type in manifest") path = my.xml.get_attribute(node, "path") if not path: path = "%s.spt" % search_type.replace("/", "_") path = "%s/%s" % (my.plugin_dir, path) if os.path.exists(path): os.unlink(path) # dump out search type registration search = Search("sthpw/search_object") search.add_filter("search_type", search_type) sobject = search.get_sobject() if not sobject: raise TacticException("Search type [%s] does not exist" % search_type) dumper = TableDataDumper() dumper.set_delimiter("#-- Start Entry --#", "#-- End Entry --#") dumper.set_include_id(False) dumper.set_sobjects([sobject]) dumper.dump_tactic_inserts(path, mode='sobject') ignore_columns = Xml.get_attribute(node, "ignore_columns") if ignore_columns: ignore_columns = ignore_columns.split(",") ignore_columns = [x.strip() for x in ignore_columns] else: ignore_columns = [] # dump out the table definition dumper = TableSchemaDumper(search_type) dumper.set_delimiter("#-- Start Entry --#", "#-- End Entry --#") dumper.set_ignore_columns(ignore_columns) dumper.dump_to_tactic(path, mode='sobject')
def _get_connects(my, process="", direction="from"): if direction == "from": opposite = "to" else: opposite = "from" if not process: connect_nodes = my.xml.get_nodes("pipeline/connect") else: connect_nodes = my.xml.get_nodes("pipeline/connect[@%s='%s' or @%s='*']" % (direction, process, direction)) connects = [] for node in connect_nodes: opposite_name = Xml.get_attribute(node, opposite) full_name = "%s/%s" % (my.get_name(), opposite_name) if process == opposite_name or process == full_name: continue connects.append(ProcessConnect(node)) return connects
def _get_connects(my, process="", direction='from'): if direction == "from": opposite = "to" else: opposite = "from" if not process: connect_nodes = my.xml.get_nodes("pipeline/connect") else: connect_nodes = my.xml.get_nodes(\ "pipeline/connect[@%s='%s' or @%s='*']" % (direction, process, direction)) connects = [] for node in connect_nodes: opposite_name = Xml.get_attribute(node, opposite) full_name = "%s/%s" % (my.get_name(), opposite_name) if process == opposite_name or process == full_name: continue connects.append(ProcessConnect(node)) return connects
def _add_access(self, type, key, level): # find if a rule for this already exists rule = self.xml.get_node("rules/group[@key='%s']" % key) if rule != None: # if nothing has changed, continue access = Xml.get_attribute(rule,"access") if level == access: raise CommandExitException() else: rule = self.xml.create_element("group") rule.setAttributeNS(None,"key",key) # set the access level rule.setAttributeNS(None,"type",type) rule.setAttributeNS(None,"access",level) #self.root.appendChild(rule) Xml.append_child(self.root, rule) return rule
def _add_access(my, type, key, level): # find if a rule for this already exists rule = my.xml.get_node("rules/group[@key='%s']" % key) if rule != None: # if nothing has changed, continue access = Xml.get_attribute(rule, "access") if level == access: raise CommandExitException() else: rule = my.xml.create_element("group") rule.setAttributeNS(None, "key", key) # set the access level rule.setAttributeNS(None, "type", type) rule.setAttributeNS(None, "access", level) #my.root.appendChild(rule) Xml.append_child(my.root, rule) return rule
def get_name(my): return Xml.get_attribute( my.node, "name" )
def execute(my): web = WebContainer.get_web() alter_mode = my.kwargs.get("alter_mode") title = my.kwargs.get("title") config_mode = web.get_form_value("config_mode") view = web.get_form_value('view') constraint = web.get_form_value("config_constraint") data_type = '' if config_mode == "advanced": config_string = web.get_form_value("config_xml") if config_string: xml = Xml() xml.read_string(config_string) node = xml.get_root_node() data_type = xml.get_attribute(node, "data_type") nullable = xml.get_attribute(node, "nullable") in ['true', 'True'] else: data_type = web.get_form_value("config_data_type") if data_type == 'Other...': data_type = web.get_form_value("config_data_type_custom") cb = CheckboxWdg("config_nullable") nullable = cb.is_checked() # if advanced is selected in the Widget Column view, data_type is '' # read from UI if not data_type and view == 'definition': data_type = web.get_form_value("config_data_type") if data_type == 'Other...': data_type = web.get_form_value("config_data_type_custom") cb = CheckboxWdg("config_nullable") nullable = cb.is_checked() column_name = web.get_form_value("column_name") search_type = web.get_form_value("target_search_type") if alter_mode == ManageSearchTypeDetailWdg.REMOVE_COLUMN: cmd = ColumnDropCmd(search_type, column_name) Command.execute_cmd(cmd) # delete widget config from definition view widget_config = WidgetDbConfig.get_by_search_type( search_type, 'definition') if widget_config: config = WidgetConfig.get( 'definition', xml=widget_config.get_xml_value('config')) config.remove_xml_element(column_name) new_xml = config.get_xml().to_string() widget_config.set_value("config", new_xml) widget_config.commit() # set cache to {} from pyasm.common import Container Container.put("WidgetConfigView:config_cache", {}) #Container.put("WidgetConfig:config_cache", {}) elif alter_mode == ManageSearchTypeDetailWdg.MODIFY_COLUMN: cmd = ColumnAlterCmd(search_type, column_name, data_type, nullable) Command.execute_cmd(cmd) element_options = {} element_options['type'] = data_type if title: element_options['title'] = title # handle the "default" view # update the widget config data type in the xml view = my.DEFAULT_VIEW config = WidgetDbConfig.get_by_search_type(search_type, view) if config: config.append_display_element(column_name, options={}, \ element_attrs=element_options) config.commit_config() elif alter_mode == ManageSearchTypeDetailWdg.ADD_COLUMN: cmd = ColumnAddCmd(search_type, column_name, data_type, nullable) Command.execute_cmd(cmd) if constraint: # add constraint from pyasm.command import ColumnAddIndexWdg cmd = ColumnAddIndexWdg() cmd.execute() else: # remove constraint pass
def get_add_textures_wdg(self): sobject = self.get_current_sobject() widget = Widget() search_type = sobject.get_search_type() search_id = sobject.get_id() url = WebContainer.get_web().get_widget_url() url.set_option("widget", "pyasm.prod.web.TextureAddTexturesWdg") url.set_option("search_type", search_type) url.set_option("search_id", search_id) url.set_option("refresh_mode", "page") ref = url.get_url() iframe = Container.get("iframe") iframe.set_width(80) action = iframe.get_on_script(ref) div = DivWdg() div.add_style("float: left") button = IconButtonWdg("Add Texture", IconWdg.IMAGE_ADD) button.add_event("onclick", action) button.add_style("margin: 3px 5px") div.add(button) div.add("Add Textures") widget.add(div) # find all of the forward references snapshot = Snapshot.get_latest_by_sobject(sobject) if snapshot: div = DivWdg() xml = snapshot.get_xml_value("snapshot") frefs = xml.get_nodes("snapshot/fref") if frefs: widget.add("<br clear='all'/><hr size='1px'/>") for fref in frefs: search_id = Xml.get_attribute(fref, "search_id") search_type = Xml.get_attribute(fref, "search_type") sobject = Search.get_by_id(search_type, search_id) if not sobject: sobject_code = "n/a" else: sobject_code = sobject.get_code() thumb = ThumbWdg() thumb.set_icon_size(30) thumb.set_show_latest_icon(True) thumb.set_sobject(sobject) div.add(thumb) div.add(sobject_code) div.add("<br/>") widget.add(div) return widget
class PluginBase(Command): def __init__(my, **kwargs): super(PluginBase,my).__init__(**kwargs) # plugin sobject (Not really used anymore?) my.search_key = my.kwargs.get("search_key") zip_path = my.kwargs.get("zip_path") upload_file_name = my.kwargs.get("upload_file_name") my.base_dir = my.kwargs.get("base_dir") my.plugin_dir = my.kwargs.get("plugin_dir") my.manifest = my.kwargs.get("manifest") my.code = my.kwargs.get("code") my.version = my.kwargs.get("version") relative_dir = my.kwargs.get("relative_dir") my.verbose = my.kwargs.get("verbose") not in [False, 'false'] # at the end of this, the following variables are needed in order to # define the plugin # # version: the version of the plugin # plugin_dir: the directory where the plugin definition is located # manifest: the description of what is in the plugin if zip_path: # assume the zip path is the same as the basename basename = os.path.basename(zip_path) basename, ext = os.path.splitext(basename) assert ext == '.zip' tmp_dir = Environment.get_tmp_dir() unzip_dir = "%s/%s" % (tmp_dir, basename) if os.path.exists(unzip_dir): shutil.rmtree(unzip_dir) # unzip the file in to the tmp_dir or plugin_dir (for install) zip_util = ZipUtil() zip_util.extract(zip_path, base_dir=tmp_dir) # assume zip path my.plugin_dir, ext = os.path.splitext(zip_path) # mv from temp if my.plugin_dir != unzip_dir: if os.path.exists(my.plugin_dir): shutil.rmtree(my.plugin_dir) shutil.move(unzip_dir, my.plugin_dir) manifest_path = "%s/manifest.xml" % my.plugin_dir f = open(manifest_path, 'r') my.manifest = f.read() f.close() elif upload_file_name: # The path is moved to the plugin dir, if this process is taking # "local" file (such as one uploaded) upload_dir = Environment.get_upload_dir() upload_path = "%s/%s" % (upload_dir, upload_file_name) plugin_base_dir = Environment.get_plugin_dir() dist_dir = Environment.get_dist_dir() if not os.path.exists(dist_dir): os.makedirs(dist_dir) basename = os.path.basename(upload_path) #if os.path.exists("%s/%s" % (plugin_base_dir, basename)): # os.unlink("%s/%s" % (plugin_base_dir, basename) ) #shutil.move(upload_path, plugin_base_dir) # copy to dist folder if os.path.exists("%s/%s" % (dist_dir, basename)): os.unlink("%s/%s" % (dist_dir, basename) ) shutil.move(upload_path, dist_dir) zip_path = "%s/%s" % (dist_dir, upload_file_name) zip_util = ZipUtil() zip_util.extract(zip_path, base_dir=plugin_base_dir) my.plugin_dir = "%s/%s" % (plugin_base_dir, basename) my.plugin_dir = my.plugin_dir[:-4] manifest_path = "%s/manifest.xml" % (my.plugin_dir) if os.path.exists(manifest_path): f = open(manifest_path, 'r') my.manifest = f.read() f.close() else: # when uploading, this will likely not be needed my.manifest = "<manifest/>" return elif relative_dir: plugin_base_dir = Environment.get_plugin_dir() my.plugin_dir = "%s/%s" % (plugin_base_dir, relative_dir) manifest_path = "%s/manifest.xml" % my.plugin_dir if not os.path.exists(manifest_path): plugin_base_dir = Environment.get_builtin_plugin_dir() my.plugin_dir = "%s/%s" % (plugin_base_dir, relative_dir) manifest_path = "%s/manifest.xml" % my.plugin_dir f = open(manifest_path, 'r') my.manifest = f.read() f.close() elif my.plugin_dir: manifest_path = "%s/manifest.xml" % (my.plugin_dir) f = open(manifest_path, 'r') my.manifest = f.read() f.close() # get the plugin sobject elif my.search_key: plugin = SearchKey.get_by_search_key(my.search_key) my.manifest = plugin.get_value("manifest") my.code = plugin.get_code() my.version = plugin.get_value("version") elif my.manifest: # everything is extracted from the manifest later pass elif my.code: search = Search("config/plugin") search.add_filter("code", my.code) plugin = search.get_sobject() # In case there is extra plugins folder which is the case when the user # is developing. relative_dir = plugin.get_value("rel_dir") plugin_base_dir = Environment.get_plugin_dir() my.plugin_dir = "%s/%s" % (plugin_base_dir, relative_dir) # TODO: fix the ZipUtil.zip_dir() manifest_path = "%s/manifest.xml" % my.plugin_dir if not os.path.exists(manifest_path): plugin_base_dir = Environment.get_builtin_plugin_dir() my.plugin_dir = "%s/%s" % (plugin_base_dir, relative_dir) manifest_path = "%s/manifest.xml" % my.plugin_dir if os.path.exists(manifest_path): f = open(manifest_path, 'r') my.manifest = f.read() f.close() else: # this condition happens likely for a versioned installed plugin from a zip file # where it starts with an extra folder "plugins" and the rel_dir has not been recorded properly my.manifest = plugin.get_value("manifest") my.code = plugin.get_code() my.version = plugin.get_value("version") else: raise Exception("No plugin found") # assertions assert my.manifest # read the xml my.xml = Xml() my.xml.read_string(my.manifest) # if code is passed in, then use that. if not my.code: my.code = my.xml.get_value("manifest/data/code") # old implementation if not my.code: my.code = my.xml.get_value("manifest/@code") if not my.version: my.version = my.xml.get_value("manifest/data/version") assert my.code if not my.base_dir: if my.code.startswith("TACTIC"): my.base_dir = Environment.get_builtin_plugin_dir() else: my.base_dir = Environment.get_plugin_dir() # set the base directory for this particular plugin if not my.plugin_dir: if my.version: my.plugin_dir = "%s/%s-%s" % (my.base_dir, my.code, my.version) else: my.plugin_dir = "%s/%s" % (my.base_dir, my.code) def get_sobjects_by_node(my, node): # get the sobjects search_type = my.xml.get_attribute(node, "search_type") expr = my.xml.get_attribute(node, "expression") code = my.xml.get_attribute(node, "code") try: search_type = SearchType.get(search_type) except SearchException, e: return [] if expr: sobjects = Search.eval(expr) elif search_type: search = Search(search_type) search.set_show_retired(True) if code: search.add_filter("code", code) # have some specific attributes for specific search types # can use wildcards like % and * if search_type == 'config/widget_config': view = Xml.get_attribute(node, "view") if view: ignore_columns = 'id,code' Xml.set_attribute(node, "ignore_columns", ignore_columns) if view.find("%") != -1 or view.find("*") != -1: view = view.replace("*", "%") view = view.replace("/", ".") search.add_filter("view", view, op="like") else: search.add_filter("view", view) elif search_type == 'config/url': url = Xml.get_attribute(node, "url") if url: ignore_columns = 'id,code' Xml.set_attribute(node, "ignore_columns", ignore_columns) if url.find("%") != -1: search.add_filter("url", url, op="like") else: search.add_filter("url", url) search.add_order_by("id") sobjects = search.get_sobjects() else: sobjects = [] return sobjects
def add_behaviors(my, widget, xml): behavior_nodes = xml.get_nodes("config/%s/behavior" % my.view) if behavior_nodes: hidden_div = DivWdg() hidden_div.add_styles("display: none"); hidden_div.add_class("spt_customlayoutwdg_handoffs") widget.add( hidden_div ) widget.add_behavior({ 'type': 'load', 'cbjs_action': ''' // handle embedded load behaviors! var el_load_list = bvr.src_el.getElements(".SPT_BVR_LOAD_PENDING"); spt.behavior.process_load_behaviors( el_load_list ); ''' }) for behavior_node in behavior_nodes: bvr_div = DivWdg() hidden_div.add( bvr_div ) css_class = Xml.get_attribute(behavior_node, 'class') behavior_str = Xml.get_node_value(behavior_node) behavior_str = behavior_str.strip() # if the event is specified in the xml, then use that event = Xml.get_attribute(behavior_node, 'event') modkeys = Xml.get_attribute(behavior_node, 'modkeys') relay_class = Xml.get_attribute(behavior_node, 'relay_class') if not behavior_str: continue try: try: bvr = eval(behavior_str) except: # try it as a string bvr_str = eval("'''\n%s\n'''" % behavior_str) if bvr_str: bvr = {} bvr['cbjs_action'] = bvr_str if event: bvr['type'] = event if modkeys: bvr['modkeys'] = modkeys # add the kwargs to this so behaviors have access bvr['kwargs'] = my.kwargs bvr['class_name'] = Common.get_full_class_name(my) if relay_class: bvr['bvr_match_class'] = relay_class if not bvr.get("type"): bvr['type'] = 'mouseup' my.content.add_relay_behavior( bvr ) elif bvr.get("type") == "smart_drag": bvr['bvr_match_class'] = css_class my.content.add_behavior(bvr) else: bvr['_handoff_'] = '@.getParent(".spt_custom_content").getElements(".%s")' % css_class if not bvr.get("type"): bvr['type'] = 'click_up' bvr_div.add_behavior( bvr ) except Exception, e: print "Error: ", e raise TacticException("Error parsing behavior [%s]" % behavior_str)
def get_label(my): return Xml.get_attribute( my.node, "label" )
def get_color(my): color = Xml.get_attribute( my.node, "color" ) return color
def get_group(my): return Xml.get_attribute( my.node, "group" )