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 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 _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_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 _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 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 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 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 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()
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
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
class SObjectDefaultConfig(Base): '''An artificial config file is made if none are found''' def __init__(self, search_type, view, config_base=None, mode="columns"): self.search_type = search_type if view: self.view = view else: self.view = config_base if not self.view: self.view = "table" # bit of protection ... : have been known to show up in view names self.view = self.view.replace(":", '_') #mode = "basic" self.xml = Xml() if mode == 'columns': self.handle_columns_mode() else: self.handle_basic_mode() def get_columns(self, required_only=False): if self.search_type == 'sthpw/virtual': return [] search_type_obj = SearchType.get(self.search_type) table = search_type_obj.get_table() from pyasm.biz import Project db_resource = Project.get_db_resource_by_search_type(self.search_type) database_name = db_resource.get_database() db = DbContainer.get(db_resource) # table may not exist try: all_columns = db.get_columns(table) columns = [] if required_only: nullables = db.get_column_nullables(table) for column in all_columns: null_ok = nullables.get(column) if not null_ok: columns.append(column) # if there are no required columns if not columns: columns = all_columns else: columns = all_columns except SqlException: Environment.add_warning( 'missing table', 'Table [%s] does not exist in database [%s]' % (table, database_name)) return [] return columns 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 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 get_type(self, element_name): xpath = "config/%s/element[@name='%s']/@type" % (self.view, element_name) type = self.xml.get_value(xpath) if not type: xpath = "config/%s/element[@name='%s']/@type" % ("definition", element_name) type = self.xml.get_value(xpath) return type def get_xml(self): return self.xml
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)
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)
class SObjectDefaultConfig(Base): '''An artificial config file is made if none are found''' def __init__(self, search_type, view, config_base=None, mode="columns"): self.search_type = search_type if view: self.view = view else: self.view = config_base if not self.view: self.view = "table" # bit of protection ... : have been known to show up in view names self.view = self.view.replace(":", '_') #mode = "basic" self.xml = Xml() if mode == 'columns': self.handle_columns_mode() else: self.handle_basic_mode() def get_columns(self, required_only=False): if self.search_type == 'sthpw/virtual': return [] search_type_obj = SearchType.get(self.search_type) table = search_type_obj.get_table() from pyasm.biz import Project db_resource = Project.get_db_resource_by_search_type(self.search_type) database_name = db_resource.get_database() db = DbContainer.get(db_resource) # table may not exist try: all_columns = db.get_columns(table) columns = [] if required_only: nullables = db.get_column_nullables(table) for column in all_columns: null_ok = nullables.get(column) if not null_ok: columns.append(column) # if there are no required columns if not columns: columns = all_columns else: columns = all_columns except SqlException: Environment.add_warning('missing table', 'Table [%s] does not exist in database [%s]' %(table, database_name)) return [] return columns 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 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 get_type(self, element_name): xpath = "config/%s/element[@name='%s']/@type" % (self.view,element_name) type = self.xml.get_value(xpath) if not type: xpath = "config/%s/element[@name='%s']/@type" % ("definition",element_name) type = self.xml.get_value(xpath) return type def get_xml(self): return self.xml