def handle_td(self, td): sobj = self.get_current_sobject() parent = None value = sobj.get_value('process') td.add_attr('spt_input_value', value) if sobj.is_insert(): state = self.get_state() parent_key = state.get('parent_key') if parent_key: parent = SearchKey.get_by_search_key(parent_key) else: # get the parent pipeline code try: parent = sobj.get_parent() except SObjectSecurityException as e: print "SObjectSecurityException raised for getting parent of [%s]" %sobj.get_code() pass except SearchException as e: if e.__str__().find('not registered') != -1: pass elif e.__str__().find('does not exist for database') != -1: pass else: raise except Exception as e: print "WARNING: ", e if parent: pipeline_code = parent.get_value("pipeline_code", no_exception=True) if pipeline_code: td.add_attr('spt_pipeline_code', pipeline_code)
def handle_td(my, td): sobj = my.get_current_sobject() parent = None value = sobj.get_value('process') td.add_attr('spt_input_value', value) if sobj.is_insert(): state = my.get_state() parent_key = state.get('parent_key') if parent_key: parent = SearchKey.get_by_search_key(parent_key) else: # get the parent pipeline code try: parent = sobj.get_parent() except SObjectSecurityException, e: print "SObjectSecurityException raised for getting parent of [%s]" % sobj.get_code( ) pass except SearchException, e: if e.__str__().find('not registered') != -1: pass elif e.__str__().find('does not exist for database') != -1: pass else: raise
def handle_td(self, td): sobject = self.get_current_sobject() parent = None if sobject.is_insert(): parent_key = self.state.get('parent_key') if parent_key: parent = SearchKey.get_by_search_key(parent_key) else: try: parent = sobject.get_parent() except SObjectSecurityException as e: pass except SearchException as e: if e.__str__().find('not registered') != -1: pass elif e.__str__().find('does not exist for database') != -1: pass else: raise process = sobject.get_value('process') current_value = sobject.get_value(self.get_name()) if current_value: value = '%s||%s'%(process, current_value) td.add_attr("spt_input_value", value) if parent: td.set_attr("spt_pipeline_code", parent.get_value("pipeline_code", no_exception=True))
def postprocess(my): web = WebContainer.get_web() value = web.get_form_value(my.get_input_name()) if not value: return # get all fo the sobjects from the search keys instance_type = my.get_option("instance_type") # path is used for self-relating in an instance table src_path = my.get_option("path") #src_sobject = my.sobject search = Search(my.sobject.get_search_type()) search.add_id_filter(my.sobject.get_id()) src_sobject = search.get_sobject() # this is passed in from EditCmd in insert mode parent_key = my.get_option('parent_key') # in some rare cases we have project as the parent_key if parent_key and my.is_insert and 'sthpw/project' not in parent_key: # this is the parent dst_sobject = SearchKey.get_by_search_key(parent_key) # add all the new sobjects #instances = dst_sobject.get_related_sobject(instance_type) instance = SearchType.create(instance_type) instance.add_related_connection(src_sobject, dst_sobject, src_path=src_path) instance.commit()
def get_files(self): paths = [] # remember this here for now self.files = {} self.snapshots = {} search_key = self.kwargs.get("search_key") sobject = SearchKey.get_by_search_key(search_key) # if it is deleted, return if not sobject: return [] if isinstance(sobject, Snapshot): snapshots = [sobject] else: snapshots = Snapshot.get_by_sobject(sobject, "publish") for snapshot in snapshots: snapshot_paths = snapshot.get_all_lib_paths() files = snapshot.get_all_file_objects() for path, file in zip(snapshot_paths, files): # if the path is a directory, get all of the files if os.path.isdir(path): for root, dirnames, filenames in os.walk(path): for filename in filenames: item_path = "%s/%s" % (root, filename) paths.append(item_path) self.files[item_path] = file self.snapshots[item_path] = snapshot for dirname in dirnames: item_path = "%s/%s/" % (root, dirname) paths.append(item_path) self.files[item_path] = file self.snapshots[item_path] = snapshot """ dirlist = os.listdir(path) for item in dirlist: item_path = "%s%s" % (path, item) if os.path.isdir(path): item_path = "%s/" % item_path paths.append(item_path) self.files[path] = file """ else: paths.append(path) self.files[path] = file base_dir_alias = file.get_value('base_dir_alias') if not self.base_dir and base_dir_alias: self.base_dir = Environment.get_asset_dir( alias=base_dir_alias) return paths
def init_kwargs(my): """initialize kwargs""" state = my.kwargs.get("state") if state: parent_key = state.get("parent_key") if parent_key: my.sobject = SearchKey.get_by_search_key(parent_key) my.expression = my.get_option("expression") if not my.expression: my.expression = my.kwargs.get("expression") my.alt_expression = my.get_option("alt_expression") if not my.alt_expression: my.alt_expression = my.kwargs.get("alt_expression") my.mode = my.get_option("mode") if not my.mode: my.mode = my.kwargs.get("mode") if not my.mode: my.mode = "value" my.show_retired = my.get_option("show_retired") if not my.show_retired: my.show_retired = my.kwargs.get("show_retired") # default to False if my.show_retired == "true": my.show_retired = True else: my.show_retired = False my.enable_eval_listener = False if my.get_option("enable_eval_listener") in [True, "true", "True", "TRUE"]: my.enable_eval_listener = True
def execute(my): plugin = my.sobject web = WebContainer.get_web() value = web.get_form_value( my.get_input_name() ) if not value: return src_search_keys = jsonloads(value) manifest = plugin.get_xml_value("manifest") top_node = manifest.get_node("manifest") for search_key in src_search_keys: sobject = SearchKey.get_by_search_key(search_key) node = manifest.create_element("sobject") # For now, a plugin must contain project specfic entries search_type = sobject.get_base_search_type() code = sobject.get_value("code") manifest.set_attribute(node, "search_type", search_type) manifest.set_attribute(node, "code", code) #search_key = SearchKey.get_by_sobject(sobject) #manifest.set_attribute(node, "search_key", search_key) manifest.append_child(top_node, node) plugin.set_value("manifest", manifest.to_string() ) plugin.commit()
def get_files(my): paths = [] # remember this here for now my.files = {} my.snapshots = {} search_key = my.kwargs.get("search_key") search_keys = my.kwargs.get("search_keys") if search_key: sobject = SearchKey.get_by_search_key(search_key) my.sobjects = [sobject] if search_keys: if isinstance(search_keys, basestring): search_keys = search_keys.replace("'", '"') search_keys = jsonloads(search_keys) my.sobjects = Search.get_by_search_keys(search_keys) if not my.sobjects: return [] my.sobject = my.sobjects[0] for sobject in my.sobjects: sobject_paths = my.get_sobject_files(sobject) paths.extend(sobject_paths) return paths
def postprocess(self): web = WebContainer.get_web() value = web.get_form_value( self.get_input_name() ) if not value: return # get all fo the sobjects from the search keys instance_type = self.get_option("instance_type") # path is used for self-relating in an instance table src_path = self.get_option("path") #src_sobject = self.sobject search = Search(self.sobject.get_search_type()) search.add_id_filter(self.sobject.get_id()) src_sobject = search.get_sobject() # this is passed in from EditCmd in insert mode parent_key = self.get_option('parent_key') # in some rare cases we have project as the parent_key if parent_key and self.is_insert and 'sthpw/project' not in parent_key: # this is the parent dst_sobject = SearchKey.get_by_search_key(parent_key) # add all the new sobjects #instances = dst_sobject.get_related_sobject(instance_type) instance = SearchType.create(instance_type) instance.add_related_connection(src_sobject, dst_sobject, src_path=src_path) instance.commit()
def check(my): search_key = my.kwargs.get('search_key') my.sobject = SearchKey.get_by_search_key(search_key) from pyasm.web import WebContainer web = WebContainer.get_web() my.old_password = web.get_form_value("old password") if isinstance(my.old_password, list): my.old_password = my.old_password[0] #encrypted = md5.new(my.old_password).hexdigest() encrypted = hashlib.md5(my.old_password).hexdigest() if encrypted != my.sobject.get_value('password'): raise UserException('Old password is incorrect.') my.password = web.get_form_value("password") if isinstance(my.password, list): my.password = my.password[0] if my.sobject == None: return UserException("Current user cannot be determined.") my.re_enter = web.get_form_value("password re-enter") if isinstance(my.re_enter, list): my.re_enter = my.re_enter[0] if my.re_enter != "" and my.re_enter != my.password: raise UserException( "Passwords must match. Please fill in the re-enter.") return True
def handle_td(my, td): sobj = my.get_current_sobject() parent = None value = sobj.get_value("process") td.add_attr("spt_input_value", value) if sobj.is_insert(): state = my.get_state() parent_key = state.get("parent_key") if parent_key: parent = SearchKey.get_by_search_key(parent_key) else: # get the parent pipeline code try: parent = sobj.get_parent() except SObjectSecurityException, e: print "SObjectSecurityException raised for getting parent of [%s]" % sobj.get_code() pass except SearchException, e: if e.__str__().find("not registered") != -1: pass elif e.__str__().find("does not exist for database") != -1: pass else: raise
def add_to_selected(cls, search_keys): # make sure the sobjects exist for search_key in search_keys: sobject = SearchKey.get_by_search_key(search_key) item = SearchType.create("sthpw/clipboard") item.set_user() item.add_related_sobject(sobject) item.set_value("category", "select") item.commit()
def execute(my): input = my.get_input() search_key = input.get("search_key") sobj = SearchKey.get_by_search_key(search_key) login_group = sobj.get_value('login_group') sobj.set_value('code', login_group) sobj.commit(triggers=False)
def execute(my): web = WebContainer.get_web() value = web.get_form_value( my.get_input_name() ) if not value: value = my.get_data() if not value: return src_search_keys = jsonloads(value) #print "xxx: ", type(src_search_keys), src_search_keys # get all fo the sobjects from the search keys #src_sobjects = SearchKey.get_by_search_keys(src_search_keys) instance_type = my.get_option("instance_type") # path is used for self-relating in an instance table src_path = my.get_option("path") src_sobjects = [] src_instances = [] for src_search_key in src_search_keys: src_sobject = SearchKey.get_by_search_key(src_search_key) if src_sobject.get_base_search_type() == instance_type: src_instances.append(src_sobject) else: src_sobjects.append(src_sobject) dst_sobject = my.sobject # get all of the current instances and see if any were removed instances = dst_sobject.get_related_sobjects(instance_type) for instance in instances: exists = False for src_instance in src_instances: if src_instance.get_search_key() == instance.get_search_key(): exists = True if not exists: instance.delete() # add all the new sobjects for src_sobject in src_sobjects: instance = SearchType.create(instance_type) instance.add_related_connection(src_sobject, dst_sobject, src_path=src_path) instance.commit()
def execute(self): web = WebContainer.get_web() value = web.get_form_value( self.get_input_name() ) if not value: value = self.get_data() if not value: return src_search_keys = jsonloads(value) #print "xxx: ", type(src_search_keys), src_search_keys # get all fo the sobjects from the search keys #src_sobjects = SearchKey.get_by_search_keys(src_search_keys) instance_type = self.get_option("instance_type") # path is used for self-relating in an instance table src_path = self.get_option("path") src_sobjects = [] src_instances = [] for src_search_key in src_search_keys: src_sobject = SearchKey.get_by_search_key(src_search_key) if src_sobject.get_base_search_type() == instance_type: src_instances.append(src_sobject) else: src_sobjects.append(src_sobject) dst_sobject = self.sobject # get all of the current instances and see if any were removed instances = dst_sobject.get_related_sobjects(instance_type) for instance in instances: exists = False for src_instance in src_instances: if src_instance.get_search_key() == instance.get_search_key(): exists = True if not exists: instance.delete() # add all the new sobjects for src_sobject in src_sobjects: instance = SearchType.create(instance_type) instance.add_related_connection(src_sobject, dst_sobject, src_path=src_path) instance.commit()
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(my): sobject = None if not my.sobjects: """ args = WebContainer.get_web().get_form_args() search_type = args['search_type'] search_id = args['search_id'] """ search_key = my.kwargs.get('search_key') if search_key: sobject = SearchKey.get_by_search_key(search_key) else: sobject = my.sobjects[0] search_type = sobject.get_search_type() search_id = sobject.get_id() my.parent = sobject
def init(self): sobject = None if not self.sobjects: """ args = WebContainer.get_web().get_form_args() search_type = args['search_type'] search_id = args['search_id'] """ search_key = self.kwargs.get('search_key') if search_key: sobject = SearchKey.get_by_search_key(search_key) else: sobject = self.sobjects[0] search_type = sobject.get_search_type() search_id = sobject.get_id() self.parent = sobject
def handle_td(my, td): sobject = my.get_current_sobject() parent = None if sobject.is_insert(): parent_key = my.state.get('parent_key') if parent_key: parent = SearchKey.get_by_search_key(parent_key) else: try: parent = sobject.get_parent() except SObjectSecurityException, e: pass except SearchException, e: if e.__str__().find('not registered') != -1: pass elif e.__str__().find('does not exist for database') != -1: pass else: raise
def get_files(self): paths = [] # remember this here for now self.files = {} self.snapshots = {} search_key = self.kwargs.get("search_key") search_keys = self.kwargs.get("search_keys") if search_key: sobject = SearchKey.get_by_search_key(search_key) self.sobjects = [sobject] if search_keys: if isinstance(search_keys, basestring): search_keys = search_keys.replace("'", '"') search_keys = jsonloads(search_keys) self.sobjects = Search.get_by_search_keys(search_keys) if not self.sobjects: return [] self.sobject = self.sobjects[0] for sobject in self.sobjects: if sobject.get_base_search_type() in ['sthpw/task', 'sthpw/note']: parent = sobject.get_parent() sobject_paths = self.get_sobject_files(parent) paths.extend(sobject_paths) else: sobject_paths = self.get_sobject_files(sobject) paths.extend(sobject_paths) return paths
def execute(self): search_key = self.search_key assert search_key sobject = SearchKey.get_by_search_key(search_key) xml = sobject.get_xml_value("access_rules") from pyasm.security import AccessRuleBuilder builder = AccessRuleBuilder(xml=xml) web = WebContainer.get_web() rules = web.get_form_values("rule") # sync the rules group = "builtin" group_default = 'deny' builder.add_default_rule(group, group_default) default_attr = builder.get_default(group) for item in permission_list: key = item.get('key') if key in rules: if default_attr == 'deny': access = "allow" builder.add_rule(group, key, access) else: builder.remove_rule(group, key) else: if default_attr == 'deny': builder.remove_rule(group, key) else: access = "deny" builder.add_rule(group, key, access) new_rules = builder.to_string() sobject.set_value("access_rules", new_rules) sobject.commit() self.add_description('Built-in access rules updated sucessfully!')
def get_display(self): parent_key = self.kwargs.get("search_key") assert (parent_key) parent = SearchKey.get_by_search_key(parent_key) parent_type = parent.get_base_search_type() # this is for backwards compatibility for ProcessSelectWdg web = WebContainer.get_web() web.set_form_value("parent_search_type", parent_type) div = DivWdg() if self.kwargs.get("__hidden__"): div.add_style("margin-top: -2px") div.add_style("margin-left: 0px") if parent.get_code() == '-1': div.add('You can only add task for an existing item.') return div from tactic.ui.panel import TableLayoutWdg, FastTableLayoutWdg expression = self.kwargs.get('expression') if not expression: expression = '' # title is used for panel refresh overlay table = FastTableLayoutWdg(search_type="sthpw/task", view="inline_add_item", mode="insert", search_key=parent_key, state={'search_key': parent_key}, expression=expression, title='Task Edit', __hidden__=self.kwargs.get("__hidden__")) div.add(table) return div
def execute(my): search_key = my.search_key assert search_key sobject = SearchKey.get_by_search_key(search_key) xml = sobject.get_xml_value("access_rules") from pyasm.security import AccessRuleBuilder builder = AccessRuleBuilder(xml=xml) web = WebContainer.get_web() rules = web.get_form_values("rule") # sync the rules group = "builtin" group_default = 'deny' builder.add_default_rule(group, group_default) default_attr = builder.get_default(group) for item in permission_list: key = item.get('key') if key in rules: if default_attr == 'deny': access = "allow" builder.add_rule(group, key, access) else: builder.remove_rule(group, key) else: if default_attr == 'deny': builder.remove_rule(group, key) else: access = "deny" builder.add_rule(group, key, access) new_rules = builder.to_string() sobject.set_value("access_rules", new_rules) sobject.commit() my.add_description('Built-in access rules updated sucessfully!')
def get_display(my): parent_key = my.kwargs.get("search_key") assert(parent_key) parent = SearchKey.get_by_search_key(parent_key) parent_type = parent.get_base_search_type() # this is for backwards compatibility for ProcessSelectWdg web = WebContainer.get_web() web.set_form_value("parent_search_type", parent_type); div = DivWdg() if my.kwargs.get("__hidden__"): div.add_style("margin-top: -2px") div.add_style("margin-left: 0px") if parent.get_code() == '-1': div.add('You can only add task for an existing item.') return div from tactic.ui.panel import TableLayoutWdg, FastTableLayoutWdg expression = my.kwargs.get('expression') if not expression: expression = '' # title is used for panel refresh overlay table = FastTableLayoutWdg( search_type="sthpw/task", view="inline_add_item", mode="insert", search_key=parent_key, state={'search_key': parent_key}, expression=expression, title='Task Edit', __hidden__=my.kwargs.get("__hidden__")) div.add(table) return div
def get_display(my): top = my.top top.add_style("padding: 10px") top.add_color("background", "background", -5) top.add_style("min-width: 600px") paths = my.get_files() # assume that all the paths are part of the same repo repo = 'tactic' for file in my.files.values(): repo = file.get_value("repo_type", no_exception=True) break if repo == 'perforce': search_key = my.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=my.files, snapshots=my.snapshots) else: # If not discovered thru base_dir_alias, use the default if not my.base_dir: my.base_dir = Environment.get_asset_dir() dir_list = SnapshotDirListWdg(base_dir=my.base_dir, location="server", show_base_dir=True,paths=paths, all_open=True, files=my.files, snapshots=my.snapshots) top.add(dir_list) return top
def init_kwargs(self): '''initialize kwargs''' state = self.kwargs.get("state") if state: parent_key = state.get("parent_key") if parent_key: self.sobject = SearchKey.get_by_search_key(parent_key) self.expression = self.get_option("expression") if not self.expression: self.expression = self.kwargs.get("expression") self.alt_expression = self.get_option("alt_expression") if not self.alt_expression: self.alt_expression = self.kwargs.get("alt_expression") self.mode = self.get_option("mode") if not self.mode: self.mode = self.kwargs.get("mode") if not self.mode: self.mode = 'value' self.show_retired = self.get_option("show_retired") if not self.show_retired: self.show_retired = self.kwargs.get("show_retired") # default to False if self.show_retired == 'true': self.show_retired = True else: self.show_retired = False self.enable_eval_listener = False if self.get_option("enable_eval_listener") in [ True, "true", "True", "TRUE" ]: self.enable_eval_listener = True
def init_kwargs(my): '''initialize kwargs''' state = my.kwargs.get("state") if state: parent_key = state.get("parent_key") if parent_key: my.sobject = SearchKey.get_by_search_key(parent_key) my.expression = my.get_option("expression") if not my.expression: my.expression = my.kwargs.get("expression") my.alt_expression = my.get_option("alt_expression") if not my.alt_expression: my.alt_expression = my.kwargs.get("alt_expression") my.mode = my.get_option("mode") if not my.mode: my.mode = my.kwargs.get("mode") if not my.mode: my.mode = 'value' my.show_retired = my.get_option("show_retired") if not my.show_retired: my.show_retired = my.kwargs.get("show_retired") # default to False if my.show_retired == 'true': my.show_retired = True else: my.show_retired = False my.enable_eval_listener = False if my.get_option("enable_eval_listener") in [ True, "true", "True", "TRUE" ]: my.enable_eval_listener = True
def get_display(my): my.sobject = my.get_current_sobject() if not my.sobject: my.sobject = my.get_sobject_from_kwargs() if my.sobject and my.sobject.is_insert(): return DivWdg() if my.sobject: my.search_key = SearchKey.get_by_sobject(my.sobject) my.kwargs['search_key'] = my.search_key else: my.search_key = my.kwargs.get('search_key') html = my.kwargs.get('html') if not html: html = "" # DEPRECATED my.state = my.kwargs.get("state") my.state = BaseRefreshWdg.process_state(my.state) if not my.state: my.state = my.kwargs my.state['search_key'] = my.search_key my.view = my.kwargs.get('view') my.view = my.view.replace("/", ".") my.view_folder = "" if my.view.startswith("."): my.view_folder = my.kwargs.get("__view_folder__") if my.view_folder: my.view = "%s%s" % (my.view_folder, my.view) parts = my.view.split(".") my.view_folder = ".".join(parts[:-1]) if not my.view and not html: raise TacticException("No view defined in custom layout") # If html is not a string, then convert it? if not isinstance(html, basestring): html = str(html) my.view_attrs = {} my.category = my.kwargs.get("category") my.search_type = my.kwargs.get("search_type") my.encoding = my.kwargs.get("encoding") if not my.encoding: my.encoding = 'utf-8' my.plugin = None xml = None # if html is not provided, then get it from the config config = None if not html: if my.config != None: config = my.config else: config = my.kwargs.get("config") if not config: config = my.get_config() if not config: #div = DivWdg() #div.add("No config defined for view [%s] for custom layout" % my.view) #return div raise TacticException("No config defined for view [%s] for custom layout" % my.view) if isinstance(config, WidgetDbConfig): config_str = config.get_value("config") else: config_str = '' if config_str.startswith("<html>"): html = config_str my.def_config = None else: xml = config.get_xml() if my.def_config == None: my.def_config = my.get_def_config(xml) # get the view attributes if isinstance(config, WidgetConfigView): top_config = config.get_configs()[0] else: top_config = config view_node = top_config.get_view_node() if view_node is None: div = DivWdg("No view node found in xml. Invalid XML entry found") return div my.view_attrs = xml.get_attributes(view_node) nodes = xml.get_nodes("config/%s/html/*" % my.view) if not nodes: div = DivWdg("No definition found") return div # convert html tag to a div html = cStringIO.StringIO() for node in nodes: # unfortunately, html does not recognize <textarea/> # so we have to make sure it becomes <textarea></textarea> text = xml.to_string(node) text = text.encode('utf-8') keys = ['textarea','input'] for key in keys: p = re.compile("(<%s.*?/>)" % key) m = p.search(text) if m: for group in m.groups(): xx = group.replace("/", "") xx = "%s</%s>" % (xx, key) text = text.replace(group, xx) text = text.replace("<%s/>" % key, "<%s></%s>" % (key, key)) # add linebreaks to element tag key = 'element' # reg full tag <element><display...></element> p = re.compile(r"(<%s\b[^>]*>(?:.*?)</%s>)" % (key, key)) # short-hand tag <element/> p1 = re.compile("(</%s>|<%s.*?/>)" %(key, key)) m = p.search(text) m1 = p1.search(text) if m: for group in m.groups(): if group: text = text.replace(group, '\n%s\n'%group) if m1: for group in m1.groups(): if group: text = text.replace(group, '\n%s\n'%group) html.write(text) html = html.getvalue() my.config = config #my.def_config = config # This is unnessary? # try to get the sobject if this is in a table element widget if my.search_key: try: # this will raise an exception if it is not in a table element sobject = my.get_current_sobject() except: sobject = SearchKey.get_by_search_key(my.search_key) sobjects = [sobject] else: try: # this will raise an exception if it is not in a table element sobject = my.get_current_sobject() if sobject: sobjects = [sobject] else: sobjects = [] except: sobject = my.sobjects my.layout = my.get_layout_wdg() # preprocess using mako include_mako = my.kwargs.get("include_mako") if not include_mako: include_mako = my.view_attrs.get("include_mako") if xml: mako_node = xml.get_node("config/%s/mako" % my.view) if mako_node is not None: mako_str = xml.get_node_value(mako_node) html = "<%%\n%s\n%%>\n%s" % (mako_str, html) from pyasm.web import Palette num_palettes = Palette.num_palettes() #if include_mako in ['true', True]: if include_mako not in ['false', False]: html = html.replace("<", "<") html = html.replace(">", ">") html = my.process_mako(html) # preparse out expressions # use relative expressions - [expr]xxx[/expr] p = re.compile('\[expr\](.*?)\[\/expr\]') parser = ExpressionParser() matches = p.finditer(html) for m in matches: full_expr = m.group() expr = m.groups()[0] result = parser.eval(expr, sobjects, single=True, state=my.state) if isinstance(result, basestring): result = Common.process_unicode_string(result) else: result = str(result) html = html.replace(full_expr, result ) # use absolute expressions - [expr]xxx[/expr] p = re.compile('\[abs_expr\](.*?)\[\/abs_expr\]') parser = ExpressionParser() matches = p.finditer(html) for m in matches: full_expr = m.group() expr = m.groups()[0] result = parser.eval(expr, single=True) if isinstance(result, basestring): result = Common.process_unicode_string(result) else: result = str(result) html = html.replace(full_expr, result ) # need a top widget that can be used to refresh top = my.top my.set_as_panel(top) top.add_class("spt_custom_top") ignore_events = my.kwargs.get("ignore_events") in ['true', True] if ignore_events: top.add_style("pointer-events: none") # create the content div content = DivWdg() content.add_class("spt_custom_content") content.add_style("position: relative") if ignore_events: content.add_style("pointer-events: none") top.add(content) my.content = content is_test = Container.get("CustomLayout::is_test") if not is_test: is_test = my.kwargs.get("is_test") in [True, 'true'] if is_test: Container.put("CustomLayout::is_test", True) my.handle_is_test(content) html = my.replace_elements(html) content.add(html) if xml: my.add_behaviors(content, xml) # remove all the extra palettes created while True: extra_palettes = Palette.num_palettes() - num_palettes if extra_palettes > 0: Palette.pop_palette() else: break if my.kwargs.get("is_top") in ['true', True]: return html elif my.kwargs.get("is_refresh"): return content else: return top
def get_action_wdg(my, name): '''get the action widget for ui option of note entry''' note_wdg = DivWdg() note_wdg.add_style("padding-top: 3px") # note options option = DivWdg(css='spt_uber_note_option') cb = CheckboxWdg('is_private') #cb.set_default_checked() checkbox_name = 'note_master_private_cb' master_cb = CheckboxWdg(checkbox_name) if master_cb.is_checked(): cb.set_default_checked() option.add_style('margin-right', '5px') option.add_style('float', 'right') option.add(cb) option.add('private') #commit = TextBtnWdg(label='save', size='small') commit = ActionButtonWdg(title='save', tip="Save Changes") commit.add_style('margin-top: -5px') commit.add_style('margin-bottom: 5px') commit.add_style('float: right') commit.add_behavior({ 'type': 'click_up', 'cbjs_action': ''' var td = bvr.src_el.getParent(".spt_table_td"); var text = td.getElement(".spt_note_text"); text.blur(); spt.dg_table.update_row(evt, bvr); td.setStyle('background-color',''); ''', 'cell_only': True }) #commit.set_scale("0.75") # do some gynastics to handle a refresh. if my.parent_wdg: info = my.parent_wdg.get_aux_info() sobject_dict = info.get('sobjects') sobject = sobject_dict.get(my.get_name()) parent = info.get('parent') else: sobject = None parent = None if not sobject: if my.parent_key: parent = SearchKey.get_by_search_key(my.parent_key) # get the latest note #search_key = my.kwargs.get("search_key") #if search_key: # sobject = SearchKey.get_by_search_key(search_key) search = Search('sthpw/note') search.add_parent_filter(parent) search.add_filter('context', name) # Make the assumption that the last one entered is by timestamp search.add_order_by('timestamp desc') sobject = search.get_sobject() # Show a history of notes if sobject: history = ActionButtonWdg(title='history', tip="Show note history") #history = TextBtnWdg(label='history', size='small') #history.get_top_el().add_style("margin-left: 4px") #history.get_top_el().add_style('float: left') history.add_style("float: left") history.add_style("margin-top: -5px") history.add_style("margin-bottom: 5px") note_wdg.add(history) my.parent_key = SearchKey.get_by_sobject(parent) context = name filter = '[{"prefix":"main_body","main_body_enabled":"on","main_body_column":"context","main_body_relation":"is","main_body_value":"%s"}]' % context history.add_behavior({ 'type': 'click_up', 'cbjs_action': "spt.popup.get_widget(evt, bvr)", 'options': { 'class_name': 'tactic.ui.panel.ViewPanelWdg', 'title': 'Notes History', 'popup_id': 'Notes_History_%s' % context }, 'args': { 'search_type': 'sthpw/note', 'view': 'summary', 'parent_key': my.parent_key, 'filter': filter, } }) note_wdg.add(commit) note_wdg.add(option) note_wdg.add("<br clear='all'/>") from pyasm.biz import PrefSetting quick_text = PrefSetting.get_value_by_key('quick_text') if quick_text: quick_sel = SelectWdg('quick_text', label='quick: ') quick_sel.set_option('values', quick_text) quick_sel.add_empty_option('-- text --', '') quick_sel.add_behavior({ 'type': 'change', 'cbjs_action': '''var val = bvr.src_el.value; var text=bvr.src_el.getParent('.spt_note_top').getElement('.spt_note_text') text.value = text.value + val; ''' }) note_wdg.add(SpanWdg(quick_sel, css='small')) note_wdg.add(HtmlElement.br(2)) # Show the last note note_wdg.add("<i>Last note</i> ") if sobject: timestamp = sobject.get_value("timestamp") timestamp = parser.parse(timestamp) timestamp = timestamp.strftime("%m/%d %H:%M") timestamp_div = SpanWdg() timestamp_div.add("(%s)" % timestamp) note_wdg.add(timestamp_div) timestamp_div.add_style("font-size: 11px") timestamp_div.add_style("font-style: italic") # add a private tag access = sobject.get_value("access") if access == 'private': private = SpanWdg() #private.add_style('float: right') private.add(" <i>-- private --</i>") note_wdg.add(private) hr = DivWdg("<hr/>") hr.add_style("height: 1px") hr.add_style("margin-top: -5px") note_wdg.add(hr) div = DivWdg() note_wdg.add(div) div.add_style("max-height", "50px") div.add_style("overflow", "auto") div.add_style("padding: 3px") if sobject: value = sobject.get_value('note') from pyasm.web import WikiUtil value = WikiUtil().convert(value) div.add(value) else: no_notes = DivWdg() div.add(no_notes) no_notes.add('<i> -- No Notes --</i>') no_notes.add_style("font-size: 11px") no_notes.add_style("opacity: 0.7") return note_wdg
def execute(my): trigger_sobj = my.get_trigger_sobj() data = trigger_sobj.get_value("data") data = jsonloads(data) print "trigger data: ", data, type(data) data_list = data if isinstance(data, dict): data_list = [data] src_task = my.get_caller() for data in data_list: # get the src task caller dst_task = None # it could be the FileCheckin Command if not isinstance(src_task, SObject): input = my.get_input() snapshot = input.get('snapshot') if not snapshot: continue if isinstance(snapshot, dict): snapshot = SearchKey.get_by_search_key(snapshot.get('__search_key__')) src_process = data.get('src_process') src_task = Search.eval("@SOBJECT(parent.sthpw/task['process','%s'])"%src_process,\ sobjects=snapshot, single=True) if not src_task: continue # make sure the caller process is the same as the source process if src_task.get_value("process") != data.get("src_process"): continue #conditionx = "@GET(.status) != 'Approved'" #result = Search.eval(conditionx, src_task) #print "result: ", result # make sure that the appropriate status was set src_status = data.get("src_status") if src_status and src_task.get_value("status") != src_status: continue dst_process = data.get("dst_process") dst_status = data.get("dst_status") sobject = src_task.get_parent() tasks = Task.get_by_sobject(sobject) updated_tasks = [] use_parent = data.get("use_parent") if use_parent in [True,'true']: parent = sobject.get_parent() parent_tasks = Task.get_by_sobject(parent, dst_process) condition = data.get("condition") if not condition: condition = "all" if condition == "all": condition_met = True for task in tasks: if src_task.get_value("status") != src_status: condition_met = False elif condition == "any": condition_met = False for task in tasks: if task.get_value("status") == src_status: condition_met = True break if condition_met: for task in parent_tasks: if task.get_value("process") == dst_process: updated_tasks.append(task) else: for task in tasks: if task.get_value("process") == dst_process: updated_tasks.append(task) for task in updated_tasks: if task.get_value("process") == dst_process: task.set_value("status", dst_status) task.commit() """
def _execute_single(my, code, name=None): # only do actions if the edit button has been pressed from pyasm.web import WebContainer web = WebContainer.get_web() no_commit = (web.get_form_value("sobject_commit") == 'false') sobject = None if my.search_key: sobject = SearchKey.get_by_search_key(my.search_key) # this is needed for action handler below my.search_type = sobject.get_search_type() else: # get the search type and search id my.search_type = web.get_form_value("search_type") if my.search_type == "": raise EditCmdException( "Search type not found" ) search_id = web.get_form_value("search_id") if search_id == "": raise EditCmdException( "Search id not found" ) # get the search object based on these parameters if search_id == "" or search_id == "-1": sobject = SearchType.create(my.search_type) else: search = Search(my.search_type) search.add_id_filter( search_id ) sobject = search.get_sobject() # there has to be an sobject to edit if sobject == None: raise EditCmdException("No sobject found with search type [%s] and id [%s]" % (my.search_type, search_id) ) action_handlers = my._get_action_handlers() # set the sobject for each action handler for action_handler in action_handlers: action_handler.set_sobject(sobject) if action_handler.check(): if my.parent_key: action_handler.set_option('parent_key', my.parent_key) if my.connect_key: action_handler.set_option('connect_key', my.connect_key) action_handler.execute() # set the parent, if there is one and it's in insert if sobject.is_insert() and my.parent_key: sobject.add_relationship(my.parent_key) if sobject.is_insert(): action = "Inserted" else: action = "Updated" # before we commit, we set what got changed in the info update_data = sobject.update_data for key, value in update_data.items(): # don't include None if value != None: my.info[key] = value if code: sobject.set_value("code", code) # only fill in a new with the passed in name if it has been # specified if name: sobject.set_value("name", name) # commit the changes unless told not to. # NOTE: this prevents any connections to be made if not no_commit: try: if sobject.is_insert(): is_insert = True else: is_insert = False sobject.commit() # only connect on insert if is_insert and my.connect_key and my.connect_key != "__NONE__": sobject.connect(my.connect_key, "task") except SqlException, e: msg = "An error was encountered adding this item. The error reported was [%s]" % e raise SqlException(msg) # ask the sobject for the description my.add_description( sobject.get_update_description() )
def get_display(my): my.sobject = my.get_current_sobject() if not my.sobject: my.sobject = my.get_sobject_from_kwargs() if my.sobject and my.sobject.is_insert(): return DivWdg() if my.sobject: my.search_key = SearchKey.get_by_sobject(my.sobject) my.kwargs['search_key'] = my.search_key else: my.search_key = my.kwargs.get('search_key') html = my.kwargs.get('html') if not html: html = "" # DEPRECATED my.state = my.kwargs.get("state") my.state = BaseRefreshWdg.process_state(my.state) if not my.state: my.state = my.kwargs my.state['search_key'] = my.search_key my.view = my.kwargs.get('view') my.view = my.view.replace("/", ".") my.view_folder = "" if my.view.startswith("."): my.view_folder = my.kwargs.get("__view_folder__") if my.view_folder: my.view = "%s%s" % (my.view_folder, my.view) parts = my.view.split(".") my.view_folder = ".".join(parts[:-1]) if not my.view and not html: raise TacticException("No view defined in custom layout") # If html is not a string, then convert it? if not isinstance(html, basestring): html = str(html) my.view_attrs = {} my.category = my.kwargs.get("category") my.search_type = my.kwargs.get("search_type") my.encoding = my.kwargs.get("encoding") if not my.encoding: my.encoding = 'utf-8' my.plugin = None xml = None # if html is not provided, then get it from the config config = None if not html: if my.config != None: config = my.config else: config = my.kwargs.get("config") if not config: config = my.get_config() if not config: #div = DivWdg() #div.add("No config defined for view [%s] for custom layout" % my.view) #return div raise TacticException("No config defined for view [%s] for custom layout" % my.view) if isinstance(config, WidgetDbConfig): config_str = config.get_value("config") else: config_str = '' if config_str.startswith("<html>"): html = config_str my.def_config = None else: xml = config.get_xml() if my.def_config == None: my.def_config = my.get_def_config(xml) # get the view attributes if isinstance(config, WidgetConfigView): top_config = config.get_configs()[0] else: top_config = config view_node = top_config.get_view_node() if view_node is None: div = DivWdg("No view node found in xml. Invalid XML entry found") return div my.view_attrs = xml.get_attributes(view_node) nodes = xml.get_nodes("config/%s/html/*" % my.view) if not nodes: div = DivWdg("No definition found") return div # convert html tag to a div html = cStringIO.StringIO() for node in nodes: # unfortunately, html does not recognize <textarea/> # so we have to make sure it becomes <textarea></textarea> text = xml.to_string(node) text = text.encode('utf-8') keys = ['textarea','input'] for key in keys: p = re.compile("(<%s.*?/>)" % key) m = p.search(text) if m: for group in m.groups(): xx = group.replace("/", "") xx = "%s</%s>" % (xx, key) text = text.replace(group, xx) text = text.replace("<%s/>" % key, "<%s></%s>" % (key, key)) # add linebreaks to element tag key = 'element' # reg full tag <element><display...></element> p = re.compile(r"(<%s\b[^>]*>(?:.*?)</%s>)" % (key, key)) # short-hand tag <element/> p1 = re.compile("(</%s>|<%s.*?/>)" %(key, key)) m = p.search(text) m1 = p1.search(text) if m: for group in m.groups(): if group: text = text.replace(group, '\n%s\n'%group) if m1: for group in m1.groups(): if group: text = text.replace(group, '\n%s\n'%group) html.write(text) html = html.getvalue() my.config = config #my.def_config = config # This is unnessary? # try to get the sobject if this is in a table element widget if my.search_key: try: # this will raise an exception if it is not in a table element sobject = my.get_current_sobject() except: sobject = SearchKey.get_by_search_key(my.search_key) sobjects = [sobject] else: try: # this will raise an exception if it is not in a table element sobject = my.get_current_sobject() if sobject: sobjects = [sobject] else: sobjects = [] except: sobject = my.sobjects my.layout = my.get_layout_wdg() # preprocess using mako include_mako = my.kwargs.get("include_mako") if not include_mako: include_mako = my.view_attrs.get("include_mako") if xml: mako_node = xml.get_node("config/%s/mako" % my.view) if mako_node is not None: mako_str = xml.get_node_value(mako_node) html = "<%%\n%s\n%%>\n%s" % (mako_str, html) from pyasm.web import Palette num_palettes = Palette.num_palettes() #if include_mako in ['true', True]: if include_mako not in ['false', False]: html = html.replace("<", "<") html = html.replace(">", ">") html = my.process_mako(html) # preparse out expressions # use relative expressions - [expr]xxx[/expr] p = re.compile('\[expr\](.*?)\[\/expr\]') parser = ExpressionParser() matches = p.finditer(html) for m in matches: full_expr = m.group() expr = m.groups()[0] result = parser.eval(expr, sobjects, single=True, state=my.state) if isinstance(result, basestring): result = Common.process_unicode_string(result) else: result = str(result) html = html.replace(full_expr, result ) # use absolute expressions - [expr]xxx[/expr] p = re.compile('\[abs_expr\](.*?)\[\/abs_expr\]') parser = ExpressionParser() matches = p.finditer(html) for m in matches: full_expr = m.group() expr = m.groups()[0] result = parser.eval(expr, single=True) if isinstance(result, basestring): result = Common.process_unicode_string(result) else: result = str(result) html = html.replace(full_expr, result ) # need a top widget that can be used to refresh top = my.top my.set_as_panel(top) top.add_class("spt_custom_top") # create the content div content = DivWdg() content.add_class("spt_custom_content") content.add_style("position: relative") top.add(content) my.content = content is_test = Container.get("CustomLayout::is_test") if not is_test: is_test = my.kwargs.get("is_test") in [True, 'true'] if is_test: Container.put("CustomLayout::is_test", True) my.handle_is_test(content) html = my.replace_elements(html) content.add(html) if xml: my.add_behaviors(content, xml) # remove all the extra palettes created while True: extra_palettes = Palette.num_palettes() - num_palettes if extra_palettes > 0: Palette.pop_palette() else: break if my.kwargs.get("is_refresh"): return content else: return top
def __init__(my, **kwargs): super(PluginBase,my).__init__(**kwargs) # plugin sobject (Not really used anymore?) my.search_key = my.kwargs.get("search_key") zip_path = my.kwargs.get("zip_path") upload_file_name = my.kwargs.get("upload_file_name") my.base_dir = my.kwargs.get("base_dir") my.plugin_dir = my.kwargs.get("plugin_dir") my.manifest = my.kwargs.get("manifest") my.code = my.kwargs.get("code") my.version = my.kwargs.get("version") relative_dir = my.kwargs.get("relative_dir") my.verbose = my.kwargs.get("verbose") not in [False, 'false'] # at the end of this, the following variables are needed in order to # define the plugin # # version: the version of the plugin # plugin_dir: the directory where the plugin definition is located # manifest: the description of what is in the plugin if zip_path: # assume the zip path is the same as the basename basename = os.path.basename(zip_path) basename, ext = os.path.splitext(basename) assert ext == '.zip' tmp_dir = Environment.get_tmp_dir() unzip_dir = "%s/%s" % (tmp_dir, basename) if os.path.exists(unzip_dir): shutil.rmtree(unzip_dir) # unzip the file in to the tmp_dir or plugin_dir (for install) zip_util = ZipUtil() zip_util.extract(zip_path, base_dir=tmp_dir) # assume zip path my.plugin_dir, ext = os.path.splitext(zip_path) # mv from temp if my.plugin_dir != unzip_dir: if os.path.exists(my.plugin_dir): shutil.rmtree(my.plugin_dir) shutil.move(unzip_dir, my.plugin_dir) manifest_path = "%s/manifest.xml" % my.plugin_dir f = open(manifest_path, 'r') my.manifest = f.read() f.close() elif upload_file_name: # The path is moved to the plugin dir, if this process is taking # "local" file (such as one uploaded) upload_dir = Environment.get_upload_dir() upload_path = "%s/%s" % (upload_dir, upload_file_name) plugin_base_dir = Environment.get_plugin_dir() dist_dir = Environment.get_dist_dir() if not os.path.exists(dist_dir): os.makedirs(dist_dir) basename = os.path.basename(upload_path) #if os.path.exists("%s/%s" % (plugin_base_dir, basename)): # os.unlink("%s/%s" % (plugin_base_dir, basename) ) #shutil.move(upload_path, plugin_base_dir) # copy to dist folder if os.path.exists("%s/%s" % (dist_dir, basename)): os.unlink("%s/%s" % (dist_dir, basename) ) shutil.move(upload_path, dist_dir) zip_path = "%s/%s" % (dist_dir, upload_file_name) zip_util = ZipUtil() zip_util.extract(zip_path, base_dir=plugin_base_dir) my.plugin_dir = "%s/%s" % (plugin_base_dir, basename) my.plugin_dir = my.plugin_dir[:-4] manifest_path = "%s/manifest.xml" % (my.plugin_dir) if os.path.exists(manifest_path): f = open(manifest_path, 'r') my.manifest = f.read() f.close() else: # when uploading, this will likely not be needed my.manifest = "<manifest/>" return elif relative_dir: plugin_base_dir = Environment.get_plugin_dir() my.plugin_dir = "%s/%s" % (plugin_base_dir, relative_dir) manifest_path = "%s/manifest.xml" % my.plugin_dir if not os.path.exists(manifest_path): plugin_base_dir = Environment.get_builtin_plugin_dir() my.plugin_dir = "%s/%s" % (plugin_base_dir, relative_dir) manifest_path = "%s/manifest.xml" % my.plugin_dir f = open(manifest_path, 'r') my.manifest = f.read() f.close() elif my.plugin_dir: manifest_path = "%s/manifest.xml" % (my.plugin_dir) f = open(manifest_path, 'r') my.manifest = f.read() f.close() # get the plugin sobject elif my.search_key: plugin = SearchKey.get_by_search_key(my.search_key) my.manifest = plugin.get_value("manifest") my.code = plugin.get_code() my.version = plugin.get_value("version") elif my.manifest: # everything is extracted from the manifest later pass elif my.code: search = Search("config/plugin") search.add_filter("code", my.code) plugin = search.get_sobject() # In case there is extra plugins folder which is the case when the user # is developing. relative_dir = plugin.get_value("rel_dir") plugin_base_dir = Environment.get_plugin_dir() my.plugin_dir = "%s/%s" % (plugin_base_dir, relative_dir) # TODO: fix the ZipUtil.zip_dir() manifest_path = "%s/manifest.xml" % my.plugin_dir if not os.path.exists(manifest_path): plugin_base_dir = Environment.get_builtin_plugin_dir() my.plugin_dir = "%s/%s" % (plugin_base_dir, relative_dir) manifest_path = "%s/manifest.xml" % my.plugin_dir if os.path.exists(manifest_path): f = open(manifest_path, 'r') my.manifest = f.read() f.close() else: # this condition happens likely for a versioned installed plugin from a zip file # where it starts with an extra folder "plugins" and the rel_dir has not been recorded properly my.manifest = plugin.get_value("manifest") my.code = plugin.get_code() my.version = plugin.get_value("version") else: raise Exception("No plugin found") # assertions assert my.manifest # read the xml my.xml = Xml() my.xml.read_string(my.manifest) # if code is passed in, then use that. if not my.code: my.code = my.xml.get_value("manifest/data/code") # old implementation if not my.code: my.code = my.xml.get_value("manifest/@code") if not my.version: my.version = my.xml.get_value("manifest/data/version") assert my.code if not my.base_dir: if my.code.startswith("TACTIC"): my.base_dir = Environment.get_builtin_plugin_dir() else: my.base_dir = Environment.get_plugin_dir() # set the base directory for this particular plugin if not my.plugin_dir: if my.version: my.plugin_dir = "%s/%s-%s" % (my.base_dir, my.code, my.version) else: my.plugin_dir = "%s/%s" % (my.base_dir, my.code)
def get_display(my): div = DivWdg() div.add_class("spt_security") div.add_attr("id", "SecurityManagerWdg") div.add_attr("spt_class_name", Common.get_full_class_name(my) ) div.add_attr("spt_search_key", my.search_key) div.add_attr("spt_update", "true") project_div = DivWdg() project_div.add_color("background", "background") project_div.add_color("color", "color") project_div.add_style("padding: 10px") project_div.add_border() project_div.add_style("width: 300px") group = SearchKey.get_by_search_key(my.search_key) title = DivWdg() title.add_class("maq_search_bar") name = group.get_value("login_group") title.add("Global security settings for %s" % name) project_div.add(title) access_rules = group.get_xml_value("access_rules") access_manager = AccessManager() access_manager.add_xml_rules(access_rules) access_level = group.get_access_level() project_code = group.get_value('project_code') if project_code: project_codes = set(project_code) else: project_codes = set() xml = LoginGroup.get_default_access_rule(access_level, project_codes) access_manager.add_xml_rules(xml) group = "builtin" global_default_access = "deny" list_div = DivWdg() list_div.add_style("color: #222") for item in permission_list: if item.get('group'): group_div = DivWdg() list_div.add(group_div) group_div.add_style("margin-top: 10px") group_div.add_style("font-weight: bold") group_div.add(item.get('group')) group_div.add("<hr/>") continue item_div = DivWdg() list_div.add(item_div) item_div.add_style("margin-top: 5px") key = item.get('key') item_default = item.get('default') if item_default: default_access = item_default else: default_access = global_default_access allowed = access_manager.check_access(group, key, "allow", default=default_access) checkbox = CheckboxWdg("rule") if allowed: checkbox.set_checked() checkbox.set_option("value", key) item_div.add(checkbox) item_div.add_style("color: #222") item_div.add(item.get('title') ) project_div.add(list_div) project_div.add("<hr>") #close_script = "spt.popup.close(bvr.src_el.getParent('.spt_popup'))" save_button = ActionButtonWdg(title="Save", tip="Save Security Settings") save_button.add_behavior( { "type": "click_up", "cbjs_action": "el=bvr.src_el.getParent('.spt_security');spt.panel.refresh(el);" } ) save_button.add_style("margin-left: auto") save_button.add_style("margin-right: auto") project_div.add(save_button) div.add(project_div) if my.update == "true": div.add(HtmlElement.br()) div.add(HtmlElement.b(my.description)) return div
def get_display(my): show_context = my.get_option('context') == 'true' top = DivWdg() # put in a js callback to determine the to use. top.add_class("spt_input_top") context_list = [] my.pipeline_codes = [] my.pipelines = [] my.in_edit_wdg = False parent_key = my.get_option("parent_key") if not parent_key: state = my.get_state() parent_key = state.get("parent_key") if parent_key: parent = Search.get_by_search_key(parent_key) pipeline_code = parent.get_value("pipeline_code", no_exception=True) if pipeline_code: top.add_attr("spt_cbjs_get_input_key", "return '%s'" % pipeline_code) else: # This is quite slow, but it works #top.add_attr("spt_cbjs_get_input_key", "var server=TacticServerStub.get(); var parent_key = cell_to_edit.getParent('.spt_table_tbody').getAttribute('spt_parent_key'); var parent = server.get_by_search_key(parent_key); return parent.pipeline_code") # ProcessElementWdg's handle_td() sets the spt_pipeline_code attribute top.add_attr("spt_cbjs_get_input_key", "return cell_to_edit.getAttribute('spt_pipeline_code')") # Need to import this dynamically from tactic.ui.panel import EditWdg # This is only executed for the popup edit widget if hasattr(my, 'parent_wdg') and isinstance(my.get_parent_wdg(), EditWdg): my.in_edit_wdg = True sobject = my.get_current_sobject() parent = sobject.get_parent() if not parent: parent_key = my.get_option('parent_key') if parent_key: parent = SearchKey.get_by_search_key(parent_key) if parent: if not parent.has_value('pipeline_code'): name = my.get_input_name() text = TextWdg(name) top.add(text) sobject = my.get_current_sobject() name = my.get_name() value = sobject.get_value(name) text.set_value(value) return top #raise TacticException('[%s] needs a pipeline_code attribute to insert task.'%parent.get_code()) pipe_code = parent.get_value('pipeline_code') if pipe_code: my.pipeline_codes = [pipe_code] my.pipelines = [Pipeline.get_by_code(pipe_code)] else: # just get all of the pipelines # Cannot use expression here, because entries are added to the # result ... this causes further queries to return with the # added entries #my.pipelines = Search.eval("@SOBJECT(sthpw/pipeline)") search = Search("sthpw/pipeline") my.pipelines = search.get_sobjects() my.pipeline_codes = [x.get_code() for x in my.pipelines] # add the default my.pipeline_codes.append("") my.pipelines.append(None) for i, pipeline_code in enumerate(my.pipeline_codes): pipeline = my.pipelines[i] div = DivWdg() top.add(div) div.add_class("spt_input_option") div.add_attr("spt_input_key", pipeline_code) name = my.get_input_name() # If the pipeline code is empty, make it free form (for now) if not pipeline_code: text = TextWdg(name) div.add(text) continue select = SelectWdg(name) select.add_empty_option("-- Select a %s --" % my.get_name() ) # TODO: make spt.dg_table.select_wdg_clicked keyboard action free so it won't interfere with # normal usage of the select if not my.in_edit_wdg: select.add_behavior( { 'type': 'click', 'cbjs_action': 'spt.dg_table.select_wdg_clicked( evt, bvr.src_el );' } ) # get the sub-pipeline processes as well processes = pipeline.get_processes(recurse=True) values = [] labels = [] for process in processes: is_sub_pipeline = False if process.is_from_sub_pipeline(): process_name = process.get_full_name() is_sub_pipeline = True else: process_name = process.get_name() # show context instead if show_context: output_contexts = pipeline.get_output_contexts(process.get_name()) for context in output_contexts: values.append(context) if is_sub_pipeline: #label = process_name label = context else: label = context labels.append(label) else: values.append(process_name) labels.append(process_name) select.set_option("values", values) select.set_option("labels", labels) div.add(select) # there is only 1 select for EditWdg if hasattr(my, 'parent_wdg') and isinstance(my.get_parent_wdg(), EditWdg): sobject = my.get_current_sobject() # this could be either process or context name = my.get_name() value = sobject.get_value(name) # special case to append a context with subcontext so it will stay selected in EditWdg if name == 'context' and value.find('/') != -1: select.append_option(value, value) if value: select.set_value(value) return top
def execute(self): trigger_sobj = self.get_trigger_sobj() data = trigger_sobj.get_value("data") data = jsonloads(data) data_list = data if isinstance(data, dict): data_list = [data] src_task = self.get_caller() for data in data_list: # get the src task caller dst_task = None # it could be the FileCheckin Command if not isinstance(src_task, SObject): input = self.get_input() snapshot = input.get('snapshot') if not snapshot: continue if isinstance(snapshot, dict): snapshot = SearchKey.get_by_search_key( snapshot.get('__search_key__')) src_process = data.get('src_process') src_task = Search.eval("@SOBJECT(parent.sthpw/task['process','%s'])"%src_process,\ sobjects=snapshot, single=True) if not src_task: continue # make sure the caller process is the same as the source process if src_task.get_value("process") != data.get("src_process"): continue #conditionx = "@GET(.status) != 'Approved'" #result = Search.eval(conditionx, src_task) #print "result: ", result # make sure that the appropriate status was set src_status = data.get("src_status") if src_status and src_task.get_value("status") != src_status: continue # Execute script if necessary script_path = trigger_sobj.get_value("script_path") if script_path: cmd = PythonTrigger(script_path=script_path) cmd.set_input(self.input) cmd.set_output(self.input) cmd.execute() continue # Execute trigger if necessary class_path = data.get("class_path") if class_path: trigger = Common.create_from_class_path(class_path) trigger.set_input(self.input) trigger.set_output(self.input) trigger.execute() continue # If no script was execute,then assume other task # statuses should be updated. dst_process = data.get("dst_process") dst_status = data.get("dst_status") sobject = src_task.get_parent() tasks = Task.get_by_sobject(sobject) updated_tasks = [] use_parent = data.get("use_parent") if use_parent in [True, 'true']: parent = sobject.get_parent() parent_tasks = Task.get_by_sobject(parent, dst_process) condition = data.get("condition") if not condition: condition = "all" if condition == "all": condition_met = True for task in tasks: if src_task.get_value("status") != src_status: condition_met = False elif condition == "any": condition_met = False for task in tasks: if task.get_value("status") == src_status: condition_met = True break if condition_met: for task in parent_tasks: if task.get_value("process") == dst_process: updated_tasks.append(task) else: for task in tasks: if task.get_value("process") == dst_process: updated_tasks.append(task) for task in updated_tasks: if task.get_value("process") == dst_process: task.set_value("status", dst_status) task.commit() """
def get_display(my): current = my.get_current_sobject() if current.is_insert(): widget = Widget() parent_key = my.get_option('parent_key') if parent_key: parent = SearchKey.get_by_search_key(parent_key) if parent: widget.add(SpanWdg(parent.get_code())) else: # use the project as the parent parent = Project.get() widget.add(SpanWdg("Project: %s" % parent.get_code())) #raise TacticException('Task creation aborted since parent is undetermined. Please check the configuration that generates this table.') text = HiddenWdg(my.get_input_name()) text.set_option('size', '40') text.set_value(parent_key) widget.add(text) return widget else: search_type = current.get_value('search_type') if not search_type: return "No parent type" widget = Widget() parent = current.get_parent() if parent: widget.add(parent.get_code()) return widget # What is this look up code for? text = TextWdg(my.get_input_name()) behavior = { 'type': 'keyboard', 'kbd_handler_name': 'DgTableMultiLineTextEdit' } text.add_behavior(behavior) widget.add(text) icon = IconButtonWdg("Look up", IconWdg.ZOOM) icon.add_behavior({ 'type': 'click_up', 'cbjs_action': ''' var options = { title: '%s', class_name: 'tactic.ui.panel.ViewPanelWdg' }; var args = { search_type: '%s', view: 'list' }; spt.popup.get_widget( {}, {options: options, args: args} ); ''' % (search_type, search_type) }) widget.add(icon) return widget
def process_sobjects(sobjects, search=None): '''process sobjects order according to pipeline process order''' if not sobjects: return if search: order_list = search.get_order_bys() # it could be search_type asc or search_tpe desc # that means the user has applied an order by in some specific column if order_list and not order_list[0].startswith('search_type'): return parent = None last_parent = None last_parent_key = None parents = [] groups = [] group = None # group tasks according to parent for i, sobject in enumerate(sobjects): # get the parent key search_type = sobject.get_value("search_type") search_id = sobject.get_value("search_id") parent_key = "%s|%s" % (search_type, search_id) process = sobject.get_value('process') if parent_key != last_parent_key: parent = SearchKey.get_by_search_key(parent_key) parents.append(parent) group = [] groups.append(group) group.append(sobject) last_parent_key = parent_key new_sobjects = [] # reorder each group for i, group in enumerate(groups): parent = parents[i] processes = [] if parent: pipeline_code = parent.get_value("pipeline_code") pipeline = Pipeline.get_by_code(pipeline_code) if pipeline: processes = pipeline.get_process_names(recurse=True) if processes: # build a sorting key dict sort_dict = {} for sobject in group: process = sobject.get_value('process') try: sort_dict[sobject] = processes.index(process) except ValueError: # put at the bottom for outdated processes # this is important to still display tasks with outdated processe names sort_dict[sobject] = len(processes) sorted_group = sorted(group, key=sort_dict.__getitem__) new_sobjects.extend(sorted_group) else: new_sobjects.extend(group) return new_sobjects
def get_display(self): current = self.get_current_sobject() if current.is_insert(): widget = Widget() parent_key = self.get_option('parent_key') if parent_key: parent = SearchKey.get_by_search_key(parent_key) if parent: widget.add(SpanWdg(parent.get_code())) else: # use the project as the parent parent = Project.get() widget.add(SpanWdg("Project: %s" % parent.get_code())) #raise TacticException('Task creation aborted since parent is undetermined. Please check the configuration that generates this table.') text = HiddenWdg(self.get_input_name()) text.set_option('size','40') text.set_value(parent_key) widget.add(text) return widget else: search_type = current.get_value('search_type') if not search_type: return "No parent type" widget = Widget() parent = current.get_parent() if parent: widget.add(parent.get_code()) return widget # What is this look up code for? text = TextWdg(self.get_input_name()) behavior = { 'type': 'keyboard', 'kbd_handler_name': 'DgTableMultiLineTextEdit' } text.add_behavior(behavior) widget.add(text) icon = IconButtonWdg("Look up", IconWdg.ZOOM) icon.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' var options = { title: '%s', class_name: 'tactic.ui.panel.ViewPanelWdg' }; var args = { search_type: '%s', view: 'list' }; spt.popup.get_widget( {}, {options: options, args: args} ); ''' % (search_type, search_type) } ) widget.add(icon) return widget
def execute(self): input = self.get_input() mode = input.get("mode") if mode not in ['insert', 'update']: return update_data = input.get("update_data") if 'name' not in update_data and 'login_group' not in update_data: return search_key = input.get("search_key") sobj = SearchKey.get_by_search_key(search_key) # this logic makes the login name take precedence and determines the # code and login_group column # the problem is that groups are global and sometimes you want to have # the project_code prepended to the group in order to scope it # correctly. However, you don't necessarily want the name of the # project to prepend the name if mode == "insert": login_group_name = sobj.get_value('login_group') if not login_group_name: raise Exception("A Group Name has not been entered. Please enter a Group Name.") sobj.set_value('name', login_group_name) elif mode == "update": if 'login_group' in update_data: raise Exception('Login group attribute is automatically updated. Please edit only the name attribute.') login_group_name = sobj.get_value('name') if not login_group_name: login_group_name = sobj.get_value('login_group') login_group = re.sub(r'[\$\s,#~`\%\*\^\&\(\)\+\=\[\]\[\}\{\;\:\'\"\<\>\?\|\\\!-]', "_", login_group_name) login_group = login_group.lower() login_group_name = sobj.get_value('login_group') # make sure the project code is prepended to the login_group if sobj.get_value("project_code"): project_code = Project.get_project_code() if not login_group.startswith("%s_" % project_code): login_group = "%s_%s" % (project_code, login_group) sobj.set_value('login_group', login_group) sobj.set_value('code', login_group) sobj.commit(triggers=False) self.update_related(login_group, login_group_name)
def get_display(my): div = DivWdg() div.add_class("spt_security") div.add_attr("id", "SecurityManagerWdg") div.add_attr("spt_class_name", Common.get_full_class_name(my) ) div.add_attr("spt_search_key", my.search_key) div.add_attr("spt_update", "true") project_div = DivWdg() project_div.add_color("background", "background") project_div.add_color("color", "color") project_div.add_style("padding: 10px") project_div.add_border() project_div.add_style("width: 300px") group = SearchKey.get_by_search_key(my.search_key) title = DivWdg() title.add_class("maq_search_bar") name = group.get_value("login_group") title.add("Global security settings for %s" % name) project_div.add(title) access_rules = group.get_xml_value("access_rules") access_manager = AccessManager() access_manager.add_xml_rules(access_rules) group = "builtin" global_default_access = "deny" list_div = DivWdg() list_div.add_style("color: #222") for item in permission_list: if item.get('group'): group_div = DivWdg() list_div.add(group_div) group_div.add_style("margin-top: 10px") group_div.add_style("font-weight: bold") group_div.add(item.get('group')) group_div.add("<hr/>") continue item_div = DivWdg() list_div.add(item_div) item_div.add_style("margin-top: 5px") key = item.get('key') item_default = item.get('default') if item_default: default_access = item_default else: default_access = global_default_access allowed = access_manager.check_access(group, key, "allow", default=default_access) checkbox = CheckboxWdg("rule") if allowed: checkbox.set_checked() checkbox.set_option("value", key) item_div.add(checkbox) item_div.add_style("color: #222") item_div.add(item.get('title') ) project_div.add(list_div) project_div.add("<hr>") #close_script = "spt.popup.close(bvr.src_el.getParent('.spt_popup'))" save_button = ActionButtonWdg(title="Save", tip="Save Security Settings") save_button.add_behavior( { "type": "click_up", "cbjs_action": "el=bvr.src_el.getParent('.spt_security');spt.panel.refresh(el);" } ) save_button.add_style("margin-left: auto") save_button.add_style("margin-right: auto") project_div.add(save_button) div.add(project_div) if my.update == "true": div.add(HtmlElement.br()) div.add(HtmlElement.b(my.description)) return div
def process_sobjects(sobjects, search=None): '''process sobjects order according to pipeline process order''' if not sobjects: return if search: order_list = search.get_order_bys() # it could be search_type asc or search_tpe desc # that means the user has applied an order by in some specific column if order_list and not order_list[0].startswith('search_type'): return parent = None last_parent = None last_parent_key = None parents = [] groups = [] group = None # group tasks according to parent for i, sobject in enumerate(sobjects): # get the parent key search_type = sobject.get_value("search_type") search_id = sobject.get_value("search_id") parent_key = "%s|%s" % (search_type, search_id) process = sobject.get_value('process') if parent_key != last_parent_key: parent = SearchKey.get_by_search_key(parent_key) parents.append(parent) group = [] groups.append(group) group.append(sobject) last_parent_key = parent_key new_sobjects = [] # reorder each group for i, group in enumerate(groups): parent = parents[i] processes = [] if parent: pipeline_code = parent.get_value("pipeline_code") pipeline = Pipeline.get_by_code( pipeline_code ) if pipeline: processes = pipeline.get_process_names(recurse=True) if processes: # build a sorting key dict sort_dict = {} for sobject in group: process = sobject.get_value('process') try: sort_dict[sobject] = processes.index(process) except ValueError: # put at the bottom for outdated processes # this is important to still display tasks with outdated processe names sort_dict[sobject] = len(processes) sorted_group = sorted(group, key=sort_dict.__getitem__) new_sobjects.extend(sorted_group) else: new_sobjects.extend(group) return new_sobjects
def _execute_single(my, code, name=None): # only do actions if the edit button has been pressed from pyasm.web import WebContainer web = WebContainer.get_web() no_commit = (web.get_form_value("sobject_commit") == 'false') sobject = None if my.search_key: sobject = SearchKey.get_by_search_key(my.search_key) if not sobject: raise TacticException('This search key [%s] no longer exists.'%my.search_key) # this is needed for action handler below my.search_type = sobject.get_search_type() else: # get the search type and search id my.search_type = web.get_form_value("search_type") if my.search_type == "": raise EditCmdException( "Search type not found" ) search_id = web.get_form_value("search_id") # get the search object based on these parameters if search_id == "" or search_id == "-1": sobject = SearchType.create(my.search_type) else: search = Search(my.search_type) search.add_id_filter( search_id ) sobject = search.get_sobject() # there has to be an sobject to edit if sobject == None: raise EditCmdException("No sobject found with search type [%s] and id [%s]" % (my.search_type, search_id) ) action_handlers = my._get_action_handlers() # set the sobject for each action handler for action_handler in action_handlers: action_handler.set_sobject(sobject) if action_handler.check(): if my.parent_key: action_handler.set_option('parent_key', my.parent_key) if my.connect_key: action_handler.set_option('connect_key', my.connect_key) action_handler.execute() # set the parent, if there is one and it's in insert if sobject.is_insert() and my.parent_key: sobject.add_relationship(my.parent_key) if sobject.is_insert(): action = "Inserted" else: action = "Updated" # before we commit, we set what got changed in the info update_data = sobject.update_data for key, value in update_data.items(): # don't include None if value != None: my.info[key] = value if code: sobject.set_value("code", code) # only fill in a new with the passed in name if it has been # specified if name: sobject.set_value("name", name) # commit the changes unless told not to. # NOTE: this prevents any connections to be made if not no_commit: try: if sobject.is_insert(): is_insert = True else: is_insert = False sobject.commit() # only connect on insert if is_insert and my.connect_key and my.connect_key != "__NONE__": sobject.connect(my.connect_key, "task") except SqlException, e: msg = "An error was encountered adding this item. The error reported was [%s]" % e raise SqlException(msg) # ask the sobject for the description my.add_description( sobject.get_update_description() )
def get_files(my): paths = [] # remember this here for now my.files = {} my.snapshots = {} search_key = my.kwargs.get("search_key") sobject = SearchKey.get_by_search_key(search_key) # if it is deleted, return if not sobject: return [] if isinstance(sobject, Snapshot): snapshots = [sobject] else: snapshots = Snapshot.get_by_sobject(sobject, "publish") for snapshot in snapshots: snapshot_paths = snapshot.get_all_lib_paths() files = snapshot.get_all_file_objects() for path, file in zip(snapshot_paths, files): # if the path is a directory, get all of the files if os.path.isdir(path): for root, dirnames, filenames in os.walk(path): for filename in filenames: item_path = "%s/%s" % (root, filename) paths.append(item_path) my.files[item_path] = file my.snapshots[item_path] = snapshot for dirname in dirnames: item_path = "%s/%s/" % (root, dirname) paths.append(item_path) my.files[item_path] = file my.snapshots[item_path] = snapshot """ dirlist = os.listdir(path) for item in dirlist: item_path = "%s%s" % (path, item) if os.path.isdir(path): item_path = "%s/" % item_path paths.append(item_path) my.files[path] = file """ else: paths.append(path) my.files[path] = file base_dir_alias = file.get_value('base_dir_alias') if not my.base_dir and base_dir_alias: my.base_dir = Environment.get_asset_dir(alias=base_dir_alias) return paths
def get_display(my): search_key = my.kwargs.get("search_key") msg = None base_search_type = SearchKey.extract_search_type(search_key) sobject = SearchKey.get_by_search_key(search_key) process_div = DivWdg() process_div.add_style('padding-top: 10px') if base_search_type in ['sthpw/task', 'sthpw/note']: my.process = sobject.get_value('process') my.context = sobject.get_value('context') if not my.process: my.process = '' parent = sobject.get_parent() if parent: search_key = SearchKey.get_by_sobject(parent) else: msg = "Parent for [%s] not found"%search_key else: my.process = my.kwargs.get('process') top = my.top top.add_class('spt_simple_checkin') top.add_color("background", "background") top.add_styles("position: relative") content = DivWdg(msg) top.add(content) #content.add_border() #content.add_color("background", "background3") #content.add_color("color", "background3") content.add_style("width: 600px") content.add_styles("margin-left: auto; margin-right: auto;") content.add_style("height: 200px") from tactic.ui.widget import CheckinWdg content.add_behavior( { 'type': 'load', 'cbjs_action': CheckinWdg.get_onload_js() } ) button_div = DivWdg() content.add(process_div) content.add(button_div) button = IconWdg(title="Check-In", icon=IconWdg.CHECK_IN_3D_LG) title = Common.get_display_title(my.checkin_action) button.add_attr('title', title) button_div.add(button) button_div.set_box_shadow("1px 1px 1px 1px") button_div.add_style("width: 60px") button_div.add_style("height: 60px") button_div.add_style("float: left") button_div.add_style("background: white") button_div.add_class("hand") button_div.add_style("padding: 2px 3px 0 0") button_div.add_style("margin: 20px 60px 20px 200px") button_div.add_style("text-align: center") button_div.add("Check-in") # to be consistent with Check-in New File if my.process: checkin_process = my.process else: # Dont' specify, the user can choose later in check-in widget checkin_process = '' button.add_behavior( { 'type': 'click_up', 'search_key': search_key, 'process': checkin_process, 'context': my.context, 'cbjs_action': ''' var class_name = 'tactic.ui.widget.CheckinWdg'; var applet = spt.Applet.get(); spt.app_busy.show("Choose file(s) to check in") var current_dir = null; var is_sandbox = false; var refresh = false var values = spt.checkin.browse_folder(current_dir, is_sandbox, refresh); if (!values) { spt.app_busy.hide(); return; } var file_paths = values.file_paths; if (file_paths.length == 0) { spt.alert("You need to select files(s) to check in."); spt.app_busy.hide(); return; } spt.app_busy.hide(); var args = { 'search_key': bvr.search_key, 'show_links': false, 'show_history': false, 'close_on_publish': true } if (bvr.process) args.process = bvr.process; if (bvr.context) args.context = bvr.context; var kwargs = {}; kwargs.values = values; spt.panel.load_popup("Check-in", class_name, args, kwargs); /* var options= { title: "Check-in Widget", class_name: 'tactic.ui.widget.CheckinWdg', popup_id: 'checkin_widget' }; var bvr2 = {}; bvr2.options = options; bvr2.values = values; bvr2.args = args; spt.popup.get_widget({}, bvr2) */ ''' } ) button_div = DivWdg() content.add(button_div) button = IconWdg(title="Check-Out", icon=IconWdg.CHECK_OUT_3D_LG) button_div.add(button) button_div.set_box_shadow("1px 1px 1px 1px") button_div.add_style("width: 60px") button_div.add_style("height: 60px") button_div.add_style("float: left") button_div.add_style("margin: 20px") button_div.add_style("padding: 2px 3px 0 0") button_div.add_style("background: white") button_div.add_class("hand") button_div.add_style("text-align: center") button_div.add("Check-out") sobject = SearchKey.get_by_search_key(search_key) # snapshot is retrieved for getting the process informatoin, they are not being used # for loading as real_time snapshot query option is used. search = Search("sthpw/snapshot") search.add_sobject_filter(sobject) if my.process: search.add_filter("process", my.process) search.add_filter("is_latest", True) snapshot = search.get_sobject() if not my.process and snapshot: my.process = snapshot.get_value('process') # for old process-less snapshots if not my.process: my.process = snapshot.get_value('context') process_wdg = DivWdg(HtmlElement.b(checkin_process)) if checkin_process: width = len(checkin_process)*10 else: width = 10 process_wdg.add_styles('margin-left: auto; margin-right: auto; text-align: center; width: %s'%width) process_div.add(process_wdg) # DO NOT pass in snapshot_code, get it in real time snapshot_codes = [] show_status = True if my.checkout_action == 'latest': cbjs_action = CheckinSandboxListWdg.get_checkout_cbjs_action(my.process, show_status) bvr = {'snapshot_codes': snapshot_codes, 'real_time': True, 'file_types': ['main'], 'filename_mode': 'repo', 'cbjs_action': cbjs_action} elif my.checkout_action == 'latest (version_omitted)': cbjs_action = CheckinSandboxListWdg.get_checkout_cbjs_action(my.process, show_status) bvr = {'snapshot_codes':snapshot_codes, 'real_time': True, 'file_types': ['main'], 'filename_mode': 'versionless', 'cbjs_action': cbjs_action} elif my.checkout_action == 'latest versionless': cbjs_action = CheckinSandboxListWdg.get_checkout_cbjs_action(my.process, show_status) bvr = {'snapshot_codes':snapshot_codes, 'real_time': True, 'versionless': True, 'file_types': ['main'], 'filename_mode': 'versionless', 'cbjs_action': cbjs_action} elif my.checkout_action == 'open file browser': bvr = { 'cbjs_action': ''' var class_name = 'tactic.ui.checkin.SObjectDirListWdg'; var kwargs = { search_keys: [bvr.search_key], process: '%s' }; spt.panel.load_popup("Check-out", class_name, kwargs); '''%my.process } bvr.update({ 'type': 'click_up', 'search_key': search_key}) button.add_behavior(bvr) title = Common.get_display_title(my.checkout_action) button.add_attr('title', title) #TODO: remove these margin-top which is used to compensate all the ButtonNewWdg top extra white space content.add("<br clear='all'/>") status_div = DivWdg() status_div.add_style('margin: 20px 0 0 10px') status_div.add_style('width: 100%') text_info = FloatDivWdg() text_info.add_styles('padding: 4px; width: 500px') text_info.add_style('margin-top: 8px') text_info.add_attr('title','Displays the last checked out file path') text_info.add_border() text_info.set_round_corners() text_content = DivWdg() text_content.add(' ') text_content.add_class('spt_status_area') text_info.add(text_content) label = FloatDivWdg('path:') label.add_style('margin: 12px 6px 0 6px') # button button = ButtonNewWdg(title="Explore", icon=IconWdg.FOLDER_GO) button.add_style('padding-bottom: 15px') button.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' var applet = spt.Applet.get(); var status_div = bvr.src_el.getParent('.spt_simple_checkin').getElement('.spt_status_area'); var value = status_div.get('text'); var dir_name = spt.path.get_dirname(value); if (dir_name) applet.open_explorer(dir_name); ''' } ) status_div.add(label) status_div.add(text_info) content.add(status_div) content.add(button) content.add_behavior({'type':'load', 'cbjs_action': ''' if (!spt.Applet.applet) { spt.api.app_busy_show('Initializing Java', 'Please wait...'); var exec = function() {var applet = spt.Applet.get()}; spt.api.app_busy_hide(exec); }'''}) return top
def get_display(my): show_context = my.get_option('context') == 'true' top = DivWdg() # put in a js callback to determine the to use. top.add_class("spt_input_top") context_list = [] my.pipeline_codes = [] my.pipelines = [] my.in_edit_wdg = False parent_key = my.get_option("parent_key") if not parent_key: state = my.get_state() parent_key = state.get("parent_key") if parent_key: parent = Search.get_by_search_key(parent_key) pipeline_code = parent.get_value("pipeline_code", no_exception=True) if pipeline_code: top.add_attr("spt_cbjs_get_input_key", "return '%s'" % pipeline_code) else: # This is quite slow, but it works #top.add_attr("spt_cbjs_get_input_key", "var server=TacticServerStub.get(); var parent_key = cell_to_edit.getParent('.spt_table_tbody').getAttribute('spt_parent_key'); var parent = server.get_by_search_key(parent_key); return parent.pipeline_code") # ProcessElementWdg's handle_td() sets the spt_pipeline_code attribute top.add_attr( "spt_cbjs_get_input_key", "return cell_to_edit.getAttribute('spt_pipeline_code')") # Need to import this dynamically from tactic.ui.panel import EditWdg # This is only executed for the popup edit widget if hasattr(my, 'parent_wdg') and isinstance(my.get_parent_wdg(), EditWdg): my.in_edit_wdg = True sobject = my.get_current_sobject() parent = sobject.get_parent() if not parent: parent_key = my.get_option('parent_key') if parent_key: parent = SearchKey.get_by_search_key(parent_key) if parent: if not parent.has_value('pipeline_code'): name = my.get_input_name() text = TextWdg(name) top.add(text) sobject = my.get_current_sobject() name = my.get_name() value = sobject.get_value(name) text.set_value(value) return top #raise TacticException('[%s] needs a pipeline_code attribute to insert task.'%parent.get_code()) pipe_code = parent.get_value('pipeline_code') if pipe_code: my.pipeline_codes = [pipe_code] my.pipelines = [Pipeline.get_by_code(pipe_code)] else: # just get all of the pipelines # Cannot use expression here, because entries are added to the # result ... this causes further queries to return with the # added entries #my.pipelines = Search.eval("@SOBJECT(sthpw/pipeline)") search = Search("sthpw/pipeline") my.pipelines = search.get_sobjects() my.pipeline_codes = [x.get_code() for x in my.pipelines] # add the default my.pipeline_codes.append("") my.pipelines.append(None) for i, pipeline_code in enumerate(my.pipeline_codes): pipeline = my.pipelines[i] div = DivWdg() top.add(div) div.add_class("spt_input_option") div.add_attr("spt_input_key", pipeline_code) name = my.get_input_name() # If the pipeline code is empty, make it free form (for now) if not pipeline_code: text = TextWdg(name) div.add(text) continue select = SelectWdg(name) select.add_empty_option("-- Select a %s --" % my.get_name()) # TODO: make spt.dg_table.select_wdg_clicked keyboard action free so it won't interfere with # normal usage of the select if not my.in_edit_wdg: select.add_behavior({ 'type': 'click', 'cbjs_action': 'spt.dg_table.select_wdg_clicked( evt, bvr.src_el );' }) if not pipeline: continue # get the sub-pipeline processes as well processes = pipeline.get_processes(recurse=True) values = [] labels = [] for process in processes: is_sub_pipeline = False if process.is_from_sub_pipeline(): process_name = process.get_full_name() is_sub_pipeline = True else: process_name = process.get_name() # show context instead if show_context: output_contexts = pipeline.get_output_contexts( process.get_name()) for context in output_contexts: values.append(context) if is_sub_pipeline: #label = process_name label = context else: label = context labels.append(label) else: values.append(process_name) labels.append(process_name) select.set_option("values", values) select.set_option("labels", labels) div.add(select) # there is only 1 select for EditWdg if hasattr(my, 'parent_wdg') and isinstance( my.get_parent_wdg(), EditWdg): sobject = my.get_current_sobject() # this could be either process or context name = my.get_name() value = sobject.get_value(name) # special case to append a context with subcontext so it will stay selected in EditWdg if name == 'context' and value.find('/') != -1: select.append_option(value, value) if value: select.set_value(value) return top
def execute(my): trigger_sobj = my.get_trigger_sobj() data = trigger_sobj.get_value("data") data = jsonloads(data) print "trigger data: ", data, type(data) data_list = data if isinstance(data, dict): data_list = [data] src_task = my.get_caller() for data in data_list: # get the src task caller dst_task = None # it could be the FileCheckin Command if not isinstance(src_task, SObject): input = my.get_input() snapshot = input.get('snapshot') if not snapshot: continue if isinstance(snapshot, dict): snapshot = SearchKey.get_by_search_key( snapshot.get('__search_key__')) src_process = data.get('src_process') src_task = Search.eval("@SOBJECT(parent.sthpw/task['process','%s'])"%src_process,\ sobjects=snapshot, single=True) if not src_task: continue # make sure the caller process is the same as the source process if src_task.get_value("process") != data.get("src_process"): continue #conditionx = "@GET(.status) != 'Approved'" #result = Search.eval(conditionx, src_task) #print "result: ", result # make sure that the appropriate status was set src_status = data.get("src_status") if src_status and src_task.get_value("status") != src_status: continue dst_process = data.get("dst_process") dst_status = data.get("dst_status") sobject = src_task.get_parent() tasks = Task.get_by_sobject(sobject) updated_tasks = [] use_parent = data.get("use_parent") if use_parent in [True, 'true']: parent = sobject.get_parent() parent_tasks = Task.get_by_sobject(parent, dst_process) condition = data.get("condition") if not condition: condition = "all" if condition == "all": condition_met = True for task in tasks: if src_task.get_value("status") != src_status: condition_met = False elif condition == "any": condition_met = False for task in tasks: if task.get_value("status") == src_status: condition_met = True break if condition_met: for task in parent_tasks: if task.get_value("process") == dst_process: updated_tasks.append(task) else: for task in tasks: if task.get_value("process") == dst_process: updated_tasks.append(task) for task in updated_tasks: if task.get_value("process") == dst_process: task.set_value("status", dst_status) task.commit() """
def execute(self): input = self.get_input() mode = input.get("mode") if mode not in ['insert', 'update']: return update_data = input.get("update_data") if 'name' not in update_data and 'login_group' not in update_data: return search_key = input.get("search_key") sobj = SearchKey.get_by_search_key(search_key) # this logic makes the login name take precedence and determines the # code and login_group column # the problem is that groups are global and sometimes you want to have # the project_code prepended to the group in order to scope it # correctly. However, you don't necessarily want the name of the # project to prepend the name if mode == "insert": login_group_name = sobj.get_value('login_group') if not login_group_name: raise Exception( "A Group Name has not been entered. Please enter a Group Name." ) sobj.set_value('name', login_group_name) elif mode == "update": if 'login_group' in update_data: raise Exception( 'Login group attribute is automatically updated. Please edit only the name attribute.' ) login_group_name = sobj.get_value('name') if not login_group_name: login_group_name = sobj.get_value('login_group') login_group = re.sub( r'[\$\s,#~`\%\*\^\&\(\)\+\=\[\]\[\}\{\;\:\'\"\<\>\?\|\\\!-]', "_", login_group_name) login_group = login_group.lower() login_group_name = sobj.get_value('login_group') # make sure the project code is prepended to the login_group if sobj.get_value("project_code"): project_code = Project.get_project_code() if not login_group.startswith("%s_" % project_code): login_group = "%s_%s" % (project_code, login_group) sobj.set_value('login_group', login_group) sobj.set_value('code', login_group) sobj.commit(triggers=False) self.update_related(login_group, login_group_name)
def get_display(my): search_key = my.kwargs.get("search_key") snapshot = my.kwargs.get("snapshot") if snapshot: my.snapshot = snapshot else: my.snapshot = SearchKey.get_by_search_key(search_key) assert my.snapshot metadata = my.snapshot.get_metadata() top = my.top top.add_color("background", "background") table = Table() table.set_max_width() top.add(table) table.set_unique_id() table.add_border() table.add_smart_styles("spt_cell", { 'padding': '3px' } ) tr = table.add_row() tr.add_gradient("background", "background3") th = table.add_header("Property") th.add_style("min-width: 200px") th.add_style("padding: 5px") th = table.add_header("Value") th.add_style("min-width: 400px") th.add_style("padding: 5px") keys = metadata.get("__keys__") if not keys: keys = metadata.keys() empty = False if not keys: empty = True keys = ['','','','','','',''] table.add_smart_styles("spt_cell", { 'height': '20px' } ) for i, key in enumerate(keys): value = metadata.get(key) title = Common.get_display_title(key) tr = table.add_row() if i % 2: tr.add_color("background", "background") tr.add_color("color", "color") else: tr.add_color("background", "background", -8) tr.add_color("color", "color") td = table.add_cell() td.add_class("spt_cell") td.add(title) td = table.add_cell() td.add_class("spt_cell") td.add(value) if empty: div = DivWdg() top.add(div) div.add_style("height: 30px") div.add_style("width: 150px") div.add_style("margin-top: -110px") div.center() div.add("<b>No Metadata</b>") div.add_border() div.add_color("background", "background3") div.add_color("color", "color3") div.add_style("padding: 20px") div.add_style("text-align: center") top.add_style("min-height: 200px") return top
def get_display(self): search_key = self.kwargs.get("search_key") snapshot = self.kwargs.get("snapshot") if snapshot: self.snapshot = snapshot else: self.snapshot = SearchKey.get_by_search_key(search_key) assert self.snapshot metadata = self.snapshot.get_metadata() top = self.top top.add_color("background", "background") table = Table() table.set_max_width() top.add(table) table.set_unique_id() table.add_border() table.add_smart_styles("spt_cell", {'padding': '3px'}) tr = table.add_row() tr.add_color("background", "background", -5) th = table.add_header("Property") th.add_style("min-width: 200px") th.add_style("padding: 5px") th = table.add_header("Value") th.add_style("min-width: 400px") th.add_style("padding: 5px") keys = metadata.get("__keys__") if not keys: keys = metadata.keys() empty = False if not keys: empty = True keys = ['', '', '', '', '', '', ''] table.add_smart_styles("spt_cell", {'height': '20px'}) for i, key in enumerate(keys): value = metadata.get(key) title = Common.get_display_title(key) tr = table.add_row() if i % 2: tr.add_color("background", "background") tr.add_color("color", "color") else: tr.add_color("background", "background", -8) tr.add_color("color", "color") td = table.add_cell() td.add_class("spt_cell") td.add(title) td = table.add_cell() td.add_class("spt_cell") td.add(value) if empty: div = DivWdg() top.add(div) div.add_style("height: 30px") div.add_style("width: 150px") div.add_style("margin-top: -110px") div.center() div.add("<b>No Metadata</b>") div.add_border() div.add_color("background", "background3") div.add_color("color", "color3") div.add_style("padding: 20px") div.add_style("text-align: center") top.add_style("min-height: 200px") return top