コード例 #1
0
    def get_language_from_request(self, request):
        supported = dict(settings.LANGUAGES)
        accept = request.META.get('HTTP_ACCEPT_LANGUAGE', '')
        for accept_lang, unused in parse_accept_lang_header(accept):
            if accept_lang == '*':
                break

            # We have a very restricted form for our language files
            # (no encoding specifier, since they all must be UTF-8 and
            # only one possible language each time. So we avoid the
            # overhead of gettext.find() and work out the MO file
            # manually.

            # 'normalized' is the root name of the locale in POSIX
            # format (which is the format used for the directories
            # holding the MO files).
            normalized = locale.locale_alias.get(to_locale(accept_lang, True))
            if not normalized:
                continue
            # Remove the default encoding from locale_alias.
            normalized = normalized.split('.')[0]

            for lang_code in (accept_lang, accept_lang.split('-')[0]):
                lang_code = lang_code.lower()
                if lang_code in supported and check_for_language(lang_code):
                    return lang_code
        return None
コード例 #2
0
ファイル: translation.py プロジェクト: idlweb/djangobile
def add_device_locale(device=None):
    global device_translations

    from django.conf import settings

    if not device or not settings.USE_I18N:
        return

    current_translation = trans._active[currentThread()]
    lang = current_translation.language()
    key = "%s#%s" % (lang, device.id)
    loc = trans.to_locale(lang)
    klass = trans.DjangoTranslation
    if sys.version_info < (2, 4):
        klass = trans.DjangoTranslation23

    device_trans = device_translations.get(key, None)
    if device_trans is None:
        translations_paths = get_translations_paths(device)
        for translations_path in translations_paths:
            try:
                t = gettext_module.translation('django', translations_path,
                                               [loc], klass)
                t.set_language(lang)
                if device_trans is None:
                    device_trans = t
                else:
                    device_trans.merge(t)
            except IOError, e:
                pass
        device_translations[key] = device_trans
        fallback = getattr(device_trans, '_fallback', None)
        if not fallback and hasattr(device_trans, 'add_fallback'):
            device_trans.add_fallback(current_translation)
コード例 #3
0
ファイル: forms.py プロジェクト: waseem18/zamboni
class AppFormDetails(AddonFormBase):
    LOCALES = [(translation.to_locale(k).replace('_', '-'), v)
               for k, v in do_dictsort(settings.LANGUAGES)]

    default_locale = forms.TypedChoiceField(required=False, choices=LOCALES)
    homepage = TransField.adapt(forms.URLField)(required=False)
    privacy_policy = TransField(
        widget=TransTextarea(), required=True,
        label=_lazy(u"Please specify your app's Privacy Policy"))

    class Meta:
        model = Webapp
        fields = ('default_locale', 'homepage', 'privacy_policy')

    def clean(self):
        # Make sure we have the required translations in the new locale.
        required = ['name', 'description']
        data = self.cleaned_data
        if not self.errors and 'default_locale' in self.changed_data:
            fields = dict((k, getattr(self.instance, k + '_id'))
                          for k in required)
            locale = data['default_locale']
            ids = filter(None, fields.values())
            qs = (Translation.objects.filter(locale=locale, id__in=ids,
                                             localized_string__isnull=False)
                  .values_list('id', flat=True))
            missing = [k for k, v in fields.items() if v not in qs]
            if missing:
                raise forms.ValidationError(
                    _('Before changing your default locale you must have a '
                      'name and description in that locale. '
                      'You are missing %s.') % ', '.join(map(repr, missing)))
        return data
コード例 #4
0
    def is_edit_mode(self, request):
        from django.utils.translation.trans_real import get_language, to_locale
        locale = to_locale(get_language())
        if 'en' in locale or request.path.find('/admin') > -1:
            return False

        #return request.GET.get('translate', 'False').lower() == 'true' and request.user.is_staff
        return request.user.is_staff and getattr(settings, 'ROSETTA_INPAGE', False)
コード例 #5
0
        def _fetch(lang, fallback=None):

            global _translations

            res = _translations.get(lang, None)
            if res is not None:
                return res

            loc = to_locale(lang)

            def _translation(path):
                try:
                    if needs_compilation('django', path, lang):
                        compile_messages('django', path, lang)
                    t = gettext_module.translation('django', path, [loc], DjangoTranslation)
                    t.set_language(lang)
                    return t
                except IOError:
                    return None

            res = _translation(globalpath)

            # We want to ensure that, for example, "en-gb" and "en-us" don't share
            # the same translation object (thus, merging en-us with a local update
            # doesn't affect en-gb), even though they will both use the core "en"
            # translation. So we have to subvert Python's internal gettext caching.
            base_lang = lambda x: x.split('-', 1)[0]
            if base_lang(lang) in [base_lang(trans) for trans in list(_translations)]:
                res._info = res._info.copy()
                res._catalog = res._catalog.copy()

            def _merge(path):
                t = _translation(path)
                if t is not None:
                    if res is None:
                        return t
                    else:
                        res.merge(t)
                return res

            for appname in reversed(settings.INSTALLED_APPS):
                app = import_module(appname)
                apppath = os.path.join(os.path.dirname(upath(app.__file__)), 'locale')

                if os.path.isdir(apppath):
                    res = _merge(apppath)

            for localepath in reversed(settings.LOCALE_PATHS):
                if os.path.isdir(localepath):
                    res = _merge(localepath)

            if res is None:
                if fallback is not None:
                    res = fallback
                else:
                    return gettext_module.NullTranslations()
            _translations[lang] = res
            return res
コード例 #6
0
    def post(self, request):
        from django.utils.translation.trans_real import to_locale, get_language
        from rosetta_inpage.utils import save_message

        source = request.POST.get('source', '')
        target_lang = request.POST.get('lang', '')
        target_msg = request.POST.get('msg', '')

        if target_lang:
            locale = to_locale(target_lang)
        else:
            locale = to_locale(get_language())

        files = save_message(source, target_msg, locale)
        return {
            'files': files,
            'msg': target_msg,
        }
コード例 #7
0
ファイル: views.py プロジェクト: ozten/zamboni
def extension_detail(request, addon):
    """Extensions details page."""

    # if current version is incompatible with this app, redirect
    comp_apps = addon.compatible_apps
    if comp_apps and request.APP not in comp_apps:
        prefixer = urlresolvers.get_url_prefix()
        prefixer.app = comp_apps.keys()[0].short
        return http.HttpResponsePermanentRedirect(reverse(
            'addons.detail', args=[addon.id]))

    # source tracking
    src = request.GET.get('src', 'addondetail')

    # get satisfaction only supports en-US
    lang = translation.to_locale(translation.get_language())
    addon.has_satisfaction = (lang == 'en_US' and
                              addon.get_satisfaction_company)

    # other add-ons from the same author(s)
    author_addons = order_by_translation(addon.authors_other_addons, 'name')

    # tags
    dev_tags, user_tags = addon.tags_partitioned_by_developer

    current_user_tags = []

    if request.user.is_authenticated():
        current_user_tags = user_tags.filter(
                addon_tags__user=request.amo_user)

    # addon recommendations
    recommended = Addon.objects.valid().only_translations().filter(
        recommended_for__addon=addon)[:5]

    # popular collections this addon is part of
    collections = Collection.objects.listed().filter(
        addons=addon, application__id=request.APP.id)

    data = {
        'addon': addon,
        'author_addons': author_addons,

        'src': src,

        'dev_tags': dev_tags,
        'user_tags': user_tags,
        'current_user_tags': current_user_tags,

        'recommendations': recommended,
        'review_form': ReviewForm(),
        'reviews': Review.objects.latest().filter(addon=addon),
        'get_replies': Review.get_replies,

        'collections': collections.order_by('-subscribers')[:3],
    }
    return jingo.render(request, 'addons/details.html', data)
コード例 #8
0
    def post(self, request):
        from django.utils.translation.trans_real import to_locale, get_language
        from rosetta_inpage.utils import save_message

        source = request.POST.get('source', '')
        target_lang = request.POST.get('lang', '')
        target_msg = request.POST.get('msg', '')

        if target_lang:
            locale = to_locale(target_lang)
        else:
            locale = to_locale(get_language())

        files = save_message(source, target_msg, locale)
        return {
            'files': files,
            'msg': target_msg,
        }
コード例 #9
0
ファイル: views.py プロジェクト: ryandoherty/zamboni
def extension_detail(request, addon):
    """Extensions details page."""
    # If current version is incompatible with this app, redirect.
    comp_apps = addon.compatible_apps
    if comp_apps and request.APP not in comp_apps:
        prefixer = urlresolvers.get_url_prefix()
        prefixer.app = comp_apps.keys()[0].short
        return redirect('addons.detail', addon.slug, permanent=True)

    # get satisfaction only supports en-US.
    lang = translation.to_locale(translation.get_language())
    addon.has_satisfaction = (lang == 'en_US' and
                              addon.get_satisfaction_company)

    # Addon recommendations.
    recommended = Addon.objects.listed(request.APP).filter(
        recommended_for__addon=addon)[:6]

    # Popular collections this addon is part of.
    collections = Collection.objects.listed().filter(
        addons=addon, application__id=request.APP.id)

    ctx = {
        'addon': addon,
        'src': request.GET.get('src', 'dp-btn-primary'),
        'version_src': request.GET.get('src', 'dp-btn-version'),
        'tags': addon.tags.not_blacklisted(),
        'grouped_ratings': GroupedRating.get(addon.id),
        'recommendations': recommended,
        'review_form': ReviewForm(),
        'reviews': Review.objects.latest().filter(addon=addon),
        'get_replies': Review.get_replies,
        'collections': collections.order_by('-subscribers')[:3],
        'abuse_form': AbuseForm(request=request),
    }

    # details.html just returns the top half of the page for speed. The bottom
    # does a lot more queries we don't want on the initial page load.
    if request.is_ajax():
        # Other add-ons/apps from the same author(s).
        if addon.is_webapp():
            others = Webapp.objects.listed().filter(type=amo.ADDON_WEBAPP)
        else:
            others = (Addon.objects.listed(request.APP)
                      .exclude(type=amo.ADDON_WEBAPP))
        others = (others.exclude(id=addon.id).distinct()
                        .filter(addonuser__listed=True,
                                authors__in=addon.listed_authors))
        ctx['author_addons'] = others[:6]
        return jingo.render(request, 'addons/impala/details-more.html', ctx)
    else:
        if addon.is_webapp():
            ctx['search_placeholder'] = 'apps'
        return jingo.render(request, 'addons/impala/details.html', ctx)
