def get_reg_hours(): # FIXME: this shold be in pyasm.biz, not pyasm.prod.biz from pyasm.prod.biz import ProdSetting reg_hours = ProdSetting.get_value_by_key("reg_hours") if not reg_hours: # auto create if it does not exist ProdSetting.create('reg_hours', '10', 'sequence', \ description='regular work hours', search_type='sthpw/project') return reg_hours
def __init__(self, dynamic_load=0, tab_key="tab", css=REG): self.tab_names = [] self.wdg_dict = {} self.dynamic_load = dynamic_load self.set_tab_key(tab_key) self.tab_style = css self.content_height = 0 self.mode = Container.get("tab_mode") # setting tab path self.tab_path = Container.get("tab_path") if not self.tab_path: self.tab_path = "Main" self.error_wdg = None self.div = DivWdg(css='left_content') if Environment.has_tactic_database(): self.invisible_list = ProdSetting.get_seq_by_key('invisible_tabs') else: self.invisible_list = [] super(TabWdg,self).__init__()
def __init__(my, dynamic_load=0, tab_key="tab", css=REG): my.tab_names = [] my.wdg_dict = {} my.dynamic_load = dynamic_load my.set_tab_key(tab_key) my.tab_style = css my.content_height = 0 my.mode = Container.get("tab_mode") # setting tab path my.tab_path = Container.get("tab_path") if not my.tab_path: my.tab_path = "Main" my.error_wdg = None my.div = DivWdg(css='left_content') if Environment.has_tactic_database(): my.invisible_list = ProdSetting.get_seq_by_key('invisible_tabs') else: my.invisible_list = [] super(TabWdg, my).__init__()
def __init__(my, dynamic_load=0, tab_key="tab", css=REG): my.tab_names = [] my.wdg_dict = {} my.dynamic_load = dynamic_load my.set_tab_key(tab_key) my.tab_style = css my.content_height = 0 my.mode = Container.get("tab_mode") # setting tab path my.tab_path = Container.get("tab_path") if not my.tab_path: my.tab_path = "Main" my.error_wdg = None my.div = DivWdg(css='left_content') if Environment.has_tactic_database(): my.invisible_list = ProdSetting.get_seq_by_key('invisible_tabs') else: my.invisible_list = [] super(TabWdg,my).__init__()
def __init__(self, dynamic_load=0, tab_key="tab", css=REG): self.tab_names = [] self.wdg_dict = {} self.dynamic_load = dynamic_load self.set_tab_key(tab_key) self.tab_style = css self.content_height = 0 self.mode = Container.get("tab_mode") # setting tab path self.tab_path = Container.get("tab_path") if not self.tab_path: self.tab_path = "Main" self.error_wdg = None self.div = DivWdg(css='left_content') if Environment.has_tactic_database(): self.invisible_list = ProdSetting.get_seq_by_key('invisible_tabs') else: self.invisible_list = [] super(TabWdg, self).__init__()
def get_seq_wdg(self): widget = Widget() help = HelpItemWdg( 'Sequences tab', 'The Sequences tab lets you create sequences which can be used to relate to shots. Each shot has a sequence code attribute which you can assign to.' ) widget.add(help) div = DivWdg(css='filter_box') search_columns = Sequence.get_search_columns() search_filter = SearchFilterWdg(name="sequence_search", columns=search_columns) div.add(SpanWdg(search_filter, css='med')) search = Search("prod/sequence") search_filter.alter_search(search) widget.add(div) view = 'table' if ProdSetting.get_value_by_key( 'shot_hierarchy') == 'episode_sequence': view = 'table_episode' table = TableWdg("prod/sequence", view) table.set_search(search) widget.add(table) return widget
def get_display(self): task_div = DivWdg(self.label) task_div.add_style("text-align: left") task_div.add_style('margin-left', '10px') setting = ProdSetting.get_by_key(self.shot_status_setting) if not setting: BaseAppServer.add_onload_script(IframeWdg.get_popup_script(\ "The Project Setting [%s] is required to be set."%self.shot_status_setting)) return # add a check-all toggle control checkbox_control = CheckboxWdg("sobj_status_control") checkbox_control.add_event( "onclick", "get_elements('sobj_status').toggle_all(this);") task_div.add(checkbox_control) checked_all_status = True for status in self.statuses: span = SpanWdg(css="med") checkbox = CheckboxWdg("sobj_status") checkbox.set_persistence() checkbox.set_option("value", status) if checked_all_status and not checkbox.is_checked(): checked_all_status = False span.add(checkbox) span.add(status) task_div.add(span) if checked_all_status: checkbox_control.set_checked() return task_div
def main(server=None, input=None): """ :param server: the TacticServerStub object :param input: a dict with data like like search_key, search_type, sobject, and update_data :return: None """ try: from formatted_emailer import EmailDirections, email_sender todays_date = date.today() one_week_ago = (todays_date - timedelta(days=7)).strftime('%Y-%m-%d') past_due_titles = server.eval("@SOBJECT(twog/title['expected_delivery_date', 'is before', '{0}']['expected_delivery_date', 'is after', '{1}'])".format(todays_date, one_week_ago)) number_of_titles_past_due = len(past_due_titles) past_due_titles = [title.get('code') for title in past_due_titles] email_subject = 'There are {0} Titles that are past due'.format(number_of_titles_past_due) message = "The following titles are past due.<br/><br/>{0}<br/><br/>Please log into Tactic and change the " \ "due date on these Titles. If you don't know when that's supposed to be, you can just change it " \ "to today's date.".format(', '.join(past_due_titles)) recipients = ProdSetting.get_seq_by_key('past_due_alert_recipients') if not recipients: return context_data = { 'to_email': recipients[0], 'subject': email_subject, 'message': message, 'from_email': '*****@*****.**', 'from_name': 'Tactic', } if len(recipients) > 1: context_data.update({'ccs', ';'.join(recipients[1:])}) internal_template_file = '/opt/spt/custom/formatted_emailer/templates/past_due_title_notification.html' if context_data['to_email']: email_file_name = 'past_due_title_notification_{0}.html'.format(todays_date) email_sender.send_email(template=internal_template_file, email_data=context_data, email_file_name=email_file_name, server=server) except AttributeError as e: traceback.print_exc() print str(e) + '\nMost likely the server object does not exist.' raise e except KeyError as e: traceback.print_exc() print str(e) + '\nMost likely the input dictionary does not exist.' raise e except Exception as e: traceback.print_exc() print str(e) raise e
def get_display(my): # just refresh the whole thing widget = DivWdg() outer_widget = DivWdg(css='spt_view_panel') search_div = DivWdg() search_bvr = { 'type': 'click_up', 'cbjs_action': 'spt.dg_table.search_cbk(evt, bvr)', 'override_class_name': 'tactic.ui.cgapp.AppShotPanelWdg', 'override_target': 'bvr.src_el.getParent(".spt_app_shot_panel")', 'extra_args': {'instance_search_type': my.instance_search_type, 'asset_search_type': my.asset_search_type} #'panel_id': 'main_body_search' } # WARNING: this is made just for main search box and won't be compatible with the simple search wdg search_wdg = SearchWdg(search_type=my.search_type, custom_search_view='search_shot_loader', parent_key='', filter=''\ , display='block', custom_filter_view='', state=None, run_search_bvr=search_bvr) #from tactic.ui.app.simple_search_wdg import SimpleSearchWdg #search_wdg = SimpleSearchWdg(search_type=my.search_type, search_view=my.simple_search_view, state=None, run_search_bvr=search_bvr) search_div.add( HtmlElement.spacer_div(1,10) ) search_div.add(search_wdg) # if there is result, it could only be one shot search = search_wdg.get_search() shots = search.get_sobjects() # avoid getting a shot when no shot is selected if not my.shot_code and len(shots) == 1: my.shot_code = shots[0].get_code() outer_widget.add(search_div) my.set_as_panel(outer_widget, class_name='spt_panel spt_view_panel spt_app_shot_panel') #show_shot_panel = False #if show_shot_panel: panel = ViewPanelWdg( search_type=my.search_type, \ inline_search=True, show_search='false', show_refresh='false', view=my.view, \ run_search_bvr=search_bvr, simple_search_view=my.simple_search_view) panel.set_sobjects(shots) widget.add(panel) show_instances_in_shot = ProdSetting.get_value_by_key("show_instances_in_shot_panel") if show_instances_in_shot != "false": widget.add(HtmlElement.h3("Asset Instances in Shot [%s]" %my.shot_code)) widget.add(HtmlElement.br(2)) asset_inst_panel = AppAssetInstancePanelWdg(search_type=my.search_type, instance_search_type=my.instance_search_type, asset_search_type=my.asset_search_type, shot_code=my.shot_code, show_search='false') widget.add(asset_inst_panel) outer_widget.add(widget) return outer_widget
def get_sobject_base(my, dirs): # add <project_code>/<table> search_type_obj = my.sobject.get_search_type_obj() project_code = my.sobject.get_project().get_code() dirs.append( project_code ) #db_name = search_type_obj.get_database() #dirs.append( db_name ) from pyasm.prod.biz import ProdSetting if project_code not in ["admin", 'sthpw']: icon_separation = ProdSetting.get_value_by_key("use_icon_separation") if not icon_separation: # put in a default icon_separation = "false" ProdSetting.create('use_icon_separation', icon_separation, 'string',\ description='Determines whether icons are in complete separate directories') if icon_separation == 'true': if my.snapshot and my.snapshot.get_value("context") == "icon": dirs.append("icon") elif my.get_file_type() == "icon": dirs.append("icon") #process = my.snapshot.get_value("process") #search_type = my.snapshot.get_value("search_type") # add a concept of branching # from pyasm.web import WidgetSettings # branch = WidgetSettings.get_value_by_key("current_branch") # #WidgetSettings.set_value_by_key("current_branch", branch) # if branch: # #dirs.append( "perforce" ) # dirs.append( branch ) table = search_type_obj.get_table() dirs.append( table ) return dirs
def __init__(my, **kwargs): my.frames = kwargs.get("frames") my.fps = kwargs.get("fps") if not my.fps: from pyasm.prod.biz import ProdSetting my.fps = ProdSetting.get_value_by_key("fps") if not my.fps: my.fps = 24 if not my.frames: timecode = kwargs.get("timecode") my.frames = my.calculate_frames(timecode, my.fps)
def get_context_wdg(self, search_type): '''drop down which selects which context to checkin''' # add a filter # use a regular SelectWdg with submit instead of FilterSelectWdg filter_div = FloatDivWdg("Context / subcontext:") select = SelectWdg("publish_context") labels, values = self.get_context_data(search_type, self.process) select.set_option("values", "|".join(values)) select.set_option("labels", "|".join(labels)) select.append_option('publish','publish') select.add_style("font-size: 0.8em") select.add_style("margin: 0px 3px") # explicitly set the value current = select.get_value() if current in values: context = current elif values: context = values[0] else: context = "" web = WebContainer.get_web() web.set_form_value("publish_context", context) select.set_value( context ) # set it to a instance variable self.context_select = select filter_div.add(select) # if specified, add a sub_context base_search_type = SearchType(search_type).get_base_key() settings = ProdSetting.get_value_by_key("%s/sub_context" % context,\ base_search_type) filter_div.add( "/ ") sub_context = None if settings: sub_context = SelectWdg("publish_sub_context") sub_context.set_option("values", settings) sub_context.set_submit_onchange() sub_context.add_empty_option("<- Select ->") else: # provide a text field sub_context = TextWdg("publish_sub_context") sub_context.set_attr('size','10') sub_context.set_persistence() filter_div.add( sub_context ) self.sub_context_select = sub_context #filter_div.add_style('padding-right','10px') return filter_div
def get_context_wdg(my, search_type): '''drop down which selects which context to checkin''' # add a filter # use a regular SelectWdg with submit instead of FilterSelectWdg filter_div = FloatDivWdg("Context / subcontext:") select = SelectWdg("publish_context") labels, values = my.get_context_data(search_type, my.process) select.set_option("values", "|".join(values)) select.set_option("labels", "|".join(labels)) select.append_option('publish','publish') select.add_style("font-size: 0.8em") select.add_style("margin: 0px 3px") # explicitly set the value current = select.get_value() if current in values: context = current elif values: context = values[0] else: context = "" web = WebContainer.get_web() web.set_form_value("publish_context", context) select.set_value( context ) # set it to a instance variable my.context_select = select filter_div.add(select) # if specified, add a sub_context base_search_type = SearchType(search_type).get_base_key() settings = ProdSetting.get_value_by_key("%s/sub_context" % context,\ base_search_type) filter_div.add( "/ ") sub_context = None if settings: sub_context = SelectWdg("publish_sub_context") sub_context.set_option("values", settings) sub_context.set_submit_onchange() sub_context.add_empty_option("<- Select ->") else: # provide a text field sub_context = TextWdg("publish_sub_context") sub_context.set_attr('size','10') sub_context.set_persistence() filter_div.add( sub_context ) my.sub_context_select = sub_context #filter_div.add_style('padding-right','10px') return filter_div
def convert_to_time(self, frames): fps = ProdSetting.get_value_by_key("fps") if not fps: fps = 24 else: fps = int(fps) minutes = frames / (60*fps) frames = frames - (minutes*60*fps) seconds = frames / fps extra = frames % fps time = "%0.2dm:%0.2ds.%0.2d" % (minutes, seconds, extra) return time
def convert_to_time(my, frames): fps = ProdSetting.get_value_by_key("fps") if not fps: fps = 24 else: fps = int(fps) minutes = frames / (60 * fps) frames = frames - (minutes * 60 * fps) seconds = frames / fps extra = frames % fps time = "%0.2dm:%0.2ds.%0.2d" % (minutes, seconds, extra) return time
def get_web_file_size(my): from pyasm.prod.biz import ProdSetting web_file_size = ProdSetting.get_value_by_key('web_file_size') thumb_size = (640, 480) if web_file_size: parts = re.split('[\Wx]+', web_file_size) thumb_size = (640, 480) if len(parts) == 2: try: thumb_size = (int(parts[0]), int(parts[1])) except ValueError: thumb_size = (640, 480) return thumb_size
def handle_tab(self, tab): tab.add(self.get_shot_list_wdg, _("Shot List") ) tab.add(self.get_summary_wdg, _("Summary") ) tab.add(self.get_milestone_wdg, _("Milestones") ) tab.add(MultiPlannerWdg, _("Planners") ) tab.add(self.get_task_manager_wdg, _("Tasks") ) #tab.add(ShotParentWdg, "Shot Parenting") ) tab.add(self.get_artist_wdg, _("Artist (Shots)") ) tab.add(self.get_supe_wdg, _("Supe (Shots)") ) tab.add(self.get_layer_wdg, _("Layers") ) tab.add(self.get_comp_wdg, _("Composites") ) tab.add(self.get_render_log_wdg, _("Render Log") ) tab.add(self.get_seq_wdg, _("Sequences") ) if ProdSetting.get_value_by_key('shot_hierarchy') == 'episode_sequence': tab.add(self.get_episode_wdg, _("Episodes") ) tab.add(self.get_notes_wdg, _("Notes") )
def handle_tab(self, tab): tab.add(self.get_shot_list_wdg, _("Shot List")) tab.add(self.get_summary_wdg, _("Summary")) tab.add(self.get_milestone_wdg, _("Milestones")) tab.add(MultiPlannerWdg, _("Planners")) tab.add(self.get_task_manager_wdg, _("Tasks")) #tab.add(ShotParentWdg, "Shot Parenting") ) tab.add(self.get_artist_wdg, _("Artist (Shots)")) tab.add(self.get_supe_wdg, _("Supe (Shots)")) tab.add(self.get_layer_wdg, _("Layers")) tab.add(self.get_comp_wdg, _("Composites")) tab.add(self.get_render_log_wdg, _("Render Log")) tab.add(self.get_seq_wdg, _("Sequences")) if ProdSetting.get_value_by_key( 'shot_hierarchy') == 'episode_sequence': tab.add(self.get_episode_wdg, _("Episodes")) tab.add(self.get_notes_wdg, _("Notes"))
def __init__(my, **kwargs): my.frames = kwargs.get("frames") my.frames = float(my.frames) my.fps = kwargs.get("fps") if not my.fps: from pyasm.prod.biz import ProdSetting my.fps = ProdSetting.get_value_by_key("fps") my.fps = int(my.fps) if not my.fps: my.fps = 24 if not my.frames: timecode = kwargs.get("timecode") my.frames = my.calculate_frames(timecode, my.fps) # handle cases where frames has a decimal: ie: 400.4 my.frames = int(float(my.frames))
def __init__(self, **kwargs): self.frames = kwargs.get("frames") self.frames = float(self.frames) self.fps = kwargs.get("fps") if not self.fps: from pyasm.prod.biz import ProdSetting self.fps = ProdSetting.get_value_by_key("fps") self.fps = int(self.fps) if not self.fps: self.fps = 24 if not self.frames: timecode = kwargs.get("timecode") self.frames = self.calculate_frames(timecode, self.fps) # handle cases where frames has a decimal: ie: 400.4 self.frames = int(float(self.frames))
def show_platform_connection(): """ A short convenience function to check Tactic's Project Settings for a value called show_platform_connection_on_hot_today, which tells the hot list whether or not to display Client-Platform connections as part of Edel's tasks. show_platform_connection_on_hot_today should be a string value set to either 'True' or 'False' (sadly Tactic does not support Boolean values for ProdSettings) :return: Boolean """ # Cast the value to str, just in case it returns None show_platform_connection_string = str(ProdSetting.get_value_by_key('show_platform_connection_on_hot_today')) if show_platform_connection_string.lower() == 'true': return True else: return False
def get_display(my): from pyasm.prod.biz import ProdSetting my.code = str(my.kwargs.get('code')) my.sk = str(my.kwargs.get('sk')) my.movement_code = str(my.kwargs.get('movement_code')) my.source_contexts = ProdSetting.get_value_by_key('source_contexts').split('|') ms = MovementScripts(movement_code=my.movement_code) table = Table() table.add_attr('class','movement_twog_easy_checkin') table.add_attr('width','100%s' % '%') table.add_row() title_bar = table.add_cell('<b><u>Checkin New File</u></b>') title_bar.add_attr('align','center') title_bar.add_attr('colspan','4') title_bar.add_style('font-size: 110%ss' % '%') processes_sel = SelectWdg('source_process_select') for ctx in my.source_contexts: processes_sel.append_option(ctx,ctx) table.add_row() mini0 = Table() mini0.add_row() mini0.add_cell('Checkin Context: ') mini0.add_cell(processes_sel) table.add_cell(mini0) mini1 = Table() mini1.add_row() file_holder = mini1.add_cell(' ') file_holder.add_attr('width','100%s' % '%') file_holder.add_attr('align','center') file_holder.add_attr('class','file_holder') button = mini1.add_cell('<input type="button" value="Browse"/>') button.add_attr('align','right') button.add_style('cursor: pointer;') button.add_behavior(ms.get_easy_checkin_browse_behavior()) big_button = mini1.add_cell('<input type="button" value="Check In" class="easy_checkin_commit" disabled/>') big_button.add_style('cursor: pointer;') big_button.add_behavior(ms.get_easy_checkin_commit_behavior(my.sk)) table.add_cell(mini1) return table
def get_seq_wdg(self): widget = Widget() help = HelpItemWdg('Sequences tab', 'The Sequences tab lets you create sequences which can be used to relate to shots. Each shot has a sequence code attribute which you can assign to.') widget.add(help) div = DivWdg(css='filter_box') search_columns = Sequence.get_search_columns() search_filter = SearchFilterWdg(name="sequence_search", columns=search_columns) div.add(SpanWdg(search_filter, css='med')) search = Search("prod/sequence") search_filter.alter_search(search) widget.add(div) view = 'table' if ProdSetting.get_value_by_key('shot_hierarchy') == 'episode_sequence': view ='table_episode' table = TableWdg("prod/sequence", view) table.set_search(search) widget.add(table) return widget
def get_display(self): task_div = DivWdg(self.label) task_div.add_style("text-align: left") task_div.add_style('margin-left','10px') setting = ProdSetting.get_by_key(self.shot_status_setting) if not setting: BaseAppServer.add_onload_script(IframeWdg.get_popup_script(\ "The Project Setting [%s] is required to be set."%self.shot_status_setting)) return # add a check-all toggle control checkbox_control = CheckboxWdg("sobj_status_control") checkbox_control.add_event("onclick", "get_elements('sobj_status').toggle_all(this);") task_div.add(checkbox_control) checked_all_status = True for status in self.statuses: span = SpanWdg(css="med") checkbox = CheckboxWdg("sobj_status") checkbox.set_persistence() checkbox.set_option("value", status) if checked_all_status and not checkbox.is_checked(): checked_all_status = False span.add(checkbox) span.add(status) task_div.add(span) if checked_all_status: checkbox_control.set_checked() return task_div
def get_display(self): outer_div = DivWdg() outer_div.set_id('new-external-rejection-form') # Set up the <input> widget for 'name' outer_div.add(HtmlElement.label('Name')) name_input = TextInputWdg(name='name') outer_div.add(name_input) root_cause_types = ProdSetting.get_seq_by_key( 'external_rejection_root_cause_types') root_cause_type_wdg = SelectWdg(name='root_cause_type', label='Root Cause Type') root_cause_type_wdg.add_empty_option() for root_cause_type in root_cause_types: root_cause_type_wdg.append_option(root_cause_type, root_cause_type) outer_div.add(root_cause_type_wdg) # TODO: Get this list from the schema, not hard coded video_rejection_reasons = [ ('video_cropping', 'Cropping'), ('video_digital_hits_macroblocking', 'Digital Hits / Macroblocking'), ('video_dropped_frames', 'Dropped Frames'), ('video_dropout', 'Dropout'), ('video_duplicate_frames', 'Duplicate Frames'), ('video_interlacing_on_a_progressive_file', 'Interlacing on a Progressive File'), ('video_motion_image_lag', 'Motion / Image Lag'), ('video_missing_elements', 'Missing Elements'), ('video_corrupt_file', 'Corrupt File'), ('video_incorrect_aspect_ratio', 'Incorrect Aspect Ratio'), ('video_incorrect_resolution', 'Incorrect Resolution'), ('video_incorrect_pixel_aspect_ratio', 'Incorrect Pixel Aspect Ratio'), ('video_incorrect_specifications', 'Incorrect Specifications'), ('video_incorrect_head_tail_format', 'Incorrect Head / Tail Format'), ('video_other', 'Other') ] audio_rejection_reasons = [ ('video_incorrect_audio_mapping', 'Incorrect Audio Mapping'), ('video_missing_audio_channel', 'Missing Audio Channel'), ('video_crackle_hiss_pop_static_ticks', 'Crackle / Hiss / Pop / Static / Ticks'), ('video_distortion', 'Distortion'), ('video_dropouts', 'Dropouts'), ('video_sync_issue', 'Sync Issue'), ('video_missing_elements', 'Missing Elements'), ('video_corrupt_missing_file', 'Corrupt / Missing File'), ('video_incorrect_specifications', 'Incorrect Specifications'), ('video_other', 'Other') ] metadata_rejection_reasons = [ ('metadata_missing_information', 'Missing Information'), ('metadata_incorrect_information', 'Incorrect Information'), ('metadata_incorrect_formatting', 'Incorrect Formatting'), ('metadata_other', 'Other') ] subtitle_rejection_reasons = [ ('subtitle_interlacing_on_subtitles', 'Interlacing on Subtitles'), ('subtitle_incorrect_subtitles', 'Incorrect Subtitles'), ('subtitle_sync_issue', 'Sync Issue'), ('subtitle_overlapping_other_text', 'Overlapping Other Text'), ('subtitle_other', 'Other') ] closed_captions_rejection_reasons = [ ('closed_captions_sync_issue', 'Sync Issue'), ('closed_captions_incorrect_cc', 'Incorrect CC'), ('closed_captions_overlapping_other_text', 'Overlapping Other Text'), ('closed_captions_other', 'Other') ] video_checkbox_table = self.setup_checkboxes_div( 'Video', video_rejection_reasons) audio_checkbox_table = self.setup_checkboxes_div( 'Audio', audio_rejection_reasons) metadata_checkbox_table = self.setup_checkboxes_div( 'MetaData', metadata_rejection_reasons) subtitle_checkbox_table = self.setup_checkboxes_div( 'Subtitles', subtitle_rejection_reasons) closed_captions_checkbox_table = self.setup_checkboxes_div( 'Closed Captions', closed_captions_rejection_reasons) outer_div.add(video_checkbox_table) outer_div.add(audio_checkbox_table) outer_div.add(metadata_checkbox_table) outer_div.add(subtitle_checkbox_table) outer_div.add(closed_captions_checkbox_table) return outer_div
def get_notes_wdg(self): widget = Widget() help = HelpItemWdg( 'Notes tab', 'The Notes tab focuses on the display of notes. It includes both shot notes and submission notes for each shot.' ) widget.add(help) div = DivWdg(css="filter_box") text = TextWdg("shot_search") text.set_persist_on_submit() div.add("Shot Search: ") div.add(text) sequence_filter = SequenceFilterWdg() div.add(sequence_filter) # add Note Context dropdown # scope with config base, also used in DiscussionWdg and SObjectTaskTableElement config_base = 'prod_notes' context_select = ProcessFilterSelectWdg(name="%s_discussion_context" %config_base,\ has_empty=False, search_type='prod/shot', label='Note Context: ' ) context_select.add_empty_option("-- Any Context --") context_select._add_options() setting = "notes_prod_context" values_option = ProdSetting.get_seq_by_key(setting) if not values_option: data_dict = {'key': setting} prod_setting = ProdSetting.get_by_key(setting) ps_id = -1 if prod_setting: ps_id = prod_setting.get_id() context_select._set_append_widget(ps_id, data_dict) labels, values = context_select.get_select_values() if values_option: context_select.append_option('', '') context_select.append_option('<< %s >>' % setting, ','.join(values_option)) for value in values_option: if value not in values: context_select.append_option(value, value) context_select.set_dom_options() div.add(context_select) hint = HintWdg('Submission notes for each shot are also included here') div.add(hint) div.add(IconRefreshWdg(long=False)) search_limit = SearchLimitWdg() div.add(search_limit) widget.add(div) # create a search search = Search("prod/shot") text_value = text.get_value() sequence_filter.alter_search(search) if text_value: filter = Search.get_compound_filter(text_value, ['code', 'description']) search.add_where(filter) search_limit.alter_search(search) sobjects = search.get_sobjects() table = TableWdg("prod/shot", config_base) table.set_class("table") table.set_sobjects(sobjects) widget.add(table) return widget
def get_notes_wdg(self): widget = Widget() help = HelpItemWdg('Notes tab', 'The Notes tab focuses on the display of notes. It includes both shot notes and submission notes for each shot.') widget.add(help) div = DivWdg(css="filter_box") text = TextWdg("shot_search") text.set_persist_on_submit() div.add("Shot Search: ") div.add(text) sequence_filter = SequenceFilterWdg() div.add(sequence_filter) # add Note Context dropdown # scope with config base, also used in DiscussionWdg and SObjectTaskTableElement config_base = 'prod_notes' context_select = ProcessFilterSelectWdg(name="%s_discussion_context" %config_base,\ has_empty=False, search_type='prod/shot', label='Note Context: ' ) context_select.add_empty_option("-- Any Context --") context_select._add_options() setting = "notes_prod_context" values_option = ProdSetting.get_seq_by_key(setting) if not values_option: data_dict = {'key': setting} prod_setting = ProdSetting.get_by_key(setting) ps_id = -1 if prod_setting: ps_id = prod_setting.get_id() context_select._set_append_widget(ps_id, data_dict) labels, values = context_select.get_select_values() if values_option: context_select.append_option('','') context_select.append_option('<< %s >>' %setting, ','.join(values_option)) for value in values_option: if value not in values: context_select.append_option(value, value) context_select.set_dom_options() div.add(context_select) hint = HintWdg('Submission notes for each shot are also included here') div.add(hint) div.add(IconRefreshWdg(long=False)) search_limit = SearchLimitWdg() div.add(search_limit) widget.add(div) # create a search search = Search("prod/shot") text_value = text.get_value() sequence_filter.alter_search(search) if text_value: filter = Search.get_compound_filter(text_value, ['code', 'description']) search.add_where(filter) search_limit.alter_search(search) sobjects = search.get_sobjects() table = TableWdg("prod/shot", config_base) table.set_class("table") table.set_sobjects(sobjects) widget.add(table) return widget
def get_display(self): # just refresh the whole thing widget = DivWdg() outer_widget = DivWdg(css='spt_view_panel') search_div = DivWdg() search_bvr = { 'type': 'click_up', 'cbjs_action': 'spt.dg_table.search_cbk(evt, bvr)', 'override_class_name': 'tactic.ui.cgapp.AppShotPanelWdg', 'override_target': 'bvr.src_el.getParent(".spt_app_shot_panel")', 'extra_args': { 'instance_search_type': self.instance_search_type, 'asset_search_type': self.asset_search_type } #'panel_id': 'main_body_search' } # WARNING: this is made just for main search box and won't be compatible with the simple search wdg search_wdg = SearchWdg(search_type=self.search_type, custom_search_view='search_shot_loader', parent_key='', filter=''\ , display='block', custom_filter_view='', state=None, run_search_bvr=search_bvr) #from tactic.ui.app.simple_search_wdg import SimpleSearchWdg #search_wdg = SimpleSearchWdg(search_type=self.search_type, search_view=self.simple_search_view, state=None, run_search_bvr=search_bvr) search_div.add(HtmlElement.spacer_div(1, 10)) search_div.add(search_wdg) # if there is result, it could only be one shot search = search_wdg.get_search() shots = search.get_sobjects() # avoid getting a shot when no shot is selected if not self.shot_code and len(shots) == 1: self.shot_code = shots[0].get_code() outer_widget.add(search_div) self.set_as_panel( outer_widget, class_name='spt_panel spt_view_panel spt_app_shot_panel') #show_shot_panel = False #if show_shot_panel: panel = ViewPanelWdg( search_type=self.search_type, \ inline_search=True, show_search='false', show_refresh='false', view=self.view, \ run_search_bvr=search_bvr, simple_search_view=self.simple_search_view) panel.set_sobjects(shots) widget.add(panel) show_instances_in_shot = ProdSetting.get_value_by_key( "show_instances_in_shot_panel") if show_instances_in_shot != "false": widget.add( HtmlElement.h3("Asset Instances in Shot [%s]" % self.shot_code)) widget.add(HtmlElement.br(2)) asset_inst_panel = AppAssetInstancePanelWdg( search_type=self.search_type, instance_search_type=self.instance_search_type, asset_search_type=self.asset_search_type, shot_code=self.shot_code, show_search='false') widget.add(asset_inst_panel) outer_widget.add(widget) return outer_widget
# data structure to store my.info my.info = {} # get the file objects if they have not already been cached if not my.file_objects: file_objects = {} snapshot_file_objects = File.get_by_snapshot(snapshot) for file_object in snapshot_file_objects: file_objects[file_object.get_code()] = file_object else: file_objects = my.file_objects protocol = my.get_option("protocol") if not protocol: from pyasm.prod.biz import ProdSetting protocol = ProdSetting.get_value_by_key('thumbnail_protocol') # go through the nodes and try to find appropriate paths my.info = ThumbWdg.get_file_info(xml, file_objects, sobject, snapshot, my.show_versionless, protocol=protocol) # find the link that will be used when clicking on the icon link_path = ThumbWdg.get_link_path(my.info, image_link_order=my.image_link_order) if link_path == None: # check for ref snapshot snapshots = snapshot.get_all_ref_snapshots() snapshot_file_objects = [] if snapshots: snapshot = snapshots[0] # change the sobject value here also, affects the Thumb id below sobject = snapshot.get_sobject()
def _get_display(my): login = WebContainer.get_login() login_name = login.get_login() web = WebContainer.get_web() context = web.get_site_context_url() div = HtmlElement.div() div.set_style("top: 0px; margin: 1.6em 0 2em 0; height: 4em") project = Project.get() if not my.title: my.title = project.get_value('title') title_data = HtmlElement.h4(my.title) link_width = '400' if web.get_app_name() != 'Browser': link_width = '240' title_data.add_class('app') control = DivWdg() control.set_style("position: absolute; float: right; top: 1px; right: 2px") help_menu = HelpMenuWdg() control.add(FloatDivWdg(help_menu, width=30)) div.add(help_menu.get_panel()) span = SpanWdg('[%s]' %project.get_code(), css='med hand') span.add_style("float: left") script = "Common.follow_click(event, '%s', 10, 0); set_display_on('%s');"\ "Common.overlay_setup('mouseup',function(){%s})"\ %(ProjectSwitchWdg.WDG_ID, ProjectSwitchWdg.WDG_ID, \ ProjectSwitchWdg.get_off_script()) span.add_event('onclick', script) control.add(span) div.add(ProjectSwitchWdg()) root = web.get_site_root() #span = SpanWdg(HtmlElement.href(ref='/%s' % root, data='[home]'), css='med') #span.add_style("float: left") #control.add(span) span = SpanWdg(HtmlElement.href(ref='/doc/', data='[docs]', target='_blank'), css='med') span.add_style("float: left") control.add(span) from pyasm.prod.biz import ProdSetting project_docs = ProdSetting.get_value_by_key("project_docs_url") if project_docs: project_code = Project.get_project_code() span = SpanWdg(HtmlElement.href(ref=project_docs, data='[%s-docs]' % project_code, target='_blank'), css='med') span.add_style("float: left") control.add(span) app_name = web.get_app_name() if app_name != 'Browser': span = SpanWdg(HtmlElement.href(ref='%s/%s'\ %(context.to_string(), app_name), data='[app]'), css='med') span.add_style("float: left") control.add(span) import urllib params = web.request.params edited_params = {} for name, value in params.items(): if name in ['marshalled', 'password', 'login']: continue if type(value) == types.ListType: if len(value) == 1: value = value[0] if isinstance(value, cgi.FieldStorage): continue if not value: continue edited_params[name] = value query_string = urllib.urlencode(edited_params, doseq=True) site_url = web.get_site_context_url().to_string() url = "%s?%s" % (site_url, query_string) span = SpanWdg() span.add_style("float: left") link = HtmlElement.href(ref=url, data='[link]') span.add(link) control.add(span) span = SpanWdg("user: "******"float: right") clipboard_div.add(clipboard) div.add(clipboard_div) skin = WebContainer.get_web().get_skin() if skin == "classic": title_div = DivWdg() title_div.add_style('width', '800px') link = HtmlElement.href(data=title_data, ref='%s/' %context.to_string()) link_div = FloatDivWdg(link, width=link_width, css='left_content') title_div.add(link_div) if not web.is_IE(): trail_div = my.get_trail() title_div.add(trail_div) title_div.add(HtmlElement.br()) div.add(title_div) else: my.add_logo(div, skin) return div
def _process_image(my, file_name): base, ext = os.path.splitext(file_name) # get all of the extensions exts = File.get_extensions(file_name) frame = 0 if len(exts) == 2: try: frame = int(exts[0]) base = base.replace(".%s" % exts[0], '' ) except ValueError: frame = 0 if frame: icon_file_name = "%s_icon.%s.png" % (base, exts[0]) web_file_name = "%s_web.%s.jpg" % (base, exts[0]) else: 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) # create the web image try: if my.texture_mode: my._resize_texture(my.file_path, tmp_web_path, 0.5) my.web_path = tmp_web_path # create the icon thumb_size = (120,100) my._resize_image(tmp_web_path, tmp_icon_path, thumb_size) my.icon_path = tmp_icon_path elif my.icon_mode: # just icon, no web # create the icon only thumb_size = (120,100) my._resize_image(my.file_path, tmp_icon_path, thumb_size) my.icon_path = tmp_icon_path else: from pyasm.prod.biz import ProdSetting web_file_size = ProdSetting.get_value_by_key('web_file_size') thumb_size = (640, 480) if web_file_size: parts = re.split('[\Wx]+', web_file_size) thumb_size = (640, 480) if len(parts) == 2: try: thumb_size = (int(parts[0]), int(parts[1])) except ValueError: thumb_size = (640, 480) my._resize_image(my.file_path, tmp_web_path, thumb_size) my.web_path = tmp_web_path # create the icon thumb_size = (120,100) my._resize_image(tmp_web_path, tmp_icon_path, thumb_size) my.icon_path = tmp_icon_path # check icon file size, reset to none if it is empty # TODO: use finally in Python 2.5 if my.web_path: web_path_size = os.stat(my.web_path)[stat.ST_SIZE] if not web_path_size: my.web_path = None if my.icon_path: icon_path_size = os.stat(my.icon_path)[stat.ST_SIZE] if not icon_path_size: my.icon_path = None except IOError, e: Environment.add_warning("Could not process file", \ "%s - %s" % (my.file_path, e.__str__())) my.web_path = None my.icon_path = None
def get_custom_setting(my, key): from pyasm.biz import ProdSetting value = ProdSetting.get_value_by_key(key) return value
def add_default_ending(my, parts, auto_version=True, is_sequence=True): context = my.snapshot.get_value("context") filename = my.file_object.get_full_file_name() # make sure that the version in the file name does not yet exist version = my.get_version_from_file_name(filename) if not auto_version and version: # if the file version is not the same as the snapshot version # then check to see if the snapshot already exists if version != my.snapshot.get_value("version"): existing_snap = Snapshot.get_by_version(my.snapshot.get_value("search_type"),\ my.snapshot.get_value("search_id"), context, version) if existing_snap: raise TacticException('A snapshot with context "%s" and version "%s" already exists.' % (context, version) ) my.snapshot.set_value("version", version) my.snapshot.commit() else: version = my.snapshot.get_value("version") if version == 0: version = "CURRENT" elif version == -1: version = "LATEST" else: if version == "": version = 1 # pad the version by by the global setting padding = Config.get_value("checkin", "version_padding") if not padding: padding = 3 else: padding = int(padding) expr = "v%%0.%sd" % padding version = expr % version revision = my.snapshot.get_value("revision", no_exception=True) if revision: revision = "r%0.2d" % revision ext = my.get_ext() # by default publish is not put into the file name if context != "publish": parts.append(context.replace("/", "_")) # add the server location #value = ProdSetting.get_value_by_key("naming/add_server") server = Config.get_value("install", "server") if server: parts.append(server) if my.is_tactic_repo(): parts.append(version) if revision: parts.append(revision) from pyasm.prod.biz import ProdSetting value = ProdSetting.get_value_by_key("naming/add_initials") if value == "false": project = Project.get() initials = Project.get().get_initials() parts.append(initials) filename = "_".join(parts) if is_sequence: filename = "%s.####.%s" % (filename, ext) elif ext: # dir don't need extension filename = "%s%s" % (filename, ext) return filename
def add_default_ending(my, parts, auto_version=True, is_sequence=True): context = my.snapshot.get_value("context") filename = my.file_object.get_full_file_name() # make sure that the version in the file name does not yet exist version = my.get_version_from_file_name(filename) if not auto_version and version: # if the file version is not the same as the snapshot version # then check to see if the snapshot already exists if version != my.snapshot.get_value("version"): existing_snap = Snapshot.get_by_version(my.snapshot.get_value("search_type"),\ my.snapshot.get_value("search_id"), context, version) if existing_snap: raise TacticException( 'A snapshot with context "%s" and version "%s" already exists.' % (context, version)) my.snapshot.set_value("version", version) my.snapshot.commit() else: version = my.snapshot.get_value("version") if version == 0: version = "CURRENT" elif version == -1: version = "LATEST" else: if version == "": version = 1 # pad the version by by the global setting padding = Config.get_value("checkin", "version_padding") if not padding: padding = 3 else: padding = int(padding) expr = "v%%0.%sd" % padding version = expr % version revision = my.snapshot.get_value("revision", no_exception=True) if revision: revision = "r%0.2d" % revision ext = my.get_ext() # by default publish is not put into the file name if context != "publish": parts.append(context.replace("/", "_")) # add the server location #value = ProdSetting.get_value_by_key("naming/add_server") server = Config.get_value("install", "server") if server: parts.append(server) if my.is_tactic_repo(): parts.append(version) if revision: parts.append(revision) from pyasm.prod.biz import ProdSetting value = ProdSetting.get_value_by_key("naming/add_initials") if value == "false": project = Project.get() initials = Project.get().get_initials() parts.append(initials) filename = "_".join(parts) if is_sequence: filename = "%s.####.%s" % (filename, ext) elif ext: # dir don't need extension filename = "%s%s" % (filename, ext) return filename
img.add_class("spt_image") # TODO: make this a preference img.add_style("background: #ccc") if type(icon_size) == types.StringType and icon_size.endswith("%"): img.add_style("%s: 100%%" % my.aspect) else: img.add_style("%s: %spx" % (my.aspect, icon_size) ) detail = my.get_option("detail") protocol = my.get_option("protocol") if not protocol: from pyasm.prod.biz import ProdSetting protocol = ProdSetting.get_value_by_key('thumbnail_protocol') if detail == "false": if my.has_img_link: if protocol =='file': dir_naming = DirNaming() client_base_dir = dir_naming.get_base_dir('client_repo') web_base_dir = Config.get_value("checkin", "web_base_dir") link_path = re.sub('^%s'%web_base_dir,'', link_path) link_path = '%s%s' %(client_base_dir[0], link_path) href = DivWdg(img) href.add_attr('title', 'Click to open via file system') href.add_behavior({'type':'click' , 'cbjs_action': "spt.Applet.get().open_explorer('%s')" %link_path})
def __init__(my, name="sobj_status", shot_status_setting="shot_status"): my.shot_status_setting = shot_status_setting my.statuses = ProdSetting.get_seq_by_key(my.shot_status_setting) super(SObjectStatusFilterWdg,my).__init__(name) my.set_persistence() my.label = "Shot Status Filter: "
def get_display(self): outer_div = DivWdg() outer_div.set_id('new-external-rejection-form') # Set up the <input> widget for 'name' outer_div.add(HtmlElement.label('Name')) name_input = TextInputWdg(name='name') outer_div.add(name_input) root_cause_types = ProdSetting.get_seq_by_key('external_rejection_root_cause_types') root_cause_type_wdg = SelectWdg(name='root_cause_type', label='Root Cause Type') root_cause_type_wdg.add_empty_option() for root_cause_type in root_cause_types: root_cause_type_wdg.append_option(root_cause_type, root_cause_type) outer_div.add(root_cause_type_wdg) # TODO: Get this list from the schema, not hard coded video_rejection_reasons = [ ('video_cropping', 'Cropping'), ('video_digital_hits_macroblocking', 'Digital Hits / Macroblocking'), ('video_dropped_frames', 'Dropped Frames'), ('video_dropout', 'Dropout'), ('video_duplicate_frames', 'Duplicate Frames'), ('video_interlacing_on_a_progressive_file', 'Interlacing on a Progressive File'), ('video_motion_image_lag', 'Motion / Image Lag'), ('video_missing_elements', 'Missing Elements'), ('video_corrupt_file', 'Corrupt File'), ('video_incorrect_aspect_ratio', 'Incorrect Aspect Ratio'), ('video_incorrect_resolution', 'Incorrect Resolution'), ('video_incorrect_pixel_aspect_ratio', 'Incorrect Pixel Aspect Ratio'), ('video_incorrect_specifications', 'Incorrect Specifications'), ('video_incorrect_head_tail_format', 'Incorrect Head / Tail Format'), ('video_other', 'Other') ] audio_rejection_reasons = [ ('video_incorrect_audio_mapping', 'Incorrect Audio Mapping'), ('video_missing_audio_channel', 'Missing Audio Channel'), ('video_crackle_hiss_pop_static_ticks', 'Crackle / Hiss / Pop / Static / Ticks'), ('video_distortion', 'Distortion'), ('video_dropouts', 'Dropouts'), ('video_sync_issue', 'Sync Issue'), ('video_missing_elements', 'Missing Elements'), ('video_corrupt_missing_file', 'Corrupt / Missing File'), ('video_incorrect_specifications', 'Incorrect Specifications'), ('video_other', 'Other') ] metadata_rejection_reasons = [ ('metadata_missing_information', 'Missing Information'), ('metadata_incorrect_information', 'Incorrect Information'), ('metadata_incorrect_formatting', 'Incorrect Formatting'), ('metadata_other', 'Other') ] subtitle_rejection_reasons = [ ('subtitle_interlacing_on_subtitles', 'Interlacing on Subtitles'), ('subtitle_incorrect_subtitles', 'Incorrect Subtitles'), ('subtitle_sync_issue', 'Sync Issue'), ('subtitle_overlapping_other_text', 'Overlapping Other Text'), ('subtitle_other', 'Other') ] closed_captions_rejection_reasons = [ ('closed_captions_sync_issue', 'Sync Issue'), ('closed_captions_incorrect_cc', 'Incorrect CC'), ('closed_captions_overlapping_other_text', 'Overlapping Other Text'), ('closed_captions_other', 'Other') ] video_checkbox_table = self.setup_checkboxes_div('Video', video_rejection_reasons) audio_checkbox_table = self.setup_checkboxes_div('Audio', audio_rejection_reasons) metadata_checkbox_table = self.setup_checkboxes_div('MetaData', metadata_rejection_reasons) subtitle_checkbox_table = self.setup_checkboxes_div('Subtitles', subtitle_rejection_reasons) closed_captions_checkbox_table = self.setup_checkboxes_div('Closed Captions', closed_captions_rejection_reasons) outer_div.add(video_checkbox_table) outer_div.add(audio_checkbox_table) outer_div.add(metadata_checkbox_table) outer_div.add(subtitle_checkbox_table) outer_div.add(closed_captions_checkbox_table) return outer_div
def _get_display(self): login = WebContainer.get_login() login_name = login.get_login() web = WebContainer.get_web() context = web.get_site_context_url() div = HtmlElement.div() div.set_style("top: 0px; margin: 1.6em 0 2em 0; height: 4em") project = Project.get() if not self.title: self.title = project.get_value('title') title_data = HtmlElement.h4(self.title) link_width = '400' if web.get_app_name() != 'Browser': link_width = '240' title_data.add_class('app') control = DivWdg() control.set_style( "position: absolute; float: right; top: 1px; right: 2px") help_menu = HelpMenuWdg() control.add(FloatDivWdg(help_menu, width=30)) div.add(help_menu.get_panel()) span = SpanWdg('[%s]' % project.get_code(), css='med hand') span.add_style("float: left") script = "Common.follow_click(event, '%s', 10, 0); set_display_on('%s');"\ "Common.overlay_setup('mouseup',function(){%s})"\ %(ProjectSwitchWdg.WDG_ID, ProjectSwitchWdg.WDG_ID, \ ProjectSwitchWdg.get_off_script()) span.add_event('onclick', script) control.add(span) div.add(ProjectSwitchWdg()) root = web.get_site_root() #span = SpanWdg(HtmlElement.href(ref='/%s' % root, data='[home]'), css='med') #span.add_style("float: left") #control.add(span) span = SpanWdg(HtmlElement.href(ref='/doc/', data='[docs]', target='_blank'), css='med') span.add_style("float: left") control.add(span) from pyasm.prod.biz import ProdSetting project_docs = ProdSetting.get_value_by_key("project_docs_url") if project_docs: project_code = Project.get_project_code() span = SpanWdg(HtmlElement.href(ref=project_docs, data='[%s-docs]' % project_code, target='_blank'), css='med') span.add_style("float: left") control.add(span) app_name = web.get_app_name() if app_name != 'Browser': span = SpanWdg(HtmlElement.href(ref='%s/%s'\ %(context.to_string(), app_name), data='[app]'), css='med') span.add_style("float: left") control.add(span) import urllib params = web.request.params edited_params = {} for name, value in params.items(): if name in ['marshalled', 'password', 'login']: continue if type(value) == types.ListType: if len(value) == 1: value = value[0] if isinstance(value, cgi.FieldStorage): continue if not value: continue edited_params[name] = value query_string = urllib.urlencode(edited_params, doseq=True) site_url = web.get_site_context_url().to_string() url = "%s?%s" % (site_url, query_string) span = SpanWdg() span.add_style("float: left") link = HtmlElement.href(ref=url, data='[link]') span.add(link) control.add(span) span = SpanWdg("user: "******"float: right") clipboard_div.add(clipboard) div.add(clipboard_div) skin = WebContainer.get_web().get_skin() if skin == "classic": title_div = DivWdg() title_div.add_style('width', '800px') link = HtmlElement.href(data=title_data, ref='%s/' % context.to_string()) link_div = FloatDivWdg(link, width=link_width, css='left_content') title_div.add(link_div) if not web.is_IE(): trail_div = self.get_trail() title_div.add(trail_div) title_div.add(HtmlElement.br()) div.add(title_div) else: self.add_logo(div, skin) return div
def __init__(self, name="sobj_status", shot_status_setting="shot_status"): self.shot_status_setting = shot_status_setting self.statuses = ProdSetting.get_seq_by_key(self.shot_status_setting) super(SObjectStatusFilterWdg, self).__init__(name) self.set_persistence() self.label = "Shot Status Filter: "
def __init__(self, name="sobj_status", shot_status_setting="shot_status"): self.shot_status_setting = shot_status_setting self.statuses = ProdSetting.get_seq_by_key(self.shot_status_setting) super(SObjectStatusFilterWdg,self).__init__(name) self.set_persistence() self.label = "Shot Status Filter: "
def __init__(my, name="sobj_status", shot_status_setting="shot_status"): my.shot_status_setting = shot_status_setting my.statuses = ProdSetting.get_seq_by_key(my.shot_status_setting) super(SObjectStatusFilterWdg, my).__init__(name) my.set_persistence() my.label = "Shot Status Filter: "