예제 #1
0
    def get_display(my):
        widget = DivWdg(id='preview_data')
        widget.add_style('padding: 6px')
        my.set_as_panel(widget)
        widget.add(SpanWdg(), 'warning')
        widget.add(HtmlElement.br(2))
        my.get_column_preview(widget)


        web = WebContainer.get_web()

        csv_parser = CsvParser(my.file_path)
        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. 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')
            widget.add(span, 'warning')
            return widget
예제 #2
0
    def get_display(my):
        widget = DivWdg(id='preview_data')
        widget.add_style('padding: 6px')
        my.set_as_panel(widget)
        widget.add(SpanWdg(), 'warning')
        widget.add(HtmlElement.br(2))
        my.get_column_preview(widget)


        web = WebContainer.get_web()

        csv_parser = CsvParser(my.file_path)
        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. 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')
            widget.add(span, 'warning')
            return widget
예제 #3
0
    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())
예제 #4
0
    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
예제 #5
0
    def get_preview_wdg(self):

        widget = Widget()

        web = WebContainer.get_web()

        csv_parser = CsvParser(self.file_path)
        csv_parser.parse()
        csv_titles = csv_parser.get_titles()
        csv_data = csv_parser.get_data()

        ajax = AjaxCmd()
        ajax.set_option("search_type", self.search_type)
        ajax.set_option("file_path", self.file_path)
        ajax.add_element_name("has_title")

        event = WebContainer.get_event_container()
        caller = event.get_event_caller(SiteMenuWdg.EVENT_ID)
        div = ajax.generate_div()
        div.set_post_ajax_script(caller)
        widget.add(div)

        columns = []
        num_columns = len(csv_titles)
        ajax.set_option("num_columns", num_columns)
        for i in range(0, num_columns):
            column = web.get_form_value("column_%s" % i)
            if column:
                column = csv_titles[i]
            else:
                column = web.get_form_value("column_new_%s" % i)

            columns.append(column)

            ajax.add_element_name("column_%s" % i)
            ajax.add_element_name("new_column_%s" % i)

        ajax.register_cmd("pyasm.command.csv_import_cmd.CsvImportCmd")
        import_button = IconButtonWdg("Import", IconWdg.REFRESH, True)
        import_button.add_event("onclick",
                                ajax.get_on_script(show_progress=False))
        import_button.add_style("float: right")
        widget.add(import_button)

        preview_submit = IconSubmitWdg("Preview", IconWdg.REFRESH, True)
        preview_submit.add_style("float: right")
        widget.add(preview_submit)

        sobject_title = self.search_type_obj.get_title()
        widget.add("<p>4. Import</p>")
        widget.add(HtmlElement.br())
        widget.add(
            "<p>The following table will be imported into %s (Showing Max: 100)</p>"
            % sobject_title)

        table = Table(css="table")
        table.add_style("width: 100%")

        table.add_row()
        for i, title in enumerate(columns):
            if not title:
                title = "<b style='color:red'>*</b>"
            table.add_header(title)

        for i, row in enumerate(csv_data):
            if i > 100:
                break
            table.add_row()
            for j, cell in enumerate(row):
                table.add_cell(cell)

        widget.add(table)

        return widget
예제 #6
0
    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
예제 #7
0
    def get_preview_wdg(my):

        widget = Widget()

        web = WebContainer.get_web()

        csv_parser = CsvParser(my.file_path)
        csv_parser.parse()
        csv_titles = csv_parser.get_titles()
        csv_data = csv_parser.get_data()



        ajax = AjaxCmd()
        ajax.set_option("search_type", my.search_type)
        ajax.set_option("file_path", my.file_path)
        ajax.add_element_name("has_title")

        event = WebContainer.get_event_container()
        caller = event.get_event_caller(SiteMenuWdg.EVENT_ID)
        div = ajax.generate_div()
        div.set_post_ajax_script(caller)
        widget.add(div)

        columns = []
        num_columns = len(csv_titles)
        ajax.set_option("num_columns", num_columns)
        for i in range(0, num_columns):
            column = web.get_form_value("column_%s" % i)
            if column:
                column = csv_titles[i]
            else:
                column = web.get_form_value("column_new_%s" % i)

            columns.append(column)

            ajax.add_element_name("column_%s" % i)
            ajax.add_element_name("new_column_%s" % i)


        ajax.register_cmd("pyasm.command.csv_import_cmd.CsvImportCmd")
        import_button = IconButtonWdg("Import", IconWdg.REFRESH, True)
        import_button.add_event("onclick", ajax.get_on_script(show_progress=False))
        import_button.add_style("float: right")
        widget.add( import_button )


        preview_submit = IconSubmitWdg("Preview", IconWdg.REFRESH, True)
        preview_submit.add_style("float: right")
        widget.add(preview_submit)

        sobject_title = my.search_type_obj.get_title()
        widget.add("<p>4. Import</p>")
        widget.add(HtmlElement.br())
        widget.add("<p>The following table will be imported into %s (Showing Max: 100)</p>" % sobject_title)


        table = Table(css="table")
        table.add_style("width: 100%")

        table.add_row()
        for i, title in enumerate(columns):
            if not title:
                title = "<b style='color:red'>*</b>"
            table.add_header(title)

        for i, row in enumerate(csv_data):
            if i > 100:
                break
            table.add_row()
            for j, cell in enumerate(row):
                table.add_cell(cell)

        widget.add(table)

        return widget
예제 #8
0
    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          
예제 #9
0
    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