Exemple #1
0
    def __init__(self):
        self.lgr = logging.getLogger('setting')
        self.trans = TranslateIt('')
        self.__ROOT_CFG_PATH = os.path.expanduser("~")
        self.__CONFIG_NAME = ".trans"
        self.__config = _DEFAULT_CONFIG

        self.check_path()

        if self.loadConfig():
            if self.keyIsValid(self.yandex_api_key):
                self.status_key = True
            else:
                self.status_key = False
Exemple #2
0
 def __init__(self):
     Gtk.Application.__init__(self,
                              flags=Gio.ApplicationFlags.HANDLES_COMMAND_LINE)
     self.lgr = logging.getLogger('')
     self.settings = SettingManager()
     self._translator = TranslateIt(self.settings.yandex_api_key)
Exemple #3
0
class SettingManager:
    def __init__(self):
        self.lgr = logging.getLogger('setting')
        self.trans = TranslateIt('')
        self.__ROOT_CFG_PATH = os.path.expanduser("~")
        self.__CONFIG_NAME = ".trans"
        self.__config = _DEFAULT_CONFIG

        self.check_path()

        if self.loadConfig():
            if self.keyIsValid(self.yandex_api_key):
                self.status_key = True
            else:
                self.status_key = False

    def check_path(self):
        if not os.path.exists(self.__ROOT_CFG_PATH):
            raise OSError(2, 'No such file or directory')
        if not os.path.isdir(self.__ROOT_CFG_PATH):
            raise Exception('Invalid config path')

        if not os.access(self.__ROOT_CFG_PATH, os.W_OK):
            raise Exception('Access wrote in path fail')

        if not os.path.exists(self.config_name):
            self.lgr.warning('No config file try create: ')
            self.saveConfig()
            # raise Exception('No config file!')
        return True

    @property
    def config_name(self):
        return self.__ROOT_CFG_PATH + '/' + self.__CONFIG_NAME

    @config_name.setter
    # @debug
    def config_name(self, new_name):
        """
        ONLY FOR DEBUG!
        :param new_name: string  $HOME full path cfg is($HOME + /.trans)
        :return:
        """
        # set invalid name!
        self.__ROOT_CFG_PATH = new_name

    def get_cfg_value(self, key):
        if key not in self.config:
            self.lgr.error("No key '%s' in config... ", key)
            # warning!
            return None
        else:
            return self.config[key]

    def set_cfg_value(self, key, val):
        if val is None:
            self.lgr.error("Skip null value for key %s", key)
            return False

        if key not in self.config:
            if key in _DEFAULT_CONFIG:
                self.lgr.debug('CFG without key %s - add new', key)
                self.config[key] = val
                return True
            else:
                self.lgr.error('Key %s invalid for $VERSION: %s', key, _VERSION)
                return False
        else:
            self.config[key] = val
            return True

    @property
    def config(self):
        """
        setup cfg from config file
        :return: dict{} example see _DEFAULT_CONFIG
        """
        if self.__config is None:
            self.lgr.error("config is None... halt?...")
        return self.__config

    @config.setter
    def config(self, cfg):
        if cfg is not None:
            self.__config = cfg

    @property
    def window_size(self):
        """
        Setup main wnd size width and height
            :return: wingeometry.Size()
        """
        return Size(self.get_cfg_value('WIDTH'), self.get_cfg_value('HEIGHT'))

    @window_size.setter
    def window_size(self, _size):
        if not type(_size) is Size:
            self.lgr.debug("The Size param required  '%s' received ", type(_size))
            raise ValueError()

        if not self.set_cfg_value('WIDTH', _size.WIDTH):
            self.lgr.warning("Fail save width window...")

        if not self.set_cfg_value('HEIGHT', _size.HEIGHT):
            self.lgr.warning("Fail save HEIGHT window...")

    @property
    def window_position(self):
        """
        Setup Position Main window (TOP / LEFT)
            :return: wingeometry.Pos()
        """
        return Pos(self.get_cfg_value('POS_TOP'), self.get_cfg_value('POS_LEFT'))

    @window_position.setter
    def window_position(self, new_pos):
        if not self.set_cfg_value('POS_TOP', new_pos.TOP):
            self.lgr.warning("Failed save '%d' top position window ", new_pos.TOP)

        if not self.set_cfg_value('POS_LEFT', new_pos.LEFT):
            self.lgr.warning("Failed save '%d' top position window ", new_pos.LEFT)

    @property
    def switch(self):
        """
        Store status switch in setting
            :return: Boolean True / False
        """
        switch = self.get_cfg_value('SWITCH')

        if switch is not None:
            type_val = type(switch)
            if type_val is bool:
                return self.get_cfg_value('SWITCH')
            else:
                self.lgr.error('Wrong type of switch `%s`, Boolean required!', type_val)
        else:
            self.lgr.error('Switch not determined in the configuration file')
        # by default
        return False

    @switch.setter
    def switch(self, state=0):
        self.set_cfg_value('SWITCH', state)

    @property
    def single_mode(self):
        """
        store View All / Single
            :return: Boolean True / False
        """
        show_all = self.get_cfg_value('SHOW_ALL')
        if show_all is not None:
            if type(show_all) is bool:
                return show_all
            else:
                self.lgr.debug('wrong cfg value, use default')

        return False

    @single_mode.setter
    def single_mode(self, state):
        self.set_cfg_value('SHOW_ALL', state)

    @property
    def yandex_api_key(self):
        """
        Store yandex Key need for translation
            :return: string
        """
        return self.get_cfg_value('API_KEY')

    @yandex_api_key.setter
    def yandex_api_key(self, __key):
        if not self.keyIsValid(__key):
            raise ValueError('Invalid key API')
        else:
            self.set_cfg_value('API_KEY', __key)
        self.saveConfig()

    def keyIsValid(self, __key):
        return self.trans.valid_key(__key)

    def loadConfig(self):
        self.lgr.debug('load from %s', self.config_name)
        config_name = self.config_name

        try:
            if not os.path.exists(config_name):
                self.lgr.debug('File "%s" doesnt exist...', config_name)
                return False

            with open(config_name, 'r') as f:
                config = json.load(f)
        except Exception as err:
            self.lgr.exception('Failed load "%s" cfg: %s',
                               config_name, err)
            return False

        if config is not None:
            self.config = config
        else:
            self.lgr.error('Error load setting!')
        return True

    def saveConfig(self):
        self.lgr.debug('Save config %s', self.config_name)

        try:
            with open(self.config_name, 'w') as f:
                status = json.dump(self.config, f)
        except Exception as err:
            self.lgr.exception('Failed save "%s": %s ',
                               self.config_name, err)
            return False

        return True
