예제 #1
0
    def _handle_resize(self, user_input):
        logger.debug("[Controller] detect resize")

        self.header.reset()
        self.footer.reset()
        self._search_and_refresh_display(user_input,
                                         is_init_property=True,
                                         is_init_query=False)
예제 #2
0
    def _end_curses(self):
        """ Terminates the curses application. """
        logger.debug("[Controller] end curses")

        curses.nocbreak()
        self.stdscr.keypad(0)
        curses.echo()
        curses.endwin()
예제 #3
0
 def __init__(self, data):
     logger.debug("[Controller] init")
     self._init_curses()
     self.model = Model(data)
     self.header = Header(self.stdscr)
     self.search_result = SearchResult(self.stdscr, self.model)
     self.footer = Footer(self.stdscr, self.model)
     self.multibyte = Multibyte(self.stdscr)
예제 #4
0
 def execute_when_enter(self, current_selected):
     result = self.model.result
     if len(result) != 0:
         url = result[current_selected].get("url")
         webbrowser.open(url, new=2)
         logger.debug("[Controller] detect Enter. open url: %s" % url)
     else:
         logger.debug("[Controller] detect Enter. but result is empty.")
예제 #5
0
    def _init_curses(self):
        """ Inits the curses application """
        logger.debug("[Controller] init curses")

        # initscr() returns a window object representing the entire screen.
        self.stdscr = curses.initscr()
        color.init()

        # turn off automatic echoing of keys to the screen
        curses.noecho()
        # Enable non-blocking mode. keys are read directly, without hitting enter.
        curses.cbreak()
        # Able mouse cursor
        curses.curs_set(1)
        self.stdscr.keypad(1)
        # Enable colorous output.
        self.stdscr.refresh()
예제 #6
0
    def _search_and_refresh_display(self,
                                    user_input,
                                    is_init_property=False,
                                    is_init_query=True):
        # Disable mouse cursor
        curses.curs_set(0)

        self.search_result.reset()

        if is_init_property:
            self.search_result.init_properties_after_create()

        result = self.search_result.update_view_in_loop()

        if is_init_query:
            logger.debug("[Controller] reset query")
            self.search_result.update_query("")

        if result:
            self.search_result.handle_key_in_loop(user_input)
예제 #7
0
파일: cli.py 프로젝트: yukihirop/gfzs
 def handle_sigint(signum, frame):
     logger.debug("detect SIGINT (Ctrl-c)")
     logger.debug("exit 0")
     sys.exit(0)
예제 #8
0
파일: cli.py 프로젝트: yukihirop/gfzs
def main() -> None:
    # https://note.nkmk.me/python-warnings-ignore-warning/
    warnings.simplefilter("ignore", FutureWarning)

    parser = init_parser()
    exec_subcommand(parser)
    args = parser.parse_args()

    progname = "gfzs"
    properties = {
        "progname": progname,
        "severity": int(args.log_level),
        "log_path": args.log_path,
    }
    logger.init_properties(**properties)
    logger.debug("start %s" % progname)

    def handle_sigint(signum, frame):
        logger.debug("detect SIGINT (Ctrl-c)")
        logger.debug("exit 0")
        sys.exit(0)

    signal.signal(signal.SIGINT, handle_sigint)

    data = None
    error = None
    errors = []
    printable_len = 100
    runtime_opts.init(args)
    ttyname = tty.get_ttyname()

    with open_tty(ttyname) as tty_f:
        _ = tty.reconnect_descriptors(tty_f)

        try:
            json_str = sys.stdin.read()
            data = json.loads(json_str)
            validator = Model(data)
            runtime_config.init()

            if not runtime_config.valid():
                logger.debug("[print] Config is invalid.")
                print("Config is invalid.")
                errors = runtime_config.errors
                return
            elif not validator.valid():
                errors = validator.errors
                return
        except json.decoder.JSONDecodeError as e:
            logger.error(e)
            print("Error: %s" % e)
            if "[ERROR]" in json_str or len(json_str) <= printable_len:
                logger.error("Input data: %s" % json_str)
                print("Input data: %s" % json_str)
            else:
                logger.error("Input data (100 chars): %s ..." %
                             json_str[:printable_len])
                print("Input data (100 chars): %s ..." %
                      json_str[:printable_len])

            logger.debug("exit 1")
            sys.exit(1)
        except Exception as e:
            errors.append(e)
        finally:
            if errors != []:
                for error in errors:
                    logger.error(error)
                    print("Error: %s" % error)

                logger.debug("exit 1")
                sys.exit(1)

        controller = Controller(data)
        try:
            _ = controller.run()
        except curses.error as e:
            error = e
        except Exception as e:
            error = e
        finally:
            controller._end_curses()
            if error != None:
                logger.error(error)
                print(error)
                logger.debug("exit 1")
                sys.exit(1)

            logger.debug("end %s" % progname, new_line=True)
