From 18bb52ee88575db88df1f0401419fd20c1005e5c Mon Sep 17 00:00:00 2001 From: Jeremy Kersten Date: Fri, 20 Jun 2014 17:33:09 +0200 Subject: [PATCH] [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. --- .../base_gengo/controller/gengo_callback.py | 45 +++++++++-- .../base_gengo/gengo_sync_schedular_data.xml | 2 + addons/base_gengo/ir_translation.py | 26 +++++- .../wizard/base_gengo_translations.py | 79 +++++++++++++------ .../static/src/js/website.translator.js | 3 +- openerp/addons/base/ir/ir_translation.py | 50 +++++++----- 6 files changed, 149 insertions(+), 56 deletions(-) diff --git a/addons/base_gengo/controller/gengo_callback.py b/addons/base_gengo/controller/gengo_callback.py index 381ac7b7fe9..44fa9b9390a 100644 --- a/addons/base_gengo/controller/gengo_callback.py +++ b/addons/base_gengo/controller/gengo_callback.py @@ -1,22 +1,53 @@ # -*- coding: utf-8 -*- import openerp +from openerp import SUPERUSER_ID from openerp.addons.web import http from openerp.addons.web.http import request +from werkzeug.wrappers import BaseResponse as Response + import json + 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') - def gengo_callback(self,**post): + def gengo_callback(self, **post): cr, uid, context = request.cr, openerp.SUPERUSER_ID, request.context translation_pool = request.registry['ir.translation'] - if post and post.get('job'): - job = json.loads(post['job']) + if post and post.get('job') and post.get('pgk'): + 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) if (job.get('status') == 'approved') and tid: term = translation_pool.browse(cr, uid, int(tid), context=context) - if term.job_id <> job.get('job_id'): - raise 'Error' - vals = {'state': 'translated', 'value': job.get('body_tgt')} - translation_pool.write(cr, uid, [int(tid)], vals, context=context) + if term.src != job.get('body_src'): + return Response("Text Altered - Not saved", status=100) + domain = [ + '|', + ('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) diff --git a/addons/base_gengo/gengo_sync_schedular_data.xml b/addons/base_gengo/gengo_sync_schedular_data.xml index 91a5c8266d8..e916489e5f7 100644 --- a/addons/base_gengo/gengo_sync_schedular_data.xml +++ b/addons/base_gengo/gengo_sync_schedular_data.xml @@ -8,6 +8,7 @@ 6 hours -1 + 0 @@ -20,6 +21,7 @@ 6 hours -1 + 0 diff --git a/addons/base_gengo/ir_translation.py b/addons/base_gengo/ir_translation.py index 306516878cc..d0a85d18183 100644 --- a/addons/base_gengo/ir_translation.py +++ b/addons/base_gengo/ir_translation.py @@ -56,16 +56,18 @@ LANG_CODE_MAPPING = { 'fi_FI': ('fi', 'Finnish') } + class ir_translation(osv.Model): _name = "ir.translation" _inherit = "ir.translation" + _columns = { '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'), - ('standard', 'Standard'), - ('pro', 'Pro'), - ('ultra', 'Ultra')], "Gengo Translation Service Level", help='You can select here the service level you want for an automatic translation using Gengo.'), + ('standard', 'Standard'), + ('pro', 'Pro'), + ('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): @@ -83,3 +85,19 @@ class ir_translation(osv.Model): def _get_gengo_corresponding_language(cr, 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) diff --git a/addons/base_gengo/wizard/base_gengo_translations.py b/addons/base_gengo/wizard/base_gengo_translations.py index 08dfb0182ae..50484048b9f 100644 --- a/addons/base_gengo/wizard/base_gengo_translations.py +++ b/addons/base_gengo/wizard/base_gengo_translations.py @@ -19,12 +19,13 @@ # ############################################################################## +import uuid import logging import re import time from openerp.osv import osv, fields -from openerp import tools +from openerp import tools, SUPERUSER_ID from openerp.tools.translate import _ _logger = logging.getLogger(__name__) @@ -36,7 +37,9 @@ except ImportError: GENGO_DEFAULT_LIMIT = 20 + class base_gengo_translations(osv.osv_memory): + GENGO_KEY = "Gengo.UUID" _name = 'base.gengo.translations' _columns = { @@ -46,9 +49,20 @@ class base_gengo_translations(osv.osv_memory): 'lang_id': fields.many2one('res.lang', 'Language', required=True), 'sync_limit': fields.integer("No. of terms to sync"), } - _defaults = {'sync_type' : 'both', - 'sync_limit' : 20 - } + _defaults = { + '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): ''' 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) else: 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: translation_ids = all_translation_ids[offset:offset + limit] offset += limit if not translation_ids: break + + terms_progress = { + 'gengo_order_ids': set(), + 'ir_translation_ids': set(), + } translation_terms = translation_pool.browse(cr, uid, translation_ids, context=context) - gengo_job_id = [term.job_id for term in translation_terms] - if gengo_job_id: - gengo_ids = ','.join(gengo_job_id) + for term in translation_terms: + terms_progress['gengo_order_ids'].add(term.order_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: job_response = gengo.getTranslationJobBatch(id=gengo_ids) except: continue if job_response['opstat'] == 'ok': 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 def _update_terms_job(self, cr, uid, job, context=None): translation_pool = self.pool.get('ir.translation') tid = int(job['custom_data']) vals = {} - if job.get('job_id', False): - vals['job_id'] = job['job_id'] + if job.get('status', False) in ('queued', 'available', 'pending', 'reviewable'): vals['state'] = 'inprogress' - if job.get('status', False) in ('queued','available','pending','reviewable'): - vals['state'] = 'inprogress' - if job.get('body_tgt', False) and job.get('status', False)=='approved': + if job.get('body_tgt', False) and job.get('status', False) == 'approved': vals['value'] = job['body_tgt'] if job.get('status', False) in ('approved', 'canceled'): vals['state'] = 'translated' if vals: 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 """ - 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(): self._update_terms_job(cr, uid, res, context=context) + return 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 ""): comment = user.company_id.gengo_comment or '' 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)] = { 'type': 'text', '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), 'auto_approve': auto_approve, '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): """ @@ -200,7 +233,7 @@ class base_gengo_translations(osv.osv_memory): if request['jobs']: result = gengo.postTranslationJobs(jobs=request) 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: _logger.error(gengo) return True @@ -218,10 +251,10 @@ class base_gengo_translations(osv.osv_memory): context = {} language_pool = self.pool.get('res.lang') 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): 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) try: diff --git a/addons/website/static/src/js/website.translator.js b/addons/website/static/src/js/website.translator.js index e88b1e4a6b6..ee61a154d73 100644 --- a/addons/website/static/src/js/website.translator.js +++ b/addons/website/static/src/js/website.translator.js @@ -6,6 +6,7 @@ var nodialog = 'website_translator_nodialog'; website.EditorBar.include({ + do_not_translate : ['-','*','!'], events: _.extend({}, website.EditorBar.prototype.events, { 'click a[data-action=edit_master]': 'edit_master', }), @@ -129,7 +130,7 @@ node.className += ' oe_translatable_inprogress'; } } else { - node.className += ' oe_translatable_todo'; + node.className += this.do_not_translate.indexOf(node.textContent.trim()) ? ' oe_translatable_todo' : ''; } node.contentEditable = true; var nid = _.uniqueId(); diff --git a/openerp/addons/base/ir/ir_translation.py b/openerp/addons/base/ir/ir_translation.py index b6a7a722ddb..7952c957caf 100644 --- a/openerp/addons/base/ir/ir_translation.py +++ b/openerp/addons/base/ir/ir_translation.py @@ -288,6 +288,31 @@ class ir_translation(osv.osv): }) 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) 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 '') if isinstance(types, basestring): types = (types,) - 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),) - 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))) + + query, params = self._get_source_query(cr, uid, name, types, lang, source, res_id) + + cr.execute(query, params) res = cr.fetchone() trad = res and res[0] or u'' if source and not trad: