Esempio n. 1
0
    def _on_setup_widgets(self):
        """Hook.
        """
        from ._api import dispense_entity

        # List of items to process
        ol = htmler.Ol()
        for eid in self.attr('eids', self.attr('ids', [])):
            entity = dispense_entity(self.attr('model'), eid)
            self.add_widget(
                widget.input.Hidden(uid='eids-' + eid, name='eids', value=eid))
            ol.append_child(
                htmler.Li(entity.odm_ui_mass_action_entity_description()))
        self.add_widget(widget.static.HTML(uid='eids-text', em=ol))

        # Submit button
        submit_button = self.get_widget(
            'action_submit')  # type: widget.button.Submit
        submit_button.value = lang.t('odm_ui@continue')
        submit_button.icon = 'angle-double-right'

        # Cancel button
        self.add_widget(
            widget.button.Link(uid='action_cancel',
                               weight=100,
                               value=lang.t('odm_ui@cancel'),
                               href=self.referer or self.redirect
                               or router.base_url(),
                               icon='fa fas fa-ban',
                               form_area='footer'))
Esempio n. 2
0
    def _on_setup_widgets(self):
        e_type = self.attr('e_type')
        eids = self.attr('eids', [])
        ol = htmler.Ol()
        for eid in eids:
            if e_type == 'role':
                ol.append_child(htmler.Li(auth.get_role(uid=eid).name))
            elif e_type == 'user':
                ol.append_child(htmler.Li(auth.get_user(uid=eid).login))

        self.add_widget(
            widget.static.Text(
                uid='confirmation_text',
                text=lang.t('auth_admin@delete_{}_confirmation'.format(
                    self.attr('e_type'))),
            ))

        self.add_widget(widget.static.HTML(
            uid='uids_text',
            em=ol,
        ))

        self.add_widget(
            widget.button.Link(uid='action_cancel',
                               weight=100,
                               form_area='footer',
                               href=self.referer or self.redirect
                               or router.base_url(),
                               value=lang.t('auth_admin@cancel'),
                               icon='fa fas fa-ban'))

        self.submit_button.color = 'btn btn-danger'
        self.submit_button.icon = 'fa fas fa-trash'
        self.submit_button.value = lang.t('auth_admin@delete')
Esempio n. 3
0
    def exec(self) -> Union[str, http.RedirectResponse]:
        # Redirect to the base URL if user is already authenticated
        if not auth.get_current_user().is_anonymous:
            return self.redirect(self.arg('__redirect', router.base_url()))

        # Determine driver's name from argument or get default
        try:
            driver_name = self.arg('driver', _api.get_driver().name)
        except auth.error.DriverNotRegistered:
            raise self.not_found()

        rule_name = self.arg('_pytsite_router_rule_name')
        if 'sign_in' in rule_name:
            form_type = 'sign-in'
            form = _api.sign_in_form(self.request, driver_name)

        elif 'sign_up' in rule_name:
            # Check if sign up is enabled
            if not auth.is_sign_up_enabled():
                raise self.not_found()

            form_type = 'sign-up'
            form = _api.sign_up_form(self.request, driver_name)

        elif 'restore_account' in rule_name:
            form_type = 'restore-account'
            form = _api.restore_account_form(self.request, driver_name)
            form.redirect = router.base_url()

        else:
            raise ValueError('Unsupported form type')

        if not form.redirect:
            form.redirect = router.base_url()

        metatag.t_set('title', form.title)

        tpl_args = {
            'driver': driver_name,
            'form_type': form_type,
            'form': form,
        }

        try:
            return router.call('auth_ui_form', tpl_args)
        except routing.error.RuleNotFound:
            return tpl.render('auth_ui/form', tpl_args)
