Example #1
0
    def after_search(self, search_results, search_params):
        '''Try to replace displayed fields with their translations (if any).
        '''

        from ckanext.publicamundi.lib.metadata import fields, bound_field
        from ckanext.publicamundi.lib.metadata import class_for_metadata, translator_for

        uf = fields.TextField()
        lang = self.target_language()

        for pkg in search_results['results']:
            source_lang = pkg.get('language')
            if not source_lang or (source_lang == lang):
                continue  # no need to translate
            dtype = pkg['dataset_type']
            md = class_for_metadata(dtype)(identifier=pkg['id'])
            translator = translator_for(md, source_lang)
            # Lookup translations in the context of this package
            translated = False
            for k in ('title', 'notes'):
                tr = translator.get_field_translator(
                    bound_field(uf, (k, ), pkg[k]))
                yf = tr.get(lang) if tr else None
                if yf:
                    pkg[k] = yf.context.value
                    translated = True
            # If at least one translation was found, mark as translated
            if translated:
                pkg['translated_to_language'] = lang

        return search_results
    def after_search(self, search_results, search_params):
        '''Try to replace displayed fields with their translations (if any).
        '''
        
        from ckanext.publicamundi.lib.metadata import fields, bound_field
        from ckanext.publicamundi.lib.metadata import class_for_metadata, translator_for
        
        uf = fields.TextField()
        lang = self.target_language()

        for pkg in search_results['results']:
            source_lang = pkg.get('language')
            if not source_lang or (source_lang == lang):
                continue # no need to translate
            dtype = pkg['dataset_type']
            md = class_for_metadata(dtype)(identifier=pkg['id']) 
            translator = translator_for(md, source_lang)
            # Lookup translations in the context of this package
            translated = False
            for k in ('title', 'notes'):
                tr = translator.get_field_translator(bound_field(uf, (k,), pkg[k]))
                yf = tr.get(lang) if tr else None
                if yf:
                    pkg[k] = yf.context.value
                    translated = True
            # If at least one translation was found, mark as translated
            if translated:
                pkg['translated_to_language'] = lang
        
        return search_results
 def __call__(self, md):
     assert self.translator is None, 'Expected to be called once!'
     self.translator = ext_metadata.translator_for(md, self.source_language)
     try:
         result = self.translator.get(self.language)
     except Exception as ex:
         self.translator = False # is unusable
         raise
     return result
Example #4
0
 def __call__(self, md):
     assert self.translator is None, 'Expected to be called once!'
     self.translator = ext_metadata.translator_for(
         md, self.source_language)
     try:
         result = self.translator.get(self.language)
     except Exception as ex:
         self.translator = False  # is unusable
         raise
     return result
    def _test_1(self, dtype, i, name, source_lang, lang):

        pkg = self.packages[dtype][i][-1]
        md = factory_for_metadata(dtype)()
        md.from_dict(pkg[dtype], is_flat=0, opts={'unserialize-values': 1})
        assert md.identifier and check_uuid(md.identifier)

        translator = translator_for(md, source_lang)
        assert translator
        assert IMetadataTranslator in zope.interface.providedBy(translator)

        # Read a translated view

        md_1 = translator.get(lang)
        assert md_1 and isinstance(md_1, type(md))
        assert ITranslatedMetadata in zope.interface.providedBy(md_1)
        assert md_1 == md, 'Nothing is translated yet, should be identical'

        # Tranlate a few fields

        translations = {}
        for key in self.translatable_fields[dtype]:
            yf = md.get_field(key)
            translations[key] = ' ** TRANSLATE ** ' + yf.context.value
            yf.context.key = (dtype, ) + key
            tr = translator.get_field_translator(yf)
            yf1 = tr.translate(lang, translations[key])
            assert yf1 and yf1.context.value
            assert yf1.context.value == translations[key]

        # Re-read a translated view

        md_2 = translator.get(lang)
        assert md_2 and isinstance(md_2, type(md))
        assert ITranslatedMetadata in zope.interface.providedBy(md_2)
        assert md_2 != md, 'Some fields should be translated'

        changes = list(dictdiffer.diff(md.to_dict(), md_2.to_dict()))
        translated_keys = set(translations.keys())
        assert len(changes) > 0
        for changetype, skey, (changed_from, changed_to) in changes:
            assert changetype == 'change'
            key = tuple(skey.split('.'))
            assert key in translations
            assert translations[key] == changed_to
            yf0, yf2 = md.get_field(key), md_2.get_field(key)
            assert yf0.context.value == changed_from
            assert yf2.context.value == changed_to
            assert key in translated_keys
            translated_keys.remove(key)
        assert not translated_keys, 'All keys should be consumed'

        pass
    def _test_1(self, dtype, i, name, source_lang, lang):
       
        pkg = self.packages[dtype][i][-1]
        md = factory_for_metadata(dtype)()
        md.from_dict(pkg[dtype], is_flat=0, opts={'unserialize-values': 1})
        assert md.identifier and check_uuid(md.identifier)
        
        translator = translator_for(md, source_lang)
        assert translator
        assert IMetadataTranslator in zope.interface.providedBy(translator)
        
        # Read a translated view
        
        md_1 = translator.get(lang)
        assert md_1 and isinstance(md_1, type(md))
        assert ITranslatedMetadata in zope.interface.providedBy(md_1)
        assert md_1 == md, 'Nothing is translated yet, should be identical'  

        # Tranlate a few fields
        
        translations = {} 
        for key in self.translatable_fields[dtype]:
            yf = md.get_field(key)
            translations[key] = ' ** TRANSLATE ** ' + yf.context.value
            yf.context.key = (dtype,) + key
            tr = translator.get_field_translator(yf)
            yf1 = tr.translate(lang, translations[key])
            assert yf1 and yf1.context.value
            assert yf1.context.value == translations[key]

        # Re-read a translated view
        
        md_2 = translator.get(lang)
        assert md_2 and isinstance(md_2, type(md))
        assert ITranslatedMetadata in zope.interface.providedBy(md_2)
        assert md_2 != md, 'Some fields should be translated'  
        
        changes = list(dictdiffer.diff(md.to_dict(), md_2.to_dict())) 
        translated_keys = set(translations.keys())
        assert len(changes) > 0
        for changetype, skey, (changed_from, changed_to) in changes:
            assert changetype == 'change'
            key = tuple(skey.split('.'))
            assert key in translations
            assert translations[key] == changed_to
            yf0, yf2 = md.get_field(key), md_2.get_field(key)
            assert yf0.context.value == changed_from 
            assert yf2.context.value == changed_to 
            assert key in translated_keys
            translated_keys.remove(key)
        assert not translated_keys, 'All keys should be consumed'
        
        pass
def dataset_translation_update(context, data_dict):
    '''Translate dataset for the active language.
    
    The accepted format data_dict is as the one passed to core `package_update`. 
    
    An additional parameter is `translate_to_language` which determines the target
    language. If not supplied, the active language (from Pylons request) will be used.
    
    All non-translatable fields will be ignored. 
    
    All fields that are not present (or are empty) in source package, will also be
    ignored.

    :param id: the name or id of the package.
    :type id: string
   
    :param translate_to_language: the target language
    :type translate_to_language: string
    
    rtype: dict
    '''
     
    # Determine target language
    
    lang = _target_language(data_dict)

    # Fetch package in source language

    context.update({
        'translate': False,
        'return_json': True
    })
    pkg = _get_action('package_show')(context, {'id': data_dict['id']})
    dtype = pkg['dataset_type']

    source_lang = pkg['language']
    if lang == source_lang:
        msg = 'The target language same as source language (%s)' % (lang)
        raise Invalid({'translate_to_language': msg})
 
    md = class_for_metadata(dtype)()
    md.from_json(pkg[dtype])
   
    # Check authorization

    _check_access(
        'package_translation_update', context, {'org': pkg['owner_org']})
    
    # Translate structured metadata
    
    translator = translator_for(md, source_lang)
    md = translator.translate(lang, data_dict[dtype])
    
    pkg[dtype] = md.to_json(return_string=False)

    # Translate core CKAN metadata

    field_translator = translator.get_field_translator
    uf = fields.TextField()
    for k in ('title', 'notes'):
        v = data_dict.get(k)
        if not (v and pkg.get(k)):
            continue # nothing to translate
        tr = field_translator(bound_field(uf, (k,), pkg[k]))
        if not tr:
            continue 
        yf = tr.translate(lang, v)
        pkg[k] = v

    # Return translated view of this package

    pkg['translated_to_language'] = lang
    return pkg
def dataset_translation_update_field(context, data_dict):
    '''Translate a dataset field for the active language.

    This is similar to `dataset_translation_update` but only updates a field per
    call. It's purpose is to be used when fields are updated individually.

    :param id: the name or id of the package.
    :type id: string

    :param translate_to_language: the target language
    :type translate_to_language: string
     
    :param key: the field's key path (as dotted path or as a tuple)
    :type : string or tuple
    
    :param value: the translated text value
    :type value: string
    '''
    
    # Determine target language
    
    lang = _target_language(data_dict)

    # Fetch package in source language

    context.update({'translate': False})
    pkg = _get_action('package_show')(context, {'id': data_dict['id']})
    dtype = pkg['dataset_type']

    source_lang = pkg['language']
    if lang == source_lang:
        msg = 'The target language same as source language (%s)' % (lang)
        raise Invalid({'translate_to_language': msg})
    
    key = data_dict.get('key')
    if not key:
        raise Invalid({'key': 'Missing'})
    if isinstance(key, basestring):
        key = tuple(key.split('.'))
    else:
        key = tuple(key)

    value = data_dict.get('value')
    if not value:
        raise Invalid({'value': 'Missing'})
    value = unicode(value)

    # Check authorization

    _check_access(
        'package_translation_update', context, {'org': pkg['owner_org']})
    
    # Update translation for field

    md = pkg[dtype]
    translator = translator_for(md, source_lang)
    
    msg = None
    yf = None
    if len(key) < 2: 
        # Translate a top-level field
        if key[0] in ['title', 'notes']:
            # A core CKAN translatable field
            uf = fields.TextField() 
            yf = bound_field(uf, key, pkg[key[0]])
    else:
        # Translate a field from structured metadata
        if key[0] == dtype:
            try:
                yf = md.get_field(key[1:])
            except:
                yf = None
                msg = 'No such field'
            if yf and not yf.queryTaggedValue('translatable'):
                yf = None 
                msg = 'Not translatable'
            if yf:
                yf.context.key = key
    
    tr = None
    if yf and yf.context.value:
        tr = translator.get_field_translator(yf)
        if tr:
            tr.translate(lang, value)

    res = {'updated': bool(tr)}
    if msg:
        res['message'] = msg;

    return res
