def test_i18n_urls(web_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.""" _ = Catalogue('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 = web_fixture.new_wsgi_app(site_root=MainUI) browser = Browser(wsgi_app) browser.open('/a_ui/aview') assert browser.title == 'A View' browser.open('/af/a_ui/aview') assert browser.title == '\'n Oogpunt' web_fixture.config.web.default_url_locale = 'af' browser.open('/a_ui/aview') assert browser.title == '\'n Oogpunt' browser.open('/en_gb/a_ui/aview') assert browser.title == 'A View'
def test_translator_singleton(): """Only one SystemWideCatalogue is ever present per process.""" SystemWideCatalogue.instance = None # To "reset" the singleton, else its __init__ will NEVER be called in this test with InitMonitor(SystemWideCatalogue) as monitor: _ = Catalogue('reahl-component') _2 = Catalogue('reahl-component') context = LocaleContextStub().install() _('test string') _.ngettext('thing', 'things', 1) _.ngettext('thing', 'things', 2) _2('test string') assert monitor.times_called == 1
def test_translator_singleton_thread_safety(): """The SystemWideCatalogue.get_instance() is this thread-safe.""" SystemWideCatalogue.instance = None # To "reset" the singleton, else its __init__ will NEVER be called in this test SystemWideCatalogue.get_instance().map_lock.acquire() saved_state = EmptyStub() saved_state.lock_released = False def release_lock(): SystemWideCatalogue.get_instance().map_lock.release() saved_state.lock_released = True timer = Timer(.1, release_lock) timer.start() context = LocaleContextStub().install() _ = Catalogue('reahl-component') _.gettext('test string') timer.cancel() assert saved_state.lock_released
def test_basic_usage(): """A Catalogue for a particular component can translate messages for that component into the interface_locale on its current ExecutionContext.""" _ = Catalogue( 'reahl-component' ) # Will find its translations in the compiled messages of reahl-component context = LocaleContextStub().install() context.test_locale = 'en_gb' assert _('test string') == 'test string' assert _.gettext('test string') == 'test string' assert _.ngettext('thing', 'things', 1) == 'thing' assert _.ngettext('thing', 'things', 3) == 'things' context.test_locale = 'af' assert _('test string') == 'toets string' assert _.gettext('test string') == 'toets string' assert _.ngettext('thing', 'things', 1) == 'ding' assert _.ngettext('thing', 'things', 3) == 'goeters'
def test_formatting(): """A Catalogue can be used to easily obtain the current locale for use by other i18n tools.""" _ = Catalogue('reahl-component') date = datetime.date(2012, 1, 10) context = LocaleContextStub().install() context.test_locale = 'en_gb' assert _.current_locale == 'en_gb' actual = babel.dates.format_date(date, format='long', locale=_.current_locale) assert actual == '10 January 2012' context.test_locale = 'af' assert _.current_locale == 'af' actual = babel.dates.format_date(date, format='long', locale=_.current_locale) assert actual == '10 Januarie 2012'
""" from reahl.component.exceptions import ProgrammerError from reahl.component.i18n import Catalogue from reahl.component.modelinterface import exposed import reahl.web.ui # These are imported here for convenience so they can be imported from reahl.web.bootstrap.ui: from reahl.web.ui import A, Article, Body, Br, Div, Footer, H, Head, Header, Img, \ Li, Link, LiteralHTML, Meta, Nav, Ol, OptGroup, P, Small, RunningOnBadge, Slot, Span, TextNode, \ Title, Ul, WrappedInput, FieldSet, Legend, HTMLAttributeValueOption, Widget, HTMLElement, HTMLWidget, \ Br, Hr _ = Catalogue('reahl-web') class Alert(Div): """A message box meant to alert the user of some message. See also: :class:`Badge`. :param view: (See :class:`reahl.web.fw.Widget`) :param message_or_widget: Message text or a Widget to display inside the Alert. :param severity: One of 'primary', 'secondary', 'success', 'info', 'warning', 'danger', 'light', 'dark' to indicate the color scheme for the Alert. """ def __init__(self, view, message_or_widget, severity): super().__init__(view)
# Copyright 2013-2020 Reahl Software Services (Pty) Ltd. All rights reserved. # # This file is part of Reahl. # # Reahl is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as # published by the Free Software Foundation; version 3 of the License. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. from sqlalchemy import Column, Integer from reahl.sqlalchemysupport import Base from reahl.component.i18n import Catalogue _ = Catalogue('reahl-domain') class Party(Base): """A Party is any legal entity which the system may keep track of.""" __tablename__ = 'party' id = Column(Integer, primary_key=True)
from reahl.web.fw import UserInterface, Widget from reahl.web.bootstrap.page import HTML5Page from reahl.web.bootstrap.ui import Div, H, P, FieldSet from reahl.web.bootstrap.navbar import Navbar, ResponsiveLayout from reahl.web.bootstrap.navs import Nav from reahl.web.bootstrap.grid import Container from reahl.web.bootstrap.forms import TextInput, Form, FormLayout, Button, ButtonLayout from reahl.component.modelinterface import exposed, Field, EmailField, Action, Event from reahl.sqlalchemysupport import Session, Base from reahl.component.i18n import Catalogue from sqlalchemy import Column, Integer, UnicodeText, Date import babel.dates # Declare a Catalogue for your component _ = Catalogue('reahl-doc') class AddressBookPage(HTML5Page): def __init__(self, view): super(AddressBookPage, self).__init__(view) self.body.use_layout(Container()) layout = ResponsiveLayout('md', colour_theme='dark', bg_scheme='primary') navbar = Navbar(view, css_id='my_nav').use_layout(layout) navbar.layout.set_brand_text(_('Address book')) navbar.layout.add(Nav(view).with_languages()) self.body.add_child(navbar)
from reahl.domain.systemaccountmodel import LoginSession from reahl.component.i18n import Catalogue from reahl.component.py3compat import ascii_as_bytes_or_str from reahl.component.context import ExecutionContext from reahl.web.fw import ReahlWSGIApplication, UrlBoundView, UserInterface, Url, Widget from reahl.web.ui import HTML5Page, Slot, Div from reahl.web.layout import Layout from reahl.web.egg import WebConfig from reahl.dev.fixtures import ReahlSystemFixture from reahl.webdev.fixtures import WebServerFixture from reahl.sqlalchemysupport_dev.fixtures import SqlAlchemyFixture from reahl.domain_dev.fixtures import PartyAccountFixture _ = Catalogue('reahl-webdev') @stubclass(ReahlWSGIApplication) class ReahlWSGIApplicationStub(ReahlWSGIApplication): def add_reahl_static_files(self): static_files = self.config.web.frontend_libraries.packaged_files() static_files_no_js = [ packaged_file for packaged_file in static_files if not packaged_file.relative_name.endswith('.js') ] return self.define_static_files('/static', static_files_no_js) class BasicPageLayout(Layout): def __init__(self, slots=['main', 'footer']):
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 Catalogue 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 _ = Catalogue('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:
def as_user_message(self): # To ensure this module can be imported at a very low level from reahl.component.i18n import Catalogue _ = Catalogue('reahl-component') return self.message if self.message else _('An error occurred: %s' % self.__class__.__name__)
""" from reahl.component.exceptions import ProgrammerError from reahl.component.i18n import Catalogue from reahl.component.context import ExecutionContext from reahl.sqlalchemysupport import PersistedField from reahl.web.fw import UserInterface, UrlBoundView, Detour, ViewPreCondition from reahl.web.ui import HTMLWidget from reahl.web.bootstrap.ui import P, Div, Ul, Li, H from reahl.web.bootstrap.forms import Form, Button, FormLayout from reahl.domain.workflowmodel import Inbox, Task, WorkflowInterface from reahl.domain.systemaccountmodel import LoginSession _ = Catalogue('reahl-domainui') class TaskBox(Li): def __init__(self, view, task): super().__init__(view) self.task = task self.add_child(P(view, text=self.task.title)) form = self.add_child(Form(view, 'task_%s' % task.id)) form.use_layout(FormLayout()) form.layout.add_input( Button(form, self.user_interface.workflow_interface.events.take_task. with_arguments(task=self.task), style='primary'), hide_label=True)
from __future__ import print_function, unicode_literals, absolute_import, division import six import sys import functools import wrapt import inspect from reahl.component.i18n import Catalogue if six.PY2: from collections import Callable else: from collections.abc import Callable _ = Catalogue('reahl-component') class DomainException(Exception): """Any exception indicating an application-specific error condition that should be communicated to a user. :keyword 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. :keyword message: Optional error message. """ def __init__(self, commit=False, message=None, detail_messages=[]): super(DomainException, self).__init__(message) self.commit = commit self.message = message