Esempio n. 1
0
    def __init__(self, model, request):
        super().__init__(model, request)
        self.request.include('frameworks')
        self.request.include('chosen')
        self.request.include('common')

        self.pages = TranslatablePageCollection(self.request.session)
Esempio n. 2
0
    def execute(self):
        from onegov.swissvotes.collections import TranslatablePageCollection

        pages = TranslatablePageCollection(self.session)
        subject = pages.by_id(self.subject_id)
        target = pages.by_id(self.target_id)
        if subject and target and subject != target:
            pages.move(subject=subject,
                       target=target,
                       direction=getattr(MoveDirection, self.direction))
Esempio n. 3
0
def test_layout_add_page(session):
    request = DummyRequest()
    model = TranslatablePageCollection(session)

    layout = AddPageLayout(model, request)
    assert layout.title == "Add page"
    assert layout.editbar_links == []
    assert path(layout.breadcrumbs) == 'DummyPrincipal/#'

    # Log in as editor
    request.roles = ['editor']
    layout = AddPageLayout(model, request)
    assert layout.editbar_links == []

    # Log in as admin
    request.roles = ['admin']
    layout = AddPageLayout(model, request)
    assert layout.editbar_links == []
Esempio n. 4
0
def add_order_column_to_pagess(context):
    if context.has_column('swissvotes_page', 'order'):
        context.operations.drop_column('swissvotes_page', 'order')
    if not context.has_column('swissvotes_page', 'order'):
        context.operations.add_column('swissvotes_page',
                                      Column('order', Integer, default=2**16))

        default = ('home', 'disclaimer', 'imprint', 'data-protection',
                   'dataset', 'about', 'contact')
        pages = TranslatablePageCollection(context.app.session())
        for id in default:
            pages.setdefault(id)
        for order, id in enumerate(default):
            pages.by_id(id).order = order
        for page in pages.query().filter(TranslatablePage.id.notin_(default)):
            order += 1
            page.order = order
Esempio n. 5
0
def view_home(self, request):
    """ The home page. """

    page = TranslatablePageCollection(request.session).setdefault('home')
    return request.redirect(request.link(page))
Esempio n. 6
0
def test_page_form(session):
    # Test apply / update
    pages = TranslatablePageCollection(session)
    page = pages.add(
        id='page',
        title_translations={
            'de_CH': 'Titel',
            'en_US': 'Title'
        },
        content_translations={
            'de_CH': 'Inhalt',
            'en_US': 'Content'
        },
    )

    form = PageForm()

    # .. de_CH
    form.apply_model(page)
    assert form.title.data == 'Titel'
    assert form.content.data == 'Inhalt'

    form.title.data = 'A'
    form.content.data = 'B'

    form.update_model(page)

    assert page.title_translations == {'de_CH': 'A', 'en_US': 'Title'}
    assert page.content_translations == {'de_CH': 'B', 'en_US': 'Content'}
    assert page.id == 'page'

    # ... en_US
    page.session_manager.current_locale = 'en_US'

    form.apply_model(page)
    assert form.title.data == 'Title'
    assert form.content.data == 'Content'

    form.title.data = 'C'
    form.content.data = 'D'

    form.update_model(page)

    assert page.title_translations == {'de_CH': 'A', 'en_US': 'C'}
    assert page.content_translations == {'de_CH': 'B', 'en_US': 'D'}
    assert page.id == 'page'

    # ... fr_CH
    page.session_manager.current_locale = 'fr_CH'

    form.apply_model(page)
    assert form.title.data == 'A'
    assert form.content.data == 'B'

    form.title.data = 'E'
    form.content.data = 'F'

    form.update_model(page)

    assert page.title_translations == {
        'de_CH': 'A',
        'en_US': 'C',
        'fr_CH': 'E'
    }
    assert page.content_translations == {
        'de_CH': 'B',
        'en_US': 'D',
        'fr_CH': 'F'
    }
    assert page.id == 'page'

    # Test ID generation
    form = PageForm()
    form.request = DummyRequest(session, DummyPrincipal())

    assert form.id == 'page-1'

    form.title.data = ' Über uns '
    assert form.id == 'uber-uns'

    form.update_model(page)
    assert page.id == 'page'

    page = TranslatablePage()
    form.update_model(page)
    assert page.id == 'uber-uns'

    # Test validation
    form = PageForm()
    assert not form.validate()

    form = PageForm(DummyPostData({'title': 'X', 'content': 'Y'}))
    assert form.validate()
