Esempio n. 1
0
    def translator_singleton_thread_safety(self, fixture):
        """The SystemwideTranslator.get_instance() is this thread-safe."""
        SystemWideTranslator.instance = None  # To "reset" the singleton, else its __init__ will NEVER be called in this test
        SystemWideTranslator.get_instance().map_lock.acquire()
        self.lock_released = False

        def release_lock():
            SystemWideTranslator.get_instance().map_lock.release()
            self.lock_released = True

        timer = Timer(.1, release_lock)
        timer.start()
        _ = Translator('reahl-component')
        _.gettext('test string')
        timer.cancel()
        vassert(self.lock_released)
Esempio n. 2
0
    def translator_singleton(self, fixture):
        """Only one SystemwideTranslator is ever present per process."""

        SystemWideTranslator.instance = None  # To "reset" the singleton, else its __init__ will NEVER be called in this test

        with InitMonitor(SystemWideTranslator) as monitor:
            _ = Translator('reahl-component')
            _2 = Translator('reahl-component')

            _('test string')
            _.ngettext('thing', 'things', 1)
            _.ngettext('thing', 'things', 2)

            _2('test string')

        vassert(monitor.times_called == 1)
Esempio n. 3
0
def i18n_urls(fixture):
    """The current locale is determined by reading the first segment of the path. If the locale is not present in the
    path, web.default_url_locale is used."""
    _ = Translator('reahl-web')

    class I18nUI(UserInterface):
        def assemble(self):
            view = self.define_view('/aview', title=_('A View'))

    class MainUI(UserInterface):
        def assemble(self):
            self.define_page(HTML5Page)
            self.define_user_interface('/a_ui',
                                       I18nUI,
                                       IdentityDictionary(),
                                       name='test_ui')

    wsgi_app = fixture.new_wsgi_app(site_root=MainUI)
    browser = Browser(wsgi_app)

    browser.open('/a_ui/aview')
    vassert(browser.title == 'A View')

    browser.open('/af/a_ui/aview')
    vassert(browser.title == '\'n Oogpunt')

    fixture.context.config.web.default_url_locale = 'af'
    browser.open('/a_ui/aview')
    vassert(browser.title == '\'n Oogpunt')

    browser.open('/en_gb/a_ui/aview')
    vassert(browser.title == 'A View')
Esempio n. 4
0
    def formatting(self, fixture):
        """A Translator can be used to easily obtain the current locale for use
           by other i18n tools."""

        _ = Translator('reahl-component')

        date = datetime.date(2012, 1, 10)

        with LocaleContextStub() as context:
            context.test_locale = 'en_gb'
            vassert(_.current_locale == 'en_gb')
            actual = babel.dates.format_date(date,
                                             format='long',
                                             locale=_.current_locale)
            vassert(actual == '10 January 2012')

            context.test_locale = 'af'
            vassert(_.current_locale == 'af')
            actual = babel.dates.format_date(date,
                                             format='long',
                                             locale=_.current_locale)
            vassert(actual == '10 Januarie 2012')
Esempio n. 5
0
    def basic_usage(self, fixture):
        """A Translator for a particular component can translate messages for that component into
           the interface_locale on its current ExecutionContext."""

        _ = Translator(
            'reahl-component'
        )  # Will find its translations in the compiled messages of reahl-component

        with LocaleContextStub() as context:
            context.test_locale = 'en_gb'
            vassert(_('test string') == 'test string')
            vassert(_.gettext('test string') == 'test string')
            vassert(_.ngettext('thing', 'things', 1) == 'thing')
            vassert(_.ngettext('thing', 'things', 3) == 'things')

            context.test_locale = 'af'
            vassert(_('test string') == 'toets string')
            vassert(_.gettext('test string') == 'toets string')
            vassert(_.ngettext('thing', 'things', 1) == 'ding')
            vassert(_.ngettext('thing', 'things', 3) == 'goeters')
Esempio n. 6
0
import six

from copy import copy

from reahl.component.exceptions import ProgrammerError, arg_checks, IsInstance
from reahl.component.i18n import Translator

import reahl.web.ui
from reahl.web.ui import A, Article, Body, Br, Div, Footer, H, Head, Header, Img, \
    Li, Link, LiteralHTML, Meta, Nav, Ol, OptGroup, P, RunningOnBadge, Slot, Span, TextNode, \
    Title, Ul, WrappedInput, FieldSet, Legend, HTMLAttributeValueOption

from reahl.web.bootstrap.grid import Container, ColumnLayout, ResponsiveSize

_ = Translator('reahl-web')


class HTML5Page(reahl.web.ui.HTML5Page):
    """A web page that may be used as the page of a web application. It ensures that everything needed by
       the framework (linked CSS and JavaScript, etc) is available on such a page.

       .. admonition:: Styling
       
          Renders as an HTML5 page with customised <head> and an empty <body>.
       
       :param view: (See :class:`reahl.web.fw.Widget`)
       :keyword title: (See :class:`reahl.web.ui.HTML5Page`)
       :keyword css_id: (See :class:`reahl.web.ui.HTMLElement`)
       
    """
Esempio n. 7
0
from reahl.sqlalchemysupport import Session, Base

