📜 ⬆️ ⬇️

Writing an app translator for Gnome [python]

Foreword



I once sat on a quiet evening, reading English-language sites. When it was necessary to translate a couple of phrases, I, as usual, opened a new tab, typed translate.google.com , copied, pasted text, clicked translate, read. And after all, such a long sequence of actions has to be done every time there is a need to translate a text, a couple of phrases, or a whole paragraph. Yes, you can use any client for translation, but the program window will have to be opened or retrieved from under other windows. Yes, the sequence is shorter, but still long. It would be great to shorten the sequence of actions to copy, click. So the idea for the applet appeared. His logic is:


And I began to read various articles on writing applets, including those in Habré . In all, gtk.Label () was used, but this is correct, those applets were used to display information. Our applet will not display any information on the panel, it is just an intermediary between us and the dialog box with the translation. Therefore, we will use gtk.Button (). So let's get started!

Dialog window



Initially, the easygui.codebox element was used to display the text, but easygui is not in the standard package and I didn’t really want to put it in place. It was decided to write your own simple control. It had to have three controls: text in the initial language, text in the translated language (it should have been a textbox in order to be able to copy the translation) and, of course, a button labeled “OK”. Thanks to these two tutors, a dialog box appeared.

The code is, in general, understandable, slightly commented.
import pygtk
pygtk.require( "2.0" )
import gtk

"" " ! =)" "" <br/>
#http: //www.pygtk.org/docs/pygtk/class-gdkwindow.html <br/>
#http: //www.moeraki.com/pygtktutorial/pygtk2tutorial/

"" " " "" <br/>
class ShowTextDialog():
def __init__(self):
self.default_window_name= "GTranslate [Neon Mercury]"

self.window=gtk.Window(gtk.WINDOW_TOPLEVEL)
self.window.set_title(self.default_window_name)
self.window.connect( "delete_event" , self.delete_event)
self.window.set_border_width(10)
self.box=gtk.VBox()
self.window.add(self.box)

"" " Label " "" <br/>
self.info=gtk.Label()
self.box.pack_start(self.info, True, False, 0)

"" " , " "" <br/>
self.textview=gtk.TextView()
self.box.pack_start(self.textview, True, True, 0)

self.button=gtk.Button( "OK" )
self.button.connect( "clicked" , self.button_clicked)
self.box.pack_start(self.button, False, False, 0)

self.info.show()
self.textview.show()
self.button.show()
self.box.show()

self.window.move(100, 100)
self.window.resize(640, 480)

"" "info - label, textbox_info - textview" "" <br/>
"" " " "" <br/>
def show(self, info, textbox_info, main_window_title= "GTranslate [Neon Mercury]" ):
info=self.process_text(info)
textbox_info=self.process_text(textbox_info)
self.info.set_text(info)
self.textview.get_buffer().set_text(textbox_info)
self.window.set_title(main_window_title)
self.window.show()

def hide(self):
self.window.hide()

def button_clicked(self, widget, data=None):
self.hide()

"" " , " "" <br/>
def delete_event(self, widget, event , data=None):
self.hide()

"" " . Google , 65536 :)" "" <br/>
"" " , !" "" <br/>
"" " max_len . " "" <br/>
"" "max_len , ." "" <br/>
def process_text(self, text, max_len=160):
result= "" <br/>
i=0
for char in text:
i+=1
if i>max_len and char == " " :
result+= "\n" <br/>
i=0
else :
if char == "\n" :<br/>
i=0
result+= char <br/>
return result


* This source code was highlighted with Source Code Highlighter .

')

Library to translate



A separate library was also written to translate the text. It is also very simple and has three functions. The first replaces the most frequently used HTML mnemonics with their equivalent. There are a lot of them, so I wrote a simple script that parsed Wikipedia and, in fact, wrote the whole function for me. I will not post it on the habr, it is very long, everything will be in the source code. The second function, which determines the source language of the text, is also simple. We just take every character of the text. If it is from the English alphabet, then we increase one counter, if from Russian, then another. That is, we define the dominant language in the text and consider it as the source. The third function is the translator. It determines the source language, sends a request to Google and receives the translated text.
"" " . - ." "" <br/>
"" " . , . ." "" <br/>
"" " - !" "" <br/>
def determine_languages(text):
en_chars_count=0
ru_chars_count=0
for char in text:
if ( char >= "a" and char <= "z" ) or ( char >= "A" and char <= "Z" ):
en_chars_count+=1
elif ( char >= "" and char <= "" ) or ( char >= "" and char <= "" ):
ru_chars_count+=1
source_lang= "en" <br/>
dest_lang= "ru" <br/>
if ru_chars_count>en_chars_count:
source_lang, dest_lang= "ru" , "en" <br/>
return source_lang, dest_lang

"" " ." "" <br/>
def translate(text):
source_lang, dest_lang=determine_languages(text)
params ={ "ie" : "UTF-8" , "text" :text,
"sl" :source_lang, "tl" :dest_lang}
params =urllib.urlencode( params )
headers={ "Content-Length" : "%d" % len( params )}

connection=httplib.HTTPConnection( "translate.google.ru" )
connection.request( "POST" , "/translate_t" , params , headers)
response=connection.getresponse()
answer=response.read()
index=answer.find( "id=result_box" )
if index!=-1:
index+=24
"" " " "" <br/>
translated_text=answer[index:answer.find( "</div" , index)]
translated_text=replace_html_mnemonics(translated_text)
translated_text=translated_text.decode( "koi8-r" )
return translated_text
else :
return ""


* This source code was highlighted with Source Code Highlighter .


Applet



Well, here is the actual code of the applet itself:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
import gtk
import gnomeapplet

import NeonDialogs
from GTranslateLib import translate

"" " ! =)" "" <br/>
#http: //www.citforum.ru/programming/python/gnome_applets/

"" " " "" <br/>
class GTranslate(gnomeapplet.Applet):
def __init__(self, applet, iid):
self.applet=applet
self.applet.set_name( "GTranslate" )
self.box=gtk.HBox()
self.applet.add(self.box)
self.button=gtk.Button( "GTranslate" )
self.box.add(self.button)
self.applet.show_all()

self.button.connect( "clicked" , self.on_button)
self.dialog=NeonDialogs.ShowTextDialog()

"" " , " "" <br/>
"" " , ." "" <br/>
def on_button(self, widget, data=None):
text=self.get_text_from_clipboard()
translated_text=translate(text)
self.dialog.show(text, translated_text)

"" " ... ." "" <br/>
def on_ppm_about(self, event , data=None):
gnome.ui.About( "GTranslate" , "1.0" , "GPL General Public License" ,
" !" ,
[ "Neon Mercury <wishmaster2009@gmail.com>" ,]).show()

"" " . clipboard , " "" <br/>
"" " - . ." ""
def get_text_from_clipboard(self):
clipboard=gtk.Clipboard(display=gtk.gdk.display_get_default(), selection= "CLIPBOARD" )
text=clipboard.wait_for_text()
clipboard.store()
return text

def applet_factory(applet, iid):
GTranslate(applet, iid)
return True

"" " . ( )." "" <br/>
def run_in_window():
main_window=gtk.Window(gtk.WINDOW_TOPLEVEL)
main_window.set_title( "GTranslate [debug mode]" )
main_window.connect( "destroy" , gtk.main_quit)
app=gnomeapplet.Applet()
applet_factory(app, None)
app.reparent(main_window)
main_window.show_all()
gtk.main()

"" " " ""
def run_in_panel():
gnomeapplet.bonobo_factory( "OAFIID:GTranslate_Factory" ,
GTranslate.__gtype__,
"GTranslate" , "1.0" , applet_factory)

"" " , run_in_panel() run_in_window()" "" <br/>
run_in_panel()


* This source code was highlighted with Source Code Highlighter .


.server file



If you wrote / copy the applet yourself, then below is the .server file for this applet.
< oaf_info >

< oaf_server iid ="OAFIID:GTranslate_Factory"
type ="exe" location =" /home/neon/applets/GTranslate/GTranslate.py " > <br/>

< oaf_attribute name ="repo_ids" type ="stringv" > <br/>
< item value ="IDL:Bonobo/GenericFactory:1.0" /> <br/>
< item value ="IDL:Bonobo/Unknown:1.0" />

</ oaf_attribute > <br/>
< oaf_attribute name ="name" type ="string" value ="GTranslate factory" /> <br/>
< oaf_attribute name ="name-ru" type ="string" value =" GTranslate" /> <br/>

< oaf_attribute name ="description" type ="string" value ="Factory of GTranslate" /> <br/>
< oaf_attribute name ="description-ru" type ="string" value =" GTranslate" /> <br/>

</ oaf_server > <br/>
< oaf_server iid ="OAFIID:GTranslate"
type ="factory" location ="OAFIID:GTranslate_Factory" > <br/>
< oaf_attribute name ="repo_ids" type ="stringv" > <br/>

< item value ="IDL:GNOME/Vertigo/PanelAppletShell:1.0" /> <br/>
< item value ="IDL:Bonobo/Control:1.0" /> <br/>
< item value ="IDL:Bonobo/Unknown:1.0" /> <br/>

</ oaf_attribute > <br/>
< oaf_attribute name ="name" type ="string" value ="GTranslate" /> <br/>
< oaf_attribute name ="name-ru" type ="string" value ="GTranslate" /> <br/>

< oaf_attribute name ="description" type ="string" value ="GTranslate service of text translation." /> <br/>
< oaf_attribute name ="description-ru" type ="string" value =" GTranslate." /> <br/>

< oaf_attribute name ="panel:category" type ="string" value ="Accessories" /> <br/>
< oaf_attribute name ="panel:icon" type ="string" value =" /home/neon/applets/GTranslate/GTranslate.png " /> <br/>

</ oaf_server > <br/>
</ oaf_info > <br/>

* This source code was highlighted with Source Code Highlighter .


One note: replace the highlighted lines with your own. The first is the path to the main applet file (GTranslate.py). The second is a picture of the applet (Optional, but beautiful). Don't forget to make the GTranslate.py file executable.

Conclusion



Here is the (tar.gz) ( rar ) archive with the sources of the applet and the installation script. To install the applet into the system, you must run the install.py file as root (to copy the files to / usr / lib / bonobo / servers /).

Now for translation, just select the text and press the GTranslate button on the panel. Good luck!

UPD: Transferred to PyGTK blog

Source: https://habr.com/ru/post/67668/


All Articles