Esempio n. 4
0
    def _on_setup_widgets(self):
        from ._api import dispense_entity

        model = self.attr('model')
        eid = self.attr('eid')

        # Setting up form's widgets through entity hook and global event
        entity = dispense_entity(model, eid)
        entity.odm_ui_m_form_setup_widgets(self)
        events.fire('odm_ui@m_form_setup_widgets.{}'.format(model),
                    frm=self,
                    entity=entity)

        if self.current_step == 1:
            # Entity model
            self.add_widget(
                widget.input.Hidden(
                    uid='model',
                    value=model,
                    form_area='hidden',
                ))

            # Entity ID
            self.add_widget(
                widget.input.Hidden(
                    uid='eid',
                    value=eid,
                    form_area='hidden',
                ))

            # Entity ref
            self.add_widget(
                widget.input.Hidden(
                    uid='ref',
                    value=entity.ref if not entity.is_new else None,
                    form_area='hidden',
                ))

        # Cancel button URL
        cancel_href = self.redirect
        if not cancel_href or cancel_href == 'ENTITY_VIEW':
            if self.referer != self.location and self.referer:
                cancel_href = self.referer
            elif not entity.is_new and entity.odm_ui_view_url():
                cancel_href = entity.odm_ui_view_url()
            else:
                cancel_href = router.base_url()

        # Cancel button
        self.add_widget(
            widget.button.Link(
                uid='action_cancel_' + str(self.current_step),
                weight=150,
                value=lang.t('odm_ui@cancel'),
                icon='fa fas fa-fw fa-remove fa-times',
                href=cancel_href,
                form_area='footer',
            ))
Esempio n. 5
0
    def exec(self):
        """Unsubscribe from content digest
        """
        s = _odm.dispense('content_digest_subscriber', self.arg('sid'))
        if s:
            s.f_set('enabled', False).save()
            _router.session().add_success_message(
                _lang.t('content_digest@unsubscription_successful'))

        return self.redirect(_router.base_url())
Esempio n. 6
0
    def exec(self):
        # Check for error from Google
        error = self.arg('error')
        if error == 'access_denied':
            raise self.forbidden(
                lang.t('auth_ui_google@user_declined_authorization'))

        # Check for code from Google
        code = self.arg('code')
        if code:
            # Restore flow from session
            flow = router.session().get(
                'google_oauth2_flow')  # type: OAuth2WebServerFlow
            if not flow:
                raise self.forbidden('Cannot retrieve stored OAuth2 flow')

            # Exchange code to credentials
            credentials = flow.step2_exchange(code)
            user = auth.get_current_user()
            user.set_option('google_oauth2_credentials', credentials.to_json())
            user.save()

            final_redirect = router.session().get(
                'google_oauth2_final_redirect', router.base_url())

            router.session().pop('google_oauth2_flow')
            router.session().pop('google_oauth2_final_redirect')

            return self.redirect(final_redirect)

        else:
            # Request new code from Google
            scope = self.args.pop('scope')  # type: str
            if scope and ',' in scope:
                scope = scope.split(',')
            flow = auth_google.create_oauth2_flow(
                scope, router.current_url(True, query=dict(self.args)))
            router.session()['google_oauth2_flow'] = flow
            router.session()['google_oauth2_final_redirect'] = self.args.pop(
                '__redirect', router.base_url())

            return self.redirect(flow.step1_get_authorize_url())
Esempio n. 7
0
    def exec(self):
        try:
            # Search for user
            user = next(
                auth.find_users(
                    query.Query(query.Eq('confirmation_hash',
                                         self.arg('code')))))
        except StopIteration:
            # No user found, redirect to sign in URL
            return self.redirect(_api.sign_in_url(redirect=router.base_url()))

        try:
            auth.switch_user_to_system()
            user.confirmation_hash = None
            if user.status == auth.USER_STATUS_WAITING:
                user.status = auth.get_new_user_status()
            user.save()
        finally:
            auth.restore_user()

        router.session().add_success_message(
            lang.t('auth_ui@registration_confirm_success'))

        return self.redirect(_api.sign_in_url(redirect=router.base_url()))
Esempio n. 8
0
    def exec(self):
        auth.sign_out(auth.get_current_user())

        return self.redirect(self.arg('__redirect', router.base_url()))
Esempio n. 9
0
    def _on_setup_widgets(self):
        role_uid = self.attr('role_uid')
        role = auth.get_role(uid=role_uid) if role_uid != '0' else None

        self.add_widget(widget.input.Text(
            uid='name',
            value=role.name if role else None,
            label=self.t('name'),
            required=True,
            enabled=role.name not in ('anonymous', 'user') if role else True,
        ))
        self.add_rule('name', auth.validation.AuthEntityFieldUnique(
            e_type='role',
            field_name='name',
            exclude_uids=role.uid if role else None,
        ))

        self.add_widget(widget.input.Text(
            uid='description',
            value=role.description if role else None,
            label=self.t('description'),
            required=True,
            enabled=role.name not in ('anonymous', 'user') if role else True,
        ))

        # Permissions tabs
        perms_tabs = widget.select.Tabs(
            uid='permissions',
            label=self.t('permissions')
        )

        # Permissions tabs content
        for g_name, g_desc in sorted(permissions.get_permission_groups().items(), key=lambda x: x[0]):
            if g_name == 'auth':
                continue

            perms = permissions.get_permissions(g_name)
            if not perms:
                continue

            # Tab
            tab_id = 'permissions-' + g_name
            perms_tabs.add_tab(tab_id, lang.t(g_desc))

            # Tab's content
            perms_tabs.add_widget(widget.select.Checkboxes(
                uid='permission-checkboxes-' + tab_id,
                name='permissions',
                items=[(p[0], lang.t(p[1])) for p in perms],
                value=role.permissions if role else [],
            ), tab_id)

        self.add_widget(perms_tabs)

        # "Cancel" button
        self.add_widget(widget.button.Link(
            uid='action_cancel',
            weight=100,
            form_area='footer',
            icon='fa fas fa-fw fa-ban',
            value=self.t('cancel'),
            href=self.referer or self.redirect or router.base_url(),
        ))