コード例 #10
0
ファイル: views.py プロジェクト: pennyfx/zamboni
def extension_detail(request, addon):
    """Extensions details page."""
    # If current version is incompatible with this app, redirect.
    comp_apps = addon.compatible_apps
    if comp_apps and request.APP not in comp_apps:
        prefixer = urlresolvers.get_url_prefix()
        prefixer.app = comp_apps.keys()[0].short
        return redirect('addons.detail', addon.slug, permanent=True)

    # get satisfaction only supports en-US.
    lang = translation.to_locale(translation.get_language())
    addon.has_satisfaction = (lang == 'en_US' and
                              addon.get_satisfaction_company)

    # Addon recommendations.
    recommended = Addon.objects.listed(request.APP).filter(
        recommended_for__addon=addon)[:6]

    # Popular collections this addon is part of.
    collections = Collection.objects.listed().filter(
        addons=addon, application__id=request.APP.id)

    ctx = {
        'addon': addon,
        'src': request.GET.get('src', 'dp-btn-primary'),
        'version_src': request.GET.get('src', 'dp-btn-version'),
        'tags': addon.tags.not_blacklisted(),
        'grouped_ratings': GroupedRating.get(addon.id),
        'recommendations': recommended,
        'review_form': ReviewForm(),
        'reviews': Review.objects.latest().filter(addon=addon),
        'get_replies': Review.get_replies,
        'collections': collections.order_by('-subscribers')[:3],
        'abuse_form': AbuseForm(request=request),
    }

    # details.html just returns the top half of the page for speed. The bottom
    # does a lot more queries we don't want on the initial page load.
    if request.is_ajax():
        # Other add-ons/apps from the same author(s).
        if addon.is_webapp():
            others = Webapp.objects.listed().filter(type=amo.ADDON_WEBAPP)
        else:
            others = (Addon.objects.listed(request.APP)
                      .exclude(type=amo.ADDON_WEBAPP))
        others = (others.exclude(id=addon.id).distinct()
                        .filter(addonuser__listed=True,
                                authors__in=addon.listed_authors))
        ctx['author_addons'] = others[:6]
        return jingo.render(request, 'addons/impala/details-more.html', ctx)
    else:
        if addon.is_webapp():
            ctx['search_placeholder'] = 'apps'
        return jingo.render(request, 'addons/impala/details.html', ctx)
コード例 #11
0
ファイル: views.py プロジェクト: ricardodani/zamboni
def impala_extension_detail(request, addon):
    """Extensions details page."""

    # if current version is incompatible with this app, redirect
    comp_apps = addon.compatible_apps
    if comp_apps and request.APP not in comp_apps:
        prefixer = urlresolvers.get_url_prefix()
        prefixer.app = comp_apps.keys()[0].short
        return http.HttpResponsePermanentRedirect(reverse(
            'addons.detail', args=[addon.slug]))

    # source tracking
    src = request.GET.get('src', 'addon-detail')

    # get satisfaction only supports en-US
    lang = translation.to_locale(translation.get_language())
    addon.has_satisfaction = (lang == 'en_US' and
                              addon.get_satisfaction_company)

    # other add-ons from the same author(s)
    author_addons = order_by_translation(addon.authors_other_addons, 'name')[:6]

    # tags
    tags = addon.tags.not_blacklisted()

    # addon recommendations
    recommended = MiniAddon.objects.valid().filter(
        recommended_for__addon=addon)[:5]

    # popular collections this addon is part of
    collections = Collection.objects.listed().filter(
        addons=addon, application__id=request.APP.id)

    data = {
        'addon': addon,
        'author_addons': author_addons,

        'src': src,
        'tags': tags,

        'grouped_ratings': GroupedRating.get(addon.id),
        'recommendations': recommended,
        'review_form': ReviewForm(),
        'reviews': Review.objects.latest().filter(addon=addon),
        'get_replies': Review.get_replies,

        'collections': collections.order_by('-subscribers')[:3],
    }
    if settings.REPORT_ABUSE:
        data['abuse_form'] = AbuseForm(request=request)

    return jingo.render(request, 'addons/impala/details.html', data)
コード例 #12
0
ファイル: utils.py プロジェクト: gboone/relate
def format_datetime_local(datetime, format="medium"):
    """Format the output of a datetime object to a localized string"""
    from babel.dates import format_datetime
    from django.conf import settings
    from django.utils.translation.trans_real import to_locale

    # See http://babel.pocoo.org/docs/api/dates/#date-and-time-formatting
    # for customizing the output format.
    try:
        result = format_datetime(datetime, format, locale=to_locale(settings.LANGUAGE_CODE))
    except ValueError:
        result = format_datetime(datetime, format, locale="en_US")

    return result
コード例 #13
0
ファイル: views.py プロジェクト: AutomatedTester/zamboni
def impala_extension_detail(request, addon):
    """Extensions details page."""

    # if current version is incompatible with this app, redirect
    comp_apps = addon.compatible_apps
    if comp_apps and request.APP not in comp_apps:
        prefixer = urlresolvers.get_url_prefix()
        prefixer.app = comp_apps.keys()[0].short
        return http.HttpResponsePermanentRedirect(
            reverse('addons.detail', args=[addon.slug]))

    # source tracking
    src = request.GET.get('src', 'addon-detail')

    # get satisfaction only supports en-US
    lang = translation.to_locale(translation.get_language())
    addon.has_satisfaction = (lang == 'en_US'
                              and addon.get_satisfaction_company)

    # other add-ons from the same author(s)
    author_addons = order_by_translation(addon.authors_other_addons,
                                         'name')[:6]

    # tags
    tags = addon.tags.not_blacklisted()

    # addon recommendations
    recommended = MiniAddon.objects.valid().filter(
        recommended_for__addon=addon)[:5]

    # popular collections this addon is part of
    collections = Collection.objects.listed().filter(
        addons=addon, application__id=request.APP.id)

    data = {
        'addon': addon,
        'author_addons': author_addons,
        'src': src,
        'tags': tags,
        'grouped_ratings': GroupedRating.get(addon.id),
        'recommendations': recommended,
        'review_form': ReviewForm(),
        'reviews': Review.objects.latest().filter(addon=addon),
        'get_replies': Review.get_replies,
        'collections': collections.order_by('-subscribers')[:3],
    }
    if settings.REPORT_ABUSE:
        data['abuse_form'] = AbuseForm(request=request)

    return jingo.render(request, 'addons/impala/details.html', data)
コード例 #14
0
ファイル: __init__.py プロジェクト: guoyu07/tower-2
def _activate(locale):
    # XXX TODO: When it comes time to load .mo files on the fly and merge
    # them, this is the place to do it.  We'll also need to implement our own
    # caching since the _translations stuff is built on a per locale basis,
    # not per locale + some key
    locale = django_trans.to_locale(locale)

    # Django caches the translation objects here
    t = django_trans._translations.get(locale, None)
    if t is not None:
        return t

    # Django's activate() simply calls translation() and adds it to a global.
    # We'll do the same here, first calling django's translation() so it can
    # do everything it needs to do, and then calling gettext directly to
    # load the rest.  We make a deepcopy because Django will return the en-US
    # catalog if it doesn't have a locale (but we do).  We don't want to merge
    # our foreign catalog into en-US.  Since Django stuck the en-US catalog
    # into its cache for this locale, we have to update that too.
    t = copy.deepcopy(django_trans.translation(locale))
    t.set_language(locale)
    try:
        # When trying to load css, js, and images through the Django server
        # gettext() throws an exception saying it can't find the .mo files.  I
        # suspect this has something to do with Django trying not to load
        # extra stuff for requests that won't need it.  I do know that I don't
        # want to try to debug it.  This is what Django does in their function
        # also.
        #
        # We check for SETTINGS_MODULE here because if it's not here, then
        # it's possible we're in a test using override_settings and we don't
        # want to flip out.
        settings_module = getattr(settings, 'SETTINGS_MODULE', None)
        if settings_module:
            # If you've got extra .mo files to load, this is the place.
            path = import_module(settings_module).path
            domain = getattr(settings, 'TEXT_DOMAIN', 'messages')
            bonus = gettext.translation(domain, path('locale'), [locale],
                                        django_trans.DjangoTranslation)
            t.merge(bonus)

            # Overwrite t (defaults to en-US) with our real locale's plural form
            t.plural = bonus.plural

    except IOError:
        pass

    django_trans._translations[locale] = t
    return t
コード例 #15
0
ファイル: __init__.py プロジェクト: thijstriemstra/tower
def _activate(locale):
    # XXX TODO: When it comes time to load .mo files on the fly and merge
    # them, this is the place to do it.  We'll also need to implement our own
    # caching since the _translations stuff is built on a per locale basis,
    # not per locale + some key
    locale = django_trans.to_locale(locale)

    # Django caches the translation objects here
    t = django_trans._translations.get(locale, None)
    if t is not None:
        return t

    # Django's activate() simply calls translation() and adds it to a global.
    # We'll do the same here, first calling django's translation() so it can
    # do everything it needs to do, and then calling gettext directly to
    # load the rest.  We make a deepcopy because Django will return the en-US
    # catalog if it doesn't have a locale (but we do).  We don't want to merge
    # our foreign catalog into en-US.  Since Django stuck the en-US catalog
    # into its cache for this locale, we have to update that too.
    t = copy.deepcopy(django_trans.translation(locale))
    t.set_language(locale)
    try:
        # When trying to load css, js, and images through the Django server
        # gettext() throws an exception saying it can't find the .mo files.  I
        # suspect this has something to do with Django trying not to load
        # extra stuff for requests that won't need it.  I do know that I don't
        # want to try to debug it.  This is what Django does in their function
        # also.
        #
        # We check for SETTINGS_MODULE here because if it's not here, then
        # it's possible we're in a test using override_settings and we don't
        # want to flip out.
        settings_module = getattr(settings, 'SETTINGS_MODULE', None)
        if settings_module:
            # If you've got extra .mo files to load, this is the place.
            path = import_module(settings_module).path
            domain = getattr(settings, 'TEXT_DOMAIN', 'messages')
            bonus = gettext.translation(domain, path('locale'), [locale],
                                        django_trans.DjangoTranslation)
            t.merge(bonus)

            # Overwrite t (defaults to en-US) with our real locale's plural form
            t.plural = bonus.plural

    except IOError:
        pass

    django_trans._translations[locale] = t
    return t
