D-Bus examples

From Apertium
Revision as of 09:11, 3 February 2011 by 98.210.210.193 (talk)
Jump to navigation Jump to search

Here are some code snippets for various programming languages (complete with completely unnecessary comments) showing how you can interface with Apertium by means of D-Bus. You'll need to install the D-Bus service for Apertium.

Python

#!/usr/bin/python
# coding=utf-8
# -*- encoding: utf-8 -*-

import dbus, sys, codecs;

sys.stdin = codecs.getwriter('utf-8')(sys.stdin);
sys.stdout = codecs.getwriter('utf-8')(sys.stdout);

mode_name = 'en-af'; # The name of the installed mode

bus = dbus.SessionBus(); # Create a new session bus

# Get the translator
translator = dbus.Interface(bus.get_object('org.apertium.mode', '/'), 'org.apertium.Translate'); 

input = sys.stdin.read(); # Read the data

print translator.translate(mode_name, {}, input); # Print the translation

Java

See also: Installing the Java D-Bus bindings and Compiling a Java D-Bus program
import org.freedesktop.DBus;
import org.freedesktop.dbus.DBusConnection;
import org.freedesktop.dbus.exceptions.DBusException;

import org.apertium.Info; // The interface we use to access org.apertium.info/

class TestDBus {

        public static void main(String[] args) throws org.freedesktop.dbus.exceptions.DBusException {
                DBusConnection bus = null;
                Info info = null;

                bus = DBusConnection.getConnection(DBusConnection.SESSION);
                info = bus.getRemoteObject("org.apertium.info", "/", Info.class);

                for (String s : info.modes()) {
                        System.out.println(s);
                }

                bus.disconnect();
        }
}

In this program, we simply use the proxy object to invoke the modes</mode> method on the D-Bus object org.apertium.info. This returns a Java List<String>; we enumerate this list, printing each string.

C++

See also: Installing the C++ D-Bus bindings and Compiling a C++ D-Bus program
#include <map>
#include <iostream>
#include <sstream>
#include <string>

#include <dbus-c++/dbus.h>
#include "Translate-glue.h"

static const char* TRANSLATE_SERVICE_NAME = "org.apertium.mode";
static const char* TRANSLATE_OBJECT_PATH = "/";

class Translate
: public org::apertium::Translate,
  public DBus::IntrospectableProxy,
  public DBus::ObjectProxy
{
public:
    Translate(DBus::Connection& connection, const char* path, const char* name)
    : DBus::ObjectProxy(connection, path, name) {
    }
};

DBus::BusDispatcher dispatcher;

int main(int argc, char** argv) {
    DBus::default_dispatcher = &dispatcher;
    DBus::Connection bus = DBus::Connection::SessionBus();

    std::stringstream input;
    std::string mode;
    std::map< ::DBus::String, ::DBus::String> translate_options;

    if (argc != 2) {
        std::cerr << "usage: dbus_test <mode>" << std::endl;
        return 1;
    }

    mode = std::string(argv[1]);

    while (!std::cin.eof() and std::cin) {
        std::string str;
        std::cin >> str;
        input << str << " ";
    }

    Translate translator(bus, TRANSLATE_OBJECT_PATH, TRANSLATE_SERVICE_NAME);
    std::cout << translator.translate(mode, translate_options, input.str()) 
              << std::endl;
}

This program is a simple emulation of the main apertium program. It takes a single parameter, which is the translation mode (something like en-ca). It reads words from stdin and calls the method translate on the D-Bus proxy object translator to translate the text read from stdin. When the translation is complete, it writes the translated string to stdout.

Clojure

(import '(org.freedesktop.dbus DBusConnection))

(def bus (. DBusConnection (getConnection (. DBusConnection SESSION))))
(def info (. bus (getRemoteObject "org.apertium.info" "/" (class org.apertium.Info))))

(doseq mode (. info (modes))
       (prn mode))

(. bus (disconnect))

Clojure is a new Lisp dialect aimed at the Java Virtual Machine. You can see that the Clojure implementation is close to the Java implementation. To run the Clojure code, you will need to pass the same command line parameters to the Java Virtual Machine as for the Java example above.

C - Glib Bindings

#include 	<glib.h>
#include	<glib-object.h>
#include	<dbus/dbus.h>
#include	<dbus/dbus-glib.h>

#define 	APERTIUM_SERVICE_NAME   "org.apertium.mode"
#define 	APERTIUM_INTERFACE	"org.apertium.Translate"
#define 	APERTIUM_OBJECT_PATH	"/"

gboolean apertium_dbus_init();
gboolean apertium_dbus_translate(const gchar*, gboolean, gchar*);

static DBusGConnection *conn = NULL;
static DBusGProxy *proxy = NULL;
static gchar *ceviri = NULL;

gboolean apertium_dbus_init()
{
	GError *error = NULL;
	
	conn = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
	
	if (conn == NULL) {
		g_warning("Error %s\n", error->message);
                g_error_free(error);
		return FALSE;
	}
	else
	{
		g_debug("conn object is %d\n", conn);
	}

	proxy = dbus_g_proxy_new_for_name_owner(conn,
						APERTIUM_SERVICE_NAME,
						APERTIUM_OBJECT_PATH,
						APERTIUM_INTERFACE,
					        &error);
		
	g_debug("proxy %d\n", proxy);
									
	if (proxy == NULL || error != NULL)
	{
		g_warning("Cannot connect to the apertium service : %s\n", error->message);
		g_error_free(error);
		return FALSE;
	}
	else
	{
		return TRUE;
	}
	
}

gboolean apertium_dbus_translate(const gchar* given_string, gboolean mark_unknown, gchar *translated_string)
{
		
	GError *error = NULL;
	gchar *ceviri = NULL;
	GHashTable *hash = NULL;
	gchar *option_key = "mark_unknown";
	gchar *option_value = NULL;
	
	hash = g_hash_table_new(g_str_hash, g_str_equal);
	
	if (mark_unknown)
	{
		g_hash_table_insert(hash, "mark_unknown", "true");
	}
	else
	{
		g_hash_table_insert(hash, "mark_unknown", "false");
	}
	
	dbus_g_proxy_call(proxy, "translate", &error, 
					G_TYPE_STRING, "en-es", 
					DBUS_TYPE_G_STRING_STRING_HASHTABLE, hash, 
					G_TYPE_STRING, given_string,
					G_TYPE_INVALID,
					G_TYPE_STRING,
					&translated_string,
					G_TYPE_INVALID);
									
	g_hash_table_destroy(hash);
	
	if (error) 
        {
	    g_error_free(error);
            return FALSE;
        }
	else
        {
            g_error_free(error);
	    return TRUE;
        }
}


int main(int argc, char** argv)
{
	if (argc <= 1)
		return 1;
	
	g_type_init();	
	
	if (apertium_dbus_init() == FALSE)
		g_error("apertium_dbus_init, unable to connect apertium DBUS service");
	else
	{
		apertium_dbus_translate(argv[1], TRUE, ceviri);	
		g_print("%s is : %s\n", argv[1], ceviri);
		g_free(ceviri);
		g_object_unref(proxy);
	}	
	return 0;
}