Esempio n. 10
0
    def _on_setup_widgets(self):
        user_uid = self.attr('user_uid')
        user = auth.get_user(uid=user_uid) if user_uid != '0' else None
        c_user = auth.get_current_user()

        row_1 = self.add_widget(widget.container.Card(
            uid='row_1',
            header=self.t('registration_info'),
            body_css='row',
        ))

        row_1_left = row_1.append_child(widget.container.Container(
            uid='row_1_left',
            css='col-xs-12 col-12 col-sm-4 col-md-2',
        ))

        row_1_center = row_1.append_child(widget.container.Container(
            uid='row_1_center',
            css='col-xs-12 col-12 col-sm-4 col-md-5',
        ))

        row_1_right = row_1.append_child(widget.container.Container(
            uid='row_1_right',
            css='col-xs-12 col-12 col-sm-4 col-md-5',
        ))

        # Picture
        row_1_left.append_child(file_ui.widget.ImagesUpload(
            uid='picture',
            value=user.picture if user else None,
            max_file_size=3,
            label=self.t('photo'),
        ))

        # Login
        row_1_center.append_child(widget.input.Email(
            uid='login',
            value=user.login if user else None,
            label=self.t('email'),
            required=True,
            enabled=c_user.is_admin,
            max_length=auth.LOGIN_MAX_LENGTH,
        ))
        self.add_rule('login', auth.validation.AuthEntityFieldUnique(
            e_type='user',
            field_name='login',
            exclude_uids=user.uid if user else None,
        ))

        # Nickname
        row_1_center.append_child(widget.input.Text(
            uid='nickname',
            value=user.nickname if user else None,
            label=self.t('nickname'),
            required=True,
            max_length=auth.NICKNAME_MAX_LENGTH,
        ))
        self.add_rules('nickname', (
            auth.user_nickname_rule,
            auth.validation.AuthEntityFieldUnique(
                e_type='user',
                field_name='nickname',
                exclude_uids=user.uid if user else None,
            )
        ))

        # Birth date
        row_1_center.append_child(widget.select.DateTime(
            uid='birth_date',
            value=user.birth_date if user else None,
            label=self.t('birth_date'),
            timepicker=False,
        ))

        # Gender
        row_1_center.append_child(widget.select.Select(
            uid='gender',
            value=user.gender if user else None,
            label=self.t('gender'),
            items=[
                ('m', self.t('male')),
                ('f', self.t('female')),
            ]
        ))

        # First name
        row_1_right.append_child(widget.input.Text(
            uid='first_name',
            value=user.first_name if user else None,
            label=self.t('first_name'),
            required=True,
            max_length=auth.FIRST_NAME_MAX_LENGTH,
        ))

        # Middle name
        row_1_right.append_child(widget.input.Text(
            uid='middle_name',
            value=user.middle_name if user else None,
            label=self.t('middle_name'),
            max_length=auth.MIDDLE_NAME_MAX_LENGTH,
        ))

        # Last name
        row_1_right.append_child(widget.input.Text(
            uid='last_name',
            value=user.last_name if user else None,
            label=self.t('last_name'),
            max_length=auth.LAST_NAME_MAX_LENGTH,
        ))

        # Position
        row_1_right.append_child(widget.input.Text(
            uid='position',
            value=user.position if user else None,
            label=self.t('position'),
            max_length=auth.USER_POSITION_MAX_LENGTH,
        ))

        # Row 2
        row_2 = self.add_widget(widget.container.Container(
            uid='row_2',
            body_css='row',
        ))

        # Row 2 left
        row_2_left = row_2.append_child(widget.container.Container(
            uid='row_2_left',
            css='col-xs-12 col-12 col-sm-6 col-lg-8',
        ))

        # Contact info
        contact = row_2_left.append_child(widget.container.Card(
            uid='contact',
            body_css='row',
            header=self.t('contact_info'),
        ))

        # Contact info left
        contact_left = contact.append_child(widget.container.Container(
            uid='contact_left',
            css='col-xs-12 col-12 col-lg-6'
        ))

        # Country
        contact_left.append_child(widget.input.Text(
            uid='country',
            value=user.country if user else None,
            label=self.t('country'),
            max_length=auth.COUNTRY_MAX_LENGTH,
        ))

        # Province
        contact_left.append_child(widget.input.Text(
            uid='province',
            value=user.province if user else None,
            label=self.t('province'),
            max_length=auth.PROVINCE_MAX_LENGTH,
        ))

        # City
        contact_left.append_child(widget.input.Text(
            uid='city',
            value=user.city if user else None,
            label=self.t('city'),
            max_length=auth.CITY_MAX_LENGTH,
        ))

        # District
        contact_left.append_child(widget.input.Text(
            uid='district',
            value=user.district if user else None,
            label=self.t('district'),
            max_length=auth.DISTRICT_MAX_LENGTH,
        ))

        # Contact info right
        contact_right = contact.append_child(widget.container.Container(
            uid='contact_right',
            css='col-xs-12 col-12 col-lg-6'
        ))

        # Street
        contact_right.append_child(widget.input.Text(
            uid='street',
            value=user.street if user else None,
            label=self.t('street'),
            max_length=auth.STREET_MAX_LENGTH,
        ))

        # House number
        contact_right.append_child(widget.input.Text(
            uid='building',
            value=user.building if user else None,
            label=self.t('building'),
            max_length=auth.BUILDING_MAX_LENGTH,
        ))

        # Apt number
        contact_right.append_child(widget.input.Text(
            uid='apt_number',
            value=user.apt_number if user else None,
            label=self.t('apt_number'),
            max_length=auth.APT_NUMBER_MAX_LENGTH,
        ))

        # Phone
        contact_right.append_child(widget.input.Text(
            uid='phone',
            value=user.phone if user else None,
            label=self.t('phone'),
            max_length=auth.PHONE_MAX_LENGTH,
        ))

        # URLs
        contact.append_child(widget.input.StringList(
            uid='urls',
            value=user.urls if user else None,
            label=self.t('social_links'),
            max_rows=10,
            add_btn_label=self.t('add_link'),
            css='col-xs-12 col-12',
        ))
        self.add_rule('urls', validation.rule.Url())

        # Row 2 right
        row_2_right = row_2.append_child(widget.container.Container(
            uid='row_2_right',
            css='col-xs-12 col-12 col-sm-6 col-lg-4',
        ))

        # Cover picture card
        cover_picture_card = row_2_right.append_child(widget.container.Card(
            uid='cover_picture_card',
            header=self.t('cover_picture'),
        ))

        # Cover picture
        cover_picture_card.append_child(file_ui.widget.ImagesUpload(
            uid='cover_picture',
            thumb_width=1200,
            thumb_height=450,
            max_file_size=5,
            value=user.cover_picture if user else None,
        ))

        # Security card
        security = row_2_right.append_child(widget.container.Card(
            uid='security',
            header=self.t('security'),
        ))

        # User account confirmed
        if c_user.is_admin and auth.is_sign_up_confirmation_required():
            security.append_child(widget.select.Checkbox(
                uid='is_confirmed',
                value=user.is_confirmed if (user and user.is_confirmed) else None,
                label=self.t('user_account_is_confirmed'),
            ))

        # Profile is public
        security.append_child(widget.select.Checkbox(
            uid='is_public',
            value=user.is_public if user else None,
            label=self.t('this_is_public_profile'),
        ))

        # New password
        security.append_child(widget.input.Password(
            uid='password',
            label=self.t('new_password'),
            autocomplete='new-password',
        ))

        # New password confirm
        security.append_child(widget.input.Password(
            uid='password_confirm',
            label=self.t('new_password_confirmation'),
            autocomplete='new-password',
        ))

        # Row 3
        row_3 = self.add_widget(widget.container.Card(
            uid='row_3',
            header=self.t('about_yourself'),
        ))

        # Description
        row_3.append_child(widget.input.TextArea(
            uid='description',
            value=user.description if user else '',
            max_length=auth.USER_DESCRIPTION_MAX_LENGTH,
        ))

        # Row 4
        if c_user.is_admin:
            admin = self.add_widget(widget.container.Card(
                uid='admin',
                header=self.t('administration'),
                body_css='row',
            ))

            admin.append_child(widget.select.Select(
                uid='status',
                value=user.status if user else auth.get_new_user_status(),
                label=self.t('status'),
                items=auth.get_user_statuses(),
                required=True,
                append_none_item=False,
                css='col-xs-12 col-12 col-md-3'
            ))

            admin.append_child(_widget.RolesCheckboxes(
                uid='roles',
                value=user.roles if user else [auth.get_role(r) for r in auth.get_new_user_roles()],
                label=self.t('roles'),
                css='col-xs-12 col-12 col-md-3'
            ))

        # "Cancel" button
        self.add_widget(widget.button.Link(
            uid='action_cancel',
            weight=100,
            form_area='footer',
            icon='fa fas fa-fw fa-ban',
            value=self.t('cancel'),
            href=self.referer or self.redirect or router.base_url(),
        ))