コード例 #16
0
def format_datetime_local(datetime, format='medium'):
    """Format the output of a datetime object to a localized string"""
    from babel.dates import format_datetime
    from django.conf import settings
    from django.utils.translation.trans_real import to_locale
    # See http://babel.pocoo.org/docs/api/dates/#date-and-time-formatting
    # for customizing the output format.
    try:
        locale = to_locale(settings.LANGUAGE_CODE)
    except ValueError:
        locale = "en_US"

    result = format_datetime(datetime, format, locale=locale)

    return result
コード例 #17
0
ファイル: views.py プロジェクト: james4388/zamboni
def extension_detail(request, addon):
    """Extensions details page."""
    # If current version is incompatible with this app, redirect.
    comp_apps = addon.compatible_apps
    if comp_apps and request.APP not in comp_apps:
        prefixer = urlresolvers.get_url_prefix()
        prefixer.app = comp_apps.keys()[0].short
        return redirect("addons.detail", addon.slug, permanent=True)

    # get satisfaction only supports en-US.
    lang = translation.to_locale(translation.get_language())
    addon.has_satisfaction = lang == "en_US" and addon.get_satisfaction_company

    # Addon recommendations.
    recommended = Addon.objects.listed(request.APP).filter(recommended_for__addon=addon)[:6]

    # Popular collections this addon is part of.
    collections = Collection.objects.listed().filter(addons=addon, application__id=request.APP.id)

    ctx = {
        "addon": addon,
        "src": request.GET.get("src", "dp-btn-primary"),
        "version_src": request.GET.get("src", "dp-btn-version"),
        "tags": addon.tags.not_blacklisted(),
        "grouped_ratings": GroupedRating.get(addon.id),
        "recommendations": recommended,
        "review_form": ReviewForm(),
        "reviews": Review.objects.latest().filter(addon=addon),
        "get_replies": Review.get_replies,
        "collections": collections.order_by("-subscribers")[:3],
        "abuse_form": AbuseForm(request=request),
    }

    # details.html just returns the top half of the page for speed. The bottom
    # does a lot more queries we don't want on the initial page load.
    if request.is_ajax():
        # Other add-ons/apps from the same author(s).
        if addon.is_webapp():
            others = Webapp.objects.listed().filter(type=amo.ADDON_WEBAPP)
        else:
            others = Addon.objects.listed(request.APP).exclude(type=amo.ADDON_WEBAPP)
        others = others.exclude(id=addon.id).distinct().filter(addonuser__listed=True, authors__in=addon.listed_authors)
        ctx["author_addons"] = others[:6]
        return jingo.render(request, "addons/impala/details-more.html", ctx)
    else:
        if addon.is_webapp():
            ctx["search_cat"] = "apps"
        return jingo.render(request, "addons/impala/details.html", ctx)
コード例 #18
0
    def setup_mofile_with_entry(self, poentry, language='en'):
        locale_location = join(settings.LOCALE_DIR, 'locale', language,
                               'LC_MESSAGES')
        pofile = polib.pofile(join(locale_location, 'django.po'))

        pofile.append(poentry)
        pofile.save()
        pofile.save_as_mofile(join(locale_location, 'django.mo'))

        jit_locale = gettext_module.translation(
            'django', join(settings.LOCALE_DIR, 'locale'),
            [trans_real.to_locale(language)], trans_real.DjangoTranslation)
        jit_locale.set_language(language)

        locale = trans_real.translation(language)
        locale.merge(jit_locale)
コード例 #19
0
    def process_request(self, request):
        """

        :param request:
        :return:
        """
        if self.is_edit_mode(request):
            logger.info('Editing mode enabled')
            from django.utils.translation.trans_real import get_language, to_locale
            locale = to_locale(get_language())

            setattr(THREAD_LOCAL_STORAGE, EDIT_MODE, True)
            setattr(THREAD_LOCAL_STORAGE, MESSAGES, set())
            setattr(THREAD_LOCAL_STORAGE, REQUEST, request)
            setattr(THREAD_LOCAL_STORAGE, REQUEST_LOCALE, locale)
        else:
            setattr(THREAD_LOCAL_STORAGE, EDIT_MODE, False)
        return None
コード例 #20
0
ファイル: addons.py プロジェクト: washort/gelato.models
class AddonBase(OnChangeMixin, ModelBase):
    STATUS_CHOICES = base.STATUS_CHOICES.items()
    LOCALES = [(translation.to_locale(k).replace('_', '-'), v) for k, v in
               do_dictsort(settings.LANGUAGES)]

    guid = models.CharField(max_length=255, unique=True, null=True)
    slug = models.CharField(max_length=30, unique=True, null=True)
    # This column is only used for webapps, so they can have a slug namespace
    # separate from addons and personas.
    app_slug = models.CharField(max_length=30, unique=True, null=True)
    name = TranslatedField()
    default_locale = models.CharField(max_length=10,
                                      default=settings.LANGUAGE_CODE,
                                      db_column='defaultlocale')

    type = models.PositiveIntegerField(db_column='addontype_id')
    status = models.PositiveIntegerField(
        choices=STATUS_CHOICES, db_index=True, default=0)
    highest_status = models.PositiveIntegerField(
        choices=STATUS_CHOICES, default=0,
        help_text="An upper limit for what an author can change.",
        db_column='higheststatus')
    icon_type = models.CharField(max_length=25, blank=True,
                                 db_column='icontype')
    homepage = TranslatedField()
    support_email = TranslatedField(db_column='supportemail')
    support_url = TranslatedField(db_column='supporturl')
    description = PurifiedField(short=False)

    summary = LinkifiedField()
    developer_comments = PurifiedField(db_column='developercomments')
    eula = PurifiedField()
    privacy_policy = PurifiedField(db_column='privacypolicy')
    the_reason = PurifiedField()
    the_future = PurifiedField()

    average_rating = models.FloatField(max_length=255, default=0, null=True,
                                       db_column='averagerating')
    bayesian_rating = models.FloatField(default=0, db_index=True,
                                        db_column='bayesianrating')
    total_reviews = models.PositiveIntegerField(default=0,
                                                db_column='totalreviews')
    weekly_downloads = models.PositiveIntegerField(
            default=0, db_column='weeklydownloads', db_index=True)
    total_downloads = models.PositiveIntegerField(
            default=0, db_column='totaldownloads')
    hotness = models.FloatField(default=0, db_index=True)

    average_daily_downloads = models.PositiveIntegerField(default=0)
    average_daily_users = models.PositiveIntegerField(default=0)
    share_count = models.PositiveIntegerField(default=0, db_index=True,
                                              db_column='sharecount')
    last_updated = models.DateTimeField(db_index=True, null=True,
        help_text='Last time this add-on had a file/version update')
    ts_slowness = models.FloatField(db_index=True, null=True,
        help_text='How much slower this add-on makes browser ts tests. '
                  'Read as {addon.ts_slowness}% slower.')

    disabled_by_user = models.BooleanField(default=False, db_index=True,
                                           db_column='inactive')
    trusted = models.BooleanField(default=False)
    view_source = models.BooleanField(default=True, db_column='viewsource')
    public_stats = models.BooleanField(default=False, db_column='publicstats')
    prerelease = models.BooleanField(default=False)
    admin_review = models.BooleanField(default=False, db_column='adminreview')
    admin_review_type = models.PositiveIntegerField(
                                    choices=base.ADMIN_REVIEW_TYPES.items(),
                                    default=base.ADMIN_REVIEW_FULL)
    site_specific = models.BooleanField(default=False,
                                        db_column='sitespecific')
    external_software = models.BooleanField(default=False,
                                            db_column='externalsoftware')
    dev_agreement = models.BooleanField(default=False,
                            help_text="Has the dev agreement been signed?")
    auto_repackage = models.BooleanField(default=True,
        help_text='Automatically upgrade jetpack add-on to a new sdk version?')
    outstanding = models.BooleanField(default=False)

    nomination_message = models.TextField(null=True,
                                          db_column='nominationmessage')
    target_locale = models.CharField(
        max_length=255, db_index=True, blank=True, null=True,
        help_text="For dictionaries and language packs")
    locale_disambiguation = models.CharField(
        max_length=255, blank=True, null=True,
        help_text="For dictionaries and language packs")

    wants_contributions = models.BooleanField(default=False)
    paypal_id = models.CharField(max_length=255, blank=True)
    charity = models.ForeignKey('Charity', null=True)
    # TODO(jbalogh): remove nullify_invalid once remora dies.
    suggested_amount = DecimalCharField(
        max_digits=8, decimal_places=2, nullify_invalid=True, blank=True,
        null=True, help_text=_(u'Users have the option of contributing more '
                               'or less than this amount.'))

    total_contributions = DecimalCharField(max_digits=8, decimal_places=2,
                                           nullify_invalid=True, blank=True,
                                           null=True)

    annoying = models.PositiveIntegerField(
        choices=base.CONTRIB_CHOICES, default=0,
        help_text=_(u"Users will always be asked in the Add-ons"
                     " Manager (Firefox 4 and above)"))
    enable_thankyou = models.BooleanField(default=False,
        help_text="Should the thankyou note be sent to contributors?")
    thankyou_note = TranslatedField()

    get_satisfaction_company = models.CharField(max_length=255, blank=True,
                                                null=True)
    get_satisfaction_product = models.CharField(max_length=255, blank=True,
                                                null=True)

    authors = models.ManyToManyField(UserProfileBase, through='AddonUser',
                                     related_name='addons')
    categories = models.ManyToManyField('Category', through='AddonCategoryBase')
    dependencies = models.ManyToManyField('self', symmetrical=False,
                                          through='AddonDependency',
                                          related_name='addons')
    premium_type = models.PositiveIntegerField(
                                    choices=base.ADDON_PREMIUM_TYPES.items(),
                                    default=base.ADDON_FREE)
    manifest_url = models.URLField(max_length=255, blank=True, null=True,
                                   verify_exists=False)
    app_domain = models.CharField(max_length=255, blank=True, null=True,
                                  db_index=True)

    _current_version = models.ForeignKey(VersionBase, related_name='___ignore',
            db_column='current_version', null=True, on_delete=models.SET_NULL)
    # This is for Firefox only.
    _backup_version = models.ForeignKey(VersionBase, related_name='___backup',
            db_column='backup_version', null=True, on_delete=models.SET_NULL)
    _latest_version = None
    make_public = models.DateTimeField(null=True)
    mozilla_contact = models.EmailField()

    # Whether the app is packaged or not (aka hosted).
    is_packaged = models.BooleanField(default=False, db_index=True)

    # This gets overwritten in the transformer.
    share_counts = collections.defaultdict(int)

    class Meta:
        db_table = 'addons'
        app_label = 'addons'

    @staticmethod
    def __new__(cls, *args, **kw):
        # # Return a Webapp instead of an Addon if the `type` column says this is
        # # really a webapp.
        # try:
        #     type_idx = AddonBase._meta._type_idx
        # except AttributeError:
        #     type_idx = (idx for idx, f in enumerate(AddonBase._meta.fields)
        #                 if f.attname == 'type').next()
        #     AddonBase._meta._type_idx = type_idx
        # if ((len(args) == len(AddonBase._meta.fields)
        #      and args[type_idx] == base.ADDON_WEBAPP)
        #     or kw and kw.get('type') == base.ADDON_WEBAPP):
        #     from gelato.models.webapp import Webapp
        #     cls = Webapp
        return super(AddonBase, cls).__new__(cls, *args, **kw)

    def __unicode__(self):
        return u'%s: %s' % (self.id, self.name)

    def __init__(self, *args, **kw):
        super(AddonBase, self).__init__(*args, **kw)
        self._first_category = {}


    @property
    def premium(self):
        """
        Returns the premium object which will be gotten by the transformer,
        if its not there, try and get it. Will return None if there's nothing
        there.
        """
        if not hasattr(self, '_premium'):
            try:
                self._premium = self.addonpremium
            except AddonPremium.DoesNotExist:
                self._premium = None
        return self._premium
コード例 #21
0
ファイル: views.py プロジェクト: chowse/zamboni
def extension_detail(request, addon):
    """Extensions details page."""

    # if current version is incompatible with this app, redirect
    comp_apps = addon.compatible_apps
    if comp_apps and request.APP not in comp_apps:
        prefixer = urlresolvers.get_url_prefix()
        prefixer.app = comp_apps.keys()[0].short
        return http.HttpResponsePermanentRedirect(reverse(
            'addons.detail', args=[addon.id]))

    # source tracking
    src = request.GET.get('src', 'addondetail')

    # get satisfaction only supports en-US
    lang = translation.to_locale(translation.get_language())
    addon.has_satisfaction = (lang == 'en_US' and
                              addon.get_satisfaction_company)

    # other add-ons from the same author(s)
    author_addons = (Addon.objects.valid().only_translations()
                     .exclude(id=addon.id)
                     .filter(addonuser__listed=True,
                             authors__in=addon.listed_authors).distinct())

    # tags
    (dev_tags, user_tags) = addon.tags_partitioned_by_developer

    current_user_tags = []

    if request.user.is_authenticated():
        current_user_tags = user_tags.filter(
                addon_tags__user=request.amo_user)

    # addon recommendations
    recommended = Addon.objects.valid().only_translations().filter(
        recommended_for__addon=addon)[:5]

    # popular collections this addon is part of
    coll_show_count = 3
    collections = Collection.objects.listed().filter(
        addons=addon, application__id=request.APP.id)
    other_coll_count = max(0, collections.count() - coll_show_count)
    popular_coll = collections.order_by('-subscribers')[:coll_show_count]

    # this user's collections
    user_collections = _details_collections_dropdown(request, addon)

    data = {
        'addon': addon,
        'author_addons': author_addons,

        'src': src,

        'dev_tags': dev_tags,
        'user_tags': user_tags,
        'current_user_tags': current_user_tags,

        'recommendations': recommended,

        'collections': popular_coll,
        'other_collection_count': other_coll_count,
        'user_collections': user_collections,
    }
    return jingo.render(request, 'addons/details.html', data)
コード例 #22
0
def messages_viewer(list_messages, view_locale=None):
    """
    Use the original translate function instead of the patched one
    """
    from django.utils.translation.trans_real import get_language, to_locale
    from rosetta_inpage.patches import original as _  # The original

    results = []
    locale = to_locale(get_language())
    catalog = utils.get_locale_catalog(locale)
    translated_count = 0

    def create(msgid):
        entry = catalog.dict.get(msgid, None)
        # is_valid_translation = True if entry and entry.translated() else False
        # is_valid_translation = True if entry and entry.msgstr is not u"" or None \
        #     and not entry.obsolete else False
        is_valid_translation = utils.is_translated(entry)

        # if translated:
        #    print "\n\n", str(is_valid_translation), ", "
        #    print "Test= ", msg, translated, "==", encode(translated.msgstr), \
        #        ", file=", str(translated.pfile), "obs=", str(translated.obsolete), "\n"

        if is_valid_translation:
            msg_target = entry.msgstr
        else:
            msg_target = _(msgid)

        if not is_valid_translation:
            css_class = 'rosetta-inpage-todo'
        elif entry and 'fuzzy' in entry.flags:
            css_class = 'rosetta-inpage-fuzzy'
        else:
            css_class = 'rosetta-inpage-foo'

        return {
            'show': show_message(msgid, view_locale),
            'hash': rosetta_inpage.hash_text(msgid),
            'source': mark_safe(msg),       # the source message
            'msg': mark_safe(msg_target),   # the translated message
            'translated': is_valid_translation,
            'fuzzy': False if entry and 'fuzzy' not in entry.flags else True,
            'css_class': css_class
        }

    def show_message(msgid, view_locale=None):
        if view_locale:
            poentry = utils.get_message(msgid, view_locale)
            if poentry and poentry.msgstr:
                return utils.encode(poentry.msgstr)
        return utils.encode(msgid)

    for msg in list_messages:
        item = create(msg)
        results.append(item)
        if item.get('translated', False):
            translated_count += 1

    sorted_results = sorted(results, key=lambda entry: entry['show'])
    return sorted_results, translated_count
コード例 #23
0
ファイル: serializers.py プロジェクト: wangeek/zamboni
class InAppProductSerializer(serializers.ModelSerializer):
    _locales = [(translation.to_locale(k).replace('_', '-').lower(), v)
                for k, v in do_dictsort(settings.LANGUAGES)]

    app = serializers.SlugRelatedField(read_only=True, slug_field='app_slug',
                                       source='webapp')
    guid = serializers.CharField(read_only=True)
    include_inactive = serializers.BooleanField(read_only=True)
    logo_url = serializers.CharField(
        validators=[URLValidator(schemes=['http', 'https'])],
        required=False)
    name = NameField()
    default_locale = serializers.ChoiceField(choices=_locales)
    price_id = serializers.PrimaryKeyRelatedField(source='price',
                                                  queryset=Price.objects)

    class Meta:
        model = InAppProduct
        fields = ['active', 'guid', 'app', 'price_id', 'name',
                  'default_locale', 'logo_url', 'include_inactive']

    def validate(self, attrs):
        default_name = attrs['name'].get(attrs['default_locale'], None)
        if ((attrs['default_locale'] not in attrs['name']) or
                not default_name):
            raise ValidationError(
                'no localization for default_locale {d} in "name"'
                .format(d=repr(attrs['default_locale'])))
        return attrs

    def validate_logo_url(self, logo_url):

        # This message is shown for all image errors even though it may
        # not be correct. This is to prevent leaking info that could
        # lead to port scanning, DOS'ing or other vulnerabilities.
        msg = _('Product logo must be a 64x64 image. '
                'Check that the URL is correct.')
        tmp_dest = StringIO()
        try:
            res = requests.get(
                logo_url, timeout=3,
                headers={'User-Agent': settings.MARKETPLACE_USER_AGENT})
            res.raise_for_status()
            payload = 0
            read_size = 100000
            for chunk in res.iter_content(read_size):
                payload += len(chunk)
                if payload > settings.MAX_INAPP_IMAGE_SIZE:
                    log.info('clean_logo_url: payload exceeded allowed '
                             'size: {url}: '.format(url=logo_url))
                    raise ValidationError(msg)
                tmp_dest.write(chunk)
        except ValidationError:
            raise
        except Exception, exc:
            log.info('clean_logo_url: exception fetching {url}: '
                     '{exc.__class__.__name__}: {exc}'
                     .format(url=logo_url, exc=exc))
            raise ValidationError(msg)

        tmp_dest.seek(0)
        try:
            img = Image.open(tmp_dest)
            img.verify()
        except Exception, exc:
            log.info('clean_logo_url: Error loading/verifying {url}: '
                     '{exc.__class__.__name__}: {exc}'
                     .format(url=logo_url, exc=exc))
            raise ValidationError(msg)
