[MERGE] website_gengo branch merged, offering the possiblity to translate the website using Gengo
bzr revid: qdp-launchpad@openerp.com-20140401073953-p46kottwmk9buhor
This commit is contained in:
commit
0a2a118ba3
|
@ -4,7 +4,7 @@
|
|||
<!--Scheduler sync Receive Request-->
|
||||
<record id="gengo_sync_receive_request_scheduler" model="ir.cron">
|
||||
<field name="name" >Gengo Sync Translation (Response)</field>
|
||||
<field eval="False" name="active"/>
|
||||
<field eval="True" name="active"/>
|
||||
<field name="interval_number">20</field>
|
||||
<field name="interval_type">minutes</field>
|
||||
<field name="numbercall">-1</field>
|
||||
|
@ -16,7 +16,7 @@
|
|||
<!--Scheduler Sync Send Request-->
|
||||
<record id="gengo_sync_send_request_scheduler" model="ir.cron">
|
||||
<field name="name" >Gengo Sync Translation (Request)</field>
|
||||
<field eval="False" name="active"/>
|
||||
<field eval="True" name="active"/>
|
||||
<field name="interval_number">20</field>
|
||||
<field name="interval_type">minutes</field>
|
||||
<field name="numbercall">-1</field>
|
||||
|
|
|
@ -23,7 +23,7 @@ from openerp.osv import fields, osv
|
|||
from openerp.tools.translate import _
|
||||
|
||||
LANG_CODE_MAPPING = {
|
||||
'ar_SA': ('ar', 'Arabic'),
|
||||
'ar_SY': ('ar', 'Arabic'),
|
||||
'id_ID': ('id', 'Indonesian'),
|
||||
'nl_NL': ('nl', 'Dutch'),
|
||||
'fr_CA': ('fr-ca', 'French (Canada)'),
|
||||
|
@ -41,7 +41,19 @@ LANG_CODE_MAPPING = {
|
|||
'fr_BE': ('fr', 'French'),
|
||||
'ru_RU': ('ru', 'Russian'),
|
||||
'it_IT': ('it', 'Italian'),
|
||||
'pt_BR': ('pt-br', 'Portuguese (Brazil)')
|
||||
'pt_BR': ('pt-br', 'Portuguese (Brazil)'),
|
||||
'th_TH': ('th', 'Thai'),
|
||||
'nb_NO': ('no', 'Norwegian'),
|
||||
'ro_RO': ('ro', 'Romanian'),
|
||||
'tr_TR': ('tr', 'Turkish'),
|
||||
'bg_BG': ('bg', 'Bulgarian'),
|
||||
'da_DK': ('da', 'Danish'),
|
||||
'en_GB': ('en-gb', 'English (British)'),
|
||||
'el_GR': ('el', 'Greek'),
|
||||
'vi_VN': ('vi', 'Vietnamese'),
|
||||
'he_IL': ('he', 'Hebrew'),
|
||||
'hu_HU': ('hu', 'Hungarian'),
|
||||
'fi_FI': ('fi', 'Finnish')
|
||||
}
|
||||
|
||||
class ir_translation(osv.Model):
|
||||
|
@ -71,18 +83,3 @@ 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 _check_lang_support(self, cr, uid, ids, context=None):
|
||||
for term in self.browse(cr, uid, ids, context=context):
|
||||
if term.gengo_translation:
|
||||
supported_langs = self._get_all_supported_languages(cr, uid, context=context)
|
||||
if supported_langs:
|
||||
tier = "nonprofit" if term.gengo_translation == 'machine' else term.gengo_translation
|
||||
language = self._get_gengo_corresponding_language(term.lang)
|
||||
if tier not in supported_langs.get(language,[]):
|
||||
return False
|
||||
return True
|
||||
|
||||
_constraints = [
|
||||
(_check_lang_support, 'The Gengo translation service selected is not supported for this language.', ['gengo_translation'])
|
||||
]
|
||||
|
|
|
@ -30,6 +30,7 @@ class res_company(osv.Model):
|
|||
"gengo_public_key": fields.text("Gengo Public Key"),
|
||||
"gengo_comment": fields.text("Comments", help="This comment will be automatically be enclosed in each an every request sent to Gengo"),
|
||||
"gengo_auto_approve": fields.boolean("Auto Approve Translation ?", help="Jobs are Automatically Approved by Gengo."),
|
||||
"gengo_sandbox": fields.boolean("Sandbox Mode", help="Check this box if you're using the sandbox mode of Gengo, mainly used for testing purpose."),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
|
|
|
@ -17,8 +17,13 @@
|
|||
<field name="gengo_private_key" password="True" nolabel="1" placeholder="Add Gengo login Private Key..."/>
|
||||
</group>
|
||||
</group>
|
||||
<group col="4">
|
||||
<field name="gengo_auto_approve"/>
|
||||
<group>
|
||||
<group>
|
||||
<field name="gengo_auto_approve"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="gengo_sandbox"/>
|
||||
</group>
|
||||
</group>
|
||||
<group string="Comments for Translator" col="1">
|
||||
<field name="gengo_comment" nolabel="1" placeholder="Add your comments here for translator...."/>
|
||||
|
|
|
@ -40,22 +40,19 @@ except ImportError:
|
|||
|
||||
GENGO_DEFAULT_LIMIT = 20
|
||||
|
||||
DEFAULT_CRON_VALS = {
|
||||
'active': True,
|
||||
'interval_number': 20,
|
||||
'interval_type': 'minutes',
|
||||
'model': "'base.gengo.translations'",
|
||||
'args': "'(%s,)'" % (str(GENGO_DEFAULT_LIMIT)),
|
||||
}
|
||||
|
||||
class base_gengo_translations(osv.osv_memory):
|
||||
|
||||
_name = 'base.gengo.translations'
|
||||
_columns = {
|
||||
'restart_send_job': fields.boolean("Restart Sending Job"),
|
||||
'sync_type': fields.selection([('send', 'Send New Terms'),
|
||||
('receive', 'Receive Translation'),
|
||||
('both', 'Both')], "Sync Type"),
|
||||
'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
|
||||
}
|
||||
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
|
||||
|
@ -74,6 +71,7 @@ class base_gengo_translations(osv.osv_memory):
|
|||
gengo = MyGengo(
|
||||
public_key=user.company_id.gengo_public_key.encode('ascii'),
|
||||
private_key=user.company_id.gengo_private_key.encode('ascii'),
|
||||
sandbox = user.company_id.gengo_sandbox,
|
||||
)
|
||||
gengo.getAccountStats()
|
||||
return (True, gengo)
|
||||
|
@ -81,22 +79,6 @@ class base_gengo_translations(osv.osv_memory):
|
|||
_logger.exception('Gengo connection failed')
|
||||
return (False, _("Gengo connection failed with this message:\n``%s``") % e)
|
||||
|
||||
def do_check_schedular(self, cr, uid, xml_id, name, fn, context=None):
|
||||
"""
|
||||
This function is used to reset a cron to its default values, or to recreate it if it was deleted.
|
||||
"""
|
||||
cron_pool = self.pool.get('ir.cron')
|
||||
cron_vals = DEFAULT_CRON_VALS.copy()
|
||||
cron_vals.update({'name': name, "function": fn})
|
||||
try:
|
||||
res = []
|
||||
_, res = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'base_gengo', xml_id)
|
||||
cron_pool.write(cr, uid, [res], cron_vals, context=context)
|
||||
except:
|
||||
#the cron job was not found, probably deleted previously, so we create it again using default values
|
||||
cron_vals.update({'numbercall': -1})
|
||||
return cron_pool.create(cr, uid, cron_vals, context=context)
|
||||
|
||||
def act_update(self, cr, uid, ids, context=None):
|
||||
'''
|
||||
Function called by the wizard.
|
||||
|
@ -113,15 +95,14 @@ class base_gengo_translations(osv.osv_memory):
|
|||
if language not in supported_langs:
|
||||
raise osv.except_osv(_("Warning"), _('This language is not supported by the Gengo translation services.'))
|
||||
|
||||
#send immediately a new request for the selected language (if any)
|
||||
ctx = context.copy()
|
||||
ctx['gengo_language'] = wizard.lang_id.id
|
||||
self._sync_request(cr, uid, limit=GENGO_DEFAULT_LIMIT, context=ctx)
|
||||
self._sync_response( cr, uid, limit=GENGO_DEFAULT_LIMIT, context=ctx)
|
||||
#check the cron jobs and eventually restart/recreate them
|
||||
if wizard.restart_send_job:
|
||||
self.do_check_schedular(cr, uid, 'gengo_sync_send_request_scheduler', _('Gengo Sync Translation (Request)'), '_sync_request', context=context)
|
||||
self.do_check_schedular(cr, uid, 'gengo_sync_receive_request_scheduler', _('Gengo Sync Translation (Response)'), '_sync_response', context=context)
|
||||
if wizard.sync_limit > 200 or wizard.sync_limit < 1:
|
||||
raise osv.except_osv(_("Warning"), _('Sync limit should between 1 to 200 for Gengo translation services.'))
|
||||
if wizard.sync_type in ['send','both']:
|
||||
self._sync_request(cr, uid, wizard.sync_limit, context=ctx)
|
||||
if wizard.sync_type in ['receive','both']:
|
||||
self._sync_response( cr, uid, wizard.sync_limit, context=ctx)
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
def _sync_response(self, cr, uid, limit=GENGO_DEFAULT_LIMIT, context=None):
|
||||
|
@ -135,31 +116,31 @@ class base_gengo_translations(osv.osv_memory):
|
|||
if not flag:
|
||||
_logger.warning("%s", gengo)
|
||||
else:
|
||||
translation_id = translation_pool.search(cr, uid, [('state', '=', 'inprogress'), ('gengo_translation', 'in', ('machine','standard','pro','ultra'))], limit=limit, context=context)
|
||||
for term in translation_pool.browse(cr, uid, translation_id, context=context):
|
||||
up_term = up_comment = 0
|
||||
if term.job_id:
|
||||
vals={}
|
||||
job_response = gengo.getTranslationJob(id=term.job_id)
|
||||
if job_response['opstat'] != 'ok':
|
||||
_logger.warning("Invalid Response! Skipping translation Terms with `id` %s." % (term.job_id))
|
||||
continue
|
||||
if job_response['response']['job']['status'] == 'approved':
|
||||
vals.update({'state': 'translated',
|
||||
'value': job_response['response']['job']['body_tgt']})
|
||||
up_term += 1
|
||||
job_comment = gengo.getTranslationJobComments(id=term.job_id)
|
||||
if job_comment['opstat']=='ok':
|
||||
gengo_comments=""
|
||||
for comment in job_comment['response']['thread']:
|
||||
gengo_comments += _('%s\n\n--\n Commented on %s by %s.') % (comment['body'], time.ctime(comment['ctime']), comment['author'])
|
||||
vals.update({'gengo_comment': gengo_comments})
|
||||
up_comment += 1
|
||||
if vals:
|
||||
translation_pool.write(cr, uid, term.id, vals)
|
||||
_logger.info("Successfully Updated `%d` terms and %d Comments." % (up_term, up_comment ))
|
||||
else:
|
||||
_logger.warning("%s", 'Cannot retrieve the Gengo job ID for translation %s: %s' % (term.id, term.src))
|
||||
translation_id = translation_pool.search(cr, uid, [('state', '=', 'inprogress'), ('gengo_translation', 'in', ('machine','standard','pro','ultra')), ('job_id', "!=",False)], limit=limit, context=context)
|
||||
translation_terms = translation_pool.browse(cr, uid, translation_id, context=context)
|
||||
gengo_job_id = [term.job_id for term in translation_terms]
|
||||
if gengo_job_id:
|
||||
gengo_ids = ','.join(gengo_job_id)
|
||||
job_response = gengo.getTranslationJobBatch(id=gengo_ids)
|
||||
if job_response['opstat'] == 'ok':
|
||||
job_response_dict = dict([(job['job_id'],job) for job in job_response['response']['jobs']])
|
||||
for term in translation_terms:
|
||||
up_term = up_comment = 0
|
||||
vals={}
|
||||
if job_response_dict[term.job_id]['status'] == 'approved':
|
||||
vals.update({'state': 'translated',
|
||||
'value': job_response_dict[term.job_id]['body_tgt']})
|
||||
up_term += 1
|
||||
job_comment = gengo.getTranslationJobComments(id=term.job_id)
|
||||
if job_comment['opstat']=='ok':
|
||||
gengo_comments=""
|
||||
for comment in job_comment['response']['thread']:
|
||||
gengo_comments += _('%s\n-- Commented on %s by %s.\n\n') % (comment['body'], time.ctime(comment['ctime']), comment['author'])
|
||||
vals.update({'gengo_comment': gengo_comments})
|
||||
up_comment += 1
|
||||
if vals:
|
||||
translation_pool.write(cr, uid, term.id, vals)
|
||||
_logger.info("Successfully Updated `%d` terms and %d Comments." % (up_term, up_comment ))
|
||||
return True
|
||||
|
||||
def _update_terms(self, cr, uid, response, context=None):
|
||||
|
@ -200,7 +181,8 @@ class base_gengo_translations(osv.osv_memory):
|
|||
'lc_src': 'en',
|
||||
'lc_tgt': translation_pool._get_gengo_corresponding_language(term.lang),
|
||||
'auto_approve': auto_approve,
|
||||
'comment': user.company_id.gengo_comment,
|
||||
'comment': user.company_id.gengo_comment and "%s %s"%(user.company_id.gengo_comment,term.gengo_comment) or term.gengo_comment,
|
||||
'callback_url': self.pool.get('ir.config_parameter').get_param(cr, uid,'web.base.url') + '/website/gengo_callback/' + str(term.id)
|
||||
}
|
||||
return {'jobs': jobs}
|
||||
|
||||
|
@ -242,7 +224,7 @@ class base_gengo_translations(osv.osv_memory):
|
|||
lang_ids = [context.get('gengo_language')]
|
||||
langs = [lang.code for lang in language_pool.browse(cr, uid, lang_ids, context=context)]
|
||||
#search for the n first terms to translate
|
||||
term_ids = translation_pool.search(cr, uid, [('state', '=', 'to_translate'), ('gengo_translation', 'in', ('machine','standard','pro','ultra')), ('lang', 'in', langs)], limit=limit, context=context)
|
||||
term_ids = translation_pool.search(cr, uid, [('state', '=', 'to_translate'), ('gengo_translation', 'in', ('machine','standard','pro','ultra')), ('lang', 'in', langs),('job_id',"=",False)], limit=limit, context=context)
|
||||
if term_ids:
|
||||
self._send_translation_terms(cr, uid, term_ids, context=context)
|
||||
_logger.info("%s Translation terms have been posted to Gengo successfully", len(term_ids))
|
||||
|
|
|
@ -8,7 +8,14 @@
|
|||
<form string="Gengo Request Form" version="7.0">
|
||||
<group>
|
||||
<field name="lang_id"/>
|
||||
<field name="restart_send_job"/>
|
||||
</group>
|
||||
<group>
|
||||
<group>
|
||||
<field name="sync_type" widget="radio"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="sync_limit" required="1"/>
|
||||
</group>
|
||||
</group>
|
||||
<footer>
|
||||
<button name="act_update" string="Send" type="object" class="oe_highlight"/>
|
||||
|
|
|
@ -206,7 +206,7 @@ class Website(openerp.addons.web.controllers.main.Home):
|
|||
views_ids = [view.get('id') for view in views if view.get('active')]
|
||||
domain = [('type', '=', 'view'), ('res_id', 'in', views_ids), ('lang', '=', lang)]
|
||||
irt = request.registry.get('ir.translation')
|
||||
return irt.search_read(request.cr, request.uid, domain, ['id', 'res_id', 'value'], context=request.context)
|
||||
return irt.search_read(request.cr, request.uid, domain, ['id', 'res_id', 'value','state','gengo_translation'], context=request.context)
|
||||
|
||||
@http.route('/website/set_translations', type='json', auth='public', website=True)
|
||||
def set_translations(self, data, lang):
|
||||
|
@ -240,6 +240,9 @@ class Website(openerp.addons.web.controllers.main.Home):
|
|||
'source': initial_content,
|
||||
'value': new_content,
|
||||
}
|
||||
if t.get('gengo_translation'):
|
||||
new_trans['gengo_translation'] = t.get('gengo_translation')
|
||||
new_trans['gengo_comment'] = t.get('gengo_comment')
|
||||
irt.create(request.cr, request.uid, new_trans)
|
||||
return True
|
||||
|
||||
|
|
|
@ -34,11 +34,17 @@
|
|||
dialog.$el.modal('hide');
|
||||
self.translate().then(function () {
|
||||
mysuper.call(self);
|
||||
if(self.gengo_translate){
|
||||
self.translation_gengo_display()
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.translate().then(function () {
|
||||
mysuper.call(self);
|
||||
if(self.gengo_translate){
|
||||
self.translation_gengo_display()
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
@ -68,7 +74,7 @@
|
|||
var source_attr = 'data-oe-source-id';
|
||||
var $editables = $('[data-oe-model="ir.ui.view"]')
|
||||
.not('link, script')
|
||||
.not('.oe_snippets,.oe_snippet, .oe_snippet *')
|
||||
.not('.oe_snippets,.oe_snippet, .oe_snippet *, .navbar-toggle')
|
||||
.not('[data-oe-type]');
|
||||
|
||||
$editables.each(function () {
|
||||
|
@ -92,7 +98,7 @@
|
|||
self.sanitizeNode($node[0]);
|
||||
}
|
||||
if (self.getInitialContent($node[0]) !== $node.text()) {
|
||||
$node.addClass('oe_dirty').removeClass('oe_translatable_todo');
|
||||
$node.addClass('oe_dirty').removeClass('oe_translatable_todo oe_translatable_inprogress');
|
||||
}
|
||||
}, 0);
|
||||
});
|
||||
|
@ -119,6 +125,9 @@
|
|||
});
|
||||
if (trans.length) {
|
||||
node.setAttribute('data-oe-translation-id', trans[0].id);
|
||||
if(trans[0].gengo_translation && (trans[0].state == 'inprogress' || trans[0].state == 'to_translate')){
|
||||
node.className += ' oe_translatable_inprogress';
|
||||
}
|
||||
} else {
|
||||
node.className += ' oe_translatable_todo';
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
</section>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<div class="pull-left">
|
||||
<div class="pull-right">
|
||||
<input type="checkbox" name="do_not_show"/>
|
||||
Do not show this dialog later.
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2013-Today OpenERP S.A. (<http://www.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/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import controllers
|
|
@ -0,0 +1,42 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2013-Today OpenERP S.A. (<http://www.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/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
{
|
||||
'name': 'Website Gengo Translator',
|
||||
'category': 'Website',
|
||||
'version': '1.0',
|
||||
'description': """
|
||||
Website Gengo Translator
|
||||
========================
|
||||
|
||||
Translate you website in one click
|
||||
""",
|
||||
'author': 'OpenERP SA',
|
||||
'depends': [
|
||||
'website',
|
||||
'base_gengo'
|
||||
],
|
||||
'data': [
|
||||
'views/website_gengo.xml',
|
||||
],
|
||||
'qweb': [],
|
||||
'installable': True,
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
import main
|
|
@ -0,0 +1,60 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import openerp
|
||||
from openerp.addons.web import http
|
||||
from openerp.addons.web.http import request
|
||||
import time
|
||||
import json
|
||||
from openerp.tools.translate import _
|
||||
|
||||
|
||||
GENGO_DEFAULT_LIMIT = 20
|
||||
|
||||
class website_gengo(http.Controller):
|
||||
|
||||
@http.route('/website/get_translated_length', type='json', auth='user', website=True)
|
||||
def get_translated_length(self, translated_ids, lang):
|
||||
ir_translation_obj = request.registry['ir.translation']
|
||||
result={"done":0}
|
||||
gengo_translation_ids = ir_translation_obj.search(request.cr, request.uid, [('id','in',translated_ids),('gengo_translation','!=', False)])
|
||||
for trans in ir_translation_obj.browse(request.cr, request.uid, gengo_translation_ids):
|
||||
result['done'] += len(trans.source.split())
|
||||
return result
|
||||
|
||||
@http.route('/website/check_gengo_set', type='json', auth='user', website=True)
|
||||
def check_gengo_set(self):
|
||||
user = request.registry['res.users'].browse(request.cr, request.uid, request.uid)
|
||||
company_flag = 0
|
||||
if not user.company_id.gengo_public_key or not user.company_id.gengo_private_key:
|
||||
company_flag = user.company_id.id
|
||||
return company_flag
|
||||
|
||||
@http.route('/website/set_gengo_config', type='json', auth='user', website=True)
|
||||
def set_gengo_config(self,config):
|
||||
user = request.registry['res.users'].browse(request.cr, request.uid, request.uid)
|
||||
if user.company_id:
|
||||
request.registry['res.company'].write(request.cr, request.uid, user.company_id.id,config)
|
||||
return True
|
||||
|
||||
@http.route('/website/post_gengo_jobs', type='json', auth='user', website=True)
|
||||
def post_gengo_jobs(self):
|
||||
request.registry['base.gengo.translations']._sync_request(request.cr, request.uid, limit=GENGO_DEFAULT_LIMIT, context=request.context)
|
||||
return True
|
||||
|
||||
@http.route('/website/gengo_callback/<model("ir.translation"):term>', type='http', auth='none')
|
||||
def gengo_callback(self,term,**post):
|
||||
if post and post.get('job'):
|
||||
translation_pool = request.registry['ir.translation']
|
||||
base_gengo_pool = request.registry['base.gengo.translations']
|
||||
job, vals = json.loads(post['job']), {}
|
||||
if job.get('status') == 'approved':
|
||||
vals.update({'state': 'translated', 'value': job.get('body_tgt')})
|
||||
flag, gengo = base_gengo_pool.gengo_authentication(request.cr, openerp.SUPERUSER_ID, context=request.context)
|
||||
job_comment = gengo.getTranslationJobComments(id=job.get('job_id'))
|
||||
if job_comment['opstat']=='ok':
|
||||
gengo_comments=""
|
||||
for comment in job_comment['response']['thread']:
|
||||
gengo_comments += _('%s\n-- Commented on %s by %s.\n\n') % (comment['body'], time.ctime(comment['ctime']), comment['author'])
|
||||
vals.update({'gengo_comment': gengo_comments})
|
||||
if vals:
|
||||
translation_pool.write(request.cr, openerp.SUPERUSER_ID, term.id, vals)
|
|
@ -0,0 +1,3 @@
|
|||
.oe_translatable_inprogress {
|
||||
background: #b7e4ff;
|
||||
}
|
|
@ -0,0 +1,188 @@
|
|||
(function () {
|
||||
'use strict';
|
||||
|
||||
var website = openerp.website;
|
||||
website.add_template_file('/website_gengo/static/src/xml/website.gengo.xml');
|
||||
|
||||
website.EditorBar.include({
|
||||
events: _.extend({}, website.EditorBar.prototype.events, {
|
||||
'click a[data-action=translation_gengo_post]': 'translation_gengo_post',
|
||||
'click a[data-action=translation_gengo_info]': 'translation_gengo_info',
|
||||
}),
|
||||
edit:function () {
|
||||
this.gengo_translate = true;
|
||||
this._super.apply(this, arguments);
|
||||
var self = this;
|
||||
var gengo_langs = ["ar_SY","id_ID","nl_NL","fr_CA","pl_PL","zh_TW","sv_SE","ko_KR","pt_PT","en_US","ja_JP","es_ES","zh_CN","de_DE","fr_FR","fr_BE","ru_RU","it_IT","pt_BR","pt_BR","th_TH","nb_NO","ro_RO","tr_TR","bg_BG","da_DK","en_GB","el_GR","vi_VN","he_IL","hu_HU","fi_FI"];
|
||||
if (gengo_langs.indexOf(website.get_context()['lang']) != -1){
|
||||
self.$('.gengo_post,.gengo_wait,.gengo_inprogress,.gengo_info').remove();
|
||||
self.$('button[data-action=save]')
|
||||
.after(openerp.qweb.render('website.ButtonGengoTranslator'));
|
||||
}
|
||||
},
|
||||
translation_gengo_display:function(){
|
||||
var self = this;
|
||||
if($('.oe_translatable_todo').length == 0){
|
||||
self.$el.find('.gengo_post').addClass("hidden");
|
||||
self.$el.find('.gengo_inprogress').removeClass("hidden");
|
||||
}
|
||||
},
|
||||
translation_gengo_post: function () {
|
||||
var self = this;
|
||||
var translatable_list = $.find('.oe_translatable_todo');
|
||||
this.new_words = 0;
|
||||
$('.oe_translatable_todo').each(function () {
|
||||
self.new_words += $(this).text().trim().replace(/ +/g," ").split(" ").length;
|
||||
});
|
||||
openerp.jsonRpc('/website/check_gengo_set', 'call', {
|
||||
}).then(function (res) {
|
||||
if (res == 0){
|
||||
var dialog = new website.GengoTranslatorPostDialog(self.new_words);
|
||||
dialog.appendTo($(document.body));
|
||||
dialog.on('service_level', this, function () {
|
||||
var gengo_service_level = dialog.$el.find(".form-control").val();
|
||||
dialog.$el.modal('hide');
|
||||
self.$el.find('.gengo_post').addClass("hidden");
|
||||
self.$el.find('.gengo_wait').removeClass("hidden");
|
||||
var trans ={}
|
||||
$('.oe_translatable_todo').each(function () {
|
||||
var $node = $(this);
|
||||
var data = $node.data();
|
||||
if (!trans[data.oeTranslationViewId]) {
|
||||
trans[data.oeTranslationViewId] = [];
|
||||
}
|
||||
trans[data.oeTranslationViewId].push({
|
||||
initial_content: self.getInitialContent(this),
|
||||
new_content:self.getInitialContent(this),
|
||||
translation_id: data.oeTranslationId || null,
|
||||
gengo_translation: gengo_service_level,
|
||||
gengo_comment:"Original page:" + document.URL
|
||||
});
|
||||
});
|
||||
openerp.jsonRpc('/website/set_translations', 'call', {
|
||||
'data': trans,
|
||||
'lang': website.get_context()['lang'],
|
||||
}).then(function () {
|
||||
$('.oe_translatable_todo').addClass('oe_translatable_inprogress').removeClass('oe_translatable_todo');
|
||||
self.$el.find('.gengo_wait').addClass("hidden");
|
||||
self.$el.find('.gengo_inprogress,.gengo_discard').removeClass("hidden");
|
||||
openerp.jsonRpc('/website/post_gengo_jobs', 'call', {});
|
||||
self.save();
|
||||
}).fail(function () {
|
||||
alert("Could not Post translation");
|
||||
});
|
||||
});
|
||||
}else{
|
||||
var dialog = new website.GengoApiConfigDialog(res);
|
||||
dialog.appendTo($(document.body));
|
||||
dialog.on('set_config', this, function () {
|
||||
dialog.$el.modal('hide');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
translation_gengo_info: function () {
|
||||
var repr = $(document.documentElement).data('mainObject');
|
||||
var view_id = repr.match(/.+\((.+), (\d+)\)/)[2];
|
||||
var translated_ids = [];
|
||||
$('.oe_translatable_text').not(".oe_translatable_inprogress").each(function(){
|
||||
translated_ids.push($(this).attr('data-oe-translation-id'));
|
||||
});
|
||||
openerp.jsonRpc('/website/get_translated_length', 'call', {
|
||||
'translated_ids': translated_ids,
|
||||
'lang': website.get_context()['lang'],
|
||||
}).done(function(res){
|
||||
var dialog = new website.GengoTranslatorStatisticDialog(res);
|
||||
dialog.appendTo($(document.body));
|
||||
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
website.GengoTranslatorPostDialog = openerp.Widget.extend({
|
||||
events: _.extend({}, website.EditorBar.prototype.events, {
|
||||
'hidden.bs.modal': 'destroy',
|
||||
'click button[data-action=service_level]': function (ev) {
|
||||
this.trigger('service_level');
|
||||
},
|
||||
}),
|
||||
template: 'website.GengoTranslatorPostDialog',
|
||||
init:function(new_words){
|
||||
this.new_words = new_words;
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
start: function () {
|
||||
this.$el.modal();
|
||||
},
|
||||
});
|
||||
|
||||
website.GengoTranslatorStatisticDialog = openerp.Widget.extend({
|
||||
events: _.extend({}, website.EditorBar.prototype.events, {
|
||||
'hidden.bs.modal': 'destroy',
|
||||
}),
|
||||
template: 'website.GengoTranslatorStatisticDialog',
|
||||
init:function(res){
|
||||
var self = this;
|
||||
this.inprogess = 0;
|
||||
this.new_words = 0;
|
||||
this.done = res.done;
|
||||
$('.oe_translatable_todo').each(function () {
|
||||
self.new_words += $(this).text().trim().replace(/ +/g," ").split(" ").length;
|
||||
});
|
||||
$('.oe_translatable_inprogress').each(function () {
|
||||
self.inprogess += $(this).text().trim().replace(/ +/g," ").split(" ").length;
|
||||
});
|
||||
this.total = this.done + this.inprogess;
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
start: function (res) {
|
||||
this.$el.modal(this.res);
|
||||
},
|
||||
});
|
||||
website.GengoApiConfigDialog = openerp.Widget.extend({
|
||||
events: _.extend({}, website.EditorBar.prototype.events, {
|
||||
'hidden.bs.modal': 'destroy',
|
||||
'click button[data-action=set_config]': 'set_config'
|
||||
}),
|
||||
template: 'website.GengoApiConfigDialog',
|
||||
init:function(company_id){
|
||||
this.company_id = company_id;
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
start: function (res) {
|
||||
this.$el.modal(this.res);
|
||||
},
|
||||
set_config:function(ev){
|
||||
var self = this;
|
||||
var public_key = this.$el.find("#gengo_public_key")[0].value;
|
||||
var private_key = this.$el.find("#gengo_private_key")[0].value;
|
||||
var auto_approve = this.$el.find("#gengo_auto_approve")[0].checked;
|
||||
var sandbox = this.$el.find("#gengo_sandbox")[0].checked;
|
||||
var pub_el = this.$el.find(".gengo_group_public")[0];
|
||||
var pri_el = this.$el.find(".gengo_group_private")[0];
|
||||
if(! public_key){
|
||||
$(pub_el).addClass("has-error");
|
||||
}
|
||||
else{
|
||||
$(pub_el).removeClass("has-error");
|
||||
}
|
||||
if(! private_key){
|
||||
$(pri_el).addClass("has-error");
|
||||
}
|
||||
else{
|
||||
$(pri_el).removeClass("has-error");
|
||||
}
|
||||
if(public_key && private_key){
|
||||
openerp.jsonRpc('/website/set_gengo_config', 'call', {
|
||||
'config': {'gengo_public_key':public_key,'gengo_private_key':private_key,'gengo_auto_approve':auto_approve,'gengo_sandbox':sandbox},
|
||||
}).then(function () {
|
||||
self.trigger('set_config');
|
||||
}).fail(function () {
|
||||
alert("Could not submit ! Try Again");
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
})();
|
|
@ -0,0 +1,163 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<templates id="template" xml:space="preserve">
|
||||
<t t-name="website.ButtonGengoTranslator">
|
||||
<a class="btn btn-danger gengo_post" data-action="translation_gengo_post" href="#">Auto Translate</a>
|
||||
<a class="btn btn-danger hidden gengo_wait disabled" href="#"><i class="fa fa-spinner fa-spin"></i> Wait</a>
|
||||
<a class="btn btn-danger hidden gengo_inprogress disabled" href="#"> <i class="fa fa-clock-o"></i> Translation in Progress</a>
|
||||
<a class="btn btn-link gengo_info" data-action="translation_gengo_info">Count Words</a>
|
||||
</t>
|
||||
<t t-name="website.TranslatorDialog">
|
||||
<div class="modal fade oe_website_translator" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button title="Close" type="button" class="close" data-dismiss="modal">×</button>
|
||||
<h2 class="modal-title">Translate this page</h2>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<section>
|
||||
<p>You are about to enter the translation mode.</p>
|
||||
<p>
|
||||
Here are the visuals used to help you translate efficiently:
|
||||
<ul class="oe_translate_examples">
|
||||
<li style="background:#ffffb6;">
|
||||
Content to translate or you can post them to <b><a href="http://gengo.com/" >Gengo</a></b> for translation.
|
||||
</li>
|
||||
<li class="oe_translatable_inprogress">
|
||||
Translation in process (Gengo)
|
||||
</li>
|
||||
<li class="oe_translatable_text">
|
||||
Already translated content
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
<p>
|
||||
In this mode, you can translate texts or post texts to Gengo for translation.
|
||||
To change the structure of the page, you must edit the
|
||||
master page.
|
||||
</p>
|
||||
</section>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<div>
|
||||
<input type="checkbox" name="do_not_show"/>
|
||||
Do not show this dialog later.
|
||||
</div>
|
||||
<div>
|
||||
<button type="button" data-action="activate" class="btn btn-primary">Ok</button>
|
||||
or
|
||||
<a data-action="discard" data-dismiss="modal" href="#">Cancel</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<t t-name="website.GengoTranslatorPostDialog">
|
||||
<div class="modal fade oe_website_translator" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button title="Close" type="button" class="close" data-dismiss="modal">×</button>
|
||||
<h2 class="modal-title">Select Gengo Translation Service Level</h2>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<section>
|
||||
<select class="form-control" required="required" autofocus="autofocus">
|
||||
<option value="machine">By Machine (Free)</option>
|
||||
<option value="standard">Standard - $ <t t-esc="(widget.new_words * 0.05).toFixed(2)"></t> </option>
|
||||
<option value="pro">Pro - $ <t t-esc="(widget.new_words * 0.10).toFixed(2)"></t></option>
|
||||
<option value="ultra">Ultra - $ <t t-esc="(widget.new_words * 0.15).toFixed(2)"></t></option>
|
||||
</select>
|
||||
</section>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" data-action="service_level" class="btn btn-primary">Post</button>
|
||||
or
|
||||
<a data-action="discard" data-dismiss="modal" href="#">Cancel</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<t t-name="website.GengoTranslatorStatisticDialog">
|
||||
<div class="modal fade oe_website_translator" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button title="Close" type="button" class="close" data-dismiss="modal">×</button>
|
||||
<h2 class="modal-title">Translator statistics for this page</h2>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<b>
|
||||
<div class="text-muted mb16"> <i class="fa fa-search-plus"></i> <t t-esc="widget.new_words"></t> new words found on this page.</div>
|
||||
<h4><i class="fa fa-dashboard"></i> Gengo Statistics <a href="https://gengo.com/c/dashboard" class="pull-right" target="new">Gengo Dashboard</a></h4>
|
||||
<hr class="mt8"/>
|
||||
<div class="text-info mb8"> <i class="fa fa-align-left"></i> Words posted for translate <t t-esc="widget.total"></t></div>
|
||||
<div class="text-warning mb8"> <i class="fa fa-cogs"></i> Words in progress <t t-esc="widget.inprogess"></t></div>
|
||||
<div class="text-success mb8"> <i class="fa fa-check"></i> Translated words <t t-esc="widget.done"></t></div>
|
||||
</b>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a data-action="discard" data-dismiss="modal" href="#">Close</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
<t t-name="website.GengoApiConfigDialog">
|
||||
<div class="modal fade oe_website_translator" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button title="Close" type="button" class="close" data-dismiss="modal">×</button>
|
||||
<h2 class="modal-title">Gengo API is not configured</h2>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<b> <h3>Steps for configure Gengo </h3>
|
||||
<div class="mb16"> 1. Go To your <b><a target="new" href="https://gengo.com/account/api_settings/">Gengo account</a></b> and generate API Keys.</div>
|
||||
<div class="mb16"> 2. Then paste generated keys in given form</div>
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item form-group gengo_group_public">
|
||||
<h4 class="list-group-item-heading">
|
||||
<label class="control-label">Public key</label>
|
||||
</h4>
|
||||
<input type="text" class="form-control url url-source" id="gengo_public_key" placeholder="Paste public key here"/>
|
||||
|
||||
</li>
|
||||
<li class="list-group-item form-group gengo_group_private">
|
||||
<h4 class="list-group-item-heading">
|
||||
<label for="link-external" class="control-label">Private key</label>
|
||||
</h4>
|
||||
<input type="text" class="form-control url url-source" id="gengo_private_key" placeholder="Paste private key here"/>
|
||||
</li>
|
||||
<li class="list-group-item form-group">
|
||||
<div>
|
||||
<label>
|
||||
<input type="checkbox" id="gengo_auto_approve" class="window-new" checked="1"/>
|
||||
Auto Approve Translation <small class="text-muted">- Jobs are Automatically Approved by Gengo.</small>
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label>
|
||||
<input type="checkbox" id="gengo_sandbox" class="window-new"/>
|
||||
Sandbox <small class="text-muted">- Enable if you using testing account</small>
|
||||
</label>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</b>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" data-action="set_config" class="btn btn-primary">Submit</button>
|
||||
or
|
||||
<a data-action="discard" data-dismiss="modal" href="#">Close</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
</templates>
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<template id="gengo_editor_head" inherit_id="website.editor_head" name="Editor Head" groups="base.group_website_publisher">
|
||||
<xpath expr='//script[@src="/website/static/src/js/website.translator.js"]' position="after">
|
||||
<link rel="stylesheet" href="/website_gengo/static/src/css/website_gengo.css"></link>
|
||||
<script t-if="translatable" type="text/javascript" src="/website_gengo/static/src/js/website_gengo.js"></script>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
</data>
|
||||
</openerp>
|
Loading…
Reference in New Issue