Esempio n. 11
0
    def exec(self):
        # Delayed import to prevent circular dependency
        from . import _api

        # Checking if the model is registered
        model = self.arg('model')
        if not _api.is_model_registered(model):
            raise self.not_found()

        # Getting finder
        f = _api.find(model)

        # Breadcrumb
        breadcrumb = widget.select.Breadcrumb('content-index-breadcrumb')
        breadcrumb.append_item(lang.t('content@home_page'), router.base_url())

        # Filter by term
        term_field_name = self.arg('term_field')
        term_alias = self.arg('term_alias')
        term = None
        if term_field_name and f.mock.has_field(term_field_name):
            term_field = f.mock.get_field(
                term_field_name)  # type: odm.field.Ref
            if term_alias and term_field.model:
                for term_model in term_field.model:
                    term = taxonomy.find(term_model).eq('alias',
                                                        term_alias).first()
                    if term:
                        self.args['term'] = term
                        if isinstance(f.mock.fields[term_field_name],
                                      odm.field.Ref):
                            f.eq(term_field_name, term)
                        elif isinstance(f.mock.fields[term_field_name],
                                        odm.field.RefsList):
                            f.inc(term_field_name, term)
                        metatag.t_set('title', term.title)
                        breadcrumb.append_item(term.title)
                    else:
                        raise self.not_found()
            else:
                raise self.not_found()

        # Filter by author
        author_nickname = self.arg('author')
        if author_nickname:
            try:
                author = auth.get_user(nickname=author_nickname)
                f.eq('author', author.uid)
                self.args['author'] = author
                metatag.t_set(
                    'title',
                    lang.t('content@articles_of_author',
                           {'name': author.first_last_name}))

                if term:
                    breadcrumb.pop_item()
                    breadcrumb.append_item(
                        term.title,
                        router.rule_url(
                            'content@index', {
                                'model': model,
                                'term_field': term_field_name,
                                'term_alias': term_alias,
                            }))

                breadcrumb.append_item(author.first_last_name)
            except auth.error.UserNotFound:
                raise self.not_found()

        self.args.update({
            'finder': f,
            'breadcrumb': breadcrumb,
        })

        try:
            # Call a controller provided by application
            return router.call('content_index', self.args)

        except routing.error.RuleNotFound:
            # Render a template provided by application
            return tpl.render('content/index', self.args)