Esempio n. 7
0
def test_layout_default(swissvotes_app):
    session = swissvotes_app.session()

    request = DummyRequest()
    request.app = swissvotes_app
    request.session = session
    model = None

    layout = DefaultLayout(model, request)
    assert layout.title == ""
    assert layout.editbar_links == []
    assert path(layout.breadcrumbs) == 'Principal'
    assert layout.static_path == 'Principal/static'
    assert layout.app_version
    assert layout.locales == [('de_CH', 'de', 'Deutsch', 'SiteLocale/'),
                              ('fr_CH', 'fr', 'Français', 'SiteLocale/'),
                              ('en_US', 'en', 'English', 'SiteLocale/')]
    assert layout.request.includes == ['frameworks', 'chosen', 'common']
    assert list(hrefs(layout.top_navigation)) == ['SwissVoteCollection/']
    assert layout.homepage_url == 'Principal/'
    assert layout.votes_url == 'SwissVoteCollection/'
    assert layout.login_url == 'Auth/login'
    assert layout.logout_url is None
    assert layout.move_page_url_template == (
        'TranslatablePageMove/?csrf-token=x')
    assert path([layout.disclaimer_link]) == 'TranslatablePage'
    layout.disclaimer_link.text == 'disclaimer'
    assert path([layout.imprint_link]) == 'TranslatablePage'
    layout.imprint_link.text == 'imprint'
    assert path([layout.data_protection_link]) == 'TranslatablePage'
    layout.data_protection_link.text == 'data-protection'

    # Login
    request.is_logged_in = True
    layout = DefaultLayout(model, request)
    assert layout.login_url is None
    assert layout.logout_url == 'Auth/logout'

    # Add some pages
    pages = TranslatablePageCollection(session)
    pages.add(id='dataset',
              title_translations={
                  'de_CH': 'Datensatz',
                  'en_US': 'Dataset'
              },
              content_translations={
                  'de_CH': 'Datensatz',
                  'en_US': 'Dataset'
              })
    pages.add(id='about',
              title_translations={
                  'de_CH': 'Über uns',
                  'en_US': 'About'
              },
              content_translations={
                  'de_CH': 'Über uns',
                  'en_US': 'About'
              })
    pages.add(id='contact',
              title_translations={
                  'de_CH': 'Kontakt',
                  'en_US': 'Contact'
              },
              content_translations={
                  'de_CH': 'Kontakt',
                  'en_US': 'Contact'
              })
    assert [item.text for item in layout.top_navigation
            ] == ['Votes', 'Datensatz', 'Über uns', 'Kontakt']

    assert layout.format_bfs_number(Decimal('100')) == '100'
    assert layout.format_bfs_number(Decimal('100.1')) == '100.1'
    assert layout.format_bfs_number(Decimal('100.12')) == '100.1'

    assert layout.format_procedure_number(None) == ''
    assert layout.format_procedure_number(Decimal('0')) == '0'
    assert layout.format_procedure_number(Decimal('00.087')) == '00.087'
    assert layout.format_procedure_number(Decimal('0.087')) == '00.087'
    assert layout.format_procedure_number(Decimal('02.060')) == '02.060'
    assert layout.format_procedure_number(Decimal('2.06')) == '02.060'
    assert layout.format_procedure_number(Decimal('16.479')) == '16.479'
    assert layout.format_procedure_number(Decimal('1859')) == '1859'
    assert layout.format_procedure_number(Decimal('1859.000')) == '1859'
    assert layout.format_procedure_number(Decimal('9309')) == '9309'
    assert layout.format_procedure_number(Decimal('9309.0')) == '9309'
    assert layout.format_procedure_number(Decimal('12239')) == '12239'
    assert layout.format_procedure_number(Decimal('12239.0')) == '12239'
    assert layout.format_policy_areas(SwissVote()) == ''

    vote = SwissVote(
        descriptor_1_level_1=Decimal('4'),
        descriptor_2_level_1=Decimal('8'),
        descriptor_2_level_2=Decimal('8.3'),
        descriptor_3_level_1=Decimal('10'),
        descriptor_3_level_2=Decimal('10.3'),
        descriptor_3_level_3=Decimal('10.33'),
    )
    assert layout.format_policy_areas(vote) == (
        '<span title="d-1-10 &gt; d-2-103 &gt; d-3-1033">d-1-10</span>,<br>'
        '<span title="d-1-4">d-1-4</span>,<br>'
        '<span title="d-1-8 &gt; d-2-83">d-1-8</span>')

    vote = SwissVote(
        descriptor_2_level_1=Decimal('10'),
        descriptor_2_level_2=Decimal('10.3'),
        descriptor_3_level_1=Decimal('10'),
        descriptor_3_level_2=Decimal('10.3'),
        descriptor_3_level_3=Decimal('10.33'),
    )
    assert layout.format_policy_areas(vote) == (
        '<span title="d-1-10 &gt; d-2-103 &#10;&#10;'
        'd-1-10 &gt; d-2-103 &gt; d-3-1033">d-1-10</span>')
