Blame engine/main.py

Packit Service 6a275b
# -*- coding: utf-8 -*-
Packit Service 6a275b
# vim:et sts=4 sw=4
Packit Service 6a275b
#
Packit Service 6a275b
# ibus-typing-booster - A completion input method for IBus
Packit Service 6a275b
#
Packit Service 6a275b
# Copyright (c) 2011-2013 Anish Patil <apatil@redhat.com>
Packit Service 6a275b
# Copyright (c) 2012-2018 Mike FABIAN <mfabian@redhat.com>
Packit Service 6a275b
#
Packit Service 6a275b
# This program is free software: you can redistribute it and/or modify
Packit Service 6a275b
# it under the terms of the GNU General Public License as published by
Packit Service 6a275b
# the Free Software Foundation, either version 3 of the License, or
Packit Service 6a275b
# (at your option) any later version.
Packit Service 6a275b
#
Packit Service 6a275b
# This program is distributed in the hope that it will be useful,
Packit Service 6a275b
# but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 6a275b
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 6a275b
# GNU General Public License for more details.
Packit Service 6a275b
#
Packit Service 6a275b
# You should have received a copy of the GNU General Public License
Packit Service 6a275b
# along with this program.  If not, see <http://www.gnu.org/licenses/>
Packit Service 6a275b
Packit Service 6a275b
import os
Packit Service 6a275b
import sys
Packit Service 6a275b
import argparse
Packit Service 6a275b
import time
Packit Service 6a275b
from gi import require_version
Packit Service 6a275b
require_version('IBus', '1.0')
Packit Service 6a275b
from gi.repository import IBus
Packit Service 6a275b
from gi.repository import GLib
Packit Service 6a275b
import re
Packit Service 6a275b
from signal import signal, SIGTERM, SIGINT
Packit Service 6a275b
Packit Service 6a275b
import factory
Packit Service 6a275b
import tabsqlitedb
Packit Service 6a275b
import version
Packit Service 6a275b
Packit Service 6a275b
DEBUG_LEVEL = int(0)
Packit Service 6a275b
try:
Packit Service 6a275b
    DEBUG_LEVEL = int(os.getenv('IBUS_TYPING_BOOSTER_DEBUG_LEVEL'))
Packit Service 6a275b
except (TypeError, ValueError):
Packit Service 6a275b
    DEBUG_LEVEL = int(0)
Packit Service 6a275b
Packit Service 6a275b
try:
Packit Service 6a275b
    ICON_DIR = os.path.join(
Packit Service 6a275b
        os.getenv('IBUS_TYPING_BOOSTER_LOCATION'),
Packit Service 6a275b
        'icons')
Packit Service 6a275b
except:
Packit Service 6a275b
    ICON_DIR = os.path.join(
Packit Service 6a275b
        version.get_prefix(), 'share/ibus-typing-booster/icons')
Packit Service 6a275b
Packit Service 6a275b
try:
Packit Service 6a275b
    SETUP_TOOL = os.path.join(
Packit Service 6a275b
        os.getenv('IBUS_TYPING_BOOSTER_LIB_LOCATION'),
Packit Service 6a275b
        'ibus-setup-typing-booster')
Packit Service 6a275b
except:
Packit Service 6a275b
    SETUP_TOOL = os.path.join(
Packit Service 6a275b
        version.get_prefix(),
Packit Service 6a275b
        'libexec/ibus-setup-typing-booster')
Packit Service 6a275b
Packit Service 6a275b
def parse_args():
Packit Service 6a275b
    '''Parse the command line arguments'''
Packit Service 6a275b
    parser = argparse.ArgumentParser()
Packit Service 6a275b
    parser.add_argument(
Packit Service 6a275b
        '--daemon', '-d',
Packit Service 6a275b
        action = 'store_true',
Packit Service 6a275b
        dest = 'daemon',
Packit Service 6a275b
        default = False,
Packit Service 6a275b
        help = 'Run as daemon, default: %(default)s')
Packit Service 6a275b
    parser.add_argument(
Packit Service 6a275b
        '--ibus', '-i',
Packit Service 6a275b
        action = 'store_true',
Packit Service 6a275b
        dest = 'ibus',
Packit Service 6a275b
        default = False,
Packit Service 6a275b
        help = 'Set the IME icon file, default: %(default)s')
Packit Service 6a275b
    parser.add_argument(
Packit Service 6a275b
        '--xml', '-x',
Packit Service 6a275b
        action = 'store_true',
Packit Service 6a275b
        dest = 'xml',
Packit Service 6a275b
        default = False,
Packit Service 6a275b
        help = 'output the engines xml part, default: %(default)s')
Packit Service 6a275b
    parser.add_argument(
Packit Service 6a275b
        '--no-debug', '-n',
Packit Service 6a275b
        action = 'store_true',
Packit Service 6a275b
        dest = 'no_debug',
Packit Service 6a275b
        default = False,
Packit Service 6a275b
        help = 'Do not redirect stdout and stderr to '
Packit Service 6a275b
        + '~/.local/share/ibus-typing-booster/debug.log, '
Packit Service 6a275b
        + 'default: %(default)s')
Packit Service 6a275b
    parser.add_argument(
Packit Service 6a275b
        '--profile', '-p',
Packit Service 6a275b
        action = 'store_true',
Packit Service 6a275b
        dest = 'profile',
Packit Service 6a275b
        default = False,
Packit Service 6a275b
        help = 'print profiling information into the debug log. '
Packit Service 6a275b
        + 'Works only when --no-debug is not used.')
Packit Service 6a275b
    return parser.parse_args()
Packit Service 6a275b
Packit Service 6a275b
_ARGS = parse_args()
Packit Service 6a275b
Packit Service 6a275b
if _ARGS.profile:
Packit Service 6a275b
    import cProfile, pstats
Packit Service 6a275b
    _PROFILE = cProfile.Profile()
Packit Service 6a275b
Packit Service 6a275b
class IMApp:
Packit Service 6a275b
    def __init__(self, exec_by_ibus):
Packit Service 6a275b
        if DEBUG_LEVEL > 1:
Packit Service 6a275b
            sys.stderr.write(
Packit Service 6a275b
                "IMApp.__init__(exec_by_ibus=%s)\n"
Packit Service 6a275b
                % exec_by_ibus)
Packit Service 6a275b
        self.__mainloop = GLib.MainLoop()
Packit Service 6a275b
        self.__bus = IBus.Bus()
Packit Service 6a275b
        self.__bus.connect("disconnected", self.__bus_destroy_cb)
Packit Service 6a275b
        self.__factory = factory.EngineFactory(self.__bus)
Packit Service 6a275b
        self.destroyed = False
Packit Service 6a275b
        if exec_by_ibus:
Packit Service 6a275b
            self.__bus.request_name(
Packit Service 6a275b
                "org.freedesktop.IBus.IbusTypingBooster", 0)
Packit Service 6a275b
        else:
Packit Service 6a275b
            self.__component = IBus.Component(
Packit Service 6a275b
                name="org.freedesktop.IBus.IbusTypingBooster",
Packit Service 6a275b
                description="Typing Booster Component",
Packit Service 6a275b
                version=version.get_version(),
Packit Service 6a275b
                license="GPL",
Packit Service 6a275b
                author="Mike FABIAN <mfabian@redhat.com>, Anish Patil <anish.developer@gmail.com>",
Packit Service 6a275b
                homepage="http://mike-fabian.github.io/ibus-typing-booster",
Packit Service 6a275b
                textdomain="ibus-typing-booster")
Packit Service 6a275b
            # now we get IME info from self.__factory.db
Packit Service 6a275b
            name = 'typing-booster'
Packit Service 6a275b
            longname = 'Typing Booster'
Packit Service 6a275b
            description = 'A completion input method to speedup typing.'
Packit Service 6a275b
            language = 't'
Packit Service 6a275b
            author = (
Packit Service 6a275b
                'Mike FABIAN <mfabian@redhat.com>'
Packit Service 6a275b
                + ', Anish Patil <anish.developer@gmail.com>')
Packit Service 6a275b
            icon = os.path.join(ICON_DIR, 'ibus-typing-booster.svg')
Packit Service 6a275b
            if not os.access(icon, os.F_OK):
Packit Service 6a275b
                icon = ''
Packit Service 6a275b
            layout = 'default'
Packit Service 6a275b
            symbol = '🚀'
