Esempio n. 1
0
def handle_add_request(logger_console, input_cmd_str, path_data_folder, error_feedback=False):
	"""
	take input and add store it

	:return:
	"""
	# local import to load this module only in case of an 'add' commands
	from fastHistory.parser.inputParser import InputParser

	one_line_input = InputParser.adjust_multi_line_input(input_cmd_str)
	# define log class
	logging.debug("input: '%s'" % one_line_input[1])
	# parse tags and store the cmd
	parser_res = InputParser.parse_input(one_line_input[1])

	if parser_res is None:
		if error_feedback:
			logger_console.log_on_console_error("wrong input")
			logger_console.log_on_console_info("syntax  :  f --add <command> #[<tag> [#<tag> ...]][@<description>]")
			logger_console.log_on_console_info("examples:  f --add ls -la #")
			logger_console.log_on_console_info("           f --add ls -la #list @show files")
			logger_console.log_on_console_info("syntax 2:  #<command> #[<tag> [#<tag> ...]][@<description>]")
			logger_console.log_on_console_info("examples:  #ls -la #")
			logger_console.log_on_console_info("           #ls -la #list @show files")
	else:
		cmd = parser_res.get_main_str()
		description = parser_res.get_description_str()
		tags = parser_res.get_tags(strict=True)

		data_manager = DataManager(path_data_folder, NAME_DATABASE_FILE, DATABASE_MODE)
		stored = data_manager.add_new_element(cmd, description, tags)
		if stored:
			logging.debug("command added")
			if one_line_input[0]:
				logger_console.log_on_console_warn("command has been adjusted")
				logger_console.log_on_console_warn("multi-line commands are not fully supported")
			logger_console.log_on_console_info("command:    '%s'" % cmd)
			if tags and len(tags) > 0 and tags[0] != "":
				str_tags = ""
				for tag in tags:
					str_tags += logger_console.tag_colored + tag + " "
				logger_console.log_on_console_info("tags:        %s" % str_tags)
			if description and len(description) > 0:
				logger_console.log_on_console_info("description: %s%s" % (logger_console.desc_colored, description))
		else:
			logging.error("store command failed")
			logger_console.log_on_console_info("store command failed, please check your log file: %s" %
											   os.path.abspath(path_data_folder + NAME_LOG_FILE))
Esempio n. 2
0
    def test_TLDR_search_with_simulated_manual_input(self):
        """
        note:
            without "thread.has_been_stopped()" check ->  >= 3 seconds
            with "thread.has_been_stopped()" check at fnames level -> 0.9 seconds
            with "thread.has_been_stopped()" check at line level -> 0.85 seconds
        :return:
        """

        test_strings = [
            "open port listen",
            "a fi le file ile"
        ]

        for test in test_strings:
            start_time = time.time()

            fake_manual_input = ""
            tldr_parser_thread = None
            tldr_parser = TLDRParser()
            for c in test:
                fake_manual_input += c
                input_data = InputParser.parse_input(test, is_search_mode=True)
                if tldr_parser_thread:
                    tldr_parser_thread.stop()
                tldr_parser_thread = TLDRParseThread(tldr_parser, input_data)
                tldr_parser_thread.start()
                time.sleep(0.05)

            while tldr_parser_thread.is_alive():
                time.sleep(0.01)

            execution_time = (time.time() - start_time)
            logging.info("execution_time: %s -> %s seconds" % (test, execution_time))
            self.assertTrue(execution_time < 3.0, msg="execution takes too long: %s sec" % execution_time)
Esempio n. 3
0
    def filter(self, search, n=100):
        """
		get filtered commands array
		:param n: 		max number of returned rows
		:param search:	filter text
		:return:		array with [cmd, description, tags array, bool advanced]
		"""
        # put all to lower case
        search = search.lower()

        # parse input search text
        input_data = InputParser.parse_input(search, is_search_mode=True)

        if input_data:
            self.search_filters = input_data

            if not input_data.is_advanced():
                filtered_data = self.database.get_last_n_filtered_elements(
                    generic_filters=input_data.get_main_words(), n=n)
            else:
                filtered_data = self.database.get_last_n_filtered_elements(
                    generic_filters=input_data.get_main_words(),
                    description_filters=input_data.get_description_words(
                        strict=True),
                    tags_filters=input_data.get_tags(strict=True),
                    n=n)
            if filtered_data:
                return filtered_data
            else:
                return []
        else:
            # the string inserted does not match the regex and a dummy response is returned
            self.search_filters = self.DUMMY_INPUT_DATA
            return []