Example #9
0
def dataset_translation_update(context, data_dict):
    '''Translate dataset for the active language.
    
    The accepted format data_dict is as the one passed to core `package_update`. 
    
    An additional parameter is `translate_to_language` which determines the target
    language. If not supplied, the active language (from Pylons request) will be used.
    
    All non-translatable fields will be ignored. 
    
    All fields that are not present (or are empty) in source package, will also be
    ignored.

    :param id: the name or id of the package.
    :type id: string
   
    :param translate_to_language: the target language
    :type translate_to_language: string
    
    rtype: dict
    '''

    # Determine target language

    lang = _target_language(data_dict)

    # Fetch package in source language

    context.update({'translate': False, 'return_json': True})
    pkg = _get_action('package_show')(context, {'id': data_dict['id']})
    dtype = pkg['dataset_type']

    source_lang = pkg['language']
    if lang == source_lang:
        msg = 'The target language same as source language (%s)' % (lang)
        raise Invalid({'translate_to_language': msg})

    md = class_for_metadata(dtype)()
    md.from_json(pkg[dtype])

    # Check authorization

    _check_access('package_translation_update', context,
                  {'org': pkg['owner_org']})

    # Translate structured metadata

    translator = translator_for(md, source_lang)
    md = translator.translate(lang, data_dict[dtype])

    pkg[dtype] = md.to_json(return_string=False)

    # Translate core CKAN metadata

    field_translator = translator.get_field_translator
    uf = fields.TextField()
    for k in ('title', 'notes'):
        v = data_dict.get(k)
        if not (v and pkg.get(k)):
            continue  # nothing to translate
        tr = field_translator(bound_field(uf, (k, ), pkg[k]))
        if not tr:
            continue
        yf = tr.translate(lang, v)
        pkg[k] = v

    # Return translated view of this package

    pkg['translated_to_language'] = lang
    return pkg
Example #10
0
def dataset_translation_update_field(context, data_dict):
    '''Translate a dataset field for the active language.

    This is similar to `dataset_translation_update` but only updates a field per
    call. It's purpose is to be used when fields are updated individually.

    :param id: the name or id of the package.
    :type id: string

    :param translate_to_language: the target language
    :type translate_to_language: string
     
    :param key: the field's key path (as dotted path or as a tuple)
    :type : string or tuple
    
    :param value: the translated text value
    :type value: string
    '''

    # Determine target language

    lang = _target_language(data_dict)

    # Fetch package in source language

    context.update({'translate': False})
    pkg = _get_action('package_show')(context, {'id': data_dict['id']})
    dtype = pkg['dataset_type']

    source_lang = pkg['language']
    if lang == source_lang:
        msg = 'The target language same as source language (%s)' % (lang)
        raise Invalid({'translate_to_language': msg})

    key = data_dict.get('key')
    if not key:
        raise Invalid({'key': 'Missing'})
    if isinstance(key, basestring):
        key = tuple(key.split('.'))
    else:
        key = tuple(key)

    value = data_dict.get('value')
    if not value:
        raise Invalid({'value': 'Missing'})
    value = unicode(value)

    # Check authorization

    _check_access('package_translation_update', context,
                  {'org': pkg['owner_org']})

    # Update translation for field

    md = pkg[dtype]
    translator = translator_for(md, source_lang)

    msg = None
    yf = None
    if len(key) < 2:
        # Translate a top-level field
        if key[0] in ['title', 'notes']:
            # A core CKAN translatable field
            uf = fields.TextField()
            yf = bound_field(uf, key, pkg[key[0]])
    else:
        # Translate a field from structured metadata
        if key[0] == dtype:
            try:
                yf = md.get_field(key[1:])
            except:
                yf = None
                msg = 'No such field'
            if yf and not yf.queryTaggedValue('translatable'):
                yf = None
                msg = 'Not translatable'
            if yf:
                yf.context.key = key

    tr = None
    if yf and yf.context.value:
        tr = translator.get_field_translator(yf)
        if tr:
            tr.translate(lang, value)

    res = {'updated': bool(tr)}
    if msg:
        res['message'] = msg

    return res