[IMP]:Improve translation synchronization

bzr revid: aja@tinyerp.com-20120806074035-11pi9wal2psnvl6w
This commit is contained in:
ajay javiya (OpenERP) 2012-08-06 13:10:35 +05:30
parent 70e73559d2
commit e4a2ac99a7
10 changed files with 434 additions and 5 deletions

View File

@ -11,7 +11,7 @@
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
@ -21,5 +21,6 @@
import res_company
import ir_translation
import wizard
import res_lang
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -31,7 +31,10 @@ Automated Translations through Gengo API
'init_xml': [],
'update_xml': [
'ir_translation.xml',
'res_company_view.xml'
'res_company_view.xml',
'res_lang_view.xml',
'wizard/gengo_response_scheduler.xml',
'wizard/alert_message_gengo.xml',
],
'demo_xml': [],
'test': [],

View File

@ -11,7 +11,7 @@
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
@ -29,8 +29,9 @@ class ir_translation(osv.Model):
'gengo_comment':fields.text("Comments"),
'gengo_translation':fields.boolean("Translation", help='This term has to be translated by Gengo automatically'),
'gengo_control':fields.boolean('Active'),
'job_id':fields.char('Gengo Job Id',size=32),
}
_defaults = {
'gengo_control':False,
}

View File

@ -0,0 +1,32 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Business Applications
# Copyright (C) 2004-2012 OpenERP S.A. (<http://openerp.com>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from osv import fields,osv
class res_company(osv.Model):
_name = "res.lang"
_description = "Languages"
_inherit = "res.lang"
_columns = {
'gengo_sync':fields.boolean('Active', help='Synchronize Translation Periodically')
}

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<openerp>
<data>
<!-- res.company form view -->
<record model="ir.ui.view" id="view_language_inherit_base_gengo_form">
<field name="name">res.lang.form.inherit</field>
<field name="inherit_id" ref="base.res_lang_form"/>
<field name="model">res.lang</field>
<field name="type">form</field>
<field name="arch" type="xml">
<xpath expr="//sheet/group" position="inside">
<field name="gengo_sync" />
</xpath>
</field>
</record>
</data>
</openerp>

View File

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import gengo_update_translation
import wrap_object
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record model="ir.ui.view" id="update_translation_wizard_view_confirm">
<field name="name">update.translations.serial.wizard.view</field>
<field name="inherit_id" ref="base.wizard_update_translations"/>
<field name="model">base.update.translations</field>
<field name="type">form</field>
<field name="arch" type="xml">
<xpath expr="//group[@name='Synchronize Translation']" position="inside">
<group colspan="4">
<field name="state" invisible="1"/>
<label string="Your Request has been Successfully Send to Gengo" states="done" colspan="4"/>
</group>
<group colspan="4">
<label string="This language is select as Active All Translation Request will be sent by System Automatically" states="inprogress" colspan="4"/>
</group>
</xpath>
</field>
</record>
</data>
</openerp>

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!--Scheduler Gengo Response-->
<record id="gengo_response_scheduler" model="ir.cron">
<field name="name" >Run Gengo Response Scheduler</field>
<field eval="True" name="active"/>
<field name="interval_number">1</field>
<field name="interval_type">minutes</field>
<field name="numbercall">-1</field>
<field eval="'base.update.translations'" name="model"></field>
<field eval="'scheduler_get_gengo_response'" name="function"/>
</record>
<!--Schedular Sync Request-->
<record id="gengo_sync_request_scheduler" model="ir.cron">
<field name="name" >Run Gengo Sync Request Scheduler</field>
<field eval="True" name="active"/>
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="numbercall">-1</field>
<field eval="'base.update.translations'" name="model"></field>
<field eval="'scheduler_get_gengo_sync_request'" name="function"/>
</record>
</data>
</openerp>

View File

