def execute(self): left_cb_name, right_cb_name = self.get_checkbox_names() web = WebContainer.get_web() right_search_keys = web.get_form_values(right_cb_name) if not right_search_keys: return right_sobjects = [] for right_search_key in right_search_keys: right_sobject = Search.get_by_search_key(right_search_key) right_sobjects.append(right_sobject) search_type = self.get_search_type() left_search_keys = web.get_form_values(left_cb_name) for left_search_key in left_search_keys: left_sobject = Search.get_by_search_key(left_search_key) for right_sobject in right_sobjects: #instance_name = "%s" % right_sobject.get_value("name") left_foreign_key = left_sobject.get_foreign_key() right_foreign_key = right_sobject.get_foreign_key() instance = SObjectFactory.create(search_type) instance.set_value(left_foreign_key, left_sobject.get_code()) instance.set_value(right_foreign_key, right_sobject.get_code()) name = left_sobject.get_code() instance.set_value("name", name) instance.commit()
def create(sobject, value, prev_value=None): if prev_value == value: return # if this is successful, the store it in the status_log search_type = sobject.get_search_type() search_id = sobject.get_id() search_code = sobject.get_value("code") status_log = SObjectFactory.create("sthpw/status_log") status_log.set_value("login", Environment.get_user_name() ) status_log.set_sobject_value(sobject) #status_log.set_value("search_type", search_type) #status_log.set_value("search_code", search_id, no_exception=True) #status_log.set_value("search_id", search_code, no_exception=True) if prev_value: status_log.set_value("from_status", prev_value) status_log.set_value("to_status", value) project_code = Project.get_project_name() status_log.set_value("project_code", project_code) status_log.commit() return status_log
def execute(self): left_cb_name , right_cb_name = self.get_checkbox_names() web = WebContainer.get_web() right_search_keys = web.get_form_values(right_cb_name) if not right_search_keys: return right_sobjects = [] for right_search_key in right_search_keys: right_sobject = Search.get_by_search_key(right_search_key) right_sobjects.append(right_sobject) search_type = self.get_search_type() left_search_keys = web.get_form_values(left_cb_name) for left_search_key in left_search_keys: left_sobject = Search.get_by_search_key( left_search_key ) for right_sobject in right_sobjects: #instance_name = "%s" % right_sobject.get_value("name") left_foreign_key = left_sobject.get_foreign_key() right_foreign_key = right_sobject.get_foreign_key() instance = SObjectFactory.create(search_type) instance.set_value(left_foreign_key, left_sobject.get_code() ) instance.set_value(right_foreign_key, right_sobject.get_code() ) name = left_sobject.get_code() instance.set_value("name", name) instance.commit()
def execute(my): web = WebContainer.get_web() if web.get_form_value("Register") == "": raise CommandExitException() # hard code this to tasks for now search_type = "sthpw/task" info = {} for key in web.get_form_keys(): # filter out unwanted keys if not key.startswith("timecard|"): continue value = web.get_form_value(key) if value == "": continue tmp, search_id, col = key.split("|") if not info.has_key(search_id): info[search_id] = [] info[search_id].append((col, value)) for search_id, values in info.items(): timecard = SObjectFactory.create("sthpw/timecard") timecard.set_value("search_type", search_type) timecard.set_value("search_id", search_id) for value in values: timecard.set_value(value[0], value[1]) timecard.commit()
def _create_timecard(my, search_type, search_id): '''create an entry in the timecard table''' timecard = SObjectFactory.create("sthpw/timecard") timecard.set_value("search_type", search_type) timecard.set_value("search_id", search_id) timecard.set_value('login', Environment.get_user_name()) timecard.set_value('project_code', Project.get_project_name()) return timecard
def create_grouping(self, item_value, container_value): grouping = self._get_existing_grouping(item_value, container_value) if grouping: return grouping sobject = SObjectFactory.create(self.grouping_search_type) sobject.set_value(self.item_foreign_key, item_value) sobject.set_value(self.container_foreign_key, container_value) sobject.commit() return sobject
def create_grouping(my, item_value, container_value): grouping = my._get_existing_grouping(item_value, container_value) if grouping: return grouping sobject = SObjectFactory.create( my.grouping_search_type ) sobject.set_value( my.item_foreign_key, item_value) sobject.set_value( my.container_foreign_key, container_value) sobject.commit() return sobject
def execute(self): web = WebContainer.get_web() # get the input names input_names = web.get_form_value( SerialStatusWdg.STATUS_CMD_INPUT).split('|') values = [] for input_name in input_names: value = web.get_form_value(input_name) if value: values.append(web.get_form_value(input_name)) # FIXME: HARDCODED Value for status column!!!! column = "status" for value in values: # get the sobject to be updated search_type, id, status = value.split("|") search = Search(search_type) search.add_id_filter(id) self.sobject = search.get_sobject() status_attr = self.sobject.get_attr(column) cur_status = status_attr.get_current_process() if cur_status == status: continue status_attr.set_status(status) update_column = 'time_update' if update_column in self.sobject.get_attr_names(): self.sobject.set_value(update_column, Sql.get_timestamp_now(), quoted=False) self.sobject.commit() # if this is successful, the store it in the status_log status_log = SObjectFactory.create("sthpw/status_log") status_log.set_value("login", Environment.get_user_name()) status_log.set_value("search_type", search_type) status_log.set_value("search_id", id) #status_log.set_value("status", "%s to %s" % (cur_status, status) ) status_log.commit() status_log.set_value("from_status", cur_status) status_log.set_value("to_status", status) # Call the finaled trigger Trigger.call(self, status)
def execute(my): web = WebContainer.get_web() # get the input names input_names = web.get_form_value(SerialStatusWdg.STATUS_CMD_INPUT).split('|') values = [] for input_name in input_names: value = web.get_form_value(input_name) if value: values.append(web.get_form_value(input_name)) # FIXME: HARDCODED Value for status column!!!! column = "status" for value in values: # get the sobject to be updated search_type,id,status = value.split("|") search = Search(search_type) search.add_id_filter(id) my.sobject = search.get_sobject() status_attr = my.sobject.get_attr(column) cur_status = status_attr.get_current_process() if cur_status == status: continue status_attr.set_status(status) update_column = 'time_update' if update_column in my.sobject.get_attr_names(): my.sobject.set_value(update_column, Sql.get_timestamp_now(), quoted=False) my.sobject.commit() # if this is successful, the store it in the status_log status_log = SObjectFactory.create("sthpw/status_log") status_log.set_value("login", Environment.get_user_name() ) status_log.set_value("search_type", search_type) status_log.set_value("search_id", id) #status_log.set_value("status", "%s to %s" % (cur_status, status) ) status_log.commit() status_log.set_value("from_status", cur_status) status_log.set_value("to_status", status) # Call the finaled trigger Trigger.call(my, status)
def check(my): # make this a callback for now my.init() # check for required columns sobj = SObjectFactory.create(my.search_type) required_columns = sobj.get_required_columns() for required in required_columns: if required in my.columns: continue else: raise UserException('Missing required column [%s] in the input CSV' % required) return True
def execute_slave(self, command): import socket, xmlrpclib, pickle, time pickled = pickle.dumps(command) queue = SObjectFactory.create("sthpw/queue") queue.set_value("queue", "render") queue.set_value("state", "pending") queue.set_value("command", command.__class__.__name__) queue.set_value("serialized", pickled) queue.set_value("priority", "AAA") queue.set_value("description", self.description) queue.set_user() queue.commit()
def postprocess(self): sobject = self.sobject if not sobject.is_insert(): return processes = ["layout", "animation", "lighting"] # create a bunch of tasks for process in processes: task = SObjectFactory.create("sthpw/task") task.set_value("description", process) task.set_value("process", process) task.set_sobject_value(sobject) task.commit()
def log_exception(my, exception): import sys,traceback tb = sys.exc_info()[2] stacktrace = traceback.format_tb(tb) stacktrace_str = "".join(stacktrace) print "-"*50 print stacktrace_str print str(exception) print "-"*50 user_name = Environment.get_user_name() exception_log = SObjectFactory.create("sthpw/exception_log") exception_log.set_value("login", user_name) exception_log.set_value("class", exception.__class__.__name__) exception_log.set_value("message", str(exception) ) exception_log.set_value("stack_trace", stacktrace_str) exception_log.commit() del tb, stacktrace
def execute(my): web = WebContainer.get_web() if web.get_form_value("Register") == "": raise CommandExitException() # hard code this to tasks for now search_type = "sthpw/task" info = {} for key in web.get_form_keys(): # filter out unwanted keys if not key.startswith("timecard|"): continue value = web.get_form_value(key) if value == "": continue tmp, search_id, col = key.split("|") if not info.has_key(search_id): info[search_id] = [] info[search_id].append( (col,value) ) for search_id, values in info.items(): timecard = SObjectFactory.create("sthpw/timecard") timecard.set_value("search_type", search_type) timecard.set_value("search_id", search_id) for value in values: timecard.set_value(value[0],value[1]) timecard.commit()
def log(cls, level, message, category="default"): assert level in ("critical", "error", "warning", "info", "debug") # record the exception user_name = Environment.get_user_name() if not user_name: user_name = "UNKNOWN" # put the debug in a completely separate transaction from the main # transaction transaction = Transaction.get(force=True) transaction.set_record(False) debug_log = SObjectFactory.create("sthpw/debug_log") debug_log.set_value("login", user_name) debug_log.set_value("level", level) debug_log.set_value("category", category) debug_log.set_value("message", message ) debug_log.commit() transaction.commit() transaction.remove_from_stack() return debug_log
def log(cls, level, message, category="default"): assert level in ("critical", "error", "warning", "info", "debug") # record the exception user_name = Environment.get_user_name() if not user_name: user_name = "UNKNOWN" # put the debug in a completely separate transaction from the main # transaction transaction = Transaction.get(force=True) transaction.set_record(False) debug_log = SObjectFactory.create("sthpw/debug_log") debug_log.set_value("login", user_name) debug_log.set_value("level", level) debug_log.set_value("category", category) debug_log.set_value("message", message) debug_log.commit() transaction.commit() transaction.remove_from_stack() return debug_log
def execute(my): web = WebContainer.get_web() if not web.get_form_value("Insert/Next") and not web.get_form_value("Insert/Exit"): return search_type = web.get_form_value("search_type") view = web.get_form_value("view") project = web.get_form_value("project") name = web.get_form_value("new_custom_name") if not name: raise TacticException("No name specified") type = web.get_form_value("new_custom_type") description = web.get_form_value("new_description") add_to_current_view = web.get_form_value("add_to_current_view") add_to_edit_view = web.get_form_value("add_to_edit_view") assert search_type if not view: view = get_template_view() # create the column cmd = ColumnAddCmd(search_type, name, type) cmd.execute() # create the type class_name = None options = {} edit_class_name = None edit_options = {} if type == "Date Range": class_name = "GanttWdg" options["start_date_column"] = "%s_start_date" % name options["end_date_column"] = "%s_end_date" % name elif type == "Date": class_name = "DateWdg" edit_class_name = "CalendarWdg" elif type == "Checkbox": class_name = "CheckTableElementWdg" edit_class_name = "CheckboxWdg" elif type == "Foreign Key": class_name = "" edit_class_name = "SelectWdg" foreign_search_type = web.get_form_value("foreign_key_search_select") edit_options["query"] = '%s|code|code' % foreign_search_type elif type == "List": class_name = "" edit_class_name = "SelectWdg" list_values = web.get_form_value("list_values") edit_options['values'] = list_values # get the config file if add_to_current_view: config = WidgetDbConfig.get_by_search_type(search_type, view) if not config: config = WidgetDbConfig.create(search_type, view) config.append_display_element(name) config.commit_config() # handle the "default" view view = DEFAULT_VIEW config = WidgetDbConfig.get_by_search_type(search_type, view) if not config: config = WidgetDbConfig.create(search_type, view) config.append_display_element(name, class_name, options) config.commit_config() # handle the "edit" if add_to_edit_view and view != "edit": config = WidgetDbConfig.get_by_search_type(search_type, "edit") if not config: config = WidgetDbConfig.create(search_type, "edit") config.append_display_element(name, edit_class_name, edit_options) config.commit_config() # create the sobject for now sobject = SObjectFactory.create("prod/custom_property") sobject.set_value("search_type", search_type) sobject.set_value("name", name) sobject.set_value("description", description) sobject.commit() my.description = "Added Property [%s] of type [%s] to [%s]" % \ (name, type, search_type)
class PreviewDataWdg(BaseRefreshWdg): def init(my): my.is_refresh = my.kwargs.get('is_refresh') my.file_path = my.kwargs.get('file_path') my.search_type = my.kwargs.get('search_type') my.search_type_obj = SearchType.get(my.search_type) web = WebContainer.get_web() my.encoder = web.get_form_value('encoder') title_row_checkbox = CheckboxWdg("has_title") my.has_title = title_row_checkbox.is_checked() lowercase_title_checkbox = CheckboxWdg("lowercase_title") my.lowercase_title = lowercase_title_checkbox.is_checked() def get_column_preview(my, div): # parse the first fow csv_parser = CsvParser(my.file_path) if my.has_title: csv_parser.set_has_title_row(True) else: csv_parser.set_has_title_row(False) if my.lowercase_title: csv_parser.set_lowercase_title(True) if my.encoder: csv_parser.set_encoder(my.encoder) try: csv_parser.parse() # that can be all kinds of encoding/decoding exception except Exception, e: # possibly incompatible encoder selected, use the default instead. # Let the user pick it. span = SpanWdg('WARNING: The selected encoder is not compatible with your csv file. Please choose the proper one (e.g. UTF-8). Refer to the documentation/tutorial on how to save your csv file with UTF-8 encoding if you have special characters in it.', css='warning') div.add(SpanWdg(e.__str__())) div.add(HtmlElement.br()) div.add(span, 'warning') return div csv_titles = csv_parser.get_titles() # for 2nd guess of similar column titles processed_csv_titles = [x.replace(' ', '_').lower() for x in csv_titles] csv_data = csv_parser.get_data() web = WebContainer.get_web() data_row = web.get_form_value('data_row') if not csv_data: div.add(SpanWdg('Your csv file seems to be empty', css='warning')) return div if not data_row: data_row = 0 else: try: data_row = int(data_row) data_row -= 1 except ValueError: data_row = 0 if data_row >= len(csv_data): data_row = len(csv_data)-1 #data_row_text.set_value(data_row) div.add( IconWdg("Important", IconWdg.CREATE) ) div.add("Use the sample row to match which columns the data will be imported into TACTIC<br/><br/>") table = Table(css='spt_csv_table') table.add_color('background','background') table.add_color('color','color') table.set_attr("cellpadding", "7") table.set_attr("border", "1") table.add_row() cb = CheckboxWdg('csv_row') cb.set_default_checked() js = ''' var cbs = bvr.src_el.getParent('.spt_csv_table').getElements('.spt_csv_row'); for (i=0; i < cbs.length; i++){ if (!cbs[i].getAttribute('special')) cbs[i].checked = bvr.src_el.checked; }''' cb.add_behavior({'type': 'click_up', 'propagate_evt': True, 'cbjs_action': js}) th = table.add_header(cb) th.add_gradient("background", "background") th = table.add_header("CSV Column Value") th.add_gradient("background", "background") th.add_class('smaller') th = table.add_header("TACTIC Column") th.add_gradient("background", "background") th.add_class('smaller') th = table.add_header("Create New Column") th.add_style('min-width: 100px') th.add_gradient("background", "background") th.add_class('smaller') columns = SearchType.get_columns(my.search_type) sobj = SObjectFactory.create(my.search_type) required_columns = sobj.get_required_columns() row = csv_data[data_row] labels = [] my.num_columns = len(row) hidden = HiddenWdg("num_columns", my.num_columns) div.add(hidden) for column in columns: if column in required_columns: label = '%s**'%column else: label = column labels.append(label) columns.append("(note)") labels.append("(Note)") skipped_columns = [] new_col_indices = [] for j, cell in enumerate(row): # skip extra empty title if j >= len(csv_titles): skipped_columns.append(str(j)) continue column_select = SelectWdg("column_%s" % j) is_new_column = True use_processed = False # only set the value if it is actually in there if csv_titles[j] in columns: column_select.set_option("default", csv_titles[j]) is_new_column = False elif processed_csv_titles[j] in columns: column_select.set_option("default", processed_csv_titles[j]) is_new_column = False use_processed = True sel_val = column_select.get_value() table.add_row() cb = CheckboxWdg('column_enabled_%s' %j) cb.set_default_checked() #cb.set_persistence() cb.set_persist_on_submit() cb.add_class('spt_csv_row') # disable the id column by default if csv_titles[j] in columns and csv_titles[j] == 'id': cb.set_option('special','true') cb.add_behavior({'type':'click_up', #'propagate_evt': True, 'cbjs_action': '''spt.alert('The id column is not meant to be imported. It can only be chosen as an Identifying Column for update purpose.'); bvr.src_el.checked = false;'''}) else: # if it is not a new column, and column selected is empty, we don't select the checkbox by default if sel_val != '' or is_new_column or not my.is_refresh: cb.set_default_checked() table.add_cell(cb) td = table.add_cell(cell) # this is an optimal max width td.add_style('max-width: 600px') column_select.add_behavior({'type': "change", 'cbjs_action': '''if (bvr.src_el.value !='') { set_display_off('new_column_div_%s'); } else { set_display_on('new_column_div_%s') }; spt.panel.refresh('preview_data', spt.api.Utility.get_input_values('csv_import_main')); '''% (j,j)}) column_select.add_empty_option("(New Column)") column_select.set_persist_on_submit() column_select.set_option("values", columns) column_select.set_option("labels", labels) display = column_select.get_buffer_display() td = table.add_cell( display ) if csv_titles[j] != 'id': if my.is_refresh: if sel_val != '': td.add_color('background','background2') else: if not is_new_column: td.add_color('background','background2') #if is_new_column: if True: # this star is not necessary, and could be misleading if one checks off Use TItle Row #td.add(" <b style='color: red'>*</b>") # new property new_column_div = DivWdg() if sel_val: new_column_div.add_style("display", "none") else: new_column_div.add_style("display", "block") new_column_div.set_id("new_column_div_%s" % j) td = table.add_cell( new_column_div ) if sel_val == '': td.add_color('background','background2') new_col_indices.append(j) text = TextWdg("new_column_%s" % j) text.add_style('border-color: #8DA832') text.set_persist_on_submit() if my.has_title: if use_processed: new_title = processed_csv_titles[j] else: new_title = csv_titles[j] text.set_value(new_title) # prefer to use bg color instead of OR to notify which one is used """ or_span = SpanWdg(" OR ", css='med') or_span.add_color('color','color') new_column_div.add(or_span) """ new_column_div.add( text ) if skipped_columns: div.add(SpanWdg('WARNING: Some titles are empty or there are too many data cells. Column index [%s] '\ 'are skipped.' %','.join(skipped_columns), css='warning')) div.add(HtmlElement.br(2)) div.add(table) # Analyze data. It will try to create a timestamp, then integer, then float, then varchar, then text column for idx in new_col_indices: column_types = {} data_cell_list = [] my.CHECK = 5 column_type = '' for k, row in enumerate(csv_data): if k >= len(row): data = '' else: data = row[idx] if data.strip() == '': continue if my.CHECK == 5: column_type = my._check_timestamp(data) if my.CHECK == 4: column_type = my._check_integer(data) if my.CHECK == 3: column_type = my._check_float(data) if my.CHECK == 2: column_type = my._check_varchar(data) # TEST: use democracy to determine type column_type = my._check_timestamp(data) if not column_type: column_type = my._check_integer(data) if not column_type: column_type = my._check_float(data) if not column_type: column_type = my._check_varchar(data) if column_types.get(column_type) == None: column_types[column_type] = 1 else: column_types[column_type] = column_types[column_type] + 1 # max 30 per analysis if k > 30: break largest = 0 for key, num in column_types.items(): if num > largest: column_type = key largest = num #table.add_cell(column_type) hidden = HiddenWdg('new_column_type_%s' %idx, value=column_type) div.add(hidden)
def get_upload_wdg(my): widget = Widget() # get the search type widget.add( "1. Select type of asset: ") # handle new search_types new_search_type = CheckboxWdg("new_search_type_checkbox") new_search_type.add_event("onclick", "toggle_display('new_search_type_div')") #span = SpanWdg(css="med") #span.add(new_search_type) #span.add("Create new type") #span.add(" ... or ... ") #widget.add(span) new_search_type_div = DivWdg() new_search_type_div.set_id("new_search_type_div") name_input = TextWdg("asset_name") title = TextWdg("asset_title") description = TextAreaWdg("asset_description") table = Table() table.add_style("margin: 10px 20px") table.add_col().set_attr('width','140') table.add_col().set_attr('width','400') table.add_row() table.add_header("Search Type: ").set_attr('align','left') table.add_cell(name_input) table.add_row() table.add_header("Title: ").set_attr('align','left') table.add_cell(title) table.add_row() table.add_header("Description: ").set_attr('align','left') table.add_cell(description) new_search_type_div.add(table) new_search_type_div.add_style("display: none") #widget.add(new_search_type_div) # or use a pre-existing one search_type_select = SearchTypeSelectWdg("filter|search_type") search_type_select.add_empty_option("-- Select --") search_type_select.set_persist_on_submit() search_type_select.set_submit_onchange() widget.add(search_type_select) my.search_type = search_type_select.get_value() if my.search_type: sobj = SObjectFactory.create(my.search_type) required_columns = sobj.get_required_columns() widget.add(SpanWdg("Required Columns: ", css='med')) if not required_columns: required_columns = ['n/a'] widget.add(SpanWdg(', '.join(required_columns), css='med')) widget.add( HtmlElement.br(2) ) widget.add( "2. Upload a csv file: ") upload_wdg = HtmlElement.upload("uploaded_file") widget.add(upload_wdg) submit = IconSubmitWdg("Upload", IconWdg.UPLOAD, True) widget.add(submit) web = WebContainer.get_web() field_storage = web.get_form_value("uploaded_file") if field_storage != "": upload = FileUpload() upload.set_field_storage(field_storage) upload.set_create_icon(False) upload.execute() files = upload.get_files() if files: my.file_path = files[0] else: my.file_path = web.get_form_value("file_path") if my.file_path: hidden = HiddenWdg("file_path", my.file_path) widget.add(hidden) return widget
search.set_limit(5) filter.alter_search(search) if not handler: if view in ["edit", "insert"]: table = EditWdg(search_type, view) else: table = TableWdg(search_type, view) else: table = eval("%s(search_type,view)" % handler) # table.alter_search(search) sobjects = search.get_sobjects() if not sobjects and view in ["edit", "insert"]: sobjects = [SObjectFactory.create(search_type)] table.set_sobjects(sobjects) widget.add(table) # show the custom properties widget.add("<h3>Custom Properties [%s]</h3>" % search_type) search = Search("prod/custom_property") search.add_filter("search_type", search_type) # This is actually reading the sthpw/custom_property conf file, weird table = TableWdg("prod/custom_property") table.set_search_limit(5) table.set_sobjects(search.get_sobjects()) widget.add(table) return widget
def execute(my): if not my.initialized: my.init() assert my.search_type assert my.file_path assert my.columns csv_parser = CsvParser(my.file_path) if my.has_title: csv_parser.set_has_title_row(True) else: csv_parser.set_has_title_row(False) if my.encoder: csv_parser.set_encoder(my.encoder) csv_parser.parse() # get the data and columns #csv_titles = csv_parser.get_titles() csv_data = csv_parser.get_data() # make sure all of the new columns are created csv_titles = [] for i, column in enumerate(my.columns): if not column: new_column = my.new_columns[i] new_column_type = my.new_column_types[i] if new_column and new_column not in ['id', 'code'] and\ i in my.enabled_idx: # create the new column from pyasm.command import ColumnAddCmd #col_type = "Name/Code" cmd = ColumnAddCmd(my.search_type, new_column, new_column_type) cmd.execute() # create the sobject for now sobject = SObjectFactory.create("prod/custom_property") sobject.set_value("search_type", my.search_type) sobject.set_value("name", new_column) sobject.set_value("description", new_column) sobject.commit() csv_titles.append( my.new_columns[i] ) else: csv_titles.append( column ) try: id_col = csv_titles.index(my.id_col) # id is special we want it to be identifiable at all times # but not importable if my.id_col != 'id' and id_col not in my.enabled_idx: id_col = -1 except ValueError: id_col = -1 new_entries = [] updated_entries = [] error_entries = [] error = False # create entries or update values for row_count, row in enumerate(csv_data): sobject = None # if id_col doesn't exist is_new_entry = False if id_col == -1: sobject = SObjectFactory.create(my.search_type) is_new_entry = True else: id = row[id_col] if id: # this essentially updates the current sobject in db if my.id_col=='code': sobject = Search.get_by_code(my.search_type, id.strip()) elif my.id_col=='id': sobject = Search.get_by_id(my.search_type, id.strip()) else: u_search = Search(my.search_type) u_search.add_filter(my.id_col, id.strip()) sobject = u_search.get_sobject() #assert sobject # in case a previously exported sobject with this code # or id has been deleted or it is a completely foreign code # or id, sobject will be None else: # skip if empty id or code continue if not sobject: sobject = SObjectFactory.create(my.search_type) is_new_entry = True new_columns = 0 note = None for cell_count, cell in enumerate(row): ''' column_override = my.columns[cell_count] if column_override: title = column_override else: title = csv_titles[cell_count] if not title: continue ''' # skip if not enabled if cell_count not in my.enabled_idx: continue title = csv_titles[cell_count] if not title: continue # always skip id column if title == "id": continue cell = cell.strip() # remove control, other characters in unicode #cell = re.sub(r'\p{Cc}','', cell) cell = re.sub(r"[\x01-\x08\x0b-\x1f\x7f-\x9f]",'', cell) if title == "(note)": note = cell else: sobject.set_value(title, cell) new_columns += 1 if not new_columns: msg = "No column or only the id column is selected." raise CommandException(msg) try: #sobject.commit(triggers=False) sobject.commit(triggers=True) if note: note_obj = SearchType.create("sthpw/note") note_obj.set_value("note", note) note_obj.set_value("process", "publish") note_obj.set_value("context", "publish") note_obj.set_user() note_obj.set_parent(sobject) note_obj.commit() except SqlException, e: msg = "Error creating new entry for row [%s]: %s, %s" % (row_count, str(row), e.__str__() ) # (Maybe not neccessary) must raise SqlException or it would fail silently if my.test_run: error = True error_entries.append(sobject.get_code()) raise SqlException(msg) else: if is_new_entry: new_entries.append(sobject.get_code()) else: updated_entries.append(sobject.get_code())
def get_upload_wdg(my): '''get search type select and upload wdg''' widget = DivWdg(css='spt_import_csv') widget.add_color('color','color') widget.add_color('background','background') widget.add_style('width: 600px') # get the search type title = DivWdg("<b>Select sType to import data into:</b> ") widget.add( title ) title.add_style("float: left") # handle new search_types new_search_type = CheckboxWdg("new_search_type_checkbox") new_search_type.add_event("onclick", "toggle_display('new_search_type_div')") #span = SpanWdg(css="med") #span.add(new_search_type) #span.add("Create new type") #span.add(" ... or ... ") #widget.add(span) new_search_type_div = DivWdg() new_search_type_div.set_id("new_search_type_div") name_input = TextWdg("asset_name") title = TextWdg("asset_title") description = TextAreaWdg("asset_description") key='csv_import' table = Table() table.set_id('csv_main_body') table.add_style("margin: 10px 10px") table.add_col().set_attr('width','140') table.add_col().set_attr('width','400') table.add_row() table.add_header("Search Type: ").set_attr('align','left') table.add_cell(name_input) table.add_row() table.add_header("Title: ").set_attr('align','left') table.add_cell(title) table.add_row() table.add_header("Description: ").set_attr('align','left') table.add_cell(description) new_search_type_div.add(table) new_search_type_div.add_style("display: none") #widget.add(new_search_type_div) div = DivWdg() search_type_select = SearchTypeSelectWdg("search_type_filter", mode=SearchTypeSelectWdg.ALL) search_type_select.add_empty_option("-- Select --") if not search_type_select.get_value(): search_type_select.set_value(my.search_type) search_type_select.set_persist_on_submit() div.add(search_type_select) widget.add(div) search_type_select.add_behavior( {'type': 'change', \ 'cbjs_action': "spt.panel.load('csv_import_main','%s', {}, {\ 'search_type_filter': bvr.src_el.value});" %(Common.get_full_class_name(my)) } ) if my.search_type: sobj = None try: sobj = SObjectFactory.create(my.search_type) except ImportError: widget.add(HtmlElement.br()) widget.add(SpanWdg('WARNING: Import Error encountered. Please choose another search type.', css='warning')) return widget required_columns = sobj.get_required_columns() if required_columns: widget.add(HtmlElement.br()) req_span = SpanWdg("Required Columns: ", css='med') req_span.add_color('color','color') widget.add(req_span) #required_columns = ['n/a'] req_span.add(', '.join(required_columns)) widget.add( HtmlElement.br() ) if my.file_path: hidden = HiddenWdg("file_path", my.file_path) widget.add(hidden) if my.web_url: file_span = FloatDivWdg('URL: <i>%s</i> ' %my.web_url, css='med') else: file_span = FloatDivWdg('File uploaded: <i>%s</i> ' %os.path.basename(my.file_path), css='med') file_span.add_color('color','color') file_span.add_style('margin: 8px 0 0 10px') file_span.add_style('font-size: 14px') widget.add(file_span) button = ActionButtonWdg(title='Change') button.add_style('float','left') button.add_behavior( {'type': 'click_up', \ 'cbjs_action': "spt.panel.load('csv_import_main','%s', {}, {\ 'search_type_filter': '%s'});" %(Common.get_full_class_name(my), my.search_type) } ) widget.add(button) widget.add("<br clear='all'/>") widget.add(HtmlElement.br()) return widget widget.add("<br/>") widget.add_style("overflow-y: auto") msg = DivWdg() widget.add(msg) msg.add( "<div style='float: left; padding-left: 100px; padding-top: 6px'><b>Upload a csv file: </b></div>") msg.add_border() msg.add_style("width: 400px") msg.add_color("background", "background3") msg.add_style("padding: 20px") msg.add_style("margin: 30 auto") msg.add_style("text-align: center") ticket = Environment.get_security().get_ticket_key() on_complete = '''var server = TacticServerStub.get(); var file = spt.html5upload.get_file(); if (file) { var file_name = file.name; // clean up the file name the way it is done in the server file_name = spt.path.get_filesystem_name(file_name); var server = TacticServerStub.get(); var class_name = 'tactic.ui.widget.CsvImportWdg'; var values = spt.api.Utility.get_input_values('csv_import_main'); values['is_refresh'] = true; values['file_name'] = file_name; values['html5_ticket'] = '%s'; try { var info = spt.panel.load('csv_import_main', class_name, {}, values); spt.app_busy.hide(); } catch(e) { spt.alert(spt.exception.handler(e)); } } else { alert('Error: file object cannot be found.') } spt.app_busy.hide();'''%ticket from tactic.ui.input import UploadButtonWdg browse = UploadButtonWdg(name='new_csv_upload', title="Browse", tip="Click to choose a csv file",\ on_complete=on_complete, ticket=ticket) browse.add_style('float: left') msg.add(browse) # this is now only used in the copy and paste Upload button for backward-compatibility upload_wdg = SimpleUploadWdg(key=key, show_upload=False) upload_wdg.add_style('display: none') msg.add(upload_wdg) #widget.add(span) msg.add("<br/><br/>-- OR --</br/><br/>") msg.add("<b>Published URL: </b>") text = TextWdg("web_url") msg.add(text) msg.add("<br/><br/>-- OR --</br/><br/>") msg.add("<b>Copy and Paste from a Spreadsheet: </b>") text = TextAreaWdg("data") text.add_style('width: 33em') text.add_class("spt_import_cut_paste") msg.add(text) button = ActionButtonWdg(title="Parse") button.add_style("margin: 5px auto") msg.add(button) button.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_import_top"); var el = top.getElement(".spt_import_cut_paste"); var applet = spt.Applet.get(); var value = el.value; var csv = []; // convert to a csv file! lines = value.split("\\n"); for (var i = 0; i < lines.length; i++) { if (lines[i] == '') { continue; } var parts = lines[i].split("\\t"); var new_line = []; for (var j = 0; j < parts.length; j++) { if (parts[j] == '') { new_line.push(''); } else { new_line.push('"'+parts[j]+'"'); } } new_line = new_line.join(","); csv.push(new_line); } csv = csv.join("\\n") // FIXME: need to get a local temp directory var path = spt.browser.os_is_Windows() ? "C:/sthpw/copy_n_paste.csv" : "/tmp/sthpw/copy_n_paste.csv"; applet.create_file(path, csv); // upload the file applet.upload_file(path) applet.rmtree(path); var top = bvr.src_el.getParent(".spt_import_csv"); var hidden = top.getElement(".spt_upload_hidden"); hidden.value = path; var file_name = spt.path.get_basename(hidden.value); file_name = spt.path.get_filesystem_name(file_name); var class_name = 'tactic.ui.widget.CsvImportWdg'; var values = spt.api.Utility.get_input_values('csv_import_main'); values['is_refresh'] = true; values['file_name'] = file_name; var info = spt.panel.load('csv_import_main', class_name, {}, values); ''' } ) return widget
def get_upload_wdg(self): widget = Widget() # get the search type widget.add("1. Select type of asset: ") # handle new search_types new_search_type = CheckboxWdg("new_search_type_checkbox") new_search_type.add_event("onclick", "toggle_display('new_search_type_div')") #span = SpanWdg(css="med") #span.add(new_search_type) #span.add("Create new type") #span.add(" ... or ... ") #widget.add(span) new_search_type_div = DivWdg() new_search_type_div.set_id("new_search_type_div") name_input = TextWdg("asset_name") title = TextWdg("asset_title") description = TextAreaWdg("asset_description") table = Table() table.add_style("margin: 10px 20px") table.add_col().set_attr('width', '140') table.add_col().set_attr('width', '400') table.add_row() table.add_header("Search Type: ").set_attr('align', 'left') table.add_cell(name_input) table.add_row() table.add_header("Title: ").set_attr('align', 'left') table.add_cell(title) table.add_row() table.add_header("Description: ").set_attr('align', 'left') table.add_cell(description) new_search_type_div.add(table) new_search_type_div.add_style("display: none") #widget.add(new_search_type_div) # or use a pre-existing one search_type_select = SearchTypeSelectWdg("filter|search_type") search_type_select.add_empty_option("-- Select --") search_type_select.set_persist_on_submit() search_type_select.set_submit_onchange() widget.add(search_type_select) self.search_type = search_type_select.get_value() if self.search_type: sobj = SObjectFactory.create(self.search_type) required_columns = sobj.get_required_columns() widget.add(SpanWdg("Required Columns: ", css='med')) if not required_columns: required_columns = ['n/a'] widget.add(SpanWdg(', '.join(required_columns), css='med')) widget.add(HtmlElement.br(2)) widget.add("2. Upload a csv file: ") upload_wdg = HtmlElement.upload("uploaded_file") widget.add(upload_wdg) submit = IconSubmitWdg("Upload", IconWdg.UPLOAD, True) widget.add(submit) web = WebContainer.get_web() field_storage = web.get_form_value("uploaded_file") if field_storage != "": upload = FileUpload() upload.set_field_storage(field_storage) upload.set_create_icon(False) upload.execute() files = upload.get_files() if files: self.file_path = files[0] else: self.file_path = web.get_form_value("file_path") if self.file_path: hidden = HiddenWdg("file_path", self.file_path) widget.add(hidden) return widget
def get_upload_wdg(my): '''get search type select and upload wdg''' widget = DivWdg(css='spt_import_csv') widget.add_color('color','color') widget.add_color('background','background') widget.add_style('width: 600px') # get the search type title = DivWdg("<b>Select sType to import data into:</b> ") widget.add( title ) title.add_style("float: left") # handle new search_types new_search_type = CheckboxWdg("new_search_type_checkbox") new_search_type.add_event("onclick", "toggle_display('new_search_type_div')") #span = SpanWdg(css="med") #span.add(new_search_type) #span.add("Create new type") #span.add(" ... or ... ") #widget.add(span) new_search_type_div = DivWdg() new_search_type_div.set_id("new_search_type_div") name_input = TextWdg("asset_name") title = TextWdg("asset_title") description = TextAreaWdg("asset_description") key='csv_import' table = Table() table.set_id('csv_main_body') table.add_style("margin: 10px 10px") table.add_col().set_attr('width','140') table.add_col().set_attr('width','400') table.add_row() table.add_header("Search Type: ").set_attr('align','left') table.add_cell(name_input) table.add_row() table.add_header("Title: ").set_attr('align','left') table.add_cell(title) table.add_row() table.add_header("Description: ").set_attr('align','left') table.add_cell(description) new_search_type_div.add(table) new_search_type_div.add_style("display: none") #widget.add(new_search_type_div) div = DivWdg() search_type_select = SearchTypeSelectWdg("search_type_filter", mode=SearchTypeSelectWdg.ALL) search_type_select.add_empty_option("-- Select --") if not search_type_select.get_value(): search_type_select.set_value(my.search_type) search_type_select.set_persist_on_submit() div.add(search_type_select) widget.add(div) search_type_select.add_behavior( {'type': 'change', \ 'cbjs_action': "spt.panel.load('csv_import_main','%s', {}, {\ 'search_type_filter': bvr.src_el.value});" %(Common.get_full_class_name(my)) } ) if my.search_type: sobj = None try: sobj = SObjectFactory.create(my.search_type) except ImportError: widget.add(HtmlElement.br()) widget.add(SpanWdg('WARNING: Import Error encountered. Please choose another search type.', css='warning')) return widget required_columns = sobj.get_required_columns() if required_columns: widget.add(HtmlElement.br()) req_span = SpanWdg("Required Columns: ", css='med') req_span.add_color('color','color') widget.add(req_span) #required_columns = ['n/a'] req_span.add(', '.join(required_columns)) widget.add( HtmlElement.br() ) if my.file_path: hidden = HiddenWdg("file_path", my.file_path) widget.add(hidden) if my.web_url: file_span = FloatDivWdg('URL: <i>%s</i> ' %my.web_url, css='med') else: file_span = FloatDivWdg('File uploaded: <i>%s</i> ' %os.path.basename(my.file_path), css='med') file_span.add_color('color','color') file_span.add_style('margin: 8px 0 0 10px') file_span.add_style('font-size: 14px') widget.add(file_span) button = ActionButtonWdg(title='Change') button.add_style('float','left') button.add_behavior( {'type': 'click_up', \ 'cbjs_action': "spt.panel.load('csv_import_main','%s', {}, {\ 'search_type_filter': '%s'});" %(Common.get_full_class_name(my), my.search_type) } ) widget.add(button) widget.add("<br clear='all'/>") widget.add(HtmlElement.br()) return widget widget.add("<br/>") widget.add_style("overflow-y: auto") msg = DivWdg() widget.add(msg) msg.add( "<div style='float: left; padding-left: 100px; padding-top: 6px'><b>Upload a csv file: </b></div>") msg.add_border() msg.add_style("width: 400px") msg.add_color("background", "background3") msg.add_style("padding: 20px") msg.add_style("margin: 30 auto") msg.add_style("text-align: center") ticket = Environment.get_security().get_ticket_key() on_complete = '''var server = TacticServerStub.get(); var file = spt.html5upload.get_file(); if (file) { var file_name = file.name; // clean up the file name the way it is done in the server //file_name = spt.path.get_filesystem_name(file_name); var server = TacticServerStub.get(); var class_name = 'tactic.ui.widget.CsvImportWdg'; var values = spt.api.Utility.get_input_values('csv_import_main'); values['is_refresh'] = true; values['file_name'] = file_name; values['html5_ticket'] = '%s'; try { var info = spt.panel.load('csv_import_main', class_name, {}, values); spt.app_busy.hide(); } catch(e) { spt.alert(spt.exception.handler(e)); } } else { alert('Error: file object cannot be found.') } spt.app_busy.hide();'''%ticket from tactic.ui.input import UploadButtonWdg browse = UploadButtonWdg(name='new_csv_upload', title="Browse", tip="Click to choose a csv file",\ on_complete=on_complete, ticket=ticket) browse.add_style('float: left') msg.add(browse) # this is now only used in the copy and paste Upload button for backward-compatibility upload_wdg = SimpleUploadWdg(key=key, show_upload=False) upload_wdg.add_style('display: none') msg.add(upload_wdg) #widget.add(span) msg.add("<br/><br/>-- OR --</br/><br/>") msg.add("<b>Published URL: </b>") text = TextWdg("web_url") msg.add(text) msg.add("<br/><br/>-- OR --</br/><br/>") msg.add("<b>Copy and Paste from a Spreadsheet: </b>") text = TextAreaWdg("data") text.add_style('width: 33em') text.add_class("spt_import_cut_paste") msg.add(text) button = ActionButtonWdg(title="Parse") button.add_style("margin: 5px auto") msg.add(button) button.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_import_top"); var el = top.getElement(".spt_import_cut_paste"); var applet = spt.Applet.get(); var value = el.value; var csv = []; // convert to a csv file! lines = value.split("\\n"); for (var i = 0; i < lines.length; i++) { if (lines[i] == '') { continue; } var parts = lines[i].split("\\t"); var new_line = []; for (var j = 0; j < parts.length; j++) { if (parts[j] == '') { new_line.push(''); } else { new_line.push('"'+parts[j]+'"'); } } new_line = new_line.join(","); csv.push(new_line); } csv = csv.join("\\n") // FIXME: need to get a local temp directory var path = spt.browser.os_is_Windows() ? "C:/sthpw/copy_n_paste.csv" : "/tmp/sthpw/copy_n_paste.csv"; applet.create_file(path, csv); // upload the file applet.upload_file(path) applet.rmtree(path); var top = bvr.src_el.getParent(".spt_import_csv"); var hidden = top.getElement(".spt_upload_hidden"); hidden.value = path; var file_name = spt.path.get_basename(hidden.value); file_name = spt.path.get_filesystem_name(file_name); var class_name = 'tactic.ui.widget.CsvImportWdg'; var values = spt.api.Utility.get_input_values('csv_import_main'); values['is_refresh'] = true; values['file_name'] = file_name; var info = spt.panel.load('csv_import_main', class_name, {}, values); ''' } ) return widget
search.set_limit(5) filter.alter_search(search) if not handler: if view in ["edit", "insert"]: table = EditWdg(search_type, view) else: table = TableWdg(search_type, view) else: table = eval("%s(search_type,view)" % handler) #table.alter_search(search) sobjects = search.get_sobjects() if not sobjects and view in ["edit", "insert"]: sobjects = [SObjectFactory.create(search_type)] table.set_sobjects(sobjects) widget.add(table) # show the custom properties widget.add("<h3>Custom Properties [%s]</h3>" % search_type) search = Search("prod/custom_property") search.add_filter("search_type", search_type) # This is actually reading the sthpw/custom_property conf file, weird table = TableWdg("prod/custom_property") table.set_search_limit(5) table.set_sobjects(search.get_sobjects()) widget.add(table) return widget
def get_display(self): widget = Widget() div = DivWdg(css="filter_box") show_span = SpanWdg(css='med') show_span.add('Show All Types: ') checkbox = FilterCheckboxWdg('show_all_types') checkbox.set_persistence() show_span.add(checkbox) show_all_types = checkbox.get_value() div.add(show_span) span = SpanWdg(css="med") span.add("Search Type: ") select = SelectWdg("filter|search_type") select.add_empty_option("-- Select --") project = Project.get() project_type = project.get_base_type() search = Search("sthpw/search_object") if show_all_types: search.add_where(''' namespace = '%s' or namespace = '%s' or search_type in ('sthpw/task') ''' % (project_type, project.get_code()) ) else: # show only the custom ones search.add_filter('namespace', project.get_code() ) search.add_order_by("title") sobjects = search.get_sobjects() select.set_sobjects_for_options(sobjects,"search_type", "title") #select.set_option("query", "sthpw/search_object|search_type|title") select.set_persistence() select.add_event("onchange", "document.form.submit()") search_type = select.get_value() span.add(select) div.add(span) # make sure the current selection exists try: SearchType.get(search_type) except SearchException as e: return div except SqlException as e: return div # add the view selector view_select = SelectWdg("view") view_select.add_empty_option("-- View --") view_select.add_event("onchange", "document.form.submit()") view_select.set_persist_on_submit() #view_select.set_persistence() span = SpanWdg(css="med") span.add("Defined Views: ") span.add(view_select) div.add(span) div.add( self.get_create_view_wdg(search_type)) div.add( HtmlElement.br(2) ) div.add( self.get_new_tab_wdg() ) widget.add(div) search = Search("sthpw/widget_config") #search.add_user_filter() search.add_filter("search_type", search_type) search.add_where("view != 'definition' and view != 'custom'") #search.add_column("view") widget_configs = search.get_sobjects() if widget_configs: view_select.set_sobjects_for_options(widget_configs,"view","view") view = view_select.get_value() if not view: view = "custom" #return widget # get the selected widget config for widget_config in widget_configs: if widget_config.get_value("view") == view: break else: return widget # get the handler: a little HACKY. config_xml = widget_config.get_xml_value("config") handler = config_xml.get_value("config/%s/@handler" % view) if not search_type: return widget widget.add(HtmlElement.br()) span = SpanWdg() custom_view = CustomViewWdg(search_type) span.add(custom_view) span.add_style("float: right") widget.add(span) widget.add( HtmlElement.br() ) widget.add("<h3>Example View [%s]</h3>" % view) # add a general filter filter_div = DivWdg() for i in range(0,1): filter = GeneralFilterWdg() filter.set_columns_from_search_type(search_type) filter_div.add("Filter: ") filter_div.add(filter) #filter_div.add(IconWdg("Remove Filter", IconWdg.RETIRE)) filter_div.add( HtmlElement.br(2) ) widget.add(filter_div) search = Search(search_type) search.set_limit(5) filter.alter_search(search) if not handler: if view in ["edit","insert"]: table = EditWdg(search_type, view) else: table = TableWdg(search_type, view) else: table = eval("%s(search_type,view)" % handler) #table.alter_search(search) sobjects = search.get_sobjects() if not sobjects and view in ["edit","insert"]: sobjects = [SObjectFactory.create(search_type)] table.set_sobjects(sobjects) widget.add(table) # show the custom properties widget.add("<h3>Custom Properties [%s]</h3>" % search_type) search = Search("prod/custom_property") search.add_filter("search_type", search_type) # This is actually reading the sthpw/custom_property conf file, weird table = TableWdg("prod/custom_property") table.set_search_limit(5) table.set_sobjects(search.get_sobjects() ) widget.add(table) return widget
def check(self): # make this a callback for now from pyasm.web import WebContainer web = WebContainer.get_web() self.search_type = web.get_form_value("search_type_filter") self.file_path = web.get_form_value("file_path") self.web_url = web.get_form_value("web_url") self.test_run = web.get_form_value("test_run")=='true' self.start_index = web.get_form_value("start_index") if self.start_index: try: self.start_index = int(self.start_index) except: self.start_index = None self.triggers_mode = web.get_form_value("triggers_mode") if self.triggers_mode in ['', 'True']: self.triggers_mode = True elif self.triggers_mode == 'False': self.triggers_mode = False if self.web_url: import urllib2 response = urllib2.urlopen(url) csv = response.read() self.file_path = "/tmp/test.csv" f = open(self.file_path, 'w') f.write(csv) f.close() # either unknown or utf-8 self.encoder = web.get_form_value("encoder") self.id_col = web.get_form_value("id_col") if not self.id_col: self.id_col = 'id' num_columns = web.get_form_value("num_columns") if num_columns: num_columns = int(num_columns) else: num_columns = 0 # indices of the enabled columns self.enabled_idx = [] self.columns = [] self.new_columns = [] self.new_column_types = [] self.note_processes = [] for i in range(0, num_columns): enabled = web.get_form_value("column_enabled_%s" % i) if enabled in ['on','true']: self.enabled_idx.append(i) # Default column name or '' for new columns column = web.get_form_value("column_%s" % i) self.columns.append(column) # New column name if column=='' new_column = web.get_form_value("new_column_%s" % i) if isinstance(new_column, unicode): new_column = self.strip_punctuation(new_column) self.new_columns.append(new_column) # New column type if column=='' new_column_type = web.get_form_value("column_type_%s" % i) self.new_column_types.append(new_column_type) # New note process if column==('note') new_note_process = web.get_form_value("note_process_%s" % i) self.note_processes.append(new_note_process) # check for required columns sobj = SObjectFactory.create(self.search_type) required_columns = sobj.get_required_columns() for required in required_columns: if required in self.columns: continue else: raise UserException('Missing required column [%s] in the input CSV' % required) self.has_title = web.get_form_value("has_title") == 'on' self.lowercase_title = web.get_form_value("lowercase_title") == 'on' return True
def check(my): # make this a callback for now from pyasm.web import WebContainer web = WebContainer.get_web() my.search_type = web.get_form_value("search_type_filter") my.file_path = web.get_form_value("file_path") my.web_url = web.get_form_value("web_url") my.test_run = web.get_form_value("test_run")=='true' my.triggers_mode = web.get_form_value("triggers_mode") if my.triggers_mode in ['', 'True']: my.triggers_mode = True elif my.triggers_mode == 'False': my.triggers_mode = False if my.web_url: import urllib2 response = urllib2.urlopen(url) csv = response.read() my.file_path = "/tmp/test.csv" f = open(my.file_path, 'w') f.write(csv) f.close() # either unknown or utf-8 my.encoder = web.get_form_value("encoder") my.id_col = web.get_form_value("id_col") if not my.id_col: my.id_col = 'id' num_columns = web.get_form_value("num_columns") if num_columns: num_columns = int(num_columns) else: num_columns = 0 # indices of the enabled columns my.enabled_idx = [] my.columns = [] my.new_columns = [] my.new_column_types = [] for i in range(0, num_columns): enabled = web.get_form_value("column_enabled_%s" % i) if enabled in ['on','true']: my.enabled_idx.append(i) column = web.get_form_value("column_%s" % i) my.columns.append(column) new_column = web.get_form_value("new_column_%s" % i) if isinstance(new_column, unicode): new_column = my.strip_punctuation(new_column) new_column_type = web.get_form_value("new_column_type_%s" % i) my.new_columns.append(new_column) my.new_column_types.append(new_column_type) # check for required columns sobj = SObjectFactory.create(my.search_type) required_columns = sobj.get_required_columns() for required in required_columns: if required in my.columns: continue else: raise UserException('Missing required column [%s] in the input CSV' % required) my.has_title = web.get_form_value("has_title") == 'on' my.lowercase_title = web.get_form_value("lowercase_title") == 'on' return True
def get_first_row_wdg(my): # read the csv file my.file_path = "" div = DivWdg() div.add( my.get_upload_wdg() ) if not my.search_type: return div if not my.file_path: return div if not my.file_path.endswith(".csv"): div.add( "Uploaded file [%s] is not a csv file"% my.file_path) return div if not os.path.exists(my.file_path): raise Exception("Path '%s' does not exists" % my.file_path) div.add(HtmlElement.br(2)) div.add( HtmlElement.b("The following is taken from first line in the uploaded csv file. Select the appropriate column to match.") ) div.add(HtmlElement.br()) div.add( HtmlElement.b("Make sure you have all the required columns** in the csv.")) option_div = DivWdg() option_div.add_style("float: left") option_div.add_style("margin-right: 30px") option_div.add("<p>3. Parsing Options:</p>") my.search_type_obj = SearchType.get(my.search_type) # first row and second row option_div.add( HtmlElement.br(2) ) option_div.add("Use Title Row: ") title_row_checkbox = FilterCheckboxWdg("has_title") title_row_checkbox.set_default_checked() option_div.add(title_row_checkbox) option_div.add( HintWdg("Set this to use the first row as a title row to match up columns in the database") ) option_div.add( HtmlElement.br(2) ) option_div.add("Sample Data Row: ") data_row_text = TextWdg("data_row") data_row_text.set_attr("size", "3") option_div.add(data_row_text) option_div.add( HintWdg("Set this as a sample data row to match the columns to the database") ) option_div.add( HtmlElement.br(2) ) div.add(option_div) my.has_title = title_row_checkbox.is_checked() # parse the first fow csv_parser = CsvParser(my.file_path) if my.has_title: csv_parser.set_has_title_row(True) else: csv_parser.set_has_title_row(False) csv_parser.parse() csv_titles = csv_parser.get_titles() csv_data = csv_parser.get_data() data_row = data_row_text.get_value() if not data_row: data_row = 0 else: try: data_row = int(data_row) except ValueError: data_row = 0 if data_row >= len(csv_data): data_row = len(csv_data)-1 data_row_text.set_value(data_row) table = Table() table.set_attr("cellpadding", "10") table.add_row() table.add_header("CSV Column Value") table.add_header("TACTIC Column") table.add_header("Create New Column") columns = my.search_type_obj.get_columns() search_type = my.search_type_obj.get_base_search_type() sobj = SObjectFactory.create(search_type) required_columns = sobj.get_required_columns() row = csv_data[data_row] labels = [] for column in columns: if column in required_columns: label = '%s**'%column else: label = column labels.append(label) for j, cell in enumerate(row): table.add_row() table.add_cell(cell) column_select = SelectWdg("column_%s" % j) column_select.add_event("onchange", "if (this.value!='') {set_display_off('new_column_div_%s')} else {set_display_on('new_column_div_%s')}" % (j,j)) column_select.add_empty_option("-- Select --") column_select.set_option("values", columns) column_select.set_option("labels", labels) # only set the value if it is actually in there if csv_titles[j] in columns: column_select.set_option("default", csv_titles[j]) column_select.set_persist_on_submit() column_select_value = column_select.get_value() display = column_select.get_buffer_display() td = table.add_cell( display ) if csv_titles[j] not in columns: td.add(" <b style='color: red'>*</b>") # new property new_column_div = DivWdg() if column_select_value: new_column_div.add_style("display", "none") else: new_column_div.add_style("display", "block") new_column_div.set_id("new_column_div_%s" % j) td = table.add_cell( new_column_div ) text = TextWdg("new_column_%s" % j) text.set_persist_on_submit() if my.has_title: text.set_value(csv_titles[j]) new_column_div.add( " ... or ..." ) new_column_div.add( text ) my.num_columns = len(row) hidden = HiddenWdg("num_columns", my.num_columns) # need to somehow specify defaults for columns div.add(table) div.add("<br/><br/>") div.add(my.get_preview_wdg()) return div
def get_first_row_wdg(self): # read the csv file self.file_path = "" div = DivWdg() div.add(self.get_upload_wdg()) if not self.search_type: return div if not self.file_path: return div if not self.file_path.endswith(".csv"): div.add("Uploaded file [%s] is not a csv file" % self.file_path) return div if not os.path.exists(self.file_path): raise Exception("Path '%s' does not exists" % self.file_path) div.add(HtmlElement.br(2)) div.add( HtmlElement. b("The following is taken from first line in the uploaded csv file. Select the appropriate column to match." )) div.add(HtmlElement.br()) div.add( HtmlElement.b( "Make sure you have all the required columns** in the csv.")) option_div = DivWdg() option_div.add_style("float: left") option_div.add_style("margin-right: 30px") option_div.add("<p>3. Parsing Options:</p>") self.search_type_obj = SearchType.get(self.search_type) # first row and second row option_div.add(HtmlElement.br(2)) option_div.add("Use Title Row: ") title_row_checkbox = FilterCheckboxWdg("has_title") title_row_checkbox.set_default_checked() option_div.add(title_row_checkbox) option_div.add( HintWdg( "Set this to use the first row as a title row to match up columns in the database" )) option_div.add(HtmlElement.br(2)) option_div.add("Sample Data Row: ") data_row_text = TextWdg("data_row") data_row_text.set_attr("size", "3") option_div.add(data_row_text) option_div.add( HintWdg( "Set this as a sample data row to match the columns to the database" )) option_div.add(HtmlElement.br(2)) div.add(option_div) self.has_title = title_row_checkbox.is_checked() # parse the first fow csv_parser = CsvParser(self.file_path) if self.has_title: csv_parser.set_has_title_row(True) else: csv_parser.set_has_title_row(False) csv_parser.parse() csv_titles = csv_parser.get_titles() csv_data = csv_parser.get_data() data_row = data_row_text.get_value() if not data_row: data_row = 0 else: try: data_row = int(data_row) except ValueError: data_row = 0 if data_row >= len(csv_data): data_row = len(csv_data) - 1 data_row_text.set_value(data_row) table = Table() table.set_attr("cellpadding", "10") table.add_row() table.add_header("CSV Column Value") table.add_header("TACTIC Column") table.add_header("Create New Column") columns = self.search_type_obj.get_columns() search_type = self.search_type_obj.get_base_search_type() sobj = SObjectFactory.create(search_type) required_columns = sobj.get_required_columns() row = csv_data[data_row] labels = [] for column in columns: if column in required_columns: label = '%s**' % column else: label = column labels.append(label) for j, cell in enumerate(row): table.add_row() table.add_cell(cell) column_select = SelectWdg("column_%s" % j) column_select.add_event( "onchange", "if (this.value!='') {set_display_off('new_column_div_%s')} else {set_display_on('new_column_div_%s')}" % (j, j)) column_select.add_empty_option("-- Select --") column_select.set_option("values", columns) column_select.set_option("labels", labels) # only set the value if it is actually in there if csv_titles[j] in columns: column_select.set_option("default", csv_titles[j]) column_select.set_persist_on_submit() column_select_value = column_select.get_value() display = column_select.get_buffer_display() td = table.add_cell(display) if csv_titles[j] not in columns: td.add(" <b style='color: red'>*</b>") # new property new_column_div = DivWdg() if column_select_value: new_column_div.add_style("display", "none") else: new_column_div.add_style("display", "block") new_column_div.set_id("new_column_div_%s" % j) td = table.add_cell(new_column_div) text = TextWdg("new_column_%s" % j) text.set_persist_on_submit() if self.has_title: text.set_value(csv_titles[j]) new_column_div.add(" ... or ...") new_column_div.add(text) self.num_columns = len(row) hidden = HiddenWdg("num_columns", self.num_columns) # need to somehow specify defaults for columns div.add(table) div.add("<br/><br/>") div.add(self.get_preview_wdg()) return div
def get_display(self): widget = Widget() div = DivWdg(css="filter_box") show_span = SpanWdg(css='med') show_span.add('Show All Types: ') checkbox = FilterCheckboxWdg('show_all_types') checkbox.set_persistence() show_span.add(checkbox) show_all_types = checkbox.get_value() div.add(show_span) span = SpanWdg(css="med") span.add("Search Type: ") select = SelectWdg("filter|search_type") select.add_empty_option("-- Select --") project = Project.get() project_type = project.get_base_type() search = Search("sthpw/search_object") if show_all_types: search.add_where(''' namespace = '%s' or namespace = '%s' or search_type in ('sthpw/task') ''' % (project_type, project.get_code())) else: # show only the custom ones search.add_filter('namespace', project.get_code()) search.add_order_by("title") sobjects = search.get_sobjects() select.set_sobjects_for_options(sobjects, "search_type", "title") #select.set_option("query", "sthpw/search_object|search_type|title") select.set_persistence() select.add_event("onchange", "document.form.submit()") search_type = select.get_value() span.add(select) div.add(span) # make sure the current selection exists try: SearchType.get(search_type) except SearchException as e: return div except SqlException as e: return div # add the view selector view_select = SelectWdg("view") view_select.add_empty_option("-- View --") view_select.add_event("onchange", "document.form.submit()") view_select.set_persist_on_submit() #view_select.set_persistence() span = SpanWdg(css="med") span.add("Defined Views: ") span.add(view_select) div.add(span) div.add(self.get_create_view_wdg(search_type)) div.add(HtmlElement.br(2)) div.add(self.get_new_tab_wdg()) widget.add(div) search = Search("sthpw/widget_config") #search.add_user_filter() search.add_filter("search_type", search_type) search.add_where("view != 'definition' and view != 'custom'") #search.add_column("view") widget_configs = search.get_sobjects() if widget_configs: view_select.set_sobjects_for_options(widget_configs, "view", "view") view = view_select.get_value() if not view: view = "custom" #return widget # get the selected widget config for widget_config in widget_configs: if widget_config.get_value("view") == view: break else: return widget # get the handler: a little HACKY. config_xml = widget_config.get_xml_value("config") handler = config_xml.get_value("config/%s/@handler" % view) if not search_type: return widget widget.add(HtmlElement.br()) span = SpanWdg() custom_view = CustomViewWdg(search_type) span.add(custom_view) span.add_style("float: right") widget.add(span) widget.add(HtmlElement.br()) widget.add("<h3>Example View [%s]</h3>" % view) # add a general filter filter_div = DivWdg() for i in range(0, 1): filter = GeneralFilterWdg() filter.set_columns_from_search_type(search_type) filter_div.add("Filter: ") filter_div.add(filter) #filter_div.add(IconWdg("Remove Filter", IconWdg.RETIRE)) filter_div.add(HtmlElement.br(2)) widget.add(filter_div) search = Search(search_type) search.set_limit(5) filter.alter_search(search) if not handler: if view in ["edit", "insert"]: table = EditWdg(search_type, view) else: table = TableWdg(search_type, view) else: table = eval("%s(search_type,view)" % handler) #table.alter_search(search) sobjects = search.get_sobjects() if not sobjects and view in ["edit", "insert"]: sobjects = [SObjectFactory.create(search_type)] table.set_sobjects(sobjects) widget.add(table) # show the custom properties widget.add("<h3>Custom Properties [%s]</h3>" % search_type) search = Search("prod/custom_property") search.add_filter("search_type", search_type) # This is actually reading the sthpw/custom_property conf file, weird table = TableWdg("prod/custom_property") table.set_search_limit(5) table.set_sobjects(search.get_sobjects()) widget.add(table) return widget