Esempio n. 4
0
    def run_loop_edit_command(self, blocks_shift, bash_parser_thread):
        """
        loop to capture user input keys to interact with the "edit command" page

        :return:    [False, None] if no change has been done, [True, <new_command_str>] otherwise]
        """
        # import this locally to improve performance when the program is loaded
        from fastHistory.pick.pageEditCommand import PageEditCommand
        page_command = PageEditCommand(
            self.drawer,
            option=self.current_selected_option,
            search_filters=self.data_manager.get_search_filters(),
            context_shift=self.context_shift,
            blocks_shift=blocks_shift)

        current_command = self.current_selected_option[
            DataManager.OPTION.INDEX_CMD]
        command_t = TextManager(
            self.current_selected_option[DataManager.OPTION.INDEX_CMD],
            max_x=self.drawer.get_max_x() - self.EDIT_FIELD_MARGIN)
        input_error_msg = None

        while True:
            if page_command.has_minimum_size():
                page_command.clean_page()
                page_command.draw_page_edit(
                    command_text=command_t.get_text_to_print(),
                    command_cursor_index=command_t.get_cursor_index_to_print(),
                    input_error_msg=input_error_msg,
                    data_from_man_page=bash_parser_thread.get_result())
                page_command.refresh_page()

            # wait for char
            c = self.drawer.wait_next_char(
                multi_threading_mode=bash_parser_thread.is_alive())

            if c == Keys.KEY_TIMEOUT:
                continue
            # save and exit
            elif c in Keys.KEYS_ENTER:
                new_command = command_t.get_text()
                if current_command == new_command:
                    return [False, None]
                else:
                    is_valid_command = InputParser.is_cmd_str_valid(
                        new_command)
                    if is_valid_command:
                        if self.data_manager.update_command(
                                current_command, new_command):
                            return [True, new_command]
                        else:
                            msg = "database error during saving, please try again"
                            logging.error(msg)
                            input_error_msg = msg
                    else:
                        input_error_msg = "no tags and description are allowed here"

            # exit without saving
            elif c == Keys.KEY_TAB or c == Keys.KEY_SHIFT_TAB or c == Keys.KEY_ESC:
                return [False, None]
            # -> command
            elif c == Keys.KEY_RIGHT:
                if command_t.is_cursor_at_the_end():
                    self.context_shift.shift_context_right()
                else:
                    command_t.move_cursor_right()
                # <- command
            elif c == Keys.KEY_LEFT:
                if not self.context_shift.is_context_index_zero():
                    self.context_shift.shift_context_left()
                elif not command_t.is_cursor_at_the_beginning():
                    command_t.move_cursor_left()
                else:
                    # do nothing, the cursor is already on the position 0
                    pass
            # delete a char of the search
            elif c in Keys.KEYS_DELETE:
                command_t.delete_char()
                input_error_msg = None
            # move cursor to the beginning
            elif c == Keys.KEY_START or c == Keys.KEY_CTRL_A:
                command_t.move_cursor_to_start()
                self.context_shift.reset_context_shifted()
            # move cursor to the end
            elif c == Keys.KEY_END or c == Keys.KEY_CTRL_E:
                command_t.move_cursor_to_end()
            elif c == Keys.KEY_RESIZE:
                # this occurs when the console size changes
                self.drawer.reset()
                command_t.set_max_x(self.drawer.get_max_x() -
                                    self.EDIT_FIELD_MARGIN)
            elif c == Keys.KEY_CTRL_U:
                command_t.set_text("")
            elif type(c) is str:
                command_t.add_string(c,
                                     self.data_manager.get_forbidden_chars())
                input_error_msg = None
            else:
                logging.error("input not handled: %s" % repr(c))
