def verify(my, login_name, password): # replace cn=attribute with cn={login} in the config ldap_path # e.g. cn={login},o=organization,ou=server,dc=domain path = Config.get_value("security", "ldap_path") server = Config.get_value("security", "ldap_server") assert path, server my.login_name = login_name my.internal = True path = path.replace("{login}", login_name) #import ldap try: l = ldap.open(server) l.simple_bind_s(path, password) l.unbind() return True except: login = Login.get_by_login(login_name) # check if it's an external account and verify with standard approach if login and login.get_value('location', no_exception=True) == 'external': auth_class = "pyasm.security.TacticAuthenticate" authenticate = Common.create_from_class_path(auth_class) is_authenticated = authenticate.verify(login_name, password) if is_authenticated == True: my.internal = False return True elif login: auth_class = "pyasm.security.TacticAuthenticate" authenticate = Common.create_from_class_path(auth_class) is_authenticated = authenticate.verify(login_name, password) if is_authenticated == True: my.internal = False return True raise SecurityException("Login/Password combination incorrect")
def get_display(my): top = my.top class_name = my.kwargs.get("display_class_name") kwargs = my.kwargs.get("display_kwargs") top.add_style("border: solid 1px #777") top.add_style("position: absolute") top.add_style("z-index: 100") top.add_style("box-shadow: 2px 2px 4px 4px #aaa") top.add_style("background: #FFF") top.add_style("margin-right: 200px") top.add_style("margin-top: -20px") top.add_style("overflow: hidden") #widget_html = "<div style='border: solid 1px #777; position: absolute; z-index: 100; box-shadow: 2px 2px 4px 4px #aaa; background: #FFF; margin-right: 20px; margin-top: -20px; overflow: hidden'>" + widget_html + "</div>"; widget = Common.create_from_class_path(class_name, kwargs) top.add(widget) show_pointer = my.kwargs.get("show_pointer") if show_pointer not in [False, 'false']: my.get_arrow_wdg() return top
def init_widget(my, widget, title=None): ''' instantiate the widget if selected. This can be called externally to instantiate any widgets added to a TabWdg''' try: # if a method was passed in, then execute it if my.mode == "check": from base_tab_wdg import BaseTabWdg try: if not issubclass(widget, BaseTabWdg): return Widget() except: return Widget() if type(widget) == types.MethodType: widget = widget() elif isinstance(widget, basestring): widget = Common.create_from_class_path(widget) elif not isinstance(widget, Widget): widget = widget() # handle docs for the help widget """ from header_wdg import DocMapping from web_wdg import HelpItemWdg help_url = ProdSetting.get_value_by_key("project_doc_url") if help_url: widget.add(HelpItemWdg('SOOT Docs', help_url)) # add the help item automatically doc = DocMapping() widget.add(HelpItemWdg('%s Tab' % title, doc.get_mapping(title))) """ # catch all exceptions and log them except Exception, e: my.handle_exception(e)
def init(my): my.widget_class = my.xml.get_value("widget/display/@class") my.draw = my.xml.get_value("widget/display/@draw") my.title = my.xml.get_value("widget/@name") my.name = my.title # convert the widget data options = {} nodes = my.xml.get_nodes("widget/display/*") for node in nodes: name = node.nodeName value = Xml.get_node_value(node) if options.has_key(name): # turn this into an array array = [] array.append(options.get(name)) array.append(value) options[name] = array else: options[name] = value my.options = options my.widget = Common.create_from_class_path(my.widget_class, [my.title])
def init(self): self.widget_class = self.xml.get_value("widget/display/@class") self.draw = self.xml.get_value("widget/display/@draw") self.title = self.xml.get_value("widget/@name") self.name = self.title # convert the widget data options = {} nodes = self.xml.get_nodes("widget/display/*") for node in nodes: name = node.nodeName value = Xml.get_node_value(node) if options.has_key(name): # turn this into an array array = [] array.append(options.get(name)) array.append(value) options[name] = array else: options[name] = value self.options = options self.widget = Common.create_from_class_path(self.widget_class, [self.title])
def execute(my): #protocol = 'xmlrpc' protocol = 'local' if protocol == 'local': server = TacticServerStub.get() else: server = TacticServerStub(protocol=protocol, setup=False) TacticServerStub.set(server) project = my.data.get("project") ticket = my.data.get("ticket") assert project assert ticket server.set_server("localhost") server.set_project(project) server.set_ticket(ticket) my.class_name = my.data.get('class_name') assert my.class_name my.kwargs = my.data.get('kwargs') if not my.kwargs: my.kwags = {} #trigger = eval("%s(**my.kwargs)" % my.class_name) trigger = Common.create_from_class_path(my.class_name, kwargs=my.kwargs) input_data = my.get_input_data() trigger.set_input(input_data) trigger.execute()
def execute(my): #protocol = 'xmlrpc' protocol = 'local' if protocol == 'local': server = TacticServerStub.get() else: server = TacticServerStub(protocol=protocol,setup=False) TacticServerStub.set(server) project = my.data.get("project") ticket = my.data.get("ticket") assert project assert ticket server.set_server("localhost") server.set_project(project) server.set_ticket(ticket) my.class_name = my.data.get('class_name') assert my.class_name my.kwargs = my.data.get('kwargs') if not my.kwargs: my.kwags = {} #trigger = eval("%s(**my.kwargs)" % my.class_name) trigger = Common.create_from_class_path(my.class_name, kwargs=my.kwargs) input_data = my.get_input_data() trigger.set_input(input_data) trigger.execute()
def get_naming(cls, naming_type, sobject=None, project=None): '''get a certain type of naming determined by type of naming''' naming_cls = "" # this import statement is needed for running Batch from pyasm.biz import Project if not project: if sobject: project = sobject.get_project() else: project = Project.get() if project: naming_cls = project.get_value("%s_naming_cls" % naming_type, no_exception=True) if not naming_cls and project.get_project_type(): naming_cls = project.get_project_type().get_value("%s_naming_cls" % naming_type, no_exception=True) # if none is defined, use defaults if not naming_cls: # TODO: this should probably be stored somewhere else if naming_type == "file": naming_cls = "pyasm.biz.FileNaming" elif naming_type == "dir": naming_cls = "pyasm.biz.DirNaming" elif naming_type == "node": naming_cls = "pyasm.prod.biz.ProdNodeNaming" naming = Common.create_from_class_path(naming_cls) return naming
def get_naming(cls, naming_type, sobject=None, project=None): '''get a certain type of naming determined by type of naming''' naming_cls = "" # this import statement is needed for running Batch from pyasm.biz import Project if not project: if sobject: project = sobject.get_project() else: project = Project.get() if project: naming_cls = project.get_value("%s_naming_cls" % naming_type, no_exception=True) if not naming_cls and project.get_project_type(): naming_cls = project.get_project_type().get_value( "%s_naming_cls" % naming_type, no_exception=True) # if none is defined, use defaults if not naming_cls: # TODO: this should probably be stored somewhere else if naming_type == "file": naming_cls = "pyasm.biz.FileNaming" elif naming_type == "dir": naming_cls = "pyasm.biz.DirNaming" elif naming_type == "node": naming_cls = "pyasm.prod.biz.ProdNodeNaming" naming = Common.create_from_class_path(naming_cls) return naming
def execute_python_cmd(my, class_name, kwargs): import sys exec_class_name = 'tactic_client_lib.scm.CmdWrapper' kwargs = json.loads(kwargs) kwargs['class_name'] = class_name cmd = Common.create_from_class_path(exec_class_name, [], kwargs) ret_val = cmd.execute() return json.dumps(ret_val)
def build_widget(cls, options): class_name = options.get('class_name') if not class_name: class_name = 'tactic.ui.panel.ViewPanelWdg' else: del(options['class_name']) widget = Common.create_from_class_path(class_name, kwargs=options) return widget
def query_EditWdg(args=None, search_type=''): import json from pyasm.widget.widget_config import WidgetConfigView def pop_classes(in_dict): out_dict = {} for key, val in in_dict.iteritems(): if not (hasattr(val, '__dict__') or key.startswith('_')): out_dict[key] = val return out_dict class_name = 'tactic.ui.panel.EditWdg' args_array = [] from pyasm.common import Common # from pyasm.common import Container widget = Common.create_from_class_path(class_name, args_array, args) widget.explicit_display() result_dict = { 'EditWdg': { 'element_descriptions': widget.element_descriptions, 'element_names': widget.element_names, 'element_titles': widget.element_titles, 'input_prefix': widget.input_prefix, 'kwargs': widget.kwargs, 'mode': widget.mode, 'security_denied': widget.security_denied, 'title': widget.title, }, 'InputWidgets': [], 'sobject': '', } input_widgets = widget.get_widgets() wdg_config = WidgetConfigView.get_by_element_names(search_type, widget.element_names, base_view=args['view']) temprorary_ignore = ['pyasm.prod.web.prod_input_wdg.ProjectSelectWdg'] # , 'pyasm.widget.input_wdg.SelectWdg' bug with this widget for i_widget in input_widgets: widget_dict = pop_classes(i_widget.__dict__) # for wv, wi in widget_dict.items(): # if type(wi) not in [dict, None, str, int, bool, list, set, tuple]: # widget_dict[wv] = str(wi) widget_dict['action_options'] = wdg_config.get_action_options( widget_dict.get('name')) widget_dict['class_name'] = i_widget.get_class_name() item_values = i_widget.get_values() if item_values: widget_dict['values'] = item_values if widget_dict['class_name'] not in temprorary_ignore: result_dict['InputWidgets'].append(widget_dict) return json.dumps(result_dict, separators=(',', ':'))
def get_code_naming(sobject,code): '''Gets the code naming object for the current project''' project = Project.get() code_naming_cls = project.get_value("code_naming_cls") if code_naming_cls == "": code_naming_cls = "pyasm.biz.CodeNaming" naming = Common.create_from_class_path(code_naming_cls, \ [sobject,code] ) return naming
def get_code_naming(sobject, code): '''Gets the code naming object for the current project''' project = Project.get() code_naming_cls = project.get_value("code_naming_cls") if code_naming_cls == "": code_naming_cls = "pyasm.biz.CodeNaming" naming = Common.create_from_class_path(code_naming_cls, \ [sobject,code] ) return naming
def init(my): web = WebContainer.get_web() widget_class = web.get_form_value("dynamic_widget") widget_args = web.get_form_values("args") if widget_class == "": raise DynamicLoaderException("Widget class [%s] is not defined" % widget_class) widget = Common.create_from_class_path( widget_class, widget_args ) my.add_widget(widget)
def run_batch(kwargs): command = k.get("command") kwargs = k.get("kwargs") login = k.get("login") project_code = k.get("project_code") from pyasm.security import Batch Batch(project_code=project_code, login_code=login) cmd = Common.create_from_class_path(command, kwargs=kwargs) Command.execute_cmd(cmd)
def init(my): web = WebContainer.get_web() widget_class = web.get_form_value("dynamic_widget") widget_args = web.get_form_values("args") if widget_class == "": raise DynamicLoaderException("Widget class [%s] is not defined" % widget_class) widget = Common.create_from_class_path(widget_class, widget_args) my.add_widget(widget)
def get_title(my): my.widget = Common.create_from_class_path(my.widget_class, [my.title]) my.widget.options = my.options my.widget.set_title(my.title) my.widget.set_name(my.title) Container.put_dict("widgets", my.title, my.widget) index = my.get_current_index() my.widget.set_sobjects(my.sobjects) my.widget.set_current_index(index) if my.draw == "false": return "" else: return my.widget.get_title()
def get_title(self): self.widget = Common.create_from_class_path(self.widget_class, [self.title]) self.widget.options = self.options self.widget.set_title(self.title) self.widget.set_name(self.title) Container.put_dict("widgets", self.title, self.widget) index = self.get_current_index() self.widget.set_sobjects(self.sobjects) self.widget.set_current_index(index) if self.draw == "false": return "" else: return self.widget.get_title()
def query_EditWdg(args=None, search_type=''): import json from pyasm.widget.widget_config import WidgetConfigView def pop_classes(in_dict): out_dict = {} for key, val in in_dict.iteritems(): if not (hasattr(val, '__dict__') or key.startswith('_')): out_dict[key] = val return out_dict class_name = 'tactic.ui.panel.EditWdg' args_array = [] from pyasm.common import Common # from pyasm.common import Container widget = Common.create_from_class_path(class_name, args_array, args) widget.explicit_display() result_dict = { 'EditWdg': { 'element_descriptions': widget.element_descriptions, 'element_names': widget.element_names, 'element_titles': widget.element_titles, 'input_prefix': widget.input_prefix, 'kwargs': widget.kwargs, 'mode': widget.mode, 'security_denied': widget.security_denied, 'title': widget.title, }, 'InputWidgets': [], 'sobject': '', } input_widgets = widget.get_widgets() wdg_config = WidgetConfigView.get_by_element_names(search_type, widget.element_names, base_view=args['view']) for i_widget in input_widgets: widget_dict = pop_classes(i_widget.__dict__) widget_dict['action_options'] = wdg_config.get_action_options(widget_dict.get('name')) widget_dict['class_name'] = i_widget.get_class_name() item_values = i_widget.get_values() if item_values: widget_dict['values'] = item_values result_dict['InputWidgets'].append(widget_dict) return json.dumps(result_dict, separators=(',', ':'))
def get_project_repo_handler(project_code=None): if not project_code: project = Project.get() else: project = Project.get_by_code(project_code) repo_handler_cls = project.get_value("repo_handler_cls", no_exception=True) if not repo_handler_cls and project.get_project_type(): repo_handler_cls = project.get_project_type().get_value("repo_handler_cls", no_exception=True) if not repo_handler_cls: repo_handler_cls = "pyasm.biz.BaseRepoHandler" repo_handler = Common.create_from_class_path(repo_handler_cls) return repo_handler
def add(self,widget,title=None): if title == None: title = widget.__class__.__name__ # determine the url and check security request_url = WebContainer.get_web().get_request_url() base = request_url.get_base() if base.endswith("/"): base = "%sIndex" % base check = "%s|%s" % (base,title) security = WebContainer.get_security() if not security.check_access("url", check, "view"): return if not security.check_access("tab", title, "view"): return self.tab_names.append(title) # for tabs, the widget passed in can be None. Only the # title is added assert widget != None # only the selected one really gets added try: # if a method was passed in, then execute it if type(widget) == types.MethodType: widget = MethodWdg(widget) elif isinstance(widget, basestring): widget = Common.create_from_class_path(widget) elif not isinstance(widget, Widget): widget = ClassWdg(widget) # catch all exceptions and log them except Exception as e: self.handle_exception(e) super(DynTabWdg,self)._add_widget(widget, title)
def add(self, widget, title=None): if title == None: title = widget.__class__.__name__ # determine the url and check security request_url = WebContainer.get_web().get_request_url() base = request_url.get_base() if base.endswith("/"): base = "%sIndex" % base check = "%s|%s" % (base, title) security = WebContainer.get_security() if not security.check_access("url", check, "view"): return if not security.check_access("tab", title, "view"): return self.tab_names.append(title) # for tabs, the widget passed in can be None. Only the # title is added assert widget != None # only the selected one really gets added try: # if a method was passed in, then execute it if type(widget) == types.MethodType: widget = MethodWdg(widget) elif isinstance(widget, basestring): widget = Common.create_from_class_path(widget) elif not isinstance(widget, Widget): widget = ClassWdg(widget) # catch all exceptions and log them except Exception as e: self.handle_exception(e) super(DynTabWdg, self)._add_widget(widget, title)
def init_widget(self, widget, title=None): ''' instantiate the widget if selected. This can be called externally to instantiate any widgets added to a TabWdg''' try: # if a method was passed in, then execute it if self.mode == "check": from base_tab_wdg import BaseTabWdg try: if not issubclass(widget, BaseTabWdg): return Widget() except: return Widget() if type(widget) == types.MethodType: widget = widget() elif isinstance(widget, basestring): widget = Common.create_from_class_path(widget) elif not isinstance(widget, Widget): widget = widget() # handle docs for the help widget """ from header_wdg import DocMapping from web_wdg import HelpItemWdg help_url = ProdSetting.get_value_by_key("project_doc_url") if help_url: widget.add(HelpItemWdg('SOOT Docs', help_url)) # add the help item automatically doc = DocMapping() widget.add(HelpItemWdg('%s Tab' % title, doc.get_mapping(title))) """ # catch all exceptions and log them except Exception as e: self.handle_exception(e) return widget
Command.execute_cmd(cmd) # set job to complete my.job.set_value("state", "complete") except Exception, e: my.job.set_value("state", "error") my.job.commit() my.jobs.remove(my.job) my.job = None my.jobs_completed += 1 elif queue_type == 'repeat': cmd = Common.create_from_class_path(command, kwargs=kwargs) attempts = 0 max_attempts = 3 retry_interval = 5 while 1: try: Command.execute_cmd(cmd) #cmd.execute() # set job to complete my.job.set_value("state", "complete") break except TacticException, e: # This is an error on this server, so just exit # and don't bother retrying
def execute(my): start = time.time() from pyasm.common import SPTDate timestamp = SPTDate.now() timestamp = SPTDate.add_gmt_timezone(timestamp) timestamp = SPTDate.convert_to_local(timestamp) format = '%Y-%m-%d %H:%M:%S' timestamp = timestamp.strftime(format) updates = my.kwargs.get("updates") if isinstance(updates, basestring): updates = jsonloads(updates) last_timestamp = my.kwargs.get("last_timestamp") #assert last_timestamp if not last_timestamp: my.info = {"updates": {}, "timestamp": timestamp} return last_timestamp = parser.parse(last_timestamp) last_timestamp = SPTDate.add_gmt_timezone(last_timestamp) # give 2 seconds of extra room last_timestamp = last_timestamp - timedelta(seconds=2) # get out all of the search_keys client_keys = set() client_stypes = set() for id, values_list in updates.items(): if isinstance(values_list, dict): values_list = [values_list] for values in values_list: handler = values.get("handler") if handler: handler = Common.create_from_class_path(handler) # it could be a list search_key = handler.get_search_key() else: search_key = values.get("search_key") if search_key: if isinstance(search_key, list): search_key_set = set(search_key) else: search_key_set = set() search_key_set.add(search_key) client_keys.update(search_key_set) stype = values.get("search_type") if stype: client_stypes.add(stype) # find all of the search that have changed changed_keys = set() changed_types = set() for check_type in ['sthpw/change_timestamp', 'sthpw/sobject_log']: search = Search(check_type) search.add_filter("timestamp", last_timestamp, op=">") search.add_filters("search_type", ["sthpw/sobject_log", "sthpw/status_log"], op="not in") changed_sobjects = search.get_sobjects() for sobject in changed_sobjects: search_type = sobject.get_value("search_type") search_code = sobject.get_value("search_code") if search_type.startswith("sthpw/"): search_key = "%s?code=%s" % (search_type, search_code) else: search_key = "%s&code=%s" % (search_type, search_code) changed_keys.add(u'%s' % search_key) changed_types.add(search_type) intersect_keys = client_keys.intersection(changed_keys) from pyasm.web import HtmlElement results = {} for id, values_list in updates.items(): if isinstance(values_list, dict): values_list = [values_list] for values in values_list: handler = values.get("handler") if handler: handler = Common.create_from_class_path(handler) # handler can return a list of search_keys search_key = handler.get_search_key() else: search_key = values.get("search_key") stype = values.get("search_type") if search_key: if isinstance(search_key, list): search_key_set = set(search_key) else: search_key_set = set() search_key_set.add(search_key) # filter for search_type first if it exists # check if any search_key is contained in intersect_keys, skip if not if stype and stype in changed_types: if len(intersect_keys - search_key_set) == len(intersect_keys): continue elif len(intersect_keys - search_key_set) == len(intersect_keys): continue # evaluate any compare expressions compare = values.get("compare") if compare: search_key = values.get("search_key") if search_key: sobject = Search.get_by_search_key(search_key) else: sobject = None cmp_result = Search.eval(compare, sobject, single=True) if cmp_result == True: continue # some value to display value = "Loading ..." else: value = HtmlElement.eval_update(values) if value == None: continue results[id] = value my.info = {"updates": results, "timestamp": timestamp} #print "Dyn Cmd duration", time.time() - start return results
def get_display(self): widget = Widget() self.search_type = self.options.get("search_type") if not self.search_type: self.search_type = self.kwargs.get("search_type") assert self.search_type self.load_options_class = self.kwargs.get('load_options_class') state = Container.get("global_state") if state: self.process = state.get("process") else: self.process = None # the filter for searching assets div = DivWdg(css='filter_box') div.add_color("background", "background2", -35) from app_init_wdg import PyMayaInit, PyXSIInit, PyHoudiniInit if WebContainer.get_web().get_selected_app() == 'Maya': app = PyMayaInit() elif WebContainer.get_web().get_selected_app() == 'XSI': app = PyXSIInit() elif WebContainer.get_web().get_selected_app() == 'Houdini': app = PyHoudiniInit() div.add(app) # add the possibility of a custom callback callback = self.options.get('callback') if callback: hidden = HiddenWdg("callback", callback) div.add(hidden) # or add the possiblity of a switch mode pipeline_type = "load" hidden = HiddenWdg("pipeline_type", pipeline_type) if self.process: process_div = DivWdg() process_div.add_style("margin: 10px") process_div.add("PROCESS: %s" % self.process) process_div.add_style("font-size: 20px") widget.add(process_div) hidden_wdg = HiddenWdg("process_select_%s" % self.search_type) hidden_wdg.set_value(self.process) widget.add(hidden_wdg) else: search_type = self.search_type if search_type == 'prod/shot_instance': search_type = 'prod/shot' process_filter = ProcessFilterWdg( self.get_context_data(search_type), search_type) span = SpanWdg(process_filter, css='med') div.add(span) widget.add(div) # load options for diff search type if self.load_options_class: load_options = Common.create_from_class_path( self.load_options_class) elif self.search_type == 'prod/asset': load_options = LoadOptionsWdg() elif self.search_type == 'prod/shot': load_options = ShotLoadOptionsWdg() elif self.search_type == 'prod/shot_instance': load_options = AnimLoadOptionsWdg() else: load_options = LoadOptionsWdg() load_options.set_prefix(self.search_type) widget.add(load_options) return widget
def check_new_job(my): num_jobs = len(my.jobs) if num_jobs >= my.max_jobs: print "Already at max jobs [%s]" % my.max_jobs return my.job = my.get_next_job() if not my.job: return # set the process key process_key = my.get_process_key() my.job.set_value("host", process_key) my.job.commit() my.jobs.append(my.job) # get some info from the job command = my.job.get_value("command") job_code = my.job.get_value("code") #print "Grabbing job [%s] ... " % job_code try: kwargs = my.job.get_json_value("data") except: try: kwargs = my.job.get_json_value("serialized") except: kwargs = {} project_code = my.job.get_value("project_code") login = my.job.get_value("login") script_path = my.job.get_value("script_path", no_exception=True) if script_path: Project.set_project(project_code) command = 'tactic.command.PythonCmd' folder = os.path.dirname(script_path) title = os.path.basename(script_path) search = Search("config/custom_script") search.add_filter("folder", folder) search.add_filter("title", title) custom_script = search.get_sobject() script_code = custom_script.get_value("script") kwargs['code'] = script_code # add the job to the kwargs kwargs['job'] = my.job #print "command: ", command #print "kwargs: ", kwargs # Because we started a new thread, the environment may not # yet be initialized try: from pyasm.common import Environment Environment.get_env_object() except: print "running batch" Batch() queue = my.job.get_value("queue", no_exception=True) queue_type = 'repeat' print "running job: ", my.job.get_value("code") if queue_type == 'inline': cmd = Common.create_from_class_path(command, kwargs=kwargs) try: Command.execute_cmd(cmd) # set job to complete my.job.set_value("state", "complete") except Exception, e: my.job.set_value("state", "error") my.job.commit() my.jobs.remove(my.job) my.job = None
def init(my): super(SObjectCalendarWdg,my).init() custom_view = my.kwargs.get('view') my.custom_layout = None if custom_view: from tactic.ui.panel import CustomLayoutWdg #custom_kwargs = my.kwargs.copy() custom_kwargs = my.kwargs.get("kwargs") if not custom_kwargs: custom_kwargs = {} elif isinstance(custom_kwargs, basestring): custom_kwargs = eval(custom_kwargs) custom_kwargs['view'] = custom_view my.custom_layout = CustomLayoutWdg(**custom_kwargs) class_name = "tactic.ui.widget.BaseCalendarDayWdg" else: class_name = my.kwargs.get('handler') if not class_name: class_name = 'tactic.ui.widget.TaskCalendarDayWdg' my.custom_layout = None my.handler = Common.create_from_class_path(class_name, [], my.kwargs) my.sobject_display_expr = my.kwargs.get('sobject_display_expr') # set the border style my.kwargs['border_type'] = 'all' my.handle_search() my.width = my.kwargs.get("cell_width") if not my.width: my.width = '100%' my.height = my.kwargs.get("cell_height") if not my.height: my.height = '80px' # preprocess the sobjects so that they are order by date my.date_sobjects = {} # get all of the weeks in this month my.sobjects_week_index = [] for i in my.weeks: my.sobjects_week_index.append([]) for index, sobject in enumerate(my.sobjects): start_date = sobject.get_value(my.start_column) if not start_date: continue start_date = parser.parse(start_date) end_date = sobject.get_value(my.end_column) if not end_date: continue end_date = parser.parse(end_date) for i, week in enumerate(my.weeks): first_day = week[0] first_day = datetime(first_day.year, first_day.month, first_day.day) last_day = week[6] + timedelta(days=1) last_day = datetime(last_day.year, last_day.month, last_day.day) is_in_week = False # if this sobject falls in this week if start_date >= first_day and start_date < last_day: is_in_week = True elif end_date >= first_day and end_date < last_day: is_in_week = True elif start_date < first_day and end_date > last_day: is_in_week = True if is_in_week: my.sobjects_week_index[i].append(sobject) # for each day in the sobject's timeline, add it to the appropriate # day list days = list(rrule.rrule(rrule.DAILY, dtstart=start_date, until=end_date)) for date in days: date_str = date.strftime("%Y-%m-%d") sobj_list = my.date_sobjects.get(date_str) if not sobj_list: # create a new list for that day sobj_list = [] my.date_sobjects[date_str] = sobj_list sobj_list.append(sobject) my.current_week = -1
def handle_simple_mode(my, custom_table, mode): tbody = custom_table.add_tbody() tbody.add_class("spt_custom_simple") if mode != 'simple': tbody.add_style('display: none') name_text = TextWdg("custom_name") name_text.add_class("spt_input") tr = custom_table.add_row() tr.add_color("background", "background", -7) td = custom_table.add_cell("Name: ") td.add_style("min-width: 150px") custom_table.add_cell(name_text) # add title custom_table.add_row() title_wdg = TextWdg("custom_title") title_wdg.add_attr("size", "50") custom_table.add_cell( "Title: " ) custom_table.add_cell( title_wdg ) # add description tr = custom_table.add_row() tr.add_color("background", "background", -7) description_wdg = TextAreaWdg("custom_description") custom_table.add_cell( "Description: " ) custom_table.add_cell( description_wdg ) type_select = SelectWdg("custom_type") type_select.add_class("spt_input") #type_select.add_empty_option("-- Select --") type_select.set_option("values", "string|text|integer|float|boolean|currency|date|foreign_key|list|button|empty") type_select.set_option("labels", "String(db)|Text(db)|Integer(db)|Float(db)|Boolean(db)|Currency(db)|Date(db)|Foreign Key(db)|List(db)|Button|Empty") #type_select.set_option("labels", "String|Integer|Boolean|Currency|Timestamp|Link|Foreign Key|List|Checkbox|Text|Number|Date|Date Range") tr = custom_table.add_row() custom_table.add_cell("Property Type: ") td = custom_table.add_cell(type_select) type_select.add_event("onchange", "spt.custom_property_adder.property_type_select_cbk(this)") # extra info for foreign key custom_table.add_row() div = DivWdg() div.add_class("foreign_key_options") div.add_style("display: none") div.add_style("margin-top: 10px") div.add("Options") div.add(HtmlElement.br()) # TODO: this class should not be in prod!! from pyasm.prod.web import SearchTypeSelectWdg div.add("Relate to: ") search_type_select = SearchTypeSelectWdg("foreign_key_search_select", mode=SearchTypeSelectWdg.CURRENT_PROJECT) div.add(search_type_select) td.add(div) # extra info for list custom_table.add_row() div = DivWdg() div.add_class("list_options") div.add_style("display: none") div.add_style("margin-top: 10px") div.add("Options") div.add(HtmlElement.br()) # TODO: this class should not be in prod!! from pyasm.prod.web import SearchTypeSelectWdg div.add("Values: ") search_type_text = TextWdg("list_values") div.add(search_type_text) td.add(div) # extra info for button custom_table.add_row() div = DivWdg() div.add_class("button_options") div.add_style("display: none") div.add_style("margin-top: 10px") class_path = "tactic.ui.table.ButtonElementWdg" button = Common.create_from_class_path(class_path) args_keys = button.get_args_keys() div.add("Options") div.add(HtmlElement.br()) for key in args_keys.keys(): div.add("Name: ") option_name_text = TextWdg("option_name") option_name_text.add_attr("readonly", "true") option_name_text.set_value(key) div.add(option_name_text) div.add(" ") div.add("Value: ") input = button.get_input_by_arg_key(key) div.add(input) #option_value_text = TextWdg("option_value") #div.add(option_value_text) div.add(HtmlElement.br()) td.add(div) # is searchable checkbox tr = custom_table.add_row() tr.add_color("background", "background", -7) current_searchable_wdg = CheckboxWdg("is_searchable") #current_view_wdg.set_checked() custom_table.add_cell("Is Searchable? ") td = custom_table.add_cell(current_searchable_wdg) custom_table.close_tbody()
def check_new_job(self, queue_type=None): num_jobs = len(self.jobs) if num_jobs >= self.max_jobs: print("Already at max jobs [%s]" % self.max_jobs) return self.job = self.get_next_job(queue_type) if not self.job: return # set the process key process_key = self.get_process_key() self.job.set_value("host", process_key) self.job.commit() self.jobs.append(self.job) # get some info from the job command = self.job.get_value("command") job_code = self.job.get_value("code") try: kwargs = self.job.get_json_value("data") except: try: # DEPRECATED kwargs = self.job.get_json_value("serialized") except: kwargs = {} if not kwargs: kwargs = {} login = self.job.get_value("login") script_path = self.job.get_value("script_path", no_exception=True) project_code = self.job.get_value("project_code") if script_path: command = 'tactic.command.PythonCmd' folder = os.path.dirname(script_path) title = os.path.basename(script_path) search = Search("config/custom_script") search.add_filter("folder", folder) search.add_filter("title", title) custom_script = search.get_sobject() script_code = custom_script.get_value("script") kwargs['code'] = script_code # add the job to the kwargs kwargs['job'] = self.job #print("command: ", command) #print("kwargs: ", kwargs) # Because we started a new thread, the environment may not # yet be initialized try: from pyasm.common import Environment Environment.get_env_object() except: # it usually is run at the very first transaction Batch() Project.set_project(project_code) queue = self.job.get_value("queue", no_exception=True) queue_type = 'repeat' stop_on_error = False print("Running job: ", self.job.get_value("code") ) if queue_type == 'inline': cmd = Common.create_from_class_path(command, kwargs=kwargs) try: Container.put(Command.TOP_CMD_KEY, None) Container.put(Transaction.KEY, None) Command.execute_cmd(cmd) # set job to complete self.job.set_value("state", "complete") except Exception as e: self.job.set_value("state", "error") self.job.commit() self.jobs.remove(self.job) self.job = None self.jobs_completed += 1 elif queue_type == 'repeat': attempts = 0 max_attempts = 3 retry_interval = 5 Container.put(Transaction.KEY, None) while 1: try: cmd = Common.create_from_class_path(command, kwargs=kwargs) Container.put(Command.TOP_CMD_KEY, None) Command.execute_cmd(cmd) #cmd.execute() # set job to complete self.job.set_value("state", "complete") break except TacticException as e: # This is an error on this server, so just exit # and don't bother retrying print("Error: ", e) self.job.set_value("state", "error") break except Exception as e: if stop_on_error: raise print("WARNING in Queue: ", e) import time time.sleep(retry_interval) attempts += 1 if attempts >= max_attempts: print("ERROR: reached max attempts") self.job.set_value("state", "error") break print("Retrying [%s]...." % attempts) self.job.commit() self.jobs.remove(self.job) self.job = None self.jobs_completed += 1 else: class ForkedTask(SchedulerTask): def __init__(self, **kwargs): super(ForkedTask, self).__init__(**kwargs) def execute(self): # check to see the status of this job """ job = self.kwargs.get('job') job_code = job.get_code() search = Search("sthpw/queue") search.add_filter("code", job_code) self.kwargs['job'] = search.get_sobject() if not job: print("Cancelling ...") return state = job.get_value("state") if state == "cancel": print("Cancelling 2 ....") return """ subprocess_kwargs = { 'login': login, 'project_code': project_code, 'command': command, 'kwargs': kwargs } subprocess_kwargs_str = jsondumps(subprocess_kwargs) install_dir = Environment.get_install_dir() python = Config.get_value("services", "python") if not python: python = 'python' args = ['%s' % python, '%s/src/tactic/command/queue.py' % install_dir] args.append(subprocess_kwargs_str) import subprocess p = subprocess.Popen(args) DbContainer.close_thread_sql() return # can't use a forked task ... need to use a system call #Command.execute_cmd(cmd) # register this as a forked task task = ForkedTask(name=job_code, job=self.job) scheduler = Scheduler.get() scheduler.start_thread() # FIXME: the queue should not be inline if queue == 'interval': interval = self.job.get_value("interval") if not interval: interval = 60 scheduler.add_interval_task(task, interval=interval,mode='threaded') else: scheduler.add_single_task(task, mode='threaded')
def get_from_db_naming(my, search_type): project_code = Project.get_project_code() if project_code in ["admin", "sthpw"]: return "" file_type = my.get_file_type() filename = my.file_object.get_full_file_name() naming = Naming.get(my.sobject, my.snapshot, file_path=filename) if not naming: return None if naming and my.checkin_type: checkin_type = naming.get_value('checkin_type') if checkin_type and my.checkin_type != checkin_type: print "mismatched checkin_type!" naming = None return None naming_util = NamingUtil() # Provide a mechanism for a custom class naming_class = naming.get_value("class_name", no_exception=True) if naming_class: kwargs = { 'sobject': my.sobject, 'snapshot': my.snapshot, 'file_object': my.file_object, 'ext': my.get_ext(), 'mode': 'file' } naming = Common.create_from_class_path(naming_class, kwargs) filename = naming.get_file() if filename: return filename # provide a mechanism for a custom client side script script_path = naming.get_value("script_path", no_exception=True) if script_path: project_code = my.sobject.get_project_code() input = { 'sobject': my.sobject, 'snapshot': my.snapshot, 'file_object': my.file_object, 'ext': my.get_ext(), 'mode': 'file', 'project': project_code } from tactic.command import PythonCmd cmd = PythonCmd(script_path=script_path, input=input) results = cmd.execute() if results: return results naming_value = naming.get_value("file_naming") if not naming_value: is_versionless = naming.get_value("latest_versionless") or naming.get_value("current_versionless") if not is_versionless: return "" # FIXME: # if this is a versionless naming, then empty uses a default # This is put here because the check-in type is determined by the # naming here. Normally, this is passed through with "naming_expr" # but in snapshot.py, it is not yet known that this is an "auto" # checkin_type because it is defined in the naming and not the # process server = Config.get_value("install", "server") if server: naming_value= "{basefile}_{snapshot.process}_%s.{ext}" % server else: naming_value = "{basefile}_{snapshot.process}.{ext}" # check for manual_version manual_version = naming.get_value('manual_version') if manual_version == True: # if the file version is not the same as the snapshot version # then check to see if the snapshot already exists filename = my.file_object.get_full_file_name() version = my.get_version_from_file_name(filename) context = my.snapshot.get_context() if version > 0 and version != my.snapshot.get_value("version"): existing_snap = Snapshot.get_snapshot(\ my.snapshot.get_value("search_type"),\ my.snapshot.get_value("search_id"), context=context, \ version=version, show_retired=True) if existing_snap: raise TacticException('You have chosen manual version in Naming for this SObject. A snapshot with context "%s" and version "%s" already exists.' % (context, version) ) my.snapshot.set_value("version", version) my.snapshot.commit() file_type = my.get_file_type() return naming_util.naming_to_file(naming_value, my.sobject,my.snapshot,my.file_object,ext=my.get_ext(),file_type=file_type)
def run(my): import time time.sleep(6) #print "Starting Timed Trigger" # checks are done every 60 seconds chunk = 60 # FIXME: not sure why we have to do a batch here from pyasm.security import Batch Batch(login_code="admin") # get the all of the timed triggers #search = Search("sthpw/timed_trigger") #search.add_filter("type", "timed") search = Search("sthpw/trigger") search.add_filter("event", "timed") timed_trigger_sobjs = search.get_sobjects() timed_triggers = [] for trigger_sobj in timed_trigger_sobjs: trigger_class = trigger_sobj.get_value("class_name") try: timed_trigger = Common.create_from_class_path(trigger_class) except ImportError: raise Exception("WARNING: [%s] does not exist" % trigger_class) timed_triggers.append(timed_trigger) while 1: time.sleep(chunk) #print "Running timer" date = Date() #print "utc: ", date.get_display_time() # go through each trigger for timed_trigger in timed_triggers: print timed_trigger if not timed_trigger.is_ready(): print "... not ready" continue if timed_trigger.is_in_separate_thread(): class xxx(threading.Thread): def run(my): try: Batch() timed_trigger._do_execute() finally: DbContainer.close_thread_sql() xxx().start() else: timed_trigger._do_execute() DbContainer.close_thread_sql() if my.end: print "Stopping timed thread" break
def get_display(my): top_wdg = DivWdg() top_wdg.add_style("color: black") top_wdg.add_style("width: 350px") top_wdg.add_style("margin-top: 10px") top_wdg.add_style("padding: 10px") top_wdg.add_border() title = DivWdg() title.add_style("color: black") title.add_style("margin-top: -22px") top_wdg.add(title) #if not my.name_string: # title.add('No database column') # return top_wdg title.add("Widget Definition") widget_types = { 'foreign_key': 'tactic.ui.table.ForeignKeyElementWdg', 'button': 'tactic.ui.table.ButtonElementWdg', 'expression': 'tactic.ui.table.ExpressionElementWdg' } web = WebContainer.get_web() config_string = web.get_form_value("config_xml") if not config_string: config_string = '<config/>' xml = Xml() xml.read_string(config_string) #print "config_string: ", config_string # get values from the config file element_name = xml.get_value('element/@name') config = WidgetConfig.get( view='element', xml='<config><element>%s</element></config>' % config_string) display_options = config.get_display_options(element_name) title = xml.get_value('element/@title') display_handler = xml.get_value('element/display/@class') if not display_handler: display_handler = 'tactic.ui.panel.TypeTableElementWdg' widget_name = xml.get_value('element/display/@widget') if not widget_name: widget_name = 'custom' custom_table = Table() custom_table.add_style("color: black") top_wdg.add(custom_table) name_text = DivWdg() name_text.add_style("color: black") name_text.add(element_name) custom_table.add_row() custom_table.add_cell("Name: ") custom_table.add_cell(name_text) # add title custom_table.add_row() title_wdg = TextWdg("custom_title") title_wdg.set_value(title) title_wdg.add_attr("size", "50") custom_table.add_cell("Title: ") custom_table.add_cell(title_wdg) # add description #custom_table.add_row() #description_wdg = TextAreaWdg("custom_description") #td = custom_table.add_cell( "Description: " ) #td.add_style("vertical-align: top") #custom_table.add_cell( description_wdg ) type_select = SelectWdg("custom_type") #type_select.add_empty_option("-- Select --") type_select.set_option( "values", "string|integer|float|boolean|currency|date|foreign_key|link|list|button|custom" ) type_select.set_option( "labels", "String(db)|Integer(db)|Float(db)|Boolean(db)|Currency(db)|Date(db)|Foreign Key|Link|List|Button|Custom" ) type_select.set_value(widget_name) #type_select.set_option("values", "string|integer|float|boolean|currency|date|link|list|foreign_key|button|empty") #type_select.set_option("labels", "String|Integer|Float|Boolean|Currency|Date|Link|List|Foreign Key|Button|Empty") custom_table.add_row() td = custom_table.add_cell("Widget Type: ") td.add_style("vertical-align: top") td = custom_table.add_cell(type_select) type_select.add_event( "onchange", "spt.CustomProject.property_type_select_cbk(this)") td.add(HtmlElement.br()) display_handler_text = TextWdg("display_handler") display_handler_text.add_attr("size", "50") display_handler_text.set_value(display_handler) td.add(display_handler_text) # extra info for foreign key custom_table.add_row() div = DivWdg() div.add_class("foreign_key_options") div.add_style("display: none") div.add_style("margin-top: 10px") div.add("Options") div.add(HtmlElement.br()) # extra info for foreign key custom_table.add_row() div = DivWdg() div.add_class("foreign_key_options") div.add_style("display: none") div.add_style("margin-top: 10px") div.add("Options") div.add(HtmlElement.br()) # TODO: this class should not be in prod!! from pyasm.prod.web import SearchTypeSelectWdg div.add("Relate to: ") search_type_select = SearchTypeSelectWdg( "foreign_key_search_select", mode=SearchTypeSelectWdg.CURRENT_PROJECT) div.add(search_type_select) td.add(div) # extra info for list custom_table.add_row() div = DivWdg() div.add_class("list_options") div.add_style("display: none") div.add_style("margin-top: 10px") div.add("Options") div.add(HtmlElement.br()) # TODO: this class should not be in prod!! from pyasm.prod.web import SearchTypeSelectWdg div.add("Values: ") search_type_text = TextWdg("list_values") div.add(search_type_text) td.add(div) # extra info for button custom_table.add_row() div = DivWdg() div.add_style("color: black") div.add_class("button_options") div.add_style("display: none") div.add_style("margin-top: 10px") #class_path = "tactic.ui.table.ButtonElementWdg" class_path = display_handler button = Common.create_from_class_path(class_path) args_keys = button.get_args_keys() div.add("Options") div.add(HtmlElement.br()) for key in args_keys.keys(): option_name_text = HiddenWdg("option_name") option_name_text.set_value(key) div.add(option_name_text) div.add("%s: " % key) div.add(" ") input = button.get_input_by_arg_key(key) value = display_options.get(key) if value: input.set_value(value) div.add(input) div.add(HtmlElement.br()) td.add(div) # is searchable checkbox #custom_table.add_row() #current_searchable_wdg = CheckboxWdg("is_searchable") #current_view_wdg.set_checked() #custom_table.add_cell("Searchable? ") #td = custom_table.add_cell(current_searchable_wdg) custom_table.close_tbody() return top_wdg
def run(my): import time time.sleep(3) print "Starting Scheduler ...." # NOTE: not sure why we have to do a batch here from pyasm.security import Batch Batch(login_code="admin") timed_triggers = [] from pyasm.biz import Project search = Search("sthpw/project") projects = search.get_sobjects() # get the all of the timed triggers #search = Search("sthpw/timed_trigger") #search.add_filter("type", "timed") for project in projects: project_code = project.get_code() try: search = Search("config/trigger?project=%s" % project_code) search.add_filter("event", "schedule") timed_trigger_sobjs = search.get_sobjects() except Exception, e: print "WARNING: ", e continue # example """ if project_code == 'broadcast2': tt = SearchType.create("config/trigger") tt.set_value("class_name", "tactic.command.PythonTrigger") # data = timed_trigges.get("data") tt.set_value("data", '''{ "type": "interval", "interval": 5, "delay": 5, "mode": "threaded", "script_path": "trigger/scheduled" } ''') timed_trigger_sobjs.append(tt) """ has_triggers = False for trigger_sobj in timed_trigger_sobjs: trigger_class = trigger_sobj.get_value("class_name") if not trigger_class and trigger_sobj.get_value("script_path"): trigger_class = 'tactic.command.PythonTrigger' data = trigger_sobj.get_json_value("data") data['project_code'] = trigger_sobj.get_project_code() try: timed_trigger = Common.create_from_class_path(trigger_class, [], data) timed_trigger.set_input(data) has_triggers = True except ImportError: raise Exception("WARNING: [%s] does not exist" % trigger_class) timed_triggers.append(timed_trigger) if has_triggers: print "Found [%s] scheduled triggers in project [%s]..." % (len(timed_triggers), project_code)
def get_display(my): is_admin_project = Project.get().is_admin() security = Environment.get_security() if is_admin_project and not security.check_access("builtin", "view_site_admin", "allow"): return Error403Wdg() # create the elements config = WidgetConfig.get(xml=my.config_xml, view="application") left_nav_handler = config.get_display_handler("left_nav") left_nav_options = config.get_display_options("left_nav") view_side_bar = None if left_nav_handler: left_nav_wdg = Common.create_from_class_path(left_nav_handler, [], left_nav_options) # caching side_bar_cache = my.get_side_bar_cache(left_nav_wdg) else: view_side_bar = False # create the main table core_table = Table() core_table.add_tbody() core_table.set_style("border: 0px; border-collapse: collapse; width: 100%;") # add a spacer row #spacer_tr = core_table.add_row() #spacer_tr.add_style("width: 100%") #td = core_table.add_cell() #td.set_style("min-height: 1px; height: 1px;") #core_table.add_cell() #core_table.add_cell() # determine if the side bar is visible if view_side_bar == None: view_side_bar = security.check_access("builtin", "view_side_bar", "allow", default='allow') # add the main cells tr, td = core_table.add_row_cell() td.add_style("padding: 0px") td.add_style("margin: 0px") # add the main resizable table from tactic.ui.container import ResizableTableWdg main_table = ResizableTableWdg() main_table.set_keep_table_size() main_table.add_style("width: 100%") td.add(main_table) left_nav_td = main_table.add_cell() if view_side_bar: left_nav_td.add_class("spt_panel") left_nav_td.add_style("padding: 0px") main_body_td = main_table.add_cell(resize=False) main_body_td.add_style("padding: 10px") main_body_td.set_style( "width: 100%; vertical-align: top; text-align: center; padding-top: 3px" ) if view_side_bar: left_nav_td.set_style( "vertical-align: top" ) # create the left navigation panel left_nav_div = DivWdg() left_nav_td.add(left_nav_div) left_nav_div.set_id("side_bar" ) # add the detail to the panel left_nav_div.add_attr("spt_class_name", left_nav_handler) for name, value in left_nav_options.items(): left_nav_div.add_attr("spt_%s" % name, value) left_nav_div.add_style("max_width: 185px") left_nav_div.add_style("width: 185px") left_nav_div.add_style("text-align: right") left_nav_div.add_style("vertical-align: top") left_nav_div.add_style("overflow: hidden") left_nav_div.add_class("spt_resizable") side_bar_inner = DivWdg() left_nav_div.add(side_bar_inner) #side_bar_inner.add_style("padding-left: 1px") side_bar_inner.add_style("width: 100%") # add side bar to nav side_bar_inner.add(side_bar_cache) left_nav_div.add_style("border-style: solid") left_nav_div.add_style("border-width: 0px 1px 0px 0px") #left_nav_div.add_color("border-color", "border") left_nav_div.add_color("border-color", "border", -10) web = WebContainer.get_web() browser = web.get_browser() if browser in ['Qt','Webkit']: min_width = "1px" else: min_width = "0px" left_nav_div.add_behavior( { 'type': 'listen', 'event_name': 'side_bar|hide_now', 'min_width': min_width, 'cbjs_action': ''' var size = bvr.src_el.getSize(); bvr.src_el.setAttribute("spt_size", size.x); bvr.src_el.setStyle("width", bvr.min_width); ''' } ) left_nav_div.add_behavior( { 'type': 'listen', 'event_name': 'side_bar|hide', 'min_width': min_width, 'cbjs_action': ''' var size = bvr.src_el.getSize(); bvr.src_el.setAttribute("spt_size", size.x); new Fx.Tween(bvr.src_el, {duration:'short'}).start('width', bvr.min_width); ''' } ) left_nav_div.add_behavior( { 'type': 'listen', 'event_name': 'side_bar|show', 'min_width': min_width, 'cbjs_action': ''' var width = bvr.src_el.getAttribute("spt_size"); if (!width) { width = 185; } if (parseInt(width) < 5) { width = 185; } //bvr.src_el.setStyle("width", width + "px"); new Fx.Tween(bvr.src_el, {duration:'short'}).start('width', bvr.min_width, width+"px"); ''' } ) left_nav_div.add_behavior( { 'type': 'listen', 'event_name': 'side_bar|toggle', 'cbjs_action': ''' var size = bvr.src_el.getSize(); if (size.x < 5) { spt.named_events.fire_event("side_bar|show", {} ); } else { spt.named_events.fire_event("side_bar|hide", {} ); } ''' } ) # create the main body panel palette = WebContainer.get_palette() color = palette.color("background2") main_body_rounded = DivWdg() main_body_inner = main_body_rounded main_body_inner.add_style("min-height: 500px") # DEBREACATED """ # add a breadcrumb breadcrumb_wdg = DivWdg() # hide the breadcrumb breadcrumb_wdg.add_style("display", "none") Container.put("breadcrumb", breadcrumb_wdg) breadcrumb_wdg.set_id("breadcrumb") breadcrumb_wdg.add_style("text-align: left") breadcrumb_wdg.add_looks( "fnt_title_3" ) main_body_inner.add(breadcrumb_wdg) """ main_body_panel = DivWdg() main_body_panel.set_id("main_body") main_body_panel.add_class("spt_main_panel") main_body_inner.add(main_body_panel) tab = MainBodyTabWdg() main_body_panel.add(tab) # TEST: NEW LAYOUT if Config.get_value("install", "layout") == "fixed": main_body_panel.add_style("margin-top: 31px") main_body_rounded.add_color("background", "background") main_body_rounded.add_style("padding: 3px 0px 0px 0px") # add the content to the main body panel try: if my.widget: tab.add(my.widget) element_name = my.widget.get_name() else: main_body_handler = config.get_display_handler("main_body") main_body_options = config.get_display_options("main_body") element_name = main_body_options.get("element_name") title = main_body_options.get("title") main_body_content = Common.create_from_class_path(main_body_handler, [], main_body_options) # get the web values from top_layout main_body_values = config.get_web_options("main_body") web = WebContainer.get_web() if isinstance(main_body_values, dict): for name, value in main_body_values.items(): web.set_form_value(name, value) main_body_content.set_name(element_name) tab.add(main_body_content, element_name, title) my.set_as_panel(main_body_panel, class_name=main_body_handler, kwargs=main_body_options) main_body_panel.add_behavior( { 'type': 'load', 'element_name': element_name, 'cbjs_action': ''' if (spt.help) spt.help.set_view(bvr.element_name); ''' } ) except Exception, e: # handle an error in the drawing buffer = my.get_buffer_on_exception() error_wdg = my.handle_exception(e) main_body_content = DivWdg() main_body_content.add(error_wdg) main_body_content = main_body_content.get_buffer_display() tab.add(main_body_content, element_name, title)
def check_new_job(my): num_jobs = len(my.jobs) if num_jobs >= my.max_jobs: print "Already at max jobs [%s]" % my.max_jobs return my.job = my.get_next_job() if not my.job: return # set the process key process_key = my.get_process_key() my.job.set_value("host", process_key) my.job.commit() my.jobs.append(my.job) # get some info from the job command = my.job.get_value("command") job_code = my.job.get_value("code") try: kwargs = my.job.get_json_value("data") except: try: # DEPRECATED kwargs = my.job.get_json_value("serialized") except: kwargs = {} if not kwargs: kwargs = {} login = my.job.get_value("login") script_path = my.job.get_value("script_path", no_exception=True) project_code = my.job.get_value("project_code") if script_path: command = 'tactic.command.PythonCmd' folder = os.path.dirname(script_path) title = os.path.basename(script_path) search = Search("config/custom_script") search.add_filter("folder", folder) search.add_filter("title", title) custom_script = search.get_sobject() script_code = custom_script.get_value("script") kwargs['code'] = script_code # add the job to the kwargs kwargs['job'] = my.job #print "command: ", command #print "kwargs: ", kwargs # Because we started a new thread, the environment may not # yet be initialized try: from pyasm.common import Environment Environment.get_env_object() except: Batch() Project.set_project(project_code) queue = my.job.get_value("queue", no_exception=True) queue_type = 'repeat' stop_on_error = False print "Running job: ", my.job.get_value("code") if queue_type == 'inline': cmd = Common.create_from_class_path(command, kwargs=kwargs) try: Command.execute_cmd(cmd) # set job to complete my.job.set_value("state", "complete") except Exception, e: my.job.set_value("state", "error") my.job.commit() my.jobs.remove(my.job) my.job = None my.jobs_completed += 1
def run(self): import time time.sleep(6) #print("Starting Timed Trigger") # checks are done every 60 seconds chunk = 60 # FIXME: not sure why we have to do a batch here from pyasm.security import Batch Batch(login_code="admin") # get the all of the timed triggers #search = Search("sthpw/timed_trigger") #search.add_filter("type", "timed") search = Search("sthpw/trigger") search.add_filter("event", "timed") timed_trigger_sobjs = search.get_sobjects() timed_triggers = [] for trigger_sobj in timed_trigger_sobjs: trigger_class = trigger_sobj.get_value("class_name") try: timed_trigger = Common.create_from_class_path(trigger_class) except ImportError: raise Exception("WARNING: [%s] does not exist" % trigger_class) timed_triggers.append(timed_trigger) while 1: time.sleep(chunk) #print("Running timer") date = Date() #print("utc: ", date.get_display_time()) # go through each trigger for timed_trigger in timed_triggers: if not timed_trigger.is_ready(): continue if timed_trigger.is_in_separate_thread(): class xxx(threading.Thread): def run(self): try: Batch() timed_trigger._do_execute() finally: DbContainer.close_thread_sql() xxx().start() else: timed_trigger._do_execute() DbContainer.close_thread_sql() if self.end: #print("Stopping timed thread") break
def execute(my): start = time.time() from pyasm.common import SPTDate timestamp = SPTDate.now() timestamp = SPTDate.add_gmt_timezone(timestamp) timestamp = SPTDate.convert_to_local(timestamp) format = '%Y-%m-%d %H:%M:%S' timestamp = timestamp.strftime(format) updates = my.kwargs.get("updates") if isinstance(updates, basestring): updates = jsonloads(updates) last_timestamp = my.kwargs.get("last_timestamp") #assert last_timestamp if not last_timestamp: my.info = { "updates": {}, "timestamp": timestamp } return last_timestamp = parser.parse(last_timestamp) last_timestamp = SPTDate.add_gmt_timezone(last_timestamp) #last_timestamp = last_timestamp - timedelta(hours=24) #print "last: ", last_timestamp # get out all of the search_keys client_keys = set() for id, values_list in updates.items(): if isinstance(values_list, dict): values_list = [values_list] for values in values_list: handler = values.get("handler") if handler: handler = Common.create_from_class_path(handler) search_key = handler.get_search_key() else: search_key = values.get("search_key") if search_key: client_keys.add(search_key) # find all of the search that have changed changed_keys = set() for check_type in ['sthpw/change_timestamp', 'sthpw/sobject_log']: search = Search(check_type) search.add_filter("timestamp", last_timestamp, op=">") search.add_filters("search_type", ["sthpw/sobject_log", "sthpw/status_log"], op="not in") #print search.get_statement() changed_sobjects = search.get_sobjects() for sobject in changed_sobjects: search_type = sobject.get_value("search_type") search_code = sobject.get_value("search_code") if search_type.startswith("sthpw/"): search_key = "%s?code=%s" % (search_type, search_code) else: search_key = "%s&code=%s" % (search_type, search_code) changed_keys.add(u'%s'%search_key) intersect_keys = client_keys.intersection(changed_keys) #for x in client_keys: # print x #print "---" #print "changed_keys: ", changed_keys #print "---" #print "intersect_keys: ", intersect_keys from pyasm.web import HtmlElement results = {} for id, values_list in updates.items(): if isinstance(values_list, dict): values_list = [values_list] for values in values_list: handler = values.get("handler") if handler: handler = Common.create_from_class_path(handler) search_key = handler.get_search_key() else: search_key = values.get("search_key") if search_key and search_key not in intersect_keys: continue # evaluate any compare expressions compare = values.get("compare") if compare: search_key = values.get("search_key") if search_key: sobject = Search.get_by_search_key(search_key) else: sobject = None cmp_result = Search.eval(compare, sobject, single=True) if cmp_result == True: continue # some randome value value = "Loading ..." else: value = HtmlElement.eval_update(values) if value == None: continue results[id] = value my.info = { "updates": results, "timestamp": timestamp } #print "time: ", time.time() - start #print results return results
def run(self): import time time.sleep(3) #print("Starting Scheduler ....") # NOTE: not sure why we have to do a batch here from pyasm.security import Batch Batch(login_code="admin") timed_triggers = [] from pyasm.biz import Project search = Search("sthpw/project") # only requires the admin project search.add_filter('code', 'sthpw', op='!=') projects = search.get_sobjects() # get the all of the timed triggers #search = Search("sthpw/timed_trigger") #search.add_filter("type", "timed") timed_trigger_sobjs = [] for project in projects: project_code = project.get_code() try: search = Search("config/trigger?project=%s" % project_code) search.add_filter("event", "schedule") items = search.get_sobjects() if items: timed_trigger_sobjs.extend(items) except Exception as e: #print("WARNING: ", e) continue # example """ if project_code == 'broadcast2': tt = SearchType.create("config/trigger") tt.set_value("class_name", "tactic.command.PythonTrigger") # data = timed_trigges.get("data") tt.set_value("data", '''{ "type": "interval", "interval": 5, "delay": 5, "mode": "threaded", "script_path": "trigger/scheduled" } ''') timed_trigger_sobjs.append(tt) """ has_triggers = False for trigger_sobj in timed_trigger_sobjs: trigger_class = trigger_sobj.get_value("class_name") if not trigger_class and trigger_sobj.get_value("script_path"): trigger_class = 'tactic.command.PythonTrigger' data = trigger_sobj.get_json_value("data") data['project_code'] = trigger_sobj.get_project_code() try: timed_trigger = Common.create_from_class_path(trigger_class, [], data) timed_trigger.set_input(data) has_triggers = True except ImportError: raise Exception("WARNING: [%s] does not exist" % trigger_class) timed_triggers.append(timed_trigger) if has_triggers and self.dev_mode: print("Found [%s] scheduled triggers in project [%s]..." % (len(timed_triggers), project_code)) from tactic.command import Scheduler, SchedulerTask scheduler = Scheduler.get() scheduler.start_thread() class TimedTask(SchedulerTask): def __init__(self, **kwargs): super(TimedTask, self).__init__(**kwargs) self.index = kwargs.get("index") self.project_code = kwargs.get("project_code") def execute(self): try: #Batch() #Command.execute_cmd(timed_trigger) Project.set_project(self.project_code) timed_triggers[self.index].execute() except Exception as e: raise finally: DbContainer.close_thread_sql() DbContainer.commit_thread_sql() DbContainer.close_all() for idx, timed_trigger in enumerate(timed_triggers): data = timed_trigger.get_input() if not data: continue """ data = { 'type': 'interval', 'interval': 10, 'delay': 0, 'mode': 'threaded' } """ project_code = data.get("project_code") task = TimedTask(index=idx, project_code=project_code) args = {} if data.get("mode"): args['mode'] = data.get("mode") trigger_type = data.get("type") if trigger_type == 'interval': interval = data.get("interval") delay = data.get("delay") if not interval: continue if not delay: delay = 3 args = { 'interval': interval, 'delay': delay, } scheduler.add_interval_task(task, **args) elif trigger_type == "daily": from dateutil import parser args['time'] = parser.parse( data.get("time") ) if data.get("weekdays"): args['weekdays'] = eval( data.get("weekdays") ) scheduler.add_daily_task(task, **args) #scheduler.add_daily_task(task, time, mode="threaded", weekdays=range(1,7)) elif trigger_type == "weekly": #scheduler.add_weekly_task(task, weekday, time, mode='threaded'): args['time'] = parser.parse( data.get("time") ) if data.get("weekday"): args['weekday'] = eval( data.get("weekday") ) scheduler.add_weekly_task(task, **args)
def get_default_wdg(self): top_class_name = WebEnvironment.get_top_class_name() kwargs = {} widget = Common.create_from_class_path(top_class_name, [], kwargs) return widget
def execute(self): #protocol = 'xmlrpc' protocol = 'local' if protocol == 'local': server = TacticServerStub.get() else: server = TacticServerStub(protocol=protocol, setup=False) TacticServerStub.set(server) project = self.data.get("project") ticket = self.data.get("ticket") assert project assert ticket server.set_server("localhost") server.set_project(project) server.set_ticket(ticket) self.class_name = self.data.get('class_name') assert self.class_name self.kwargs = self.data.get('kwargs') if not self.kwargs: self.kwags = {} #trigger = eval("%s(**self.kwargs)" % self.class_name) trigger = Common.create_from_class_path(self.class_name, kwargs=self.kwargs) input_data = self.get_input_data() trigger.set_input(input_data) try: trigger.execute() info = trigger.get_info() result = info.get("result") if result is not None: # map booleans to a message if result in ['true', True]: result = 'complete' elif result in ['false', False]: result = 'revise' self.set_pipeline_status(result) self.info['result'] = result else: self.set_pipeline_status("complete") self.info['result'] = "complete" except Exception as e: #self.set_pipeline_status("error", {"error": str(e)}) self.set_pipeline_status("revise", {"error": str(e)}) import sys, traceback print("Error: ", e) # print the stacktrace tb = sys.exc_info()[2] stacktrace = traceback.format_tb(tb) stacktrace_str = "".join(stacktrace) print("-" * 50) print(stacktrace_str) print(str(e)) print("-" * 50) self.info['result'] = "error" self.info['message'] = str(e)
def get_repo(my): repo_handler = my.get_repo_class() repo = Common.create_from_class_path(repo_handler) return repo
def _run(self): task = self.kwargs.get("task") paths = task.get_paths() count = 0 restart = False while True: if not paths: time.sleep(1) continue path = paths.pop(0) checkin_path = "%s.checkin" % path lock_path = "%s.lock" % path error_path = "%s.error" % path if not os.path.exists(path): continue if not os.path.exists(checkin_path): #print "Action Thread SKIP: no checkin path [%s]" % checkin_path continue else: # Exit if another process is also checking this file in. f = open(checkin_path, "r") pid = f.readline() f.close() if pid != str(os.getpid()): continue try: kwargs = { "project_code": task.project_code, "search_type": task.search_type, "base_dir": task.base_dir, "process": task.process, "script_path": task.script_path, "path": path } handler = task.get("handler") if handler: cmd = Common.create_from_class_path(handler, [], kwargs) else: # create a "custom" command that will act on the file cmd = CheckinCmd(**kwargs) #print "Process [%s] checking in [%s]" % (os.getpid(), path) cmd.execute() # TEST #time.sleep(1) #if os.path.exists(path): # os.unlink(path) count += 1 if count == 20: restart = True task.set_clean(True) break except Exception as e: print "Error: ", e f = open(error_path, "w") f.write(str(e)) f.close() #raise finally: task.set_clean(True) if os.path.exists(checkin_path): os.unlink(checkin_path) if os.path.exists(lock_path): os.unlink(lock_path) task.set_clean(False) if restart: task.set_clean(True) # restart every 20 check-ins if restart: for path in paths: checkin_path = "%s.checkin" % path lock_path = "%s.lock" % path if os.path.exists(checkin_path): os.unlink(checkin_path) if os.path.exists(lock_path): os.unlink(lock_path) # this exaggerates the effect of not pausing check thread for cleaning #time.sleep(10) Common.kill()
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_default_wdg(my): top_class_name = WebEnvironment.get_top_class_name() kwargs = {} widget = Common.create_from_class_path(top_class_name, [], kwargs) return widget
def get_handler(my): handler_class = my.get_value("handler") repo_handler = Common.create_from_class_path(handler_class) return handler
def get_from_db_naming(my, protocol): project_code = Project.get_project_code() if project_code in ["admin", "sthpw"]: return None # get the naming object naming = Naming.get(my.sobject, my.snapshot) if not naming: return None if protocol == 'sandbox': mode = 'sandbox_dir' else: mode = 'dir' # Provide a mechanism for a custom class naming_class = naming.get_value("class_name", no_exception=True) #naming_class = "pyasm.biz.TestFileNaming" if naming_class: kwargs = { 'sobject': my.sobject, 'snapshot': my.snapshot, 'file_object': my._file_object, #'ext': my.get_ext(), 'file_type': my.file_type, 'mode': mode } naming = Common.create_from_class_path(naming_class, [], kwargs) dirname = naming.get_dir() if dirname: return dirname # provide a mechanism for a custom client side script script_path = naming.get_value("script_path", no_exception=True) if script_path: project_code = my.sobject.get_project_code() input = { 'sobject': my.sobject, 'snapshot': my.snapshot, 'file_object': my._file_object, #'ext': my.get_ext(), 'file_type': my.file_type, 'mode': mode, 'project': project_code } from tactic.command import PythonCmd cmd = PythonCmd(script_path=script_path, input=input) results = cmd.execute() if results: return results naming_util = NamingUtil() naming_expr = '' if protocol == 'sandbox': naming_expr = naming.get_value("sandbox_dir_naming") if not naming_expr: naming_expr = naming.get_value("dir_naming") # so it can take the default if not naming_expr: return None file_type = my.get_file_type() # build the dir name dir_name = naming_util.naming_to_dir(naming_expr, my.sobject, my.snapshot, file=my._file_object, file_type=file_type) return dir_name
def get_from_db_naming(my, search_type): project_code = Project.get_project_code() if project_code in ["admin", "sthpw"]: return "" file_type = my.get_file_type() filename = my.file_object.get_full_file_name() naming = Naming.get(my.sobject, my.snapshot, file_path=filename) if not naming: return None if naming and my.checkin_type: checkin_type = naming.get_value('checkin_type') if checkin_type and my.checkin_type != checkin_type: print "mismatched checkin_type!" naming = None return None naming_util = NamingUtil() # Provide a mechanism for a custom class naming_class = naming.get_value("class_name", no_exception=True) if naming_class: kwargs = { 'sobject': my.sobject, 'snapshot': my.snapshot, 'file_object': my.file_object, 'ext': my.get_ext(), 'mode': 'file' } naming = Common.create_from_class_path(naming_class, kwargs) filename = naming.get_file() if filename: return filename # provide a mechanism for a custom client side script script_path = naming.get_value("script_path", no_exception=True) if script_path: project_code = my.sobject.get_project_code() input = { 'sobject': my.sobject, 'snapshot': my.snapshot, 'file_object': my.file_object, 'ext': my.get_ext(), 'mode': 'file', 'project': project_code } from tactic.command import PythonCmd cmd = PythonCmd(script_path=script_path, input=input) results = cmd.execute() if results: return results naming_value = naming.get_value("file_naming") if not naming_value: is_versionless = naming.get_value( "latest_versionless") or naming.get_value( "current_versionless") if not is_versionless: return "" # FIXME: # if this is a versionless naming, then empty uses a default # This is put here because the check-in type is determined by the # naming here. Normally, this is passed through with "naming_expr" # but in snapshot.py, it is not yet known that this is an "auto" # checkin_type because it is defined in the naming and not the # process server = Config.get_value("install", "server") if server: naming_value = "{basefile}_{snapshot.process}_%s.{ext}" % server else: naming_value = "{basefile}_{snapshot.process}.{ext}" # check for manual_version manual_version = naming.get_value('manual_version') if manual_version == True: # if the file version is not the same as the snapshot version # then check to see if the snapshot already exists filename = my.file_object.get_full_file_name() version = my.get_version_from_file_name(filename) context = my.snapshot.get_context() if version > 0 and version != my.snapshot.get_value("version"): existing_snap = Snapshot.get_snapshot(\ my.snapshot.get_value("search_type"),\ my.snapshot.get_value("search_id"), context=context, \ version=version, show_retired=True) if existing_snap: raise TacticException( 'You have chosen manual version in Naming for this SObject. A snapshot with context "%s" and version "%s" already exists.' % (context, version)) my.snapshot.set_value("version", version) my.snapshot.commit() file_type = my.get_file_type() return naming_util.naming_to_file(naming_value, my.sobject, my.snapshot, my.file_object, ext=my.get_ext(), file_type=file_type)
def execute(my): start = time.time() from pyasm.common import SPTDate timestamp = SPTDate.now() timestamp = SPTDate.add_gmt_timezone(timestamp) timestamp = SPTDate.convert_to_local(timestamp) format = '%Y-%m-%d %H:%M:%S' timestamp = timestamp.strftime(format) updates = my.kwargs.get("updates") if isinstance(updates, basestring): updates = jsonloads(updates) last_timestamp = my.kwargs.get("last_timestamp") #assert last_timestamp if not last_timestamp: my.info = {"updates": {}, "timestamp": timestamp} return last_timestamp = parser.parse(last_timestamp) last_timestamp = SPTDate.add_gmt_timezone(last_timestamp) #last_timestamp = last_timestamp - timedelta(hours=24) #print "last: ", last_timestamp # get out all of the search_keys client_keys = set() for id, values_list in updates.items(): if isinstance(values_list, dict): values_list = [values_list] for values in values_list: handler = values.get("handler") if handler: handler = Common.create_from_class_path(handler) search_key = handler.get_search_key() else: search_key = values.get("search_key") if search_key: client_keys.add(search_key) # find all of the search that have changed changed_keys = set() for check_type in ['sthpw/change_timestamp', 'sthpw/sobject_log']: search = Search(check_type) search.add_filter("timestamp", last_timestamp, op=">") search.add_filters("search_type", ["sthpw/sobject_log", "sthpw/status_log"], op="not in") #print search.get_statement() changed_sobjects = search.get_sobjects() for sobject in changed_sobjects: search_type = sobject.get_value("search_type") search_code = sobject.get_value("search_code") if search_type.startswith("sthpw/"): search_key = "%s?code=%s" % (search_type, search_code) else: search_key = "%s&code=%s" % (search_type, search_code) changed_keys.add(u'%s' % search_key) intersect_keys = client_keys.intersection(changed_keys) #for x in client_keys: # print x #print "---" #print "changed_keys: ", changed_keys #print "---" #print "intersect_keys: ", intersect_keys from pyasm.web import HtmlElement results = {} for id, values_list in updates.items(): if isinstance(values_list, dict): values_list = [values_list] for values in values_list: handler = values.get("handler") if handler: handler = Common.create_from_class_path(handler) search_key = handler.get_search_key() else: search_key = values.get("search_key") if search_key and search_key not in intersect_keys: continue # evaluate any compare expressions compare = values.get("compare") if compare: search_key = values.get("search_key") if search_key: sobject = Search.get_by_search_key(search_key) else: sobject = None cmp_result = Search.eval(compare, sobject, single=True) if cmp_result == True: continue # some value to display value = "Loading ..." else: value = HtmlElement.eval_update(values) if value == None: continue results[id] = value my.info = {"updates": results, "timestamp": timestamp} #print "time: ", time.time() - start #print results return results