Esempio n. 12
0
    def exec(self):
        from . import _api

        model = self.arg('model')
        entity = _api.find(model, status='*', check_publish_time=False) \
            .eq('_id', self.arg('eid')) \
            .first()  # type: _model.ContentWithURL

        # Check entity existence
        if not entity:
            raise self.not_found()

        # Check permissions
        if not entity.odm_auth_check_entity_permissions(CONTENT_PERM_VIEW):
            raise self.not_found()

        # Show non-published entities only to authors and users who can edit or delete them
        c_user = auth.get_current_user()
        if (entity.has_field('publish_time') and entity.publish_time > datetime.now()) or \
                (entity.has_field('status') and entity.status in (CONTENT_STATUS_UNPUBLISHED, CONTENT_STATUS_WAITING)):
            if not (entity.author == c_user
                    or entity.odm_auth_check_entity_permissions(
                        [PERM_MODIFY, PERM_DELETE])):
                raise self.not_found()

        # Show warnings about unpublished entities
        if entity.has_field(
                'publish_time') and entity.publish_time > datetime.now():
            router.session().add_warning_message(
                lang.t('content@content_warning_future_publish_time'))
        if entity.has_field('status') and entity.status in (
                CONTENT_STATUS_UNPUBLISHED, CONTENT_STATUS_WAITING):
            router.session().add_warning_message(
                lang.t('content@content_status_warning_{}'.format(
                    entity.status)))

        # Breadcrumb
        breadcrumb = widget.select.Breadcrumb('content-index-breadcrumb')
        breadcrumb.append_item(lang.t('content@home_page'), router.base_url())
        entity.content_breadcrumb(breadcrumb)

        # Meta title
        if entity.has_field('title'):
            title = entity.title
            metatag.t_set('title', title)
            metatag.t_set('og:title', title)
            metatag.t_set('twitter:title', title)

        # Meta description
        if entity.has_field('description'):
            description = entity.f_get('description')
            metatag.t_set('description', description)
            metatag.t_set('og:description', description)
            metatag.t_set('twitter:description', description)

        # Meta keywords
        if entity.has_field('tags'):
            metatag.t_set('keywords', entity.f_get('tags', as_string=True))

        # Meta image
        if entity.has_field('images') and entity.images:
            metatag.t_set('twitter:card', 'summary_large_image')
            image_w = 900
            image_h = 500
            image_url = entity.images[0].get_url(width=image_w, height=image_h)
            metatag.t_set('og:image', image_url)
            metatag.t_set('og:image:width', str(image_w))
            metatag.t_set('og:image:height', str(image_h))
            metatag.t_set('twitter:image', image_url)
        else:
            metatag.t_set('twitter:card', 'summary')

        # Various metatags
        metatag.t_set('og:type', 'article')
        metatag.t_set('og:url', entity.url)
        metatag.t_set('article:publisher', entity.url)

        # 'Author' metatag
        if entity.has_field('author') and entity.author:
            metatag.t_set('author', entity.author.first_last_name)
            metatag.t_set('article:author', entity.author.first_last_name)

        # Alternate languages URLs
        for lng in lang.langs(False):
            f_name = 'localization_' + lng
            if entity.has_field(f_name) and entity.f_get(f_name):
                hreflang.put(lng, entity.f_get(f_name).url)
            else:
                hreflang.remove(lng)

        # Update args
        self.args.update({
            'entity': entity,
            'breadcrumb': breadcrumb,
        })

        # Notify listeners
        events.fire('content@view', entity=entity)

        try:
            # Call a controller provided by application
            return router.call('content_view', self.args)

        except routing.error.RuleNotFound:
            # Render a template provided by application
            return tpl.render('content/view', self.args)
