def _check(self): # This will kill the TACTIC process # This is very harsh and should be used sparingly if at all use_restart = Config.get_value("services", "use_periodic_restart") if use_restart in [True, 'true']: if self.num_checks and self.num_checks % self.kill_interval == 0: # read pid file log_dir = "%s/log" % Environment.get_tmp_dir() file = open("%s/pid.%s" % (log_dir,self.port), "r") pid = file.read() file.close() Common.kill(pid) #self.run() self.num_checks += 1 return self.num_checks += 1 start = time.clock() try: response = self.check() except IOError, e: pid = self._get_pid() if pid: Common.kill(pid)
def final_kill(self): '''Kill the startup, startup_queue, watch_folder processes. This is used primarily in Windows Service. Linux service should have actively killed the processes already''' log_dir = "%s/log" % Environment.get_tmp_dir() files = os.listdir(log_dir) ports = [] watch_folders = [] queues = [] for filename in files: base, ext = os.path.splitext(filename) if base == 'pid': ports.append(ext[1:]) elif base == 'watch_folder': watch_folders.append(ext[1:]) elif base == 'startup_queue': queues.append(ext[1:]) for port in ports: try: file_name = "%s/pid.%s" % (log_dir,port) file = open(file_name, "r") pid = file.readline().strip() file.close() Common.kill(pid) except IOError, e: continue
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 execute(my): import atexit import time atexit.register( my.cleanup ) while 1: my.check_existing_jobs() my.check_new_job() time.sleep(my.check_interval) #DbContainer.close_thread_sql() if my.max_jobs_completed != -1 and my.jobs_completed > my.max_jobs_completed: Common.restart()
def get_display(my): sobject = my.get_current_sobject() mode = my.get_option("mode") if not mode: mode = "sandbox" widget = Widget() sobject_dir = "" sobject_lib_dir = "" # find the path to open explorer if sobject.is_insert(): button = IconWdg("No Path Found", IconWdg.CROSS, long=False) else: try: if mode == "sandbox": sobject_dir = my.get_base_dir(sobject) elif mode in ["client_repo", "repository"]: sobject_dir = my.get_client_repo_dir(sobject) sobject_lib_dir = my.get_lib_dir(sobject) sobject_dir = sobject_dir.strip() sobject_dir = Common.process_unicode_string(sobject_dir) except TacticException, e: print "WARNING: ", str(e) button = IconWdg("No Path Found", IconWdg.CROSS, long=False) else:
def execute(my): import cherrypy print print "Stopping TACTIC ..." print print " ... stopping Schduler" scheduler = Scheduler.get() scheduler.stop() print " ... stopping Cherrypy" cherrypy.engine.stop() cherrypy.engine.exit() print " ... closing DB connections" DbContainer.close_all_global_connections() print " ... kill current process" Common.kill() print "Done."
def get_example_chooser_content(self): choice_list_div = DivWdg() choice_list_div.set_id("UiExampleChoiceList") choice_list_div.add_styles( "background: #202020; color: #999999; border: 1px solid black; " \ "border-top: 0px;" ) example_wdg_classes = self._get_example_widget_classes() choice_list_div.add( "<br/>" ) for ex_wdg_class in example_wdg_classes: ex_wdg = ex_wdg_class() ex_title = ex_wdg.get_example_title() ex_desc = ex_wdg.get_example_description() ex_class_path = Common.get_full_class_name( ex_wdg ) ex_div = DivWdg() ex_div.add_styles( "color: #999999; padding: 8px; padding-left: 20px; cursor: pointer;" ) ex_div.add_class("SPT_DTS") ex_div.add_behavior( {'type': 'click_up', 'cbjs_action': 'spt.ui_play.show_example("%s");' % ex_class_path } ) ex_div.add( ex_title ) choice_list_div.add( ex_div ) choice_list_div.add( "<br/>" ) return choice_list_div
def color(my, category, modifier=0, default=None): if not category: category = 'background' # make default adjustments if category.startswith("#"): color = category category = "color" else: color = my.colors.get(category) if not color: color = my.colors.get(default) if not color: color = category if category == 'background2' and not color: category = 'background' modifier += 10 color = my.colors.get(category) if category == 'color2' and not color: category = 'color' modifier += 10 color = my.colors.get(category) return Common.modify_color(color, modifier)
def get_process_select_data(search_type, extra_process=[], project_code='', is_filter=False, is_group_restricted=False, sobject=None ): '''get a tuple of data used for the SelectWdg''' context_dict = Pipeline.get_process_name_dict(search_type, project_code, is_group_restricted, sobject=sobject) labels = [] values = [] keys = context_dict.keys() keys.sort() process_values = Common.sort_dict(context_dict) for idx, value in enumerate(process_values): key = keys[idx] labels.append('<< %s >>' %key) if is_filter: # add all the process names in this pipeline into the value values.append(','.join(value)) else: values.append('') # extra process may not be needed if extra_process: value.extend(extra_process) if len(context_dict) > 1 and idx < len(context_dict)-1 : value.append('') values.extend(value) labels.extend(value) return labels, values
def get_related_wdg(my, aliases): div = DivWdg() div.add("<b>Related links</b>:  ") div.add_style("margin-top: 5px") div.add_style("margin-bottom: 5px") div.add_style("margin-left: 10px") titles = [Common.get_display_title(x.replace("-"," ")) for x in aliases] for alias, title in zip(aliases, titles): link_div = SpanWdg() div.add(link_div) link_div.add_color("background", "background") link_div.add(title) link_div.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' spt.help.set_top(); spt.help.load_alias("%s"); ''' % alias } ) link_div.add_class("spt_link") link_div.add_class("hand") return div
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_section_wdg(my, view, editable=True, default=False): title = "" if editable: edit_mode = "edit" else: edit_mode = "read" kwargs = { "title": title, "config_search_type": my.search_type, "view": view, "width": "300", "mode": edit_mode, "default": str(default), } if view in ["definition", "custom_definition"]: kwargs["recurse"] = "false" from view_section_wdg import ViewSectionWdg section_wdg = ViewSectionWdg(**kwargs) class_path = Common.get_full_class_name(section_wdg) section_div = DivWdg(css="spt_panel") section_div.add_style("display: block") section_div.set_attr("spt_class_name", class_path) for name, value in kwargs.items(): if name == "config": continue section_div.set_attr("spt_%s" % name, value) section_div.add(section_wdg) return section_div
def filter_line_handler(my, path, line): '''NOT used now''' return line # this is only called if the project code is different from the # template code file_name = os.path.basename(path) if file_name in ['sthpw_project.spt']: # change codes to project code if line.startswith('''insert.set_value('code','''): line = '''insert.set_value('code', """%s""")\n''' % my.project_code elif line.startswith('''insert.set_value('title','''): title = Common.get_display_title(my.project_code) line = '''insert.set_value('title', """%s""")\n''' % title elif line.startswith('''insert.set_value('is_template','''): if my.is_template: line = '''insert.set_value('is_template', """true""")\n''' else: line = '''insert.set_value('is_template', """false""")\n''' elif file_name in ['sthpw_schema.spt']: if line.startswith('''insert.set_value('code','''): line = '''insert.set_value('code', """%s""")\n''' % my.project_code elif file_name in ['sthpw_pipeline.spt']: if line.startswith('''insert.set_value('project_code','''): line = '''insert.set_value('project_code', """%s""")\n''' % my.project_code return line
def _process_pdf(my, file_name): base, ext = os.path.splitext(file_name) # naming convetion should take care of inserting a suffix like icon, web # but these paths need a unique name icon_file_name = base + "_icon.png" tmp_icon_path = "%s/%s" % (my.tmp_dir, icon_file_name) thumb_web_size = my.get_web_file_size() web_file_name = base + "_web.png" tmp_web_path = "%s/%s" % (my.tmp_dir, web_file_name) if sys.platform == 'darwin': return else: if not Common.which(convert_exe): return try: my.file_path = my.file_path.encode('utf-8') import shlex, subprocess subprocess.call([convert_exe, '-geometry','80','-raise','2x2','%s[0]'%my.file_path,\ "%s"%tmp_icon_path]) subprocess.call([convert_exe, '-geometry','%sx%s'%(thumb_web_size[0], \ thumb_web_size[1]),'-raise','2x2','%s[0]' %my.file_path, "%s"%tmp_web_path]) except Exception, e: print "Error extracting from pdf [%s]" % e return
def run_method(my, name, method): try: #upgrade = eval( '%s()' %my.__class__.__name__) upgrade = BaseUpgrade() except NameError: print "Failed to import upgrade script for %s" %my.__class__.__name__ return # substitute the function of 'execute' method with the # upgrade script Common.add_func_to_class(method, upgrade, upgrade.__class__, 'execute') upgrade.set_project(my.project_code) upgrade.set_upgrade_method(name) upgrade.set_quiet(my.quiet) upgrade.set_confirmed(my.is_confirmed) Command.execute_cmd(upgrade, call_trigger=False)
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 get_checkin(my): '''the button which initiates the checkin''' # create the button with the javascript function widget = Widget() #button = TextBtnWdg(label=my.PUBLISH_BUTTON, size='large', width='100', side_padding='20', vert_offset='-5') #button.get_top_el().add_class('smaller') button = ActionButtonWdg(title=my.PUBLISH_BUTTON, tip='Publish the selected assets') button.add_style('margin-bottom: 10px') #button.add_color("background", "background") hidden = HiddenWdg(my.PUBLISH_BUTTON, '') button.add( hidden ) ''' status_sel = SelectWdg('checkin_status', label='Status: ') status_sel.set_option('setting', 'checkin_status') status_sel.set_persist_on_submit() status_sel.add_empty_option('-- Checkin Status --') widget.add(status_sel) ''' widget.add(button) # custom defined server_cbk = "pyasm.prod.web.AssetCheckinCbk" #TODO: make other Publish Buttons call their own handle_input function exec( Common.get_import_from_class_path(server_cbk) ) exec( "%s.handle_input(button, my.search_type, my.texture_search_type)" % server_cbk) return widget
def get_data(my, sobject): values = [] labels = [] if not my.config: return values, labels for element in my.elements: options = my.config.get_display_options(element) attrs = my.config.get_element_attributes(element) label = attrs.get('title') if not label: label = Common.get_display_title(element) labels.append(label) expression = options.get("expression") if not expression: value = 0 else: value = Search.eval(expression, sobject, single=True) values.append(value) return values, labels
def set_as_panel(my, widget): widget.add_class("spt_panel") widget.add_attr("spt_class_name", Common.get_full_class_name(my) ) for name, value in my.kwargs.items(): widget.add_attr("spt_%s" % name, value)
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 _process_video(my, file_name): ffmpeg = Common.which("ffmpeg") if not ffmpeg: return thumb_web_size = my.get_web_file_size() thumb_icon_size = (120, 100) exts = File.get_extensions(file_name) base, ext = os.path.splitext(file_name) icon_file_name = "%s_icon.png" % base web_file_name = "%s_web.jpg" % base tmp_icon_path = "%s/%s" % (my.tmp_dir, icon_file_name) tmp_web_path = "%s/%s" % (my.tmp_dir, web_file_name) #cmd = '''"%s" -i "%s" -r 1 -ss 00:00:01 -t 1 -s %sx%s -vframes 1 "%s"''' % (ffmpeg, my.file_path, thumb_web_size[0], thumb_web_size[1], tmp_web_path) #os.system(cmd) import subprocess try: subprocess.call([ffmpeg, '-i', my.file_path, "-y", "-ss", "00:00:01","-t","1",\ "-s","%sx%s"%(thumb_web_size[0], thumb_web_size[1]),"-vframes","1","-f","image2", tmp_web_path]) if os.path.exists(tmp_web_path): my.web_path = tmp_web_path else: my.web_path = None except Exception, e: Environment.add_warning("Could not process file", \ "%s - %s" % (my.file_path, e.__str__())) pass
def get_section_wdg(self, view, editable=True, default=False): title = "" target_id = "sobject_relation" if editable: edit_mode = 'edit' else: edit_mode = 'read' kwargs = { 'title': title, 'config_search_type': self.search_type, 'view': view, 'target_id': target_id, 'width': '300', 'prefix': 'manage_side_bar', 'mode': edit_mode, 'default': str(default) } if view in ["definition", "custom_definition"]: kwargs['recurse'] = "false" section_wdg = ViewSectionWdg(**kwargs) class_path = Common.get_full_class_name(section_wdg) section_div = DivWdg() section_div.add_style("display: block") section_div.set_attr('spt_class_name', class_path) for name, value in kwargs.items(): if name == "config": continue section_div.set_attr("spt_%s" % name, value) section_div.add(section_wdg) return section_div
def _test_symlink(my): if os.name == 'nt': return # create a new test.txt file file_path = "./symlink.txt" file = open(file_path, 'w') file.write("symlink test") file.close() checkin = FileCheckin(my.person, file_path, context="sym_test", checkin_type='auto') checkin.execute() snap = Snapshot.get_versionless(my.person.get_search_type(), my.person.get_id(), "sym_test", mode='latest', create=False) my.assertEquals(True, isinstance(snap, Snapshot)) if snap: lib_path =snap.get_lib_path_by_type('main') my.assertEquals(True, os.path.exists(lib_path)) rel_path = os.readlink(lib_path) lib_dir = os.path.dirname(lib_path) # this is essentially handle_link() in FileUndo class wd = os.getcwd() os.chdir(lib_dir) real_path = os.path.join(lib_dir, os.path.abspath(rel_path)) # lib_path points to real_path expected_rel_path = Common.relative_path(lib_path, real_path) my.assertEquals(True, os.path.exists(real_path)) my.assertEquals(expected_rel_path, rel_path) os.chdir(wd)
def add_publish_wdg(my, sobject, publish_msg): layer_name = sobject.get_value('name') shot_code = sobject.get_value('shot_code') fla_link, fla = my._get_file_info(my.get_template()) if fla_link == None: # put a failsafe template url = WebContainer.get_web().get_base_url() base = url.to_string() fla_link = "%s/context/template/flash-layer_default.fla" % base fla = "flash-layer_default.fla" button = IconButtonWdg("publish layer", IconWdg.PUBLISH) # set up event event_name = "%s_%s" %(sobject.get_search_key(), FlashActionWdg.PUBLISH_ACTION) #button.add_event_caller("onclick", event_name) event = WebContainer.get_event_container() function = '%s;document.form.submit();' \ %event.get_event_caller(event_name) # escape the single quotes for function button.add_event("onclick", "comment_bubble.show(event, '%s', '%s')" \ % (layer_name, Common.escape_quote(function))) event.add_listener(event_name, "pyflash.publish_layer('%s', '%s', '%s', '%s', '%s', '%s')" \ % (shot_code, layer_name, fla_link, fla, publish_msg.get_id(), my.PREFIX_MODE) ) span = SpanWdg(publish_msg) my.div.add(button) my.div.add(span)
def get_display(my): div = DivWdg() class_path = Common.get_full_class_name(my) from tactic.ui.panel import HashPanelWdg try: widget = HashPanelWdg.get_widget_from_hash("/index", return_none=True) div.add(widget) except: widget = None if not widget: class_path = class_path.replace("IndexWdg", "IndexWdg2") kwargs = {} div.add_behavior( { 'type': 'load', 'class_path': class_path, 'kwargs': kwargs, 'cbjs_action': ''' spt.dom.load_js(["popup.js"], function() { spt.panel.load(bvr.src_el, bvr.class_path, bvr.kwargs); }); ''' } ) return div
def get_display(self): from tactic.ui.panel import ViewPanelWdg, CustomLayoutWdg top = self.top detail_view = self.kwargs.get("detail_view") if detail_view: self.kwargs['view'] = detail_view layout = CustomLayoutWdg(**self.kwargs) else: top.add_style("margin: 20px") day = self.kwargs.get("day") title = self.kwargs.get("st_title") title = Common.pluralize(title) title_wdg = DivWdg() top.add(title_wdg) title_wdg.add("<div style='font-size: 25px'>%s for date: %s</div>" % (title, day)) title_wdg.add("List of %s on this day." % title) title_wdg.add("<hr/>") self.kwargs['show_shelf'] = False layout = ViewPanelWdg(**self.kwargs) top.add(layout) return top
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 copy_sobject(my, sobject, dst_search_type, context=None, checkin_mode='inplace'): new_sobject = SearchType.create(dst_search_type) search_type = SearchType.get(dst_search_type) columns = SearchType.get_columns(dst_search_type) data = sobject.get_data() for name, value in data.items(): if name in ['id','pipeline_code']: continue if name not in columns: continue if not value: continue if name == "code": value = Common.get_next_sobject_code(sobject, 'code') if not value: continue new_sobject.set_value(name, value) if SearchType.column_exists(dst_search_type, "project_code"): project_code = Project.get_project_code() new_sobject.set_value("project_code", project_code) new_sobject.commit() # get all of the current snapshots and file paths associated if not context: snapshots = Snapshot.get_all_current_by_sobject(sobject) else: snapshots = [Snapshot.get_current_by_sobject(sobject, context)] if not snapshots: return msgs = [] for snapshot in snapshots: #file_paths = snapshot.get_all_lib_paths() file_paths_dict = snapshot.get_all_paths_dict() file_types = file_paths_dict.keys() if not file_types: continue # make sure the paths match the file_types file_paths = [file_paths_dict.get(x)[0] for x in file_types] mode = checkin_mode # checkin the files (inplace) try: context = snapshot.get_value('context') checkin = FileCheckin(new_sobject, context=context, file_paths=file_paths, file_types=file_types, mode=mode) checkin.execute() #print "done: ", context, new_sobject.get_related_sobjects("sthpw/snapshot") except CheckinException, e: msgs.append('Post-process Check-in Error for %s: %s ' %(context, e.__str__()))
def get_color(my): color = Xml.get_attribute( my.node, "color" ) from pyasm.web import Palette theme = Palette.get().get_theme() if theme == 'dark': color = Common.modify_color(color, -50) return color
def _process_video(my, file_name): ffmpeg = Common.which("ffmpeg") if not ffmpeg: return thumb_web_size = my.get_web_file_size() thumb_icon_size = (120, 100) exts = File.get_extensions(file_name) base, ext = os.path.splitext(file_name) icon_file_name = "%s_icon.png" % base web_file_name = "%s_web.jpg" % base tmp_icon_path = "%s/%s" % (my.tmp_dir, icon_file_name) tmp_web_path = "%s/%s" % (my.tmp_dir, web_file_name) #cmd = '''"%s" -i "%s" -r 1 -ss 00:00:01 -t 00:00:01 -s %sx%s -f image2 "%s"''' % (ffmpeg, my.file_path, thumb_web_size[0], thumb_web_size[1], tmp_web_path) #os.system(cmd) import subprocess try: subprocess.call([ffmpeg, '-i', my.file_path, "-y", "-ss", "00:00:01","-t","00:00:01",\ "-s","%sx%s"%(thumb_web_size[0], thumb_web_size[1]), "-f","image2", tmp_web_path]) my.web_path = tmp_web_path except: pass try: subprocess.call([ffmpeg, '-i', my.file_path, "-y", "-ss", "00:00:01","-t","00:00:01",\ "-s","%sx%s"%(thumb_icon_size[0], thumb_icon_size[1]), "-f","image2", tmp_icon_path]) my.icon_path = tmp_icon_path except: pass
my.job.commit() my.jobs.remove(my.job) my.job = None my.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 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 print "Error: ", e my.job.set_value("state", "error")
def get_subdisplay(my, views): div = DivWdg() div.set_attr('spt_class_name', Common.get_full_class_name(my)) div.add(my.get_bookmark_menu_wdg("", None, views)) return div
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)
class NamingUtil(object): '''Interface to simply specifying naming convention''' # # try a new naming language which makes use of simple expression language # def naming_to_file(self, template, sobject, snapshot, file=None, ext=None, file_type=None): ''' # chr001_model_v004_00001.ext ''' version_padding = Config.get_value("checkin", "version_padding") if version_padding: version_padding = int(version_padding) else: version_padding = 3 version_expr = "%%0.%dd" % version_padding # the main sobject project = sobject.get_project() # parse the pattern string expression = re.compile(r'{(.*?)}') #expression = re.compile(r'{([\w|\.|\#]+\[?\d?\]?)}') temp_list = expression.findall(template) result = template from pyasm.biz import ExpressionParser xp = ExpressionParser() # if nothing is found, then just return parse through an expression ''' if not temp_list: #return template # put in the ability to add expressions env_sobjects = { 'snapshot': snapshot, 'file': file } file_name = file.get_value("file_name") base_type = file.get_value("base_type") if base_type =='directory': base = file_name ext = None else: base, ext = os.path.splitext(file_name) if not ext: value = None else: # external ext starts with a . ext = ext.lstrip(".") value = ext vars = {'EXT': value, 'BASEFILE': base} result = xp.eval(template, sobject, mode='string', env_sobjects=env_sobjects, vars=vars) test = template test = test.replace("{", "") test = test.replace("}", "") # don't allow / in filename test = test.replace("/", "_") if test != result: return result ''' base = None if file: file_name = file.get_value("file_name") base_type = file.get_value("base_type") if base_type == 'directory': base = file_name ext = None else: base, file_ext = os.path.splitext(file_name) # passed in ext takes prescedence if not ext: ext = file_ext if not ext: value = None else: # external ext starts with a . ext = ext.lstrip(".") value = ext vars = {'EXT': value, 'BASEFILE': base} for part in temp_list: index = -1 if part.startswith(("@", "$")): env_sobjects = {'snapshot': snapshot, 'file': file} value = xp.eval("{%s}" % part, sobject, env_sobjects=env_sobjects, vars=vars, single=True) elif part.find(".") != -1: # explict declarations object, attr = part.split(".") if attr.endswith(']'): # ugly, but it works attr, index = attr.split("[") index = int(index.rstrip("]")) if object == "sobject": value = sobject.get_value(attr) elif object == "snapshot": if not snapshot: continue value = snapshot.get_value(attr) if attr in ['version', 'revision']: if value: value = version_expr % int(value) else: value = "0" * version_padding #value = snapshot.get_value(attr) elif object == "file": if attr == 'file_type': if file_type: value = file_type else: value = 'main' else: value = file.get_value(attr) elif object == "parent": parent = sobject.get_parent() if not parent: value = "NO_PARENT" else: value = parent.get_value(attr) elif object in ["login", "user"]: login = Environment.get_login() value = login.get_value(attr) elif object == "project": project = Project.get() value = project.get_value(attr) else: raise NamingException("Can't parse part [%s] in template" % part) else: # use implicit declarations attr = part if attr.endswith(']'): # ugly, but it works attr, index = attr.split("[") index = int(index.rstrip("]")) if attr in ["context", "process", "snapshot_type"]: value = snapshot.get_value(attr) elif attr == "version": value = snapshot.get_value(attr) if value: value = version_expr % int(value) else: value = "0" * version_padding elif attr == "revision": value = snapshot.get_value(attr) if value: value = version_expr % int(value) else: value = "0" * version_padding elif attr.startswith("#"): if not snapshot: continue value = snapshot.get_value("version") expr = "%%0.%sd" % len(attr) if value: value = expr % int(value) else: value = "0" * len(attr) elif attr == "basefile": file_name = file.get_value("file_name") base_type = file.get_value("base_type") if base_type == 'directory': value = file_name else: base, ext = os.path.splitext(file_name) value = base elif attr == "ext": if not ext: file_name = file.get_value("file_name") base_type = file.get_value("base_type") if base_type == 'directory': value = '' else: base, ext = os.path.splitext(file_name) value = ext.lstrip(".") else: # external ext starts with a . ext = ext.lstrip(".") value = ext elif attr in ["login", "user"]: login = Environment.get_login() value = login.get_value("login") elif attr == "file_type": if file_type: value = file_type else: value = 'main' elif attr.startswith('date'): # {date,%Y-%m-%d_%H-%M-%S]} import time parts = attr.split(",", 1) if len(parts) == 2: format = parts[1] else: format = "%Y%m%d" value = time.strftime(format, time.localtime()) else: value = sobject.get_value(attr) # tbis applies to context for now if index != -1: value = re.split("[/]", value) if len(value) <= index: value = '!' else: value = value[index] #if not value: # raise NamingException("Value for part [%s] is empty" % part) if isinstance(value, int): value = str(value) elif value is None: value = "" result = result.replace("{%s}" % part, value) # don't allow / in filename, # FIXME: it's not put in get_filesystem_name since it # is used for directory name also, need to modify that result = result.replace("/", "_") # remove trailing . if any if result and result[-1] == '.': result = result[:-1] # post process result so that it looks good result = Common.get_filesystem_name(result) return result def _get_timestamp(self, sobject): '''get the portion yyyy-mm-dd''' return sobject.get_value('timestamp')[0:10] def naming_to_dir(self, template, sobject, snapshot, file=None, file_type=None): ''' # shot/SEQ001/shot_001 ''' # the main sobject project = sobject.get_project() # parse the pattern string expression = re.compile(r'{(.*?)}') temp_list = expression.findall(template) from pyasm.biz import ExpressionParser xp = ExpressionParser() ''' # if nothing is found, then just return parse through an expression if not temp_list: #return template # put in the ability to add expressions env_sobjects = { 'snapshot': snapshot, 'file': file } result = xp.eval(template, sobject, mode='string', env_sobjects=env_sobjects) test = template test = test.replace("{", "") test = test.replace("}", "") if test != result: return result ''' # version padding defaults version_padding = Config.get_value("checkin", "version_padding") if version_padding: version_padding = int(version_padding) else: version_padding = 3 version_expr = "%%0.%dd" % version_padding # use simplified expressions result = template for part in temp_list: index = -1 if part.startswith(("@", "$")): env_sobjects = {'snapshot': snapshot, 'file': file} value = xp.eval("{%s}" % part, sobject, env_sobjects=env_sobjects, single=True, use_cache=False) elif part.find(".") != -1: # explict declarasions object, attr = part.split(".") if attr.endswith(']'): # ugly, but it works attr, index = attr.split("[") index = int(index.rstrip("]")) if object == "sobject": if attr == "timestamp": value = self._get_timestamp(sobject) else: value = sobject.get_value(attr) elif object == "snapshot": if not snapshot: value = "" else: if attr == "timestamp": value = self._get_timestamp(snapshot) else: value = snapshot.get_value(attr) if attr in ['version', 'revision']: if value: value = version_expr % int(value) else: value = "0" * version_padding elif object == "search_type": search_type_obj = sobject.get_search_type_obj() value = search_type_obj.get_value(attr) elif object == "parent": parent = sobject.get_parent() if not parent: value = "NO_PARENT" else: if attr == 'timestamp': value = self._get_timestamp(parent) else: value = parent.get_value(attr) elif object == "project": project = Project.get() value = project.get_value(attr) elif object in ["login", "user"]: login = Environment.get_login() value = login.get_value(attr) elif object == "file": if attr == 'file_type': if file_type: value = file_type else: value = 'main' else: value = file.get_value(attr) else: raise NamingException("Can't parse part [%s] in template" % part) else: # use implicit declarations attr = part if attr.endswith(']'): # ugly, but it works attr, index = attr.split("[") index = int(index.rstrip("]")) if attr in ['context','process','snapshot_type','version','revision'] \ and not snapshot: continue if attr in ["context", "process", "snapshot_type"]: value = snapshot.get_value(attr) elif attr == "version": value = snapshot.get_value(attr) if value: value = version_expr % int(value) else: value = "0" * version_padding elif attr == "revision": value = snapshot.get_value(attr) if value: value = version_expr % int(value) else: value = "0" * version_padding elif attr.startswith("#"): if not snapshot: continue value = snapshot.get_value("version") expr = "%%0.%sd" % len(attr) if value: value = expr % int(value) else: value = "0" * len(attr) elif attr.startswith("id"): value = "%0.5d" % sobject.get_id() elif attr == "basefile": if file: file_name = file.get_value("file_name") base_type = file.get_value("base_type") if base_type == 'directory': value = file_name else: base, ext = os.path.splitext(file_name) value = base # Remove # signs as they cause problems index = value.find("#") if index != -1: if value[index - 1] in '-._': value = value[:index - 1] + value[index + 1:] value = value.replace("#", "") else: value = "" elif attr == "ext": if not ext: file_name = file.get_value("file_name") base_type = file.get_value("base_type") if base_type == 'directory': value = '' else: base, ext = os.path.splitext(file_name) value = ext.lstrip(".") else: # external ext starts with a . ext = ext.lstrip(".") value = ext elif attr in ["login", "user"]: login = Environment.get_login() value = login.get_value("login") elif attr == "file_type": if file_type: value = file_type else: value = 'main' else: if attr == "timestamp": value = self._get_timestamp(sobject) else: value = sobject.get_value(attr) if index != -1: value = re.split("[/]", value) if len(value) <= index: value = '!' else: try: value = value[index] except IndexError, e: value = "" if not sobject.is_insert() and not value: value = "" #raise NamingException("Naming convention error: Value for part [%s] is empty" % part) if isinstance(value, int): value = str(value) result = result.replace("{%s}" % part, value) # post process result so that it looks good result = Common.get_filesystem_dir(result) return result
def init(my): super(SObjectCalendarWdg, my).init() custom_view = my.kwargs.get('view') my.custom_sobject_view = my.kwargs.get('sobject_view') if not my.custom_sobject_view: my.custom_sobject_view = 'table' 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 check_new_job(my, queue_type=None): 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(queue_type) 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: # it usually is run at the very first transaction 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: Container.put(Command.TOP_CMD_KEY, None) Container.put(Transaction.KEY, None) 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 get_display(my): search_type_obj = SearchType.get(my.search_type) sobj_title = search_type_obj.get_title() my.color_mode = my.kwargs.get("color_mode") if not my.color_mode: my.color_mode = "default" top_div = my.top top_div.add_class("spt_edit_top") if not my.is_refresh: my.set_as_panel(top_div) content_div = DivWdg() content_div.add_class("spt_edit_top") content_div.add_class("spt_edit_form_top") content_div.set_attr("spt_search_key", my.search_key) if not Container.get_dict("JSLibraries", "spt_edit"): content_div.add_behavior({ 'type': 'load', 'cbjs_action': my.get_onload_js() }) layout_view = my.kwargs.get("layout_view") if layout_view: layout_wdg = my.get_custom_layout_wdg(layout_view) content_div.add(layout_wdg) return content_div # add close listener # NOTE: this is an absolute search, but is here for backwards # compatibility content_div.add_named_listener( 'close_EditWdg', ''' var popup = bvr.src_el.getParent( ".spt_popup" ); if (popup) spt.popup.close(popup); ''') attrs = my.config.get_view_attributes() default_access = attrs.get("access") if not default_access: default_access = "edit" project_code = Project.get_project_code() security = Environment.get_security() base_key = search_type_obj.get_base_key() key = {'search_type': base_key, 'project': project_code} access = security.check_access("sobject", key, "edit", default=default_access) if not access: my.is_disabled = True else: my.is_disabled = False disable_wdg = None if my.is_disabled: # TODO: This overlay doesn't work in IE, size, position, # and transparency all fail. disable_wdg = DivWdg(id='edit_wdg') disable_wdg.add_style("position: absolute") disable_wdg.add_style("height: 90%") disable_wdg.add_style("width: 100%") disable_wdg.add_style("left: 0px") #disable_wdg.add_style("bottom: 0px") #disable_wdg.add_style("top: 0px") disable_wdg.add_style("opacity: 0.2") disable_wdg.add_style("background: #fff") #disable_wdg.add_style("-moz-opacity: 0.2") disable_wdg.add_style("filter: Alpha(opacity=20)") disable_wdg.add("<center>EDIT DISABLED</center>") content_div.add(disable_wdg) attrs = my.config.get_view_attributes() #inner doesn't get styled. inner = DivWdg() content_div.add(inner) menu = my.get_header_context_menu() menus = [menu.get_data()] menus_in = { 'HEADER_CTX': menus, } SmartMenu.attach_smart_context_menu(inner, menus_in, False) #insert the header before body into inner show_header = my.kwargs.get("show_header") if show_header not in ['false', False]: my.add_header(inner, sobj_title) #insert table into a body container so styling gets applied table = Table() body_container = DivWdg() body_container.add_class("spt_popup_body") body_container.add(table) inner.add(body_container) if my.color_mode == "default": table.add_color("background", "background") elif my.color_mode == "transparent": table.add_style("background", "transparent") table.add_color("color", "color") width = attrs.get('width') if not width: width = my.kwargs.get("width") if not width: width = 600 height = attrs.get('height') if height: table.add_style("height: %s" % height) tr = table.add_row() stype_type = search_type_obj.get_value("type", no_exception=True) if my.mode != 'insert' and stype_type in ['media'] and my.sobjects: td = table.add_cell() width += 300 from tactic.ui.panel import ThumbWdg2 thumb = ThumbWdg2() thumb.set_sobject(my.sobjects[0]) td.add(thumb) thumb.add_style("margin: 0px 10px") path = thumb.get_lib_path() td.add_style("padding: 10px") td.add_attr("rowspan", len(my.widgets) + 2) td.add_style("min-width: 250px") td.add_style("vertical-align: top") td.add_border(direction="right") if path: td.add("<h3>File Information</h3>") td.add("<br/>") from pyasm.checkin import BaseMetadataParser parser = BaseMetadataParser.get_parser_by_path(path) data = parser.get_tactic_metadata() data_table = Table() data_table.add_style("margin: 15px") td.add(data_table) for name, value in data.items(): data_table.add_row() display_name = Common.get_display_title(name) dtd = data_table.add_cell("%s: " % display_name) dtd.add_style("width: 150px") dtd.add_style("padding: 3px") dtd = data_table.add_cell(value) dtd.add_style("padding: 3px") else: td.add("<h3>No Image</h3>") td.add("<br/>") # set the width table.add_style("width: %s" % width) single = my.kwargs.get("single") if single in ['false', False] and my.mode == 'insert': multi_div = DivWdg() multi_div.add_style("text-align: left") multi_div.add_style("padding: 5px 10px") multi_div.add("<b>Specify number of new items to add: </b>") multi_div.add(" " * 4) multi_text = TextWdg("multiplier") multi_text.add_class("form-control") multi_div.add(multi_text) multi_text.add_style("display: inline-block") multi_text.add_style("width: 60px") tr, td = table.add_row_cell(multi_div) if my.color_mode == "defaultX": td.add_color("border-color", "table_border", default="border") td.add_style("border-width: 1px") td.add_style("border-style: solid") td.add_style("padding: 8 3 8 3") td.add_color("background", "background3") td.add_color("color", "color3") security = Environment.get_security() # break the widgets up in columns num_columns = attrs.get('num_columns') if not num_columns: num_columns = my.kwargs.get('num_columns') if not num_columns: num_columns = 1 else: num_columns = int(num_columns) # go through each widget and draw it index = 0 for i, widget in enumerate(my.widgets): # since a widget name called code doesn't necessariy write to code column, it is commented out for now """ key = { 'search_type' : search_type_obj.get_base_key(), 'column' : widget.get_name(), 'project': project_code} # check security on widget if not security.check_access( "sobject_column",\ key, "edit"): my.skipped_element_names.append(widget.get_name()) continue """ if not hasattr(widget, 'set_input_prefix'): msg = DivWdg( "Warning: The widget definition for [%s] uses [%s] and is not meant for use in Edit Layout. Please revise the edit_definition in widget config." % (widget.get_name(), widget.__class__.__name__)) msg.add_style('color: orange') content_div.add(msg) content_div.add(HtmlElement.br()) continue if my.input_prefix: widget.set_input_prefix(my.input_prefix) # Bootstrap widget.add_class("form-control") if not isinstance(widget, CheckboxWdg): widget.add_style("width: 100%") if isinstance(widget, EditTitleWdg): tr, td = table.add_row_cell() tr.add_color("background", "background", -5) td.add_style("height", "30px") td.add_style("padding", "0px 10px") td.add(widget) index = 0 continue if isinstance(widget, HiddenWdg): content_div.add(widget) continue # Set up any validations configured on the widget ... from tactic.ui.app import ValidationUtil v_util = ValidationUtil(widget=widget) v_bvr = v_util.get_validation_bvr() if v_bvr: if (isinstance(widget, CalendarInputWdg)): widget.set_validation(v_bvr.get('cbjs_validation'), v_bvr.get('validation_warning')) else: widget.add_behavior(v_bvr) widget.add_behavior(v_util.get_input_onchange_bvr()) new_row = index % num_columns == 0 if new_row: tr = table.add_row() if my.color_mode == "default": if index % 2 == 0: tr.add_color("background", "background") else: tr.add_color("background", "background", -1) index += 1 show_title = widget.get_option("show_title") if not show_title: show_title = my.kwargs.get("show_title") if show_title in ['false', False]: show_title = False else: show_title = True if show_title: title = widget.get_title() td = table.add_cell(title) td.add_style("padding: 15px 15px 10px 5px") td.add_style("vertical-align: top") title_width = my.kwargs.get("title_width") if title_width: td.add_style("width: %s" % title_width) else: td.add_style("width: 150px") security = Environment.get_security() if security.check_access("builtin", "view_site_admin", "allow"): SmartMenu.assign_as_local_activator(td, 'HEADER_CTX') if my.color_mode == "defaultX": td.add_color("border-color", "table_border", default="border") td.add_style("border-width: 1") td.add_style("border-style: solid") td.add_style("text-align: right") hint = widget.get_option("hint") if hint: #hint_wdg = HintWdg(hint) #hint_wdg.add_style("float: right") #td.add( hint_wdg ) td.add_attr("title", hint) if not show_title: th, td = table.add_row_cell(widget) continue else: td = table.add_cell(widget) #td = table.add_cell( widget.get_value() ) td.add_style("min-width: 300px") td.add_style("padding: 10px 25px 10px 5px") td.add_style("vertical-align: top") if my.color_mode == "defaultX": td.add_color("border-color", "table_border", default="border") td.add_style("border-width: 1") td.add_style("border-style: solid") if not my.is_disabled and not my.mode == 'view': inner.add(my.get_action_html()) if my.input_prefix: prefix = HiddenWdg("input_prefix", my.input_prefix) tr, td = table.add_row_cell() td.add(prefix) top_div.add(content_div) return top_div
def get_widget_from_hash(cls, hash, return_none=False, force_no_index=False, kwargs={}): from pyasm.web import DivWdg if hash.startswith("//"): use_top = False hash = hash[1:] else: use_top = True import re p = re.compile("^/(\w+)") m = p.search(hash) if not m: if return_none: return None print "Cannot parse hash[%s]" % hash return DivWdg("Cannot parse hash [%s]" % hash) key = m.groups()[0] # guest user should never be able to see admin site if key != 'login': security = Environment.get_security() login = security.get_user_name() if login == "guest" and key == 'admin': #from pyasm.widget import Error403Wdg #return Error403Wdg().get_buffer_display() from pyasm.widget import WebLoginWdg # HACK: if the guest access is full, the the outer form # is not defined ... force it in here. This is because the # top used it TopWdg and not TitleTopWdg div = DivWdg() div.add("<form id='form' name='form' method='post' enctype='multipart/form-data'>\n") web_login_wdg = WebLoginWdg().get_buffer_display() div.add(web_login_wdg) div.add("</form>\n") return div sobject = cls._get_predefined_url(key, hash) # look up the url if not sobject: search = Search("config/url") search.add_filter("url", "/%s/%%"%key, "like") search.add_filter("url", "/%s"%key) search.add_where("or") sobject = search.get_sobject() if not sobject: if return_none: return None return DivWdg("No Widget found for hash [%s]" % hash) config = sobject.get_value("widget") config = config.replace('&','&') url = sobject.get_value("url") url = url.strip() # update the config value with expressions options = Common.extract_dict(hash, url) for name, value in options.items(): config = config.replace("{%s}" % name, value) xml = Xml() xml.read_string(config) use_index, use_admin, use_sidebar = cls._get_flags(xml, sobject, force_no_index, kwargs) if use_admin: # use admin from tactic.ui.app import PageNavContainerWdg top = PageNavContainerWdg( hash=hash, use_sidebar=use_sidebar ) return top.get_buffer_display() elif use_index: # check if there is an index search = Search("config/url") search.add_filter("url", "/index") index = search.get_sobject() # just use admin if no index page is found if not index: from tactic.ui.app import PageNavContainerWdg top = PageNavContainerWdg( hash=hash, use_sidebar=use_sidebar ) return top.get_buffer_display() config = index.get_value("widget") xml = Xml() xml.read_string(config) node = xml.get_node("element/display") options.update(xml.get_node_values_of_children(node)) class_name = xml.get_value("element/display/@class") if class_name: options['class_name'] = class_name # this passes the hash value to the index widget # which must handle it accordingly options['hash'] = hash top = cls.build_widget(options) return top.get_buffer_display() # process the options and then build the widget from the xml options = Common.extract_dict(hash, url) for name, value in kwargs.items(): options[name] = value node = xml.get_node("element/display") options.update(xml.get_node_values_of_children(node)) class_name = xml.get_value("element/display/@class") if class_name: options['class_name'] = class_name widget = cls.build_widget(options) name = hash.lstrip("/") name = name.replace("/", " ") widget.set_name(name) return widget
def get_display(my): # Custom URLs have the ability to send out different content types url = my.kwargs.get("url") web = WebContainer.get_web() #content_type = my.kwargs.get("content_type") #print "content_type: ", content_type hash = my.kwargs.get("hash") ticket = web.get_form_value("ticket") method = web.get_request_method() headers = web.get_request_headers() accept = headers.get("Accept") expression = url.get_value("url") kwargs = Common.extract_dict(hash, expression) # Does the URL listen to specific Accept values? # or does it enforce a return content type ... and how does one # know what exactly is supported? Accept is kind of complicated. # Easier to put in as a paramenter ... but should accept both # get the widget designated for hash kwargs['Accept'] = accept kwargs['Method'] = method from tactic.ui.panel import HashPanelWdg hash_widget = HashPanelWdg.get_widget_from_hash(hash, kwargs=kwargs) # Really, the hash widget should determine what is returned, but # should take the Accept into account. It is not up to this # class to determine what is or isn't implemented, not is it the # responsibility of this class to convert the data. So, it # returns whatever is given. widget = Widget() # We need to to get the content-type from the widget ... however # it decides to make use of the "Accept" type #widget.get_content_type() # # Example implementation of custom script, run by hash_widget # if accept == "application/json": value = hash_widget.get_display() value = jsondumps(value) web.set_content_type(accept) elif accept == "application/xml": from pyasm.common import Xml value = hash_widget.get_display() if isinstance(value, basestring): xml = Xml(value) value = xml.to_string() elif isinstance(value, Xml): value = value.to_string() web.set_content_type(accept) elif accept == "plain/text": from pyasm.common import Xml value = hash_widget.get_display() value = str(value) web.set_content_type(accept) else: # return text/html value = DivWdg() if isinstance(hash_widget, basestring): value.add(hash_widget) else: value.add(hash_widget.get_display()) web.set_content_type("text/html") widget.add(value) return widget
def get_display(my): top = DivWdg() top.add_border() top.add_style("padding: 10px") top.add_color("color", "color") top.add_gradient("background", "background", 0, -5) #top.add_style("height: 550px") top.add_class("spt_reports_top") my.set_as_panel(top) inner = DivWdg() top.add(inner) title = DivWdg() title.add("Reports") title.add_style("font-size: 18px") title.add_style("font-weight: bold") title.add_style("text-align: center") title.add_style("padding: 10px") title.add_style("margin: -10px -10px 0px -10px") inner.add(title) title.add_gradient("background", "background3", 5, -10) from tactic.ui.widget import TitleWdg subtitle = TitleWdg(name_of_title='List of Built in Reports', help_alias='main') inner.add(subtitle) inner.add("<br/>") button_div = DivWdg() inner.add(button_div) button_div.add_class("spt_buttons_top") button_div.add_style("margin-top: -5px") button_div.add_style("margin-bottom: 30px") button_div.add_border() button_div.add_style("margin-top: -15px") button_div.add_style("margin-bottom: 0px") button_div.add_style("width: 100%") button_div.add_style("height: 33px") button_div.add_color("background", "background2") button_div.add_style("margin-left: auto") button_div.add_style("margin-right: auto") button = SingleButtonWdg(title="Collapse", icon=IconWdg.HOME) button_div.add(button) button.add_style("float: left") button.add_style("left: 5px") button.add_style("top: 5px") # FIXME: get home for the user #home = 'tactic.ui.startup.ContentCreatorWdg' home = 'tactic.ui.startup.MainWdg' button.add_behavior({ 'type': 'click_up', 'cbjs_action': ''' spt.tab.set_main_body_tab(); var class_name = 'tactic.ui.startup.MainWdg'; var kwargs = { help_alias: 'main' }; spt.tab.add_new("_startup", "Startup", class_name, kwargs); ''' }) """ button = SingleButtonWdg(title="Collapse", icon=IconWdg.ARROW_UP) button_div.add(button) button.add_class("spt_collapse") inner.add(button_div) button.add_style("float: left") button.add_style("left: 5px") button.add_style("top: 5px") button.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_reports_top"); var element = top.getElement(".spt_reports_list"); var buttons = bvr.src_el.getParent(".spt_buttons_top"); expand = buttons.getElement(".spt_expand"); new Fx.Tween(element).start('margin-top', "-400px"); expand.setStyle("display", ""); bvr.src_el.setStyle("display", "none"); ''' } ) button = SingleButtonWdg(title="Expand", icon=IconWdg.ARROW_DOWN) button.add_style("display: none") button.add_class("spt_expand") button_div.add(button) button.add_style("left: 5px") button.add_style("top: 5px") inner.add(button_div) button.add_style("float: left") button.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_reports_top"); var element = top.getElement(".spt_reports_list"); var buttons = bvr.src_el.getParent(".spt_buttons_top"); collapse = buttons.getElement(".spt_collapse"); new Fx.Tween(element).start('margin-top', "0px"); collapse.setStyle("display", ""); bvr.src_el.setStyle("display", "none"); ''' } ) """ reports = [] # read the config file from pyasm.widget import WidgetConfig tmp_path = __file__ dir_name = os.path.dirname(tmp_path) file_path = "%s/../config/reports-conf.xml" % (dir_name) config = WidgetConfig.get(file_path=file_path, view="definition") category = my.kwargs.get('category') # get all of the configs from the database if not category or category in ["custom_reports", "custom_charts"]: search = Search("config/widget_config") search.add_op("begin") if category == "custom_reports": search.add_filter("widget_type", "report") elif category == "custom_charts": search.add_filter("widget_type", "chart") elif not category: search.add_filters("widget_type", ["chart", "report"]) search.add_op("or") db_configs = search.get_sobjects() else: db_configs = [] element_names = my.kwargs.get("element_names") if element_names is None: element_names = config.get_element_names() project = Project.get() for element_name in element_names: key = {'project': project.get_code(), 'element': element_name} key2 = {'project': project.get_code(), 'element': '*'} key3 = {'element': element_name} key4 = {'element': '*'} keys = [key, key2, key3, key4] if not top.check_access("link", keys, "view", default="deny"): continue attrs = config.get_element_attributes(element_name) report_data = {} kwargs = config.get_display_options(element_name) class_name = kwargs.get('class_name') # the straight xml definition contains the sidebar class_name # with LinkWdg ... we shouldn't use this, so build the # element from scratch #xml = config.get_element_xml(element_name) from pyasm.search import WidgetDbConfig xml = WidgetDbConfig.build_xml_definition(class_name, kwargs) report_data['class_name'] = class_name report_data['kwargs'] = kwargs report_data['title'] = attrs.get("title") report_data['description'] = attrs.get("description") report_data['image'] = attrs.get("image") report_data['xml'] = xml reports.append(report_data) for db_config in db_configs: element_name = db_config.get_value("view") key = {'project': project.get_code(), 'element': element_name} key2 = {'project': project.get_code(), 'element': '*'} key3 = {'element': element_name} key4 = {'element': '*'} keys = [key, key2, key3, key4] if not top.check_access("link", keys, "view", default="deny"): continue report_data = {} view = db_config.get_value("view") kwargs = {'view': view} parts = view.split(".") title = Common.get_display_title(parts[-1]) xml = db_config.get_value("config") report_data['class_name'] = "tactic.ui.panel.CustomLayoutWdg" report_data['kwargs'] = kwargs report_data['title'] = title report_data['description'] = title report_data['image'] = None report_data['xml'] = xml report_data['widget_type'] = db_config.get_value("widget_type") if report_data['widget_type'] == 'report': report_data['category'] = "custom_reports" elif report_data['widget_type'] == 'chart': report_data['category'] = "custom_charts" reports.append(report_data) """ report_data = { 'title': 'Tasks Completed This Week', 'class_name': 'tactic.ui.panel.ViewPanelWdg', 'kwargs': { 'search_type': 'sthpw/task', 'view': 'table' }, } reports.append(report_data) """ if category == 'list_item_reports' or not category: search_types = Project.get().get_search_types() for search_type in search_types: base_key = search_type.get_base_key() key = {'project': project.get_code(), 'code': base_key} key2 = {'project': project.get_code(), 'code': '*'} key3 = {'code': base_key} key4 = {'code': '*'} keys = [key, key2, key3, key4] if not top.check_access( "search_type", keys, "view", default="deny"): continue if not SearchType.column_exists(base_key, "pipeline_code"): continue thumb_div = DivWdg() image = thumb_div thumb_div.add_border() thumb_div.set_box_shadow("1px 1px 1px 1px") thumb_div.add_style("width: 60px") thumb = ThumbWdg() thumb_div.add(thumb) thumb.set_sobject(search_type) thumb.set_icon_size(60) report_data = { 'title': '%s Workflow Status' % search_type.get_title(), 'description': 'Number of items in each process', 'class_name': 'tactic.ui.report.stype_report_wdg.STypeReportWdg', 'kwargs': { 'search_type': base_key }, 'image': thumb_div } reports.append(report_data) report_data = { 'title': '%s Labor Cost Report' % search_type.get_title(), 'description': 'Labor Cost Breakdown for each Item', 'class_name': 'tactic.ui.panel.ViewPanelWdg', 'kwargs': { 'search_type': search_type.get_code(), 'view': "table", 'show_header': False, 'mode': 'simple', 'element_names': "preview,code,title,cost_breakdown,bid_hours,bid_cost,actual_hours,actual_cost,overbudget,variance" }, 'image': IconWdg("", IconWdg.REPORT_03) } reports.append(report_data) table2 = Table() inner.add(table2) table2.add_style("width: 100%") categories_div = DivWdg() td = table2.add_cell(categories_div) td.add_style("vertical-align: top") td.add_style("width: 200px") td.add_color("background", "background3") td.add_border() #categories_div.add_style("margin: -1px 0px 0px -1px") categories_div.add_style("padding-top: 10px") #categories_div.add_style("float: left") categories_div.add_color("color", "color3") categories = config.get_all_views() categories.insert(-1, "list_item_reports") categories.insert(-1, "custom_charts") categories.insert(-1, "custom_reports") table_div = DivWdg() td = table2.add_cell(table_div) td.add_style("vertical-align: top") table_div.add_class("spt_reports_list") table_div.add_border() table_div.add_color("background", "background", -5) table_div.add_style("min-height: 500px") for i, category in enumerate(categories): if i == len(categories) - 1: categories_div.add("<hr/>") config.set_view(category) element_names = config.get_element_names() if category == "definition": title = "All Reports" else: title = Common.get_display_title(category) category_div = DivWdg() categories_div.add(category_div) category_div.add(title) category_div.add_style("padding: 5px") category_div.add_class("hand") category_div.add_behavior({ 'type': 'click_up', 'category': category, 'element_names': element_names, 'class_name': Common.get_full_class_name(my), 'cbjs_action': ''' var kwargs = { is_refresh: true, category: bvr.category, element_names: bvr.element_names } //spt.panel.refresh(top, kwargs); var top = bvr.src_el.getParent(".spt_reports_top"); spt.panel.load(top, bvr.class_name, kwargs); ''' }) bgcolor = category_div.get_color("background3", -10) category_div.add_behavior({ 'type': 'mouseover', 'bgcolor': bgcolor, 'cbjs_action': ''' bvr.src_el.setStyle("background", bvr.bgcolor); ''' }) category_div.add_behavior({ 'type': 'mouseout', 'bgcolor': bgcolor, 'cbjs_action': ''' bvr.src_el.setStyle("background", ""); ''' }) # create a bunch of panels table = Table() table_div.add(table) table.add_color("color", "color") table.add_style("margin-top: 20px") table.center() table_div.add_style("margin: -3px -3px -1px -2px") if not reports: tr = table.add_row() td = table.add_cell() td.add("There are no reports defined.") td.add_style("padding: 50px") if my.kwargs.get("is_refresh") in ['true', True]: return inner else: return top for i, report in enumerate(reports): #if i == 0 or i%4 == 0: if i % 3 == 0: tr = table.add_row() td = table.add_cell() td.add_style("vertical-align: top") td.add_style("padding: 3px") title = report #description = '''The schema is used to layout the basic components of your project. Each component represents a list of items that you use in your business everyday.''' description = report.get("title") # Each node will contain a list of "items" and will be stored as a table in the database.''' class_name = report.get("class_name") kwargs = report.get("kwargs") title = report.get("title") description = report.get("description") widget_type = report.get("widget_type") image = report.get("image") icon = report.get("icon") xml = report.get("xml") if image: div = DivWdg() if isinstance(image, basestring): image = image.upper() image = eval("IconWdg('', IconWdg.%s)" % image) div.add_style("margin-left: 15px") div.add_style("margin-top: 5px") else: image = image div.add(image) image = div elif icon: icon = icon.upper() image = eval("IconWdg('', IconWdg.%s)" % icon) else: div = DivWdg() """ import random num = random.randint(0,3) if num == 1: image = IconWdg("Bar Chart", IconWdg.GRAPH_BAR_01) elif num == 2: image = IconWdg("Bar Chart", IconWdg.GRAPH_LINE_01) else: image = IconWdg("Bar Chart", IconWdg.GRAPH_BAR_02) """ if widget_type == "chart": image = IconWdg("Chart", IconWdg.GRAPH_BAR_02) else: image = IconWdg("No Image", IconWdg.WARNING) div.add_style("margin-left: 15px") div.add_style("margin-top: 5px") div.add(image) image = div behavior = { 'type': 'click_up', 'title': title, 'class_name': class_name, 'kwargs': kwargs, 'cbjs_action': ''' spt.tab.set_main_body_tab(); //var top = bvr.src_el.getParent(".spt_reports_top"); //spt.tab.set_tab_top(top); spt.tab.add_new(bvr.title, bvr.title, bvr.class_name, bvr.kwargs); ''' } schema_wdg = my.get_section_wdg(title, description, image, behavior) schema_wdg.add_behavior({ 'type': 'load', 'title': title, 'class_name': class_name, 'xml': xml, 'kwargs': kwargs, 'cbjs_action': ''' var report_top = bvr.src_el; report_top.kwargs = bvr.kwargs; report_top.class_name = bvr.class_name; report_top.element_name = bvr.title; report_top.xml = bvr.xml; ''' }) td.add(schema_wdg) inner.add("<br/>") #from tactic.ui.container import TabWdg #tab = TabWdg(show_add=False) #inner.add(tab) if my.kwargs.get("is_refresh") in ['true', True]: return inner else: return top
def get_display(my): search_key = my.kwargs.get("search_key") path = my.kwargs.get("path") parser_str = my.kwargs.get("parser") use_tactic_tags = my.kwargs.get("use_tactic_tags") from pyasm.checkin import PILMetadataParser, ImageMagickMetadataParser, ExifMetadataParser, BaseMetadataParser if parser_str: parser = BaseMetadataParser.get_parser(parser_str, path) else: parser = BaseMetadataParser.get_parser_by_path(path) if parser: if use_tactic_tags in ['true', True]: metadata = parser.get_tactic_metadata() else: metadata = parser.get_metadata() else: 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") if len(str(value)) > 500: inside = DivWdg() td.add(inside) value = value[:500] inside.add(value) inside.add_style("max-width: 600px") else: 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_predefined_url(cls, key, hash): # make some predefined fake urls if key in ["link", "tab", "admin"]: # this is called by PageNav if key == "admin": expression = "/admin/link/{link}" else: expression = "/%s/{link}" % key options = Common.extract_dict(hash, expression) link = options.get("link") if not link: return None # test link security project_code = Project.get_project_code() security = Environment.get_security() keys = [ { "element": link }, { "element": "*" }, { "element": link, "project": project_code }, { "element": "*", "project": project_code } ] if not security.check_access("link", keys, "allow", default="deny"): return None from tactic.ui.panel import SideBarBookmarkMenuWdg personal = False if '.' in link: personal = True config = SideBarBookmarkMenuWdg.get_config("SideBarWdg", link, personal=personal) options = config.get_display_options(link) if not options: from pyasm.biz import Schema config_xml = [] config_xml.append( ''' <config> ''') config_schema = Schema.get_predefined_schema('config') SideBarBookmarkMenuWdg.get_schema_snippet("_config_schema", config_schema, config_xml) schema = Schema.get_admin_schema() SideBarBookmarkMenuWdg.get_schema_snippet("_admin_schema", schema, config_xml) config_xml.append( ''' </config> ''') xml = "".join(config_xml) from pyasm.widget import WidgetConfig schema_config = WidgetConfig.get(view="_admin_schema", xml=xml) options = schema_config.get_display_options(link) if not options: schema_config.set_view("_config_schema") options = schema_config.get_display_options(link) if not options: return None class_name = options.get("class_name") widget_key = options.get("widget_key") if widget_key: class_name = WidgetClassHandler().get_display_handler(widget_key) elif not class_name: class_name = 'tactic.ui.panel.ViewPanelWdg' if key in ["admin", "tab"]: use_index = "false" else: use_index = "true" if key in ['admin']: use_admin = "true" else: use_admin = "false" xml = [] xml.append('''<element admin="%s" index="%s">''' % (use_admin, use_index)) xml.append(''' <display class="%s">''' % class_name) for name, value in options.items(): xml.append("<%s>%s</%s>" % (name, value, name) ) xml.append(''' </display>''') xml.append('''</element>''') xml = "\n".join(xml) sobject = SearchType.create("config/url") sobject.set_value("url", "/%s/{value}" % key) sobject.set_value("widget", xml ) return sobject else: return None
def get_repo(my): repo_handler = my.get_repo_class() repo = Common.create_from_class_path(repo_handler) return repo
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 __init__(my, is_refresh=False): super(UndoLogWdg, my).__init__() my.all_users_flag = False my.all_namespaces_flag = False my.add_class("spt_panel") my.add_attr("spt_class_name", Common.get_full_class_name(my))
def get_display(my): config_search_type = "config/widget_config" configs = [] all_element_names = [] from tactic.ui.panel import SideBarBookmarkMenuWdg SideBarBookmarkMenuWdg.add_internal_config(configs, ['definition']) for internal_config in configs: all_element_names = internal_config.get_element_names() search = Search(config_search_type) search.add_filter("search_type", 'SideBarWdg') search.add_filter("view", 'definition') search.add_filter("login", None) config = search.get_sobject() element_names = [] if config: element_names = config.get_element_names() for name in element_names: if 'separator' in name: element_names.remove(name) all_element_names.extend(element_names) all_element_names = [str(name) for name in all_element_names] all_element_names = Common.get_unique_list(all_element_names) widget = DivWdg(css='spt_load_test_top') span = SpanWdg( 'This loads all the pages defined in the Project views in popups. It will take a few minutes.' ) widget.add(span) widget.add('<br/>') div = ActionButtonWdg(title='Run') web = WebContainer.get_web() base_url = web.get_base_url().to_string() base_url = '%s/tactic/%s' % (base_url, Project.get_project_code()) div.add_behavior({ 'type': 'click_up', 'cbjs_action': ''' var element_names = eval(%s); var all_element_names = eval(%s); var top = spt.get_parent(bvr.src_el, '.spt_load_test_top'); var cb = spt.get_element(top, '.spt_input') if (cb.checked) element_list = all_element_names; else element_list = element_names for (var k=0; k < element_list.length; k++) { var name = element_list[k]; //if (k > 3) break; var url = '%s/#/link/' + name; var bvr2 = { title: name, target_id: 'TEST', options: {'link': name, 'title': name, 'path': '/Link Test/' + name }, is_popup: true}; spt.side_bar.display_link_cbk(null, bvr2); } ''' % (element_names, all_element_names, base_url) }) widget.add('<br/>') cb = CheckboxWdg('include_internal', label='include built-in pages') span = SpanWdg(cb, css='med') span.add_color('color', 'color') widget.add(span) widget.add(div) widget.add('<br/>') widget.add('<br/>') return widget
def get_display(my): top = DivWdg() top.add_border() top.add_style("padding: 10px") top.add_color("color", "color") top.add_color("background", "background") top.add_class("spt_reports_top") title = DivWdg() title.add("Themes") title.add_style("font-size: 18px") title.add_style("font-weight: bold") title.add_style("text-align: center") title.add_style("padding: 10px") title.add_style("margin: -10px -10px 10px -10px") title.add_gradient("background", "background3", 5, -10) top.add(title) from tactic.ui.widget import TitleWdg subtitle = TitleWdg(name_of_title='List of Themes', help_alias='project-startup-themes') top.add(subtitle) top.add("<br/>") themes = [] # read the config file """ from pyasm.widget import WidgetConfig tmp_path = __file__ dir_name = os.path.dirname(tmp_path) file_path="%s/../config/themes-conf.xml" % (dir_name) config = WidgetConfig.get(file_path=file_path, view="definition") element_names = config.get_element_names() for element_name in element_names: attrs = config.get_element_attributes(element_name) theme_data = {} kwargs = config.get_display_options(element_name) class_name = kwargs.get('class_name') theme_data['class_name'] = class_name theme_data['kwargs'] = kwargs theme_data['title'] = attrs.get("title") theme_data['description'] = attrs.get("description") theme_data['image'] = attrs.get("image") themes.append(theme_data) """ # get all of the configs from the database search = Search("config/widget_config") search.add_filter("widget_type", "theme") db_configs = search.get_sobjects() for db_config in db_configs: theme_data = {} view = db_config.get_value("view") kwargs = {'view': view} #parts = view.split(".") #title = Common.get_display_title(parts[-1]) title = view title = title.replace(".", " ") title = title.replace("_", " ") title = Common.get_display_title(title) xml = db_config.get_value("config") theme_data['class_name'] = "tactic.ui.panel.CustomLayoutWdg" theme_data['kwargs'] = kwargs theme_data['view'] = view theme_data['title'] = title theme_data['description'] = title theme_data['image'] = None theme_data['xml'] = xml theme_data['widget_type'] = db_config.get_value("widget_type") themes.append(theme_data) if not themes: no_themes_div = DivWdg() top.add(no_themes_div) no_themes_div.add_style("margin-left: auto") no_themes_div.add_style("margin-right: auto") no_themes_div.add_style("width: 400px") no_themes_div.add_style("height: 50px") no_themes_div.add_style("text-align: center") no_themes_div.add_style("padding: 50px 50px") no_themes_div.add_style("margin-top: 100px") no_themes_div.add_style("margin-bottom: 100px") no_themes_div.add_style("font-weight: bold") no_themes_div.add_border() no_themes_div.add_color("background", "background3") no_themes_div.add("No themes activated in thie project") return top # create a bunch of panels table = Table() top.add(table) table.add_color("color", "color") table.add_style("margin-bottom: 20px") table.center() # get all of the /index URLs search = Search("config/url") search.add_filter("url", "/index") indexes = search.get_sobjects() current_view = None for index in indexes: widget_xml = index.get_xml_value("widget") current_view = widget_xml.get_value("element/display/view") for i, theme in enumerate(themes): if i == 0 or i % 4 == 0: tr = table.add_row() td = table.add_cell() td.add_style("vertical-align: top") td.add_style("padding: 3px") description = theme.get("title") # Each node will contain a list of "items" and will be stored as a table in the database.''' class_name = theme.get("class_name") kwargs = theme.get("kwargs") title = theme.get("title") description = theme.get("description") xml = theme.get("xml") or "" view = theme.get("view") #if current_view == view.replace(".", "/"): # td.add("CURRENT") image = theme.get("image") icon = theme.get("icon") if image: div = DivWdg() if isinstance(image, basestring): image = image.upper() image = eval("IconWdg('', IconWdg.%s)" % image) div.add_style("margin-left: 15px") div.add_style("margin-top: 5px") else: image = image div.add(image) image = div elif icon: icon = icon.upper() image = eval("IconWdg('', IconWdg.%s)" % icon) else: div = DivWdg() #image = IconWdg("Bar Chart", IconWdg.WARNING) image = IconWdg("Bar Chart", IconWdg.DASHBOARD_02) div.add_style("margin-left: 15px") div.add_style("margin-top: 5px") div.add(image) image = div behavior = { 'type': 'click_up', 'title': title, 'class_name': class_name, 'kwargs': kwargs, 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_reports_top"); spt.tab.set_main_body_tab(); //spt.tab.set_tab_top(top); var kwargs = {}; spt.tab.add_new(bvr.title, bvr.title, bvr.class_name, bvr.kwargs); ''' } schema_wdg = my.get_section_wdg(title, description, image, behavior) schema_wdg.add_behavior({ 'type': 'load', 'title': title, 'class_name': class_name, 'view': view, 'xml': xml, 'kwargs': kwargs, 'cbjs_action': ''' var report_top = bvr.src_el; report_top.kwargs = bvr.kwargs; report_top.class_name = bvr.class_name; report_top.element_name = bvr.title; report_top.view = bvr.view; report_top.xml = bvr.xml; ''' }) td.add(schema_wdg) #from tactic.ui.container import TabWdg #tab = TabWdg(show_add=False) #top.add(tab) return top
def _test_symlink(my): if os.name == 'nt': return # create a new test.txt file file_path = "./symlink.txt" file = open(file_path, 'w') file.write("symlink test") file.close() file_path2 = "./symlink_append.txt" file = open(file_path2, 'w') file.write("append test") file.close() checkin = FileCheckin(my.person, file_path, context="sym_test", checkin_type='auto') checkin.execute() snap = checkin.get_snapshot() versionless_snap = Snapshot.get_versionless( my.person.get_search_type(), my.person.get_id(), "sym_test", mode='latest', create=False) my.assertEquals(True, isinstance(versionless_snap, Snapshot)) main_lib_path = snap.get_lib_path_by_type('main') my.assertEquals( main_lib_path.endswith( '/sym_test/.versions/symlink_sym_test_v001.txt'), True) if versionless_snap: lib_path = versionless_snap.get_lib_path_by_type('main') my.assertEquals(True, os.path.exists(lib_path)) rel_path = os.readlink(lib_path) lib_dir = os.path.dirname(lib_path) # this is essentially handle_link() in FileUndo class wd = os.getcwd() os.chdir(lib_dir) real_path = os.path.join(lib_dir, os.path.abspath(rel_path)) # lib_path points to real_path expected_rel_path = Common.relative_path(lib_path, real_path) my.assertEquals(True, os.path.exists(real_path)) my.assertEquals(expected_rel_path, rel_path) os.chdir(wd) # if not inplace or preallocate mode, keep_file_name should be False checkin = FileAppendCheckin(snap.get_code(), [file_path2], file_types=['add'], keep_file_name=False, checkin_type='auto') checkin.execute() snap = checkin.get_snapshot() main_lib_path = snap.get_lib_path_by_type('add') my.assertEquals(snap.get_value('is_current'), True) my.assertEquals(snap.get_value('is_latest'), True) my.assertEquals( main_lib_path.endswith( '/sym_test/.versions/symlink_append_sym_test_v001.txt'), True) versionless_snap = Snapshot.get_versionless( my.person.get_search_type(), my.person.get_id(), "sym_test", mode='latest', create=False) if versionless_snap: lib_path = versionless_snap.get_lib_path_by_type('add') my.assertEquals( lib_path.endswith('/sym_test/symlink_append_sym_test.txt'), True) my.assertEquals(os.path.exists(lib_path), True)