def get_display(my): web = WebContainer.get_web() context_url = web.get_context_url().to_string() js_url = "%s/javascript" % context_url spt_js_url = "%s/spt_js" % context_url # adding new core "spt" javascript library folder version = Environment.get_release_version() # add some third party libraries third_party = js_includes.third_party security = Environment.get_security() for include in js_includes.third_party: Container.append_seq("Page:js", "%s/%s" % (spt_js_url,include)) all_js_path = js_includes.get_compact_js_filepath() if os.path.exists( all_js_path ): Container.append_seq("Page:js", "%s/%s" % (context_url, js_includes.get_compact_js_context_path_suffix())) else: for include in js_includes.legacy_core: Container.append_seq("Page:js", "%s/%s" % (js_url,include)) for include in js_includes.spt_js: Container.append_seq("Page:js", "%s/%s" % (spt_js_url,include)) for include in js_includes.legacy_app: Container.append_seq("Page:js", "%s/%s" % (js_url,include)) # custom js files to include includes = Config.get_value("install", "include_js") includes = includes.split(",") for include in includes: include = include.strip() if include: print "include: ", include Container.append_seq("Page:js", include) widget = Widget() js_files = Container.get("Page:js") for js_file in js_files: widget.add('<script src="%s?ver=%s" ></script>\n' % (js_file,version) ) return widget
def get_display(my): web = WebContainer.get_web() context_url = web.get_context_url().to_string() js_url = "%s/javascript" % context_url spt_js_url = "%s/spt_js" % context_url # adding new core "spt" javascript library folder version = Environment.get_release_version() # add some third party libraries third_party = js_includes.third_party security = Environment.get_security() # FIXME: this logic should not be located here. # no reason to have the edit_area_full.js if not security.check_access("builtin", "view_script_editor", "allow") and security.check_access("builtin", "view_site_admin", "allow"): if "edit_area/edit_area_full.js" in third_party: third_party.remove("edit_area/edit_area_full.js") for include in js_includes.third_party: Container.append_seq("Page:js", "%s/%s" % (spt_js_url,include)) all_js_path = js_includes.get_compact_js_filepath() if os.path.exists( all_js_path ): Container.append_seq("Page:js", "%s/%s" % (context_url, js_includes.get_compact_js_context_path_suffix())) else: for include in js_includes.legacy_core: Container.append_seq("Page:js", "%s/%s" % (js_url,include)) for include in js_includes.spt_js: Container.append_seq("Page:js", "%s/%s" % (spt_js_url,include)) for include in js_includes.legacy_app: Container.append_seq("Page:js", "%s/%s" % (js_url,include)) #Container.append_seq("Page:js", "http://webplayer.unity3d.com/download_webplayer-3.x/3.0/uo/UnityObject.js") #Container.append_seq("Page:js", "/context/spt_js/UnityObject.js") #widget = DivWdg() #widget.set_id("javascript") #my.set_as_panel(widget) widget = Widget() js_files = Container.get("Page:js") for js_file in js_files: widget.add('<script src="%s?ver=%s" ></script>\n' % (js_file,version) ) return widget
def convert_file(self, src_path, dst_path): upgrade_dir = Environment.get_upgrade_dir() tmp_dir = Environment.get_tmp_dir() dir = os.path.dirname(dst_path) if dir and not os.path.exists(dir): os.makedirs(dir) f = open(src_path, 'r') f2 = open(dst_path, 'w') # prepend lines lines = self.get_prepend_lines() for line in lines: f2.write(line) for line in f.xreadlines(): line = self.handle_line(line) if line == None: continue f2.write(line) f.close() f2.close() return dst_path
def get_display(my): sobject = my.get_current_sobject() sk = sobject.get_search_key() widget = DivWdg() sts_to_perm = {'twog/qc_report_vars': 'compression|qc supervisor|edeliveries'} if '-1' not in sk: table = Table() table.add_attr('width', '50px') login = Environment.get_login() user_name = login.get_login() groups = Environment.get_group_names() st = sk.split('?')[0]; perms = sts_to_perm[st] allow = False for g in groups: if g in perms: allow = True if user_name == 'admin': allow = True if allow: table.add_row() cell1 = table.add_cell(my.x_butt) cell1.add_attr('id','sp_del_%s' % sk) launch_behavior = my.get_delete_behavior(sk) cell1.add_style('cursor: pointer;') cell1.add_behavior(launch_behavior) widget.add(table) return widget
def filter_xml(my, xml): dirname = os.path.dirname(my.rel_path) # filter images img_nodes = xml.get_nodes("//img") install_dir = Environment.get_install_dir() for node in img_nodes: src = xml.get_attribute(node, "src") if src.startswith("/tactic/plugins/"): plugin_dir = Environment.get_plugin_dir() path = "%s/%s" % (plugin_dir, src.replace("/tactic/plugins/", "") ) elif src.startswith("/tactic/builtin_plugins/"): plugin_dir = Environment.get_builtin_plugin_dir() path = "%s/%s" % (plugin_dir, src.replace("/tactic/builtin_plugins/", "") ) elif src.startswith("/"): path = "%s/src%s" % (install_dir, src) else: path = "%s/doc/%s/%s" % (install_dir, dirname, src) size = (0,0) try: from PIL import Image im = Image.open(path) size = im.size except IOError, e: print "Error importing Image: ", e except:
def test_all(self): batch = Batch() Environment.get_security().set_admin(True) from pyasm.unittest import UnittestEnvironment, Sample3dEnvironment test_env = UnittestEnvironment() test_env.create() sample3d_env = Sample3dEnvironment(project_code='sample3d') sample3d_env.create() Project.set_project("unittest") try: self.access_manager = Environment.get_security().get_access_manager() self._test_all() finally: # Reset access manager for tear down Environment.get_security()._access_manager = self.access_manager Environment.get_security().reset_access_manager() self._tear_down() Environment.get_security().set_admin(True) test_env.delete() Environment.get_security().set_admin(True) sample3d_env.delete() Site.pop_site()
def _do_execute(my): # restablish the site if my.site: Site.set_site(my.site) Environment.set_security(my.security) my.execute()
def __init__(self, ticket, site=None): super(XmlRpcInit,self).__init__() if not site: # if not explicitly set, keep the current site site = Site.get_site() self.set_app_server("xmlrpc") self.ticket = ticket # clear the main container #Container.clear() Environment.set_env_object( self ) # set up the security object security = Security() Environment.set_security(security) if site: Site.set_site(site) self._do_login()
def execute(my): from pyasm.common import ZipUtil ziputil = ZipUtil() paths = my.kwargs.get("paths") upload_dir = Environment.get_upload_dir() template_dir = Environment.get_template_dir() for path in paths: path = path.replace("\\", "/") basename = os.path.basename(path) upload_path = "%s/%s" % (upload_dir, basename) if not upload_path.endswith(".zip"): continue print "upload: ", upload_path if not os.path.exists(upload_path): continue print "template_dir: ", template_dir shutil.move(upload_path, template_dir) to_path = "%s/%s" % (template_dir, basename) # unzip the file ziputil.extract(to_path)
def __init__(self, login_name, password=None): super(XmlRpcLogin,self).__init__() self.set_app_server("xmlrpc") # If the tag <force_lowercase_login> is set to "true" # in the TACTIC config file, # then force the login string argument to be lowercase. # This tag is false by default. self.login_name = login_name if Config.get_value("security","force_lowercase_login") == "true": self.login_name = self.login_name.lower() self.password = password # clear the main container #Container.clear() Environment.set_env_object( self ) # set up the security object security = Security() Environment.set_security(security) self._do_login()
def get_columns(my, required_only=False): if my.search_type == 'sthpw/virtual': return [] search_type_obj = SearchType.get(my.search_type) table = search_type_obj.get_table() from pyasm.biz import Project db_resource = Project.get_db_resource_by_search_type(my.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 _process_video(my, file_name): if not HAS_FFMPEG: return thumb_web_size = my.get_web_file_size() thumb_icon_size = (120, 100) exts = File.get_extensions(file_name) base, ext = os.path.splitext(file_name) icon_file_name = "%s_icon.png" % base web_file_name = "%s_web.jpg" % base tmp_icon_path = "%s/%s" % (my.tmp_dir, icon_file_name) tmp_web_path = "%s/%s" % (my.tmp_dir, web_file_name) #cmd = '''"%s" -i "%s" -r 1 -ss 00:00:01 -t 1 -s %sx%s -vframes 1 "%s"''' % (ffmpeg, my.file_path, thumb_web_size[0], thumb_web_size[1], tmp_web_path) #os.system(cmd) import subprocess try: subprocess.call([ffmpeg_exe, '-i', my.file_path, "-y", "-ss", "00:00:00","-t","1",\ "-s","%sx%s"%(thumb_web_size[0], thumb_web_size[1]),"-vframes","1","-f","image2", tmp_web_path]) if os.path.exists(tmp_web_path): my.web_path = tmp_web_path else: my.web_path = None except Exception, e: Environment.add_warning("Could not process file", \ "%s - %s" % (my.file_path, e.__str__())) pass
def get_render_dir(my): ticket = Environment.get_security().get_ticket_key() tmpdir = Environment.get_tmp_dir() render_dir = "%s/temp/%s" % (tmpdir, ticket) System().makedirs(render_dir) return render_dir
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 execute(my): filename = my.kwargs.get("filename") ticket = my.kwargs.get("ticket") upload_dir = Environment.get_upload_dir(ticket=ticket) # can't rely on that #ticket = Environment.get_ticket() asset_temp_dir = "%s/temp/%s" % (Environment.get_asset_dir(), ticket) if not os.path.exists(asset_temp_dir): os.makedirs(asset_temp_dir) from_path = "%s/%s" % (upload_dir, filename) icon_creator = IconCreator(from_path) icon_creator.execute() icon_path = icon_creator.get_icon_path() to_path = "%s/%s" % (asset_temp_dir, filename) if icon_path: shutil.copy(icon_path, to_path) my.info = { "web_path": "/assets/temp/%s/%s" % (ticket, filename), "lib_path": to_path } else: my.info = {}
def get_side_bar_cache(my, 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 execute(self): web = self.get_web() keys = web.get_form_keys() file_name = self.kwargs.get("file_name") # process and get the uploaded files dir = Environment.get_upload_dir() license_file = "%s/%s" % (dir, file_name) if not os.path.exists(license_file): raise TacticException("Error retrieving the license file in [%s]"%license_file) std_name = 'tactic-license.xml' head, file_name = os.path.split(license_file) # no restrictions for license file #if file_name != std_name: # raise TacticException("License file name should be named tactic-license.xml. The file given is [%s]" %file_name) license_dir = Environment.get_license_dir() current_license = "%s/%s" %(license_dir, std_name) if os.path.exists(current_license): FileUndo.remove(current_license) FileUndo.move(license_file, current_license) self.add_description('Renewed license file') security = Environment.get_security() security.reread_license()
def get_display(my): widget = Widget() if not my.select: return widget if not my.schema: Environment.add_warning("No schema defined") widget.add("No schema defined") return widget if not my.search_type: Environment.add_warning("HierarchicalFilterWdg: Cannot find current search_type") widget.add("Cannot find current search_type") return widget span = SpanWdg(css="med") parent_type = my.get_parent_type() if parent_type: parent_type_obj = SearchType.get(parent_type) span.add("%s: " % parent_type_obj.get_value("title")) # assume that there is a code in the parent my.select.add_empty_option("-- Select --") my.select.set_option("query", "%s|code|code" % my.parent_type) span.add(my.select) widget.add(span) return widget
def main(): install_dir = tacticenv.get_install_dir() version = Environment.get_release_version() api_version = Environment.get_release_api_version() client_api_dir = '%s/src/client' % install_dir context_client_dir = '%s/src/context/client' % install_dir print "install: ", install_dir print "version: ", version # copy scm directory in api scm_dir = "%s/src/tactic/scm" % install_dir client_dir = "%s/src/client" % install_dir to_scm_dir = "%s/src/client/tactic_client_lib/scm" % install_dir if os.path.exists(to_scm_dir): shutil.rmtree(to_scm_dir) shutil.copytree(scm_dir, to_scm_dir) # create the client api zip package into context/client dir path = "%s/src/context/client/tactic-api-%s.zip" % (install_dir, api_version) if os.path.exists(path): os.system('''rm "%s"''' % path) os.system('''cd "%s"; zip -r "%s" "tactic_client_lib"''' % (client_api_dir, path) ) # copy the client api into the standalone minimal python from_dir = '%s/src/client/tactic_client_lib' % install_dir python = '%s/src/client/python-3.6.6-win32-minimal' % install_dir to_dir = '%s/Lib/site-packages/tactic_client_lib' % python if os.path.exists(to_dir): shutil.rmtree(to_dir) shutil.copytree(from_dir, to_dir) # copy and rename to the api version to_name = "tactic-api-python-%s" % api_version to_dir = os.path.dirname(python) + "/" + to_name; if os.path.exists(to_dir): shutil.rmtree(to_dir) shutil.copytree(python, to_dir) # zip this up to_dir = os.path.dirname(python) zip_path = "%s/%s.zip" % (to_dir, to_name) if os.path.exists(zip_path): os.unlink(zip_path) os.system('''cd "%s"; zip -r "%s.zip" "%s"''' % (to_dir, to_name, to_name) ) shutil.rmtree("%s/%s" % (to_dir, to_name) ) # final_path = "%s/%s.zip" % (context_client_dir, to_name) if os.path.exists(final_path): os.unlink(final_path) print(zip_path, final_path) shutil.move(zip_path, final_path)
def get_file_contents(version_filename): env = Environment() install_dir = env.get_install_dir() path = '/src/client/tactic_client_lib' fullPath = install_dir + path + '/' + version_filename f = open(fullPath, 'r') version_string = f.read() f.close() return version_string
def handle_path(my, src_path): src_path = src_path.replace("\\", "/") # upload folder basename = os.path.basename(src_path) if my.mode =='copy': target_path = src_path target_dir = os.path.dirname(target_path) else: target_dir = Environment.get_upload_dir() target_path = "%s/%s" % (target_dir, basename) base_dir = Environment.get_template_dir() template_dir = "%s/%s" % (base_dir, my.project_code) if os.path.exists(template_dir): shutil.rmtree(template_dir) #raise TacticException("Template is already installed at [%s]" %template_dir) # unzip the file from pyasm.common import ZipUtil # this is fixed for windows if zipping doesn't use compression paths = ZipUtil.extract(target_path) # veryify that the paths extracted are the expected ones rootname, ext = os.path.splitext(basename) # check if it unzips at the templates folder directly unzip_at_template_dir = False # move the plugin zip file to the appropriate folder if my.mode == 'copy': # if they manually drop the zip file already here, skip if target_dir != base_dir: shutil.copy(target_path, base_dir) else: unzip_at_template_dir = True else: shutil.move(target_path, base_dir) # move unzipped files into the plugin area # remove any version info, only allow 1 particular version installed for now import re rootname = re.sub('(.*)(-)(\d.*)', r'\1', rootname) unzip_path = "%s/%s" % (target_dir, rootname) dest_dir = '%s/%s'%(base_dir, rootname) if not unzip_at_template_dir and os.path.exists(dest_dir): shutil.rmtree(dest_dir) shutil.move(unzip_path, dest_dir)
def execute(self): self.section = None # make sure tmp config is unset. Config.unset_tmp_config() Config.reload_config() web = WebContainer.get_web() # read the current config file. # copy config to the path config_path = Config.get_config_path() if not os.path.exists(config_path): print "Installing default config file" dirname = os.path.dirname(config_path) if not os.path.exists(dirname): os.makedirs(dirname) if os.name == 'nt': osname = 'win32' else: osname = 'linux' install_dir = Environment.get_install_dir() install_config_path = "%s/src/install/start/config/tactic_%s-conf.xml" % ( install_dir, osname) shutil.copy(install_config_path, dirname) try: self.configure_db() self.configure_install() self.configure_mail_services() self.configure_gen_services() self.configure_asset_dir() self.configure_palette() self.configure_security() except Exception as e: raise TacticException('Error in [%s]: %s'%(self.section, e.__str__())) # FIXME: if this all fails, then revert back self.save_config() # after saving the config, test the database self.load_bootstrap() # remove the first run file data_dir = Environment.get_data_dir() path = "%s/first_run" % data_dir if os.path.exists(path): os.unlink(path) self.restart_program()
def _test_guest_allow(self): '''test Config tag allow_guest in security tag. Note: Since it is hard to emulate AppServer class, this is based on logic which handles in _get_display of BaseAppServer. 1. If allow_guest is false, then it is necessary that Sudo is instantiated. 2. If allow_guest is true, then it is necessary that guest login rules are added and login_as_guest is executed. ''' security = Security() Environment.set_security(security) #1. allow_guest is false fail = False try: sudo = Sudo() except Exception as e: fail = True self.assertEquals( False, fail ) sudo.exit() key = [{'code': "*"}] project_access = security.check_access("project", key, "allow") self.assertEquals(project_access, False) #2. allow_guest is true Site.set_site("default") try: security.login_as_guest() ticket_key = security.get_ticket_key() access_manager = security.get_access_manager() xml = Xml() xml.read_string(''' <rules> <rule column="login" value="{$LOGIN}" search_type="sthpw/login" access="deny" op="!=" group="search_filter"/> <rule group="project" code="default" access="allow"/> </rules> ''') access_manager.add_xml_rules(xml) finally: Site.pop_site() default_key = [{'code': "default"}] project_access = security.check_access("project", default_key, "allow") self.assertEquals(project_access, True) unittest_key = [{'code', "sample3d"}] project_access = security.check_access("project", unittest_key, "allow") self.assertEquals(project_access, False)
def get_display(my): alias = my.kwargs.get("alias") my.rel_path = my.kwargs.get("rel_path") if not my.rel_path: from tactic_client_lib import TacticServerStub server = TacticServerStub.get(protocol="local") my.rel_path = server.get_doc_link(alias) if not my.rel_path or my.rel_path == "none_found": # raise TacticException("Help alias [%s] does not exist" % alias) layout = DivWdg() layout.add(HelpCreateWdg(alias=alias)) layout.add(HelpDocFilterWdg(alias="main")) return layout # special condition for plugins path if my.rel_path.startswith("/plugins/"): plugin_dir = Environment.get_plugin_dir() rel_path = my.rel_path.replace("/plugins/", "") path = "%s/%s" % (plugin_dir, rel_path) elif my.rel_path.startswith("/builtin_plugins/"): plugin_dir = Environment.get_builtin_plugin_dir() rel_path = my.rel_path.replace("/builtin_plugins/", "") path = "%s/%s" % (plugin_dir, rel_path) elif my.rel_path.startswith("/assets/"): asset_dir = Environment.get_asset_dir() rel_path = my.rel_path.replace("/assets/", "") path = "%s/%s" % (asset_dir, rel_path) else: # see if there is an override doc_dir = os.environ.get("TACTIC_DOC_DIR") if not doc_dir: doc_dir = Config.get_value("install", "doc_dir") if not doc_dir: install_dir = Environment.get_install_dir() doc_dir = "%s/doc" % install_dir path = "%s/%s" % (doc_dir, my.rel_path) html = [] try: f = open(path, "r") count = 0 for line in f: line = my.filter_line(line, count) html.append(line) count += 1 f.close() except Exception, e: print "Error processing: ", e html.append("Error processing document: %s<br/><br/>" % str(e))
def print_file_location_msg(): env = Environment() install_dir = env.get_install_dir() print ' The version files are located here:' print ' %s/VERSION' % install_dir print ' %s/src/context/VERSION' % install_dir print ' %s/src/client/tactic_client_lib/VERSION' % install_dir print ' %s/src/pyasm/application/common/interpreter/tactic_client_lib/VERSION' % install_dir print '' print ' The client tactic.zip is located here:' print ' %s/src/client/tactic_client_lib/tactic.zip' % install_dir
def init(self): self.task_code = self.kwargs.get('task_code', '') self.task_pipelines = '' self.parent_sk = self.kwargs.get('parent_sk', '') self.parent_pyclass = '' self.order_sk = self.kwargs.get('order_sk', '') self.groups = Environment.get_group_names() if 'user' in self.kwargs.keys(): self.user = str(self.kwargs.get('user')) else: self.user = Environment.get_user_name()
def init(my): nothing = 'true' my.server = None my.login = Environment.get_login() my.groups_arr = Environment.get_group_names() my.groups_str = '' for guy in my.groups_arr: if my.groups_str == '': my.groups_str = guy else: my.groups_str = '%s,%s' % (my.groups_str, guy) my.user_name = my.login.get_login()
def get_by_code(cls, code, allow_default=False): '''it is fatal not to have a pipeline, so put a default''' if not code: return None # first look at project specific pipeline pipeline = Search.get_by_code("config/pipeline", code) if not pipeline: pipeline = super(Pipeline,cls).get_by_code(code) if not pipeline and code == 'task': # Create a default task pipeline pipeline = SearchType.create("sthpw/pipeline") pipeline.set_value("code", "task") from pyasm.biz import Task xml = Task.get_default_task_xml() pipeline.set_value("pipeline", xml) pipeline.set_pipeline(xml) pipeline.set_value("search_type", "sthpw/task") #pipeline.commit() if not pipeline and allow_default: search = Search(cls) search.add_filter('code', 'default') pipeline = search.get_sobject() if not pipeline: pipeline = cls.create('default', \ 'default pipeline', '') xml = pipeline.get_xml_value("pipeline") # create a default process for the table root = xml.get_root_node() element = xml.create_element("process") Xml.set_attribute(element,"name", "default_process") Xml.append_child(root, element) pipeline.set_value('pipeline', xml.get_xml()) pipeline.commit() # set the pipeline pipeline.set_pipeline(pipeline.get_value('pipeline')) Environment.add_warning("pipeline autogenerated", \ "[default] pipeline has just been created.") # Sometimes, a pipeline is instantiated without calling set_pipeline() # to be looked into if pipeline and not pipeline.get_processes(): pipeline.set_pipeline(pipeline.get_value('pipeline')) return pipeline
def convert_upgrade(self, namespace): self.namespace = namespace upgrade_dir = Environment.get_upgrade_dir() tmp_dir = Environment.get_tmp_dir() src_path ="%s/project/%s_upgrade.py" % (upgrade_dir, namespace) dst_path = "%s/upgrade/%s/%s_upgrade.py" % (tmp_dir, self.vendor, namespace) self.convert_file(src_path, dst_path) return dst_path
def __init__(self, ticket=None): super(TacticInit,self).__init__() self.ticket = ticket # create the main container Container.create() Environment.set_env_object( self ) # set up the security object security = Security() Environment.set_security(security)
def _test_sobject_access_manager(my): '''test a more realistic example''' # create a test person person = Person.create("Donald", "Duck", "DisneyLand", "A duck!!!") my.person = person for project_code in ['unittest', 'unittest', 'sample3d']: task = SearchType.create('sthpw/task') task.set_sobject_value(person) task.set_value('assigned', 'unittest_guy') task.set_value('project_code', project_code) task.set_value('description', 'do something good') task.set_value('process', 'unittest') task.set_value('context', 'unittest') task.commit() # an extra task for list-based search_filter test task = SearchType.create('sthpw/task') task.set_sobject_value(person) task.set_value('assigned', 'unittest_gal') task.set_value('project_code', 'unittest') task.set_value('description', 'do something good') task.set_value('process', 'unittest2') task.set_value('context', 'unittest2') task.commit() # add these rules to the current user rules = """ <rules> <rule group="sobject_column" default="edit"/> <rule group="sobject_column" search_type="unittest/person" column="name_first" access="edit"/> <rule group="sobject_column" search_type="unittest/person" column="name_last" access="deny"/> <rule group="sobject_column" search_type="unittest/person" column="nationality" access="deny"/> </rules> """ xml = Xml() xml.read_string(rules) access_manager = Environment.get_security().get_access_manager() access_manager.add_xml_rules(xml) # disable admin for this test access_manager.set_admin(False) # should succeed person.set_value("name_first", "Donny") # should fail try: person.set_value("name_last", "Ducky") except SecurityException, e: pass
def filter_sobjects(self, orig_sobjects): # look for groups that are relevant groups = Environment.get_security().get_groups() login = Environment.get_security().get_login() # either we are user centric or process centric user = login.get_value("login") sobjects = [] # filter out sobjects that do not have appropriate tasks if orig_sobjects: search_type = orig_sobjects[0].get_search_type() ids = [str(x.get_id()) for x in orig_sobjects] search = Search("sthpw/task") search.add_filter("search_type", search_type) search.add_where("search_id in (%s)" % ",".join(ids)) # get only tasks assigned to a user show_assigned_only = True if show_assigned_only: search.add_filter("assigned", user) search.add_where("status in ('Pending','In Progress')") search.add_where("status is NULL") tasks = search.get_sobjects() task_search_ids = [int(x.get_value("search_id")) for x in tasks] # once we have all of the tasks for this episode, we filter # out any assets that don't have these tasks for orig_sobject in orig_sobjects: search_id = orig_sobject.get_id() if search_id in task_search_ids: sobjects.append(orig_sobject) return sobjects
def __init__(my, project_code=None, login_code=None): my.set_app_server("batch") super(Batch, my).__init__() my.login_code = login_code # clear the main container Container.create() # set this as the environment if not project_code: my.context = my.get_default_context() else: my.context = project_code Environment.set_env_object(my) # set up the security object security = Security() Environment.set_security(security) my._do_login() site_dir = Environment.get_site_dir() if site_dir not in sys.path: sys.path.insert(0, site_dir) # set the project from pyasm.biz import Project if my.context == "batch": Project.set_project("admin") else: Project.set_project(my.context) my.initialize_python_path() DbContainer.commit_thread_sql()
def _parse_form(my): # get the downloaded files and sort them web = WebContainer.get_web() my.upload_values.sort() filenames = [] ticket = web.get_cookie("login_ticket") # create a new entry for every file for upload_value in my.upload_values: tmp_dir = Environment.get_tmp_dir() basename = os.path.basename(upload_value) file_path = "%s/upload/%s/%s" % (tmp_dir, ticket, basename) filenames.append(basename) creator = IconCreator(file_path) creator.create_icons() my.file_paths = [file_path] file_types = ["main"] web_path = creator.get_web_path() if web_path != None: my.file_paths.append(web_path) file_types.append("web") icon_path = creator.get_icon_path() if icon_path != None: my.file_paths.append(icon_path) file_types.append("icon") sobject = None if my.search_key: sobject = Search.get_by_search_key(my.search_key) else: sobject = SObjectFactory.create(my.search_type) sobject.commit() checkin = FileCheckin( sobject, my.file_paths, file_types,\ column=my.column ) checkin.set_description(web.get_form_value(SObjectUploadCmd.PUBLISH_COMMENT)) checkin.execute() my.repo_file_list.append(checkin.file_dict) my.description = "Added files: %s" % filenames
def get_display(my): sobject = my.get_current_sobject() try: import qb except ImportError: Environment.add_warning("Qube not installed", "Qube not installed") return "---" dispatcher_id = sobject.get_value("dispatcher_id") all_jobinfo = qb.jobinfo(filters={'id': dispatcher_id}) if not all_jobinfo: return "---" job_info = all_jobinfo[0] status = job_info.get('status') timestart = job_info.get('timestart') timecomplete = job_info.get('timecomplete') timeelapsed = int(timecomplete) - int(timestart) return "%s (%ss)" % (status, timeelapsed)
def upgrade(): print "Running upgrade on 'sthpw' database" install_dir = Environment.get_install_dir() from pyasm.common import Config python = Config.get_value("services", "python") if not python: python = "python" cmd = "%s \"%s/src/bin/upgrade_db.py\" -f -y -p sthpw" % (python, install_dir) print cmd os.system(cmd)
def execute(my): web = WebContainer.get_web() # get the input names input_names = web.get_form_value(SerialStatusWdg.STATUS_CMD_INPUT).split('|') values = [] for input_name in input_names: value = web.get_form_value(input_name) if value: values.append(web.get_form_value(input_name)) # FIXME: HARDCODED Value for status column!!!! column = "status" for value in values: # get the sobject to be updated search_type,id,status = value.split("|") search = Search(search_type) search.add_id_filter(id) my.sobject = search.get_sobject() status_attr = my.sobject.get_attr(column) cur_status = status_attr.get_current_process() if cur_status == status: continue status_attr.set_status(status) update_column = 'time_update' if update_column in my.sobject.get_attr_names(): my.sobject.set_value(update_column, Sql.get_timestamp_now(), quoted=False) my.sobject.commit() # if this is successful, the store it in the status_log status_log = SObjectFactory.create("sthpw/status_log") status_log.set_value("login", Environment.get_user_name() ) status_log.set_value("search_type", search_type) status_log.set_value("search_id", id) #status_log.set_value("status", "%s to %s" % (cur_status, status) ) status_log.commit() status_log.set_value("from_status", cur_status) status_log.set_value("to_status", status) # Call the finaled trigger Trigger.call(my, status)
def get_display(self): paths = self.get_files() top = self.top top.add_style("padding: 10px") top.add_color("background", "background") top.add_style("min-width: 500px") top.add_style("font-size: 12px") top.add_class("spt_sobject_dir_list_top") self.set_as_panel(top) inner = DivWdg() top.add(inner) show_title = self.kwargs.get("show_title") if show_title not in [False, 'false']: title_wdg = DivWdg() inner.add(title_wdg) title_wdg.add("File Browser [%s]" % self.sobject.get_code()) title_wdg.add_color("background", "background3") title_wdg.add_style("padding: 16px 10px") title_wdg.add_style("margin: -10px -10px 10px -10px") title_wdg.add_style("font-weight: bold") show_shelf = self.kwargs.get("show_shelf") if show_shelf not in [False, 'false']: shelf_wdg = DivWdg() inner.add(shelf_wdg) shelf_wdg.add(self.get_shelf_wdg()) shelf_wdg.add_style("padding: 5px") shelf_wdg.add_style("margin: -5px -5px 15px -5px") shelf_wdg.add_style("font-weight: bold") base_dir = Environment.get_asset_dir() dir_list = SnapshotDirListWdg(base_dir=base_dir, location="server", show_base_dir=True, paths=paths, all_open=True, files=self.files, snapshots=self.snapshots) inner.add(dir_list) if self.kwargs.get("is_refresh"): return inner else: 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 get_remote_repo(self): # remote repo does not make sense in batch mode if Environment.get_app_server() == 'batch': return remote_repos = Container.get("remote_repos") if remote_repos == None: search = Search("sthpw/remote_repo") remote_repos = search.get_sobjects() Container.put("remote_repos", remote_repos) # TODO: Get this function out of this class # THIS function requires the web from pyasm.web import WebContainer web = WebContainer.get_web() if not web: return None # if a login name is found, use that instead of doing the more # stringent IP match current_user = Environment.get_user_name() simple_remote_repo = RemoteRepo.get_by_login(current_user) if simple_remote_repo: return simple_remote_repo src_ip = web.get_request_host() if not src_ip: return for remote_repo in remote_repos: tgt_ip = remote_repo.get_value("ip_address") mask = remote_repo.get_value("ip_mask") if Common.match_ip(src_ip, tgt_ip, mask): return remote_repo return None
def create(src_sobject, dst_sobject, context="reference", direction="both"): project_code = Project.get_project_code() if not context: context = "reference" # ensure that the connection doesn't already exist search = Search("sthpw/connection") search.add_sobject_filter(src_sobject, prefix="src_") search.add_sobject_filter(dst_sobject, prefix="dst_") if search.get_count(): Environment.add_warning("Already connected", "%s is already connected to %s" % (src_sobject.get_code(), dst_sobject.get_code() ) ) return connection = SearchType.create("sthpw/connection") connection.set_value("src_search_type", src_sobject.get_search_type() ) connection.set_value("dst_search_type", dst_sobject.get_search_type() ) connection.set_value("src_search_id", src_sobject.get_id() ) connection.set_value("dst_search_id", dst_sobject.get_id() ) connection.set_value("context", context) connection.set_value("project_code", project_code) connection.commit() if direction == "both": connection = SearchType.create("sthpw/connection") connection.set_value("src_search_type", dst_sobject.get_search_type() ) connection.set_value("dst_search_type", src_sobject.get_search_type() ) connection.set_value("src_search_id", dst_sobject.get_id() ) connection.set_value("dst_search_id", src_sobject.get_id() ) connection.set_value("context", context) connection.set_value("project_code", project_code) connection.commit() return connection
def get_display(my): top_div = DivWdg() top_div.add_styles("text-align: center") top_div.add_style("margin-top: 10px") top_div.add_style("opacity: 0.5") top_div.add_style("font-size: 10px") tactic_span = SpanWdg() tactic_span.add( "TACTIC®" ) rel_span = SpanWdg() rel_span.add( " Release %s" % Environment.get_release_version() ) top_div.add( tactic_span ) top_div.add( rel_span ) top_div.add( " © 2005-2013, Southpaw Technology Inc. All Rights Reserved. " ) show_license_info = my.kwargs.get("show_license_info") if show_license_info: security = Environment.get_security() if security: license = Environment.get_security().get_license() company = license.get_data("company") if company.startswith('ALL'): lic_type = '' tmps = company.split('-') if tmps: lic_type = tmps[-1] lic_type = lic_type.strip() license_text = "Open Source License - %s" %lic_type else: license_text = "Licensed to %s" % company else: license_text = "No License" top_div.add( license_text ) top_div.add("<br/>"*2) return top_div
def init(self): install_dir = Environment.get_install_dir() # initialize js = ''' <!-- TACTIC --> // Fixes var spt = {}; spt.browser = {}; spt.browser.is_IE = function() { return false; } spt.error = function(error) { throw(error); } ''' self.ctx.eval(js) sources = ["environment.js", "client_api.js"] for source in sources: #path = "tactic/%s" % source path = "%s/src/context/spt_js/%s" % (install_dir, source) js = open(path).read() self.ctx.eval(js) js = ''' spt._delegate = function(func_name, args, kwargs) { // convert everything to json var args2 = []; for (var i in args) { args2.push(args[i]); } if (typeof(kwargs) == "undefined") { kwargs = {}; } args2 = JSON.stringify(args2); kwargs = JSON.stringify(kwargs); var ret_val = spt_delegator.execute(func_name, args2, kwargs); ret_val = JSON.parse(ret_val); return ret_val; } var server = TacticServerStub.get(); ''' self.ctx.eval(js)
def postprocess(my): if my.sobject.is_general_asset(): return # check to see if there are any snapshots # context is specified here to ignore any icon snapshots snapshot = Snapshot.get_latest_by_sobject(my.sobject, context='publish') if snapshot: return column = "snapshot" new_file_paths = [] file_paths = [] # copy the default file to /tmp template_code = my.get_default_code() template = my.get_template_obj() if template: template_code = template.get_value('code') tmpl_snapshot = Snapshot.get_latest_by_sobject(template) file_paths = tmpl_snapshot.get_all_lib_paths() else: file_types = ['.fla', '.png', '_icon.png', '.swf'] # TODO: this is a web depedency we don't need from pyasm.web import WebContainer web = WebContainer.get_web() for type in file_types: file_paths.append('%s/template/%s%s' % (web.get_context_dir(), \ template_code, type)) for file_path in file_paths: # rename and copy each file to /tmp base_name = os.path.basename(file_path) base_name = File.remove_file_code(base_name) base_name = base_name.replace(template_code, \ my.get_naming().get_current_code(my.sobject) ) # do a straight copy : No undo tmp_dir = Environment.get_tmp_dir() new_file_path = "%s/download/%s" % (tmp_dir, base_name) shutil.copyfile(file_path, new_file_path) new_file_paths.append(new_file_path) file_types = [".fla", ".png", "icon", ".swf"] checkin = FileCheckin( my.sobject, new_file_paths, file_types, \ snapshot_type="flash", column=column ) checkin.execute()
def convert_bootstrap(self): upgrade_dir = Environment.get_upgrade_dir() file_names = [ "bootstrap_schema.sql", "sthpw_schema.sql", "config_schema.sql" ] for file_name in file_names: src_file = "%s/postgresql/%s" % (upgrade_dir, file_name) dst_file = "%s/%s/%s" % (upgrade_dir, self.vendor.lower(), file_name) print "Converting .." print " from: ", src_file print " to: ", dst_file self.convert_file(src_file, dst_file)
def _check(my): # This will kill the TACTIC process # This is very harsh and should be used sparingly if at all use_restart = Config.get_value("services", "use_periodic_restart") if use_restart in [True, 'true']: if my.num_checks and my.num_checks % my.kill_interval == 0: # read pid file log_dir = "%s/log" % Environment.get_tmp_dir() file = open("%s/pid.%s" % (log_dir,my.port), "r") pid = file.read() file.close() print "Killing process: ", pid Common.kill(pid) #my.run() my.num_checks += 1 return my.num_checks += 1 start = time.clock() try: response = my.check() except IOError, e: print "Tactic IOError: ", str(e) # Kill if unresponsive ... (only on linux) log_dir = "%s/log" % Environment.get_tmp_dir() file = open("%s/pid.%s" % (log_dir,my.port), "r") pid = file.read() file.close() print "Killing process: ", pid Common.kill(pid)
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 _do_login(my): allow_guest = Config.get_value("security", "allow_guest") if allow_guest == 'true': allow_guest = True else: allow_guest = False security = Environment.get_security() ticket = security.login_with_ticket(my.ticket, allow_guest=allow_guest) if not ticket: raise SecurityException( "Cannot login with key: %s. Session may have expired." % my.ticket)
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_source_link(self, node): search_type = Xml.get_attribute(node, "search_type") search_id = Xml.get_attribute(node, "search_id") context = Xml.get_attribute(node, "context") version = Xml.get_attribute(node, "version") source_snapshot = Snapshot.get_by_version(search_type, search_id, \ context, version ) if not source_snapshot: Environment.add_warning("Snapshot not found", "Reference snapshot for [%s|%s] does not exist" \ % (search_type, search_id) ) return '' #raise WidgetException( "Reference snapshot in '%s' does not exist" \ # % snapshot.get_id() ) source = source_snapshot.get_sobject() # get the file link file_name = source_snapshot.get_name_by_type("main") path = "%s/%s" % (source_snapshot.get_web_dir(), file_name) return HtmlElement.href("Source: %s" %source.get_value("code"), \ ref=path )
def get_display(self): top = self.top top.add_style("padding: 10px") top.add_color("background", "background", -5) top.add_style("min-width: 600px") paths = self.get_files() # assume that all the paths are part of the same repo repo = 'tactic' for file in self.files.values(): repo = file.get_value("repo_type", no_exception=True) break if repo == 'perforce': search_key = self.kwargs.get("search_key") sobject = SearchKey.get_by_search_key(search_key) project = sobject.get_project() depot = project.get_value("location", no_exception=True) if not depot: depot = project.get_code() location = '//%s' % depot dir_list = SnapshotDirListWdg(base_dir=location, location="scm", show_base_dir=True, paths=paths, all_open=True, files=self.files, snapshots=self.snapshots) else: # If not discovered thru base_dir_alias, use the default if not self.base_dir: self.base_dir = Environment.get_asset_dir() dir_list = SnapshotDirListWdg(base_dir=self.base_dir, location="server", show_base_dir=True, paths=paths, all_open=True, files=self.files, snapshots=self.snapshots) top.add(dir_list) return top
def __init__(self, project_code=None, login_code=None, site=None): self.set_app_server("batch") if not site: # if not explicitly set, keep the current site site = Site.get_site() plugin_dir = Environment.get_plugin_dir() if plugin_dir not in sys.path: sys.path.insert(0, plugin_dir) super(Batch,self).__init__() self.login_code = login_code # clear the main container Container.create() if site: Site.set_site(site) # set this as the environment if not project_code: self.context = self.get_default_context() else: self.context = project_code Environment.set_env_object( self ) # set up the security object security = Security() Environment.set_security(security) self._do_login() site_dir = Environment.get_site_dir() if site_dir not in sys.path: sys.path.insert(0, site_dir) # set the project from pyasm.biz import Project if self.context == "batch": Project.set_project("admin") else: Project.set_project(self.context) self.initialize_python_path() # start workflow engine #from pyasm.command import Workflow #Workflow().init() DbContainer.commit_thread_sql()
def __init__(self, num_processes=None): self.check_interval = 120 self.startup = True self.num_processes = num_processes self.dev_mode = False import sys plugin_dir = Environment.get_plugin_dir() sys.path.insert(0, plugin_dir) sql = DbContainer.get("sthpw") # before batch, clean up the ticket with a NULL code sql.do_update('DELETE from "ticket" where "code" is NULL;') self.tactic_threads = [] self.mode = 'normal'
def generate(color): # find the base path tactic_base = Environment.get_install_dir() basedir = "%s/src/context/ui_proto/roundcorners/rc_%s" % ( tactic_base, color.replace("#", "")) basename = "rc_%s_10x10" % color cmd = CornerGenerator(color=color, basedir=basedir, basename=basename) cmd.execute() basename = "rc_%s_5x5" % color cmd = CornerGenerator(color=color, basedir=basedir, basename=basename, size=5) cmd.execute()
def execute(my): assert my.snapshot assert my.sobject # add some additional options my.set_option("snapshot_code", my.snapshot.get_code()) my.set_option("render_dir", my.get_render_dir()) input_path = my.get_input_path() my.set_option("input_path", input_path) # handle the policy if it exists policy = my.render_package.get_policy() if policy: width = policy.get_value("width") height = policy.get_value("height") frame_by = policy.get_value("frame_by") extra_settings = policy.get_value("extra_settings") my.set_option("resolution", "%sx%s" % (width, height)) my.set_option("width", width) my.set_option("height", height) my.set_option("frame_by", frame_by) my.set_option("extra_settings", extra_settings) # get some information from the render context search_type = my.sobject.get_search_type_obj() description = "Render %s: %s" % (search_type.get_title(), my.sobject.get_code()) # create queue in tactic related to this submission if not my.queue: my.queue = Queue.create(my.sobject, "render", "9999", description) else: my.queue.set_sobject_value(my.sobject) my.queue.set_value('login', Environment.get_user_name()) # have to make sure it is committed to get a queue_id if my.queue.get_id() == -1: my.queue.commit() # submit the job to the dispatcher dispatcher_id = my.submit() # store the dispatcher id in the queue object my.queue.set_value("dispatcher_id", dispatcher_id) my.queue.commit()
def get_display(self): top = DivWdg() hash = self.kwargs.get("hash") pathname = self.kwargs.get("pathname") 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: widget = self.get_default_wdg() top.add(widget) # This would provide a way to get the default index widget. #elif hash == "/projects": # widget = self.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 = self.get_default_wdg() else: from pyasm.security import Site widget = HashPanelWdg.get_widget_from_hash(hash, return_none=True) if not widget: if hash == "/index": widget = self.get_default_wdg() elif hash == '/admin': widget = self.get_default_wdg() else: widget = HashPanelWdg.get_widget_from_hash( "/index", return_none=True) top.add(widget) return top
def execute(self): template = self.kwargs.get("template") template_dir = Environment.get_template_dir() template = self.kwargs.get("template") from pyasm.search import FileUndo path = "%s/%s-1.0.0.zip" % (template_dir, template) if not os.path.exists(path): raise Exception("Path [%s] does not exists" % path) FileUndo.remove(path) path = "%s/%s" % (template_dir, template) FileUndo.remove(path)
def get_display(my): if not my.html_file: return "" utility_path = "%s/src/context/utility" % Environment.get_install_dir() html_templates_path = "%s/templates" % utility_path custom_template_path = "%s/site_custom" % utility_path if my.content_type == 'title': return my.page_title elif my.content_type == 'body': body_template_fp = open( "%s/print_custom_page_TEMPLATE_body_contents.html" % html_templates_path, "r") body_template = body_template_fp.read() body_template_fp.close() layout_html_fp = open( "%s/%s" % (custom_template_path, my.html_file), "r") layout_html = layout_html_fp.read() layout_html_fp.close() layout_bits = layout_html.split("[[DATA_GATHER]]") layout_html = "%s%s" % (layout_bits[0], layout_bits[2]) stmt = layout_bits[1].strip() stmt_bits = stmt.split("\n") stmt_arr = [] for s in stmt_bits: stmt_arr.append(s.strip()) stmt = '\n'.join(stmt_arr) exec stmt # assigns 'gather_specs' dictionary ... layout_html_filled = my.process_data_gather( my.search_key, gather_specs, layout_html) body_html = body_template.replace("[[PRINT_LAYOUT_PLACEHOLDER]]", layout_html_filled) return body_html return "" # FIXME: should error or return some error message
def get_user_projects(cls): search = Search("sthpw/project") projects = search.get_sobjects() security = Environment.get_security() key = {"code": "*"} if security.check_access("project", key, "allow", default="deny"): return projects # which projects is a user allowed to see allowed = [] for project in projects: key = {"code": project.get_code()} if security.check_access("project", key, "allow", default="deny"): allowed.append(project) return allowed
def get_view_menu(self): is_admin = False security = Environment.get_security() if security.check_access("builtin", "view_site_admin", "allow"): is_admin = True menu_items = [ { "type": "action", "label": "Save Current View", "bvr_cb": { 'cbjs_action': "spt.dg_table.view_action_cbk('save','%s', bvr);" % self.table_id, 'is_admin': is_admin } }, { "type": "action", "label": "Save My View As...", "bvr_cb": { 'cbjs_action': "spt.dg_table.view_action_cbk('add_my_view','%s', bvr);" % self.table_id } }, ] if is_admin: menu_items.insert( 2, { "type": "action", "label": "Save Project View As ...", "bvr_cb": { 'cbjs_action': "spt.dg_table.view_action_cbk('save_project_view','%s', bvr);" % self.table_id } }) return { 'menu_id': 'ActionBar_ViewMenu_Main', 'width': 150, 'allow_icons': False, 'opt_spec_list': menu_items }