Packit Service 6a275b
Packit Service 6a275b
            engine = IBus.EngineDesc(name=name,
Packit Service 6a275b
                                     longname=longname,
Packit Service 6a275b
                                     description=description,
Packit Service 6a275b
                                     language=language,
Packit Service 6a275b
                                     license='GPL',
Packit Service 6a275b
                                     author=author,
Packit Service 6a275b
                                     icon=icon,
Packit Service 6a275b
                                     layout=layout,
Packit Service 6a275b
                                     symbol=symbol)
Packit Service 6a275b
            self.__component.add_engine(engine)
Packit Service 6a275b
            self.__bus.register_component(self.__component)
Packit Service 6a275b
Packit Service 6a275b
    def run(self):
Packit Service 6a275b
        if DEBUG_LEVEL > 1:
Packit Service 6a275b
            sys.stderr.write("IMApp.run()\n")
Packit Service 6a275b
        if _ARGS.profile:
Packit Service 6a275b
            _PROFILE.enable()
Packit Service 6a275b
        self.__mainloop.run()
Packit Service 6a275b
        self.__bus_destroy_cb()
Packit Service 6a275b
Packit Service 6a275b
    def quit(self):
Packit Service 6a275b
        if DEBUG_LEVEL > 1:
Packit Service 6a275b
            sys.stderr.write("IMApp.quit()\n")
Packit Service 6a275b
        self.__bus_destroy_cb()
Packit Service 6a275b
Packit Service 6a275b
    def __bus_destroy_cb(self, bus=None):
Packit Service 6a275b
        if DEBUG_LEVEL > 1:
Packit Service 6a275b
            sys.stderr.write("IMApp.__bus_destroy_cb(bus=%s)\n" % bus)
Packit Service 6a275b
        if self.destroyed:
Packit Service 6a275b
            return
Packit Service 6a275b
        print("finalizing:)")
Packit Service 6a275b
        self.__factory.do_destroy()
Packit Service 6a275b
        self.destroyed = True
Packit Service 6a275b
        self.__mainloop.quit()
Packit Service 6a275b
        if _ARGS.profile:
Packit Service 6a275b
            _PROFILE.disable()
Packit Service 6a275b
            stats = pstats.Stats(_PROFILE)
Packit Service 6a275b
            stats.strip_dirs()
Packit Service 6a275b
            stats.sort_stats('cumulative')
Packit Service 6a275b
            stats.print_stats('tabsqlite', 25)
Packit Service 6a275b
            stats.print_stats('hunspell_suggest', 25)
Packit Service 6a275b
            stats.print_stats('hunspell_table', 25)
Packit Service 6a275b
            stats.print_stats('itb_emoji', 25)
Packit Service 6a275b
Packit Service 6a275b
def cleanup (ima_ins):
Packit Service 6a275b
    ima_ins.quit()
Packit Service 6a275b
    sys.exit()
Packit Service 6a275b
Packit Service 6a275b
def indent(elem, level=0):
Packit Service 6a275b
    '''Use to format xml Element pretty :)'''
Packit Service 6a275b
    i = "\n" + level*"    "
Packit Service 6a275b
    if len(elem):
Packit Service 6a275b
        if not elem.text or not elem.text.strip():
Packit Service 6a275b
            elem.text = i + "    "
Packit Service 6a275b
        for e in elem:
Packit Service 6a275b
            indent(e, level+1)
Packit Service 6a275b
            if not e.tail or not e.tail.strip():
Packit Service 6a275b
                e.tail = i + "    "
Packit Service 6a275b
        if not e.tail or not e.tail.strip():
Packit Service 6a275b
            e.tail = i
Packit Service 6a275b
    else:
Packit Service 6a275b
        if level and (not elem.tail or not elem.tail.strip()):
Packit Service 6a275b
            elem.tail = i
Packit Service 6a275b
Packit Service 6a275b
def main():
Packit Service 6a275b
    '''Main program'''
Packit Service 6a275b
    if not _ARGS.xml and not _ARGS.no_debug:
Packit Service 6a275b
        if not os.access(
Packit Service 6a275b
                os.path.expanduser('~/.local/share/ibus-typing-booster'),
Packit Service 6a275b
                os.F_OK):