예제 #9
0
    def run(self) -> int:
        input_mode = True
        user_input = ""
        box_select_begin_y = 2
        arrow_keys = {
            curses.KEY_DOWN: "KEY_DOWN",
            curses.KEY_UP: "KEY_UP",
            curses.KEY_LEFT: "KEY_LEFT",
            curses.KEY_RIGHT: "KEY_RIGHT",
        }
        backspace_keys = {
            curses.ascii.BS: "ASCII_BS",
            curses.ascii.DEL: "ASCII_DEL",
            curses.KEY_BACKSPACE: "KEY_BACKSPACE",
        }

        self.header.create()

        self.search_result.create(box_select_begin_y)
        self.search_result.init_properties_after_create()
        self.search_result.update_view_in_loop()

        self.footer.create()
        self.footer.activate(is_init=True)

        while True:
            # stdscr.refresh is called in the process of updating the query of footer and disappears at that time
            self.header.create()

            if input_mode:
                self.footer.activate()
            else:
                self.search_result.update_view_in_loop()

            try:
                user_input = self.multibyte.getch()
            except curses.error:
                continue
            except KeyboardInterrupt:
                self._end_curses()
                break

            if input_mode:
                logger.debug("[Controller] input mode")
                if user_input in arrow_keys:
                    input_mode = False
                    logger.debug("[Controller] keyboard input: '%s'" %
                                 (arrow_keys[user_input]))
                    self._search_and_refresh_display(user_input,
                                                     is_init_query=False)
                elif user_input == KEY_ESC:
                    logger.debug(
                        "[Controller] keyboard input: 'KEY_ESC' (pass)")
                    pass
                elif user_input == KEY_ENTER:
                    input_mode = False
                    logger.debug(
                        "[Controller] keyboard input: 'KEY_ENTER'. query is '%s'"
                        % (self.model.query))
                    self._search_and_refresh_display(user_input,
                                                     is_init_query=False)
                # https://www.programcreek.com/python/?code=mingrammer%2Fawesome-finder%2Fawesome-finder-master%2Fawesome%2Ftui.py
                elif user_input in backspace_keys:
                    if self.model.query == "":
                        pass
                    else:
                        self.footer.delete_char()
                        self._search_and_refresh_display(user_input,
                                                         is_init_property=True,
                                                         is_init_query=False)
                elif user_input == curses.KEY_RESIZE:
                    logger.debug("[Controller] keyboard input: 'KEY_RESIZE'")
                    self._handle_resize(user_input)
                # I don't know the reason, but - 1 may come in
                elif user_input == -1:
                    pass
                else:
                    text = chr(user_input)
                    will_query = self.model.query + text
                    if self.model.validate_query(will_query):
                        self.footer.write(text)
                        self._search_and_refresh_display(user_input,
                                                         is_init_property=True,
                                                         is_init_query=False)
            else:
                logger.debug("[Controller] input mode")
                if user_input in arrow_keys:
                    self.search_result.handle_key_in_loop(user_input)
                elif user_input == KEY_ESC:
                    logger.debug(
                        "[Controller] keyboard input: 'KEY_ESC' (pass)")
                    pass
                elif user_input == KEY_ENTER:
                    self.execute_when_enter(
                        self.search_result.current_selected)
                elif user_input in backspace_keys:
                    logger.debug("[Controller] keyboard input: '%s'" %
                                 backspace_keys[user_input])
                    input_mode = True
                    self.footer.activate()
                    self.footer.delete_char()
                    self._search_and_refresh_display(user_input,
                                                     is_init_property=True,
                                                     is_init_query=False)
                elif user_input == curses.KEY_RESIZE:
                    self._handle_resize(user_input)
                # I don't know the reason, but - 1 may come in
                elif user_input == -1:
                    logger.unknown("[Controller] keyboard input: '-1'")
                    pass
                else:
                    input_mode = True
                    text = chr(user_input)
                    self.footer.activate()
                    self.footer.write(text)
예제 #10
0
    # local

    # https://codechacha.com/ja/how-to-import-python-files/
    sys.path.append(os.path.dirname(os.path.abspath(
        os.path.dirname(__file__))))
    import runtime.config as runtime_config
    import runtime.opts as runtime_opts

    progname = "gfzs.controller"
    properties = {
        "progname": progname,
        "severity": 0,
        "log_path": "./tmp/gfzs.log"
    }
    logger.init_properties(**properties)
    logger.debug("start %s" % progname)

    def handle_sigint(signum, frame):
        logger.debug("detect SIGINT (Ctrl-c)")
        logger.debug("exit 0")
        sys.exit(0)

    signal.signal(signal.SIGINT, handle_sigint)

    runtime_config.init()
    runtime_opts.init()
    if not runtime_config.valid():
        logger.debug("[prinnt] Config is invalid.")
        print("Config is invalid.")
        for error in runtime_config.errors:
            logger.error(error)