Esempio n. 8
0
class DefaultLayout(ChameleonLayout):

    day_long_format = 'skeleton:MMMMd'
    date_long_format = 'long'
    datetime_long_format = 'medium'

    def __init__(self, model, request):
        super().__init__(model, request)
        self.request.include('frameworks')
        self.request.include('chosen')
        self.request.include('common')

        self.pages = TranslatablePageCollection(self.request.session)

    @cached_property
    def title(self):
        return ""

    @cached_property
    def top_navigation(self):
        result = [Link(_("Votes"), self.votes_url)]
        for page in self.pages.query():
            if page.id not in self.request.app.static_content_pages:
                result.append(
                    Link(
                        page.title,
                        self.request.link(page),
                        sortable_id=page.id,
                    ))
        return result

    @cached_property
    def editbar_links(self):
        return []

    @cached_property
    def breadcrumbs(self):
        return [Link(_("Homepage"), self.homepage_url)]

    @cached_property
    def app_version(self):
        return self.app.settings.core.theme.version

    @cached_property
    def static_path(self):
        return self.request.link(self.app.principal, 'static')

    @cached_property
    def homepage_url(self):
        return self.request.link(self.app.principal)

    @cached_property
    def disclaimer_link(self):
        page = self.pages.setdefault('disclaimer')
        return Link(page.title, self.request.link(page))

    @cached_property
    def imprint_link(self):
        page = self.pages.setdefault('imprint')
        return Link(page.title, self.request.link(page))

    @cached_property
    def data_protection_link(self):
        page = self.pages.setdefault('data-protection')
        return Link(page.title, self.request.link(page))

    @cached_property
    def votes_url(self):
        return self.request.link(SwissVoteCollection(self.request.app))

    @cached_property
    def login_url(self):
        if not self.request.is_logged_in:
            return self.request.link(Auth.from_request(self.request,
                                                       to=self.homepage_url),
                                     name='login')

    @cached_property
    def logout_url(self):
        if self.request.is_logged_in:
            return self.request.link(Auth.from_request(self.request,
                                                       to=self.homepage_url),
                                     name='logout')

    @cached_property
    def move_page_url_template(self):
        return self.csrf_protected_url(
            self.request.link(TranslatablePageMove.for_url_template()))

    @cached_property
    def locales(self):
        result = []
        assert self.app.locales == {'de_CH', 'fr_CH', 'en_US'}
        for locale_code in ('de_CH', 'fr_CH', 'en_US'):
            locale = Locale.parse(locale_code)
            result.append(
                (locale_code, locale.language,
                 locale.get_language_name().capitalize(),
                 self.request.link(SiteLocale(locale_code, self.request.url))))
        return result

    def format_policy_areas(self, vote):
        paths = [area.label_path for area in vote.policy_areas]
        paths = groupbylist(sorted(paths), key=lambda x: x[0])

        translate = self.request.translate
        return ",<br>".join([
            "<span title=\"{}\">{}</span>".format(
                " &#10;&#10;".join([
                    " &gt; ".join([translate(part) for part in title])
                    for title in titles
                ]), translate(value)) for value, titles in paths
        ])

    def format_bfs_number(self, number, decimal_places=None):
        """ Hide the decimal places if there are none (simple votes). """

        decimal_places = 0 if number.to_integral_value() == number else 1
        return self.format_number(number, decimal_places)

    def format_number(self, number, decimal_places=None, padding=''):
        """ Takes the given numer and formats it according to locale.

        If the number is an integer, the default decimal places are 0,
        otherwise 2.

        Overwrites parent class to use "." instead of "," for fr_CH locale
        as would be returned by babel.

        """
        if number is None:
            return ''

        if decimal_places is None:
            if isinstance(number, numbers.Integral):
                decimal_places = 0
            else:
                decimal_places = 2

        locale = self.request.locale
        # Fixes using "," for french locale instead of "." as for german
        if locale == 'fr_CH':
            locale = 'de_CH'
        decimal, group = self.number_symbols(locale)
        result = '{{:{},.{}f}}'.format(padding, decimal_places).format(number)
        return result.translate({ord(','): group, ord('.'): decimal})

    def format_procedure_number(self, number):
        """ There are two different formats for the procedure number: a plain
        sequence number before 1974/75 and a sequence number prefixed with the
        year.

        The first one is in the range (1, ~12500) and stored as decimal without
        a decimal place. The second one is in the range (~74000, n) and stored
        as decimal / 1000.
        """
        if number is None:
            return ''
        if number.to_integral_value() == number:
            return str(number.to_integral_value())
        return self.format_number(number, 3, '06')
Esempio n. 9
0
def get_page(app, id):
    return TranslatablePageCollection(app.session()).by_id(id)
Esempio n. 10
0
def get_pages(app):
    return TranslatablePageCollection(app.session())