Packit Service 6a275b
            os.system('mkdir -p ~/.local/share/ibus-typing-booster')
Packit Service 6a275b
        logfile = os.path.expanduser(
Packit Service 6a275b
            '~/.local/share/ibus-typing-booster/debug.log')
Packit Service 6a275b
        sys.stdout = open(logfile, mode='a', buffering=1)
Packit Service 6a275b
        sys.stderr = open(logfile, mode='a', buffering=1)
Packit Service 6a275b
        print('--- Starting: %s ---' %time.strftime('%Y-%m-%d: %H:%M:%S'))
Packit Service 6a275b
Packit Service 6a275b
    if _ARGS.xml:
Packit Service 6a275b
        from xml.etree.ElementTree import Element, SubElement, tostring
Packit Service 6a275b
Packit Service 6a275b
        egs = Element('engines')
Packit Service 6a275b
Packit Service 6a275b
        for language in ('t',):
Packit Service 6a275b
            _engine = SubElement (egs,'engine')
Packit Service 6a275b
Packit Service 6a275b
            _name = SubElement (_engine, 'name')
Packit Service 6a275b
            _name.text = 'typing-booster'
Packit Service 6a275b
Packit Service 6a275b
            _longname = SubElement (_engine, 'longname')
Packit Service 6a275b
            _longname.text = 'Typing Booster'
Packit Service 6a275b
Packit Service 6a275b
            _language = SubElement (_engine, 'language')
Packit Service 6a275b
            _language.text = language
Packit Service 6a275b
Packit Service 6a275b
            _license = SubElement (_engine, 'license')
Packit Service 6a275b
            _license.text = 'GPL'
Packit Service 6a275b
Packit Service 6a275b
            _author = SubElement (_engine, 'author')
Packit Service 6a275b
            _author.text = (
Packit Service 6a275b
                'Mike FABIAN <mfabian@redhat.com>'
Packit Service 6a275b
                + ', Anish Patil <anish.developer@gmail.com>')
Packit Service 6a275b
Packit Service 6a275b
            _icon = SubElement (_engine, 'icon')
Packit Service 6a275b
            _icon.text = os.path.join(ICON_DIR, 'ibus-typing-booster.svg')
Packit Service 6a275b
Packit Service 6a275b
            _layout = SubElement (_engine, 'layout')
Packit Service 6a275b
            _layout.text = 'default'
Packit Service 6a275b
Packit Service 6a275b
            _desc = SubElement (_engine, 'description')
Packit Service 6a275b
            _desc.text = 'A completion input method to speedup typing.'
Packit Service 6a275b
Packit Service 6a275b
            _symbol = SubElement(_engine,'symbol')
Packit Service 6a275b
            _symbol.text = '🚀'
Packit Service 6a275b
Packit Service 6a275b
            _setup = SubElement(_engine,'setup')
Packit Service 6a275b
            _setup.text = SETUP_TOOL
Packit Service 6a275b
Packit Service 6a275b
        # now format the xmlout pretty
Packit Service 6a275b
        indent (egs)
Packit Service 6a275b
        egsout = tostring(egs, encoding='utf8', method='xml').decode('utf-8')
Packit Service 6a275b
        patt = re.compile('<\?.*\?>\n')
Packit Service 6a275b
        egsout = patt.sub('', egsout)
Packit Service 6a275b
        sys.stdout.buffer.write((egsout+'\n').encode('utf-8'))
Packit Service 6a275b
        return 0
Packit Service 6a275b
Packit Service 6a275b
    if _ARGS.daemon :
Packit Service 6a275b
        if os.fork():
Packit Service 6a275b
            sys.exit()
Packit Service 6a275b
Packit Service 6a275b
    ima = IMApp(_ARGS.ibus)
Packit Service 6a275b
    signal (SIGTERM, lambda signum, stack_frame: cleanup(ima))
Packit Service 6a275b
    signal (SIGINT, lambda signum, stack_frame: cleanup(ima))
Packit Service 6a275b
    try:
Packit Service 6a275b
        ima.run()
Packit Service 6a275b
    except KeyboardInterrupt:
Packit Service 6a275b
        ima.quit()
Packit Service 6a275b
Packit Service 6a275b
if __name__ == "__main__":
Packit Service 6a275b
    main()
Packit Service 6a275b