Esempio n. 13
0
def generate_rss(model: str, filename: str, lng: str = '*',
                 finder_setup: Callable[[odm.SingleModelFinder], None] = None,
                 item_setup: Callable[[feed.xml.Serializable, Content], None] = None, length: int = 20):
    """Generate RSS feeds
    """
    # Setup finder
    finder = find(model, language=lng)
    if finder_setup:
        finder_setup(finder)

    # Preparing output directory
    output_dir = path.join(reg.get('paths.static'), 'feed')
    if not path.exists(output_dir):
        makedirs(output_dir, 0o755, True)

    # Create generator
    content_settings = reg.get('content')
    parser = feed.rss.Parser()

    # Get <channel> element
    channel = parser.get_children('channel')[0]

    # Channel title
    channel.append_child(feed.rss.em.Title(content_settings.get('home_title_' + lng) or 'UNTITLED'))

    # Channel description
    channel.append_child(feed.rss.em.Description(content_settings.get('home_description_' + lng)))

    # Channel link
    channel.append_child(feed.rss.em.Link(router.base_url()))

    # Channel language
    channel.append_child(feed.rss.em.Language(lng))

    # Channel logo
    logo_url = router.url(reg.get('content.rss_logo_url', 'assets/app/img/logo-rss.png'))
    channel.append_child(feed.rss.yandex.Logo(logo_url))
    square_logo_url = router.url(reg.get('content.rss_square_logo_url', 'assets/app/img/logo-rss-square.png'))
    channel.append_child(feed.rss.yandex.Logo(square_logo_url, square=True))

    # Append channel's items
    for entity in finder.get(length):
        item = feed.rss.em.Item()
        try:
            item.append_child(feed.rss.em.Title(entity.title))
            item.append_child(feed.rss.em.Link(entity.url))
            item.append_child(feed.rss.em.PdaLink(entity.url))
            item.append_child(feed.rss.em.Description(entity.description if entity.description else entity.title))
            item.append_child(feed.rss.em.PubDate(entity.publish_time))
            item.append_child(feed.rss.em.Author('{} ({})'.format(entity.author.login, entity.author.first_last_name)))
        except odm.error.FieldNotDefined:
            pass

        # Section
        if entity.has_field('section'):
            item.append_child(feed.rss.em.Category(entity.section.title))

        # Tags
        if entity.has_field('tags'):
            for tag in entity.tags:
                item.append_child(feed.rss.pytsite.Tag(tag.title))

        # Images
        if entity.has_field('images') and entity.images:
            # Attaching all the images as enclosures
            for img in entity.images:
                item.append_child(feed.rss.em.Enclosure(url=img.get_url(), length=img.length, type=img.mime))

        # Video links
        if entity.has_field('video_links') and entity.video_links:
            m_group = item.append_child(feed.rss.media.Group())
            for link_url in entity.video_links:
                m_group.add_widget(feed.rss.media.Player(url=link_url))

        # Body
        if entity.has_field('body'):
            item.append_child(feed.rss.yandex.FullText(entity.f_get('body', process_tags=False, remove_tags=True)))
            item.append_child(feed.rss.content.Encoded(entity.f_get('body', process_tags=False, remove_tags=True)))
            item.append_child(feed.rss.pytsite.FullText(entity.f_get('body', process_tags=False)))

        if item_setup:
            item_setup(item, entity)

        channel.append_child(item)

    # Write feed content
    out_path = path.join(output_dir, '{}-{}.xml'.format(filename, lng))
    with open(out_path, 'wt', encoding='utf-8') as f:
        f.write(parser.generate())

    logger.info("RSS feed successfully written to '{}'.".format(out_path))