コード例 #24
0
def get_settings(conf_file_leafname, election_app=None, tests=False):
    conf = get_conf(conf_file_leafname)

    debug = bool(int(conf.get('STAGING')))

    # Get the requested ELECTION_APP:
    if election_app is None:
        election_app = conf['ELECTION_APP']
    election_app_fully_qualified = 'elections.' + election_app
    election_settings_module = election_app_fully_qualified + '.settings'
    elections_module = importlib.import_module(election_settings_module)

    language_code = conf.get('LANGUAGE_CODE', 'en-gb')

    # Internationalization
    # https://docs.djangoproject.com/en/1.6/topics/i18n/
    locale_paths = [
        join(BASE_DIR, 'locale')
    ]
    # The code below sets LANGUAGES to only those we have translations
    # for, so at the time of writing that will be:
    #   [('en', 'English'), ('es-ar', 'Argentinian Spanish')]
    # whereas the default setting is a long list of languages which
    # includes:
    #   ('es', 'Spanish').
    # If someone's browser sends 'Accept-Language: es', that means that it
    # will be found in this list, but since there are no translations for 'es'
    # it'll fall back to LANGUAGE_CODE.  However, if there is no 'es' in
    # LANGUAGES, then Django will attempt to do a best match, so if
    # Accept-Language is 'es' then it will use the 'es-ar' translation.  We think
    # this is generally desirable (e.g. so someone can see YourNextMP in Spanish
    # if their browser asks for Spanish).
    languages = [
        l for l in LANGUAGES
        if exists(join(locale_paths[0], to_locale(l[0])))
    ]
    languages.append(('cy-gb', 'Welsh'))
    languages.append(('es-cr', 'Costa Rican Spanish'))

    # The language selection has been slightly complicated now that we
    # have two es- languages: es-ar and es-cr.  Chrome doesn't offer
    # Costa Rican Spanish as one of its language choices, so the best
    # you can do is choose 'Spanish - español'. (This might well be
    # the case in other browsers too.)  Since 'es-ar' comes first in
    # 'languages' after the preceding code, this means that someone
    # viewing the Costa Rica site with Chrome's preferred language set
    # to Spanish (i.e. with 'es' first in Accept-Language) will get
    # the Argentinian Spanish translations instead of Costa Rican
    # Spanish.  To get around this, look for the default language code
    # for the site, and if that's present, move it to the front of
    # 'languages'.  This should be generally helpful behaviour: the
    # default language code of the site should take precedence over
    # another language that happens to match based on the generic part
    # of the language code.
    language_code_index = next(
        (i for i, l in enumerate(languages) if l[0] == language_code),
        None
    )
    if language_code_index is not None:
        languages.insert(0, languages.pop(language_code_index))

    # Make sure the MEDIA_ROOT directory actually exists:
    media_root = conf.get('MEDIA_ROOT') or join(BASE_DIR, 'media')
    # Make sure that the MEDIA_ROOT and subdirectory for archived CSV
    # files exist:
    mkdir_p(join(media_root, 'csv-archives'))

    # Database
    # https://docs.djangoproject.com/en/1.6/ref/settings/#databases
    if conf.get('DATABASE_SYSTEM') == 'postgresql':
        databases = {
            'default': {
                'ENGINE':   'django.db.backends.postgresql_psycopg2',
                'NAME':     conf.get('YNMP_DB_NAME'),
                'USER':     conf.get('YNMP_DB_USER'),
                'PASSWORD': conf.get('YNMP_DB_PASS'),
                'HOST':     conf.get('YNMP_DB_HOST'),
                'PORT':     conf.get('YNMP_DB_PORT'),
            }
        }
    else:
        databases = {
            'default': {
                'ENGINE': 'django.db.backends.sqlite3',
                'NAME': join(BASE_DIR, 'db.sqlite3'),
            }
        }

    # Setup caches depending on DEBUG:
    if debug:
        cache = {'BACKEND': 'django.core.cache.backends.dummy.DummyCache'}
        cache_thumbnails = {'BACKEND': 'django.core.cache.backends.dummy.DummyCache'}
    else:
        cache = {
            'TIMEOUT': None, # cache keys never expire; we invalidate them
            'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
            'LOCATION': '127.0.0.1:11211',
            'KEY_PREFIX': databases['default']['NAME'],
        }
        cache_thumbnails = {
            'TIMEOUT': 60 * 60 * 24 * 2, # expire after two days
            'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
            'LOCATION': '127.0.0.1:11211',
            'KEY_PREFIX': databases['default']['NAME'] + "-thumbnails",
        }

    # Create a dictionary with these settings and other simpler ones:
    result = {
        'BASE_DIR': BASE_DIR,
        'ALLOWED_HOSTS': conf.get('ALLOWED_HOSTS'),
        'DEBUG': debug,
        'RUNNING_TESTS': tests,

        # Google analytics settings:
        'GOOGLE_ANALYTICS_ACCOUNT': conf.get('GOOGLE_ANALYTICS_ACCOUNT'),
        'USE_UNIVERSAL_ANALYTICS': conf.get('USE_UNIVERSAL_ANALYTICS', True),

        # The Twitter account referenced in the Twitter card data:
        'TWITTER_USERNAME': conf.get('TWITTER_USERNAME', ''),

        # The email address which is made public on the site for sending
        # support email to:
        'SUPPORT_EMAIL': conf['SUPPORT_EMAIL'],

        # Email addresses that error emails are sent to when DEBUG = False
        'ADMINS': conf['ADMINS'],

        # The From: address for all emails except error emails
        'DEFAULT_FROM_EMAIL': conf['DEFAULT_FROM_EMAIL'],

        # The From: address for error emails
        'SERVER_EMAIL': conf['SERVER_EMAIL'],

        # SECURITY WARNING: keep the secret key used in production secret!
        'SECRET_KEY': conf['SECRET_KEY'],

        'TEMPLATE_DEBUG': True,
        'TEMPLATE_DIRS': (
            join(BASE_DIR, 'mysite', 'templates'),
        ),
        'TEMPLATE_CONTEXT_PROCESSORS': TEMPLATE_CONTEXT_PROCESSORS + (
            # Required by allauth template tags
            "django.core.context_processors.request",
            # allauth specific context processors
            "allauth.account.context_processors.account",
            "allauth.socialaccount.context_processors.socialaccount",
            "django.contrib.messages.context_processors.messages",
            "mysite.context_processors.add_settings",
            "mysite.context_processors.election_date",
            "mysite.context_processors.add_group_permissions",
            "mysite.context_processors.add_notification_data",
            "mysite.context_processors.locale",
            "mysite.context_processors.add_site",
        ),

        'ELECTION_APP': election_app,
        'ELECTION_APP_FULLY_QUALIFIED': election_app_fully_qualified,

        # The Django applications in use:
        'INSTALLED_APPS': (
            'django.contrib.admin',
            'django.contrib.auth',
            'django.contrib.contenttypes',
            'django.contrib.humanize',
            'django.contrib.sessions',
            'django.contrib.messages',
            'django.contrib.staticfiles',
            'django.contrib.sites',
            'django_nose',
            'django_extensions',
            'pipeline',
            'statici18n',
            'sorl.thumbnail',
            'rest_framework',
            'rest_framework.authtoken',
            'images',
            'haystack',
            'elections',
            'popolo',
            election_app_fully_qualified,
            'candidates',
            'tasks',
            'alerts',
            'cached_counts',
            'moderation_queue',
            'auth_helpers',
            'debug_toolbar',
            'template_timings_panel',
            'official_documents',
            'results',
            'notifications',
            'allauth',
            'allauth.account',
            'allauth.socialaccount',
            'allauth.socialaccount.providers.google',
            'allauth.socialaccount.providers.facebook',
            'allauth.socialaccount.providers.twitter',
            'corsheaders',
            'crispy_forms',
        ),

        'SITE_ID': 1,

        'MIDDLEWARE_CLASSES': (
            'debug_toolbar.middleware.DebugToolbarMiddleware',
            'corsheaders.middleware.CorsMiddleware',
            'django.contrib.sessions.middleware.SessionMiddleware',
            'django.middleware.locale.LocaleMiddleware',
            'django.middleware.common.CommonMiddleware',
            'django.middleware.csrf.CsrfViewMiddleware',
            'django.contrib.auth.middleware.AuthenticationMiddleware',
            'candidates.middleware.CopyrightAssignmentMiddleware',
            'candidates.middleware.DisallowedUpdateMiddleware',
            'django.contrib.messages.middleware.MessageMiddleware',
            'django.middleware.clickjacking.XFrameOptionsMiddleware',
        ),

        # django-allauth settings:
        'AUTHENTICATION_BACKENDS': (
            # Needed to login by username in Django admin, regardless of `allauth`
            "django.contrib.auth.backends.ModelBackend",
            # `allauth` specific authentication methods, such as login by e-mail
            "allauth.account.auth_backends.AuthenticationBackend",
        ),
        'SOCIALACCOUNT_PROVIDERS': {
            'google': {'SCOPE': ['https://www.googleapis.com/auth/userinfo.profile'],
                       'AUTH_PARAMS': {'access_type': 'online'}},
            'facebook': {'SCOPE': ['email',]},
        },
        'LOGIN_REDIRECT_URL': '/',
        'ACCOUNT_EMAIL_VERIFICATION': 'mandatory',
        'ACCOUNT_EMAIL_REQUIRED': True,
        'ACCOUNT_USERNAME_REQUIRED': True,
        'SOCIALACCOUNT_AUTO_SIGNUP': True,

        'ROOT_URLCONF': 'mysite.urls',
        'WSGI_APPLICATION': 'mysite.wsgi.application',

        # Django Debug Toolbar settings:
        'DEBUG_TOOLBAR_PATCH_SETTINGS': False,
        'DEBUG_TOOLBAR_PANELS': [
            'debug_toolbar.panels.versions.VersionsPanel',
            'debug_toolbar.panels.timer.TimerPanel',
            'debug_toolbar.panels.settings.SettingsPanel',
            'debug_toolbar.panels.headers.HeadersPanel',
            'debug_toolbar.panels.request.RequestPanel',
            'debug_toolbar.panels.sql.SQLPanel',
            'debug_toolbar.panels.staticfiles.StaticFilesPanel',
            'debug_toolbar.panels.templates.TemplatesPanel',
            'debug_toolbar.panels.cache.CachePanel',
            'debug_toolbar.panels.signals.SignalsPanel',
            'debug_toolbar.panels.logging.LoggingPanel',
            'debug_toolbar.panels.redirects.RedirectsPanel',
            'template_timings_panel.panels.TemplateTimings.TemplateTimings',
        ],
        'INTERNAL_IPS': ['127.0.0.1'],

        # Language settings (calculated above):
        'LOCALE_PATHS': locale_paths,
        'LANGUAGES': languages,
        'LANGUAGE_CODE': language_code,
        'TIME_ZONE': conf.get('TIME_ZONE', 'Europe/London'),
        'USE_I18N': True,
        'USE_L10N': True,
        'USE_TZ': True,
        'DD_MM_DATE_FORMAT_PREFERRED': conf.get('DD_MM_DATE_FORMAT_PREFERRED', True),

        # The media and static file settings:
        'MEDIA_ROOT': media_root,
        'MEDIA_URL': '/media/',

        # Settings for staticfiles and Django pipeline:
        'STATIC_URL': '/static/',
        'STATIC_ROOT': join(BASE_DIR, 'static'),
        'STATICI18N_ROOT': join(BASE_DIR, 'mysite', 'static'),
        'STATICFILES_DIRS': (
            join(BASE_DIR, 'mysite', 'static'),
        ),
        'STATICFILES_FINDERS': (
            'django.contrib.staticfiles.finders.FileSystemFinder',
            'django.contrib.staticfiles.finders.AppDirectoriesFinder',
            'pipeline.finders.PipelineFinder',
        ),
        'PIPELINE_CSS': {
            'image-review': {
                'source_filenames': (
                    'moderation_queue/css/jquery.Jcrop.css',
                    'moderation_queue/css/crop.scss',
                ),
                'output_filename': 'css/image-review.css',
            },
            'official_documents': {
                'source_filenames': (
                    'official_documents/css/official_documents.scss',
                ),
                'output_filename': 'css/official_documents.css',
            },
            'all': {
                'source_filenames': (
                    'candidates/style.scss',
                    'cached_counts/style.scss',
                    'select2/select2.css',
                    'jquery/jquery-ui.css',
                    'jquery/jquery-ui.structure.css',
                    'jquery/jquery-ui.theme.css',
                    'moderation_queue/css/photo-upload.scss',
                ),
                'output_filename': 'css/all.css',
            }
        },
        'PIPELINE_JS': {
            'image-review': {
                'source_filenames': (
                    'moderation_queue/js/jquery.color.js',
                    'moderation_queue/js/jquery.Jcrop.js',
                    'moderation_queue/js/crop.js',
                ),
                'output_filename': 'js/image-review.js',
            },
            'all': {
                'source_filenames': (
                    'jquery/jquery-1.11.1.js',
                    'jquery/jquery-ui.js',
                    'foundation/js/foundation/foundation.js',
                    'foundation/js/foundation/foundation.equalizer.js',
                    'foundation/js/foundation/foundation.dropdown.js',
                    'foundation/js/foundation/foundation.tooltip.js',
                    'foundation/js/foundation/foundation.offcanvas.js',
                    'foundation/js/foundation/foundation.accordion.js',
                    'foundation/js/foundation/foundation.joyride.js',
                    'foundation/js/foundation/foundation.alert.js',
                    'foundation/js/foundation/foundation.topbar.js',
                    'foundation/js/foundation/foundation.reveal.js',
                    'foundation/js/foundation/foundation.slider.js',
                    'foundation/js/foundation/foundation.magellan.js',
                    'foundation/js/foundation/foundation.clearing.js',
                    'foundation/js/foundation/foundation.orbit.js',
                    'foundation/js/foundation/foundation.interchange.js',
                    'foundation/js/foundation/foundation.abide.js',
                    'foundation/js/foundation/foundation.tab.js',
                    'select2/select2.js',
                    'js/constituency.js',
                    'js/person_form.js',
                    'js/home_geolocation_form.js',
                    'js/versions.js',
                ),
                'output_filename': 'js/all.js'
            }
        },
        'PIPELINE_COMPILERS': (
            'pipeline.compilers.sass.SASSCompiler',
        ),
        'PIPELINE_SASS_ARGUMENTS': '--trace --quiet',
        'PIPELINE_CSS_COMPRESSOR': 'pipeline.compressors.yui.YUICompressor',
        'PIPELINE_JS_COMPRESSOR': 'pipeline.compressors.yui.YUICompressor',
        # On some platforms this might be called "yuicompressor", so it may be
        # necessary to symlink it into your PATH as "yui-compressor".
        'PIPELINE_YUI_BINARY': '/usr/bin/env yui-compressor',

        'TEST_RUNNER': 'django_nose.NoseTestSuiteRunner',

        'SOURCE_HINTS': _(
            "Please don't quote third-party candidate sites \u2014 "
            "we prefer URLs of news stories or official candidate pages."
        ),

        # By default, cache successful results from MapIt for a day
        'MAPIT_CACHE_SECONDS': 86400,
        'DATABASES': databases,
        'CACHES': {
            'default': cache,
            'thumbnails': cache_thumbnails,
        },

        # sorl-thumbnail settings:
        'THUMBNAIL_CACHE': 'thumbnails',
        'THUMBNAIL_DEBUG': debug,

        # Settings for restricting user activity to reduce abuse:
        'RESTRICT_RENAMES': conf.get('RESTRICT_RENAMES'),
        'EDITS_ALLOWED': conf.get('EDITS_ALLOWED', True),

        # Django Rest Framework settings:
        'REST_FRAMEWORK': {
            'DEFAULT_PERMISSION_CLASSES': ('candidates.api_permissions.ReadOnly',),
            'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning',
            'DEFAULT_FILTER_BACKENDS': ('rest_framework.filters.DjangoFilterBackend',),
            'PAGE_SIZE': 10,
        },

        # allow attaching extra data to notifications:
        'NOTIFICATIONS_USE_JSONFIELD': True,

        'HAYSTACK_SIGNAL_PROCESSOR': 'haystack.signals.RealtimeSignalProcessor',

        'HAYSTACK_CONNECTIONS': {
            'default': {
                'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine',
                'URL': 'http://127.0.0.1:9200/',
                'INDEX_NAME': '{0}_{1}'.format(conf.get('YNMP_DB_NAME'), conf.get('YNMP_DB_HOST')),
            },
        },

        # CORS config
        'CORS_ORIGIN_ALLOW_ALL': True,
        'CORS_URLS_REGEX': r'^/api/.*$',
        'CORS_ALLOW_METHODS': (
            'GET',
            'OPTIONS',
        ),
    }
    if not conf.get('NEW_ACCOUNTS_ALLOWED', True):
        result['ACCOUNT_ADAPTER'] = \
            'mysite.account_adapter.NoNewUsersAccountAdapter'
    if tests:
        result['NOSE_ARGS'] = [
            '--nocapture',
            '--with-yanc',
            # There are problems with OpenCV on Travis, so don't even try to
            # import moderation_queue/faces.py
            '--ignore-files=faces',
        ]
        if election_app == 'example':
            result['NOSE_ARGS'].append('--with-doctest')
    else:
        # If we're not testing, use PipelineCachedStorage
        result['STATICFILES_STORAGE'] = \
            'pipeline.storage.PipelineCachedStorage'
    if conf.get('NGINX_SSL'):
        result['SECURE_PROXY_SSL_HEADER'] = ('HTTP_X_FORWARDED_PROTO', 'https')
        result['ACCOUNT_DEFAULT_HTTP_PROTOCOL'] = 'https'
    for required_election_app_setting in (
            'SITE_OWNER',
            'COPYRIGHT_HOLDER',
    ):
        result[required_election_app_setting] = \
            getattr(elections_module, required_election_app_setting)
    for optional_election_app_setting, default in (
            ('SITE_OWNER_URL', ''),
            ('AREAS_TO_ALWAYS_RETURN', []),
            ('IMAGE_PROXY_URL', ''),
    ):
        try:
            result[optional_election_app_setting] = \
                getattr(elections_module, optional_election_app_setting)
        except AttributeError:
            result[optional_election_app_setting] = default
    # Make sure there's a trailing slash at the end of base MapIt URL:
    result['MAPIT_BASE_URL'] = \
        re.sub(r'/*$', '/', elections_module.MAPIT_BASE_URL)

    result['INSTALLED_APPS'] = list(result['INSTALLED_APPS'])
    result['INSTALLED_APPS'].extend(
        getattr(elections_module, 'INSTALLED_APPS', [])
    )

    return result
