~ubuntu-branches/ubuntu/natty/tryton-server/natty-security

« back to all changes in this revision

Viewing changes to trytond/ir/translation.py

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Baumann, Daniel Baumann, Mathias Behrle
  • Date: 2009-04-21 19:27:00 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20090421192700-hmiosex03jt5qf01
Tags: 1.2.0-1
[ Daniel Baumann ]
* Merging upstream version 1.2.0.
* Tidy rules files.
* Updating version information in manpage.
* Updating copyright file for new upstream release.
* Including TODO file in docs.

[ Mathias Behrle ]
* Updating application description.

[ Daniel Baumann ]
* Correcting wrapping of control file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
10
10
from xml.dom import minidom
11
11
from difflib import SequenceMatcher
12
12
import csv
13
 
from trytond.osv import fields, OSV, Cacheable
14
 
from trytond.wizard import Wizard, WizardOSV
 
13
from trytond.model import ModelView, ModelSQL, fields
 
14
from trytond.model.cacheable import Cacheable
 
15
from trytond.wizard import Wizard
15
16
from trytond import tools
16
 
from trytond import pooler
 
17
from trytond.tools import file_open
 
18
from trytond.backend import TableHandler
 
19
import os
17
20
 
18
21
TRANSLATION_TYPE = [
19
22
    ('field', 'Field'),
35
38
csv.register_dialect("TRYTON", TRYTON)
36
39
 
37
40
 
38
 
class Translation(OSV, Cacheable):
 
41
class Translation(ModelSQL, ModelView, Cacheable):
39
42
    "Translation"
40
43
    _name = "ir.translation"
41
44
    _description = __doc__
53
56
 
54
57
    def __init__(self):
55
58
        super(Translation, self).__init__()
56
 
        Cacheable.__init__(self)
57
59
        self._sql_constraints += [
58
60
            ('translation_uniq',
59
61
                'UNIQUE (name, res_id, lang, type, src, module)',
61
63
        ]
62
64
        self._max_len = 10240
63
65
 
64
 
    def _auto_init(self, cursor, module_name):
65
 
        super(Translation, self)._auto_init(cursor, module_name)
66
 
        cursor.execute('SELECT indexname FROM pg_indexes ' \
67
 
                'WHERE indexname = ' \
68
 
                    '\'ir_translation_lang_type_name_index\'')
69
 
        if not cursor.rowcount:
70
 
            cursor.execute('CREATE INDEX ' \
71
 
                    'ir_translation_lang_type_name_index ' \
72
 
                    'ON ir_translation (lang, type, name)')
73
 
        cursor.execute('SELECT indexname FROM pg_indexes ' \
74
 
                'WHERE indexname = ' \
75
 
                    '\'ir_translation_lang_type_name_src_index\'')
76
 
        if not cursor.rowcount:
77
 
            cursor.execute('CREATE INDEX ' \
78
 
                    'ir_translation_lang_type_name_src_index ' \
79
 
                    'ON ir_translation (lang, type, name, src)')
 
66
    def init(self, cursor, module_name):
 
67
        super(Translation, self).init(cursor, module_name)
 
68
 
 
69
        table = TableHandler(cursor, self, module_name)
 
70
        table.index_action(['lang', 'type', 'name'], 'add')
 
71
        table.index_action(['lang', 'type', 'name', 'src'], 'add')
80
72
 
81
73
    def default_fuzzy(self, cursor, user, context=None):
82
74
        return False
106
98
        return res
107
99
 
108
100
    def _get_ids(self, cursor, name, ttype, lang, ids):
 
101
        model_fields_obj = self.pool.get('ir.model.field')
 
102
        model_obj = self.pool.get('ir.model')
 
103
 
109
104
        translations, to_fetch = {}, []
110
105
        name = unicode(name)
111
106
        ttype = unicode(ttype)
112
107
        lang = unicode(lang)
113
 
        if name.split(',')[0] == 'ir.model.field':
114
 
            model_fields_obj = self.pool.get('ir.model.field')
 
108
        if name.split(',')[0] in ('ir.model.field', 'ir.model'):
115
109
            field_name = name.split(',')[1]
116
 
            if field_name == 'field_description':
117
 
                ttype = 'field'
 
110
            if name.split(',')[0] == 'ir.model.field':
 
111
                if field_name == 'field_description':
 
112
                    ttype = u'field'
 
113
                else:
 
114
                    ttype = u'help'
 
115
                records = model_fields_obj.browse(cursor, 0, ids)
118
116
            else:
119
 
                ttype = 'help'
120
 
            fields = model_fields_obj.read(cursor, 0, ids,
121
 
                    ['model', 'name'])
 
117
                ttype = u'model'
 
118
                records = model_obj.browse(cursor, 0, ids)
122
119
 
123
120
            trans_args = []
124
 
            for field in fields:
125
 
                name = field['model'][1] + ',' + field['name']
 
121
            for record in records:
 
122
                if ttype in ('field', 'help'):
 
123
                    name = record.model.model + ',' + record.name
 
124
                else:
 
125
                    name = record.model + ',' + field_name
126
126
                trans_args.append((name, ttype, lang, None))
127
127
            self._get_sources(cursor, trans_args)
128
128
 
129
 
            for field in fields:
130
 
                name = field['model'][1] + ',' + field['name']
131
 
                translations[field['id']] = self._get_source(cursor,
 
129
            for record in records:
 
130
                if ttype in ('field', 'help'):
 
131
                    name = record.model.model + ',' + record.name
 
132
                else:
 
133
                    name = record.model + ',' + field_name
 
134
                translations[record.id] = self._get_source(cursor,
132
135
                        name, ttype, lang)
133
136
            return translations
134
137
        for obj_id in ids:
138
141
            else:
139
142
                to_fetch.append(obj_id)
140
143
        if to_fetch:
141
 
            cursor.execute('SELECT res_id, value ' \
142
 
                    'FROM ir_translation ' \
143
 
                    'WHERE lang = %s ' \
144
 
                        'AND type = %s ' \
145
 
                        'AND name = %s ' \
146
 
                        'AND value != \'\' ' \
147
 
                        'AND value IS NOT NULL ' \
148
 
                        'AND fuzzy = false ' \
149
 
                        'AND res_id in (' + \
150
 
                            ','.join([str(x) for x in to_fetch]) + ')',
151
 
                    (lang, ttype, name))
152
 
            for res_id, value in cursor.fetchall():
153
 
                self.add(cursor, (lang, ttype, name, res_id), value)
154
 
                translations[res_id] = value
 
144
            for i in range(0, len(to_fetch), cursor.IN_MAX):
 
145
                sub_to_fetch = to_fetch[i:i + cursor.IN_MAX]
 
146
                cursor.execute('SELECT res_id, value ' \
 
147
                        'FROM ir_translation ' \
 
148
                        'WHERE lang = %s ' \
 
149
                            'AND type = %s ' \
 
150
                            'AND name = %s ' \
 
151
                            'AND value != \'\' ' \
 
152
                            'AND value IS NOT NULL ' \
 
153
                            'AND fuzzy = false ' \
 
154
                            'AND res_id in (' + \
 
155
                                ','.join([str(x) for x in sub_to_fetch]) + ')',
 
156
                        (lang, ttype, name))
 
157
                for res_id, value in cursor.fetchall():
 
158
                    self.add(cursor, (lang, ttype, name, res_id), value)
 
159
                    translations[res_id] = value
155
160
        for res_id in ids:
156
161
            if res_id not in translations:
157
162
                self.add(cursor, (lang, ttype, name, res_id), False)
159
164
        return translations
160
165
 
161
166
    def _set_ids(self, cursor, user, name, ttype, lang, ids, value):
 
167
        model_fields_obj = self.pool.get('ir.model.field')
 
168
        model_obj = self.pool.get('ir.model')
 
169
 
162
170
        model_name, field_name = name.split(',')
163
 
        if model_name == 'ir.model.field':
164
 
            model_fields_obj = self.pool.get('ir.model.field')
165
 
            if field_name == 'field_description':
166
 
                ttype = 'field'
 
171
        if model_name in ('ir.model.field', 'ir.model'):
 
172
            if model_name == 'ir.model.field':
 
173
                if field_name == 'field_description':
 
174
                    ttype = 'field'
 
175
                else:
 
176
                    ttype = 'help'
 
177
                records = model_fields_obj.browse(cursor, user, ids)
167
178
            else:
168
 
                ttype = 'help'
169
 
            for field in model_fields_obj.browse(cursor, user, ids):
170
 
                name = field.model + ',' + field.name
 
179
                ttype = 'model'
 
180
                records = model_obj.browse(cursor, user, ids)
 
181
            for record in records:
 
182
                if ttype in ('field', 'help'):
 
183
                    name = record.model + ',' + record.name
171
184
                ids2 = self.search(cursor, user, [
172
185
                    ('lang', '=', lang),
173
186
                    ('type', '=', ttype),
178
191
                        'name': name,
179
192
                        'lang': lang,
180
193
                        'type': ttype,
181
 
                        'src': field[field_name],
 
194
                        'src': record[field_name],
182
195
                        'value': value,
183
196
                        'fuzzy': False,
184
197
                        })
185
198
                else:
186
199
                    self.write(cursor, user, ids, {
187
 
                        'src': field[field_name],
 
200
                        'src': record[field_name],
188
201
                        'value': value,
189
202
                        'fuzzy': False,
190
203
                        })
234
247
                        'AND src = %s ' \
235
248
                        'AND value != \'\' ' \
236
249
                        'AND value IS NOT NULL ' \
237
 
                        'AND fuzzy = false ',
 
250
                        'AND fuzzy = false ' \
 
251
                        'AND res_id = 0',
238
252
                    (lang, ttype, str(name), source))
239
253
        else:
240
254
            cursor.execute('SELECT value ' \
244
258
                        'AND name = %s ' \
245
259
                        'AND value != \'\' ' \
246
260
                        'AND value IS NOT NULL ' \
247
 
                        'AND fuzzy = false ',
 
261
                        'AND fuzzy = false ' \
 
262
                        'AND res_id = 0',
248
263
                    (lang, ttype, str(name)))
249
264
        res = cursor.fetchone()
250
265
        if res:
261
276
        Return a dict with the translations.
262
277
        '''
263
278
        res = {}
264
 
        clause = ''
265
 
        value = []
 
279
        clause = []
266
280
        if len(args) > cursor.IN_MAX:
267
281
            for i in range(0, len(args), cursor.IN_MAX):
268
282
                sub_args = args[i:i + cursor.IN_MAX]
280
294
            else:
281
295
                res[(name, ttype, lang, source)] = False
282
296
                self.add(cursor, (lang, ttype, name, source), False)
283
 
                if clause:
284
 
                    clause += ' OR '
285
297
                if source:
286
 
                    clause += '(lang = %s ' \
 
298
                    clause += [('(lang = %s ' \
287
299
                            'AND type = %s ' \
288
300
                            'AND name = %s ' \
289
301
                            'AND src = %s ' \
290
302
                            'AND value != \'\' ' \
291
303
                            'AND value IS NOT NULL ' \
292
 
                            'AND fuzzy = false)'
293
 
                    value.extend((lang, ttype, str(name), source))
 
304
                            'AND fuzzy = false ' \
 
305
                            'AND res_id = 0)',
 
306
                            (lang, ttype, str(name), source))]
294
307
                else:
295
 
                    clause += '(lang = %s ' \
 
308
                    clause += [('(lang = %s ' \
296
309
                            'AND type = %s ' \
297
310
                            'AND name = %s ' \
298
311
                            'AND value != \'\' ' \
299
312
                            'AND value IS NOT NULL ' \
300
 
                            'AND fuzzy = false)'
301
 
                    value.extend((lang, ttype, str(name)))
 
313
                            'AND fuzzy = false ' \
 
314
                            'AND res_id = 0)',
 
315
                            (lang, ttype, str(name)))]
302
316
        if clause:
303
 
            cursor.execute('SELECT lang, type, name, src, value ' \
304
 
                    'FROM ir_translation ' \
305
 
                    'WHERE ' + clause, value)
306
 
            for lang, ttype, name, source, value in cursor.fetchall():
307
 
                if (name, ttype, lang, source) not in args:
308
 
                    source = None
309
 
                res[(name, ttype, lang, source)] = value
310
 
                self.add(cursor, (lang, ttype, name, source), value)
 
317
            for i in range(0, len(clause), cursor.IN_MAX):
 
318
                sub_clause = clause[i:i + cursor.IN_MAX]
 
319
                cursor.execute('SELECT lang, type, name, src, value ' \
 
320
                        'FROM ir_translation ' \
 
321
                        'WHERE ' + ' OR '.join([x[0] for x in sub_clause]),
 
322
                        reduce(lambda x, y: x + y, [x[1] for x in sub_clause]))
 
323
                for lang, ttype, name, source, value in cursor.fetchall():
 
324
                    if (name, ttype, lang, source) not in args:
 
325
                        source = None
 
326
                    res[(name, ttype, lang, source)] = value
 
327
                    self.add(cursor, (lang, ttype, name, source), value)
311
328
        return res
312
329
 
313
330
    def delete(self, cursor, user, ids, context=None):
373
390
        reader = csv.reader(datas)
374
391
        for row in reader:
375
392
            break
 
393
 
 
394
        id2translation = {}
 
395
        key2ids = {}
 
396
        module_translation_ids = self.search(cursor, user, [
 
397
            ('lang', '=', lang),
 
398
            ('module', '=', module),
 
399
            ], context=context)
 
400
        for translation in self.browse(cursor, user, module_translation_ids,
 
401
                context=context):
 
402
            if translation.type in ('odt', 'view', 'wizard_button',
 
403
                    'selection', 'error'):
 
404
                key = (translation.name, translation.res_id, translation.type,
 
405
                        translation.src)
 
406
            elif translation.type in ('field', 'model','help'):
 
407
                key = (translation.name, translation.res_id, translation.type)
 
408
            else:
 
409
                raise Exception('Unknow translation type: %s' % translation.type)
 
410
            key2ids.setdefault(key, []).append(translation.id)
 
411
            id2translation[translation.id] = translation
 
412
 
376
413
        for row in reader:
377
 
            ttype = row[0]
378
 
            name = row[1]
379
 
            res_id = row[2]
380
 
            src = row[3]
381
 
            value = row[4]
382
 
            fuzzy = int(row[5])
383
 
            ids = []
 
414
            ttype = row[0].decode('utf-8')
 
415
            name = row[1].decode('utf-8')
 
416
            res_id = row[2].decode('utf-8')
 
417
            src = row[3].decode('utf-8')
 
418
            value = row[4].decode('utf-8')
 
419
            fuzzy = bool(int(row[5]))
384
420
 
385
421
            model = name.split(',')[0]
386
422
            if model in fs_id2db_id:
392
428
                continue
393
429
 
394
430
            if ttype in ('odt', 'view', 'wizard_button', 'selection', 'error'):
395
 
                ids = self.search(cursor, user, [
396
 
                    ('name', '=', name),
397
 
                    ('res_id', '=', res_id),
398
 
                    ('lang', '=', lang),
399
 
                    ('type', '=', ttype),
400
 
                    ('src', '=', src),
401
 
                    ], context=context)
 
431
                key = (name, res_id, ttype, src)
402
432
            elif ttype in('field', 'model','help'):
403
 
                ids = self.search(cursor, user, [
404
 
                    ('name', '=', name),
405
 
                    ('res_id', '=', res_id),
406
 
                    ('lang', '=', lang),
407
 
                    ('type', '=', ttype),
408
 
                    ], context=context)
 
433
                key = (name, res_id, ttype)
409
434
            else:
410
435
                raise Exception('Unknow translation type: %s' % ttype)
 
436
            ids = key2ids.get(key, [])
411
437
 
412
438
            if not ids:
413
 
                translation_ids.append(self.create(cursor, user, {
 
439
                translation_ids.append(self.create(cursor, 0, {
414
440
                    'name': name,
415
441
                    'res_id': res_id,
416
442
                    'lang': lang,
421
447
                    'module': module,
422
448
                    }, context=ctx))
423
449
            else:
424
 
                cursor.execute('SELECT id FROM ir_translation ' \
425
 
                        'WHERE (write_uid IS NULL OR write_uid = 0) ' \
426
 
                            'AND id IN ' \
427
 
                                '(' + ','.join(['%s' for x in ids]) + ')',
428
 
                        ids)
429
 
                ids2 = [x[0] for x in cursor.fetchall()]
 
450
                ids2 = []
 
451
                for translation_id in ids:
 
452
                    translation = id2translation[translation_id]
 
453
                    if translation.value != value \
 
454
                            or translation.fuzzy != fuzzy:
 
455
                        ids2.append(translation.id)
430
456
                if ids2:
431
 
                    self.write(cursor, user, ids2, {
 
457
                    self.write(cursor, 0, ids2, {
432
458
                        'value': value,
433
459
                        'fuzzy': fuzzy,
434
460
                        }, context=ctx)
435
461
                translation_ids += ids
436
462
 
437
 
        cursor.execute('DELETE FROM ir_translation ' \
438
 
                'WHERE module = %s ' \
439
 
                    'AND lang = %s ' \
440
 
                    'AND id NOT IN ' \
441
 
                        '(' + ','.join(['%s' for x in translation_ids]) + ')',
442
 
                (module, lang) + tuple(translation_ids))
 
463
        if translation_ids:
 
464
            for i in range(0, len(translation_ids), cursor.IN_MAX):
 
465
                sub_translation_ids = translation_ids[i:i + cursor.IN_MAX]
 
466
                cursor.execute('DELETE FROM ir_translation ' \
 
467
                        'WHERE module = %s ' \
 
468
                            'AND lang = %s ' \
 
469
                            'AND id NOT IN (' + \
 
470
                            ','.join(['%s' for x in sub_translation_ids]) + \
 
471
                            ')',
 
472
                        (module, lang) + tuple(sub_translation_ids))
443
473
        return len(translation_ids)
444
474
 
445
475
    def translation_export(self, cursor, user, lang, module, context=None):
446
476
        model_data_obj = self.pool.get('ir.model.data')
447
477
 
 
478
        if context is None:
 
479
            context = {}
 
480
 
448
481
        model_data_ids = model_data_obj.search(cursor, user, [
449
482
            ('module', '=', module),
450
483
            ], context=context)
458
491
        writer = csv.writer(buf, 'TRYTON')
459
492
        writer.writerow(HEADER)
460
493
 
 
494
        ctx = context.copy()
 
495
        ctx['language'] = 'en_US'
461
496
        translation_ids = self.search(cursor, user, [
462
497
            ('lang', '=', lang),
463
498
            ('module', '=', module),
466
501
                ('name', 'ASC'),
467
502
                ('src', 'ASC'),
468
503
                ('res_id', 'ASC'),
469
 
            ], context=context)
 
504
            ], context=ctx)
470
505
        for translation in self.browse(cursor, user, translation_ids,
471
506
                context=context):
472
507
            row = []
490
525
                    value = translation[field] or ''
491
526
                    value = value.encode('utf-8')
492
527
                    row.append(value)
493
 
            writer.writerow(row)
 
528
            if len(row) == len(HEADER):
 
529
                writer.writerow(row)
494
530
 
495
531
        file_data = buf.getvalue()
496
532
        buf.close()
499
535
Translation()
500
536
 
501
537
 
502
 
class ReportTranslationSetInit(WizardOSV):
 
538
class ReportTranslationSetInit(ModelView):
503
539
    "Update Report Translation"
504
540
    _name = 'ir.translation.set_report.init'
505
541
    _description = __doc__
507
543
ReportTranslationSetInit()
508
544
 
509
545
 
510
 
class ReportTranslationSetStart(WizardOSV):
 
546
class ReportTranslationSetStart(ModelView):
511
547
    "Update Report Translation"
512
548
    _name = 'ir.translation.set_report.start'
513
549
    _description = __doc__
548
584
 
549
585
        if node.nodeType in (node.CDATA_SECTION_NODE, node.TEXT_NODE):
550
586
            if node.parentNode \
551
 
                    and node.parentNode.tagName == 'text:placeholder':
 
587
                    and node.parentNode.tagName in ('text:placeholder',
 
588
                            'text:page-number', 'text:page-count'):
552
589
                return strings
553
590
 
554
591
            if node.nodeValue:
562
599
 
563
600
    def _set_report_translation(self, cursor, user, data, context):
564
601
        report_obj = self.pool.get('ir.action.report')
565
 
        report_ids = report_obj.search(cursor, user, [], context=context)
 
602
 
 
603
        ctx = context.copy()
 
604
        ctx['active_test'] = False
 
605
 
 
606
        report_ids = report_obj.search(cursor, user, [], context=ctx)
566
607
 
567
608
        if not report_ids:
568
609
            return {}
575
616
                        'AND type = %s ' \
576
617
                        'AND name = %s ' \
577
618
                        'AND module = %s',
578
 
                    ('en_US', 'odt', report.report_name, report.module))
 
619
                    ('en_US', 'odt', report.report_name, report.module or ''))
579
620
            trans_reports = {}
580
621
            for trans in cursor.dictfetchall():
581
622
                trans_reports[trans['src']] = trans
582
623
 
583
 
            try:
584
 
                content = report.report_content
585
 
            except:
586
 
                continue
587
 
            if not content:
588
 
                continue
589
 
 
590
 
            content_io = StringIO.StringIO(report.report_content)
591
 
            content_z = zipfile.ZipFile(content_io, mode='r')
592
 
 
593
 
            content_xml = content_z.read('content.xml')
594
 
            document = dom.minidom.parseString(content_xml)
595
 
            strings = self._translate_report(document.documentElement)
596
 
 
597
 
            style_xml = content_z.read('styles.xml')
598
 
            document = dom.minidom.parseString(style_xml)
599
 
            strings += self._translate_report(document.documentElement)
 
624
            strings = []
 
625
 
 
626
            odt_content = ''
 
627
            if report.report:
 
628
                odt_content = file_open(report.report.replace('/', os.sep),
 
629
                        mode='rb').read()
 
630
            for content in (report.report_content_data, odt_content):
 
631
                if not content:
 
632
                    continue
 
633
 
 
634
                content_io = StringIO.StringIO(content)
 
635
                content_z = zipfile.ZipFile(content_io, mode='r')
 
636
 
 
637
                content_xml = content_z.read('content.xml')
 
638
                document = dom.minidom.parseString(content_xml)
 
639
                strings = self._translate_report(document.documentElement)
 
640
 
 
641
                style_xml = content_z.read('styles.xml')
 
642
                document = dom.minidom.parseString(style_xml)
 
643
                strings += self._translate_report(document.documentElement)
600
644
 
601
645
            style_content = None
602
646
            try:
603
 
                style_content = report.style_content
 
647
                style_content = base64.decodestring(report.style_content)
604
648
            except:
605
649
                pass
606
650
 
650
694
                cursor.execute('DELETE FROM ir_translation ' \
651
695
                        'WHERE name = %s ' \
652
696
                            'AND type = %s ' \
 
697
                            'AND module = %s ' \
653
698
                            'AND src NOT IN ' \
654
699
                                '(' + ','.join(['%s' for x in strings]) + ')',
655
 
                        (report.report_name, 'odt') + tuple(strings))
 
700
                        (report.report_name, 'odt', report.module) + \
 
701
                                tuple(strings))
656
702
        return {}
657
703
 
658
704
ReportTranslationSet()
659
705
 
660
706
 
661
 
class TranslationCleanInit(WizardOSV):
 
707
class TranslationCleanInit(ModelView):
662
708
    'Clean translation init'
663
709
    _name = 'ir.translation.clean.init'
664
710
    _description = __doc__
666
712
TranslationCleanInit()
667
713
 
668
714
 
669
 
class TranslationCleanStart(WizardOSV):
 
715
class TranslationCleanStart(ModelView):
670
716
    'Clean translation start'
671
717
    _name = 'ir.translation.clean.start'
672
718
    _description = __doc__
706
752
        translation_obj = self.pool.get('ir.translation')
707
753
        model_data_obj = self.pool.get('ir.model.data')
708
754
        report_obj = self.pool.get('ir.action.report')
709
 
        pool_wizard = pooler.get_pool_wizard(cursor.dbname)
 
755
 
 
756
        ctx = context.copy()
 
757
        ctx['active_test'] = False
710
758
 
711
759
        offset = 0
712
760
        limit = cursor.IN_MAX
734
782
                        continue
735
783
                elif translation.type == 'model':
736
784
                    try:
737
 
                        model_name, _ = translation.name.split(',', 1)
 
785
                        model_name, field_name = translation.name.split(',', 1)
738
786
                    except ValueError:
739
787
                        to_delete.append(translation.id)
740
788
                        continue
741
789
                    if model_name not in self.pool.object_name_list():
742
790
                        to_delete.append(translation.id)
743
791
                        continue
 
792
                    if translation.res_id:
 
793
                        model_obj = self.pool.get(model_name)
 
794
                        if field_name not in model_obj._columns:
 
795
                            to_delete.append(translation.id)
 
796
                            continue
 
797
                        field = model_obj._columns[field_name]
 
798
                        if not hasattr(field, 'translate') or \
 
799
                                not field.translate:
 
800
                            to_delete.append(translation.id)
 
801
                            continue
 
802
                    elif field_name not in ('name'):
 
803
                        to_delete.append(translation.id)
 
804
                        continue
744
805
                elif translation.type == 'odt':
745
806
                    if not report_obj.search(cursor, user, [
746
807
                        ('report_name', '=', translation.name),
747
 
                        ], context=context):
 
808
                        ], context=ctx):
748
809
                        to_delete.append(translation.id)
749
810
                        continue
750
811
                elif translation.type == 'selection':
761
822
                        to_delete.append(translation.id)
762
823
                        continue
763
824
                    field = model_obj._columns[field_name]
764
 
                    if not hasattr(field, 'selection') or not field.selection:
 
825
                    if not hasattr(field, 'selection') or not field.selection \
 
826
                            or not ((hasattr(field, 'translate_selection') and \
 
827
                            field.translate_selection) or True):
765
828
                        to_delete.append(translation.id)
766
829
                        continue
767
830
                    if isinstance(field.selection, (tuple, list)) \
781
844
                    except ValueError:
782
845
                        to_delete.append(translation.id)
783
846
                        continue
784
 
                    wizard = pool_wizard.get(wizard_name)
 
847
                    if wizard_name not in \
 
848
                            self.pool.object_name_list(type='wizard'):
 
849
                        to_delete.append(translation.id)
 
850
                        continue
 
851
                    wizard = self.pool.get(wizard_name, type='wizard')
785
852
                    if not wizard:
786
853
                        to_delete.append(translation.id)
787
854
                        continue
822
889
                            'delete_workflow_record',
823
890
                            'domain_validation_record',
824
891
                            'required_validation_record',
 
892
                            'access_error',
 
893
                            'read_error',
 
894
                            'write_error',
 
895
                            'required_field',
 
896
                            'foreign_model_missing',
 
897
                            'foreign_model_exist',
825
898
                            ):
826
899
                        continue
827
900
                    if model_name in self.pool.object_name_list():
833
906
                        if translation.src not in errors:
834
907
                            to_delete.append(translation.id)
835
908
                            continue
836
 
                    elif model_name in pool_wizard.object_name_list():
837
 
                        wizard_obj = pool_wizard.get(model_name)
 
909
                    elif model_name in self.pool.object_name_list(type='wizard'):
 
910
                        wizard_obj = self.pool.get(model_name, type='wizard')
838
911
                        errors = wizard_obj._error_messages.values()
839
912
                        if translation.src not in errors:
840
913
                            to_delete.append(translation.id)
858
931
TranslationClean()
859
932
 
860
933
 
861
 
class TranslationUpdateInit(WizardOSV):
 
934
class TranslationUpdateInit(ModelView):
862
935
    "Update translation - language"
863
936
    _name = 'ir.translation.update.init'
864
937
    _description = __doc__
894
967
                    ' \'selection\', \'error\')',
895
968
                (data['form']['lang'],))
896
969
        for row in cursor.dictfetchall():
897
 
            translation_obj.create(cursor, user, {
 
970
            translation_obj.create(cursor, 0, {
898
971
                'name': row['name'],
899
972
                'res_id': row['res_id'],
900
973
                'lang': data['form']['lang'],
912
985
                    'AND type in (\'field\', \'model\', \'help\')',
913
986
                (data['form']['lang'],))
914
987
        for row in cursor.dictfetchall():
915
 
            translation_obj.create(cursor, user, {
 
988
            translation_obj.create(cursor, 0, {
916
989
                'name': row['name'],
917
990
                'res_id': row['res_id'],
918
991
                'lang': data['form']['lang'],
940
1013
                        'AND lang = %s',
941
1014
                    (row['src'], row['name'], row['res_id'], row['type'],
942
1015
                        data['form']['lang']))
 
1016
 
 
1017
        cursor.execute('SELECT src, MAX(value) AS value FROM ir_translation ' \
 
1018
                'WHERE lang = %s ' \
 
1019
                    'AND src IN (' \
 
1020
                        'SELECT src FROM ir_translation ' \
 
1021
                        'WHERE (value = \'\' OR value IS NULL) ' \
 
1022
                            'AND lang = %s) ' \
 
1023
                    'AND value != \'\' AND value IS NOT NULL ' \
 
1024
                'GROUP BY src', (data['form']['lang'], data['form']['lang']))
 
1025
 
 
1026
        for row in cursor.dictfetchall():
 
1027
            cursor.execute('UPDATE ir_translation ' \
 
1028
                    'SET fuzzy = True, ' \
 
1029
                        'value = %s ' \
 
1030
                    'WHERE src = %s ' \
 
1031
                        'AND (value = \'\' OR value IS NULL) ' \
 
1032
                        'AND lang = %s', (row['value'], row['src'],
 
1033
                            data['form']['lang']))
 
1034
 
943
1035
        cursor.execute('UPDATE ir_translation ' \
944
1036
                'SET fuzzy = False ' \
945
1037
                'WHERE (value = \'\' OR value IS NULL) ' \
987
1079
TranslationUpdate()
988
1080
 
989
1081
 
990
 
class TranslationExportInit(WizardOSV):
 
1082
class TranslationExportInit(ModelView):
991
1083
    "Export translation - language and module"
992
1084
    _name = 'ir.translation.export.init'
993
1085
    _description = __doc__
998
1090
 
999
1091
    def get_language(self, cursor, user, context):
1000
1092
        lang_obj = self.pool.get('ir.lang')
1001
 
        lang_ids = lang_obj.search(cursor, user, [], context=context)
 
1093
        lang_ids = lang_obj.search(cursor, user, [
 
1094
            ('translatable', '=', True),
 
1095
            ], context=context)
1002
1096
        langs = lang_obj.browse(cursor, user, lang_ids, context=context)
1003
1097
        res = [(lang.code, lang.name) for lang in langs]
1004
1098
        return res
1005
1099
 
1006
1100
    def get_module(self, cursor, user, context):
1007
1101
        module_obj = self.pool.get('ir.module.module')
1008
 
        module_ids = module_obj.search(cursor, user, [], context=context)
 
1102
        module_ids = module_obj.search(cursor, user, [
 
1103
            ('state', 'in', ['installed', 'to upgrade', 'to remove']),
 
1104
            ], context=context)
1009
1105
        modules = module_obj.browse(cursor, user, module_ids, context=context)
1010
1106
        res =  [(module.name, module.name) for module in modules]
1011
1107
        return res
1013
1109
TranslationExportInit()
1014
1110
 
1015
1111
 
1016
 
class TranslationExportStart(WizardOSV):
 
1112
class TranslationExportStart(ModelView):
1017
1113
    "Export translation - file"
1018
1114
    _description = __doc__
1019
1115
    _name = 'ir.translation.export.start'