Esempio n. 5
0
    def run_loop_edit_tags(self, bash_parser_thread):
        """
        loop to capture user input keys to interact with the "add tag" page

        :return:
        """
        # import this locally to improve performance when the program is loaded
        from fastHistory.pick.pageEditTags import PageEditTags
        page_tags = PageEditTags(
            self.drawer,
            option=self.current_selected_option,
            search_filters=self.data_manager.get_search_filters(),
            context_shift=self.context_shift)

        current_command = self.current_selected_option[
            DataManager.OPTION.INDEX_CMD]
        new_tags = self.current_selected_option[DataManager.OPTION.INDEX_TAGS]
        new_tags_str = ""
        for tag in new_tags:
            if len(tag) > 0:
                new_tags_str += InputParser.TAG_SIGN + tag + " "

        new_tags_t = TextManager(new_tags_str,
                                 max_x=self.drawer.get_max_x() -
                                 self.EDIT_FIELD_MARGIN)
        new_tags_t.add_string(InputParser.TAG_SIGN,
                              self.data_manager.get_forbidden_chars())

        input_error_msg = None

        while True:
            if page_tags.has_minimum_size():
                page_tags.clean_page()
                page_tags.draw_page_edit(
                    tags_text=new_tags_t.get_text_to_print(),
                    tags_cursor_index=new_tags_t.get_cursor_index_to_print(),
                    input_error_msg=input_error_msg,
                    data_from_man_page=bash_parser_thread.get_result())
                page_tags.refresh_page()

            # wait for char
            c = self.drawer.wait_next_char(
                multi_threading_mode=bash_parser_thread.is_alive())

            if c == Keys.KEY_TIMEOUT:
                continue
            elif c in Keys.KEYS_ENTER:
                new_tags_array = InputParser.parse_tags_str(
                    new_tags_t.get_text())
                if new_tags_array is not None:
                    if self.data_manager.update_tags(current_command,
                                                     new_tags_array):
                        return True
                    else:
                        msg = "database error during saving, please try again"
                        logging.error(msg)
                        input_error_msg = msg
                else:
                    input_error_msg = self.TEXT_NOT_ALLOWED_STR
            # exit without saving
            # TODO fix return if "alt+char" is pressed
            elif c == Keys.KEY_TAB or c == Keys.KEY_SHIFT_TAB or c == Keys.KEY_ESC:
                return False
            # -> command
            elif c == Keys.KEY_RIGHT:
                if new_tags_t.is_cursor_at_the_end():
                    self.context_shift.shift_context_right()
                else:
                    # move the search cursor one position right (->)
                    new_tags_t.move_cursor_right()
                # <- command
            elif c == Keys.KEY_LEFT:
                if not self.context_shift.is_context_index_zero():
                    self.context_shift.shift_context_left()
                elif not new_tags_t.is_cursor_at_the_beginning():
                    new_tags_t.move_cursor_left()
                else:
                    # do nothing, the cursor is already on the position 0
                    pass
                    # delete a char of the search
            elif c in Keys.KEYS_DELETE:
                # the delete is allowed if the search text is not empty and if
                if new_tags_t.delete_char():
                    self.context_shift.reset_context_shifted()
                if input_error_msg is not None:
                    new_tags_array = InputParser.parse_tags_str(
                        new_tags_t.get_text())
                    if new_tags_array is None:
                        input_error_msg = self.TEXT_NOT_ALLOWED_STR
                    else:
                        input_error_msg = None
            # move cursor to the beginning
            elif c == Keys.KEY_START or c == Keys.KEY_CTRL_A:
                new_tags_t.move_cursor_to_start()
                self.context_shift.reset_context_shifted()
            # move cursor to the end
            elif c == Keys.KEY_END or c == Keys.KEY_CTRL_E:
                new_tags_t.move_cursor_to_end()
            # this occurs when the console size changes
            elif c == Keys.KEY_RESIZE:
                self.drawer.reset()
                new_tags_t.set_max_x(self.drawer.get_max_x() -
                                     self.EDIT_FIELD_MARGIN)
            elif c == Keys.KEY_CTRL_U:
                new_tags_t.set_text("")
            elif type(c) is str:
                new_tags_t.add_string(c,
                                      self.data_manager.get_forbidden_chars())
                new_tags_array = InputParser.parse_tags_str(
                    new_tags_t.get_text())
                if new_tags_array is None:
                    input_error_msg = self.TEXT_NOT_ALLOWED_STR
                else:
                    input_error_msg = None
            else:
                logging.error("input not handled: %s" % repr(c))
Esempio n. 6
0
    def run_loop_edit_description(self, blocks_shift, bash_parser_thread):
        """
        loop to capture user input keys to interact with the "add description" page

        :return:
        """
        # import this locally to improve performance when the program is loaded
        from fastHistory.pick.pageEditDescription import PageEditDescription
        page_desc = PageEditDescription(
            self.drawer,
            option=self.current_selected_option,
            search_filters=self.data_manager.get_search_filters(),
            context_shift=self.context_shift,
            blocks_shift=blocks_shift)

        current_command = self.current_selected_option[
            DataManager.OPTION.INDEX_CMD]
        description_t = TextManager(
            InputParser.DESCRIPTION_SIGN +
            self.current_selected_option[DataManager.OPTION.INDEX_DESC],
            max_x=self.drawer.get_max_x() - self.EDIT_FIELD_MARGIN)
        input_error_msg = None

        while True:
            if page_desc.has_minimum_size():
                page_desc.clean_page()
                page_desc.draw_page_edit(
                    description_text=description_t.get_text_to_print(),
                    description_cursor_index=description_t.
                    get_cursor_index_to_print(),
                    input_error_msg=input_error_msg,
                    data_from_man_page=bash_parser_thread.get_result())
                page_desc.refresh_page()

            # wait for char
            c = self.drawer.wait_next_char(
                multi_threading_mode=bash_parser_thread.is_alive())

            if c == Keys.KEY_TIMEOUT:
                continue
            # save and exit
            elif c in Keys.KEYS_ENTER:
                new_description = InputParser.parse_description(
                    description_t.get_text())
                if new_description is not None:
                    if self.data_manager.update_description(
                            current_command, new_description):
                        return True
                    else:
                        msg = "database error during saving, please try again"
                        logging.error(msg)
                        input_error_msg = msg
                else:
                    input_error_msg = self.TEXT_NOT_ALLOWED_STR

            # exit without saving
            elif c == Keys.KEY_TAB or c == Keys.KEY_SHIFT_TAB or c == Keys.KEY_ESC:
                return False
            # -> command
            elif c == Keys.KEY_RIGHT:
                if description_t.is_cursor_at_the_end():
                    self.context_shift.shift_context_right()
                else:
                    description_t.move_cursor_right()
                # <- command
            elif c == Keys.KEY_LEFT:
                if not self.context_shift.is_context_index_zero():
                    self.context_shift.shift_context_left()
                elif not description_t.is_cursor_at_the_beginning():
                    description_t.move_cursor_left()
                else:
                    # do nothing, the cursor is already on the position 0
                    pass
            # delete a char of the search
            elif c in Keys.KEYS_DELETE:
                description_t.delete_char()
                if input_error_msg is not None:
                    new_description = InputParser.parse_description(
                        description_t.get_text())
                    if new_description is None:
                        input_error_msg = self.TEXT_NOT_ALLOWED_STR
                    else:
                        input_error_msg = None
            # move cursor to the beginning
            elif c == Keys.KEY_START or c == Keys.KEY_CTRL_A:
                description_t.move_cursor_to_start()
                self.context_shift.reset_context_shifted()
            # move cursor to the end
            elif c == Keys.KEY_END or c == Keys.KEY_CTRL_E:
                description_t.move_cursor_to_end()
            elif c == "#":  # Keys.KEY_RESIZE:
                # this occurs when the console size changes
                self.drawer.reset()
                description_t.set_max_x(self.drawer.get_max_x() -
                                        self.EDIT_FIELD_MARGIN)
            elif c == Keys.KEY_CTRL_U:
                description_t.set_text("")
            elif type(c) is str:
                description_t.add_string(
                    c, self.data_manager.get_forbidden_chars())
                new_description = InputParser.parse_description(
                    description_t.get_text())
                if new_description is None:
                    input_error_msg = self.TEXT_NOT_ALLOWED_STR
                else:
                    input_error_msg = None
            else:
                logging.error("input not handled: %s" % repr(c))
Esempio n. 7
0
    def run_loop_tldr(self, cached_in_memory_pages):
        """
        :return:
        """
        tldr_parser = TLDRParser(cached_in_memory_pages)
        tldr_parser_thread = None
        input_data = InputData(False, "", [])
        tldr_options_reload_needed = True
        tldr_options_waiting = True
        tldr_examples_reload_needed = True
        tldr_ui_reload = True
        msg_to_show = None

        page_tldr_search = PageSelectTLDR(self.drawer)

        while True:
            # TODO fix "alt+d" crash
            if tldr_options_reload_needed:
                tldr_options_reload_needed = False
                input_data = InputParser.parse_input(
                    self.search_field.get_text_lower(), is_search_mode=True)
                if tldr_parser_thread:
                    tldr_parser_thread.stop()
                tldr_parser_thread = TLDRParseThread(tldr_parser, input_data)
                tldr_parser_thread.start()
                tldr_options_waiting = True

            if tldr_options_waiting and not tldr_parser_thread.is_alive():
                tldr_options_waiting = False
                self.tldr_options = tldr_parser_thread.get_result_tldr_options(
                )
                self.update_tldr_options_to_draw()
                tldr_examples_reload_needed = True
                tldr_ui_reload = True

            if tldr_examples_reload_needed:
                tldr_examples_reload_needed = False
                if len(self.tldr_options_draw) > 0:
                    tldr_page_match = self.tldr_options_draw[
                        self.tldr_options_draw_index]
                    self.tldr_examples = tldr_parser.get_tldr_cmd_examples(
                        tldr_page_match)
                    self.update_tldr_example_to_draw()
                    self.update_tldr_options_to_draw_cmd_availability()
                    # reset example index
                    self.tldr_examples_index = self.tldr_examples.get_first_example_index(
                    )
                    self.tldr_examples_draw_index = self.tldr_examples_index
                else:
                    self.tldr_examples = ParsedTLDRExample()
                    self.tldr_examples_index = 0
                    self.tldr_examples_draw = []

            if page_tldr_search.has_minimum_size():
                page_tldr_search.draw_page(
                    search_filters=self.search_field,
                    input_data=input_data,
                    tldr_options_draw=self.tldr_options_draw,
                    tldr_options_draw_index=self.tldr_options_draw_index,
                    tldr_examples_draw=self.tldr_examples_draw,
                    example_draw_index=self.tldr_examples_draw_index,
                    example_content_shift=self.example_content_shift,
                    focus_area=self.focus,
                    has_url_more_info=self.tldr_examples.has_url_more_info(),
                    is_waiting=tldr_options_waiting,
                    msg_to_show=msg_to_show)

            if msg_to_show:
                msg_to_show = None

            # wait for char
            c = self.drawer.wait_next_char(
                multi_threading_mode=tldr_parser_thread.is_alive())
            logging.debug("pressed key: %s" % repr(c))

            tldr_ui_reload = True
            if c == Keys.KEY_TIMEOUT:
                tldr_ui_reload = False
                continue
            elif c in Keys.KEYS_ENTER:
                selected_example = self.get_selected_example(
                    search_input=input_data)
                if selected_example:
                    return [True, [True, selected_example]]
            elif c == Keys.KEY_CTRL_SPACE:
                example_to_copy = self.get_selected_example(
                    search_input=input_data, copied=True)
                if example_to_copy:
                    msg_to_show = ConsoleUtils.copy_to_clipboard(
                        example_to_copy, show_data_in_msg=False)[1]
            elif c == Keys.KEY_CTRL_L:
                if self.tldr_examples.has_url_more_info():
                    msg_to_show = ConsoleUtils.copy_to_clipboard(
                        self.tldr_examples.get_url_more_info())[1]
            elif c == Keys.KEY_CTRL_E:
                res = ConsoleUtils.copy_to_clipboard(
                    self.tldr_examples.get_tldr_github_page())
                msg_to_show = res[1]
            elif c == Keys.KEY_TAB:
                self.flip_focus()
            # go back to main page
            elif c == Keys.KEY_CTRL_F or c == Keys.KEY_CTRL_D or c == Keys.KEY_ESC:
                return [False, 0]
            elif c == Keys.KEY_UP:
                if self.move_up():
                    tldr_examples_reload_needed = True
            elif c == Keys.KEY_DOWN:
                if self.move_down():
                    tldr_examples_reload_needed = True
            # -> command
            elif c == Keys.KEY_RIGHT:
                self.move_right()
            # <- command
            elif c == Keys.KEY_LEFT:
                self.move_left()
            # this occurs when the console size changes
            elif c == Keys.KEY_RESIZE:
                self.drawer.reset()
                self.search_field.set_max_x(self.drawer.get_max_x(),
                                            with_margin_x=True)
                self.update_tldr_options_to_draw()
            # move cursor to the beginning
            elif c == Keys.KEY_START or c == Keys.KEY_CTRL_A:
                self.search_field.move_cursor_to_start()
                self.example_content_shift.reset_context_shifted()
                self.focus = PageSelectTLDR.Focus.AREA_FILES
            # move cursor to the end
            elif c == Keys.KEY_CTRL_E:
                self.search_field.move_cursor_to_end()
                self.example_content_shift.reset_context_shifted()
                self.focus = PageSelectTLDR.Focus.AREA_FILES
            elif c == Keys.KEY_CTRL_U:
                if self.search_field.set_text(""):
                    tldr_options_reload_needed = True
            # delete a char of the search
            elif c in Keys.KEYS_DELETE:
                if self.delete_char():
                    tldr_options_reload_needed = True
            # normal search char
            elif type(c) is str:
                if self.add_str(c):
                    tldr_options_reload_needed = True
            else:
                logging.error("input not handled: %s" % repr(c))