from reahl.web.fw import UserInterface, Widget
from reahl.web.layout import PageLayout
from reahl.web.bootstrap.ui import HTML5Page, Div, P, H
from reahl.web.bootstrap.forms import Form, TextInput, Button, FieldSet, FormLayout, ButtonLayout
from reahl.web.bootstrap.grid import ColumnLayout, ResponsiveSize, Container
from reahl.web.bootstrap.navs import Nav, PillLayout

from reahl.component.modelinterface import exposed, EmailField, Field, Event, Action
from reahl.component.i18n import Translator
import babel.dates 


_ = Translator('reahl-doc')


class AddressBookPage(HTML5Page):
    def __init__(self, view):
        super(AddressBookPage, self).__init__(view)
        self.use_layout(PageLayout(document_layout=Container()))
        contents_layout = ColumnLayout(('secondary', ResponsiveSize(md=3)),
                                       ('main', ResponsiveSize(md=9))).with_slots()
        self.layout.contents.use_layout(contents_layout)
        nav = Nav(view).use_layout(PillLayout(stacked=True))
        contents_layout.columns['secondary'].add_child(nav.with_languages())


class AddressBookUI(UserInterface):
    def assemble(self):
Esempio n. 8
0
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
"""Exceptions used throughout several Reahl components."""

from __future__ import print_function, unicode_literals, absolute_import, division
import six
import inspect
import sys
import functools

import wrapt
import inspect

from reahl.component.i18n import Translator
import collections

_ = Translator('reahl-component')


class DomainException(Exception):
    """Any exception indicating an application-specific error condition that 
       should be communicated to a user.

       :param commit: Set to True to indicate that the current database transaction 
                      should be committed. By default transactions are rolled back
                      when a DomainException is raised.
    """
    def __init__(self, commit=False):
        self.commit = commit


#    __hash__ = None
Esempio n. 9
0
import datetime

from sqlalchemy import Column, Table, Integer, ForeignKey, UnicodeText, String, DateTime, Boolean
from sqlalchemy.orm import relationship, backref

from reahl.component.i18n import Translator
from reahl.sqlalchemysupport import metadata, Session, PersistedField, Base
from reahl.component.modelinterface import Action
from reahl.component.modelinterface import CurrentUser
from reahl.component.modelinterface import Event
from reahl.component.modelinterface import exposed
from reahl.component.modelinterface import secured
from reahl.component.context import ExecutionContext
from reahl.domain.partymodel import Party

_ = Translator('reahl-domain')


class WorkflowInterface(object):
    """An object that @exposes a number of Events that user interface 
       Widgets can use to access the functionality of this module.
       
       Obtain an instance of WorkflowInterface by merely instantiating it.

       **@exposed events:**
       
        - take_task = Requests that the given task be reserved for the account currently logged in.
        - defer_task = Indicates that the current user will tend to the given task later.
        - go_to_task = Indicates that the current user is attending to a task previously deferred.
        - release_task = Releases the current task back into the que for other users to tend to.
    """
Esempio n. 10
0
from reahl.stubble import stubclass
from reahl.tofu import Fixture

from reahl.webdev.tools import DriverBrowser
from reahl.webdeclarative.webdeclarative import UserSession

from reahl.domain_dev.fixtures import PartyModelZooMixin
from reahl.domain.systemaccountmodel import LoginSession
from reahl.sqlalchemysupport import Session
from reahl.component.i18n import Translator
from reahl.component.py3compat import ascii_as_bytes_or_str
from reahl.web.fw import ReahlWSGIApplication, WebExecutionContext, UrlBoundView, UserInterface, Url, Widget
from reahl.web.layout import PageLayout, ColumnLayout
from reahl.web.ui import HTML5Page

_ = Translator('reahl-webdev')


@stubclass(ReahlWSGIApplication)
class ReahlWSGIApplicationStub(ReahlWSGIApplication):
    def add_reahl_static_files(self):  # To save time, this is costly...
        pass


class WebBasicsMixin(PartyModelZooMixin):
    def log_in(self,
               browser=None,
               session=None,
               system_account=None,
               stay_logged_in=False):
        session = session or self.session
Esempio n. 11
0
from sqlalchemy.ext.declarative import instrument_declarative, declarative_base, DeclarativeMeta
from sqlalchemy.exc import InvalidRequestError
from sqlalchemy import Column, Integer, ForeignKey
from alembic.migration import MigrationContext
from alembic.operations import Operations
from alembic.autogenerate import compare_metadata

from reahl.component.i18n import Translator
from reahl.component.eggs import ReahlEgg
from reahl.component.dbutils import ORMControl
from reahl.component.context import ExecutionContext, NoContextFound
from reahl.component.modelinterface import Field, IntegerConstraint
from reahl.component.exceptions import ProgrammerError
from reahl.component.config import Configuration

_ = Translator('reahl-sqlalchemysupport')


class SqlAlchemyConfig(Configuration):
    filename = 'sqlalchemy.config.py'
    config_key = 'sqlalchemy'

    def do_injections(self, config):
        if not isinstance(config.reahlsystem.orm_control, SqlAlchemyControl):
            config.reahlsystem.orm_control = SqlAlchemyControl(echo=False)


def reahl_scope():
    try:
        return ExecutionContext.get_context_id()
    except NoContextFound: