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)
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)
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')
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')
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')
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`) """
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):
# 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
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. """
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
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: