def get_db_resource_by_search_type(cls, search_type): if search_type.startswith('sthpw/'): # get the local db_resource from pyasm.security import Site site = Site.get_site() db_resource = None if site: db_resource = Site.get_db_resource(site, "sthpw") if not db_resource: db_resource = DbResource.get_default("sthpw") return db_resource project_code = cls.get_database_by_search_type(search_type) project = Project.get_by_code(project_code) if not project: raise Exception("Error: Project [%s] does not exist" % project_code) if search_type.startswith("salesforce/"): db_resource_code = "Salesforce" db_resource = DbResource.get_by_code(db_resource_code, project_code) return db_resource db_resource = project.get_project_db_resource() return db_resource
def _do_execute(my): # restablish the site if my.site: Site.set_site(my.site) Environment.set_security(my.security) my.execute()
def execute(self): if not self.login_name: self.login_name = self.kwargs.get('login'); # invalidate the ticket security = Environment.get_security() ticket = security.get_ticket() if ticket == None: return login_name = ticket.get_value("login") print "Signing out: ", login_name # expire the ticket from pyasm.security import Site site = Site.get() if site: Site.set_site("default") try: from pyasm.search import Sql, DbContainer sql = DbContainer.get("sthpw") ticket.set_value("expiry", sql.get_timestamp_now(), quoted=False) ticket.commit() except: if site: Site.pop_site()
def error_page(my, status, message, traceback, version): # check if this project exists response = cherrypy.response request = cherrypy.request path = request.path_info parts = path.split("/") if len(parts) < 3: cherrypy.response.body = '<meta http-equiv="refresh" content="0;url=/tactic" />' return from pyasm.security import Site site_obj = Site.get() path_info = site_obj.break_up_request_path(path) if path_info: site = path_info['site'] project_code = path_info['project_code'] else: project_code = parts[2] site = "" # sites is already mapped in config for cherrypy if site == "plugins": return print "WARNING:" print " status: ", status print " message: ", message print " site: ", site print " project_code: ", project_code # Dump out the error has_site = False try: from pyasm.security import TacticInit TacticInit() Site.set_site(site) if site: eval("cherrypy.root.tactic.%s.%s" % (site, project_code)) else: eval("cherrypy.root.tactic.%s" % project_code) # if project_code is empty , it raises SyntaxError except (AttributeError, SyntaxError), e: print "WARNING: ", e has_project = False has_site = True
def get_default_project(cls): from pyasm.security import Site project = Site.get().get_default_project() if project: return project project = Config.get_value("install", "default_project") return project
def get_site_root(self): from pyasm.security import Site site = Site.get().get_site_root() if site: return site return "tactic"
def get_db_triggers(cls): site_triggers = Container.get(cls.KEY) if site_triggers == None: # find all of the triggers search = Search("sthpw/trigger") search.add_project_filter() site_triggers = search.get_sobjects() Container.put(cls.KEY, site_triggers) # find all of the project triggers from pyasm.biz import Project site = Site.get_site() project_code = Project.get_project_code() key = "%s:%s:%s" % (cls.KEY, project_code, site) project_triggers = Container.get(key) if project_triggers == None: if project_code not in ['admin','sthpw']: try: search = Search("config/trigger") project_triggers = search.get_sobjects() except SearchException as e: print("WARNING: ", e) project_triggers = [] else: project_triggers = [] Container.put(key, project_triggers) triggers = [] triggers.extend(site_triggers) triggers.extend(project_triggers) return triggers
def get_asset_dir(cls, file_object=None, alias=None): '''get base asset directory''' if file_object: alias = file_object.get_value('base_dir_alias') if not alias: alias = "default" from pyasm.security import Site asset_dir = Site.get().get_asset_dir(file_object=file_object,alias=alias) if asset_dir: return asset_dir alias_dict = cls.get_asset_dirs() asset_dir = alias_dict.get(alias) if not asset_dir: data_dir = Environment.get_data_dir() if data_dir: asset_dir = "%s/assets" % data_dir return asset_dir
def execute(my): if my.mode == 'basic': return # cache sthpw tables definitions from pyasm.security import Site site = Site.get_site() if site: key = "%s:sthpw_column_info" % site else: key = "sthpw_column_info" data = CacheContainer.get(key) if data == None: tables = ['project', 'search_object', 'login', 'login_group', 'login_in_group','snapshot','file','trigger','notification','ticket'] kwargs = { "key": key, "database": 'sthpw', "tables": tables, } cache = TableInfoCache( **kwargs ) # cache search object table search_type_cache = SearchTypeCache.get("sthpw/search_object") search_type_cache.build_cache_by_column("search_type") # cache login table search_type_cache = SearchTypeCache.get("sthpw/login") search_type_cache.build_cache_by_column("login") # cache login_group table search_type_cache = SearchTypeCache.get("sthpw/login_group") search_type_cache.build_cache_by_column("login_group")
def set_project(cls, project_code): '''This is kept here because everybody is used to using this''' security = Environment.get_security() # FIXME: # Because it is possible to call this before one is # logged in. This is required to see the login screen. from pyasm.security import get_security_version security_version = get_security_version() if security_version != 1 and not project_code == 'admin': key = { 'code': project_code } key2 = { 'code': "*" } keys = [key, key2] if not security.check_access("project", keys, access="allow", default="deny"): user = Environment.get_login() if user: user = user.get_value("login") raise SecurityException("User [%s] is not permitted to view project [%s]" % (user, project_code)) else: raise SecurityException("User is not permitted to view project [%s]" % (project_code)) from pyasm.security import Site site = Site.get_site() PROJECT_KEY = "Project:global:%s:" % site Container.put(PROJECT_KEY, project_code)
def get_display(self): web = WebContainer.get_web() response = web.get_response() # get info from url site_obj = Site.get() path = web.get_request_path() path_info = site_obj.break_up_request_path(path) site = path_info.get("site") project_code = path_info.get("project_code") # find the relative path hash = self.kwargs.get("hash") parts = hash[1:] rel_path = "/".join(parts) #rel_path = "asset/Fantasy/Castle/54d45150c61251f65687d716cc3951f1_v001.jpg" # construct all of the paths asset_dir = web.get_asset_dir() base_dir = "%s/%s" % (asset_dir, project_code) path = "%s/%s" % (base_dir, rel_path) filename = os.path.basename(rel_path) print "path: ", path # determine the mimetype automatically import mimetypes base, ext = os.path.splitext(path) ext = ext.lower() mimetype = mimetypes.types_map[ext] headers = response.headers response.headers['Content-Type'] = mimetype response.headers['Content-Disposition'] = 'inline; filename={0}'.format(filename) use_xsendfile = True if use_xsendfile: response.headers['X-Sendfile'] = path return Widget(path) else: response.headers['Content-Transfer-Encoding'] = 'BINARY' widget = Widget() f = open(path, 'rb') data = f.read() f.close() widget.add(data) return widget
def get_global_project_code(cls): from pyasm.security import Site site = Site.get_site() PROJECT_KEY = "Project:global:%s:" % site project_code = Container.get(PROJECT_KEY) if not project_code: project_code = "admin" Project.set_global_project_code(project_code) return project_code
def clear_db_cache(cls): Container.put(cls.KEY, None) site = Site.get_site() from pyasm.biz import Project project_code = Project.get_project_code() key = "%s:%s:%s" % (cls.KEY, project_code, site) Container.put(key, None)
def get_db_resource_by_search_type(cls, search_type): if search_type.startswith('sthpw/'): # get the local db_resource from pyasm.security import Site site = Site.get_site() db_resource = None if site: db_resource = Site.get_db_resource(site, "sthpw") if not db_resource: db_resource = DbResource.get_default("sthpw") return db_resource project_code = cls.get_database_by_search_type(search_type) project = Project.get_by_code(project_code) if not project: raise Exception("Error: Project [%s] does not exist" % project_code) db_resource = project.get_project_db_resource() return db_resource
def get_display(self): web = WebContainer.get_web() response = web.get_response() # get info from url site_obj = Site.get() path = web.get_request_path() path_info = site_obj.break_up_request_path(path) site = path_info.get("site") project_code = path_info.get("project_code") # find the relative path hash = self.kwargs.get("hash") parts = hash[1:] rel_path = "/".join(parts) #rel_path = "asset/Fantasy/Castle/54d45150c61251f65687d716cc3951f1_v001.jpg" # construct all of the paths asset_dir = web.get_asset_dir() base_dir = "%s/%s" % (asset_dir, project_code) path = "%s/%s" % (base_dir, rel_path) filename = os.path.basename(rel_path) print "path: ", path # determine the mimetype automatically import mimetypes base, ext = os.path.splitext(path) ext = ext.lower() mimetype = mimetypes.types_map[ext] headers = response.headers response.headers['Content-Type'] = mimetype response.headers[ 'Content-Disposition'] = 'inline; filename={0}'.format(filename) use_xsendfile = True if use_xsendfile: response.headers['X-Sendfile'] = path return Widget(path) else: response.headers['Content-Transfer-Encoding'] = 'BINARY' widget = Widget() f = open(path, 'rb') data = f.read() f.close() widget.add(data) return widget
def error_page(self, status, message, traceback, version): # check if this project exists response = cherrypy.response request = cherrypy.request path = request.path_info parts = path.split("/") if len(parts) < 3: cherrypy.response.body = '<meta http-equiv="refresh" content="0;url=/tactic" />' return from pyasm.security import Site site_obj = Site.get() path_info = site_obj.break_up_request_path(path) if path_info: site = path_info['site'] project_code = path_info['project_code'] else: project_code = parts[2] site = "" # sites is already mapped in config for cherrypy if site == "plugins": return has_site = False try: from pyasm.security import TacticInit TacticInit() Site.set_site(site) if site: eval("cherrypy.root.tactic.%s.%s" % (site, project_code)) else: eval("cherrypy.root.tactic.%s" % project_code) # if project_code is empty , it raises SyntaxError except (AttributeError, SyntaxError), e: print("WARNING: ", e) has_project = False has_site = True
def get_display(my): top = DivWdg() hash = my.kwargs.get("hash") Container.put("url_hash", hash) security = Environment.get_security() is_admin = security.check_access("builtin", "view_site_admin", "allow") if hash == "/admin" and not is_admin: hash = "/index" if not hash: # NOTE: this really doesn't get call anymore because an empty # hash gets remapped to "/index" widget = my.get_default_wdg() top.add(widget) # This would provide a way to get the default index widget. #elif hash == "/projects": # widget = my.get_default_wdg() # from tactic_sites.default.modules import IndexWdg # top.add( IndexWdg() ) else: from tactic.ui.panel import HashPanelWdg project_code = Project.get_project_code() if project_code == 'admin' and hash == '/index': widget = my.get_default_wdg() else: print "HASH: ", hash print "project: ", project_code from pyasm.security import Site print "site: ", Site.get_site() widget = HashPanelWdg.get_widget_from_hash(hash, return_none=True) if not widget: if hash == "/index": widget = my.get_default_wdg() elif hash == '/admin': widget = my.get_default_wdg() else: widget = HashPanelWdg.get_widget_from_hash("/index", return_none=True) top.add(widget) return top
def get_display(my): top = DivWdg() hash = my.kwargs.get("hash") Container.put("url_hash", hash) security = Environment.get_security() is_admin = security.check_access("builtin", "view_site_admin", "allow") if hash == "/admin" and not is_admin: hash = "/index" if not hash: # NOTE: this really doesn't get call anymore because an empty # hash gets remapped to "/index" widget = my.get_default_wdg() top.add(widget) # This would provide a way to get the default index widget. #elif hash == "/projects": # widget = my.get_default_wdg() # from tactic_sites.default.modules import IndexWdg # top.add( IndexWdg() ) else: from tactic.ui.panel import HashPanelWdg project_code = Project.get_project_code() if project_code == 'admin' and hash == '/index': widget = my.get_default_wdg() else: print "HASH: ", hash print "project: ", project_code from pyasm.security import Site print "site: ", Site.get_site() widget = HashPanelWdg.get_widget_from_hash(hash, return_none=True) if not widget: if hash == "/index": widget = my.get_default_wdg() elif hash == '/admin': widget = my.get_default_wdg() else: widget = HashPanelWdg.get_widget_from_hash( "/index", return_none=True) top.add(widget) return top
def index(my): # check if this project exists response = cherrypy.response request = cherrypy.request path = request.path_info from pyasm.security import Site default_project = Site.get().get_default_project() if not default_project: default_project = "admin" path = path.rstrip("/") path = "%s/%s" % (path, default_project) return '''<META http-equiv="refresh" content="0;URL=%s">''' % path
def __init__(my, **kwargs): my.kwargs = kwargs user = my.kwargs.get('user') project = my.kwargs.get('project') my.site = my.kwargs.get('site') if not my.site: # if not explicitly set, keep the site that is current my.site = Site.get_site() if user and project: from pyasm.security import Batch Batch(site=my.site, login_code=user, project_code=project) my.security = Environment.get_security()
def get_context_name(my): '''this includes all of the subdirectories as well as the main context''' path = my.get_request_path() p = re.compile( r"/(tactic|projects)/?(\w+)/") m = p.search(path) if not m: return "default" from pyasm.security import Site site_obj = Site.get() path_info = site_obj.break_up_request_path(path) if path_info: context = path_info.get("project_code") else: context = m.groups()[1] return context
def get_web_dir(cls, file_object=None, alias=None): '''get base web directory''' if file_object: alias = file_object.get_value('base_dir_alias') if not alias: alias = "default" from pyasm.security import Site site = Site.get() web_dir = site.get_web_dir(file_object=file_object, alias=alias) if web_dir: return web_dir alias_dict = cls.get_web_dirs() web_dir = alias_dict.get(alias) if not web_dir: web_dir = "/assets" return web_dir
def get_web_dir(cls, file_object=None, alias=None): '''get base web directory''' if file_object: alias = file_object.get_value('base_dir_alias') if not alias: alias = "default" from pyasm.security import Site site = Site.get() web_dir = site.get_web_dir(file_object=file_object,alias=alias) if web_dir: return web_dir alias_dict = cls.get_web_dirs() web_dir = alias_dict.get(alias) if not web_dir: web_dir = "/assets" return web_dir
def execute(my): if my.mode == 'basic': return # cache sthpw tables definitions from pyasm.security import Site site = Site() if site: key = "%s:sthpw_column_info" % site else: key = "sthpw_column_info" data = CacheContainer.get(key) if data == None: tables = [ 'project', 'search_object', 'login', 'login_group', 'login_in_group', 'snapshot', 'file', 'trigger', 'notification', 'ticket' ] kwargs = { "key": key, "database": 'sthpw', "tables": tables, } cache = TableInfoCache(**kwargs) # cache search object table search_type_cache = SearchTypeCache.get("sthpw/search_object") search_type_cache.build_cache_by_column("search_type") # cache login table search_type_cache = SearchTypeCache.get("sthpw/login") search_type_cache.build_cache_by_column("login") # cache login_group table search_type_cache = SearchTypeCache.get("sthpw/login_group") search_type_cache.build_cache_by_column("login_group")
def get_asset_dir(cls, file_object=None, alias=None): '''get base asset directory''' if file_object: alias = file_object.get_value('base_dir_alias') if not alias: alias = "default" from pyasm.security import Site asset_dir = Site.get().get_asset_dir(file_object=file_object, alias=alias) if asset_dir: return asset_dir alias_dict = cls.get_asset_dirs() asset_dir = alias_dict.get(alias) if not asset_dir: data_dir = Environment.get_data_dir() if data_dir: asset_dir = "%s/assets" % data_dir return asset_dir
def get_by_key(cls, key, search_type=None): from pyasm.security import Site site = Site.get_site() Site.set_site( Site.get_first_site() ) project = Project.get_project_code() dict_key = '%s:%s' %(key, search_type) search = Search(cls.SEARCH_TYPE, project_code=project) search.add_filter("key", key) if search_type: search.add_filter("search_type", search_type) if Project.get_project_name() in ['admin', 'sthpw']: return None prod_setting = ProdSetting.get_by_search(search, dict_key) Site.pop_site() return prod_setting
def get_by_key(cls, key, search_type=None): from pyasm.security import Site site = Site.get_site() Site.set_site(Site.get_first_site()) try: project = Project.get_project_code() dict_key = '%s:%s' % (key, search_type) search = Search(cls.SEARCH_TYPE, project_code=project) search.add_filter("key", key) if search_type: search.add_filter("search_type", search_type) if Project.get_project_name() in ['admin', 'sthpw']: return None prod_setting = ProdSetting.get_by_search(search, dict_key) finally: Site.pop_site() return prod_setting
class DeleteProjectToolWdg(DeleteToolWdg): # For now, project creation is not undoable def is_undoable(cls): return True is_undoable = classmethod(is_undoable) def get_related_types(my, search_type): # find all the relationships schema = Schema.get() related_types = schema.get_related_search_types(search_type) parent_type = schema.get_parent_type(search_type) child_types = schema.get_child_types(search_type) # some special considerations # FIXME: this needs to be more automatic. Should only be # deletable children (however, that will be defined) if search_type in ['sthpw/task', 'sthpw/note', 'sthpw/snapshot']: if "sthpw/project" in related_types: related_types.remove("sthpw/project") if "sthpw/login" in related_types: related_types.remove("sthpw/login") if "config/process" in related_types: related_types.remove("config/process") if parent_type in related_types: related_types.remove(parent_type) related_types.append('sthpw/note') related_types.append('sthpw/task') related_types.append('sthpw/snapshot') related_types.append('sthpw/work_hour') related_types.append('sthpw/pipeline') related_types.append('sthpw/sobject_list') return related_types def get_display(my): top = my.top top.add_color("background", "background") top.add_color("color", "color") top.add_style("width", "400px") top.add_border() top.add_class("spt_delete_project_tool_top") login = Environment.get_user_name() if login != 'admin': top.add(IconWdg(icon=IconWdg.WARNING)) top.add("Only Admin can delete projects") top.add_style("padding: 50px") top.add_style("text-align: center") return top site = my.kwargs.get("site") if site: Site.set_site(site) project_code = my.kwargs.get("project_code") # check if delete permissions exist for this site and project security = Environment.get_security() if False and not security.check_access("project", project_code, "delete"): top.add(IconWdg(icon=IconWdg.WARNING)) top.add("Not permitted to delete this project") top.add_style("padding: 30px") top.add_style("text-align: center") top.add_style("margin: 50px 30px") top.add_border() top.add_color("background", "background3") return top if project_code: project = Project.get_by_code(project_code) if not project: top.add(IconWdg(icon=IconWdg.WARNING)) top.add("No project [%s] exists in this database" % project_code) top.add_style("padding: 30px") top.add_style("text-align: center") top.add_style("margin: 50px 30px") top.add_border() top.add_color("background", "background3") return top search_key = project.get_search_key() else: search_key = my.kwargs.get("search_key") project = Search.get_by_search_key(search_key) if project: project_code = project.get_code() title_wdg = DivWdg() if project: top.add(title_wdg) title_wdg.add(IconWdg(icon=IconWdg.WARNING)) title_wdg.add("Deleting Project: %s" % project.get_value("title")) title_wdg.add_color("background", "background", -5) title_wdg.add_style("padding: 5px") title_wdg.add_style("font-weight: bold") title_wdg.add_style("font-size: 14px") content = DivWdg() top.add(content) content.add_style("padding: 10px") if not search_key: warning_msg = "Projects must be deleted individually" content.add(DivWdg(warning_msg, css='warning')) content.add("<br/>") return top warning_msg = "Deleting a project will delete the database associated with this project. All data and files will be lost. Please consider carefully before proceeding." if warning_msg: warning_wdg = DivWdg(warning_msg, css='warning') content.add(warning_wdg) warning_wdg.add_style("margin: 20 10px") content.add("<br/>") if not project_code: content.add("This project [%s] has been deleted." % search_key) return top elif not project: content.add("This project [%s] has been deleted." % project_code) return top assert project_code assert project content.add("<br/>") content.add( "<b>NOTE: These items will be deleted, but the sTypes entries in search_objects table will be retained.</b> " ) content.add("<br/>") content.add("<br/>") total_items_wdg = DivWdg() total_items = 0 content.add(total_items_wdg) # find all of the sTypes details_wdg = DivWdg() content.add(details_wdg) details_wdg.add_style("max-height: 300px") details_wdg.add_style("overflow-y: auto") details_wdg.add_style("padding-left: 15px") details_wdg.add_border() search_types = project.get_search_types() related_types = [] for search_type_obj in search_types: search_type_wdg = DivWdg() title = search_type_obj.get_title() search_type = search_type_obj.get_value("search_type") search_type_wdg.add_style("margin-top: 5px") search_type_wdg.add_style("margin-bottom: 5px") details_wdg.add(search_type_wdg) search_type_wdg.add(title) search_type_wdg.add(" (%s)" % search_type) search = Search(search_type, project_code=project_code) count = search.get_count() total_items += count search_type_wdg.add(" - %s item(s)" % count) # TODO: this is similar to SearchType.get_related_types(). streamline at some point. related_types = my.get_related_types(search_type) for related_type in related_types: try: search = Search(related_type) except Exception, e: print "WARNING: ", e continue full_search_type = "%s?project=%s" % (search_type, project_code) if related_type.startswith("sthpw/"): search.add_filter("search_type", full_search_type) count = search.get_count() if count == 0: continue total_items += count related_wdg = DivWdg() related_wdg.add_style('padding-left: 25px') search_type_wdg.add(related_wdg) related_wdg.add(related_type) related_wdg.add(" - %s item(s)" % count) if total_items: total_items_wdg.add("Total # of items to be deleted: ") total_items_wdg.add(total_items) total_items_wdg.add_style("font-size: 14px") total_items_wdg.add_style("font-weight: bold") total_items_wdg.add("<br/>") content.add("<br/>" * 2) content.add("<b>Do you wish to continue deleting? </b>") radio = RadioWdg("mode") radio.add_class("spt_mode_radio") radio.set_value("delete") radio.add_style("margin-left: 15") radio.add_style("margin-top: 5") content.add(radio) content.add("<br/>" * 3) #content.add("<b>Or do you just wish to retire the project? </b>") #radio = RadioWdg("mode") #radio.add_class("spt_mode_radio") #radio.set_value("retire") #content.add(radio) #content.add(radio) #content.add("<br/>"*2) #button = ActionButtonWdg(title="Retire") #content.add(button) #button.add_style("float: left") buttons = Table() content.add(buttons) buttons.add_row() buttons.add_style("margin-left: auto") buttons.add_style("margin-right: auto") buttons.add_style("width: 250px") button = ActionButtonWdg(title="Delete", color="danger") buttons.add_cell(button) command_class = my.kwargs.get("command_class") if not command_class: command_class = 'tactic.ui.tools.DeleteProjectCmd' on_complete = my.kwargs.get("on_complete") button.add_behavior({ 'type': 'click_up', #'search_type': search_type, 'project_code': project_code, 'site': site, 'related_types': related_types, 'command_class': command_class, 'on_complete': on_complete, 'cbjs_action': ''' spt.app_busy.show("Deleting"); var class_name = bvr.command_class; var kwargs = { 'site': bvr.site, 'project_code': bvr.project_code, 'related_types': bvr.related_types }; var top = bvr.src_el.getParent(".spt_delete_project_tool_top"); var radios = top.getElements(".spt_mode_radio"); //if (!radios[0].checked && !radios[1].checked) { if (!radios[0].checked) { spt.alert("Please confirm the delete by checking the radio button."); spt.app_busy.hide(); return; } var mode = 'retire'; if (radios[0].checked == true) { mode = 'delete'; } if (mode == 'retire') { return; } var success = false; var server = TacticServerStub.get(); setTimeout(function() { spt.app_busy.show("Deleting Project ["+bvr.project_code+"]") var error_message = "Error deleting project ["+bvr.project_code+"]"; try { server.start({'title': 'Deleted Project ', 'description': 'Deleted Project [' + bvr.project_code + ']'}); server.execute_cmd(class_name, kwargs); success = true; var top = bvr.src_el.getParent(".spt_popup"); spt.popup.destroy(top); server.finish(); } catch(e) { error_message = spt.exception.handler(e); } spt.app_busy.hide(); if (success) { if (bvr.on_complete) { on_complete = function() { eval(bvr.on_complete); } on_complete(); } spt.notify.show_message("Successfully deleted project ["+bvr.project_code+"]"); spt.tab.set_main_body_tab(); spt.tab.reload_selected(); } else { if (error_message.test(/does not exist/)) error_message += '. You are advised to sign out and log in again.'; spt.error(error_message); } }, 100); ''' }) button = ActionButtonWdg(title="Cancel") buttons.add_cell(button) button.add_behavior({ 'type': 'click_up', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_popup"); spt.popup.destroy(top); ''' }) if site: Site.pop_site() return top
def get_project_db_resource(my, database=None): # get the db resource for attached to this particular project. # Not the db_resource for "sthpw/project" for which # project.get_db_resource() does from pyasm.security import Site site = Site.get_site() if site: key = "Project:db_resource_cache:%s" % site else: key = "Project:db_resource_cache" resource_dict = Container.get(key) if resource_dict: resource = resource_dict.get(my.get_code()) if resource != None: return resource else: resource_dict = {} Container.put(key, resource_dict) # the project defines the resource if not database: database = my.get_database_name() assert database if database == 'sthpw': # get if from the config db_resource_code = None else: db_resource_code = my.get_value("db_resource", no_exception=True) if not db_resource_code: # this could be any project, not just sthpw # already looked at cache, so set use_cache to False db_resource = Site.get_db_resource(site, database) if not db_resource: db_resource = DbResource.get_default(database, use_cache=False) #db_resource = DbResource.get_default(database, use_cache=False) resource_dict[key] = db_resource return db_resource #elif isinstance(db_resource_code, DbResource): elif DbResource.is_instance(db_resource_code): db_resource = db_resource_code resource_dict[key] = db_resource return db_resource db_resource_code = db_resource_code.strip() search = Search("sthpw/db_resource") search.add_filter("code", db_resource_code) db_resource_sobj = search.get_sobject() if not db_resource_sobj: raise TacticException("Database Resource [%s] does not exist" % db_resource_code) host = db_resource_sobj.get_value("host") vendor = db_resource_sobj.get_value("vendor") host = db_resource_sobj.get_value("host") port = db_resource_sobj.get_value("port") user = db_resource_sobj.get_value("login") password = db_resource_sobj.get_value("password") db_resource = DbResource(user=user, database=database, host=host, port=port, vendor=vendor, password=password) #Container.put(key, db_resource) resource_dict[key] = db_resource return db_resource
def get_display(my): top = my.top top.add_color("background", "background") top.add_color("color", "color") top.add_style("width", "400px") top.add_border() top.add_class("spt_delete_project_tool_top") login = Environment.get_user_name() if login != 'admin': top.add(IconWdg(icon=IconWdg.WARNING)) top.add("Only Admin can delete projects") top.add_style("padding: 50px") top.add_style("text-align: center") return top site = my.kwargs.get("site") if site: Site.set_site(site) project_code = my.kwargs.get("project_code") # check if delete permissions exist for this site and project security = Environment.get_security() if False and not security.check_access("project", project_code, "delete"): top.add(IconWdg(icon=IconWdg.WARNING)) top.add("Not permitted to delete this project") top.add_style("padding: 30px") top.add_style("text-align: center") top.add_style("margin: 50px 30px") top.add_border() top.add_color("background", "background3") return top if project_code: project = Project.get_by_code(project_code) if not project: top.add(IconWdg(icon=IconWdg.WARNING)) top.add("No project [%s] exists in this database" % project_code) top.add_style("padding: 30px") top.add_style("text-align: center") top.add_style("margin: 50px 30px") top.add_border() top.add_color("background", "background3") return top search_key = project.get_search_key() else: search_key = my.kwargs.get("search_key") project = Search.get_by_search_key(search_key) if project: project_code = project.get_code() title_wdg = DivWdg() if project: top.add(title_wdg) title_wdg.add(IconWdg(icon=IconWdg.WARNING)) title_wdg.add("Deleting Project: %s" % project.get_value("title") ) title_wdg.add_color("background", "background", -5) title_wdg.add_style("padding: 5px") title_wdg.add_style("font-weight: bold") title_wdg.add_style("font-size: 14px") content = DivWdg() top.add(content) content.add_style("padding: 10px") if not search_key: warning_msg = "Projects must be deleted individually" content.add(DivWdg(warning_msg, css='warning')) content.add("<br/>") return top warning_msg = "Deleting a project will delete the database associated with this project. All data and files will be lost. Please consider carefully before proceeding." if warning_msg: warning_wdg = DivWdg(warning_msg, css='warning') content.add(warning_wdg) warning_wdg.add_style("margin: 20 10px") content.add("<br/>") if not project_code: content.add("This project [%s] has been deleted."%search_key) return top elif not project: content.add("This project [%s] has been deleted."%project_code) return top assert project_code assert project content.add("<br/>") content.add("<b>NOTE: These items will be deleted, but the sTypes entries in search_objects table will be retained.</b> ") content.add("<br/>") content.add("<br/>") total_items_wdg = DivWdg() total_items = 0 content.add(total_items_wdg) # find all of the sTypes details_wdg = DivWdg() content.add(details_wdg) details_wdg.add_style("max-height: 300px") details_wdg.add_style("overflow-y: auto") details_wdg.add_style("padding-left: 15px") details_wdg.add_border() search_types = project.get_search_types() related_types = [] for search_type_obj in search_types: search_type_wdg = DivWdg() title = search_type_obj.get_title() search_type = search_type_obj.get_value("search_type") search_type_wdg.add_style("margin-top: 5px") search_type_wdg.add_style("margin-bottom: 5px") details_wdg.add(search_type_wdg) search_type_wdg.add(title) search_type_wdg.add(" (%s)" % search_type ) search = Search( search_type, project_code=project_code ) count = search.get_count() total_items += count search_type_wdg.add(" - %s item(s)" % count) # TODO: this is similar to SearchType.get_related_types(). streamline at some point. related_types = my.get_related_types(search_type) for related_type in related_types: try: search = Search(related_type) except Exception, e: print "WARNING: ", e continue full_search_type = "%s?project=%s" % (search_type, project_code) if related_type.startswith("sthpw/"): search.add_filter("search_type", full_search_type) count = search.get_count() if count == 0: continue total_items += count related_wdg = DivWdg() related_wdg.add_style('padding-left: 25px') search_type_wdg.add(related_wdg) related_wdg.add(related_type) related_wdg.add(" - %s item(s)" % count)
def create_sobject_log(cls, log, transaction_data=None): if not transaction_data: transaction_data = log.get_value("transaction") # log a reference to each sobject affected already_logged = {} xml = Xml() xml.read_string(transaction_data) nodes = xml.get_nodes("transaction/*") # list of sobjects not logged not_logged = set([ 'sthpw/transaction_log', 'sthpw/clipboard', 'sthpw/sobject_log', 'sthpw/file', 'sthpw/message', 'sthpw/message_log', ]) find_parent = set([ 'sthpw/snapshot', 'sthpw/note', 'sthpw/task' ]) from pyasm.security import Site current_site = Site.get_site() for node in nodes: node_name = xml.get_node_name(node) if node_name == "sobject": search_type = Xml.get_attribute(node,"search_type") search_type_obj = SearchType.get(search_type) if search_type_obj.get_base_key() in not_logged: continue search_id = Xml.get_attribute(node,"search_id") search_code = Xml.get_attribute(node,"search_code") site = Xml.get_attribute(node,"site") if search_code: search_key = "%s?code=%s" % (search_type, search_code) else: search_key = "%s|%s" % (search_type, search_id) if already_logged.get(search_key): continue already_logged[search_key] = True # delete items are not presently logged ... # TODO: maybe they should be action = Xml.get_attribute(node,"action") if action == "delete": continue has_site = False if site: try: Site.set_site(site) has_site = True except: print "Site [%s] does not exist" % site continue try: if search_code: sobject = Search.get_by_code(search_type, search_code) else: sobject = Search.get_by_id(search_type, search_id) if sobject: SObjectLog.create(sobject, log, action) else: # record has been deleted if search_code: print("Skipped SObject log creation for [%s?code=%s]" %(search_type, search_code)) else: print("Skipped SObject log creation for [%s|%s]" %(search_type, search_id)) if search_type_obj.get_base_key() in find_parent: try: if sobject: sobject = sobject.get_parent() except (SearchException, SqlException): # don't worry if this parent can't be found. pass if sobject: SObjectLog.create(sobject, log, "child_%s" % action) finally: if has_site: Site.pop_site()
def get_default_project(cls): from pyasm.security import Site project = Site.get().get_default_project() return project
def add_top_behaviors(self): self.body.add_relay_behavior( { 'type': 'click', 'bvr_match_class': 'tactic_popup', 'cbjs_action': ''' var view = bvr.src_el.getAttribute("view"); if (!view) { spt.alert("No view found"); } var target = bvr.src_el.getAttribute("target"); var title = bvr.src_el.getAttribute("title"); var class_name = 'tactic.ui.panel.CustomLayoutWdg'; var kwargs = { view: view, } var attributes = bvr.src_el.attributes; for (var i = 0; i < attributes.length; i++) { var name = attributes[i].name; if (name == "class") { continue; } var value = attributes[i].value; kwargs[name] = value; } spt.panel.load_popup(title, class_name, kwargs); ''' } ) self.body.add_relay_behavior( { 'type': 'click', 'bvr_match_class': 'tactic_load', 'cbjs_action': ''' var view = bvr.src_el.getAttribute("view"); if (!view) { spt.alert("No view found"); } var target_class = bvr.src_el.getAttribute("target"); if (! target_class ) { target_class = "spt_content"; } if (target_class.indexOf(".") != "-1") { var parts = target_class.split("."); var top = bvr.src_el.getParent("."+parts[0]); var target = top.getElement("."+parts[1]); } else { var target = $(document.body).getElement("."+target_class); } var class_name = 'tactic.ui.panel.CustomLayoutWdg'; var kwargs = { view: view, } var attributes = bvr.src_el.attributes; for (var i = 0; i < attributes.length; i++) { var name = attributes[i].name; if (name == "class") { continue; } var value = attributes[i].value; kwargs[name] = value; } spt.panel.load(target, class_name, kwargs); var scroll = bvr.src_el.getAttribute("scroll"); if (scroll == "top") { window.scrollTo(0,0); } ''' } ) self.body.add_relay_behavior( { 'type': 'click', 'bvr_match_class': 'tactic_link', 'cbjs_action': ''' var href = bvr.src_el.getAttribute("href"); if (!href) { spt.alert("No href defined for this link"); return; } var target = bvr.src_el.getAttribute("target"); if (!target) { target = "_self"; } window.open(href, target); ''' } ) self.body.add_relay_behavior( { 'type': 'click', 'bvr_match_class': 'tactic_refresh', 'cbjs_action': ''' var target_class = bvr.src_el.getAttribute("target"); if (target_class.indexOf(".") != "-1") { var parts = target_class.split("."); var top = bvr.src_el.getParent("."+parts[0]); var target = top.getElement("."+parts[1]); } else { var target = $(document.body).getElement("."+target_class); } spt.panel.refresh(target); ''' } ) self.body.add_relay_behavior( { 'type': 'click', 'bvr_match_class': 'tactic_new_tab', 'cbjs_action': ''' var view = bvr.src_el.getAttribute("view") var search_key = bvr.src_el.getAttribute("search_key") var expression = bvr.src_el.getAttribute("expression") var name = bvr.src_el.getAttribute("name"); var title = bvr.src_el.getAttribute("title"); if (!name) { name = title; } if (!title) { title = name; } if (!title && !name) { title = name = "Untitled"; } if (expression) { var server = TacticServerStub.get(); var sss = server.eval(expression, {search_keys: search_key, single: true}) search_key = sss.__search_key__; } spt.tab.set_main_body_tab() if (view) { var cls = "tactic.ui.panel.CustomLayoutWdg"; var kwargs = { view: view } } else if (search_key) { var cls = "tactic.ui.tools.SObjectDetailWdg"; var kwargs = { search_key: search_key } } var attributes = bvr.src_el.attributes; for (var i = 0; i < attributes.length; i++) { var attr_name = attributes[i].name; if (attr_name == "class") { continue; } var value = attributes[i].value; kwargs[attr_name] = value; } try { spt.tab.add_new(name, title, cls, kwargs); } catch(e) { spt.alert(e); } ''' } ) self.body.add_relay_behavior( { 'type': 'click', 'bvr_match_class': 'tactic_submit', 'cbjs_action': ''' var command = bvr.src_el.getAttribute("command"); var kwargs = { } var server = TacticServerStub.get(); try { server.execute_cmd(command, kwargs); } catch(e) { spt.alert(e); } ''' } ) self.body.add_relay_behavior( { 'type': 'mouseenter', 'bvr_match_class': 'tactic_hover', 'cbjs_action': ''' var bgcolor = bvr.src_el.getStyle("background"); bvr.src_el.setAttribute("spt_bgcolor", bgcolor); bvr.src_el.setStyle("background", "#EEE"); ''' } ) self.body.add_relay_behavior( { 'type': 'mouseleave', 'bvr_match_class': 'tactic_hover', 'cbjs_action': ''' var bgcolor = bvr.src_el.getAttribute("spt_bgcolor"); if (!bgcolor) bgcolor = ""; //var bgcolor = "" bvr.src_el.setStyle("background", bgcolor); ''' } ) self.body.set_unique_id() self.body.add_smart_style( "tactic_load", "cursor", "pointer" ) # check version of the database project = Project.get() version = project.get_value("last_version_update") release = Environment.get_release_version() #if version < release: # FIXME: can't do this ... TACTIC cannot be running when the database # is upgrading. if False: try: from pyasm.security import Site site = Site.get_site() install_dir = Environment.get_install_dir() cmd = '''python "%s/src/bin/upgrade_db.py" -f -s "%s" --quiet --yes &''' % (install_dir, site) print("cmd: ", cmd) os.system(cmd) pass except Exception as e: print("WARNING: ", e)
def setup_sites(my): context_path = "%s/src/context" % my.install_dir doc_dir = "%s/doc" % my.install_dir plugin_dir = Environment.get_plugin_dir() builtin_plugin_dir = Environment.get_builtin_plugin_dir() dist_dir = Environment.get_dist_dir() log_dir = "%s/log" % Environment.get_tmp_dir() def CORS(): #cherrypy.response.headers["Access-Control-Allow-Origin"] = "http://192.168.0.15:8100" cherrypy.response.headers["Access-Control-Allow-Origin"] = "*" cherrypy.response.headers["Access-Control-Allow-Headers"] = "Origin, X-Requested-With, Content-Type, Accept" cherrypy.tools.CORS = cherrypy.Tool('before_handler', CORS) config = { 'global': { 'server.socket_host': '127.0.0.1', 'server.socket_port': 80, 'log.screen': False, 'request.show_tracebacks': True, 'tools.log_headers.on': True, 'server.log_file': "%s/tactic_log" % log_dir, 'server.max_request_body_size': 0, #'server.socket_timeout': 60, 'response.timeout': 3600, 'tools.encode.on': True, 'tools.encode.encoding': 'utf-8', 'tools.decode.on': True, 'tools.decode.encoding': 'utf-8', #'encoding_filter.on': True, #'decoding_filter.on': True 'tools.CORS.on': True }, '/context': {'tools.staticdir.on': True, 'tools.staticdir.dir': context_path, # Need to do this because on windows servers, jar files # are served as text/html 'tools.staticdir.content_types': { 'jar': 'application/java-archive' } }, '/assets': {'tools.staticdir.on': True, 'tools.staticdir.dir': Environment.get_asset_dir() }, '/doc': {'tools.staticdir.on': True, 'tools.staticdir.dir': doc_dir, 'tools.staticdir.index': "index.html" }, # NOTE: expose the entire plugins directory '/tactic/plugins': { 'tools.staticdir.on': True, 'tools.staticdir.dir': plugin_dir, }, '/tactic/builtin_plugins': { 'tools.staticdir.on': True, 'tools.staticdir.dir': builtin_plugin_dir, }, '/tactic/dist': { 'tools.staticdir.on': True, 'tools.staticdir.dir': dist_dir, }, '/plugins': { 'tools.staticdir.on': True, 'tools.staticdir.dir': plugin_dir, }, '/builtin_plugins': { 'tools.staticdir.on': True, 'tools.staticdir.dir': builtin_plugin_dir, }, '/dist': { 'tools.staticdir.on': True, 'tools.staticdir.dir': dist_dir, }, } # set up the root directory cherrypy.root = Root() cherrypy.tree.mount( cherrypy.root, config=config) from pyasm.search import Search search = Search("sthpw/project") search.add_filter("type", "resource", op="!=") projects = search.get_sobjects() # find out if one of the projects is the root root_initialized = False if not root_initialized: project_code = Project.get_default_project() if project_code and project_code !='default': from tactic.ui.app import SitePage cherrypy.root.tactic = SitePage(project_code) cherrypy.root.projects = SitePage(project_code) root_initialized = True if not root_initialized: # load in the base site at root from tactic_sites.default.context.Index import Index cherrypy.root.tactic = Index() cherrypy.root.projects = Index() for project in projects: project_code = project.get_code() my.register_project(project_code, config) my.register_project("default", config) print from pyasm.security import Site site_obj = Site.get() site_obj.register_sites(my, config) #my.register_project("vfx", config, site="vfx_demo") #my.register_project("default", config, site="vfx_demo") return config
def get_display(self): top = self.top top.add_color("background", "background") top.add_color("color", "color") top.add_style("width", "400px") top.add_border() top.add_class("spt_delete_project_tool_top") site = self.kwargs.get("site") set_site = self.kwargs.get("set_site") if set_site != False and site: Site.set_site(site) login = Environment.get_user_name() security = Environment.get_security() if not security.is_admin() and not security.is_in_group(self.delete_group): top.add(IconWdg(icon=IconWdg.WARNING)) top.add("Only Admin can delete projects") top.add_style("padding: 50px") top.add_style("text-align: center") if set_site and site: Site.pop_site() return top project_code = self.kwargs.get("project_code") # check if delete permissions exist for this site and project security = Environment.get_security() if False and not security.check_access("project", project_code, "delete"): top.add(IconWdg(icon=IconWdg.WARNING)) top.add("Not permitted to delete this project") top.add_style("padding: 30px") top.add_style("text-align: center") top.add_style("margin: 50px 30px") top.add_border() top.add_color("background", "background3") return top if project_code: project = Project.get_by_code(project_code) if not project: top.add(IconWdg(icon=IconWdg.WARNING)) top.add("No project [%s] exists in this database" % project_code) top.add_style("padding: 30px") top.add_style("text-align: center") top.add_style("margin: 50px 30px") top.add_border() top.add_color("background", "background3") return top search_key = project.get_search_key() else: search_key = self.kwargs.get("search_key") project = Search.get_by_search_key(search_key) if project: project_code = project.get_code() title_wdg = DivWdg() if project: top.add(title_wdg) title_wdg.add(IconWdg(icon=IconWdg.WARNING)) title_wdg.add("Deleting Project: %s" % project.get_value("title") ) title_wdg.add_color("background", "background", -5) title_wdg.add_style("padding: 5px") title_wdg.add_style("font-weight: bold") title_wdg.add_style("font-size: 14px") content = DivWdg() top.add(content) content.add_style("padding: 10px") if not search_key: warning_msg = "Projects must be deleted individually" content.add(DivWdg(warning_msg, css='warning')) content.add("<br/>") return top warning_msg = "Deleting a project will delete the database associated with this project. All data and files will be lost. Please consider carefully before proceeding." if warning_msg: warning_wdg = DivWdg(warning_msg, css='warning') content.add(warning_wdg) warning_wdg.add_style("margin: 20 10px") content.add("<br/>") if not project_code: content.add("This project [%s] has been deleted."%search_key) return top elif not project: content.add("This project [%s] has been deleted."%project_code) return top assert project_code assert project content.add("<br/>") content.add("<b>NOTE: These items will be deleted, but the sTypes entries in search_objects table will be retained.</b> ") content.add("<br/>") content.add("<br/>") total_items_wdg = DivWdg() total_items = 0 content.add(total_items_wdg) # find all of the sTypes details_wdg = DivWdg() content.add(details_wdg) details_wdg.add_style("max-height: 300px") details_wdg.add_style("overflow-y: auto") details_wdg.add_style("padding-left: 15px") details_wdg.add_border() search_types = project.get_search_types() related_types = [] for search_type_obj in search_types: search_type_wdg = DivWdg() title = search_type_obj.get_title() search_type = search_type_obj.get_value("search_type") search_type_wdg.add_style("margin-top: 5px") search_type_wdg.add_style("margin-bottom: 5px") details_wdg.add(search_type_wdg) search_type_wdg.add(title) search_type_wdg.add(" (%s)" % search_type ) search = Search( search_type, project_code=project_code ) count = search.get_count() total_items += count search_type_wdg.add(" - %s item(s)" % count) # TODO: this is similar to SearchType.get_related_types(). streamline at some point. related_types = self.get_related_types(search_type) for related_type in related_types: try: search = Search(related_type) except Exception as e: print("WARNING: ", e) continue full_search_type = "%s?project=%s" % (search_type, project_code) if related_type.startswith("sthpw/"): search.add_filter("search_type", full_search_type) count = search.get_count() if count == 0: continue total_items += count related_wdg = DivWdg() related_wdg.add_style('padding-left: 25px') search_type_wdg.add(related_wdg) related_wdg.add(related_type) related_wdg.add(" - %s item(s)" % count) if total_items: total_items_wdg.add("Total # of items to be deleted: ") total_items_wdg.add(total_items) total_items_wdg.add_style("font-size: 14px") total_items_wdg.add_style("font-weight: bold") total_items_wdg.add("<br/>") content.add("<br/>"*2) content.add("<b>Do you wish to continue deleting? </b>") radio = RadioWdg("mode") radio.add_class("spt_mode_radio") radio.set_value("delete") radio.add_style("margin-left: 15") radio.add_style("margin-top: 5") content.add(radio) content.add("<br/>"*3) #content.add("<b>Or do you just wish to retire the project? </b>") #radio = RadioWdg("mode") #radio.add_class("spt_mode_radio") #radio.set_value("retire") #content.add(radio) #content.add(radio) #content.add("<br/>"*2) #button = ActionButtonWdg(title="Retire") #content.add(button) #button.add_style("float: left") buttons = Table() content.add(buttons) buttons.add_row() buttons.add_style("margin-left: auto") buttons.add_style("margin-right: auto") buttons.add_style("width: 250px") button = ActionButtonWdg(title="Delete", color="danger") buttons.add_cell(button) command_class = self.kwargs.get("command_class") if not command_class: command_class = 'tactic.ui.tools.DeleteProjectCmd' on_complete = self.kwargs.get("on_complete") button.add_behavior( { 'type': 'click_up', #'search_type': search_type, 'project_code': project_code, 'site': site, 'related_types': related_types, 'command_class': command_class, 'on_complete': on_complete, 'cbjs_action': ''' spt.app_busy.show("Deleting"); var class_name = bvr.command_class; var kwargs = { 'site': bvr.site, 'project_code': bvr.project_code, 'related_types': bvr.related_types }; var top = bvr.src_el.getParent(".spt_delete_project_tool_top"); var radios = top.getElements(".spt_mode_radio"); //if (!radios[0].checked && !radios[1].checked) { if (!radios[0].checked) { spt.alert("Please confirm the delete by checking the radio button."); spt.app_busy.hide(); return; } var mode = 'retire'; if (radios[0].checked == true) { mode = 'delete'; } if (mode == 'retire') { return; } var success = false; var server = TacticServerStub.get(); setTimeout(function() { spt.app_busy.show("Deleting Project ["+bvr.project_code+"]") var error_message = "Error deleting project ["+bvr.project_code+"]"; try { server.start({'title': 'Deleted Project ', 'description': 'Deleted Project [' + bvr.project_code + ']'}); server.execute_cmd(class_name, kwargs); success = true; } catch(e) { error_message = spt.exception.handler(e); } spt.app_busy.hide(); if (success) { if (bvr.on_complete) { on_complete = function() { eval(bvr.on_complete); } on_complete(); } spt.notify.show_message("Successfully deleted project ["+bvr.project_code+"]"); spt.tab.set_main_body_tab(); spt.tab.reload_selected(); } else { if (error_message.test(/does not exist/)) error_message += '. You are advised to sign out and log in again.'; spt.error(error_message); } var top = bvr.src_el.getParent(".spt_popup"); spt.popup.destroy(top); server.finish(); }, 100); ''' } ) button = ActionButtonWdg(title="Cancel") buttons.add_cell(button) button.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_popup"); spt.popup.destroy(top); ''' } ) if site: Site.pop_site() return top
def get_project_db_resource(my, database=None): # get the db resource for attached to this particular project. # Not the db_resource for "sthpw/project" for which # project.get_db_resource() does from pyasm.security import Site site = Site.get_site() if site: key = "Project:db_resource_cache:%s" % site else: key = "Project:db_resource_cache" resource_dict = Container.get(key) if resource_dict: resource = resource_dict.get( my.get_code() ) if resource != None: return resource else: resource_dict = {} Container.put(key, resource_dict) # the project defines the resource if not database: database = my.get_database_name() assert database if database == 'sthpw': # get if from the config db_resource_code = None else: db_resource_code = my.get_value("db_resource", no_exception=True) if not db_resource_code: # this could be any project, not just sthpw # already looked at cache, so set use_cache to False db_resource = Site.get_db_resource(site, database) if not db_resource: db_resource = DbResource.get_default(database, use_cache=False) #db_resource = DbResource.get_default(database, use_cache=False) resource_dict[key] = db_resource return db_resource #elif isinstance(db_resource_code, DbResource): elif DbResource.is_instance(db_resource_code): db_resource = db_resource_code resource_dict[key] = db_resource return db_resource db_resource_code = db_resource_code.strip() search = Search("sthpw/db_resource") search.add_filter("code", db_resource_code) db_resource_sobj = search.get_sobject() if not db_resource_sobj: raise TacticException("Database Resource [%s] does not exist" % db_resource_code) host = db_resource_sobj.get_value("host") vendor = db_resource_sobj.get_value("vendor") host = db_resource_sobj.get_value("host") port = db_resource_sobj.get_value("port") user = db_resource_sobj.get_value("login") password = db_resource_sobj.get_value("password") db_resource = DbResource(user=user, database=database, host=host, port=port, vendor=vendor, password=password) #Container.put(key, db_resource) resource_dict[key] = db_resource return db_resource
def get_display(my): web = WebContainer.get_web() widget = Widget() html = HtmlElement("html") is_xhtml = False if is_xhtml: web.set_content_type("application/xhtml+xml") widget.add('''<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> ''') html.add_attr("xmlns", "http://www.w3.org/1999/xhtml") #html.add_attr("xmlns:svg", "http://www.w3.org/2000/svg") # add the copyright widget.add(my.get_copyright_wdg()) widget.add(html) # create the header head = HtmlElement("head") html.add(head) head.add( '<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>\n' ) head.add('<meta http-equiv="X-UA-Compatible" content="IE=edge"/>\n') # Add the tactic favicon head.add( '<link rel="shortcut icon" href="/context/favicon.ico" type="image/x-icon"/>' ) # add the css styling head.add(my.get_css_wdg()) # add the title in the header project = Project.get() project_code = project.get_code() project_title = project.get_value("title") if web.is_admin_page(): is_admin = " - Admin" else: is_admin = "" if project_code == 'admin': head.add("<title>TACTIC Site Admin</title>\n") else: head.add("<title>%s%s</title>\n" % (project_title, is_admin)) # add the javascript libraries head.add(JavascriptImportWdg()) # add the body body = my.body html.add(body) body.add_event('onload', 'spt.onload_startup(this)') top = my.top # Add a NOSCRIPT tag block here to provide a warning message on browsers where 'Enable JavaScript' # is not checked ... TODO: clean up and re-style to make look nicer top.add(""" <NOSCRIPT> <div style="border: 2px solid black; background-color: #FFFF99; color: black; width: 600px; height: 70px; padding: 20px;"> <img src="%s" style="border: none;" /> <b>Javascript is not enabled on your browser!</b> <p>This TACTIC powered, web-based application requires JavaScript to be enabled in order to function. In your browser's options/preferences, please make sure that the 'Enable JavaScript' option is checked on, click OK to accept the settings change, and then refresh this web page.</p> </div> </NOSCRIPT> """ % (IconWdg.get_icon_path("ERROR"))) # add the content content_div = DivWdg() top.add(content_div) Container.put("TopWdg::content", content_div) # add a dummy button for global behaviors from tactic.ui.widget import ButtonNewWdg, IconButtonWdg ButtonNewWdg(title="DUMMY", icon=IconWdg.FILM) IconButtonWdg(title="DUMMY", icon=IconWdg.FILM) # NOTE: it does not need to be in the DOM. Just needs to be # instantiated #content_div.add(button) if my.widgets: content_wdg = my.get_widget('content') else: content_wdg = Widget() my.add(content_wdg) content_div.add(content_wdg) # add a calendar wdg from tactic.ui.widget import CalendarWdg cal_wdg = CalendarWdg(css_class='spt_calendar_template_top') cal_wdg.top.add_style('display: none') content_div.add(cal_wdg) if web.is_admin_page(): from tactic_branding_wdg import TacticCopyrightNoticeWdg branding = TacticCopyrightNoticeWdg(show_license_info=True) top.add(branding) # add the admin bar security = Environment.get_security() if not web.is_admin_page() and security.check_access( "builtin", "view_site_admin", "allow"): div = DivWdg() top.add(div) top.add_style("padding-top: 21px") div.add_class("spt_admin_bar") # home icon_div = DivWdg() div.add(icon_div) icon_div.add_style("float: left") icon_div.add_style("margin-right: 10px") icon_div.add_style("margin-top: -3px") icon_button = IconButtonWdg(title="Home", icon="BS_HOME") icon_div.add(icon_button) icon_button.add_behavior({ 'type': 'click_up', 'cbjs_action': ''' window.location.href="/"; ''' }) div.add_style("height: 15px") div.add_style("padding: 3px 0px 3px 15px") #div.add_style("margin-bottom: -5px") div.add_style("position: fixed") div.add_style("top: 0px") div.add_style("left: 0px") div.add_style("opacity: 0.7") div.add_style("width: 100%") #div.add_gradient("background", "background2", 20, 10) div.add_style("background-color", "#000") div.add_style("color", "#FFF") div.add_style("z-index", "1000") div.add_class("hand") div.set_box_shadow("0px 5px 5px") # remove icon_div = DivWdg() div.add(icon_div) icon_div.add_style("float: right") icon_div.add_style("margin-right: 10px") icon_div.add_style("margin-top: -3px") icon_button = IconButtonWdg(title="Remove Admin Bar", icon="BS_REMOVE") icon_div.add(icon_button) icon_button.add_behavior({ 'type': 'click_up', 'cbjs_action': ''' var parent = bvr.src_el.getParent(".spt_admin_bar"); bvr.src_el.getParent(".spt_top").setStyle("padding-top", "0px"); spt.behavior.destroy_element(parent); ''' }) # sign-out icon_div = DivWdg() div.add(icon_div) icon_div.add_style("float: right") icon_div.add_style("margin-right: 5px") icon_div.add_style("margin-top: -3px") icon_button = IconButtonWdg(title="Sign Out", icon="BS_LOG_OUT") icon_div.add(icon_button) icon_button.add_behavior({ 'type': 'click_up', 'cbjs_action': ''' var ok = function(){ var server = TacticServerStub.get(); server.execute_cmd("SignOutCmd", {login: bvr.login} ); window.location.href="/"; } spt.confirm("Are you sure you wish to sign out?", ok ) ''' }) div.add("<b>ADMIN >></b>") div.add_behavior({ 'type': 'listen', 'event_name': 'close_admin_bar', 'cbjs_action': ''' bvr.src_el.getParent(".spt_top").setStyle("padding-top", "0px"); spt.behavior.destroy_element(bvr.src_el); ''' }) div.add_behavior({ 'type': 'mouseover', 'cbjs_action': ''' bvr.src_el.setStyle("opacity", 0.85) //new Fx.Tween(bvr.src_el).start('height', "30px"); ''' }) div.add_behavior({ 'type': 'mouseout', 'cbjs_action': ''' bvr.src_el.setStyle("opacity", 0.7) //new Fx.Tween(bvr.src_el).start('height', "15px"); ''' }) project_code = Project.get_project_code() site_root = web.get_site_root() div.add_behavior({ 'type': 'click_up', 'site_root': site_root, 'project_code': project_code, 'cbjs_action': ''' var url = "/"+bvr.site_root+"/"+bvr.project_code+"/admin/link/_startup"; window.open(url); ''' }) # Add the script editor listener load_div = DivWdg() top.add(load_div) load_div.add_behavior({ 'type': 'listen', 'event_name': 'show_script_editor', 'cbjs_action': ''' var js_popup_id = "TACTIC Script Editor"; var js_popup = $(js_popup_id); if( js_popup ) { spt.popup.toggle_display( js_popup_id, false ); } else { spt.panel.load_popup(js_popup_id, "tactic.ui.app.ShelfEditWdg", {}, {"load_once": true} ); } ''' }) # deal with the palette defined in /index which can override the palette if my.kwargs.get("hash") == (): key = "index" search = Search("config/url") search.add_filter("url", "/%s/%%" % key, "like") search.add_filter("url", "/%s" % key) search.add_where("or") url = search.get_sobject() if url: xml = url.get_xml_value("widget") palette_key = xml.get_value("element/@palette") # look up palette the expression for index from pyasm.web import Palette palette = Palette.get() palette.set_palette(palette_key) colors = palette.get_colors() colors = jsondumps(colors) script = HtmlElement.script(''' var env = spt.Environment.get(); env.set_colors(%s); env.set_palette('%s'); ''' % (colors, palette_key)) top.add(script) env = Environment.get() client_handoff_dir = env.get_client_handoff_dir(include_ticket=False, no_exception=True) client_asset_dir = env.get_client_repo_dir() login = Environment.get_login() user_name = login.get_value("login") user_id = login.get_id() login_groups = Environment.get_group_names() from pyasm.security import Site site = Site.get_site() kiosk_mode = Config.get_value("look", "kiosk_mode") if not kiosk_mode: kiosk_mode = 'false' # add environment information script = HtmlElement.script(''' var env = spt.Environment.get(); env.set_site('%s'); env.set_project('%s'); env.set_user('%s'); env.set_user_id('%s'); var login_groups = '%s'.split('|'); env.set_login_groups(login_groups); env.set_client_handoff_dir('%s'); env.set_client_repo_dir('%s'); env.set_kiosk_mode('%s'); ''' % (site, Project.get_project_code(), user_name, user_id, '|'.join(login_groups), client_handoff_dir, client_asset_dir, kiosk_mode)) top.add(script) # add a global container for commonly used widgets div = DivWdg() top.add(div) div.set_id("global_container") # add in the app busy widget # find out if there is an override for this search = Search("config/url") search.add_filter("url", "/app_busy") url = search.get_sobject() if url: busy_div = DivWdg() div.add(busy_div) busy_div.add_class("SPT_PUW") busy_div.add_styles( "display: none; position: absolute; z-index: 1000") busy_div.add_class("app_busy_msg_block") busy_div.add_style("width: 300px") busy_div.add_style("height: 100px") busy_div.add_style("padding: 20px") busy_div.add_color("background", "background3") busy_div.add_border() busy_div.set_box_shadow() busy_div.set_round_corners(20) busy_div.set_attr("id", "app_busy_msg_block") # put the custom url here title_wdg = DivWdg() busy_div.add(title_wdg) title_wdg.add_style("font-size: 20px") title_wdg.add_class("spt_app_busy_title") busy_div.add("<hr/>") msg_div = DivWdg() busy_div.add(msg_div) msg_div.add_class("spt_app_busy_msg") else: from page_header_wdg import AppBusyWdg div.add(AppBusyWdg()) # popup parent popup = DivWdg() popup.set_id("popup") div.add(popup) # create another general popup popup_div = DivWdg() popup_div.set_id("popup_container") popup_div.add_class("spt_panel") popup = PopupWdg(id="popup_template", destroy_on_close=True) popup_div.add(popup) div.add(popup_div) inner_html_div = DivWdg() inner_html_div.set_id("inner_html") div.add(inner_html_div) # add in a global color from tactic.ui.input import ColorWdg color = ColorWdg() div.add(color) # add in a global notify wdg from notify_wdg import NotifyWdg widget.add(NotifyWdg()) from tactic.ui.app import DynamicUpdateWdg widget.add(DynamicUpdateWdg()) return widget
# Dump out the error print "WARNING: ", path, status, message try: eval("cherrypy.root.tactic.%s" % project_code) # if project_code is empty , it raises SyntaxError except (AttributeError, SyntaxError), e: has_project = False else: has_project = True # make sure the appropriate site is set (based on the ticket) from pyasm.security import Site cookie = cherrypy.request.cookie if cookie.has_key("login_ticket"): cookie = cookie["login_ticket"].value site = Site.get().get_by_ticket(cookie) else: html_response = '''<html> <head><meta http-equiv="Refresh" content="0; url=/"></head> </html>''' response.body = '' return html_response Site.set_site(site) # if the url does not exist, but the project does, then check to # to see if cherrypy knows about it project = Project.get_by_code(project_code) if not has_project and project and project.get_value("type") != 'resource':
def add_top_behaviors(self): self.body.add_relay_behavior({ 'type': 'click', 'bvr_match_class': 'tactic_popup', 'cbjs_action': ''' var view = bvr.src_el.getAttribute("view"); if (!view) { spt.alert("No view found"); } var target = bvr.src_el.getAttribute("target"); var title = bvr.src_el.getAttribute("title"); var class_name = 'tactic.ui.panel.CustomLayoutWdg'; var kwargs = { view: view, } var attributes = bvr.src_el.attributes; for (var i = 0; i < attributes.length; i++) { var name = attributes[i].name; if (name == "class") { continue; } var value = attributes[i].value; kwargs[name] = value; } spt.panel.load_popup(title, class_name, kwargs); ''' }) self.body.add_relay_behavior({ 'type': 'click', 'bvr_match_class': 'tactic_load', 'cbjs_action': ''' var view = bvr.src_el.getAttribute("view"); if (!view) { spt.alert("No view found"); } var target_class = bvr.src_el.getAttribute("target"); if (! target_class ) { target_class = "spt_content"; } if (target_class.indexOf(".") != "-1") { var parts = target_class.split("."); var top = bvr.src_el.getParent("."+parts[0]); var target = top.getElement("."+parts[1]); } else { var target = $(document.body).getElement("."+target_class); } var class_name = 'tactic.ui.panel.CustomLayoutWdg'; var kwargs = { view: view, } var attributes = bvr.src_el.attributes; for (var i = 0; i < attributes.length; i++) { var name = attributes[i].name; if (name == "class") { continue; } var value = attributes[i].value; kwargs[name] = value; } spt.panel.load(target, class_name, kwargs); var scroll = bvr.src_el.getAttribute("scroll"); if (scroll == "top") { window.scrollTo(0,0); } ''' }) self.body.add_relay_behavior({ 'type': 'click', 'bvr_match_class': 'tactic_link', 'cbjs_action': ''' var href = bvr.src_el.getAttribute("href"); if (!href) { spt.alert("No href defined for this link"); return; } var target = bvr.src_el.getAttribute("target"); if (!target) { target = "_self"; } window.open(href, target); ''' }) self.body.add_relay_behavior({ 'type': 'click', 'bvr_match_class': 'tactic_refresh', 'cbjs_action': ''' var target_class = bvr.src_el.getAttribute("target"); if (target_class.indexOf(".") != "-1") { var parts = target_class.split("."); var top = bvr.src_el.getParent("."+parts[0]); var target = top.getElement("."+parts[1]); } else { var target = $(document.body).getElement("."+target_class); } spt.panel.refresh(target); ''' }) self.body.add_relay_behavior({ 'type': 'click', 'bvr_match_class': 'tactic_new_tab', 'cbjs_action': ''' var view = bvr.src_el.getAttribute("view") var search_key = bvr.src_el.getAttribute("search_key") var expression = bvr.src_el.getAttribute("expression") var name = bvr.src_el.getAttribute("name"); var title = bvr.src_el.getAttribute("title"); if (!name) { name = title; } if (!title) { title = name; } if (!title && !name) { title = name = "Untitled"; } if (expression) { var server = TacticServerStub.get(); var sss = server.eval(expression, {search_keys: search_key, single: true}) search_key = sss.__search_key__; } spt.tab.set_main_body_tab() if (view) { var cls = "tactic.ui.panel.CustomLayoutWdg"; var kwargs = { view: view } } else if (search_key) { var cls = "tactic.ui.tools.SObjectDetailWdg"; var kwargs = { search_key: search_key } } var attributes = bvr.src_el.attributes; for (var i = 0; i < attributes.length; i++) { var attr_name = attributes[i].name; if (attr_name == "class") { continue; } var value = attributes[i].value; kwargs[attr_name] = value; } try { spt.tab.add_new(name, title, cls, kwargs); } catch(e) { spt.alert(e); } ''' }) self.body.add_relay_behavior({ 'type': 'click', 'bvr_match_class': 'tactic_submit', 'cbjs_action': ''' var command = bvr.src_el.getAttribute("command"); var kwargs = { } var server = TacticServerStub.get(); try { server.execute_cmd(command, kwargs); } catch(e) { spt.alert(e); } ''' }) self.body.add_relay_behavior({ 'type': 'mouseenter', 'bvr_match_class': 'tactic_hover', 'cbjs_action': ''' var bgcolor = bvr.src_el.getStyle("background"); bvr.src_el.setAttribute("spt_bgcolor", bgcolor); bvr.src_el.setStyle("background", "#EEE"); ''' }) self.body.add_relay_behavior({ 'type': 'mouseleave', 'bvr_match_class': 'tactic_hover', 'cbjs_action': ''' var bgcolor = bvr.src_el.getAttribute("spt_bgcolor"); if (!bgcolor) bgcolor = ""; //var bgcolor = "" bvr.src_el.setStyle("background", bgcolor); ''' }) self.body.set_unique_id() self.body.add_smart_style("tactic_load", "cursor", "pointer") # check version of the database project = Project.get() version = project.get_value("last_version_update") release = Environment.get_release_version() #if version < release: # FIXME: can't do this ... TACTIC cannot be running when the database # is upgrading. if False: try: from pyasm.security import Site site = Site.get_site() install_dir = Environment.get_install_dir() cmd = '''python "%s/src/bin/upgrade_db.py" -f -s "%s" --quiet --yes &''' % ( install_dir, site) print("cmd: ", cmd) os.system(cmd) pass except Exception as e: print("WARNING: ", e)
# Dump out the error print "WARNING: ", path, status, message try: eval("cherrypy.root.tactic.%s" % project_code) # if project_code is empty , it raises SyntaxError except (AttributeError, SyntaxError), e: has_project = False else: has_project = True # make sure the appropriate site is set (based on the ticket) from pyasm.security import Site cookie = cherrypy.request.cookie if cookie.has_key("login_ticket"): cookie = cookie["login_ticket"].value site = Site.get().get_by_ticket(cookie) else: html_response = '''<html> <head><meta http-equiv="Refresh" content="0; url=/"></head> </html>''' response.body = '' return html_response Site.set_site(site) # if the url does not exist, but the project does, then check to # to see if cherrypy knows about it project = Project.get_by_code(project_code) if not has_project and project and project.get_value( "type") != 'resource':
def create_sobject_log(cls, log, transaction_data=None): if not transaction_data: transaction_data = log.get_value("transaction") # log a reference to each sobject affected already_logged = {} xml = Xml() xml.read_string(transaction_data) nodes = xml.get_nodes("transaction/*") # list of sobjects not logged not_logged = set([ 'sthpw/transaction_log', 'sthpw/clipboard', 'sthpw/sobject_log', 'sthpw/file', 'sthpw/message', 'sthpw/message_log', ]) find_parent = set(['sthpw/snapshot', 'sthpw/note', 'sthpw/task']) from pyasm.security import Site current_site = Site.get_site() for node in nodes: node_name = xml.get_node_name(node) if node_name == "sobject": search_type = Xml.get_attribute(node, "search_type") search_type_obj = SearchType.get(search_type) if search_type_obj.get_base_key() in not_logged: continue search_id = Xml.get_attribute(node, "search_id") search_code = Xml.get_attribute(node, "search_code") site = Xml.get_attribute(node, "site") if search_code: search_key = "%s?code=%s" % (search_type, search_code) else: search_key = "%s|%s" % (search_type, search_id) if already_logged.get(search_key): continue already_logged[search_key] = True # delete items are not presently logged ... # TODO: maybe they should be action = Xml.get_attribute(node, "action") if action == "delete": continue has_site = False if site: try: Site.set_site(site) has_site = True except: print "Site [%s] does not exist" % site continue try: if search_code: sobject = Search.get_by_code(search_type, search_code) else: sobject = Search.get_by_id(search_type, search_id) if sobject: SObjectLog.create(sobject, log, action) else: # record has been deleted if search_code: print( "Skipped SObject log creation for [%s?code=%s]" % (search_type, search_code)) else: print("Skipped SObject log creation for [%s|%s]" % (search_type, search_id)) if search_type_obj.get_base_key() in find_parent: try: if sobject: sobject = sobject.get_parent() except (SearchException, SqlException): # don't worry if this parent can't be found. pass if sobject: SObjectLog.create(sobject, log, "child_%s" % action) finally: if has_site: Site.pop_site()
def execute(self): input_data = self.get_input_data() data = self.data # add site info to the data object site = Site.get_site() if site and not data.get("site"): data['site'] = site result = True # input data for the handler if self.mode == 'separate process,blocking': input_data_str = jsondumps(input_data) data_str = jsondumps(data) file = __file__ py_exec = Config.get_value("services", "python") if not py_exec: py_exec = "python" retcode = subprocess.call( [py_exec, file, data_str, input_data_str]) elif self.mode == 'separate process,non-blocking': input_data_str = jsondumps(input_data) data_str = jsondumps(data) file = __file__ py_exec = Config.get_value("services", "python") if not py_exec: py_exec = "python" retcode = subprocess.Popen( [py_exec, file, data_str, input_data_str]) result = "wait" elif self.mode == 'separate process,queued': kwargs = data.get("kwargs") priority = kwargs.get("priority") or 99999 description = kwargs.get("description") or "Trigger" queue_type = kwargs.get("trigger") or "trigger" class_name = "pyasm.command.QueueTrigger" kwargs = { 'input_data': input_data, 'data': data, } from tactic.command import Queue queue_item = Queue.add(class_name, kwargs, queue_type=queue_type, priority=priority, description=description) result = "wait" elif self.mode == 'same process,new transaction': # run it inline trigger = ScriptTrigger() trigger.set_data(data) trigger.set_input(input_data) trigger.execute() # if it was not overridden by the trigger, the return default for the mode if not self.info.has_key("result"): self.info['result'] = result
def get_display(my): top = my.top top.add_color("background", "background") top.add_color("color", "color") top.add_style("width", "400px") top.add_border() top.add_class("spt_delete_project_tool_top") login = Environment.get_user_name() if login != 'admin': top.add(IconWdg(icon=IconWdg.WARNING)) top.add("Only Admin can delete projects") top.add_style("padding: 50px") top.add_style("text-align: center") return top site = my.kwargs.get("site") if site: Site.set_site(site) project_code = my.kwargs.get("project_code") # check if delete permissions exist for this site and project security = Environment.get_security() if False and not security.check_access("project", project_code, "delete"): top.add(IconWdg(icon=IconWdg.WARNING)) top.add("Not permitted to delete this project") top.add_style("padding: 30px") top.add_style("text-align: center") top.add_style("margin: 50px 30px") top.add_border() top.add_color("background", "background3") return top if project_code: project = Project.get_by_code(project_code) if not project: top.add(IconWdg(icon=IconWdg.WARNING)) top.add("No project [%s] exists in this database" % project_code) top.add_style("padding: 30px") top.add_style("text-align: center") top.add_style("margin: 50px 30px") top.add_border() top.add_color("background", "background3") return top search_key = project.get_search_key() else: search_key = my.kwargs.get("search_key") project = Search.get_by_search_key(search_key) if project: project_code = project.get_code() title_wdg = DivWdg() if project: top.add(title_wdg) title_wdg.add(IconWdg(icon=IconWdg.WARNING)) title_wdg.add("Deleting Project: %s" % project.get_value("title")) title_wdg.add_color("background", "background", -5) title_wdg.add_style("padding: 5px") title_wdg.add_style("font-weight: bold") title_wdg.add_style("font-size: 14px") content = DivWdg() top.add(content) content.add_style("padding: 10px") if not search_key: warning_msg = "Projects must be deleted individually" content.add(DivWdg(warning_msg, css='warning')) content.add("<br/>") return top warning_msg = "Deleting a project will delete the database associated with this project. All data and files will be lost. Please consider carefully before proceeding." if warning_msg: warning_wdg = DivWdg(warning_msg, css='warning') content.add(warning_wdg) warning_wdg.add_style("margin: 20 10px") content.add("<br/>") if not project_code: content.add("This project [%s] has been deleted." % search_key) return top elif not project: content.add("This project [%s] has been deleted." % project_code) return top assert project_code assert project content.add("<br/>") content.add( "<b>NOTE: These items will be deleted, but the sTypes entries in search_objects table will be retained.</b> " ) content.add("<br/>") content.add("<br/>") total_items_wdg = DivWdg() total_items = 0 content.add(total_items_wdg) # find all of the sTypes details_wdg = DivWdg() content.add(details_wdg) details_wdg.add_style("max-height: 300px") details_wdg.add_style("overflow-y: auto") details_wdg.add_style("padding-left: 15px") details_wdg.add_border() search_types = project.get_search_types() related_types = [] for search_type_obj in search_types: search_type_wdg = DivWdg() title = search_type_obj.get_title() search_type = search_type_obj.get_value("search_type") search_type_wdg.add_style("margin-top: 5px") search_type_wdg.add_style("margin-bottom: 5px") details_wdg.add(search_type_wdg) search_type_wdg.add(title) search_type_wdg.add(" (%s)" % search_type) search = Search(search_type, project_code=project_code) count = search.get_count() total_items += count search_type_wdg.add(" - %s item(s)" % count) # TODO: this is similar to SearchType.get_related_types(). streamline at some point. related_types = my.get_related_types(search_type) for related_type in related_types: try: search = Search(related_type) except Exception, e: print "WARNING: ", e continue full_search_type = "%s?project=%s" % (search_type, project_code) if related_type.startswith("sthpw/"): search.add_filter("search_type", full_search_type) count = search.get_count() if count == 0: continue total_items += count related_wdg = DivWdg() related_wdg.add_style('padding-left: 25px') search_type_wdg.add(related_wdg) related_wdg.add(related_type) related_wdg.add(" - %s item(s)" % count)
def get_display(my): web = WebContainer.get_web() widget = Widget() html = HtmlElement("html") is_xhtml = False if is_xhtml: web.set_content_type("application/xhtml+xml") widget.add('''<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> ''') html.add_attr("xmlns", "http://www.w3.org/1999/xhtml") #html.add_attr("xmlns:svg", "http://www.w3.org/2000/svg") # add the copyright widget.add( my.get_copyright_wdg() ) widget.add(html) # create the header head = HtmlElement("head") html.add(head) head.add('<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>\n') head.add('<meta http-equiv="X-UA-Compatible" content="IE=edge"/>\n') # Add the tactic favicon head.add('<link rel="shortcut icon" href="/context/favicon.ico" type="image/x-icon"/>') # add the css styling head.add(my.get_css_wdg()) # add the title in the header project = Project.get() project_code = project.get_code() project_title = project.get_value("title") if web.is_admin_page(): is_admin = " - Admin" else: is_admin = "" if project_code == 'admin': head.add("<title>TACTIC Site Admin</title>\n" ) else: head.add("<title>%s%s</title>\n" % (project_title, is_admin) ) # add the javascript libraries head.add( JavascriptImportWdg() ) # add the body body = my.body html.add( body ) body.add_event('onload', 'spt.onload_startup(this)') top = my.top # Add a NOSCRIPT tag block here to provide a warning message on browsers where 'Enable JavaScript' # is not checked ... TODO: clean up and re-style to make look nicer top.add( """ <NOSCRIPT> <div style="border: 2px solid black; background-color: #FFFF99; color: black; width: 600px; height: 70px; padding: 20px;"> <img src="%s" style="border: none;" /> <b>Javascript is not enabled on your browser!</b> <p>This TACTIC powered, web-based application requires JavaScript to be enabled in order to function. In your browser's options/preferences, please make sure that the 'Enable JavaScript' option is checked on, click OK to accept the settings change, and then refresh this web page.</p> </div> </NOSCRIPT> """ % ( IconWdg.get_icon_path("ERROR") ) ) # add the content content_div = DivWdg() top.add(content_div) Container.put("TopWdg::content", content_div) # add a dummy button for global behaviors from tactic.ui.widget import ButtonNewWdg, IconButtonWdg ButtonNewWdg(title="DUMMY", icon=IconWdg.FILM) IconButtonWdg(title="DUMMY", icon=IconWdg.FILM) # NOTE: it does not need to be in the DOM. Just needs to be # instantiated #content_div.add(button) if my.widgets: content_wdg = my.get_widget('content') else: content_wdg = Widget() my.add(content_wdg) content_div.add( content_wdg ) # add a calendar wdg from tactic.ui.widget import CalendarWdg cal_wdg = CalendarWdg(css_class='spt_calendar_template_top') cal_wdg.top.add_style('display: none') content_div.add(cal_wdg) if web.is_admin_page(): from tactic_branding_wdg import TacticCopyrightNoticeWdg branding = TacticCopyrightNoticeWdg(show_license_info=True) top.add(branding) # add the admin bar security = Environment.get_security() if not web.is_admin_page() and security.check_access("builtin", "view_site_admin", "allow"): div = DivWdg() top.add(div) top.add_style("padding-top: 21px") div.add_class("spt_admin_bar") # home icon_div = DivWdg() div.add(icon_div) icon_div.add_style("float: left") icon_div.add_style("margin-right: 10px") icon_div.add_style("margin-top: -3px") icon_button = IconButtonWdg(title="Home", icon="BS_HOME") icon_div.add(icon_button) icon_button.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' window.location.href="/"; ''' } ) div.add_style("height: 15px") div.add_style("padding: 3px 0px 3px 15px") #div.add_style("margin-bottom: -5px") div.add_style("position: fixed") div.add_style("top: 0px") div.add_style("left: 0px") div.add_style("opacity: 0.7") div.add_style("width: 100%") #div.add_gradient("background", "background2", 20, 10) div.add_style("background-color", "#000") div.add_style("color", "#FFF") div.add_style("z-index", "1000") div.add_class("hand") div.set_box_shadow("0px 5px 5px") # remove icon_div = DivWdg() div.add(icon_div) icon_div.add_style("float: right") icon_div.add_style("margin-right: 10px") icon_div.add_style("margin-top: -3px") icon_button = IconButtonWdg(title="Remove Admin Bar", icon="BS_REMOVE") icon_div.add(icon_button) icon_button.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' var parent = bvr.src_el.getParent(".spt_admin_bar"); bvr.src_el.getParent(".spt_top").setStyle("padding-top", "0px"); spt.behavior.destroy_element(parent); ''' } ) # sign-out icon_div = DivWdg() div.add(icon_div) icon_div.add_style("float: right") icon_div.add_style("margin-right: 5px") icon_div.add_style("margin-top: -3px") icon_button = IconButtonWdg(title="Sign Out", icon="BS_LOG_OUT") icon_div.add(icon_button) icon_button.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' var ok = function(){ var server = TacticServerStub.get(); server.execute_cmd("SignOutCmd", {login: bvr.login} ); window.location.href="/"; } spt.confirm("Are you sure you wish to sign out?", ok ) ''' } ) div.add("<b>ADMIN >></b>") div.add_behavior( { 'type': 'listen', 'event_name': 'close_admin_bar', 'cbjs_action': ''' bvr.src_el.getParent(".spt_top").setStyle("padding-top", "0px"); spt.behavior.destroy_element(bvr.src_el); ''' } ) div.add_behavior( { 'type': 'mouseover', 'cbjs_action': ''' bvr.src_el.setStyle("opacity", 0.85) //new Fx.Tween(bvr.src_el).start('height', "30px"); ''' } ) div.add_behavior( { 'type': 'mouseout', 'cbjs_action': ''' bvr.src_el.setStyle("opacity", 0.7) //new Fx.Tween(bvr.src_el).start('height', "15px"); ''' } ) project_code = Project.get_project_code() site_root = web.get_site_root() div.add_behavior( { 'type': 'click_up', 'site_root': site_root, 'project_code': project_code, 'cbjs_action': ''' var url = "/"+bvr.site_root+"/"+bvr.project_code+"/admin/link/_startup"; window.open(url); ''' } ) # Add the script editor listener load_div = DivWdg() top.add(load_div) load_div.add_behavior( { 'type': 'listen', 'event_name': 'show_script_editor', 'cbjs_action': ''' var js_popup_id = "TACTIC Script Editor"; var js_popup = $(js_popup_id); if( js_popup ) { spt.popup.toggle_display( js_popup_id, false ); } else { spt.panel.load_popup(js_popup_id, "tactic.ui.app.ShelfEditWdg", {}, {"load_once": true} ); } '''} ) # deal with the palette defined in /index which can override the palette if my.kwargs.get("hash") == (): key = "index" search = Search("config/url") search.add_filter("url", "/%s/%%"%key, "like") search.add_filter("url", "/%s"%key) search.add_where("or") url = search.get_sobject() if url: xml = url.get_xml_value("widget") palette_key = xml.get_value("element/@palette") # look up palette the expression for index from pyasm.web import Palette palette = Palette.get() palette.set_palette(palette_key) colors = palette.get_colors() colors = jsondumps(colors) script = HtmlElement.script(''' var env = spt.Environment.get(); env.set_colors(%s); env.set_palette('%s'); ''' % (colors, palette_key) ) top.add(script) env = Environment.get() client_handoff_dir = env.get_client_handoff_dir(include_ticket=False, no_exception=True) client_asset_dir = env.get_client_repo_dir() login = Environment.get_login() user_name = login.get_value("login") user_id = login.get_id() login_groups = Environment.get_group_names() from pyasm.security import Site site = Site.get_site() kiosk_mode = Config.get_value("look", "kiosk_mode") if not kiosk_mode: kiosk_mode = 'false' # add environment information script = HtmlElement.script(''' var env = spt.Environment.get(); env.set_site('%s'); env.set_project('%s'); env.set_user('%s'); env.set_user_id('%s'); var login_groups = '%s'.split('|'); env.set_login_groups(login_groups); env.set_client_handoff_dir('%s'); env.set_client_repo_dir('%s'); env.set_kiosk_mode('%s'); ''' % (site, Project.get_project_code(), user_name, user_id, '|'.join(login_groups), client_handoff_dir,client_asset_dir, kiosk_mode)) top.add(script) # add a global container for commonly used widgets div = DivWdg() top.add(div) div.set_id("global_container") # add in the app busy widget # find out if there is an override for this search = Search("config/url") search.add_filter("url", "/app_busy") url = search.get_sobject() if url: busy_div = DivWdg() div.add(busy_div) busy_div.add_class( "SPT_PUW" ) busy_div.add_styles( "display: none; position: absolute; z-index: 1000" ) busy_div.add_class("app_busy_msg_block") busy_div.add_style("width: 300px") busy_div.add_style("height: 100px") busy_div.add_style("padding: 20px") busy_div.add_color("background", "background3") busy_div.add_border() busy_div.set_box_shadow() busy_div.set_round_corners(20) busy_div.set_attr("id","app_busy_msg_block") # put the custom url here title_wdg = DivWdg() busy_div.add(title_wdg) title_wdg.add_style("font-size: 20px") title_wdg.add_class("spt_app_busy_title") busy_div.add("<hr/>") msg_div = DivWdg() busy_div.add(msg_div) msg_div.add_class("spt_app_busy_msg") else: from page_header_wdg import AppBusyWdg div.add( AppBusyWdg() ) # popup parent popup = DivWdg() popup.set_id("popup") div.add(popup) # create another general popup popup_div = DivWdg() popup_div.set_id("popup_container") popup_div.add_class("spt_panel") popup = PopupWdg(id="popup_template",destroy_on_close=True) popup_div.add(popup) div.add(popup_div) inner_html_div = DivWdg() inner_html_div.set_id("inner_html") div.add(inner_html_div) # add in a global color from tactic.ui.input import ColorWdg color = ColorWdg() div.add(color) # add in a global notify wdg from notify_wdg import NotifyWdg widget.add(NotifyWdg()) from tactic.ui.app import DynamicUpdateWdg widget.add( DynamicUpdateWdg() ) return widget
def execute(self): input_data = self.get_input_data() data = self.data # add site info to the data object site = Site.get_site() if site and not data.get("site"): data['site'] = site result = True # input data for the handler if self.mode == 'separate process,blocking': input_data_str = jsondumps(input_data) data_str = jsondumps(data) file = __file__ py_exec = Config.get_value("services", "python") if not py_exec: py_exec = "python" retcode = subprocess.call([py_exec, file, data_str, input_data_str]) elif self.mode == 'separate process,non-blocking': input_data_str = jsondumps(input_data) data_str = jsondumps(data) file = __file__ py_exec = Config.get_value("services", "python") if not py_exec: py_exec = "python" retcode = subprocess.Popen([py_exec, file, data_str, input_data_str]) result = "wait" elif self.mode == 'separate process,queued': kwargs = data.get("kwargs") priority = kwargs.get("priority") or 99999 description = kwargs.get("description") or "Trigger" queue_type = kwargs.get("trigger") or "trigger" class_name = "pyasm.command.QueueTrigger" kwargs = { 'input_data': input_data, 'data': data, } from tactic.command import Queue queue_item = Queue.add(class_name, kwargs, queue_type=queue_type, priority=priority, description=description) result = "wait" elif self.mode == 'same process,new transaction': # run it inline trigger = ScriptTrigger() trigger.set_data(data) trigger.set_input(input_data) trigger.execute() # if it was not overridden by the trigger, the return default for the mode if not self.info.has_key("result"): self.info['result'] = result