def execute(my): class_names = my.kwargs.get("class_names") attrs_list = my.kwargs.get("attrs_list") kwargs_list = my.kwargs.get("kwargs_list") xml = Xml() xml.create_doc("config") root = xml.get_root_node() view = xml.create_element("tab") xml.append_child(root, view) for class_name, attrs, kwargs in zip(class_names, attrs_list, kwargs_list): element = xml.create_element("element") xml.append_child(view, element) for key, value in attrs.items(): xml.set_attribute(element, key, value) display = xml.create_element("display") xml.append_child(element, display) xml.set_attribute(display, "class", class_name) for key, value in kwargs.items(): attr = xml.create_text_element(key, value, node=display) xml.append_child(display, attr) xml_string = xml.to_string() from pyasm.web import WidgetSettings WidgetSettings.set_value_by_key("tab", xml_string)
def execute(my): database = "sthpw" sql = DbContainer.get(database) value_array = sql.do_query("select code, cc from (select code, count(code) as cc from file group by code order by cc desc) as X where cc > 1;") #value_array = sql.do_query("select code, cc from (select code, count(code) as cc from file group by code order by cc desc) as X;") print "found [%s] pairs" % len(value_array) for count, value_list in enumerate(value_array): if count >= BATCH: break # get the file object file_code = value_list[0] search = Search("sthpw/file") search.add_filter("code", file_code) files = search.get_sobjects() #if len(files) == 1: # continue for file in files: project_code = file.get_value("project_code") if not project_code: print "WARNING: file [%s] has no project_code" % file_code continue project = Project.get_by_code(project_code) initials = project.get_initials() id = file.get_id() new_file_code = "%s%s" % (id, initials) if file_code == new_file_code: continue print "-"*20 print "switching: ", file_code, "to", new_file_code snapshot_code = file.get_value("snapshot_code") snapshot = Snapshot.get_by_code(snapshot_code) assert snapshot snapshot_xml = snapshot.get_xml_value("snapshot") print snapshot_xml.to_string() node = snapshot_xml.get_node("snapshot/file[@file_code='%s']" % file_code) Xml.set_attribute(node, "file_code", new_file_code) print snapshot_xml.to_string() assert node # set the file_code file.set_value("code", new_file_code) file.commit() # set the snapshot snapshot.set_value("snapshot", snapshot_xml.to_string() ) snapshot.commit()
def execute(my): class_names = my.kwargs.get("class_names") attrs_list = my.kwargs.get("attrs_list") kwargs_list = my.kwargs.get("kwargs_list") xml = Xml() xml.create_doc("config") root = xml.get_root_node() view = xml.create_element("tab") xml.append_child(root, view) for class_name, attrs, kwargs in zip(class_names, attrs_list, kwargs_list): element = xml.create_element("element") xml.append_child(view, element) for key, value in attrs.items(): xml.set_attribute(element, key, value) display = xml.create_element("display") xml.append_child(element, display) xml.set_attribute(display, "class", class_name) for key, value in kwargs.items(): attr = xml.create_text_element(key, value, node=display) xml.append_child(display, attr) xml_string = xml.to_string() from pyasm.web import WidgetSettings WidgetSettings.set_value_by_key("tab", xml_string)
def handle_config(my): web = WebContainer.get_web() search_type = my.kwargs.get("search_type") view = my.view config_search_type = "config/widget_config" search = Search(config_search_type) search.add_filter("search_type", search_type) search.add_filter("view", view) search.add_filter("login", my.login) config = search.get_sobject() if not config: config = SearchType.create(config_search_type) config.set_value("search_type", search_type) config.set_value("view", view) if my.login: config.set_value("login", my.login) xml = config.get_xml_value("config", "config") root = xml.get_root_node() # reinitialize config._init() # build a new config view_node = xml.create_element(view) root.appendChild(view_node) config_mode = web.get_form_value("config_mode") if config_mode == "advanced": config_string = web.get_form_value("config_xml") else: config_title = web.get_form_value("config_title") config_icon = web.get_form_value("config_icon") config_icon2 = web.get_form_value("config_icon2") if config_icon2: config_icon = config_icon2 # TAKEN FROM API: should be centralized or something from tactic.ui.panel import SideBarBookmarkMenuWdg config_view = SideBarBookmarkMenuWdg.get_config(search_type, view) node = config_view.get_element_node(my.element_name) if node: config_xml = config_view.get_xml() node = config_view.get_element_node(my.element_name) Xml.set_attribute(node, "title", config_title) Xml.set_attribute(node, "icon", config_icon) config_string = config_xml.to_string(node) else: config_string = ''' <element name="%s" title="%s" icon="%s"/> ''' % (my.element_name, config_title, config_icon) config.append_xml_element(my.element_name, config_string) config.commit_config()
def handle_config(my): web = WebContainer.get_web() search_type = my.kwargs.get("search_type") view = my.view config_search_type = "config/widget_config" search = Search(config_search_type) search.add_filter("search_type", search_type) search.add_filter("view", view) search.add_filter("login", my.login) config = search.get_sobject() if not config: config = SearchType.create(config_search_type) config.set_value("search_type", search_type ) config.set_value("view", view ) if my.login: config.set_value("login", my.login ) xml = config.get_xml_value("config", "config") root = xml.get_root_node() # reinitialize config._init() # build a new config view_node = xml.create_element(view) root.appendChild(view_node) config_mode = web.get_form_value("config_mode") if config_mode == "advanced": config_string = web.get_form_value("config_xml") else: config_title = web.get_form_value("config_title") config_icon = web.get_form_value("config_icon") config_icon2 = web.get_form_value("config_icon2") if config_icon2: config_icon = config_icon2 # TAKEN FROM API: should be centralized or something from tactic.ui.panel import SideBarBookmarkMenuWdg config_view = SideBarBookmarkMenuWdg.get_config(search_type, view) node = config_view.get_element_node(my.element_name) if node: config_xml = config_view.get_xml() node = config_view.get_element_node(my.element_name) Xml.set_attribute(node, "title", config_title) Xml.set_attribute(node, "icon", config_icon) config_string = config_xml.to_string(node) else: config_string = ''' <element name="%s" title="%s" icon="%s"/> ''' %(my.element_name, config_title, config_icon) config.append_xml_element(my.element_name, config_string) config.commit_config()
def handle_columns_mode(self): doc = self.xml.create_doc("config") root = self.xml.get_root_node() columns = self.get_columns() if len(columns) == 1 and columns[0] == "id": columns = self.get_columns(required_only=False) # create the table # search is a special view for SearchWdg and it should not be created if self.view not in ['search', 'publish']: if self.view.find('@') != -1: table = self.xml.create_element('view', attrs={'name': self.view}) else: table = self.xml.create_element(self.view) self.xml.append_child(root, table) for column in columns: if column in ["_id", "id", "oid", "s_status"]: continue element = self.xml.create_element("element") Xml.set_attribute(element, "name", column) self.xml.append_child(table, element) # add history, input and output for the load view (designed for app loading) if self.view == 'load': element = self.xml.create_element("element") Xml.set_attribute(element, "name", "checkin") self.xml.append_child(table, element) for column in ['input', 'output']: element = self.xml.create_element("element") Xml.set_attribute(element, "name", column) Xml.set_attribute(element, "edit", "false") display_element = self.xml.create_element("display") Xml.set_attribute(display_element, "class", "tactic.ui.cgapp.LoaderElementWdg") self.xml.append_child(element, display_element) stype, key = SearchType.break_up_key(self.search_type) op1 = self.xml.create_text_element("search_type", stype) op2 = self.xml.create_text_element("mode", column) self.xml.append_child(display_element, op1) self.xml.append_child(display_element, op2) self.xml.append_child(table, element) value = self.xml.to_string() self.xml = Xml() self.xml.read_string(value)
def handle_columns_mode(my): doc = my.xml.create_doc("config") root = my.xml.get_root_node() columns = my.get_columns() if len(columns) == 1 and columns[0] == "id": columns = my.get_columns(required_only=False) # create the table # search is a special view for SearchWdg and it should not be created if my.view not in ['search','publish']: if my.view.find('@') != -1: table = my.xml.create_element('view', attrs={'name': my.view}) else: table = my.xml.create_element(my.view) my.xml.append_child(root, table) for column in columns: if column in ["_id", "id", "oid", "s_status"]: continue element = my.xml.create_element("element") Xml.set_attribute(element, "name", column) my.xml.append_child(table, element) # add history, input and output for the load view (designed for app loading) if my.view == 'load': element = my.xml.create_element("element") Xml.set_attribute(element, "name", "checkin") my.xml.append_child(table, element) for column in ['input', 'output']: element = my.xml.create_element("element") Xml.set_attribute(element, "name", column) Xml.set_attribute(element, "edit", "false") display_element = my.xml.create_element("display") Xml.set_attribute(display_element, "class", "tactic.ui.cgapp.LoaderElementWdg") my.xml.append_child(element, display_element) stype, key = SearchType.break_up_key(my.search_type) op1 = my.xml.create_text_element("search_type", stype) op2 = my.xml.create_text_element("mode", column) my.xml.append_child(display_element, op1) my.xml.append_child(display_element, op2) my.xml.append_child(table, element) value = my.xml.to_string() my.xml = Xml() my.xml.read_string(value)
def get_by_code(cls, code, allow_default=False): '''it is fatal not to have a pipeline, so put a default''' if not code: return None # first look at project specific pipeline pipeline = Search.get_by_code("config/pipeline", code) if not pipeline: pipeline = super(Pipeline,cls).get_by_code(code) if not pipeline and code == 'task': # Create a default task pipeline pipeline = SearchType.create("sthpw/pipeline") pipeline.set_value("code", "task") from pyasm.biz import Task xml = Task.get_default_task_xml() pipeline.set_value("pipeline", xml) pipeline.set_pipeline(xml) pipeline.set_value("search_type", "sthpw/task") #pipeline.commit() if not pipeline and allow_default: search = Search(cls) search.add_filter('code', 'default') pipeline = search.get_sobject() if not pipeline: pipeline = cls.create('default', \ 'default pipeline', '') xml = pipeline.get_xml_value("pipeline") # create a default process for the table root = xml.get_root_node() element = xml.create_element("process") Xml.set_attribute(element,"name", "default_process") Xml.append_child(root, element) pipeline.set_value('pipeline', xml.get_xml()) pipeline.commit() # set the pipeline pipeline.set_pipeline(pipeline.get_value('pipeline')) Environment.add_warning("pipeline autogenerated", \ "[default] pipeline has just been created.") # Sometimes, a pipeline is instantiated without calling set_pipeline() # to be looked into if pipeline and not pipeline.get_processes(): pipeline.set_pipeline(pipeline.get_value('pipeline')) return pipeline
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_by_code(cls, code, allow_default=False): '''it is fatal not to have a pipeline, so put a default''' if not code: return None # first look at project specific pipeline pipeline = Search.get_by_code("config/pipeline", code) if not pipeline: pipeline = super(Pipeline, cls).get_by_code(code) if not pipeline and code == 'task': # Create a default task pipeline pipeline = SearchType.create("sthpw/pipeline") pipeline.set_value("code", "task") from pyasm.biz import Task xml = Task.get_default_task_xml() pipeline.set_value("pipeline", xml) pipeline.set_pipeline(xml) pipeline.set_value("search_type", "sthpw/task") #pipeline.commit() if not pipeline and allow_default: search = Search(cls) search.add_filter('code', 'default') pipeline = search.get_sobject() if not pipeline: pipeline = cls.create('default', \ 'default pipeline', '') xml = pipeline.get_xml_value("pipeline") # create a default process for the table root = xml.get_root_node() element = xml.create_element("process") Xml.set_attribute(element, "name", "default_process") Xml.append_child(root, element) pipeline.set_value('pipeline', xml.get_xml()) pipeline.commit() # set the pipeline pipeline.set_pipeline(pipeline.get_value('pipeline')) Environment.add_warning("pipeline autogenerated", \ "[default] pipeline has just been created.") # Sometimes, a pipeline is instantiated without calling set_pipeline() # to be looked into if pipeline and not pipeline.get_processes(): pipeline.set_pipeline(pipeline.get_value('pipeline')) return pipeline
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_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 dump(self, plugin_code, project_code, search_types): xml = Xml() self.xml = xml xml.create_doc("manifest") manifest_node = xml.get_root_node() xml.set_attribute(manifest_node, "code", plugin_code) # DUMP the data for search_type in search_types: data_node = xml.create_element("search_type") xml.append_child(manifest_node, data_node) xml.set_attribute(data_node, "code", search_type) # This exports the data """ data_node = xml.create_element("sobject") xml.append_child(manifest_node, data_node) xml.set_attribute(data_node, "search_type", search_type) # find the currval st_obj = SearchType.get(search_type) # have to call nextval() to initiate this sequence in the session in psql since Postgres 8.1 seq_id = st_obj.sequence_nextval() seq_id = st_obj.sequence_currval() seq_id -= 1 if seq_id > 0: st_obj.sequence_setval(seq_id) xml.set_attribute(data_node, "seq_max", seq_id) """ print xml.to_string() # create a virtual plugin plugin = SearchType.create("sthpw/plugin") plugin.set_value("version", "1.0.0") plugin.set_value("code", "%s_project" % project_code) base_dir = "./templates" creator = PluginCreator(base_dir=base_dir, plugin=plugin, manifest=xml.to_string()) creator.execute()
def dump(my, plugin_code, project_code, search_types): xml = Xml() my.xml = xml xml.create_doc("manifest") manifest_node = xml.get_root_node() xml.set_attribute(manifest_node, "code", plugin_code) # DUMP the data for search_type in search_types: data_node = xml.create_element("search_type") xml.append_child(manifest_node, data_node) xml.set_attribute(data_node, "code", search_type) # This exports the data """ data_node = xml.create_element("sobject") xml.append_child(manifest_node, data_node) xml.set_attribute(data_node, "search_type", search_type) # find the currval st_obj = SearchType.get(search_type) # have to call nextval() to initiate this sequence in the session in psql since Postgres 8.1 seq_id = st_obj.sequence_nextval() seq_id = st_obj.sequence_currval() seq_id -= 1 if seq_id > 0: st_obj.sequence_setval(seq_id) xml.set_attribute(data_node, "seq_max", seq_id) """ print xml.to_string() # create a virtual plugin plugin = SearchType.create("sthpw/plugin") plugin.set_value("version", "1.0.0") plugin.set_value("code", "%s_project" % project_code) base_dir = "./templates" creator = PluginCreator( base_dir=base_dir, plugin=plugin, manifest=xml.to_string() ) creator.execute()
def _get_edit_config(self, view, process_names): xml = Xml() xml.create_doc("config") root = xml.get_root_node() view_node = xml.create_element(view) #root.appendChild(view_node) xml.append_child(root, view_node) for idx, process_name in enumerate(process_names): element = xml.create_element('element') Xml.set_attribute(element, 'name', process_name) #view_node.appendChild(element) xml.append_child(view_node, element) display = xml.create_element('display') Xml.set_attribute(display, 'class', "pyasm.widget.TextAreaWdg") #element.appendChild(display) xml.append_child(element, display) config_xml = xml.to_string() widget_config = WidgetConfig.get(view=view, xml = config_xml) widget_config_view = WidgetConfigView('sthpw/note', view, [widget_config]) return widget_config_view
def handle_config2(my): """for db column search config stuff, not used yet""" web = WebContainer.get_web() search_type = "SearchTypeSchema" view = "definition" config_search_type = "config/widget_config" search = Search(config_search_type) search.add_filter("search_type", search_type) search.add_filter("view", view) config = search.get_sobject() if not config: config = SearchType.create(config_search_type) config.set_value("search_type", search_type) config.set_value("view", view) xml = config.get_xml_value("config", "config") root = xml.get_root_node() # reinitialize config._init() # build a new config view_node = xml.create_element(view) root.appendChild(view_node) config_mode = web.get_form_value("config_mode") if config_mode == "advanced": config_string = web.get_form_value("config_xml") else: config_data_type = web.get_form_value("config_data_type") if config_data_type == "Other...": config_data_type = web.get_form_value("config_data_type_custom") config_nullable = web.get_form_value("config_nullable") # TAKEN FROM API: should be centralized or something from tactic.ui.panel import SideBarBookmarkMenuWdg config_view = SideBarBookmarkMenuWdg.get_config(search_type, view) node = config_view.get_element_node(my.element_name) if node: config_xml = config_view.get_xml() node = config_view.get_element_node(my.element_name) Xml.set_attribute(node, "data_type", config_data_type) Xml.set_attribute(node, "nullable", config_nullable) Xml.set_attribute(node, "new", "True") config_string = config_xml.to_string(node) else: config_string = """ <element name="%s" data_type="%s" nullable="%s" new="True"/> """ % ( my.element_name, config_data_type, config_nullable, ) config.append_xml_element(my.element_name, config_string) config.commit_config()
def _get_main_config(self, view, process_names): '''get the main config for this table layout''' xml = Xml() xml.create_doc("config") root = xml.get_root_node() view_node = xml.create_element(view) #root.appendChild(view_node) xml.append_child(root, view_node) for idx, process_name in enumerate(process_names): element = xml.create_element('element') Xml.set_attribute(element, 'name', process_name) #view_node.appendChild(element) xml.append_child(view_node, element) display = xml.create_element('display') if self.element_class: Xml.set_attribute(display, 'class',self.element_class) else: Xml.set_attribute(display, 'class', "tactic.ui.app.NoteTableElementWdg") #element.appendChild(display) xml.append_child(element, display) op_element = xml.create_data_element('parent_key', self.search_key) xml.append_child(display, op_element) config_xml = xml.to_string() widget_config = WidgetConfig.get(view=view, xml = config_xml) widget_config_view = WidgetConfigView('sthpw/note', view, [widget_config]) return widget_config_view
def _get_main_config(my, view, process_names): '''get the main config for this table layout''' xml = Xml() xml.create_doc("config") root = xml.get_root_node() view_node = xml.create_element(view) #root.appendChild(view_node) xml.append_child(root, view_node) for idx, process_name in enumerate(process_names): element = xml.create_element('element') Xml.set_attribute(element, 'name', process_name) #view_node.appendChild(element) xml.append_child(view_node, element) display = xml.create_element('display') if my.element_class: Xml.set_attribute(display, 'class', my.element_class) else: Xml.set_attribute(display, 'class', "tactic.ui.app.NoteTableElementWdg") #element.appendChild(display) xml.append_child(element, display) op_element = xml.create_data_element('parent_key', my.search_key) xml.append_child(display, op_element) config_xml = xml.to_string() widget_config = WidgetConfig.get(view=view, xml=config_xml) widget_config_view = WidgetConfigView('sthpw/note', view, [widget_config]) return widget_config_view
def _get_edit_config(my, view, process_names): xml = Xml() xml.create_doc("config") root = xml.get_root_node() view_node = xml.create_element(view) #root.appendChild(view_node) xml.append_child(root, view_node) for idx, process_name in enumerate(process_names): element = xml.create_element('element') Xml.set_attribute(element, 'name', process_name) #view_node.appendChild(element) xml.append_child(view_node, element) display = xml.create_element('display') Xml.set_attribute(display, 'class', "pyasm.widget.TextAreaWdg") #element.appendChild(display) xml.append_child(element, display) config_xml = xml.to_string() widget_config = WidgetConfig.get(view=view, xml=config_xml) widget_config_view = WidgetConfigView('sthpw/note', view, [widget_config]) return widget_config_view
def serialize(my): '''provide the ability for a widget to serialize itself''' xml = Xml() xml.create_doc("config") # create the top element element = xml.create_element("element") xml.set_attribute(element, "name", my.name) # create the display handler display = xml.create_element("display") xml.set_attribute(display, "class", Common.get_full_class_name(my)) element.appendChild(display) # create the options for name, value in my.kwargs.items(): if value: option = xml.create_text_element(name, value) else: # avoid the \n in the textContent of the textNode option = xml.create_element(name) display.appendChild(option) return xml.to_string(element)
def handle_config2(my): '''for db column search config stuff, not used yet''' web = WebContainer.get_web() search_type = "SearchTypeSchema" view = "definition" config_search_type = "config/widget_config" search = Search(config_search_type) search.add_filter("search_type", search_type) search.add_filter("view", view) config = search.get_sobject() if not config: config = SearchType.create(config_search_type) config.set_value("search_type", search_type) config.set_value("view", view) xml = config.get_xml_value("config", "config") root = xml.get_root_node() # reinitialize config._init() # build a new config view_node = xml.create_element(view) root.appendChild(view_node) config_mode = web.get_form_value("config_mode") if config_mode == "advanced": config_string = web.get_form_value("config_xml") else: config_data_type = web.get_form_value("config_data_type") if config_data_type == 'Other...': config_data_type = web.get_form_value( "config_data_type_custom") config_nullable = web.get_form_value("config_nullable") # TAKEN FROM API: should be centralized or something from tactic.ui.panel import SideBarBookmarkMenuWdg config_view = SideBarBookmarkMenuWdg.get_config(search_type, view) node = config_view.get_element_node(my.element_name) if node: config_xml = config_view.get_xml() node = config_view.get_element_node(my.element_name) Xml.set_attribute(node, "data_type", config_data_type) Xml.set_attribute(node, "nullable", config_nullable) Xml.set_attribute(node, "new", "True") config_string = config_xml.to_string(node) else: config_string = ''' <element name="%s" data_type="%s" nullable="%s" new="True"/> ''' % (my.element_name, config_data_type, config_nullable) config.append_xml_element(my.element_name, config_string) config.commit_config()
def serialize(my): '''provide the ability for a widget to serialize itself''' xml = Xml() xml.create_doc("config") # create the top element element = xml.create_element("element") xml.set_attribute(element, "name", my.name) # create the display handler display = xml.create_element("display") xml.set_attribute(display, "class", Common.get_full_class_name(my) ) element.appendChild(display) # create the options for name, value in my.kwargs.items(): if value: option = xml.create_text_element(name, value) else: # avoid the \n in the textContent of the textNode option = xml.create_element(name) display.appendChild(option) return xml.to_string(element)
def execute(self): sobject = self.sobject name = self.get_name() web = WebContainer.get_web() naming = web.get_form_value(name) if not naming: return xml = Xml(string=naming) sample_name = xml.get_value("naming/@sample") parts = re.split( '[\\/._]', sample_name) # make some adjustments based on selections nodes = xml.get_nodes("naming/part") for idx, node in enumerate(nodes): type_value = web.get_form_value("type_%s" % idx) part = parts[idx] if not type_value: continue if type_value == "placeholder": Xml.set_attribute(nodes[idx], "type", "placeholder") Xml.set_attribute(nodes[idx], "value", part) else: a, b = type_value.split("/") Xml.set_attribute(nodes[idx], "type", a) Xml.set_attribute(nodes[idx], "name", b) naming = xml.to_string() sobject.set_value(name, naming)
def execute(my): sobject = my.sobject name = my.get_name() web = WebContainer.get_web() naming = web.get_form_value(name) if not naming: return xml = Xml(string=naming) sample_name = xml.get_value("naming/@sample") parts = re.split( '[\\/._]', sample_name) # make some adjustments based on selections nodes = xml.get_nodes("naming/part") for idx, node in enumerate(nodes): type_value = web.get_form_value("type_%s" % idx) part = parts[idx] if not type_value: continue if type_value == "placeholder": Xml.set_attribute(nodes[idx], "type", "placeholder") Xml.set_attribute(nodes[idx], "value", part) else: a, b = type_value.split("/") Xml.set_attribute(nodes[idx], "type", a) Xml.set_attribute(nodes[idx], "name", b) naming = xml.to_string() sobject.set_value(name, naming)
def set_attribute(my, name, value): return Xml.set_attribute(my.node, name, value)
def execute(my): mode = my.kwargs.get("mode") # modes are either naming based or file object based #mode = "naming" #mode = "file" assert mode in ['naming', 'file'] search_type = my.kwargs.get("search_type") search_keys = my.kwargs.get("search_keys") assert search_type or search_keys if search_type: print "@SOBJECT(%s)" % search_type sobjects = Search.eval("@SOBJECT(%s)" % search_type) else: sobjects = Search.get_by_search_keys(search_keys) if not sobjects: print "No sobjects to process" return snapshots = Search.eval("@SOBJECT(sthpw/snapshot)", sobjects) # set an arbitrary limit for now limit = 1000 base_dir = Environment.get_asset_dir() num_found = 0 errors = [] for i, snapshot in enumerate(snapshots): if i > limit: break print "Processing: %s of %s" % (i, len(snapshots) ) file_types = snapshot.get_all_file_types() for file_type in file_types: files = snapshot.get_files_by_type(file_type) # FIXME: not sure why we have this limitation, although it is # a pretty rare occurance if len(files) > 1: raise Exception("More than one file with type [%s] in snapshot [%s]" % (file_type, snapshot.get_code()) ) file = files[0] file_name = file.get_value("file_name") # check-in dir is not subject to changes in asset_dir checkin_dir = file.get_value("checkin_dir") old_path = "%s/%s" % ( checkin_dir, file_name ) try: if mode == "naming": # preallocated path is used to align a file to the # current naming convention # FIXME: # there is a behavior in naming to add "_web" and # "_icon" on the file name. In this case, we don't # want that, so ask for main if file_type in ['icon', 'web']: path = snapshot.get_preallocated_path('main', file_name) else: path = snapshot.get_preallocated_path(file_type, file_name) elif mode == "file": # relative_dir is used to align a file to the current # place pointed to by the "file" object relative_dir = file.get_value("relative_dir") path = "%s/%s/%s" % ( base_dir, relative_dir, file_name ) else: raise Exception("Invalid mode [%s]" % mode) except Exception, e: error = "Snapshot [%s] has an error getting preallocated path: [%s]" % (snapshot.get_code(), e.message ) errors.append(error) continue if old_path == path: continue num_found += 1 print "snapshot: ", snapshot.get_value("code") print "old: ", old_path print "new: ", path print "-"*20 new_dir = os.path.dirname(path) new_filename = os.path.basename(path) new_relative_dir = new_dir.replace(base_dir, '') new_relative_dir = new_relative_dir.strip("/") xml = snapshot.get_xml_value("snapshot") node = xml.get_node("snapshot/file[@type='%s']" % file_type) Xml.set_attribute(node, "name", new_filename) # update all of the file file.set_value("file_name", new_filename) file.set_value("checkin_dir", new_dir) file.set_value("relative_dir", new_relative_dir) snapshot.set_value("snapshot", xml.to_string() ) dirname = os.path.dirname(path) if not os.path.exists(dirname): FileUndo.mkdir(dirname) exists = False if os.path.islink(old_path): exists = os.path.lexists(old_path) else: exists = os.path.exists(old_path) if not exists: print '... old does not exist' continue FileUndo.move(old_path, path) file.commit() snapshot.commit() # try to remove the old folder (if it's empty, it will be removed) dirname = os.path.dirname(old_path) while 1: try: os.rmdir(dirname) dirname = os.path.dirname(dirname) except: break
def set_attribute(self, name, value): return Xml.set_attribute(self.node, name, value)
class PageNavContainerWdg(BaseRefreshWdg): def init(self): link = self.kwargs.get('link') hash = self.kwargs.get('hash') self.widget = None if link: from tactic.ui.panel import SideBarBookmarkMenuWdg personal = False if '.' in link: personal = True config = SideBarBookmarkMenuWdg.get_config("SideBarWdg", link, personal=personal) options = config.get_display_options(link) # this is vital for view saving element_name = link attr_dict = config.get_element_attributes(link) title = attr_dict.get('title') hash = "/tab/%s" % link config = ''' <config> <application> <element name="left_nav"> <display class="tactic.ui.panel.SideBarPanelWdg"> </display> </element> <element name="main_body"> <display class="tactic.ui.panel.HashPanelWdg"> <hash>%s</hash> <element_name>%s</element_name> <title>%s</title> </display> <web/> </element> </application> </config> ''' % (hash, element_name, title) elif hash: from tactic.ui.panel import HashPanelWdg self.widget = HashPanelWdg.get_widget_from_hash(hash, force_no_index=True) config = None else: security = Environment.get_security() start_link = security.get_start_link() if start_link: self.kwargs['link'] = start_link return self.init() # search for a defined welcome view search = Search("config/widget_config") search.add_filter("category", "top_layout") search.add_filter("view", "welcome") config_sobj = search.get_sobject() if config_sobj: config = config_sobj.get_value("config") else: config = WidgetSettings.get_value_by_key("top_layout") if not config: config = self.get_default_config() self.config_xml = Xml() self.config_xml.read_string(config) def get_default_config(self): use_sidebar = self.kwargs.get('use_sidebar') if use_sidebar==False: config = ''' <config> <application> <element name="main_body"> <display class="tactic.ui.startup.MainWdg"/> <web/> </element> </application> </config> ''' else: config = ''' <config> <application> <element name="left_nav"> <display class="tactic.ui.panel.SideBarPanelWdg"> <auto_size>True</auto_size> </display> </element> <element name="main_body"> <display class="tactic.ui.startup.MainWdg"/> <web/> </element> </application> </config> ''' return config def set_state(self, panel_name, widget_class, options, values): '''this is called by side_bar.js mostly''' # set the class name display_node = self.config_xml.get_node("config/application/element[@name='%s']/display" % (panel_name) ) self.config_xml.set_attribute(display_node, "class", widget_class) # remove all the old options #display_node = self.config_xml.get_node("config/application/element[@name='%s']/display" % panel_name ) for child_node in self.config_xml.get_children(display_node): self.config_xml.remove_child(display_node, child_node) # set the options for name, value in options.items(): node = self.config_xml.get_node("config/application/element[@name='%s']/display/%s" % (panel_name, name) ) if isinstance( value, basestring ): #print("WARNING: set application: skipping [%s] with value [%s]" % (name, value)) #continue element = self.config_xml.create_text_element(name, value) self.config_xml.append_child(display_node, element) elif isinstance( value, dict): # if it is a dictionary # TODO: run recursively.. supports 2 level only now sub_element = self.config_xml.create_element(name) self.config_xml.append_child(display_node, element) for name2, value2 in value.items(): if isinstance(value2, dict): sub_element2 = self.config_xml.create_element(name2) self.config_xml.append_child(sub_element, sub_element2) for name3, value3 in value2.items(): element = self.config_xml.create_text_element(name3, value3) self.config_xml.append_child(sub_element2, element) else: element = self.config_xml.create_text_element(name2, value2) self.config_xml.append_child(sub_element, element) # web value node value_node = self.config_xml.get_node("config/application/element[@name='%s']/web" % (panel_name) ) if value_node != None: for child_node in self.config_xml.get_children(value_node): self.config_xml.remove_child(value_node, child_node) else: # create it value_node = self.config_xml.create_element('web') element_node = self.config_xml.get_node("config/application/element[@name='%s']" % (panel_name) ) self.config_xml.append_child(element_node, value_node) # set the values for name, value in values.items(): node = self.config_xml.get_node("config/application/element[@name='%s']/web/%s" % (panel_name, name) ) if not isinstance(value, basestring): print("WARNING: set application: skipping [%s] with value [%s]" % (name, value)) continue element = self.config_xml.create_text_element(name, value) self.config_xml.append_child(value_node, element) WidgetSettings.set_key_values("top_layout", [self.config_xml.to_string()]) def get_state(self): return self.config_xml def get_side_bar_cache(self, left_nav_wdg): project = Project.get() project_code = project.get_code() # do it with sobject #key = "%s_side_bar" % project.get_code() #cache = Search.get("sthpw/widget_cache") #cache.add_filter("key", key) #sobject = cache.get_sobject() #value = sobject.get_value("cache") login = Environment.get_user_name() tmp_dir = "%s/cache/side_bar" % Environment.get_tmp_dir() filename = "%s__%s.html" % (project_code, login) path = "%s/%s" % (tmp_dir, filename) # use files import os if os.path.exists(path): f = open(path, "r") html = f.read() f.close() else: dirname = os.path.dirname(path) if not os.path.exists(dirname): os.makedirs(dirname) f = open(path, "w") html = left_nav_wdg.get_buffer_display() f.write(html) f.close() return html def get_display(self): is_admin_project = Project.get().is_admin() security = Environment.get_security() if is_admin_project and not security.check_access("builtin", "view_site_admin", "allow"): return Error403Wdg() # create the elements config = WidgetConfig.get(xml=self.config_xml, view="application") left_nav_handler = config.get_display_handler("left_nav") left_nav_options = config.get_display_options("left_nav") view_side_bar = None if left_nav_handler: left_nav_wdg = Common.create_from_class_path(left_nav_handler, [], left_nav_options) # caching side_bar_cache = self.get_side_bar_cache(left_nav_wdg) else: view_side_bar = False # create the main table core_table = Table() core_table.add_tbody() core_table.set_style("border: 0px; border-collapse: collapse; width: 100%;") # add a spacer row #spacer_tr = core_table.add_row() #spacer_tr.add_style("width: 100%") #td = core_table.add_cell() #td.set_style("min-height: 1px; height: 1px;") #core_table.add_cell() #core_table.add_cell() # determine if the side bar is visible if view_side_bar == None: view_side_bar = security.check_access("builtin", "view_side_bar", "allow", default='allow') # add the main cells tr, td = core_table.add_row_cell() td.add_style("padding: 0px") td.add_style("margin: 0px") # add the main resizable table from tactic.ui.container import ResizableTableWdg main_table = ResizableTableWdg() main_table.set_keep_table_size() main_table.add_style("width: 100%") td.add(main_table) left_nav_td = main_table.add_cell() if view_side_bar: left_nav_td.add_class("spt_panel") left_nav_td.add_style("padding: 0px") main_body_td = main_table.add_cell(resize=False) main_body_td.add_style("padding: 10px") main_body_td.set_style( "width: 100%; vertical-align: top; text-align: center; padding-top: 3px" ) if view_side_bar: left_nav_td.set_style( "vertical-align: top" ) # create the left navigation panel left_nav_div = DivWdg() left_nav_td.add(left_nav_div) left_nav_div.set_id("side_bar" ) # add the detail to the panel left_nav_div.add_attr("spt_class_name", left_nav_handler) for name, value in left_nav_options.items(): left_nav_div.add_attr("spt_%s" % name, value) left_nav_div.add_style("max_width: 185px") left_nav_div.add_style("width: 185px") left_nav_div.add_style("text-align: right") left_nav_div.add_style("vertical-align: top") left_nav_div.add_style("overflow: hidden") left_nav_div.add_class("spt_resizable") side_bar_inner = DivWdg() left_nav_div.add(side_bar_inner) #side_bar_inner.add_style("padding-left: 1px") side_bar_inner.add_style("width: 100%") # add side bar to nav side_bar_inner.add(side_bar_cache) left_nav_div.add_style("border-style: solid") left_nav_div.add_style("border-width: 0px 1px 0px 0px") #left_nav_div.add_color("border-color", "border") left_nav_div.add_color("border-color", "border", -10) web = WebContainer.get_web() browser = web.get_browser() if browser in ['Qt','Webkit']: min_width = "1px" else: min_width = "0px" left_nav_div.add_behavior( { 'type': 'listen', 'event_name': 'side_bar|hide_now', 'min_width': min_width, 'cbjs_action': ''' var size = bvr.src_el.getSize(); bvr.src_el.setAttribute("spt_size", size.x); bvr.src_el.setStyle("width", bvr.min_width); ''' } ) left_nav_div.add_behavior( { 'type': 'listen', 'event_name': 'side_bar|hide', 'min_width': min_width, 'cbjs_action': ''' var size = bvr.src_el.getSize(); bvr.src_el.setAttribute("spt_size", size.x); new Fx.Tween(bvr.src_el, {duration:'short'}).start('width', bvr.min_width); ''' } ) left_nav_div.add_behavior( { 'type': 'listen', 'event_name': 'side_bar|show', 'min_width': min_width, 'cbjs_action': ''' var width = bvr.src_el.getAttribute("spt_size"); if (!width) { width = 185; } if (parseInt(width) < 5) { width = 185; } //bvr.src_el.setStyle("width", width + "px"); new Fx.Tween(bvr.src_el, {duration:'short'}).start('width', bvr.min_width, width+"px"); ''' } ) left_nav_div.add_behavior( { 'type': 'listen', 'event_name': 'side_bar|toggle', 'cbjs_action': ''' var size = bvr.src_el.getSize(); if (size.x < 5) { spt.named_events.fire_event("side_bar|show", {} ); } else { spt.named_events.fire_event("side_bar|hide", {} ); } ''' } ) # create the main body panel palette = WebContainer.get_palette() color = palette.color("background2") main_body_rounded = DivWdg() main_body_inner = main_body_rounded main_body_inner.add_style("min-height: 500px") # DEBREACATED """ # add a breadcrumb breadcrumb_wdg = DivWdg() # hide the breadcrumb breadcrumb_wdg.add_style("display", "none") Container.put("breadcrumb", breadcrumb_wdg) breadcrumb_wdg.set_id("breadcrumb") breadcrumb_wdg.add_style("text-align: left") breadcrumb_wdg.add_looks( "fnt_title_3" ) main_body_inner.add(breadcrumb_wdg) """ main_body_panel = DivWdg() main_body_panel.set_id("main_body") main_body_panel.add_class("spt_main_panel") main_body_inner.add(main_body_panel) tab = MainBodyTabWdg() main_body_panel.add(tab) # TEST: NEW LAYOUT if Config.get_value("install", "layout") == "fixed": main_body_panel.add_style("margin-top: 31px") main_body_rounded.add_color("background", "background") main_body_rounded.add_style("padding: 3px 0px 0px 0px") # add the content to the main body panel try: if self.widget: tab.add(self.widget) element_name = self.widget.get_name() else: main_body_handler = config.get_display_handler("main_body") main_body_options = config.get_display_options("main_body") element_name = main_body_options.get("element_name") title = main_body_options.get("title") main_body_content = Common.create_from_class_path(main_body_handler, [], main_body_options) # get the web values from top_layout main_body_values = config.get_web_options("main_body") web = WebContainer.get_web() if isinstance(main_body_values, dict): for name, value in main_body_values.items(): web.set_form_value(name, value) main_body_content.set_name(element_name) tab.add(main_body_content, element_name, title) self.set_as_panel(main_body_panel, class_name=main_body_handler, kwargs=main_body_options) main_body_panel.add_behavior( { 'type': 'load', 'element_name': element_name, 'cbjs_action': ''' if (spt.help) spt.help.set_view(bvr.element_name); ''' } ) except Exception as e: # handle an error in the drawing buffer = self.get_buffer_on_exception() error_wdg = self.handle_exception(e) main_body_content = DivWdg() main_body_content.add(error_wdg) main_body_content = main_body_content.get_buffer_display() tab.add(main_body_content, element_name, title) # add the main container container_div = DivWdg() container_div.set_style("width: 100%;") # NOTE: the td should not be the sliding element! So we create a div inside the TD to be the sliding element main_body_div = DivWdg() main_body_div.set_id("horizontal_main_body_slider") main_body_div.add(main_body_inner) """ # get the global drag_ghost_div drag_ghost_div = self.get_drag_ghost_div() drag_ghost_div.set_id( "drag_ghost_copy" ) drag_ghost_div.add_class( "SPT_PUW" ) # make it a Page Utility Widget (now processed client side) drag_ghost_div.set_z_start( 400 ) """ from page_header_wdg import PageHeaderWdg header_panel = DivWdg() header_panel.set_id("main_header") header_panel.add_attr("spt_class_name", "tactic.ui.app.PageHeaderWdg") header_wdg = PageHeaderWdg() header_panel.add(header_wdg) container_div.add( header_panel.get_buffer_display() ) main_body_dis = main_body_div.get_buffer_display() main_body_td.add(main_body_dis) container_div.add( core_table ) #container_div.add( drag_ghost_div ) is_admin = False security = Environment.get_security() if security.check_access("builtin", "view_site_admin", "allow"): is_admin = True if is_admin: from quick_box_wdg import QuickBoxWdg quick_box = QuickBoxWdg() container_div.add(quick_box) container_div.add_behavior( { 'type': 'load', 'cbjs_action': ''' spt.named_events.fire_event("close_admin_bar"); ''' } ) return container_div def handle_exception(self, e): '''The tab widget is a special widget concerning exceptions because it usually represents the outer skin of the content of the web page. The titles of the tab must be displayed in order for the site to remain functional in the case of an exception''' from pyasm.widget import ExceptionWdg widget = ExceptionWdg(e) self.error_wdg = Widget() self.error_wdg.add(widget) return self.error_wdg """ def get_drag_ghost_div(self): drag_ghost_div = HtmlElement.div() drag_ghost_div.set_attr( "id", "drag_ghost_copy" ) drag_ghost_div.set_attr( "element_copied", "_NONE_" ) drag_ghost_div.add_class( "REG_ID" ) drag_ghost_div.set_style("background: #393950; color: #c2c2c2; border: solid 1px black;' \ 'text-align: left; padding: 10px;', filter: alpha(opacity=60); " + "opacity: 0.6; position: absolute; display: none; left: 0px; top: 0px;" + " z-index: 110;" ) drag_ghost_div.add("Ghost Div") return drag_ghost_div """ def get_drag_div(self): drag_div = HtmlElement.div() drag_div.set_style( "position: absolute; left: 100px; top: 400px; min-width: 400px; width: 400px; " + "background-color: white; border: solid black;" ) drag_handle_div = HtmlElement.div() drag_handle_div.set_style( "cursor: default; background-color: gray; border-bottom: dotted black; " + "padding: 3px; font-family: sans-serif; font-weight: bold;" ) # NOTE: to specify behaviors on a widget, you can use the .add_behavior() method ... use one behavior # specification dictionary (hash) string per call to add_behavior (but you can add multiple # behaviors by making multiple calls to add_behavior) # drag_handle_div.add_behavior( "{type:'click', mouse_btn:'LMB', modkeys:'SHIFT', dst_el:'@.parentNode', " + "cbfn_action: spt.cb.change_color_action}" ) drag_handle_div.add_behavior( "{type:'drag', mouse_btn:'LMB', modkeys:'', src_el:'@.parentNode'}" ) drag_handle_div.add("Drag Handle -- click and drag me!") drag_div.add( drag_handle_div ) drag_div.add( "<p>This is a draggable div ... click on the drag handle above and drag this thing around!</p>" ) return drag_div
def execute(my): import datetime now = datetime.datetime.now() version = now.strftime("%Y%m%d_%H%M%S") project_code = my.kwargs.get("project_code") if project_code: project = Project.get_by_code(project_code) else: project = Project.get() project_code = project.get_code() server_code = my.kwargs.get("server") assert server_code if not isinstance(server_code, basestring): server_code = server_code.get_value("code") base_dir = my.kwargs.get('base_dir') ticket = Environment.get_ticket() tmp_dir = "%s/sync_%s" % (Environment.get_tmp_dir(), ticket) if not os.path.exists(tmp_dir): os.makedirs(tmp_dir) server = Search.get_by_code("sthpw/sync_server", server_code) if server.get_value("sync_mode") == "file": if not base_dir: base_dir = server.get_value("base_dir") else: raise Exception("sync mode [%s] not support" % sync_mode) # FIXME: not sure if this is valid anymore asset_dir = Environment.get_asset_dir() base_dir = "%s/_temp" % asset_dir # create the project template from tactic.command import ProjectTemplateCreatorCmd cmd = ProjectTemplateCreatorCmd(project_code=project_code, version=version, base_dir=tmp_dir) cmd.execute() project_path = cmd.get_zip_path() # create zip of the project files from pyasm.common import ZipUtil zip_util = ZipUtil() asset_dir = Environment.get_asset_dir() project_dir = "%s/%s" % (asset_dir, project_code) zip_dir = "%s/%s" % (tmp_dir, project_code) file_path = "%s-files-%s.zip" % (zip_dir, version) if os.path.exists(file_path): os.unlink(file_path) zip_util.zip_dir2(project_dir, zip_path=file_path) # create a manifest for all the data in the project. xml = Xml() my.xml = xml xml.create_doc("manifest") manifest_node = xml.get_root_node() xml.set_attribute(manifest_node, "code", "%s-data" % project_code) search_types = project.get_search_types() # just dump the data for search_type in search_types: data_node = xml.create_element("sobject") xml.append_child(manifest_node, data_node) xml.set_attribute(data_node, "search_type", search_type.get_value("search_type")) # dump the note entries data_node = xml.create_element("sobject") xml.append_child(manifest_node, data_node) xml.set_attribute( data_node, "expression", "@SOBJECT(sthpw/note['project_code','%s'])" % project_code) xml.set_attribute(data_node, "search_type", "sthpw/note") # dump the task entries data_node = xml.create_element("sobject") xml.append_child(manifest_node, data_node) xml.set_attribute( data_node, "expression", "@SOBJECT(sthpw/task['project_code','%s'])" % project_code) xml.set_attribute(data_node, "search_type", "sthpw/task") # dump the snapshot entries data_node = xml.create_element("sobject") xml.append_child(manifest_node, data_node) xml.set_attribute( data_node, "expression", "@SOBJECT(sthpw/snapshot['project_code','%s'])" % project_code) xml.set_attribute(data_node, "search_type", "sthpw/snapshot") # dump the file entries data_node = xml.create_element("sobject") xml.append_child(manifest_node, data_node) xml.set_attribute( data_node, "expression", "@SOBJECT(sthpw/file['project_code','%s'])" % project_code) xml.set_attribute(data_node, "search_type", "sthpw/file") manifest = xml.to_string() # create a virtual plugin sobject from tactic.command import PluginCreator plugin = SearchType.create("config/plugin") plugin.set_value("version", version) plugin.set_value("code", "%s_project" % project_code) creator = PluginCreator(base_dir=tmp_dir, plugin=plugin, manifest=manifest, version=version) creator.execute() data_path = creator.get_zip_path() # move the files to the appropriate base_dir import shutil if not os.path.exists(base_dir): os.makedirs(base_dir) if os.path.exists(project_path): basename = os.path.basename(project_path) if os.path.exists("%s/%s" % (base_dir, basename)): os.unlink("%s/%s" % (base_dir, basename)) shutil.move(project_path, base_dir) if os.path.exists(data_path): basename = os.path.basename(data_path) if os.path.exists("%s/%s" % (base_dir, basename)): os.unlink("%s/%s" % (base_dir, basename)) shutil.move(data_path, base_dir) if os.path.exists(file_path): basename = os.path.basename(file_path) if os.path.exists("%s/%s" % (base_dir, basename)): os.unlink("%s/%s" % (base_dir, basename)) shutil.move(file_path, base_dir) shutil.rmtree(tmp_dir) my.handle_manifest(base_dir, project_code, version)
class PageNavContainerWdg(BaseRefreshWdg): def init(self): link = self.kwargs.get('link') hash = self.kwargs.get('hash') self.widget = None if link: from tactic.ui.panel import SideBarBookmarkMenuWdg personal = False if '.' in link: personal = True config = SideBarBookmarkMenuWdg.get_config("SideBarWdg", link, personal=personal) options = config.get_display_options(link) # this is vital for view saving element_name = link attr_dict = config.get_element_attributes(link) title = attr_dict.get('title') hash = "/tab/%s" % link config = ''' <config> <application> <element name="left_nav"> <display class="tactic.ui.panel.SideBarPanelWdg"> </display> </element> <element name="main_body"> <display class="tactic.ui.panel.HashPanelWdg"> <hash>%s</hash> <element_name>%s</element_name> <title>%s</title> </display> <web/> </element> </application> </config> ''' % (hash, element_name, title) elif hash: from tactic.ui.panel import HashPanelWdg self.widget = HashPanelWdg.get_widget_from_hash( hash, force_no_index=True) config = None else: security = Environment.get_security() start_link = security.get_start_link() if start_link: self.kwargs['link'] = start_link return self.init() # search for a defined welcome view search = Search("config/widget_config") search.add_filter("category", "top_layout") search.add_filter("view", "welcome") config_sobj = search.get_sobject() if config_sobj: config = config_sobj.get_value("config") else: config = WidgetSettings.get_value_by_key("top_layout") if not config: config = self.get_default_config() self.config_xml = Xml() self.config_xml.read_string(config) def get_default_config(self): use_sidebar = self.kwargs.get('use_sidebar') if use_sidebar == False: config = ''' <config> <application> <element name="main_body"> <display class="tactic.ui.startup.MainWdg"/> <web/> </element> </application> </config> ''' else: config = ''' <config> <application> <element name="left_nav"> <display class="tactic.ui.panel.SideBarPanelWdg"> <auto_size>True</auto_size> </display> </element> <element name="main_body"> <display class="tactic.ui.startup.MainWdg"/> <web/> </element> </application> </config> ''' return config def set_state(self, panel_name, widget_class, options, values): '''this is called by side_bar.js mostly''' # set the class name display_node = self.config_xml.get_node( "config/application/element[@name='%s']/display" % (panel_name)) self.config_xml.set_attribute(display_node, "class", widget_class) # remove all the old options #display_node = self.config_xml.get_node("config/application/element[@name='%s']/display" % panel_name ) for child_node in self.config_xml.get_children(display_node): self.config_xml.remove_child(display_node, child_node) # set the options for name, value in options.items(): node = self.config_xml.get_node( "config/application/element[@name='%s']/display/%s" % (panel_name, name)) if isinstance(value, basestring): #print("WARNING: set application: skipping [%s] with value [%s]" % (name, value)) #continue element = self.config_xml.create_text_element(name, value) self.config_xml.append_child(display_node, element) elif isinstance(value, dict): # if it is a dictionary # TODO: run recursively.. supports 2 level only now sub_element = self.config_xml.create_element(name) self.config_xml.append_child(display_node, element) for name2, value2 in value.items(): if isinstance(value2, dict): sub_element2 = self.config_xml.create_element(name2) self.config_xml.append_child(sub_element, sub_element2) for name3, value3 in value2.items(): element = self.config_xml.create_text_element( name3, value3) self.config_xml.append_child(sub_element2, element) else: element = self.config_xml.create_text_element( name2, value2) self.config_xml.append_child(sub_element, element) # web value node value_node = self.config_xml.get_node( "config/application/element[@name='%s']/web" % (panel_name)) if value_node != None: for child_node in self.config_xml.get_children(value_node): self.config_xml.remove_child(value_node, child_node) else: # create it value_node = self.config_xml.create_element('web') element_node = self.config_xml.get_node( "config/application/element[@name='%s']" % (panel_name)) self.config_xml.append_child(element_node, value_node) # set the values for name, value in values.items(): node = self.config_xml.get_node( "config/application/element[@name='%s']/web/%s" % (panel_name, name)) if not isinstance(value, basestring): print( "WARNING: set application: skipping [%s] with value [%s]" % (name, value)) continue element = self.config_xml.create_text_element(name, value) self.config_xml.append_child(value_node, element) WidgetSettings.set_key_values("top_layout", [self.config_xml.to_string()]) def get_state(self): return self.config_xml def get_side_bar_cache(self, left_nav_wdg): project = Project.get() project_code = project.get_code() # do it with sobject #key = "%s_side_bar" % project.get_code() #cache = Search.get("sthpw/widget_cache") #cache.add_filter("key", key) #sobject = cache.get_sobject() #value = sobject.get_value("cache") login = Environment.get_user_name() tmp_dir = "%s/cache/side_bar" % Environment.get_tmp_dir() filename = "%s__%s.html" % (project_code, login) path = "%s/%s" % (tmp_dir, filename) # use files import os if os.path.exists(path): f = open(path, "r") html = f.read() f.close() else: dirname = os.path.dirname(path) if not os.path.exists(dirname): os.makedirs(dirname) f = open(path, "w") html = left_nav_wdg.get_buffer_display() f.write(html) f.close() return html def get_display(self): is_admin_project = Project.get().is_admin() security = Environment.get_security() if is_admin_project and not security.check_access( "builtin", "view_site_admin", "allow"): return Error403Wdg() # create the elements config = WidgetConfig.get(xml=self.config_xml, view="application") left_nav_handler = config.get_display_handler("left_nav") left_nav_options = config.get_display_options("left_nav") view_side_bar = None if left_nav_handler: left_nav_wdg = Common.create_from_class_path( left_nav_handler, [], left_nav_options) # caching side_bar_cache = self.get_side_bar_cache(left_nav_wdg) else: view_side_bar = False # create the main table core_table = Table() core_table.add_tbody() core_table.set_style( "border: 0px; border-collapse: collapse; width: 100%;") # add a spacer row #spacer_tr = core_table.add_row() #spacer_tr.add_style("width: 100%") #td = core_table.add_cell() #td.set_style("min-height: 1px; height: 1px;") #core_table.add_cell() #core_table.add_cell() # determine if the side bar is visible if view_side_bar == None: view_side_bar = security.check_access("builtin", "view_side_bar", "allow", default='allow') # add the main cells tr, td = core_table.add_row_cell() td.add_style("padding: 0px") td.add_style("margin: 0px") # add the main resizable table from tactic.ui.container import ResizableTableWdg main_table = ResizableTableWdg() main_table.set_keep_table_size() main_table.add_style("width: 100%") td.add(main_table) left_nav_td = main_table.add_cell() if view_side_bar: left_nav_td.add_class("spt_panel") left_nav_td.add_style("padding: 0px") main_body_td = main_table.add_cell(resize=False) main_body_td.add_style("padding: 10px") main_body_td.set_style( "width: 100%; vertical-align: top; text-align: center; padding-top: 3px" ) if view_side_bar: left_nav_td.set_style("vertical-align: top") # create the left navigation panel left_nav_div = DivWdg() left_nav_td.add(left_nav_div) left_nav_div.set_id("side_bar") # add the detail to the panel left_nav_div.add_attr("spt_class_name", left_nav_handler) for name, value in left_nav_options.items(): left_nav_div.add_attr("spt_%s" % name, value) left_nav_div.add_style("max_width: 185px") left_nav_div.add_style("width: 185px") left_nav_div.add_style("text-align: right") left_nav_div.add_style("vertical-align: top") left_nav_div.add_style("overflow: hidden") left_nav_div.add_class("spt_resizable") side_bar_inner = DivWdg() left_nav_div.add(side_bar_inner) #side_bar_inner.add_style("padding-left: 1px") side_bar_inner.add_style("width: 100%") # add side bar to nav side_bar_inner.add(side_bar_cache) left_nav_div.add_style("border-style: solid") left_nav_div.add_style("border-width: 0px 1px 0px 0px") #left_nav_div.add_color("border-color", "border") left_nav_div.add_color("border-color", "border", -10) web = WebContainer.get_web() browser = web.get_browser() if browser in ['Qt', 'Webkit']: min_width = "1px" else: min_width = "0px" left_nav_div.add_behavior({ 'type': 'listen', 'event_name': 'side_bar|hide_now', 'min_width': min_width, 'cbjs_action': ''' var size = bvr.src_el.getSize(); bvr.src_el.setAttribute("spt_size", size.x); bvr.src_el.setStyle("width", bvr.min_width); ''' }) left_nav_div.add_behavior({ 'type': 'listen', 'event_name': 'side_bar|hide', 'min_width': min_width, 'cbjs_action': ''' var size = bvr.src_el.getSize(); bvr.src_el.setAttribute("spt_size", size.x); new Fx.Tween(bvr.src_el, {duration:'short'}).start('width', bvr.min_width); ''' }) left_nav_div.add_behavior({ 'type': 'listen', 'event_name': 'side_bar|show', 'min_width': min_width, 'cbjs_action': ''' var width = bvr.src_el.getAttribute("spt_size"); if (!width) { width = 185; } if (parseInt(width) < 5) { width = 185; } //bvr.src_el.setStyle("width", width + "px"); new Fx.Tween(bvr.src_el, {duration:'short'}).start('width', bvr.min_width, width+"px"); ''' }) left_nav_div.add_behavior({ 'type': 'listen', 'event_name': 'side_bar|toggle', 'cbjs_action': ''' var size = bvr.src_el.getSize(); if (size.x < 5) { spt.named_events.fire_event("side_bar|show", {} ); } else { spt.named_events.fire_event("side_bar|hide", {} ); } ''' }) # create the main body panel palette = WebContainer.get_palette() color = palette.color("background2") main_body_rounded = DivWdg() main_body_inner = main_body_rounded main_body_inner.add_style("min-height: 500px") # DEBREACATED """ # add a breadcrumb breadcrumb_wdg = DivWdg() # hide the breadcrumb breadcrumb_wdg.add_style("display", "none") Container.put("breadcrumb", breadcrumb_wdg) breadcrumb_wdg.set_id("breadcrumb") breadcrumb_wdg.add_style("text-align: left") breadcrumb_wdg.add_looks( "fnt_title_3" ) main_body_inner.add(breadcrumb_wdg) """ main_body_panel = DivWdg() main_body_panel.set_id("main_body") main_body_panel.add_class("spt_main_panel") main_body_inner.add(main_body_panel) tab = MainBodyTabWdg() main_body_panel.add(tab) # TEST: NEW LAYOUT if Config.get_value("install", "layout") == "fixed": main_body_panel.add_style("margin-top: 31px") main_body_rounded.add_color("background", "background") main_body_rounded.add_style("padding: 3px 0px 0px 0px") # add the content to the main body panel try: if self.widget: tab.add(self.widget) element_name = self.widget.get_name() else: main_body_handler = config.get_display_handler("main_body") main_body_options = config.get_display_options("main_body") element_name = main_body_options.get("element_name") title = main_body_options.get("title") main_body_content = Common.create_from_class_path( main_body_handler, [], main_body_options) # get the web values from top_layout main_body_values = config.get_web_options("main_body") web = WebContainer.get_web() if isinstance(main_body_values, dict): for name, value in main_body_values.items(): web.set_form_value(name, value) main_body_content.set_name(element_name) tab.add(main_body_content, element_name, title) self.set_as_panel(main_body_panel, class_name=main_body_handler, kwargs=main_body_options) main_body_panel.add_behavior({ 'type': 'load', 'element_name': element_name, 'cbjs_action': ''' if (spt.help) spt.help.set_view(bvr.element_name); ''' }) except Exception as e: # handle an error in the drawing buffer = self.get_buffer_on_exception() error_wdg = self.handle_exception(e) main_body_content = DivWdg() main_body_content.add(error_wdg) main_body_content = main_body_content.get_buffer_display() tab.add(main_body_content, element_name, title) # add the main container container_div = DivWdg() container_div.set_style("width: 100%;") # NOTE: the td should not be the sliding element! So we create a div inside the TD to be the sliding element main_body_div = DivWdg() main_body_div.set_id("horizontal_main_body_slider") main_body_div.add(main_body_inner) """ # get the global drag_ghost_div drag_ghost_div = self.get_drag_ghost_div() drag_ghost_div.set_id( "drag_ghost_copy" ) drag_ghost_div.add_class( "SPT_PUW" ) # make it a Page Utility Widget (now processed client side) drag_ghost_div.set_z_start( 400 ) """ from page_header_wdg import PageHeaderWdg header_panel = DivWdg() header_panel.set_id("main_header") header_panel.add_attr("spt_class_name", "tactic.ui.app.PageHeaderWdg") header_wdg = PageHeaderWdg() header_panel.add(header_wdg) container_div.add(header_panel.get_buffer_display()) main_body_dis = main_body_div.get_buffer_display() main_body_td.add(main_body_dis) container_div.add(core_table) #container_div.add( drag_ghost_div ) is_admin = False security = Environment.get_security() if security.check_access("builtin", "view_site_admin", "allow"): is_admin = True if is_admin: from quick_box_wdg import QuickBoxWdg quick_box = QuickBoxWdg() container_div.add(quick_box) container_div.add_behavior({ 'type': 'load', 'cbjs_action': ''' spt.named_events.fire_event("close_admin_bar"); ''' }) return container_div def handle_exception(self, e): '''The tab widget is a special widget concerning exceptions because it usually represents the outer skin of the content of the web page. The titles of the tab must be displayed in order for the site to remain functional in the case of an exception''' from pyasm.widget import ExceptionWdg widget = ExceptionWdg(e) self.error_wdg = Widget() self.error_wdg.add(widget) return self.error_wdg """ def get_drag_ghost_div(self): drag_ghost_div = HtmlElement.div() drag_ghost_div.set_attr( "id", "drag_ghost_copy" ) drag_ghost_div.set_attr( "element_copied", "_NONE_" ) drag_ghost_div.add_class( "REG_ID" ) drag_ghost_div.set_style("background: #393950; color: #c2c2c2; border: solid 1px black;' \ 'text-align: left; padding: 10px;', filter: alpha(opacity=60); " + "opacity: 0.6; position: absolute; display: none; left: 0px; top: 0px;" + " z-index: 110;" ) drag_ghost_div.add("Ghost Div") return drag_ghost_div """ def get_drag_div(self): drag_div = HtmlElement.div() drag_div.set_style( "position: absolute; left: 100px; top: 400px; min-width: 400px; width: 400px; " + "background-color: white; border: solid black;") drag_handle_div = HtmlElement.div() drag_handle_div.set_style( "cursor: default; background-color: gray; border-bottom: dotted black; " + "padding: 3px; font-family: sans-serif; font-weight: bold;") # NOTE: to specify behaviors on a widget, you can use the .add_behavior() method ... use one behavior # specification dictionary (hash) string per call to add_behavior (but you can add multiple # behaviors by making multiple calls to add_behavior) # drag_handle_div.add_behavior( "{type:'click', mouse_btn:'LMB', modkeys:'SHIFT', dst_el:'@.parentNode', " + "cbfn_action: spt.cb.change_color_action}") drag_handle_div.add_behavior( "{type:'drag', mouse_btn:'LMB', modkeys:'', src_el:'@.parentNode'}" ) drag_handle_div.add("Drag Handle -- click and drag me!") drag_div.add(drag_handle_div) drag_div.add( "<p>This is a draggable div ... click on the drag handle above and drag this thing around!</p>" ) return drag_div
def handle_basic_mode(self): doc = self.xml.create_doc("config") root = self.xml.get_root_node() db_columns = self.get_columns() if "code" in db_columns: columns = ["preview", "code"] elif "name" in db_columns: columns = ["preview", "name"] elif "id" in db_columns: columns = ["preview", "id"] table = self.xml.create_element("table") Xml.append_child(root, table) for column in ["preview", "code"]: element = self.xml.create_element("element") Xml.set_attribute(element, "name", column) Xml.append_child(table, element) # create the edit edit = self.xml.create_element("edit") Xml.append_child(root, edit) for column in ["preview", "code"]: element = self.xml.create_element("element") Xml.set_attribute(element, "name", column) Xml.append_child(edit, element) # create the manual publish view publish = self.xml.create_element("publish") Xml.append_child(root, publish) element = self.xml.create_element("element") Xml.set_attribute(element, "name", "image") Xml.append_child(publish, element) dis_element = self.xml.create_element("display") Xml.set_attribute(dis_element, "class", "ThumbInputWdg") act_element = self.xml.create_element("action") Xml.set_attribute(act_element, "class", "NullAction") Xml.append_child(element, dis_element) Xml.append_child(element, act_element) element = self.xml.create_element("element") Xml.set_attribute(element, "name", "publish_files") Xml.append_child(publish, element) dis_element = self.xml.create_element("display") Xml.set_attribute(dis_element, "class", "UploadWdg") # add options option = self.xml.create_text_element('names', 'publish_icon|publish_main') Xml.append_child(dis_element, option) option = self.xml.create_text_element('required', 'false|true') Xml.append_child(dis_element, option) act_element = self.xml.create_element("action") Xml.set_attribute(act_element, "class", "MultiUploadAction") # add options option = self.xml.create_text_element('names', 'publish_icon|publish_main') Xml.append_child(act_element, option) option = self.xml.create_text_element('types', 'icon_main|main') Xml.append_child(act_element, option) Xml.append_child(element, dis_element) Xml.append_child(element, act_element) value = self.xml.to_string() self.xml = Xml() self.xml.read_string(value)
def export_template(my): xml = Xml() my.xml = xml xml.create_doc("manifest") manifest_node = xml.get_root_node() # Old implementation. Code is now on the data node xml.set_attribute(manifest_node, "code", my.template_project_code) # dump the notification entries data_node = xml.create_element("data") xml.append_child(manifest_node, data_node) code_node = xml.create_element("code") xml.append_child(data_node, code_node) xml.set_node_value(code_node, my.template_project_code) version = my.kwargs.get("version") or "" version_node = xml.create_element("version") xml.append_child(data_node, version_node) xml.set_node_value(version_node, version) # dump the project entry data_node = xml.create_element("sobject") xml.append_child(manifest_node, data_node) xml.set_attribute(data_node, "expression", "@SOBJECT(sthpw/project['code','%s'])" % my.project_code) xml.set_attribute(data_node, "search_type", "sthpw/project") xml.set_attribute(data_node, "unique", "true") # dump the project_type entry data_node = xml.create_element("sobject") xml.append_child(manifest_node, data_node) xml.set_attribute(data_node, "expression", "@SOBJECT(sthpw/project['code','%s'].sthpw/project_type)" % my.project_code) xml.set_attribute(data_node, "search_type", "sthpw/project_type") xml.set_attribute(data_node, "unique", "true") # dump the schema entry data_node = xml.create_element("sobject") xml.append_child(manifest_node, data_node) xml.set_attribute(data_node, "expression", "@SOBJECT(sthpw/schema['code','%s'])" % my.project_code) xml.set_attribute(data_node, "search_type", "sthpw/schema") xml.set_attribute(data_node, "unique", "true") # find the project template search types namespace = my.project_type if not namespace or namespace == "default": namespace = my.project_code project_search_types = Search.eval("@GET(sthpw/search_object['namespace','%s'].search_type)" % namespace) #project_types = Search.eval("@GET(sthpw/search_object['namespace','%s'].search_type)" % my.project_code) # just dump the definition for data for search_type in project_search_types: data_node = xml.create_element("search_type") xml.append_child(manifest_node, data_node) xml.set_attribute(data_node, "code", search_type) search_types = [ "config/custom_script", "config/widget_config", "config/naming", "config/client_trigger", "config/process", "config/trigger", "config/url", #"config/ingest_rule", #"config/ingest_session", ] for search_type in search_types: data_node = xml.create_element("sobject") xml.append_child(manifest_node, data_node) xml.set_attribute(data_node, "search_type", search_type) # find the currval st_obj = SearchType.get(search_type) # have to call nextval() to initiate this sequence in the session in psql since Postgres 8.1 seq_id = SearchType.sequence_nextval(search_type) seq_id = SearchType.sequence_currval(search_type) seq_id -= 1 if seq_id > 0: SearchType.sequence_setval(search_type, seq_id) xml.set_attribute(data_node, "seq_max", seq_id) #xml.set_attribute(data_node, "path", "data.spt") # dump the login_groups entries data_node = xml.create_element("sobject") xml.append_child(manifest_node, data_node) xml.set_attribute(data_node, "expression", "@SOBJECT(sthpw/login_group['project_code','%s'])" % my.project_code) xml.set_attribute(data_node, "search_type", "sthpw/login_group") xml.set_attribute(data_node, "unique", "true") # dump the pipelines entries data_node = xml.create_element("sobject") xml.append_child(manifest_node, data_node) xml.set_attribute(data_node, "expression", "@SOBJECT(sthpw/pipeline['project_code','%s'])" % my.project_code) xml.set_attribute(data_node, "search_type", "sthpw/pipeline") xml.set_attribute(data_node, "unique", "true") # dump the notification entries data_node = xml.create_element("sobject") xml.append_child(manifest_node, data_node) xml.set_attribute(data_node, "expression", "@SOBJECT(sthpw/notification['project_code','%s'])" % my.project_code) xml.set_attribute(data_node, "search_type", "sthpw/notification") from plugin import PluginCreator creator = PluginCreator( base_dir=my.base_dir, manifest=xml.to_string(), force=True, version=version ) creator.execute() my.zip_path = creator.get_zip_path()
def execute(self): import datetime now = datetime.datetime.now() version = now.strftime("%Y%m%d_%H%M%S") project_code = self.kwargs.get("project_code") if project_code: project = Project.get_by_code(project_code) else: project = Project.get() project_code = project.get_code() server_code = self.kwargs.get("server") assert server_code if not isinstance(server_code, basestring): server_code = server_code.get_value("code") base_dir = self.kwargs.get('base_dir') ticket = Environment.get_ticket() tmp_dir = "%s/sync_%s" % (Environment.get_tmp_dir(), ticket) if not os.path.exists(tmp_dir): os.makedirs(tmp_dir) server = Search.get_by_code("sthpw/sync_server", server_code) if server.get_value("sync_mode") == "file": if not base_dir: base_dir = server.get_value("base_dir") else: raise Exception("sync mode [%s] not support" % sync_mode) # FIXME: not sure if this is valid anymore asset_dir = Environment.get_asset_dir() base_dir = "%s/_temp" % asset_dir # create the project template from tactic.command import ProjectTemplateCreatorCmd cmd = ProjectTemplateCreatorCmd(project_code=project_code, version=version, base_dir=tmp_dir) cmd.execute() project_path = cmd.get_zip_path() # create zip of the project files from pyasm.common import ZipUtil zip_util = ZipUtil() asset_dir = Environment.get_asset_dir() project_dir = "%s/%s" % (asset_dir, project_code) zip_dir = "%s/%s" % (tmp_dir, project_code) file_path = "%s-files-%s.zip" % (zip_dir, version) if os.path.exists(file_path): os.unlink(file_path) zip_util.zip_dir2(project_dir, zip_path=file_path) # create a manifest for all the data in the project. xml = Xml() self.xml = xml xml.create_doc("manifest") manifest_node = xml.get_root_node() xml.set_attribute(manifest_node, "code", "%s-data" % project_code) search_types = project.get_search_types() # just dump the data for search_type in search_types: data_node = xml.create_element("sobject") xml.append_child(manifest_node, data_node) xml.set_attribute(data_node, "search_type", search_type.get_value("search_type")) # dump the note entries data_node = xml.create_element("sobject") xml.append_child(manifest_node, data_node) xml.set_attribute(data_node, "expression", "@SOBJECT(sthpw/note['project_code','%s'])" % project_code) xml.set_attribute(data_node, "search_type", "sthpw/note") # dump the task entries data_node = xml.create_element("sobject") xml.append_child(manifest_node, data_node) xml.set_attribute(data_node, "expression", "@SOBJECT(sthpw/task['project_code','%s'])" % project_code) xml.set_attribute(data_node, "search_type", "sthpw/task") # dump the snapshot entries data_node = xml.create_element("sobject") xml.append_child(manifest_node, data_node) xml.set_attribute(data_node, "expression", "@SOBJECT(sthpw/snapshot['project_code','%s'])" % project_code) xml.set_attribute(data_node, "search_type", "sthpw/snapshot") # dump the file entries data_node = xml.create_element("sobject") xml.append_child(manifest_node, data_node) xml.set_attribute(data_node, "expression", "@SOBJECT(sthpw/file['project_code','%s'])" % project_code) xml.set_attribute(data_node, "search_type", "sthpw/file") manifest = xml.to_string() # create a virtual plugin sobject from tactic.command import PluginCreator plugin = SearchType.create("config/plugin") plugin.set_value("version", version) plugin.set_value("code", "%s_project" % project_code) creator = PluginCreator( base_dir=tmp_dir, plugin=plugin, manifest=manifest, version=version ) creator.execute() data_path = creator.get_zip_path() # move the files to the appropriate base_dir import shutil if not os.path.exists(base_dir): os.makedirs(base_dir) if os.path.exists(project_path): basename = os.path.basename(project_path) if os.path.exists("%s/%s" % (base_dir, basename)): os.unlink("%s/%s" % (base_dir, basename)) shutil.move(project_path, base_dir) if os.path.exists(data_path): basename = os.path.basename(data_path) if os.path.exists("%s/%s" % (base_dir, basename)): os.unlink("%s/%s" % (base_dir, basename)) shutil.move(data_path, base_dir) if os.path.exists(file_path): basename = os.path.basename(file_path) if os.path.exists("%s/%s" % (base_dir, basename)): os.unlink("%s/%s" % (base_dir, basename)) shutil.move(file_path, base_dir) shutil.rmtree(tmp_dir) self.handle_manifest(base_dir, project_code, version)
def set_attribute(my, name, value): return Xml.set_attribute(my.node, name, value)
def execute(self): mode = self.kwargs.get("mode") # modes are either naming based or file object based #mode = "naming" #mode = "file" assert mode in ['naming', 'file'] search_type = self.kwargs.get("search_type") search_keys = self.kwargs.get("search_keys") assert search_type or search_keys if search_type: print "@SOBJECT(%s)" % search_type sobjects = Search.eval("@SOBJECT(%s)" % search_type) else: sobjects = Search.get_by_search_keys(search_keys) if not sobjects: print "No sobjects to process" return snapshots = Search.eval("@SOBJECT(sthpw/snapshot)", sobjects) # set an arbitrary limit for now limit = 1000 base_dir = Environment.get_asset_dir() num_found = 0 errors = [] for i, snapshot in enumerate(snapshots): if i > limit: break print "Processing: %s of %s" % (i, len(snapshots)) file_types = snapshot.get_all_file_types() for file_type in file_types: files = snapshot.get_files_by_type(file_type) # FIXME: not sure why we have this limitation, although it is # a pretty rare occurance if len(files) > 1: raise Exception( "More than one file with type [%s] in snapshot [%s]" % (file_type, snapshot.get_code())) file = files[0] file_name = file.get_value("file_name") # check-in dir is not subject to changes in asset_dir checkin_dir = file.get_value("checkin_dir") old_path = "%s/%s" % (checkin_dir, file_name) try: if mode == "naming": # preallocated path is used to align a file to the # current naming convention # FIXME: # there is a behavior in naming to add "_web" and # "_icon" on the file name. In this case, we don't # want that, so ask for main if file_type in ['icon', 'web']: path = snapshot.get_preallocated_path( 'main', file_name) else: path = snapshot.get_preallocated_path( file_type, file_name) elif mode == "file": # relative_dir is used to align a file to the current # place pointed to by the "file" object relative_dir = file.get_value("relative_dir") path = "%s/%s/%s" % (base_dir, relative_dir, file_name) else: raise Exception("Invalid mode [%s]" % mode) except Exception as e: error = "Snapshot [%s] has an error getting preallocated path: [%s]" % ( snapshot.get_code(), e.message) errors.append(error) continue if old_path == path: continue num_found += 1 print("snapshot: ", snapshot.get_value("code")) print("old: ", old_path) print("new: ", path) print("-" * 20) new_dir = os.path.dirname(path) new_filename = os.path.basename(path) new_relative_dir = new_dir.replace(base_dir, '') new_relative_dir = new_relative_dir.strip("/") xml = snapshot.get_xml_value("snapshot") node = xml.get_node("snapshot/file[@type='%s']" % file_type) Xml.set_attribute(node, "name", new_filename) # update all of the file file.set_value("file_name", new_filename) file.set_value("checkin_dir", new_dir) file.set_value("relative_dir", new_relative_dir) snapshot.set_value("snapshot", xml.to_string()) dirname = os.path.dirname(path) if not os.path.exists(dirname): FileUndo.mkdir(dirname) exists = False if os.path.islink(old_path): exists = os.path.lexists(old_path) else: exists = os.path.exists(old_path) if not exists: print '... old does not exist' continue FileUndo.move(old_path, path) file.commit() snapshot.commit() # try to remove the old folder (if it's empty, it will be removed) dirname = os.path.dirname(old_path) while 1: try: os.rmdir(dirname) dirname = os.path.dirname(dirname) except: break if errors: print "Errors:" for error in errors: print error print "-" * 20 print "Found %s of %s snapshots which have paths different from naming" % ( num_found, len(snapshots))
def filter_sobject_handler(my, sobject): search_type = sobject.get_base_search_type() if search_type == 'sthpw/project': project = Project.get_by_code(my.project_code) if project: sobject.set_value("id", project.get_id() ) # change the code of the project sobject.set_value("code", my.project_code) title = Common.get_display_title(my.project_code) sobject.set_value("title", title) if my.is_template: sobject.set_value("is_template", True) else: sobject.set_value("is_template", False) elif search_type == 'sthpw/schema': sobject.set_value("code", my.project_code) elif search_type == 'sthpw/notification': sobject.set_value("project_code", my.project_code) sobject.set_value("code", "") elif search_type in ['sthpw/pipeline']: sobject.set_value("project_code", my.project_code) if my.template_project_code != my.project_code: # get the old code old_code = sobject.get_code() if old_code.startswith("%s/" % my.template_project_code): new_code = old_code.replace("%s/" % my.template_project_code, "%s/" % my.project_code) else: new_code = "%s/%s" % (my.project_code, old_code) sobject.set_value("code", new_code) elif search_type in ['sthpw/login_group']: sobject.set_value("project_code", my.project_code) if my.template_project_code != my.project_code: # get the old login_group for column in ['login_group', 'code']: old_code = sobject.get_value(column) if old_code.startswith("%s/" % my.template_project_code): new_code = old_code.replace("%s/" % my.template_project_code, "%s/" % my.project_code) else: new_code = "%s/%s" % (my.project_code, old_code) sobject.set_value(column, new_code) # go through the access rules and replace project access_rules = sobject.get_xml_value("access_rules") nodes = access_rules.get_nodes("rules/rule") for node in nodes: project_code = Xml.get_attribute(node, "project") if project_code and project_code != "*" and project_code == my.template_project_code: Xml.set_attribute(node, "project", my.project_code) sobject.set_value("access_rules", access_rules.to_string()) return sobject
def handle_basic_mode(my): doc = my.xml.create_doc("config") root = my.xml.get_root_node() db_columns = my.get_columns() if "code" in db_columns: columns = ["preview", "code"] elif "name" in db_columns: columns = ["preview", "name"] elif "id" in db_columns: columns = ["preview", "id"] table = my.xml.create_element("table") Xml.append_child(root, table) for column in ["preview", "code"]: element = my.xml.create_element("element") Xml.set_attribute(element, "name", column) Xml.append_child(table, element) # create the edit edit = my.xml.create_element("edit") Xml.append_child(root, edit) for column in ["preview", "code"]: element = my.xml.create_element("element") Xml.set_attribute(element, "name", column) Xml.append_child(edit, element) # create the manual publish view publish = my.xml.create_element("publish") Xml.append_child(root, publish) element = my.xml.create_element("element") Xml.set_attribute(element, "name", "image") Xml.append_child(publish, element) dis_element = my.xml.create_element("display") Xml.set_attribute(dis_element, "class", "ThumbInputWdg") act_element = my.xml.create_element("action") Xml.set_attribute(act_element, "class", "NullAction") Xml.append_child(element, dis_element) Xml.append_child(element, act_element) element = my.xml.create_element("element") Xml.set_attribute(element, "name", "publish_files") Xml.append_child(publish, element) dis_element = my.xml.create_element("display") Xml.set_attribute(dis_element, "class", "UploadWdg") # add options option = my.xml.create_text_element('names','publish_icon|publish_main') Xml.append_child(dis_element, option) option = my.xml.create_text_element('required','false|true') Xml.append_child(dis_element, option) act_element = my.xml.create_element("action") Xml.set_attribute(act_element, "class", "MultiUploadAction") # add options option = my.xml.create_text_element('names','publish_icon|publish_main') Xml.append_child(act_element, option) option = my.xml.create_text_element('types','icon_main|main') Xml.append_child(act_element, option) Xml.append_child(element, dis_element) Xml.append_child(element, act_element) value = my.xml.to_string() my.xml = Xml() my.xml.read_string(value)
def filter_sobject_handler(my, sobject): search_type = sobject.get_base_search_type() if search_type == 'sthpw/project': project = Project.get_by_code(my.project_code) if project: sobject.set_value("id", project.get_id()) # change the code of the project sobject.set_value("code", my.project_code) title = Common.get_display_title(my.project_code) sobject.set_value("title", title) if my.is_template: sobject.set_value("is_template", True) else: sobject.set_value("is_template", False) elif search_type == 'sthpw/schema': sobject.set_value("code", my.project_code) elif search_type == 'sthpw/notification': sobject.set_value("project_code", my.project_code) sobject.set_value("code", "") elif search_type in ['sthpw/pipeline']: sobject.set_value("project_code", my.project_code) if my.template_project_code != my.project_code: # get the old code old_code = sobject.get_code() if old_code.startswith("%s/" % my.template_project_code): new_code = old_code.replace( "%s/" % my.template_project_code, "%s/" % my.project_code) else: new_code = "%s/%s" % (my.project_code, old_code) sobject.set_value("code", new_code) elif search_type in ['sthpw/login_group']: sobject.set_value("project_code", my.project_code) if my.template_project_code != my.project_code: # get the old login_group for column in ['login_group', 'code']: old_code = sobject.get_value(column) if old_code.startswith("%s/" % my.template_project_code): new_code = old_code.replace( "%s/" % my.template_project_code, "%s/" % my.project_code) else: new_code = "%s/%s" % (my.project_code, old_code) sobject.set_value(column, new_code) # go through the access rules and replace project access_rules = sobject.get_xml_value("access_rules") nodes = access_rules.get_nodes("rules/rule") for node in nodes: project_code = Xml.get_attribute(node, "project") if project_code and project_code != "*" and project_code == my.template_project_code: Xml.set_attribute(node, "project", my.project_code) sobject.set_value("access_rules", access_rules.to_string()) return sobject
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 export_template(my): xml = Xml() my.xml = xml xml.create_doc("manifest") manifest_node = xml.get_root_node() # Old implementation. Code is now on the data node xml.set_attribute(manifest_node, "code", my.template_project_code) # dump the notification entries data_node = xml.create_element("data") xml.append_child(manifest_node, data_node) code_node = xml.create_element("code") xml.append_child(data_node, code_node) xml.set_node_value(code_node, my.template_project_code) version = my.kwargs.get("version") or "" version_node = xml.create_element("version") xml.append_child(data_node, version_node) xml.set_node_value(version_node, version) # dump the project entry data_node = xml.create_element("sobject") xml.append_child(manifest_node, data_node) xml.set_attribute( data_node, "expression", "@SOBJECT(sthpw/project['code','%s'])" % my.project_code) xml.set_attribute(data_node, "search_type", "sthpw/project") xml.set_attribute(data_node, "unique", "true") # dump the project_type entry data_node = xml.create_element("sobject") xml.append_child(manifest_node, data_node) xml.set_attribute( data_node, "expression", "@SOBJECT(sthpw/project['code','%s'].sthpw/project_type)" % my.project_code) xml.set_attribute(data_node, "search_type", "sthpw/project_type") xml.set_attribute(data_node, "unique", "true") # dump the schema entry data_node = xml.create_element("sobject") xml.append_child(manifest_node, data_node) xml.set_attribute( data_node, "expression", "@SOBJECT(sthpw/schema['code','%s'])" % my.project_code) xml.set_attribute(data_node, "search_type", "sthpw/schema") xml.set_attribute(data_node, "unique", "true") # find the project template search types namespace = my.project_type if not namespace or namespace == "default": namespace = my.project_code project_search_types = Search.eval( "@GET(sthpw/search_object['namespace','%s'].search_type)" % namespace) #project_types = Search.eval("@GET(sthpw/search_object['namespace','%s'].search_type)" % my.project_code) # just dump the definition for data for search_type in project_search_types: data_node = xml.create_element("search_type") xml.append_child(manifest_node, data_node) xml.set_attribute(data_node, "code", search_type) search_types = [ "config/custom_script", "config/widget_config", "config/naming", "config/client_trigger", "config/process", "config/trigger", "config/url", #"config/ingest_rule", #"config/ingest_session", ] for search_type in search_types: data_node = xml.create_element("sobject") xml.append_child(manifest_node, data_node) xml.set_attribute(data_node, "search_type", search_type) # find the currval st_obj = SearchType.get(search_type) # have to call nextval() to initiate this sequence in the session in psql since Postgres 8.1 seq_id = SearchType.sequence_nextval(search_type) seq_id = SearchType.sequence_currval(search_type) seq_id -= 1 if seq_id > 0: SearchType.sequence_setval(search_type, seq_id) xml.set_attribute(data_node, "seq_max", seq_id) #xml.set_attribute(data_node, "path", "data.spt") # dump the login_groups entries data_node = xml.create_element("sobject") xml.append_child(manifest_node, data_node) xml.set_attribute( data_node, "expression", "@SOBJECT(sthpw/login_group['project_code','%s'])" % my.project_code) xml.set_attribute(data_node, "search_type", "sthpw/login_group") xml.set_attribute(data_node, "unique", "true") # dump the pipelines entries data_node = xml.create_element("sobject") xml.append_child(manifest_node, data_node) xml.set_attribute( data_node, "expression", "@SOBJECT(sthpw/pipeline['project_code','%s'])" % my.project_code) xml.set_attribute(data_node, "search_type", "sthpw/pipeline") xml.set_attribute(data_node, "unique", "true") # dump the notification entries data_node = xml.create_element("sobject") xml.append_child(manifest_node, data_node) xml.set_attribute( data_node, "expression", "@SOBJECT(sthpw/notification['project_code','%s'])" % my.project_code) xml.set_attribute(data_node, "search_type", "sthpw/notification") from plugin import PluginCreator creator = PluginCreator(base_dir=my.base_dir, manifest=xml.to_string(), force=True, version=version) creator.execute() my.zip_path = creator.get_zip_path()