Previous Section  < Day Day Up >  Next Section

Hack 54 Don't Get Lost in Translation

figs/expert.gif figs/hack54.gif

Since IRC is accessible from anywhere in the world, cross the language barriers with a translator bot.

Writing a bot to translate phrases between different languages doesn't require a mastery of translation nor the ability to parse output from web-based translators. This bot uses a Web Service to get its data. The translator Web Service is not listed on XMethods but is provided by RestlessDelusions.net. Here is the information about the service that you need:


WSDL URL

http://www.restlessdelusions.com/projects/services/translate/translate.asmx?WSDL


Operation

TranslateLanguage


Input message parts


Language list

This has the original language and the language to translate to. Each language is given a two-letter code and is separated by a | character. To translate from English to French, the argument would be en|fr.


Output message name

TranslateLanguageResult

Language pairs that can be translated and their abbreviations are as follows:


en|de

English to German


en|es

English to Spanish


en|fr

English to French


en|it

English to Italian


en|pt

English to Portuguese


de|en

German to English


de|fr

German to French


es|en

Spanish to English


fr|en

French to English


fr|de

French to German


it|en

Italian to English


pt|en

Portuguese to English

8.5.1 The Code

Now, to use this Web Service, you need to change only a few parts from the WeatherService class [Hack #53] . The changes are simple—replace the values of key variables with the correct values from this service and adjust the method to use two arguments. The lines you need to change are bold in the following example:

import java.util.*;

import samples.client.DynamicInvoker;



public class TranslatorService {



    static String wsdlLocation = "http://www.restlessdelusions.com/projects/

    services/translate/translate.asmx?WSDL";

    static String operationName= "TranslateLanguage";

    static String outputName = "TranslateLanguageResult";

    static String portName = null;





    public static String translatePhrase(String languages, String phrase) {

        String[] args =

              new String[] {wsdlLocation, operationName, languages, phrase};

        try {

            DynamicInvoker invoker=new DynamicInvoker(wsdlLocation);

            HashMap map = invoker.invokeMethod(operationName, portName, args);

            return map.get(outputName).toString( );

        }catch (Exception e){return null;}

    }

}

You now have a working method for using the Web Service to translate text and need to write the code for the bot to use the service. It is convenient to add the code here into the onMessage method from the previous Web Services hack. You can assume that the user input will come in the following format:

WSBot, translate en to fr Hello world!

This line assumes that users know the codes for each language. You may want to provide a help message that lists each language and its code.

To process this request, you can begin as with the previous example, using a StringTokenizer to parse the input.

        String query = t.nextToken( );

        if (query.equals("translate")) {

            String response = "";

Then the next step will be to pull out the two languages:

            String sourceLanguage = t.nextToken( );

            t.nextToken( );   // Get rid of the "to".

            String targetLanguage = t.nextToken( );

Now, the rest of the tokens store the message to be translated. Unfortunately, StringTokenizer does not have a method to nicely return the rest of the tokens, so you must use a loop to aggregate them into a string:

            String messageToTranslate = "";

            while (t.hasMoreTokens( ))

                messageToTranslate = messageToTranslate + " " + t.nextToken( );

Now, with a little error checking, you can make the call to your translatePhrase method:

            if (!sourceLanguage.equals("") && 

                !targetLanguage.equals("") && 

                !messageToTranslate.equals("")){

    

                String lang = sourceLanguage + "|" + targetLanguage;

                String result = TranslatorService.translatePhrase(

                        lang, messageToTranslate);

                response = result;

            } else {

                response = "I could not understand your input.";

            }

            sendMessage(channel, response);

        }

    ...

8.5.2 Running the Hack

As with the previous Web Services hack, you will need to ensure that you have all of the Axis components in your classpath when you compile the bot:

% javac -classpath .:pircbot.jar:axis-1_1/lib/axis.jar: \  axis-1_1/lib/axis-ant.jar: \

  axis-1_1/lib/commons-discovery.jar:axis-1_1/lib/commons-logging.jar: \

  axis-1_1/lib/jaxrpc.jar:axis-1_1/lib/log4j-1.2.8.jar: \  axis-1_1/lib/saaj.jar: \

  axis-1_1/lib/wsdl4j.jar *.java

Depending on the name of your main class, you can then run the bot like so:

% java -classpath .:pircbot.jar:axis-1_1/lib/axis.jar: \  axis-1_1/lib/axis-ant.jar: \ 

  axis-1_1/lib/commons-discovery.jar: \  axis-1_1/lib/commons-logging.jar: \ 

  axis-1_1/lib/jaxrpc.jar:axis-1_1/lib/log4j-1.2.8.jar: \  axis-1_1/lib/saaj.jar: \ 

  axis-1_1/lib/wsdl4j.jar  Main 

Replace Main with the correct name for your main class if it is different.

As soon as the bot connects to the server, it is ready to offer its translation service to all of the channels you dispatch it to:

<Jibbler> WSBot, translate en to de I love IRC

<WSBot> Ich liebe IRC

This hack is a good demonstration of the power of Web Services. Anybody who's tried to achieve a similar task by parsing raw HTML from a web page will certainly appreciate the simplicity.

Jennifer Golbeck

    Previous Section  < Day Day Up >  Next Section