Exemple #4
0
class TransApplication(Gtk.Application):
    def __init__(self):
        Gtk.Application.__init__(self,
                                 flags=Gio.ApplicationFlags.HANDLES_COMMAND_LINE)
        self.lgr = logging.getLogger('')
        self.settings = SettingManager()
        self._translator = TranslateIt(self.settings.yandex_api_key)

    def do_startup(self):
        Gtk.Application.do_startup(self)

    def do_activate(self):
        if self.create_main_wnd():
            self.ok_run()
        else:
            self.show_get_apikey_dialog()

    def do_command_line(self, args):
        Gtk.Application.do_command_line(self, args)

        parser = argparse.ArgumentParser()
        parser.add_argument('-v', '--verbose', action='store_true',
                            help='set logger level to verbose')
        args = parser.parse_args(args.get_arguments()[1:])

        if args.verbose:
            print('DEBUG mode on..')
            self.create_logger(logging.DEBUG)
        else:
            self.create_logger()

        self.do_activate()
        return 0

    def do_shutdown(self):
        exit(0)

    def ok_run(self):
        self.timer.start()
        self.load_other_settings()

        if self.settings.single_mode:
            self.lgr.debug('Single mode = True')
            self.win.clipboard_primary_status = not self.settings.switch
            self.win.clipboard_selection_status = self.settings.switch

        else:
            self.win.clipboard_primary_status = not self.settings.switch
            self.win.clipboard_selection_status = True

    def msg_dialog_global_err(self):
        dialog = Gtk.MessageDialog(transient_for=self.win,
                                   destroy_with_parent=True,
                                   message_type=Gtk.MessageType.ERROR,
                                   buttons=Gtk.ButtonsType.OK,
                                   modal=True,
                                   text="Connection aborted: Temporary failure in name resolution")
        dialog.run()
        dialog.destroy()

    def show_get_apikey_dialog(self):
        self.key_wnd = guigetkey.GeTokenWnd(self)
        self.key_wnd.wnd.set_transient_for(self.win)
        self.key_wnd.wnd.set_modal(True)
        self.key_wnd.wnd.connect("response", self.get_api_dialog_response)
        self.key_wnd.wnd.show_all()

    def get_api_dialog_response(self, widget, response_id):
        if response_id == Gtk.ResponseType.OK:
            key = self.key_wnd.edit.get_text()
            if not self.settings.keyIsValid(key):
                self.lgr.debug('The key "%s" is not passed server validation', key)
                self.key_wnd.show_error('invalid key!')
                return 0
            else:
                # 3 time key_valid run!
                self.settings.yandex_api_key = key
                self._translator.key = key
                self.ok_run()
        else:
            self.quit()
        widget.destroy()

    # timer use there!
    def timer_start(self):
        self.timer.work = True

    def timer_stop(self):
        self.timer.work = False

    def timer_halt(self):
        self.timer.work = False
        self.timer.halt()

    def translate(self, txt):
        if len(txt) > 1:
            return self._translator.translate(txt)
        else:
            self.lgr.debug('skip text (len <=1)')

    def create_logger(self, level=logging.ERROR):
        ch = logging.StreamHandler()
        formt = logging.Formatter('%(levelname)s: \t%(asctime)s | %(process)d | %(lineno)d: '
                                  '%(module)s.%(funcName)s | %(name)s  | %(message)s')
        ch.setFormatter(formt)

        self.lgr.setLevel(level)
        ch.setLevel(level)

        self.lgr.addHandler(ch)
        self.lgr.info('Load logger done: ')

    # timer call back fn:
    def callback_end_time(self):
        """callback for timer"""
        self.win.pb.set_visible(False)

        if not self.win.clipboard_primary_status:
            self.lgr.debug('Clipboard primary disable...')
            return False
        txt = self.win.primary_text

        if len(txt) < 1:
            self.lgr.debug('The text is too short: %s`', txt)
            return False

        answer = self.translate(txt)
        self.win.translated_primary_text = answer

    # timer tick call back:
    def call_back_pulse(self):
        self.win.pb.pulse()

    # settings:
    def load_other_settings(self):
        self.win.single_mode = self.settings.single_mode
        if self.win.single_mode:
            self.act_view_behavior_single.activate()

        if self.win.switch.get_state() == self.settings.switch:
            # on  switch setup: clipboard_primary_status /clipboard_selection_status
            self.win.on_switch_change(self.win.switch, None)
        else:
            self.win.switch.set_state(self.settings.switch)

    def load_window_geometry(self):
        pos_from_setting = self.settings.window_position
        self.lgr.debug('Set window position `%d`x`%d` ', pos_from_setting.TOP, pos_from_setting.LEFT)
        self.win.move(pos_from_setting.TOP, pos_from_setting.LEFT)

        size_from_setting = self.settings.window_size
        self.lgr.debug("Set window size `%d`x`%d` ", size_from_setting.WIDTH, size_from_setting.HEIGHT)
        self.win.set_default_size(size_from_setting.WIDTH, size_from_setting.HEIGHT)

    def save_settings(self):
        current_win_pos = self.win.get_position()
        _pos = Pos(current_win_pos[0], current_win_pos[1])
        self.lgr.info('save windows position: %d x %d', _pos.TOP, _pos.LEFT)
        self.settings.window_position = _pos

        current_win_size = self.win.get_size()
        _size = Size(current_win_size[0], current_win_size[1])
        self.lgr.info('windows size to save: %d x %d', _size.WIDTH, _size.HEIGHT)
        self.settings.window_size = _size

        self.settings.single_mode = self.win.single_mode
        self.settings.switch = self.win.switch.get_active()
        self.settings.saveConfig()

    # actions:
    def on_close_mainwnd(self, *args):
        self.act_quit.activate()

    def act_quit_execute(self, action, parameter):
        self.timer_halt()
        self.save_settings()
        self.quit()

    # velodrome
    def view_behavior_all(self, act, *args):
        self.gsubmenu.remove_all()
        self.gsubmenu.append('* all', "app.view_all")
        self.gsubmenu.append('single', "app.view_single")
        self.win.single_mode = False

    def view_behavior_single(self, act, *args):
        self.gsubmenu.remove_all()
        self.gsubmenu.append('all', "app.view_all")
        self.gsubmenu.append('* single', "app.view_single")
        self.win.single_mode = True

    # GUI:
    def create_main_wnd(self):
        """
        Create Main window
            :return: True if yandex api key is valid
        """
        self.win = MainWnd(self)

        self.add_window(self.win)
        self.menu_main = Gio.Menu()
        self.gsubmenu = Gio.Menu()

        self.menu_main.append_submenu('show', self.gsubmenu)
        # self.radio_all = True -> * show all esle show single
        self.gsubmenu.append('* all', "app.view_all")
        self.gsubmenu.append('single', "app.view_single")

        self.menu_main.append("About", "app.about")
        self.menu_main.append("_____________")
        self.menu_main.append("Quit", "app.quit")

        self.set_app_menu(self.menu_main)

        self.timer = Timer(self.callback_end_time, self.call_back_pulse)

        self.win.connect("delete_event", self.on_close_mainwnd)

        self.act_view_behavior_all = Gio.SimpleAction.new("view_all", None)
        self.act_view_behavior_all.connect("activate", self.view_behavior_all)
        self.add_action(self.act_view_behavior_all)

        self.act_view_behavior_single = Gio.SimpleAction.new("view_single", None)
        self.act_view_behavior_single.connect("activate", self.view_behavior_single)
        self.add_action(self.act_view_behavior_single)

        self.act_about = Gio.SimpleAction.new("about", None)
        self.act_about.connect("activate", self.win.act_about_execute)
        self.add_action(self.act_about)

        self.act_quit = Gio.SimpleAction.new("quit", None)
        self.act_quit.connect("activate", self.act_quit_execute)
        self.add_action(self.act_quit)

        self.load_window_geometry()
        self.win.show_all()

        status_key = self.settings.keyIsValid(self.settings.yandex_api_key)

        if status_key:
            if status_key == yatranslate.ERR_CONNECTION_ABORTED:
                self.lgr.error('Cannot connect to server, exit..')
                self.msg_dialog_global_err()
                sys.exit(0)
            return True

        return False