[FIX] Gengo - Update modoel ir_translation for gengo and make it working. Works with order and not job, because when you send a batch to translate, you don't know all the job but only the order.

This commit is contained in:
Jeremy Kersten 2014-06-20 17:33:09 +02:00
parent 65f68c1f65
commit 18bb52ee88
6 changed files with 149 additions and 56 deletions

View File

@ -1,22 +1,53 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import openerp import openerp
from openerp import SUPERUSER_ID
from openerp.addons.web import http from openerp.addons.web import http
from openerp.addons.web.http import request from openerp.addons.web.http import request
from werkzeug.wrappers import BaseResponse as Response
import json import json
class website_gengo(http.Controller): class website_gengo(http.Controller):
def get_gengo_key(self, cr):
icp = request.registry['ir.config_parameter']
return icp.get_param(cr, SUPERUSER_ID, request.registry['base.gengo.translations'].GENGO_KEY, default="")
@http.route('/website/gengo_callback', type='http', auth='none') @http.route('/website/gengo_callback', type='http', auth='none')
def gengo_callback(self,**post): def gengo_callback(self, **post):
cr, uid, context = request.cr, openerp.SUPERUSER_ID, request.context cr, uid, context = request.cr, openerp.SUPERUSER_ID, request.context
translation_pool = request.registry['ir.translation'] translation_pool = request.registry['ir.translation']
if post and post.get('job'): if post and post.get('job') and post.get('pgk'):
job = json.loads(post['job']) if post.get('pgk') != self.get_gengo_key(cr):
return Response("Bad authentication - 403/412", status=412)
job = json.loads(post['job'], 'utf-8')
tid = job.get('custom_data', False) tid = job.get('custom_data', False)
if (job.get('status') == 'approved') and tid: if (job.get('status') == 'approved') and tid:
term = translation_pool.browse(cr, uid, int(tid), context=context) term = translation_pool.browse(cr, uid, int(tid), context=context)
if term.job_id <> job.get('job_id'): if term.src != job.get('body_src'):
raise 'Error' return Response("Text Altered - Not saved", status=100)
vals = {'state': 'translated', 'value': job.get('body_tgt')} domain = [
translation_pool.write(cr, uid, [int(tid)], vals, context=context) '|',
('id', "=", int(tid)),
'&', '&', '&', '&', '&',
('state', '=', term.state),
('gengo_translation', '=', term.gengo_translation),
('src', "=", term.src),
('type', "=", term.type),
('name', "=", term.name),
('lang', "=", term.lang),
#('order_id', "=", term.order_id),
]
all_ir_tanslations = translation_pool.search(cr, uid, domain, context=context or {})
if all_ir_tanslations:
vals = {'state': 'translated', 'value': job.get('body_tgt')}
translation_pool.write(cr, uid, all_ir_tanslations, vals, context=context)
return Response("OK", status=200)
else:
return Response("No terms found", status=104)
return Response("Not saved", status=100)

View File

@ -8,6 +8,7 @@
<field name="interval_number">6</field> <field name="interval_number">6</field>
<field name="interval_type">hours</field> <field name="interval_type">hours</field>
<field name="numbercall">-1</field> <field name="numbercall">-1</field>
<field name="doall">0</field>
<field eval="'base.gengo.translations'" name="model"></field> <field eval="'base.gengo.translations'" name="model"></field>
<field eval="'_sync_response'" name="function"/> <field eval="'_sync_response'" name="function"/>
<field eval="'(20,)'" name="args"/> <field eval="'(20,)'" name="args"/>
@ -20,6 +21,7 @@
<field name="interval_number">6</field> <field name="interval_number">6</field>
<field name="interval_type">hours</field> <field name="interval_type">hours</field>
<field name="numbercall">-1</field> <field name="numbercall">-1</field>
<field name="doall">0</field>
<field eval="'base.gengo.translations'" name="model"></field> <field eval="'base.gengo.translations'" name="model"></field>
<field eval="'_sync_request'" name="function"/> <field eval="'_sync_request'" name="function"/>
<field eval="'(20,)'" name="args"/> <field eval="'(20,)'" name="args"/>

View File

