<commit_before>'''
Created on Jun 23, 2011

@package superdesk
@copyright 2011 Sourcefabric o.p.s.
@license http://www.gnu.org/licenses/gpl-3.0.txt
@author: <NAME>

SQL alchemy implementation for language API.
'''

from ..api.country import Country, ICountryService
from ally.api.model import Part
from ally.container import wire
from ally.container.ioc import injected
from ally.exception import InputError, Ref
from ally.internationalization import _
from ally.support.api.util_service import trimIter, processQuery
from babel.core import Locale
from babel.localedata import locale_identifiers

# --------------------------------------------------------------------

class Countries(dict):
    '''
    A simple dictionary class used for marking the countries codes (as keys) and country default names (as values).
    '''

@injected
class CountryServiceBabelAlchemy(ICountryService):
    '''
    Implementation for @see: ICountryService using Babel library for translating country names and for the country codes
    it uses an external source.
    '''

    countries = Countries; wire.entity('countries')

    def __init__(self):
        '''
        Construct the country service.
        '''
        assert isinstance(self.countries, Countries), 'Invalid countries %s' % self.countries
        self._locales = {code:Locale.parse(code) for code in locale_identifiers()}

    def getByCode(self, code, locales):
        '''
        @see: ICountryService.getByCode
        '''
        if code not in self.countries: raise InputError(Ref(_('Unknown country code'), ref=Country.Code))
        return Country(code, self._translate(code, self._localesOf(locales)))

    def getAllAvailable(self, locales, offset=None, limit=None, q=None):
        '''
        @see: ILanguageService.getAllAvailable
        '''
        locales = self._localesOf(locales)
        if q:
            countries = (Country(code, self._translate(code, locales)) for code in self.countries)
            countries = processQuery(countries, q, Country)
            length = len(countries)
            countries = trimIter(countries, length, offset, limit)
        else:
            length = len(self._locales)
            countries = trimIter(self.countries, length, offset, limit)
            countries = (Country(code, self._translate(code, locales)) for code in countries)
        return Part(countries, length)

    # ----------------------------------------------------------------

    def _localeOf(self, code):
        '''
        Helper that parses the code to a babel locale.
        
        @param code: string
            The language code to provide the locale for.
        @return: Locale|None
            The locale for the code or None if the code is not valid.
        '''
        assert isinstance(code, str), 'Invalid code %s' % code
        return self._locales.get(code.replace('-', '_'))

    def _localesOf(self, codes):
        '''
        Helper method that based on a language code list will provide a babel locales.<commit_msg>NR-114 : Live Blog back end<commit_after>'''
Created on Jun 23, 2011

@package superdesk
@copyright 2011 Sourcefabric o.p.s.
@license http://www.gnu.org/licenses/gpl-3.0.txt
@author: <NAME>

SQL alchemy implementation for language API.
'''

from ..api.country import Country, ICountryService
from ally.api.model import Part
from ally.container import wire
from ally.container.ioc import injected
from ally.exception import InputError, Ref
from ally.internationalization import _
from ally.support.api.util_service import trimIter, processQuery
from babel.core import Locale
from babel.localedata import locale_identifiers

# --------------------------------------------------------------------

class Countries(dict):
    '''
    A simple dictionary class used for marking the countries codes (as keys) and country default names (as values).
    '''

@injected
class CountryServiceBabelAlchemy(ICountryService):
    '''
    Implementation for @see: ICountryService using Babel library for translating country names and for the country codes
    it uses an external source.
    '''

    countries = Countries; wire.entity('countries')

    def __init__(self):
        '''
        Construct the country service.
        '''
        assert isinstance(self.countries, Countries), 'Invalid countries %s' % self.countries
        self._locales = {code:Locale.parse(code) for code in locale_identifiers()}

    def getByCode(self, code, locales):
        '''
        @see: ICountryService.getByCode
        '''
        if code not in self.countries: raise InputError(Ref(_('Unknown country code'), ref=Country.Code))
        return Country(code, self._translate(code, self._localesOf(locales)))

    def getAllAvailable(self, locales, offset=None, limit=None, q=None):
        '''
        @see: ILanguageService.getAllAvailable
        '''
        locales = self._localesOf(locales)
        if q:
            countries = (Country(code, self._translate(code, locales)) for code in self.countries)
            countries = processQuery(countries, q, Country)
            length = len(countries)
            countries = trimIter(countries, length, offset, limit)
        else:
            length = len(self.countries)
            countries = trimIter(self.countries, length, offset, limit)
            countries = (Country(code, self._translate(code, locales)) for code in countries)
        return Part(countries, length)

    # ----------------------------------------------------------------

    def _localeOf(self, code):
        '''
        Helper that parses the code to a babel locale.
        
        @param code: string
            The language code to provide the locale for.
        @return: Locale|None
            The locale for the code or None if the code is not valid.
        '''
        assert isinstance(code, str), 'Invalid code %s' % code
        return self._locales.get(code.replace('-', '_'))

    def _localesOf(self, codes):
        '''
        Helper method that based on a language code list will provide a babel locales.
{'fraction_non_alphanumeric': 0.13388293487221764, 'fraction_numerical': 0.004451772464962902, 'mean_word_length': 2.4603536794067313, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7661277', 'n_tokens_mistral': 1621, 'n_tokens_neox': 1572, 'n_words': 523}