@ -0,0 +1,142 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Business Applications
# Copyright (C) 2004-2012 OpenERP S.A. (<http://openerp.com>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from osv import osv, fields
import tools
import cStringIO
from tools.translate import _
import wrap_object
import logging
_logger = logging.getLogger(__name__)
class gengo_update_translation(osv.osv_memory):
def send_translation_terms(self, cr, uid, ids, context):
"""Lasy Loading will be perform when user or cron send a bunch of request."""
total_term=0
limit= 0
translation_list=context['translation_term_id']
range_jobs=1
meta = self.pool.get('jobs.meta')
translation_pool=self.pool.get('ir.translation')
user = self.pool.get('res.users').browse(cr, uid, uid, context)
gengo = meta.gengo_authentication(cr,uid,ids,context)
job_length=len(context['translation_term_id'])
remain=len(context['translation_term_id']) % wrap_object.REQUEST_LIMIT
if len(context['translation_term_id']) > wrap_object.REQUEST_LIMIT:
if remain > 0:
range_jobs=(len(context['translation_term_id']) / wrap_object.REQUEST_LIMIT) + 1
else:
range_jobs=len(context['translation_term_id']) / wrap_object.REQUEST_LIMIT
for length in range(0,range_jobs):
trans_list=[]
if job_length > wrap_object.REQUEST_LIMIT:
job_length-=wrap_object.REQUEST_LIMIT
limit+=wrap_object.REQUEST_LIMIT
else:
limit+=remain
for key in translation_list[total_term:limit]:
trans_list.append(key)
total_term=limit
jobs = meta.pack_jobs_request(cr,uid,trans_list,context={'language_code':context['lang']})
result = gengo.postTranslationJobs(jobs = jobs)
self.write(cr, uid, ids, {'state':'done'})
if user.company_id.gengo_tier == 'machine':
if result.get('opstat')=='ok':
for job in result.get('response').get('jobs'):
for translation_id,val in job.items():
translation_pool.write(cr,uid,int(translation_id),{'value':
val['body_tgt'],'state':'translated','gengo_control':True})
else:
for job in result.get('response').get('jobs'):
for translation_id,val in job.items():
translation_pool.write(cr,uid,int(translation_id),{'job_id':val['job_id']})
return
def act_update(self, cr, uid, ids, context=None):
try:
language_pool=self.pool.get('res.lang')
this = self.browse(cr, uid, ids)[0]
translation_pool=self.pool.get('ir.translation')
lang_search_id=language_pool.search(cr, uid, [('gengo_sync','=',True),('code','=',this.lang)])
if not lang_search_id:
translation_term_id=translation_pool.search(cr,uid,[('state','=','translate'), ('gengo_translation','=','True'),('lang','=',this.lang)])
context.update({'lang':this.lang,'translation_term_id':translation_term_id})
self.send_translation_terms(cr,uid,ids,context)
return
else:
self.write(cr, uid, ids, {'state':'inprogress'})
except Exception, e:
raise osv.except_osv(_('Warning !'), _('%s') % e)
def scheduler_get_gengo_response(self, cr, uid, ids=0, context=None):
"""Scheduler will be call to get response from gengo and all term will get
by scheduler which terms are in reviewable state"""
meta = self.pool.get('jobs.meta')
translation_pool=self.pool.get('ir.translation')
gengo = meta.gengo_authentication(cr,uid,ids,context)
res = gengo.getTranslationJobs(status = "approved")
if res:
response = meta.unpack_jobs_response(res)
for job in response.response:
translation_id=translation_pool.search(cr,uid,[('job_id','=',job.job_id)],context)
response=gengo.getTranslationJob(id = job.job_id)
translation_pool.write(cr,uid,translation_id,{'value':response['response']['job']['body_tgt'],'state':'translated','gengo_control':True})
def scheduler_get_gengo_sync_request(self, cr, uid, ids=0, context=None):
"""This scheduler will send a job request to the gengo , which terms are
in translate state and gengo_translation is true"""
if context is None:
context={}
try:
language_pool=self.pool.get('res.lang')
translation_pool=self.pool.get('ir.translation')
lang_search_id=language_pool.search(cr, uid, [('gengo_sync','=',True)])
lang_ids=language_pool.read(cr, uid,lang_search_id)
for lang_id in lang_ids:
translation_term_id=translation_pool.search(cr,uid,[('state','=','translate'), ('gengo_translation','=','True'),('lang','=',lang_id['code']),('job_id','=',False)])
context.update({'lang':lang_id['code'],'translation_term_id':translation_term_id})
if translation_term_id:
self.send_translation_terms(cr, uid, ids, context)
except Exception, e:
_logger.warning('A Gengo Exception is occur:: %s',e)
_name = 'base.update.translations'
_inherit = "base.update.translations"
_columns= {
'state':fields.selection([('init','init'),('inprogress','inprogress'),('done','done')], 'state'),
}
_defaults= {
'state':'init',
}
gengo_update_translation()