@ -56,16 +56,18 @@ LANG_CODE_MAPPING = {
'fi_FI': ('fi', 'Finnish') 'fi_FI': ('fi', 'Finnish')
} }
class ir_translation(osv.Model): class ir_translation(osv.Model):
_name = "ir.translation" _name = "ir.translation"
_inherit = "ir.translation" _inherit = "ir.translation"
_columns = { _columns = {
'gengo_comment': fields.text("Comments & Activity Linked to Gengo"), 'gengo_comment': fields.text("Comments & Activity Linked to Gengo"),
'job_id': fields.char('Gengo Job ID', size=32), 'order_id': fields.char('Gengo Order ID', size=32),
"gengo_translation": fields.selection([('machine', 'Translation By Machine'), "gengo_translation": fields.selection([('machine', 'Translation By Machine'),
('standard', 'Standard'), ('standard', 'Standard'),
('pro', 'Pro'), ('pro', 'Pro'),
('ultra', 'Ultra')], "Gengo Translation Service Level", help='You can select here the service level you want for an automatic translation using Gengo.'), ('ultra', 'Ultra')], "Gengo Translation Service Level", help='You can select here the service level you want for an automatic translation using Gengo.'),
} }
def _get_all_supported_languages(self, cr, uid, context=None): def _get_all_supported_languages(self, cr, uid, context=None):
@ -83,3 +85,19 @@ class ir_translation(osv.Model):
def _get_gengo_corresponding_language(cr, lang): def _get_gengo_corresponding_language(cr, lang):
return lang in LANG_CODE_MAPPING and LANG_CODE_MAPPING[lang][0] or lang return lang in LANG_CODE_MAPPING and LANG_CODE_MAPPING[lang][0] or lang
def _get_source_query(self, cr, uid, name, types, lang, source, res_id):
query, params = super(ir_translation, self)._get_source_query(name, types, lang, source, res_id)
query += """
ORDER BY
CASE
WHEN gengo_translation=%s then 10
WHEN gengo_translation=%s then 20
WHEN gengo_translation=%s then 30
WHEN gengo_translation=%s then 40
ELSE 0
END DESC
"""
params += ('machine', 'standard', 'ultra', 'pro',)
return (query, params)

View File