コード例 #25
0
ファイル: conf.py プロジェクト: wjt/yournextrepresentative
def get_settings(conf_file_leafname, election_app=None, tests=False):
    conf = get_conf(conf_file_leafname)

    debug = bool(int(conf.get('STAGING')))

    # Get the requested ELECTION_APP:
    if election_app is None:
        election_app = conf['ELECTION_APP']
    election_app_fully_qualified = 'elections.' + election_app

    language_code = conf.get('LANGUAGE_CODE', 'en-gb')

    # Internationalization
    # https://docs.djangoproject.com/en/1.6/topics/i18n/
    locale_paths = [
        join(BASE_DIR, 'locale')
    ]
    # The code below sets LANGUAGES to only those we have translations
    # for, so at the time of writing that will be:
    #   [('en', 'English'), ('es-ar', 'Argentinian Spanish')]
    # whereas the default setting is a long list of languages which
    # includes:
    #   ('es', 'Spanish').
    # If someone's browser sends 'Accept-Language: es', that means that it
    # will be found in this list, but since there are no translations for 'es'
    # it'll fall back to LANGUAGE_CODE.  However, if there is no 'es' in
    # LANGUAGES, then Django will attempt to do a best match, so if
    # Accept-Language is 'es' then it will use the 'es-ar' translation.  We think
    # this is generally desirable (e.g. so someone can see YourNextMP in Spanish
    # if their browser asks for Spanish).
    languages = [
        l for l in LANGUAGES
        if exists(join(locale_paths[0], to_locale(l[0])))
    ]
    languages.append(('cy-gb', 'Welsh'))
    languages.append(('es-cr', 'Costa Rican Spanish'))

    # The language selection has been slightly complicated now that we
    # have two es- languages: es-ar and es-cr.  Chrome doesn't offer
    # Costa Rican Spanish as one of its language choices, so the best
    # you can do is choose 'Spanish - español'. (This might well be
    # the case in other browsers too.)  Since 'es-ar' comes first in
    # 'languages' after the preceding code, this means that someone
    # viewing the Costa Rica site with Chrome's preferred language set
    # to Spanish (i.e. with 'es' first in Accept-Language) will get
    # the Argentinian Spanish translations instead of Costa Rican
    # Spanish.  To get around this, look for the default language code
    # for the site, and if that's present, move it to the front of
    # 'languages'.  This should be generally helpful behaviour: the
    # default language code of the site should take precedence over
    # another language that happens to match based on the generic part
    # of the language code.
    language_code_index = next(
        (i for i, l in enumerate(languages) if l[0] == language_code),
        None
    )
    if language_code_index is not None:
        languages.insert(0, languages.pop(language_code_index))

    # Make sure the MEDIA_ROOT directory actually exists:
    media_root = conf.get('MEDIA_ROOT') or join(BASE_DIR, 'media')
    # Make sure that the MEDIA_ROOT and subdirectory for archived CSV
    # files exist:
    mkdir_p(join(media_root, 'csv-archives'))

    # Database
    # https://docs.djangoproject.com/en/1.6/ref/settings/#databases
    if conf.get('DATABASE_SYSTEM') == 'postgresql':
        databases = {
            'default': {
                'ENGINE':   'django.db.backends.postgresql_psycopg2',
                'NAME':     conf.get('YNMP_DB_NAME'),
                'USER':     conf.get('YNMP_DB_USER'),
                'PASSWORD': conf.get('YNMP_DB_PASS'),
                'HOST':     conf.get('YNMP_DB_HOST'),
                'PORT':     conf.get('YNMP_DB_PORT'),
            }
        }
    else:
        databases = {
            'default': {
                'ENGINE': 'django.db.backends.sqlite3',
                'NAME': join(BASE_DIR, 'db.sqlite3'),
            }
        }

    # Setup caches depending on DEBUG:
    if debug:
        cache = {'BACKEND': 'django.core.cache.backends.dummy.DummyCache'}
        cache_thumbnails = {'BACKEND': 'django.core.cache.backends.dummy.DummyCache'}
    else:
        cache = {
            'TIMEOUT': None, # cache keys never expire; we invalidate them
            'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
            'LOCATION': '127.0.0.1:11211',
            'KEY_PREFIX': databases['default']['NAME'],
        }
        cache_thumbnails = {
            'TIMEOUT': 60 * 60 * 24 * 2, # expire after two days
            'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
            'LOCATION': '127.0.0.1:11211',
            'KEY_PREFIX': databases['default']['NAME'] + "-thumbnails",
        }

    # Create a dictionary with these settings and other simpler ones:
    result = {
        'BASE_DIR': BASE_DIR,
        'ALLOWED_HOSTS': conf.get('ALLOWED_HOSTS'),
        'DEBUG': debug,
        'RUNNING_TESTS': tests,

        # Google analytics settings:
        'GOOGLE_ANALYTICS_ACCOUNT': conf.get('GOOGLE_ANALYTICS_ACCOUNT'),
        'USE_UNIVERSAL_ANALYTICS': conf.get('USE_UNIVERSAL_ANALYTICS', True),

        # The Twitter account referenced in the Twitter card data:
        'TWITTER_USERNAME': conf.get('TWITTER_USERNAME', ''),

        # The email address which is made public on the site for sending
        # support email to:
        'SUPPORT_EMAIL': conf['SUPPORT_EMAIL'],

        # Email addresses that error emails are sent to when DEBUG = False
        'ADMINS': conf['ADMINS'],

        # The From: address for all emails except error emails
        'DEFAULT_FROM_EMAIL': conf['DEFAULT_FROM_EMAIL'],

        # The From: address for error emails
        'SERVER_EMAIL': conf['SERVER_EMAIL'],

        # SECURITY WARNING: keep the secret key used in production secret!
        'SECRET_KEY': conf['SECRET_KEY'],

        'TEMPLATE_DEBUG': True,
        'TEMPLATE_DIRS': (
            join(BASE_DIR, 'mysite', 'templates'),
        ),
        'TEMPLATE_CONTEXT_PROCESSORS': TEMPLATE_CONTEXT_PROCESSORS + (
            # Required by allauth template tags
            "django.core.context_processors.request",
            # allauth specific context processors
            "allauth.account.context_processors.account",
            "allauth.socialaccount.context_processors.socialaccount",
            "django.contrib.messages.context_processors.messages",
            "mysite.context_processors.add_settings",
            "mysite.context_processors.election_date",
            "mysite.context_processors.add_group_permissions",
            "mysite.context_processors.add_notification_data",
            "mysite.context_processors.locale",
            "mysite.context_processors.add_site",
        ),

        'ELECTION_APP': election_app,
        'ELECTION_APP_FULLY_QUALIFIED': election_app_fully_qualified,

        # The Django applications in use:
        'INSTALLED_APPS': [
            'django.contrib.admin',
            'django.contrib.auth',
            'django.contrib.contenttypes',
            'django.contrib.humanize',
            'django.contrib.sessions',
            'django.contrib.messages',
            'django.contrib.staticfiles',
            'django.contrib.sites',
            'django_nose',
            'django_extensions',
            'pipeline',
            'statici18n',
            'sorl.thumbnail',
            'rest_framework',
            'rest_framework.authtoken',
            'images',
            'haystack',
            'elections',
            'popolo',
            election_app_fully_qualified,
            'candidates',
            'tasks',
            'alerts',
            'cached_counts',
            'moderation_queue',
            'auth_helpers',
            'debug_toolbar',
            'template_timings_panel',
            'official_documents',
            'results',
            'notifications',
            'allauth',
            'allauth.account',
            'allauth.socialaccount',
            'allauth.socialaccount.providers.google',
            'allauth.socialaccount.providers.facebook',
            'allauth.socialaccount.providers.twitter',
            'corsheaders',
            'crispy_forms',
        ],

        'SITE_ID': 1,

        'MIDDLEWARE_CLASSES': (
            'debug_toolbar.middleware.DebugToolbarMiddleware',
            'corsheaders.middleware.CorsMiddleware',
            'django.contrib.sessions.middleware.SessionMiddleware',
            'django.middleware.locale.LocaleMiddleware',
            'django.middleware.common.CommonMiddleware',
            'django.middleware.csrf.CsrfViewMiddleware',
            'django.contrib.auth.middleware.AuthenticationMiddleware',
            'candidates.middleware.CopyrightAssignmentMiddleware',
            'candidates.middleware.DisallowedUpdateMiddleware',
            'django.contrib.messages.middleware.MessageMiddleware',
            'django.middleware.clickjacking.XFrameOptionsMiddleware',
        ),

        # django-allauth settings:
        'AUTHENTICATION_BACKENDS': (
            # Needed to login by username in Django admin, regardless of `allauth`
            "django.contrib.auth.backends.ModelBackend",
            # `allauth` specific authentication methods, such as login by e-mail
            "allauth.account.auth_backends.AuthenticationBackend",
        ),
        'SOCIALACCOUNT_PROVIDERS': {
            'google': {'SCOPE': ['https://www.googleapis.com/auth/userinfo.profile'],
                       'AUTH_PARAMS': {'access_type': 'online'}},
            'facebook': {'SCOPE': ['email',]},
        },
        'LOGIN_REDIRECT_URL': '/',
        'ACCOUNT_EMAIL_VERIFICATION': 'mandatory',
        'ACCOUNT_EMAIL_REQUIRED': True,
        'ACCOUNT_USERNAME_REQUIRED': True,
        'SOCIALACCOUNT_AUTO_SIGNUP': True,

        'ROOT_URLCONF': 'mysite.urls',
        'WSGI_APPLICATION': 'mysite.wsgi.application',

        # Django Debug Toolbar settings:
        'DEBUG_TOOLBAR_PATCH_SETTINGS': False,
        'DEBUG_TOOLBAR_PANELS': [
            'debug_toolbar.panels.versions.VersionsPanel',
            'debug_toolbar.panels.timer.TimerPanel',
            'debug_toolbar.panels.settings.SettingsPanel',
            'debug_toolbar.panels.headers.HeadersPanel',
            'debug_toolbar.panels.request.RequestPanel',
            'debug_toolbar.panels.sql.SQLPanel',
            'debug_toolbar.panels.staticfiles.StaticFilesPanel',
            'debug_toolbar.panels.templates.TemplatesPanel',
            'debug_toolbar.panels.cache.CachePanel',
            'debug_toolbar.panels.signals.SignalsPanel',
            'debug_toolbar.panels.logging.LoggingPanel',
            'debug_toolbar.panels.redirects.RedirectsPanel',
            'template_timings_panel.panels.TemplateTimings.TemplateTimings',
        ],
        'INTERNAL_IPS': ['127.0.0.1'],

        # Language settings (calculated above):
        'LOCALE_PATHS': locale_paths,
        'LANGUAGES': languages,
        'LANGUAGE_CODE': language_code,
        'TIME_ZONE': conf.get('TIME_ZONE', 'Europe/London'),
        'USE_I18N': True,
        'USE_L10N': True,
        'USE_TZ': True,
        'DD_MM_DATE_FORMAT_PREFERRED': conf.get('DD_MM_DATE_FORMAT_PREFERRED', True),

        # The media and static file settings:
        'MEDIA_ROOT': media_root,
        'MEDIA_URL': '/media/',

        # Settings for staticfiles and Django pipeline:
        'STATIC_URL': '/static/',
        'STATIC_ROOT': join(BASE_DIR, 'static'),
        'STATICI18N_ROOT': join(BASE_DIR, 'mysite', 'static'),
        'STATICFILES_DIRS': (
            join(BASE_DIR, 'mysite', 'static'),
        ),
        'STATICFILES_FINDERS': (
            'django.contrib.staticfiles.finders.FileSystemFinder',
            'django.contrib.staticfiles.finders.AppDirectoriesFinder',
            'pipeline.finders.PipelineFinder',
        ),
        'PIPELINE': {
            'STYLESHEETS': {
                'image-review': {
                    'source_filenames': (
                        'moderation_queue/css/jquery.Jcrop.css',
                        'moderation_queue/css/crop.scss',
                    ),
                    'output_filename': 'css/image-review.css',
                },
                'official_documents': {
                    'source_filenames': (
                        'official_documents/css/official_documents.scss',
                    ),
                    'output_filename': 'css/official_documents.css',
                },
                'all': {
                    'source_filenames': (
                        'candidates/style.scss',
                        'cached_counts/style.scss',
                        'select2/select2.css',
                        'jquery/jquery-ui.css',
                        'jquery/jquery-ui.structure.css',
                        'jquery/jquery-ui.theme.css',
                        'moderation_queue/css/photo-upload.scss',
                    ),
                    'output_filename': 'css/all.css',
                }
            },
            'JAVASCRIPT': {
                'image-review': {
                    'source_filenames': (
                        'moderation_queue/js/jquery.color.js',
                        'moderation_queue/js/jquery.Jcrop.js',
                        'moderation_queue/js/crop.js',
                    ),
                    'output_filename': 'js/image-review.js',
                },
                'all': {
                    'source_filenames': (
                        'jquery/jquery-1.11.1.js',
                        'jquery/jquery-ui.js',
                        'foundation/js/foundation/foundation.js',
                        'foundation/js/foundation/foundation.equalizer.js',
                        'foundation/js/foundation/foundation.dropdown.js',
                        'foundation/js/foundation/foundation.tooltip.js',
                        'foundation/js/foundation/foundation.offcanvas.js',
                        'foundation/js/foundation/foundation.accordion.js',
                        'foundation/js/foundation/foundation.joyride.js',
                        'foundation/js/foundation/foundation.alert.js',
                        'foundation/js/foundation/foundation.topbar.js',
                        'foundation/js/foundation/foundation.reveal.js',
                        'foundation/js/foundation/foundation.slider.js',
                        'foundation/js/foundation/foundation.magellan.js',
                        'foundation/js/foundation/foundation.clearing.js',
                        'foundation/js/foundation/foundation.orbit.js',
                        'foundation/js/foundation/foundation.interchange.js',
                        'foundation/js/foundation/foundation.abide.js',
                        'foundation/js/foundation/foundation.tab.js',
                        'select2/select2.js',
                        'js/constituency.js',
                        'js/person_form.js',
                        'js/home_geolocation_form.js',
                        'js/versions.js',
                    ),
                    'output_filename': 'js/all.js'
                }
            },

            'COMPILERS': (
                'pipeline.compilers.sass.SASSCompiler',
            ),
            'SASS_BINARY': 'sassc',
            'CSS_COMPRESSOR': 'pipeline.compressors.yui.YUICompressor',
            'JS_COMPRESSOR': 'pipeline.compressors.yui.YUICompressor',
            # On some platforms this might be called "yuicompressor", so it may be
            # necessary to symlink it into your PATH as "yui-compressor".
            'YUI_BINARY': '/usr/bin/env yui-compressor',
        },


        'TEST_RUNNER': 'django_nose.NoseTestSuiteRunner',

        'SOURCE_HINTS': _(
            u"Please don't quote third-party candidate sites \u2014 "
            u"we prefer URLs of news stories or official candidate pages."
        ),

        # By default, cache successful results from MapIt for a day
        'MAPIT_CACHE_SECONDS': 86400,
        'DATABASES': databases,
        'CACHES': {
            'default': cache,
            'thumbnails': cache_thumbnails,
        },

        # sorl-thumbnail settings:
        'THUMBNAIL_CACHE': 'thumbnails',
        'THUMBNAIL_DEBUG': debug,

        # Settings for restricting user activity to reduce abuse:
        'RESTRICT_RENAMES': conf.get('RESTRICT_RENAMES'),
        'EDITS_ALLOWED': conf.get('EDITS_ALLOWED', True),

        # A bearer token for the Twitter API for mapping between
        # Twitter usernames and IDs.
        'TWITTER_APP_ONLY_BEARER_TOKEN': conf.get('TWITTER_APP_ONLY_BEARER_TOKEN'),

        # Django Rest Framework settings:
        'REST_FRAMEWORK': {
            'DEFAULT_PERMISSION_CLASSES': ('candidates.api_permissions.ReadOnly',),
            'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning',
            'DEFAULT_FILTER_BACKENDS': ('rest_framework.filters.DjangoFilterBackend',),
            'DEFAULT_RENDERER_CLASSES': (
                'rest_framework.renderers.JSONRenderer',
                'rest_framework_jsonp.renderers.JSONPRenderer',
                'rest_framework.renderers.BrowsableAPIRenderer',
            ),
            'PAGE_SIZE': 10,
        },

        # allow attaching extra data to notifications:
        'NOTIFICATIONS_USE_JSONFIELD': True,

        'HAYSTACK_SIGNAL_PROCESSOR': 'haystack.signals.RealtimeSignalProcessor',

        'HAYSTACK_CONNECTIONS': {
            'default': {
                'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine',
                'URL': 'http://127.0.0.1:9200/',
                'INDEX_NAME': '{0}_{1}'.format(conf.get('YNMP_DB_NAME'), conf.get('YNMP_DB_HOST')),
            },
        },

        # CORS config
        'CORS_ORIGIN_ALLOW_ALL': True,
        'CORS_URLS_REGEX': r'^/(api|upcoming-elections)/.*$',
        'CORS_ALLOW_METHODS': (
            'GET',
            'OPTIONS',
        ),
    }
    if not conf.get('NEW_ACCOUNTS_ALLOWED', True):
        result['ACCOUNT_ADAPTER'] = \
            'mysite.account_adapter.NoNewUsersAccountAdapter'
    result['CANDIDATES_REQUIRED_FOR_WEIGHTED_PARTY_LIST'] = \
        conf.get('CANDIDATES_REQUIRED_FOR_WEIGHTED_PARTY_LIST', 20)
    result['HOIST_ELECTED_CANDIDATES'] = \
        conf.get('HOIST_ELECTED_CANDIDATES', True)
    if tests:
        result['NOSE_ARGS'] = [
            '--nocapture',
            '--with-yanc',
            # There are problems with OpenCV on Travis, so don't even try to
            # import moderation_queue/faces.py
            '--ignore-files=faces',
        ]
        if election_app == 'example':
            result['NOSE_ARGS'].append('--with-doctest')
    else:
        # If we're not testing, use PipelineCachedStorage
        result['STATICFILES_STORAGE'] = \
            'pipeline.storage.PipelineCachedStorage'
    if conf.get('NGINX_SSL'):
        result['SECURE_PROXY_SSL_HEADER'] = ('HTTP_X_FORWARDED_PROTO', 'https')
        result['ACCOUNT_DEFAULT_HTTP_PROTOCOL'] = 'https'

    add_election_specific_settings(result, election_app_fully_qualified)

    result['RESULTS_FEATURE_ACTIVE'] = True

    result['DATE_FORMAT'] = conf.get('DATE_FORMAT', "jS E Y")

    return result