View File

@ -0,0 +1,159 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Business Applications
# Copyright (C) 2004-2012 OpenERP S.A. (<http://openerp.com>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from osv import orm, osv
import tools
from tools.translate import _
from mygengo import MyGengo
import re
REQUEST_LIMIT=10
LANG_MAPPING={
'ar':'Arabic',
'id':'Indonesian',
'nl':'Dutch',
'fr-ca':'French (Canada)',
'pl':'Polish',
'zh-tw':'Chinese (Traditional)',
'sv':'Swedish',
'ko':'Korean',
'pt':'Portuguese (Europe)',
'en':'English',
'ja':'Japanese',
'es':'Spanish (Spain)',
'zh':'Chinese (Simplified)',
'de':'German',
'fr':'French',
'ru':'Russian',
'it':'Italian',
'pt-br':'Portuguese (Brazil)',
}
LANG_CODE_MAPPING = {
'ar_SA':'ar',
'id_ID':'id',
'nl_NL':'nl',
'fr_CA':'fr-ca',
'pl':'pl',
'zh_TW':'zh-tw',
'sv_SE':'sv',
'ko_KR':'ko',
'pt_PT':'pt',
'en':'en',
'ja_JP':'ja',
'es_ES':'es',
'zh_CN':'zh',
'de_DE':'de',
'fr_FR':'fr',
'ru_RU':'ru',
'it_IT':'it',
'pt_BR':'pt-br'
}
class gengo_response(object):
"""
"""
def __init__(self, jobs):
response = jobs['response']
job = []
jobs_id=[]
if isinstance(response, list):
job = [ gengo_job(value) for value in response]
else:
job = [ gengo_job(value) for value in response.values()]
jobs.update({'response': job})
self._data = jobs
def __getitem__(self, name):
return self._data[name]
def __getattr__(self, name):
try:
return self[name]
except KeyError, e:
raise AttributeError(e)
class gengo_job(object):
"""
"""
def __init__(self, job):
self._data = job
def __getitem__(self, name):
return self._data[name]
def __getattr__(self, name):
try:
return self[name]
except KeyError, e:
raise AttributeError(e)
class JobsMeta(orm.AbstractModel):
_name="jobs.meta"
def gengo_authentication(self,cr,uid,ids,context=None):
''' To Send Request and Get Response from Gengo User needs Public and Private
key for that user need to signup to gengo and get public and private
key which is provided by gengo to authentic user '''
gengo_parameter_pool=self.pool.get('res.users').browse(cr,uid,uid,context)
try:
gengo = MyGengo(
public_key = gengo_parameter_pool.company_id.gengo_public_key.encode('ascii'),
private_key = gengo_parameter_pool.company_id.gengo_private_key.encode('ascii'),
sandbox = True,
)
return gengo
except Exception, e:
raise osv.except_osv(_('Warning !'), _(e))
def pack_jobs_request(self, cr, uid, translation_term_id, context):
jobs={}
auto_approve = 0
gengo_parameter_pool=self.pool.get('res.users').browse(cr, uid, uid, context)
translation_pool =self.pool.get('ir.translation')
if gengo_parameter_pool.company_id.gengo_auto_approve == True:
auto_approve=1
for key,value in LANG_CODE_MAPPING.items():
if key == context['language_code']:
for terms in translation_pool.read(cr, uid, translation_term_id, context=None):
# translation_pool.write(cr,uid,translation_term_id,{'state':'inprogress'})
if re.search(r"[a-z A-Z]",terms['src']):
job = {'type':'text',
'slug':'single::English to '+ LANG_MAPPING.get(value),
'tier':gengo_parameter_pool.company_id.gengo_tier,
'body_src':terms['src'],
'lc_src':'en',
'lc_tgt':value,
'auto_approve': auto_approve,
'comment':gengo_parameter_pool.company_id.gengo_comment ,
}
jobs.update({terms['id']: job})
return {'jobs': jobs}
def unpack_jobs_response(self, jobs):
return gengo_response(jobs)