Esempio n. 14
0
def _generate_sitemap():
    """Generate content sitemap
    """
    global _sitemap_generation_works

    if _sitemap_generation_works:
        raise RuntimeError('Sitemap generation is still in progress')

    _sitemap_generation_works = True
    logger.info('Sitemap generation start.')

    output_dir = path.join(reg.get('paths.static'), 'sitemap')
    if path.exists(output_dir):
        rmtree(output_dir)
    makedirs(output_dir, 0o755, True)

    sitemap_index = sitemap.Index()
    links_per_file = 50000
    loop_count = 1
    loop_links = 1
    sm = sitemap.Sitemap()
    sm.add_url(router.base_url(), datetime.now(), 'always', 1)
    for lng in lang.langs():
        for model in reg.get('content.sitemap_models', ()):
            logger.info(
                "Sitemap generation started for model '{}', language '{}'".
                format(model, lang.lang_title(lng)))

            for entity in _api.find(model,
                                    language=lng):  # type: ContentWithURL
                sm.add_url(entity.url, entity.publish_time)
                loop_links += 1

                # Flush sitemap
                if loop_links >= links_per_file:
                    loop_count += 1
                    loop_links = 0
                    sitemap_path = sm.write(
                        path.join(output_dir, 'data-%02d.xml' % loop_count),
                        True)
                    logger.info(
                        "'{}' successfully written with {} links".format(
                            sitemap_path, loop_links))
                    sitemap_index.add_url(
                        router.url('/sitemap/{}'.format(
                            path.basename(sitemap_path))))
                    del sm
                    sm = sitemap.Sitemap()

    # If non-flushed sitemap exist
    if len(sm):
        sitemap_path = sm.write(
            path.join(output_dir, 'data-%02d.xml' % loop_count), True)
        logger.info("'{}' successfully written with {} links.".format(
            sitemap_path, loop_links))
        sitemap_index.add_url(
            router.url('/sitemap/{}'.format(path.basename(sitemap_path))))

    if len(sitemap_index):
        sitemap_index_path = sitemap_index.write(
            path.join(output_dir, 'index.xml'))
        logger.info("'{}' successfully written.".format(sitemap_index_path))

    logger.info('Sitemap generation stop.')
    _sitemap_generation_works = False