コード例 #26
0
        def _fetch(lang, fallback=None):

            global _translations

            res = _translations.get(lang, None)
            if res is not None:
                return res

            loc = to_locale(lang)

            def _translation(path):
                try:
                    if needs_compilation('django', path, lang):
                        compile_messages('django', path, lang)
                    t = gettext_module.translation('django', path, [loc],
                                                   DjangoTranslation)
                    t.set_language(lang)
                    return t
                except IOError:
                    return None

            res = _translation(globalpath)

            # We want to ensure that, for example, "en-gb" and "en-us" don't share
            # the same translation object (thus, merging en-us with a local update
            # doesn't affect en-gb), even though they will both use the core "en"
            # translation. So we have to subvert Python's internal gettext caching.
            base_lang = lambda x: x.split('-', 1)[0]
            if base_lang(lang) in [
                    base_lang(trans) for trans in list(_translations)
            ]:
                res._info = res._info.copy()
                res._catalog = res._catalog.copy()

            def _merge(path):
                t = _translation(path)
                if t is not None:
                    if res is None:
                        return t
                    else:
                        res.merge(t)
                return res

            for appname in reversed(settings.INSTALLED_APPS):
                app = import_module(appname)
                apppath = os.path.join(os.path.dirname(upath(app.__file__)),
                                       'locale')

                if os.path.isdir(apppath):
                    res = _merge(apppath)

            for localepath in reversed(settings.LOCALE_PATHS):
                if os.path.isdir(localepath):
                    res = _merge(localepath)

            if res is None:
                if fallback is not None:
                    res = fallback
                else:
                    return gettext_module.NullTranslations()
            _translations[lang] = res
            return res
コード例 #27
0
def normalize_language(language):
    return locale.locale_alias.get(to_locale(language, True))
コード例 #28
0
### Here be dragons.
# Django decided to require that ForeignKeys be unique.  That's generally
# reasonable, but Translations break that in their quest for all things unholy.
# Here we monkeypatch the error collector Django uses in validation to skip any
# messages generated by Translations. (Django #13284)
import re

from django.conf import settings
from django.core.management import validation
from django.utils.translation import trans_real

from jinja2.filters import do_dictsort

Parent = validation.ModelErrorCollection


class ModelErrorCollection(Parent):
    skip = ("Field 'id' under model '\w*Translation' must "
            "have a unique=True constraint.")

    def add(self, context, error):
        if not re.match(self.skip, error):
            Parent.add(self, context, error)

validation.ModelErrorCollection = ModelErrorCollection


LOCALES = [(trans_real.to_locale(k).replace('_', '-'), v) for k, v in
           do_dictsort(settings.LANGUAGES)]
コード例 #29
0
ファイル: testi18n.py プロジェクト: alexanbj/viktigpedia
    def setup_mofile_with_entry(self, poentry, language='en'):
        locale_location = join(settings.LOCALE_DIR, 'locale', language, 'LC_MESSAGES')
        pofile = polib.pofile(join(locale_location, 'django.po'))

        pofile.append(poentry)
        pofile.save()
        pofile.save_as_mofile(join(locale_location, 'django.mo'))
        
        jit_locale = gettext_module.translation('django', join(settings.LOCALE_DIR, 'locale'), [trans_real.to_locale(language)], trans_real.DjangoTranslation)
        jit_locale.set_language(language)
        
        locale = trans_real.translation(language)
        locale.merge(jit_locale)
コード例 #30
0
from django.conf import settings
from django.utils.translation import trans_real

from jinja2.filters import do_dictsort

LOCALES = [(trans_real.to_locale(k).replace('_', '-'), v)
           for k, v in do_dictsort(settings.LANGUAGES)]