Skip to content

Commit

Permalink
port search provider to Gio.Application and Gio provided DBus bindings (
Browse files Browse the repository at this point in the history
  • Loading branch information
mufeedali authored Dec 5, 2023
2 parents 3a66d33 + ec98dc1 commit 8f050bc
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 51 deletions.
14 changes: 0 additions & 14 deletions build-aux/flatpak/pypi-dependencies.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,6 @@
}
]
},
{
"name": "python3-dbus-python",
"buildsystem": "simple",
"build-commands": [
"pip3 install --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"dbus-python\" --no-build-isolation"
],
"sources": [
{
"type": "file",
"url": "https://files.pythonhosted.org/packages/b1/5c/ccfc167485806c1936f7d3ba97db6c448d0089c5746ba105b6eb22dba60e/dbus-python-1.2.18.tar.gz",
"sha256": "92bdd1e68b45596c833307a5ff4b217ee6929a1502f5341bae28fd120acf7260"
}
]
},
{
"name": "python3-gtts",
"buildsystem": "simple",
Expand Down
123 changes: 86 additions & 37 deletions dialect/search_provider/search_provider.in
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,25 @@
# Copyright 2020 Nikita Kravets
# Copyright 2020-2022 Rafael Mardojai CM
# Copyright 2021-2022 Mufeed Ali
# Copyright 2023 Markus Göllnitz
# SPDX-License-Identifier: GPL-3.0-or-later

import sys
import logging
import locale
import gettext

import dbus
import dbus.service
from dbus.mainloop.glib import DBusGMainLoop

import gi

gi.require_version('Soup', '3.0')
from gi.repository import GLib
from gi.repository import GLib, Gio

from dialect.session import Session
from dialect.settings import Settings
from dialect.languages import get_lang_name
from dialect.providers import TRANSLATORS
from dialect.providers.base import ApiKeyRequired, InvalidApiKey

SEARCH_BUS_NAME = 'org.gnome.Shell.SearchProvider2'
SBN = dict(dbus_interface=SEARCH_BUS_NAME)

CLIPBOARD_PREFIX = 'copy-to-clipboard'
ERROR_PREFIX = 'translation-error'

Expand All @@ -39,17 +34,40 @@ ui_trans.install(names=['gettext'])
locale.bindtextdomain('dialect', localedir)
locale.textdomain('dialect')


class TranslateService(dbus.service.Object):
bus_name = '@[email protected]'
_object_path = '@object_path@'

dbus_interface_description = '''
<!DOCTYPE node PUBLIC
'-//freedesktop//DTD D-BUS Object Introspection 1.0//EN'
'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'>
<node>
<interface name="org.gnome.Shell.SearchProvider2">
<method name="GetInitialResultSet">
<arg type="as" name="terms" direction="in" />
<arg type="as" name="results" direction="out" />
</method>
<method name="GetSubsearchResultSet">
<arg type="as" name="previous_results" direction="in" />
<arg type="as" name="terms" direction="in" />
<arg type="as" name="results" direction="out" />
</method>
<method name="GetResultMetas">
<arg type="as" name="identifiers" direction="in" />
<arg type="aa{sv}" name="metas" direction="out" />
</method>
<method name="ActivateResult">
<arg type="s" name="identifier" direction="in" />
<arg type="as" name="terms" direction="in" />
<arg type="u" name="timestamp" direction="in" />
</method>
<method name="LaunchSearch">
<arg type="as" name="terms" direction="in" />
<arg type="u" name="timestamp" direction="in" />
</method>
</interface>
</node>
'''

class TranslateService:
def __init__(self):
# init dbus
self.session_bus = dbus.SessionBus()
bus_name = dbus.service.BusName(self.bus_name, bus=self.session_bus)
dbus.service.Object.__init__(self, bus_name, self._object_path)

self.loaded = False
self.load_failed = False

Expand All @@ -66,7 +84,6 @@ class TranslateService(dbus.service.Object):
Settings.get().connect('changed', self._on_settings_changed)
Settings.get().connect('translator-changed', self._on_translator_changed)

@dbus.service.method(in_signature='as', out_signature='as', **SBN)
def GetInitialResultSet(self, terms):
"""
Join separate terms in one ID line, start translation and send this line back
Expand All @@ -90,11 +107,9 @@ class TranslateService(dbus.service.Object):
)
]

@dbus.service.method(in_signature='asas', out_signature='as', **SBN)
def GetSubsearchResultSet(self, _previous_results, new_terms):
return self.GetInitialResultSet(new_terms)

@dbus.service.method(in_signature='as', out_signature='aa{sv}', **SBN)
def GetResultMetas(self, ids):
"""Send translated text"""

Expand All @@ -106,8 +121,8 @@ class TranslateService(dbus.service.Object):
text = self.translations[translate_id]
return [
{
'id': translate_id,
'name': text,
'id': GLib.Variant("s", translate_id),
'name': GLib.Variant("s", text),
}
]

Expand All @@ -121,34 +136,32 @@ class TranslateService(dbus.service.Object):

return [
{
'id': translate_id,
'name': text,
'description': description,
'id': GLib.Variant("s", translate_id),
'name': GLib.Variant("s", text),
'description': GLib.Variant("s", description),
},
{
'id': ids[1],
'name': _('Copy'),
'description': _('Copy translation to clipboard'),
'clipboardText': text,
'id': GLib.Variant("s", ids[1]),
'name': GLib.Variant("s", _('Copy')),
'description': GLib.Variant("s", _('Copy translation to clipboard')),
'clipboardText': GLib.Variant("s", text),
},
]

else:
# Probably never needed, just in case
return [
dict(
id=id,
name=id,
id=GLib.Variant("s", id),
name=GLib.Variant("s", id),
)
for id in ids
]

@dbus.service.method(in_signature='sasu', **SBN)
def ActivateResult(self, result_id, terms, timestamp):
if not result_id.startswith(CLIPBOARD_PREFIX):
self.LaunchSearch(terms, timestamp)

@dbus.service.method(in_signature='asu', terms='as', timestamp='u', **SBN)
def LaunchSearch(self, terms, _timestamp):
text = ' '.join(terms)
GLib.spawn_async_with_pipes(None, ['@BIN@', '--text', text], None, GLib.SpawnFlags.SEARCH_PATH, None)
Expand Down Expand Up @@ -229,7 +242,43 @@ class TranslateService(dbus.service.Object):
else:
self._load_translator()

class TranslateServiceApplication(Gio.Application):

def __init__(self):
Gio.Application.__init__(self,
application_id='@[email protected]',
flags=Gio.ApplicationFlags.IS_SERVICE,
inactivity_timeout=10000)
self.service_object = TranslateService()
self.search_interface = Gio.DBusNodeInfo.new_for_xml(dbus_interface_description).interfaces[0]

def do_dbus_register(self, connection, object_path):
try:
connection.register_object(object_path=object_path,
interface_info=self.search_interface,
method_call_closure=self.on_dbus_method_call)
except:
self.quit()
return False
finally:
return True

def on_dbus_method_call(self, connection, sender, object_path, interface_name, method_name, parameters, invocation):
self.hold()

method = getattr(self.service_object, method_name)
arguments = list(parameters.unpack())

results = method(*arguments),
if results == (None,):
results = ()
results_type = "(" + "".join(map(lambda argument_info: argument_info.signature, self.search_interface.lookup_method(method_name).out_args)) + ")"
wrapped_results = GLib.Variant(results_type, results)

invocation.return_value(wrapped_results)

self.release()

if __name__ == "__main__":
DBusGMainLoop(set_as_default=True)
TranslateService()
GLib.MainLoop().run()
app = TranslateServiceApplication()
sys.exit(app.run())

0 comments on commit 8f050bc

Please sign in to comment.