@ -19,12 +19,13 @@
# #
############################################################################## ##############################################################################
import uuid
import logging import logging
import re import re
import time import time
from openerp.osv import osv, fields from openerp.osv import osv, fields
from openerp import tools from openerp import tools, SUPERUSER_ID
from openerp.tools.translate import _ from openerp.tools.translate import _
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
@ -36,7 +37,9 @@ except ImportError:
GENGO_DEFAULT_LIMIT = 20 GENGO_DEFAULT_LIMIT = 20
class base_gengo_translations(osv.osv_memory): class base_gengo_translations(osv.osv_memory):
GENGO_KEY = "Gengo.UUID"
_name = 'base.gengo.translations' _name = 'base.gengo.translations'
_columns = { _columns = {
@ -46,9 +49,20 @@ class base_gengo_translations(osv.osv_memory):
'lang_id': fields.many2one('res.lang', 'Language', required=True), 'lang_id': fields.many2one('res.lang', 'Language', required=True),
'sync_limit': fields.integer("No. of terms to sync"), 'sync_limit': fields.integer("No. of terms to sync"),
} }
_defaults = {'sync_type' : 'both', _defaults = {
'sync_limit' : 20 'sync_type': 'both',
} 'sync_limit': 20
}
def init(self, cr):
icp = self.pool['ir.config_parameter']
if not icp.get_param(cr, SUPERUSER_ID, self.GENGO_KEY, default=None):
icp.set_param(cr, SUPERUSER_ID, self.GENGO_KEY, str(uuid.uuid4()))
def get_gengo_key(self, cr):
icp = self.pool['ir.config_parameter']
return icp.get_param(cr, SUPERUSER_ID, self.GENGO_KEY, default="Undefined")
def gengo_authentication(self, cr, uid, context=None): def gengo_authentication(self, cr, uid, context=None):
''' '''
This method tries to open a connection with Gengo. For that, it uses the Public and Private This method tries to open a connection with Gengo. For that, it uses the Public and Private
@ -113,48 +127,68 @@ class base_gengo_translations(osv.osv_memory):
_logger.warning("%s", gengo) _logger.warning("%s", gengo)
else: else:
offset = 0 offset = 0
all_translation_ids = translation_pool.search(cr, uid, [('state', '=', 'inprogress'), ('gengo_translation', 'in', ('machine', 'standard', 'pro', 'ultra')), ('job_id', "!=", False)], context=context) all_translation_ids = translation_pool.search(cr, uid, [('state', '=', 'inprogress'), ('gengo_translation', 'in', ('machine', 'standard', 'pro', 'ultra')), ('order_id', "!=", False)], context=context)
while True: while True:
translation_ids = all_translation_ids[offset:offset + limit] translation_ids = all_translation_ids[offset:offset + limit]
offset += limit offset += limit
if not translation_ids: if not translation_ids:
break break
terms_progress = {
'gengo_order_ids': set(),
'ir_translation_ids': set(),
}
translation_terms = translation_pool.browse(cr, uid, translation_ids, context=context) translation_terms = translation_pool.browse(cr, uid, translation_ids, context=context)
gengo_job_id = [term.job_id for term in translation_terms] for term in translation_terms:
if gengo_job_id: terms_progress['gengo_order_ids'].add(term.order_id)
gengo_ids = ','.join(gengo_job_id) terms_progress['ir_translation_ids'].add(tools.ustr(term.id))
for order_id in terms_progress['gengo_order_ids']:
order_response = gengo.getTranslationOrderJobs(id=order_id)
jobs_approved = order_response.get('response', []).get('order', []).get('jobs_approved', [])
gengo_ids = ','.join(jobs_approved)
if gengo_ids: # Need to check, because getTranslationJobBatch don't catch this case and so call the getTranslationJobs because no ids in url
try: try:
job_response = gengo.getTranslationJobBatch(id=gengo_ids) job_response = gengo.getTranslationJobBatch(id=gengo_ids)
except: except:
continue continue
if job_response['opstat'] == 'ok': if job_response['opstat'] == 'ok':
for job in job_response['response'].get('jobs', []): for job in job_response['response'].get('jobs', []):
self._update_terms_job(cr, uid, job, context=context) if job.get('custom_data') in terms_progress['ir_translation_ids']:
self._update_terms_job(cr, uid, job, context=context)
return True return True
def _update_terms_job(self, cr, uid, job, context=None): def _update_terms_job(self, cr, uid, job, context=None):
translation_pool = self.pool.get('ir.translation') translation_pool = self.pool.get('ir.translation')
tid = int(job['custom_data']) tid = int(job['custom_data'])
vals = {} vals = {}
if job.get('job_id', False): if job.get('status', False) in ('queued', 'available', 'pending', 'reviewable'):
vals['job_id'] = job['job_id']
vals['state'] = 'inprogress' vals['state'] = 'inprogress'
if job.get('status', False) in ('queued','available','pending','reviewable'): if job.get('body_tgt', False) and job.get('status', False) == 'approved':
vals['state'] = 'inprogress'
if job.get('body_tgt', False) and job.get('status', False)=='approved':
vals['value'] = job['body_tgt'] vals['value'] = job['body_tgt']
if job.get('status', False) in ('approved', 'canceled'): if job.get('status', False) in ('approved', 'canceled'):
vals['state'] = 'translated' vals['state'] = 'translated'
if vals: if vals:
translation_pool.write(cr, uid, [tid], vals, context=context) translation_pool.write(cr, uid, [tid], vals, context=context)
def _update_terms(self, cr, uid, response, context=None): def _update_terms(self, cr, uid, response, term_ids, context=None):
""" """
Update the terms after their translation were requested to Gengo Update the terms after their translation were requested to Gengo
""" """
for jobs in response.get('jobs', []): translation_pool = self.pool.get('ir.translation')
vals = {
'order_id': response.get('order_id', ''),
'state': 'inprogress'
}
translation_pool.write(cr, uid, term_ids, vals, context=context)
jobs = response.get('jobs', [])
if jobs:
for t_id, res in jobs.items(): for t_id, res in jobs.items():
self._update_terms_job(cr, uid, res, context=context) self._update_terms_job(cr, uid, res, context=context)
return return
def pack_jobs_request(self, cr, uid, term_ids, context=None): def pack_jobs_request(self, cr, uid, term_ids, context=None):
@ -173,7 +207,7 @@ class base_gengo_translations(osv.osv_memory):
if re.search(r"\w", term.src or ""): if re.search(r"\w", term.src or ""):
comment = user.company_id.gengo_comment or '' comment = user.company_id.gengo_comment or ''
if term.gengo_comment: if term.gengo_comment:
comment+='\n' + term.gengo_comment comment += '\n' + term.gengo_comment
jobs[time.strftime('%Y%m%d%H%M%S') + '-' + str(term.id)] = { jobs[time.strftime('%Y%m%d%H%M%S') + '-' + str(term.id)] = {
'type': 'text', 'type': 'text',
'slug': 'Single :: English to ' + term.lang, 'slug': 'Single :: English to ' + term.lang,
@ -184,10 +218,9 @@ class base_gengo_translations(osv.osv_memory):
'lc_tgt': translation_pool._get_gengo_corresponding_language(term.lang), 'lc_tgt': translation_pool._get_gengo_corresponding_language(term.lang),
'auto_approve': auto_approve, 'auto_approve': auto_approve,
'comment': comment, 'comment': comment,
'callback_url': self.pool.get('ir.config_parameter').get_param(cr, uid,'web.base.url') + '/website/gengo_callback' 'callback_url': self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url') + '/website/gengo_callback?pgk=' + self.get_gengo_key(cr)
} }
return {'jobs': jobs, 'as_group': 1} return {'jobs': jobs, 'as_group': 0}
def _send_translation_terms(self, cr, uid, term_ids, context=None): def _send_translation_terms(self, cr, uid, term_ids, context=None):
""" """
@ -200,7 +233,7 @@ class base_gengo_translations(osv.osv_memory):
if request['jobs']: if request['jobs']:
result = gengo.postTranslationJobs(jobs=request) result = gengo.postTranslationJobs(jobs=request)
if result['opstat'] == 'ok': if result['opstat'] == 'ok':
self._update_terms(cr, uid, result['response'], context=context) self._update_terms(cr, uid, result['response'], term_ids, context=context)
else: else:
_logger.error(gengo) _logger.error(gengo)
return True return True
@ -218,10 +251,10 @@ class base_gengo_translations(osv.osv_memory):
context = {} context = {}
language_pool = self.pool.get('res.lang') language_pool = self.pool.get('res.lang')
translation_pool = self.pool.get('ir.translation') translation_pool = self.pool.get('ir.translation')
domain = [('state', '=', 'to_translate'), ('gengo_translation', 'in', ('machine', 'standard', 'pro', 'ultra')), ('job_id', "=", False)] domain = [('state', '=', 'to_translate'), ('gengo_translation', 'in', ('machine', 'standard', 'pro', 'ultra')), ('order_id', "=", False)]
if context.get('gengo_language', False): if context.get('gengo_language', False):
lc = language_pool.browse(cr, uid, context['gengo_language'], context=context).code lc = language_pool.browse(cr, uid, context['gengo_language'], context=context).code
domain.append( ('lang', '=', lc) ) domain.append(('lang', '=', lc))
all_term_ids = translation_pool.search(cr, uid, domain, context=context) all_term_ids = translation_pool.search(cr, uid, domain, context=context)
try: try:

View File

@ -6,6 +6,7 @@
var nodialog = 'website_translator_nodialog'; var nodialog = 'website_translator_nodialog';
website.EditorBar.include({ website.EditorBar.include({
do_not_translate : ['-','*','!'],
events: _.extend({}, website.EditorBar.prototype.events, { events: _.extend({}, website.EditorBar.prototype.events, {
'click a[data-action=edit_master]': 'edit_master', 'click a[data-action=edit_master]': 'edit_master',
}), }),
@ -129,7 +130,7 @@
node.className += ' oe_translatable_inprogress'; node.className += ' oe_translatable_inprogress';
} }
} else { } else {
node.className += ' oe_translatable_todo'; node.className += this.do_not_translate.indexOf(node.textContent.trim()) ? ' oe_translatable_todo' : '';
} }
node.contentEditable = true; node.contentEditable = true;
var nid = _.uniqueId(); var nid = _.uniqueId();

View File

@ -288,6 +288,31 @@ class ir_translation(osv.osv):
}) })
return len(ids) return len(ids)
def _get_source_query(self, cr, uid, name, types, lang, source, res_id):
if source:
query = """SELECT value
FROM ir_translation
WHERE lang=%s
AND type in %s
AND src=%s"""
params = (lang or '', types, tools.ustr(source))
if res_id:
query += "AND res_id=%s"
params += (res_id,)
if name:
query += " AND name=%s"
params += (tools.ustr(name),)
else:
query = """SELECT value
FROM ir_translation
WHERE lang=%s
AND type in %s
AND name=%s"""
params = (lang or '', types, tools.ustr(name))
return (query, params)
@tools.ormcache(skiparg=3) @tools.ormcache(skiparg=3)
def _get_source(self, cr, uid, name, types, lang, source=None, res_id=None): def _get_source(self, cr, uid, name, types, lang, source=None, res_id=None):
""" """
@ -310,27 +335,10 @@ class ir_translation(osv.osv):
return tools.ustr(source or '') return tools.ustr(source or '')
if isinstance(types, basestring): if isinstance(types, basestring):
types = (types,) types = (types,)
if source:
query = """SELECT value query, params = self._get_source_query(cr, uid, name, types, lang, source, res_id)
FROM ir_translation
WHERE lang=%s cr.execute(query, params)
AND type in %s
AND src=%s"""
params = (lang or '', types, tools.ustr(source))
if res_id:
query += "AND res_id=%s"
params += (res_id,)
if name:
query += " AND name=%s"
params += (tools.ustr(name),)
cr.execute(query, params)
else:
cr.execute("""SELECT value
FROM ir_translation
WHERE lang=%s
AND type in %s
AND name=%s""",
(lang or '', types, tools.ustr(name)))
res = cr.fetchone() res = cr.fetchone()
trad = res and res[0] or u'' trad = res and res[0] or u''
if source and not trad: if source and not trad: