示例#1
0
    def action(self, resource, context, form):
        email = form['email'].strip()

        # 1. Make the user, or get it
        results = context.database.search(format='user', email=email)
        if len(results) == 0:
            # New user
            user = context.root.make_user()
            for name in self.fields:
                field = self.get_field(name)
                if field and getattr(field, 'persistent', True):
                    self.set_value(user, context, name, form)

            user.update_pending_key()
            email_id = 'user-ask-for-confirmation'
        else:
            # User already registered
            user = results.get_resources().next()
            email_id = 'register-already-registered'

        # 2. Send email
        send_email(email_id, context, email, user=user)

        # 3. Show message
        message = MSG(
            u'<div id="registration-end-msg">'
            u'An email has been sent to you, to finish the registration '
            u'process follow the instructions detailed in it.</div>')
        return message.gettext().encode('utf-8')
示例#2
0
文件: event.py 项目: matrixorz/ikaaro
 def get_before_namespace(self, resource, context):
     # Set organizer infos in ${before}
     owner = resource.get_owner()
     owner = resource.get_resource(owner).get_title()
     owner_msg = MSG(u'<p id="event-owner">Created by <em>{owner}</em></p>')
     owner_msg = owner_msg.gettext(owner=owner).encode('utf-8')
     return XMLParser(owner_msg)
示例#3
0
文件: user_views.py 项目: hforge/shop
    def get_namespace(self, resource, context):
        proxy = super(Shop_UserSendConfirmation, self)
        namespace = proxy.get_namespace(resource, context)

        confirm_msg = MSG(u"""Fill this form to receive a mail with the link
                              to activate your account""")
        namespace['required_msg'] = (list(XMLParser(confirm_msg.gettext().encode('utf8'))) +
                                     list(XMLParser('<br/>')) +
                                     list(namespace['required_msg']))
        return namespace
示例#4
0
文件: autoadd.py 项目: nkhine/ikaaro
    def get_title(self, context):
        if self.title is not None:
            return self.title

        cls = self._resource_class
        if cls:
            class_title = cls.class_title.gettext()
            title = MSG(u'Add {class_title}')
            return title.gettext(class_title=class_title)

        return MSG(u'Add resource').gettext()
示例#5
0
文件: page_views.py 项目: hforge/wiki
 def GET(self, resource, context):
     try:
         from lpod.rst2odt import rst2odt
     except ImportError:
         msg = MSG(u'<p>Please install <a href="{href}">{name}</a> '
                   u'for Python on the server.</p>')
         msg = msg.gettext(href='http://lpod-project.org/', name='LpOD')
         return msg.encode('utf_8')
     # Just to ignore pyflakes warning
     rst2odt
     proxy = super(WikiPage_ToODT, self)
     return proxy.GET(resource, context)
示例#6
0
文件: page_views.py 项目: hforge/wiki
    def get_options(cls):
        context = get_context()
        container = context.resource.parent

        options = [{'name': '', 'value': MSG(u"lpoD default template")}]
        for resource in container.get_resources():
            if not resource.class_id in ALLOWED_FORMATS:
                continue
            msg = MSG(u'{title} (<a href="{link}">view</a>)')
            msg = msg.gettext(title=resource.get_title(),
                    link=context.get_link(resource)).encode('utf_8')
            options.append({'name': resource.name, 'value': XMLParser(msg)})
        return options
示例#7
0
文件: deposit.py 项目: hforge/shop
 def get_payment_way_description(self, context, total_amount):
     msg = MSG(u"Pay {percent}% of {original_amount} now ({amount})")
     percent = self.get_property('percent')
     if self.get_property('pay_tax'):
         total_amount = total_amount['with_tax'].split(' ')[0]
         total_amount = decimal(total_amount)
     else:
         total_amount = total_amount['without_tax'].split(' ')[0]
         total_amount = decimal(total_amount)
     amount = total_amount * (percent / decimal('100.0'))
     msg = msg.gettext(percent=percent,
                       original_amount=format_price(total_amount),
                       amount=format_price(amount))
     return list(XMLParser(msg.encode('utf-8'))) + self.get_property('data')
示例#8
0
文件: cc.py 项目: nicolasderam/ikaaro
 def get_message(self, context, language=None):
     """This function must return the tuple (subject, body)
     """
     # Subject
     subject = MSG(u'[{title}] has been modified')
     subject = subject.gettext(title=self.get_title(), language=language)
     # Body
     message = MSG(u'DO NOT REPLY TO THIS EMAIL. To view modifications '
                   u'please visit:\n{resource_uri}')
     uri = context.get_link(self)
     uri = str(context.uri.resolve(uri))
     uri += '/;commit_log'
     body = message.gettext(resource_uri=uri, language=language)
     # And return
     return subject, body
示例#9
0
文件: crm_views.py 项目: hforge/crm
    def action_postpone(self, resource, context, form):
        postpone = form['postpone']
        alert = datetime.combine(postpone, time(9, 0))
        pattern = MSG(u'<a href="{path}">{title}</a>', format='replace')
        missions = []
        for path in form['ids']:
            mission = resource.get_resource(path)
            mission.set_property('crm_m_alert', alert)
            missions.append(pattern.gettext(path=path,
                title=mission.get_title()))

        postpone = context.format_date(postpone)
        missions = u", ".join(missions)
        context.message = MSG_MISSIONS_POSTPONED(postpone=postpone,
                missions=missions)
示例#10
0
文件: skin.py 项目: hforge/shop
 def get_template_title(self, context):
     here = context.resource
     # XXX Confidentiality problems
     if isinstance(here, ShopUser):
         return here.get_public_title()
     # In the website
     site_root = here.get_site_root()
     if site_root is here:
         return site_root.get_title()
     # Somewhere else
     if site_root.get_property('hide_website_title_on_meta_title'):
         message = MSG(u"{here_title}")
     else:
         message = MSG(u"{here_title} > {root_title}")
     return message.gettext(root_title=site_root.get_title(),
                            here_title=here.get_title())
示例#11
0
文件: messages.py 项目: kennym/itools
 def __call__(self, **kw):
     if not kw:
         # Also skipping stl calls
         raise AttributeError, 'missing variables to substitute'
     message = MSG.gettext(self, language=None, **kw)
     # Send a translated copy of this instance
     return self.__class__(message, domain=self.domain)
示例#12
0
文件: utils.py 项目: hforge/itws
def get_linked_resources_message(resource, context, state='public'):
    # Customize message if webpage uses private/pending resources
    referenced_resources = list(get_linked_resources(resource))
    if len(referenced_resources) == 0:
        return None

    message = MSG(u'This {title} uses pending/private resources '
                  u'please go to '
                  u'<a href="{path}/;backlinks">backlinks interface</a>.')
    path = context.get_link(resource)
    path = XMLContent.encode(path)
    class_title = resource.class_title.gettext()
    message = message.gettext(title=class_title,
                              path=path).encode('utf8')
    message = XHTMLBody.decode(message)
    # Return custom message
    return message
示例#13
0
    def _register(self, resource, context, email):
        site_root = context.site_root
        # Add the user
        users = site_root.get_resource('users')
        user = users.set_user(email, None)
        # Set the role to 'Member'
        default_role = site_root.class_roles[1]
        site_root.set_user_role(user.name, default_role)

        # Send confirmation email
        user.send_confirmation(context, email)

        # Bring the user to the login form
        message = MSG(
            u"An email has been sent to you, to finish the registration "
            u"process follow the instructions detailed in it.")
        return message.gettext().encode('utf-8')
示例#14
0
 def get_items(self, context):
     unit = self.get_property("unit")
     criterium = self.get_property("criterium")
     uri = context.uri
     options = []
     get_record_value = self.handler.get_record_value
     # Get values
     values = [(None, None)]
     for record in self.handler.get_records():
         min_value = get_record_value(record, "min")
         max_value = get_record_value(record, "max")
         values.append((min_value, max_value))
     for value in values:
         min_value, max_value = value
         min_value_q = int(min_value * 100) if min_value else None
         max_value_q = int(max_value * 100) if max_value else None
         value = (min_value_q, max_value_q)
         name = IntegerRange.encode(value)
         if min_value is None and max_value:
             title = MSG(u"Less than {max_value} {unit}")
         elif min_value and max_value:
             title = MSG(u"From {min_value} to {max_value} {unit}")
         elif max_value is None and min_value:
             title = MSG(u"More than {min_value} {unit}")
         else:
             title = MSG(u"All")
             name = None
             value = None
         selected = context.query.get(criterium) == value
         kw = {criterium: name, "batch_start": 0}
         uri = uri.replace(**kw)
         title = title.gettext(min_value=min_value, max_value=max_value, unit=unit)
         options.append(
             {
                 "name": name,
                 "criterium": criterium,
                 "query": RangeQuery(criterium, min_value_q, max_value_q),
                 "selected": selected,
                 "uri": uri,
                 "css": "selected" if selected else None,
                 "title": title,
             }
         )
     return options
示例#15
0
文件: user_views.py 项目: hforge/shop
    def get_namespace(self, resource, context):
        proxy = super(Shop_UserConfirmRegistration, self)
        namespace = proxy.get_namespace(resource, context)

        confirm_msg = MSG(u"""
          You have not yet confirmed your registration.<br/>
          To confirm it, please click on the confirmation link
          included on the registration confirmation email.<br/>
          You can also fill your email address and your activation
          key (received on the mail) in the following form.<br/>
          If you havn't received your registration key,
          <a href=";send_confirmation_view">
            you can receive it again by clicking here.
          </a>
          """)
        namespace['required_msg'] = (list(XMLParser(confirm_msg.gettext().encode('utf8'))) +
                                     list(XMLParser('<br/>')) +
                                     list(namespace['required_msg']))
        return namespace
示例#16
0
文件: event.py 项目: matrixorz/ikaaro
    def get_message(self, context, language=None):
        # Subject
        title=self.get_title()
        subject = MSG(u'The event "{title}" has been modified')
        subject = subject.gettext(title=title, language=language)
        # Body
        message = MSG(u'DO NOT REPLY TO THIS EMAIL.\n\n'
                      u'The user "{last_author}" has made some modifications '
                      u'to the event "{title}".\n'
                      u'To view these modifications please visit:\n'
                      u'{resource_uri}\n')
        uri = context.get_link(self)
        uri = str(context.uri.resolve(uri))
        uri += '/;edit'
        last_author = self.get_value('last_author')
        last_author = context.root.get_user_title(last_author)
        body = message.gettext(last_author=last_author, resource_uri=uri,
                               title=title, language=language)

        # And return
        return subject, body
示例#17
0
文件: skins.py 项目: matrixorz/ikaaro
    def get_template_title(self, context):
        """Return the title to give to the template document.
        """
        here = context.resource
        root = context.root
        root_title = root.get_title()

        # Choose the template
        if not root.is_allowed_to_view(context.user, here):
            return ''
        elif root is here:
            template = MSG(u"{view_title} - {root_title}")
            here_title = None
        else:
            template = MSG(u"{here_title} - {view_title} - {root_title}")
            here_title = here.get_title()

        # The view
        view_title = context.view.get_title(context)

        # Ok
        return template.gettext(root_title=root_title, here_title=here_title,
                                view_title=view_title)
示例#18
0
    def get_email_html(self, context, web_version=False):
        header = []
        if web_version is False:
            header = MSG(u"""
                <center>
                  <span style="font-size:10px;font-weight:bold;
                    font-family:Arial,Helvetica,sans-serif;">
                    <a href="{page_uri}" target="_blank">Click here</a>
                    to see this news on you browser
                  </span>
                </center>
                """).gettext(page_uri=self.get_newsletter_uri(context))
            header = HTMLParser(header.encode('utf-8'))
        footer = MSG(u"""
            <center>
              <span style="font-size:10px;font-weight:bold;
                font-family:Arial,Helvetica,sans-serif;">
                <a href="{unsub_uri}" target="_blank">Click here</a>
                to unsubscribe
              </span>
            </center>
            """).gettext(unsub_uri=self.get_unsubscribe_uri(context))
        footer = HTMLParser(footer.encode('utf-8'))

        handler = self.handler
        body = handler.get_body()
        events = (handler.events[:body.start + 1]
                  + header
                  + handler.events[body.start + 1:body.end]
                  + footer
                  + handler.events[body.end:])
        # Rewrite link with scheme and autority
        prefix = self.get_site_root().get_pathto(self)
        html_data = set_prefix(events, prefix='%s/' % prefix, uri=context.uri)
        html_data = stl(events=html_data, mode='xhtml')
        return html_data
示例#19
0
文件: cc.py 项目: staverne/ikaaro
class MassSubscribeButton(Button):
    access = True
    name = 'mass_subscribe'
    title = MSG(u'OK')
示例#20
0
文件: cc.py 项目: staverne/ikaaro
class Observable(Resource):

    # Fields
    cc_list = Followers_Field(multiple=True,
                              indexed=True,
                              title=MSG(u'Followers'))

    confirm_register_subject = MSG(u"Confirmation required")
    confirm_register_text = MSG(
        u'To confirm subscription, click the link:\n\n {uri}\n')

    confirm_unregister_subject = MSG(u"Confirmation required")
    confirm_unregister_text = MSG(
        u'To confirm unsubscription, click the link:\n\n {uri}\n')

    invitation_subject = MSG(u'Invitation')
    invitation_text = MSG(
        u'To accept the invitation, click the link\n\n {uri}\n')

    def get_message(self, context, language=None):
        """This function must return the tuple (subject, body)
        """
        # Subject
        subject = MSG(u'[{title}] has been modified')
        subject = subject.gettext(title=self.get_title(), language=language)
        # Body
        message = MSG(u'DO NOT REPLY TO THIS EMAIL. To view modifications '
                      u'please visit:\n{resource_uri}')
        uri = context.get_link(self)
        uri = str(context.uri.resolve(uri))
        uri += '/;commit_log'
        body = message.gettext(resource_uri=uri, language=language)
        # And return
        return subject, body

    def get_subscribed_users(self, skip_unconfirmed=True):
        cc_list = self.get_property('cc_list')
        if not cc_list:
            return []

        users = []
        for cc in cc_list:
            # case 1: subscribed user or unsubscription pending user
            status = cc.get_parameter('status')
            if status in (None, 'U'):
                users.append(cc.value)
                continue

            # other
            if skip_unconfirmed is False and status == 'S':
                users.append(cc.value)

        return users

    def is_subscribed(self, username, skip_unconfirmed=True):
        return username in self.get_subscribed_users(skip_unconfirmed)

    def is_confirmed(self, username):
        for cc in self.get_property('cc_list'):
            if cc.value == username:
                status = cc.get_parameter('status')
                return status is None
        return False

    def is_subscription_allowed(self, username):
        return True

    def get_register_key(self, username, status='S'):
        for cc in self.get_property('cc_list'):
            if cc.value == username and cc.get_parameter('status') == status:
                return cc.get_parameter('key')
        return None

    def set_register_key(self, username, unregister=False):
        cc_list = self.get_property('cc_list')
        status = 'U' if unregister is True else 'S'
        # Find existing key
        for cc in cc_list:
            key = cc.get_parameter('key')
            if (cc.value == username and cc.get_parameter('status') == status
                    and key is not None):
                # Reuse found key
                return key
        # Generate key
        key = generate_password(30)
        # Filter out username
        cc_list = [cc for cc in cc_list if cc.value != username]
        # Create new dict to force metadata commit
        cc_list.append(Property(username, status=status, key=key))
        self.set_property('cc_list', cc_list)
        return key

    def reset_register_key(self, username):
        cc_list = self.get_property('cc_list')
        # Filter out username
        cc_list = [cc for cc in cc_list if cc.value != username]
        # Create new dict to force metadata commit
        cc_list.append(Property(username))
        self.set_property('cc_list', cc_list)

    def subscribe_user(self, email=None, user=None):
        root = self.get_resource('/')

        # Get the user
        if user is None:
            if email is None:
                raise ValueError, "email or user are mandatory"
            user = root.get_user_from_login(email)

        # Create it if needed
        if user is None:
            user = root.make_user(email, password=None)
            # Mark it as new
            key = generate_password(30)
            user.set_property('user_state', 'pending', key=key)

        # Add to subscribers list
        self.reset_register_key(user.name)

        return user

    def unsubscribe_user(self, username):
        cc_list = self.get_property('cc_list')
        # Filter out username
        cc_list = [cc for cc in cc_list if cc.value != username]
        self.set_property('cc_list', cc_list)

    def after_register(self, username):
        pass

    def after_unregister(self, username):
        pass

    def send_confirm_register(self, user, context, unregister=False):
        username = user.name
        if unregister is False:
            key = self.set_register_key(username)
            view = ';confirm_register'
            subject = self.confirm_register_subject
            text = self.confirm_register_text
        else:
            key = self.set_register_key(username, unregister=True)
            view = ';confirm_unregister'
            subject = self.confirm_unregister_subject
            text = self.confirm_unregister_text

        # Build the confirmation link
        confirm_url = context.uri.resolve(view)
        email = user.get_value('email')
        confirm_url.query = {'key': key, 'email': email}
        subject = subject.gettext()
        text = text.gettext(uri=confirm_url)
        context.root.send_email(email, subject, text=text)

    def notify_subscribers(self, context):
        # 1. Check the resource has been modified
        # XXX This test is broken now comments are stored as separate objects
        #       if not context.database.is_changed(self):
        #           return

        # 2. Get list of subscribed users
        users = self.get_subscribed_users()
        if not users:
            return

        # 3. Build the message for each language
        root = context.root
        website_languages = root.get_value('website_languages')
        default_language = root.get_default_language()
        messages_dict = {}
        for language in website_languages:
            messages_dict[language] = self.get_message(context, language)

        # 4. Send the message
        auth_user = context.user.name if context.user else None

        for username in users:
            if username == auth_user:
                continue
            # Not confirmed yet
            if self.get_register_key(username) is not None:
                continue
            user = root.get_user(username)
            if user and user.get_value('user_state') == 'active':
                mail = user.get_value('email')

                language = user.get_value('user_language')
                if language not in website_languages:
                    language = default_language
                subject, body = messages_dict[language]

                root.send_email(mail, subject, text=body)

    #######################################################################
    # UI
    #######################################################################
    subscribe = SubscribeForm
    confirm_register = ConfirmSubscription
    confirm_unregister = ConfirmUnsubscription
    accept_invitation = AcceptInvitation
示例#21
0
文件: cc.py 项目: staverne/ikaaro
class SubscribeForm(CompositeView):
    access = 'is_allowed_to_view'
    title = MSG(u'Subscriptions')

    subviews = [RegisterForm, ManageForm, MassSubscriptionForm]
示例#22
0
文件: ws_odf.py 项目: hforge/hforge
    def get_namespace(self, resource, context):
        path = context.query['path']
        if path is None:
            path = Path('.')

        if path.startswith_slash:
            path.startswith_slash = False

        # Namespace: the location
        base = '/%s/;browse_tests' % context.site_root.get_pathto(resource)
        link = base + '?path=%s'
        location = [{'name': MSG(u'Test Suite'), 'link': link % '.'}]
        for i, name in enumerate(path):
            p = path[:i+1]
            try:
                test_suite.get_handler(p)
            except LookupError:
                location.append({'name': name, 'link': None})
                body = MSG(u'The "{path}" resource has not been found')
                body = body.gettext(path=p)
                return {'location': location, 'body': body}
            else:
                location.append({'name': name, 'link': link % p})

        # Get the handler
        handler = test_suite.get_handler(path)

        # (1) View PO file
        root = context.root
        if isinstance(handler, POFile):
            template = root.get_resource('/ui/odf-i18n/view_po.xml')
            units = handler.get_units()
            msgs = [ {'id': x.source, 'str': x.target} for x in units ]
            namespace = {'messages': msgs}
            body = stl(template, namespace)

            return {'location': location, 'body': body}

        # Load setup file
        if handler.has_handler('setup.conf'):
            setup = handler.get_handler('setup.conf', cls=ConfigFile)
        else:
            setup = None

        # (2) Browse Folders
        children = handler.get_handler_names()
        children.sort()
        a_handler = handler.get_handler(children[0])
        if isinstance(a_handler, Folder):
            files = []
            for child in children:
                child_handler = handler.get_handler(child)
                number = 0
                for x in test_suite.database.fs.traverse(child_handler.key):
                    if x.endswith('.po'):
                        number += 1
                files.append({'child_name': child,
                              'to_child': link % ('%s/%s' % (path, child)),
                              'number': number})

            namespace = {'content': files}
            template = root.get_resource('/ui/odf-i18n/browse_folder.xml')
            body = stl(template, namespace)
            return {'location': location, 'body': body}

        # (3) Test Folder
        if setup is None:
            title = description = reference = url_reference = None
        else:
            title = setup.get_value('title')
            description = setup.get_value('description')
            reference = setup.get_value('reference')
            url_reference = setup.get_value('url_reference')
            # Format the description (may contain XML)
            description = XMLParser(description)

        files = []
        for child in children:
            if child != 'setup.conf':
                child_path = '%s/%s' % (path, child)
                view = (link % child_path) if child.endswith('.po') else None
                files.append({
                    'child_name': child,
                    'view': view,
                    'to_child': ';download?path=%s' % child_path})

        template = root.get_resource('/ui/odf-i18n/browse_test.xml')
        namespace = {
            'title': title,
            'description': description,
            'reference': reference,
            'url_reference': url_reference,
            'content': files}
        body = stl(template, namespace)

        return {'location': location, 'body': body}
示例#23
0
文件: views.py 项目: mmather02/itools
    def get_namespace(self, resource, context, query=None):
        """This utility method builds a namespace suitable to use to produce
        an HTML form. Its input data is a dictionnary that defines the form
        variables to consider:

          {'toto': Unicode(mandatory=True, multiple=False, default=u'toto'),
           'tata': Unicode(mandatory=True, multiple=False, default=u'tata')}

        Every element specifies the datatype of the field.
        The output is like:

            {<field name>: {'value': <field value>, 'class': <CSS class>}
             ...}
        """
        # Figure out whether the form has been submit or not (FIXME This
        # heuristic is not reliable)
        schema = self.get_schema(resource, context)
        submit = (context.method == 'POST')

        # Build the namespace
        namespace = {}
        for name in schema:
            datatype = schema[name]
            is_readonly = getattr(datatype, 'readonly', False)
            is_multilingual = getattr(datatype, 'multilingual', False)

            error = None
            if submit and not is_readonly:
                try:
                    value = context.get_form_value(name, type=datatype)
                except FormError, err:
                    if err.missing:
                        error = MSG(u'This field is required.')
                    else:
                        error = MSG(u'Invalid value.')

                    if issubclass(datatype, Enumerate):
                        value = datatype.get_namespace(None)
                    else:
                        generic_datatype = String(multilingual=is_multilingual)
                        value = context.get_form_value(name,
                                                       type=generic_datatype)
                else:
                    if issubclass(datatype, Enumerate):
                        value = datatype.get_namespace(value)
                    elif is_multilingual:
                        for language in value:
                            value[language] = datatype.encode(value[language])
                    else:
                        value = datatype.encode(value)
            else:
                try:
                    value = self.get_value(resource, context, name, datatype)
                except FormError, err:
                    if err.missing:
                        error = MSG(u'This field is required.')
                    else:
                        error = MSG(u'Invalid value.')

                    if issubclass(datatype, Enumerate):
                        value = datatype.get_namespace(None)
                    else:
                        value = None
                else:
示例#24
0
class User(Folder):

    class_id = 'user'
    class_version = '20081217'
    class_title = MSG(u'User')
    class_icon16 = '/ui/ikaaro/icons/16x16/user.png'
    class_icon48 = '/ui/ikaaro/icons/48x48/user.png'
    class_views = [
        'profile', 'edit_account', 'edit_preferences', 'edit_password',
        'edit_groups'
    ]

    # Fields
    firstname = Firstname_Field()
    lastname = Lastname_Field()
    email = UserEmail_Field()
    password = UserPassword_Field()
    avatar = File_Field(title=MSG(u'Avatar'))
    user_language = Char_Field()
    user_timezone = Char_Field()
    user_state = UserState_Field()
    groups = UserGroups_Field()
    username = Char_Field(indexed=True, stored=True)  # Backwards compatibility

    # Remove some fields
    title = None
    description = None
    subject = None
    text = None

    ########################################################################
    # Indexing
    ########################################################################
    def get_catalog_values(self):
        proxy = super(User, self)
        values = proxy.get_catalog_values()
        # email domain
        email = self.get_value('email')
        if email and '@' in email:
            values['email_domain'] = email.split('@', 1)[1]
        # username (overrides default)
        values['username'] = self.get_login_name()
        # groups
        values['groups'] = self.get_value('groups')
        # Ok
        return values

    ########################################################################
    # API / Authentication
    ########################################################################
    def get_user_id(self):
        # Used by itools.web
        return str(self.name)

    def get_password(self):
        password = self.get_property('password')
        return password[-1] if password else None

    def get_auth_token(self):
        # Used by itools.web
        password = self.get_password()
        return password.value if password else None

    def authenticate(self, password):
        my_password = self.get_password()
        if my_password is None:
            return False
        algo = my_password.get_parameter('algo', 'sha1')
        salt = my_password.get_parameter('salt', '')

        password_hashed, salt = get_secure_hash(password, algo, salt)
        return password_hashed == my_password.value

    def _login(self, password, context):
        # We call this method '_login' to avoid a name clash with the login
        # view.

        if not self.authenticate(password):
            error = MSG_LOGIN_WRONG_NAME_OR_PASSWORD
        elif self.get_value('user_state') == 'inactive':
            error = ERROR(
                u'Your account has been canceled, contact the administrator '
                u' if you want to get access again.')
        else:
            error = None
            context.login(self)

        # To activate this feature set the lastlog field
        lastlog = self.get_field('lastlog')
        if lastlog:
            success = error is None
            self.set_value('lastlog', context.timestamp, success=success)

        # Ok
        return error

    def update_pending_key(self):
        state = self.get_property('user_state')
        if state.value == 'pending':
            # TODO Implement expiration
            return state.get_parameter('key')

        key = generate_password(30)
        self.set_value('user_state', 'pending', key=key)
        return key

    ########################################################################
    # API
    ########################################################################
    def get_owner(self):
        return str(self.abspath)

    def get_title(self, language=None):
        firstname = self.get_value('firstname')
        lastname = self.get_value('lastname')
        if firstname:
            if lastname:
                return '%s %s' % (firstname, lastname)
            return firstname
        if lastname:
            return lastname
        return self.get_login_name().decode('utf-8')

    login_name_property = 'email'

    def get_login_name(self):
        return self.get_value(self.login_name_property)

    def get_timezone(self):
        return self.get_value('user_timezone')

    #######################################################################
    # Views
    #######################################################################
    resend_confirmation = User_ResendConfirmation()
    confirm_registration = User_ConfirmRegistration()
    change_password_forgotten = User_ChangePasswordForgotten()
    profile = User_Profile()
    edit_account = User_EditAccount()
    edit_preferences = User_EditPreferences()
    edit_password = User_EditPassword()
    edit_groups = AutoEdit(access='is_admin',
                           fields=['groups'],
                           title=MSG(u'Edit groups'))
示例#25
0
class Payment_Widget(Widget):

    total_price = {'with_tax': decimal('0'), 'without_tax': decimal('0')}

    title1 = None
    title2 = MSG(u'Please choose a payment mode')

    template = list(
        XMLParser(
            """
      <h2 stl:if="title1">${title1}</h2>

      <input type="text" name="amount" value="${total_price_with_tax}" size="6"/> €

      <h2>${title2}</h2>

      <table cellpadding="5px" cellspacing="0">
        <tr stl:repeat="payment payments" stl:if="payment/enabled">
          <td valign="top">
            <input type="radio" name="payment" checked="${payment/selected}"
              id="payment-${payment/name}" value="${payment/name}"/>
          </td>
          <td valign="top">
            ${payment/value}<br/><br/>
            <img stl:if="payment/logo" src="${payment/logo}/;download"/>
          </td>
          <td style="width:400px;vertical-align:top;">
            ${payment/description}
          </td>
        </tr>
      </table>
      """, stl_namespaces))

    def get_namespace(self, datatype, value):
        context = get_context()
        total_price = self.total_price
        namespace = {
            'payments': [],
            'title1': self.title1,
            'title2': self.title2,
            'total_price_with_tax': total_price['with_tax'] or None,
            'total_price': total_price
        }
        payments = get_shop(context.resource).get_resource('payments')
        for mode in payments.search_resources(cls=PaymentWay):
            logo = mode.get_property('logo')
            if logo:
                logo = mode.get_resource(logo, soft=True)
            shipping_groups = mode.get_property('only_this_groups')
            user_group = context.user.get_property('user_group')
            if len(shipping_groups) > 0 and user_group not in shipping_groups:
                continue
            if mode.is_enabled(context) is False:
                continue
            namespace['payments'].append({
                'name':
                mode.name,
                'value':
                mode.get_title(),
                'description':
                mode.get_payment_way_description(context, total_price),
                'logo':
                str(context.resource.get_pathto(logo)) if logo else None,
                'enabled':
                True,
                'selected':
                None
            })
        # Select first mode by default
        if namespace['payments'] != []:
            namespace['payments'][0]['selected'] = True
        return namespace
示例#26
0
class OrderDownButton(BrowseButton):

    access = 'is_allowed_to_edit'
    name = 'order_down'
    title = MSG(u'Order down')
示例#27
0
文件: views.py 项目: hforge/itools
 def on_query_error_default(self, resource, context):
     message = MSG(u'The query could not be processed.').gettext()
     return message.encode('utf-8')
示例#28
0
class AutoAdd(AutoForm):

    access = 'is_allowed_to_add'

    actions = [Button(access=True, css='button-ok', title=MSG(u'Add'))]
    action_goto = None
    goto_view = None
    goto_parent_view = None # DEPRECATED -> use action_goto
    msg_new_resource = messages.MSG_NEW_RESOURCE


    # Fields
    fields = []
    def get_fields(self):
        cls = self._resource_class
        for name in self.fields:
            field = self.get_field(name)
            if not is_prototype(field, Field):
                field = cls.get_field(name)

            if not field:
                continue

            # Access control
            if field.access('write', cls):
                yield name


    def get_field(self, name):
        cls = self._resource_class
        field = getattr(self, name, None)
        if field is None or not is_prototype(field, Field):
            field = cls.get_field(name)
        return field



    #######################################################################
    # GET
    #######################################################################
    @proto_lazy_property
    def _resource_class(self):
        context = self.context

        class_id = context.query['type']
        if not class_id:
            return None
        return context.database.get_resource_class(class_id)


    def get_title(self, context):
        if self.title is not None:
            return self.title

        cls = self._resource_class
        if cls:
            class_title = cls.class_title.gettext()
            title = MSG(u'Add {class_title}')
            return title.gettext(class_title=class_title)

        return MSG(u'Add resource').gettext()


    def _get_datatype(self, resource, context, name):
        cls = self._resource_class

        field = self.get_field(name)

        field = field(resource=cls) # bind
        return field.get_datatype()


    def get_query_schema(self):
        context = get_context()
        resource = context.resource

        schema = self.get_schema(resource, context)
        for name, datatype in schema.items():
            if getattr(datatype, 'mandatory', False) is True:
                schema[name] = datatype(mandatory=False)

        schema['type'] = String
        return schema


    def get_schema(self, resource, context):
        schema = {
            'cls_description': Unicode,
            'referrer': URI}
        for name in self.get_fields():
            datatype = self._get_datatype(resource, context, name)
            if datatype is None:
                continue
            # Special case: datetime
            elif issubclass(datatype, DateTime):
                schema['%s_time' % name] = Time
            # Special case: birthdate
            elif issubclass(datatype, BirthDate):
                schema['%s_day' % name] = Days
                schema['%s_month' % name] = Months
                schema['%s_year' % name] = Years

            # Standard case
            schema[name] = datatype

        return schema


    def _get_widget(self, resource, context, name):
        field = self.get_field(name)
        return field.get_widget(name)


    def get_widgets(self, resource, context):
        widgets = [
            ReadOnlyWidget('cls_description'),
            HiddenWidget('referrer')]
        for name in self.get_fields():
            widget = self._get_widget(resource, context, name)
            widgets.append(widget)

        return widgets


    def get_value(self, resource, context, name, datatype):
        if name == 'cls_description':
            # View cls_description
            value = getattr(self, name, None)
            if value is not None:
                return value.gettext() if value else u''
            # Resource cls_description
            cls = self._resource_class
            value = cls.class_description
            return value.gettext() if value else u''
        elif name == 'referrer':
            referrer = context.query.get('referrer')
            return referrer or context.get_referrer()
        value = context.query.get(name)
        if value is None:
            proxy = super(AutoAdd, self)
            return proxy.get_value(resource, context, name, datatype)

        if getattr(datatype, 'multilingual', False):
            for language in resource.get_edit_languages(context):
                value.setdefault(language, u'')

        return value



    #######################################################################
    # POST
    #######################################################################
    def get_container(self, resource, context, form):
        # Container
        container = resource
        path = str(container.abspath)

        # Access control
        class_id = context.query['type']
        root = context.root
        if not root.has_permission(context.user, 'add', container, class_id):
            path = '/' if path == '.' else '/%s/' % path
            msg = ERROR(u'Adding resources to {path} is not allowed.')
            raise FormError, msg.gettext(path=path)

        # Ok
        return container


    automatic_resource_name = False
    def get_new_resource_name(self, form):
        if self.automatic_resource_name:
            return form['container'].make_resource_name()

        # If the name is not explicitly given, use the title
        name = form.get('name', '').strip()
        if name:
            return name

        context = get_context()
        lang = self.resource.get_edit_languages(context)[0]
        return form['title'][lang]


    def _get_form(self, resource, context):
        form = super(AutoAdd, self)._get_form(resource, context)

        # 1. The container
        container = self.get_container(resource, context, form)
        form['container'] = container

        # 2. The name
        name = self.get_new_resource_name(form)
        if not name:
            raise FormError, messages.MSG_NAME_MISSING
        try:
            name = checkid(name)
        except UnicodeEncodeError:
            name = None
        if name is None:
            raise FormError, messages.MSG_BAD_NAME

        # Check the name is free
        if container.get_resource(name, soft=True) is not None:
            raise FormError, messages.MSG_NAME_CLASH
        form['name'] = name

        # Ok
        return form


    def set_value(self, resource, context, name, form):
        """Return True if an error occurs otherwise False. If an error
        occurs, the context.message must be an ERROR instance.
        """
        if name.endswith(('_time', '_year', '_day', '_month')):
            return False

        if resource.get_field(name) is None:
            return False

        value = form[name]
        if type(value) is dict:
            for language, data in value.iteritems():
                resource.set_value(name, data, language=language)
        else:
            resource.set_value(name, value)
        return False


    def init_new_resource(self, resource, context, form):
        child = form['child']

        schema = self.get_schema(resource, context)
        for name in self.get_fields():
            datatype = schema.get(name)
            if not datatype:
                continue
            readonly = getattr(datatype, 'readonly', False)
            persistent = getattr(datatype, 'persistent', True)
            if persistent and not readonly:
                if self.set_value(child, context, name, form):
                    return None
        return child


    def make_new_resource(self, resource, context, form):
        """Returns None if there is an error, otherwise return the new
        resource.
        """
        # 1. Make the resource
        container = form['container']
        cls = self._resource_class
        form['child'] = container.make_resource(form['name'], cls)
        # 2. Set properties
        return self.init_new_resource(resource, context, form)


    def action(self, resource, context, form):
        child = self.make_new_resource(resource, context, form)
        if child is None:
            return

        # Ok
        if self.action_goto:
            # Get same redirection from x/y/z/;edit and x/y/z and x/y/z/
            goto = self.action_goto
            if goto[0] not in ('/', 'http://'):
                path = str(context.uri.path)
                if ('/;' not in path and '/?' not in path
                        and not path.endswith('/')):
                    goto = '%s/%s' % (resource.name, goto)
            return context.come_back(self.msg_new_resource, goto=goto)
        # goto_parent_view # Deprecated : To replace by action_goto
        goto = str(child.abspath)
        if self.goto_parent_view:
            goto = './;%s' % self.goto_parent_view
        # goto_view (from Child)
        elif self.goto_view:
            goto = '%s/;%s' % (child.abspath, self.goto_view)
        return context.come_back(self.msg_new_resource, goto=goto)
示例#29
0
class OrderedFolder(Folder):

    class_title = MSG(u'Ordered Folder')
    class_views = ['browse_content']

    # Fields
    order = URI_Field(title=MSG(u'Order'), multiple=True)

    allow_to_unorder_items = False


    def make_resource(self, name, cls, **kw):
        resource = super(OrderedFolder, self).make_resource(name, cls, **kw)
        if self.can_be_ordered(cls):
            order = self.get_value('order')
            order = order + [resource.name]
            self.set_value('order', order)
        return resource


    base_classes = None
    def can_be_ordered(self, cls):
        if not self.base_classes:
            return True
        for base_class in cls.__mro__:
            if getattr(base_class, 'class_id', None) in self.base_classes:
                return True
        return False



    def get_ordered_values(self):
        ordered_names = list(self.get_value('order'))
        # Unordered names
        if self.allow_to_unorder_items is False:
            for name in self.get_names():
                if name not in ordered_names:
                    ordered_names.append(name)
        return ordered_names


    def get_resources_in_order(self):
        for name in self.get_ordered_values():
            yield self.get_resource(name)


    def order_up(self, ids):
        order = self.get_ordered_values()
        order = list(order)
        for id in ids:
            index = order.index(id)
            if index > 0:
                order.remove(id)
                order.insert(index - 1, id)
        # Update the order
        self.set_value('order', order)


    def order_down(self, ids):
        order = self.get_ordered_values()
        order = list(order)
        for id in ids:
            index = order.index(id)
            order.remove(id)
            order.insert(index + 1, id)
        # Update the order
        self.set_value('order', order)


    def order_top(self, ids):
        order = self.get_ordered_values()
        order = list(order)
        order = ids + [ id for id in order if id not in ids ]
        # Update the order
        self.set_value('order', order)


    def order_bottom(self, ids):
        order = self.get_ordered_values()
        order = list(order)
        order = [ id for id in order if id not in ids ] + ids
        # Update the order
        self.set_value('order', order)


    def order_add(self, ids):
        order = self.get_ordered_values()
        order = list(order)
        order = [ id for id in order if id not in ids ] + ids
        # Update the order
        self.set_value('order', order)


    def order_remove(self, ids):
        order = self.get_ordered_values()
        order = list(order)
        order = [ id for id in order if id not in ids ]
        # Update the order
        self.set_value('order', order)


    # Views
    browse_content = OrderedFolder_BrowseContent
示例#30
0
class Skin(object):

    class_title = MSG(u'Skin')
    class_icon16 = '/ui/ikaaro/icons/16x16/skin.png'
    class_icon48 = '/ui/ikaaro/icons/48x48/skin.png'

    # User Interface widgets
    languages_template = LanguagesTemplate
    location_template = LocationTemplate


    def __init__(self, key):
        self.key = key


    def get_environment_key(self, server):
        """ In development environment we can use '/ui_dev/skin/' directory
        for skin (to avoid build JS/CSS at every changes)
        """
        if server and server.is_development_environment():
            build_path = str(server.environment['build_path'])
            base_path = self.key.split('/ui/')[0]
            new_key = self.key.replace(base_path, build_path)
            new_key = new_key.replace('/ui/', '/ui_dev/')
            if vfs.exists(new_key):
                # Use local skin
                return new_key
        return self.key

    #######################################################################
    # HTML head
    #######################################################################
    def get_template_title(self, context):
        """Return the title to give to the template document.
        """
        here = context.resource
        root = context.root
        root_title = root.get_title()

        # Choose the template
        if not root.is_allowed_to_view(context.user, here):
            return ''
        elif root is here:
            template = MSG(u"{view_title} - {root_title}")
            here_title = None
        else:
            template = MSG(u"{here_title} - {view_title} - {root_title}")
            here_title = here.get_title()

        # The view
        view_title = context.view.get_title(context)

        # Ok
        return template.gettext(root_title=root_title, here_title=here_title,
                                view_title=view_title)


    def _get_theme_file(self, context, name):
        theme = context.database.get_resource('/config/theme')
        if context.root.is_allowed_to_view(context.user, theme):
            value = theme.get_value(name)
            if value:
                return value

        return None


    def get_styles(self, context):
        # Generic
        styles = ['/ui/ikaaro/bo.css']

        # Skin
        if isfile('%s/style.css' % self.key):
            styles.append('%s/style.css' % self.base_path)

        # View
        get_styles = getattr(context.view, 'get_styles', None)
        if get_styles is None:
            extra = getattr(context.view, 'styles', [])
        else:
            extra = get_styles(context)
        styles.extend(extra)

        # Database style
        if self._get_theme_file(context, 'style'):
            styles.append(
                '/config/theme/;get_file?name=style&mimetype=text/css')

        # Ok
        return styles


    def get_scripts(self, context):
        scripts = [
            '/ui/ikaaro/jquery.js',
            '/ui/ikaaro/javascript.js']

        # This skin's JavaScript
        if isfile('%s/javascript.js' % self.key):
            scripts.append('%s/javascript.js' % self.base_path)

        # View
        for script in get_view_scripts(context.view, context):
            if script not in scripts:
                scripts.append(script)

        # Ok
        return scripts


    def get_meta_tags(self, context):
        """Return a list of dict with meta tags to give to the template
        document.
        """
        here = context.resource
        root = context.root

        meta = []
        # Set description
        try:
            property = here.get_property('description')
        except ValueError:
            pass
        else:
            if property:
                meta.append({
                    'name': 'description',
                    'lang': property.get_parameter('lang'),
                    'content': property.value})

        # Set keywords for all languages
        for language in root.get_value('website_languages'):
            try:
                value = here.get_value('subject', language)
            except ValueError:
                continue
            if value is None:
                continue
            value = value.strip()
            if value:
                meta.append({'name': 'keywords', 'lang': language,
                             'content': value})

        # Search engine optimization
        seo = root.get_resource('config/seo')
        for key, meta_name in [
            ('google_site_verification', 'google-site-verification'),
            ('yahoo_site_verification', 'y_key'),
            ('bing_site_verification', 'msvalidate.01')]:
            verification_key = seo.get_value(key)
            if verification_key:
                meta.append({'name': meta_name,
                             'lang': None,
                             'content': verification_key})

        # View
        # meta are defined as a tuple (name, content, language)
        extra_meta = getattr(context.view, 'meta', [])
        for (name, content, lang) in extra_meta:
            meta.append({'name': name, 'content': content, 'lang': lang})

        return meta


    def get_favicon(self, context):
        # Case 1: from the database
        favicon = self._get_theme_file(context, 'favicon')
        if favicon:
            favicon_href = '/config/theme/;get_file?name=favicon'
            favicon_type = favicon.get_mimetype()
            return favicon_href, favicon_type

        # Case 2: from the skin
        favicon = '%s/favicon.ico' % self.base_path
        if context.get_template(favicon):
            return (favicon, 'image/x-icon')

        # Case 3: default
        return ('/ui/ikaaro/favicon.ico', 'image/x-icon')


    #######################################################################
    # Authenticated user
    #######################################################################
    def get_usermenu(self, context):
        """Return a dict {'name': ..., 'title': ..., 'home': ...}
        """
        here = context.resource
        base_path = context.get_link(here)

        # Case 1: Anonymous
        user = context.user
        if user is None:
            return [{'href': '%s/;login' % base_path,
                     'title': MSG(u'Sign in'),
                     'id': 'links-menu-login'}]

        # Case 2: Authenticated
        usermenu = [
            # Home
            {'href': '/users/%s' % user.name,
             'title': user.get_title(),
             'id': 'links-menu-profile'},
            # Logout
            {'href': '%s/;logout' % base_path,
             'title': MSG(u'Log out'),
             'id': 'links-menu-logout'}]

        # Add content
        container = here
        if isinstance(here, Folder) is False:
            container = here.parent
        view = container.get_view('new_resource')
        if context.is_access_allowed(container, view):
            usermenu.append({
                'href': '%s/;new_resource' % context.get_link(container),
                'title': MSG(u'Add content'),
                'id': 'links-menu-new'})

        # Configuration
        config = here.get_resource('/config')
        if context.root.is_allowed_to_view(user, config):
            usermenu.append({
                'href': '/config',
                'title': MSG(u'Configuration'),
                'id': 'links-menu-configuration'})

        return usermenu


    #######################################################################
    # Body
    #######################################################################
    def _get_page_title(self, context):
        resource = context.resource
        view = context.view

        # Not allowed to view resource
        root = context.root
        if not root.is_allowed_to_view(context.user, resource):
            return ''

        # Page title
        try:
            get_page_title = view.get_page_title
        except AttributeError:
            return resource.get_page_title()

        return get_page_title(resource, context)


    def get_messages(self, context):
        """Return the message string of the last action.
        A list of messages is supported.
        """
        # Text
        if context.message is not None:
            messages = context.message
        elif 'error' in context.uri.query:
            messages = ERROR(context.get_query_value('error', type=Unicode))
        elif 'info' in context.uri.query:
            messages = INFO(context.get_query_value('info', type=Unicode))
        # XXX For backwards compatibility
        elif 'message' in context.uri.query:
            messages = INFO(context.get_query_value('message', type=Unicode))
        else:
            return None

        # Multiple messages:
        if not isinstance(messages, list):
            messages = [messages]

        messages_ns = []
        for message in messages:
            css_class = getattr(message, 'css', 'info')
            messages_ns.append({'message': message, 'class': css_class})

        namespace = {'messages': messages_ns}

        template = context.get_template('/ui/aruni/message.xml')
        return stl(template, namespace)


    def _get_context_menus(self, context):
        resource = context.resource
        # Resource
        for menu in resource.get_context_menus():
            menu = menu(resource=resource, context=context)
            yield menu.render()

        # View
        get_context_menus = getattr(context.view, 'get_context_menus', None)
        if get_context_menus is None:
            menus = getattr(context.view, 'context_menus', [])
        else:
            menus = get_context_menus()

        for menu in menus:
            menu = menu(resource=resource, context=context)
            yield menu.render()


    def get_footer(self, context):
        footer = context.root.get_resource('config/footer')
        return footer.get_html_data()


    def get_menu_namespace(self, context):
        menu = context.root.get_resource('config/menu')
        return menu.get_menu_namespace(context)


    #######################################################################
    # Main
    #######################################################################
    def build_namespace(self, context):
        # Context menus
        context_menus = self._get_context_menus(context)
        context_menus = list(context_menus)

        # The favicon.ico
        favicon_href, favicon_type = self.get_favicon(context)

        # Logo
        logo = self._get_theme_file(context, 'logo')
        logo_href = '/config/theme/;get_file?name=logo' if logo else None

        # The document language
        languages = context.root.get_value('website_languages')
        language = context.accept_language.select_language(languages)

        # The base URI
        uri = context.uri
        if uri.path and not context.view_name and not uri.path.endswith_slash:
            uri = deepcopy(uri)
            uri.path.endswith_slash = True

        # Location template
        location_template = self.location_template
        if location_template:
            location_template = location_template(context=context)

        # Ok
        return {
            # HTML head
            'language': language,
            'title': self.get_template_title(context),
            'base_uri': str(uri),
            'canonical_uri': context.view.get_canonical_uri(context),
            'styles': self.get_styles(context),
            'scripts': self.get_scripts(context),
            'meta_tags': self.get_meta_tags(context),
            'favicon_href': favicon_href,
            'favicon_type': favicon_type,
            # logo
            'logo_href': logo_href,
            # Usermenu (the links at the top)
            'usermenu': self.get_usermenu(context),
            # menu
            'menu': self.get_menu_namespace(context),
            # Location & Views
            'location': location_template,
            'languages': self.languages_template(context=context),
            # Body
            'page_title': self._get_page_title(context),
            'message': self.get_messages(context),
            'context_menus': context_menus,
            # Footer
            'footer': self.get_footer(context),
        }


    def get_template(self, context):
        paths = [
            '%s/template.xhtml' % self.base_path,
            '/ui/aruni/template.xhtml']
        for path in paths:
            template = context.get_template(path)
            if template:
                return path, template

        raise ValueError, 'XXX'


    def template(self, content):
        context = get_context()
        # Build the namespace
        namespace = self.build_namespace(context)
        namespace['body'] = content

        # Set the encoding to UTF-8
        context.content_type = 'text/html; charset=UTF-8'

        # Load the template
        prefix, handler = self.get_template(context)

        # Build the output
        s = ['<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"\n'
             '  "http://www.w3.org/TR/html4/strict.dtd">']
        # STL
        data = stl(handler, namespace, prefix=prefix, mode='html')
        s.append(data)

        return ''.join(s)
示例#31
0
class MenuItem(OrderedFolder):

    class_id = 'config-menu-item'
    class_title = MSG(u'Menu')

    # Fields
    path = URI_Field(required=True,
                     title=MSG(u'Path'),
                     widget=PathSelectorWidget)
    target = Target_Field

    def get_document_types(self):
        return [MenuItem]

    # Views
    class_views = ['edit', 'browse_content', 'add_menu', 'commit_log']
    _fields = ['title', 'path', 'target']
    new_instance = AutoAdd(fields=_fields)
    edit = AutoEdit(fields=_fields)
    browse_content = MenuItem_Browse
    add_menu = AddMenu

    # API
    def _is_allowed_to_access(self, context, uri):
        # Get the reference and path
        ref, path, view = split_reference(uri)

        # Broken entry
        if ref is None or path == '':
            return False

        # External link
        if ref.scheme:
            return True

        # Broken link
        resource = self.get_resource(path, soft=True)
        if resource is None:
            return False

        if view:
            # Remove the first '/;' of the view
            view = resource.get_view(view[2:], ref.query)
            if not view:
                return False
            # Check ACL
            return context.is_access_allowed(resource, view)

        # Check if the user can access to resource views
        # get_views checks ACLs with by calling is_access_allowed
        resource_views = list(resource.get_views())
        return len(resource_views) > 0

    def get_menu_namespace_level(self, context, url, use_first_child=False):
        menu_abspath = self.abspath
        here = context.resource
        here_abspath = here.abspath
        here_view_name = url[-1]
        here_abspath_and_view = '%s/%s' % (here_abspath, here_view_name)
        items = []

        for resource in self.get_resources_in_order():
            uri = resource.get_value('path')
            if not self._is_allowed_to_access(context, uri):
                continue
            ref, path, view = split_reference(uri)
            title = resource.get_value('title')
            target = resource.get_value('target')

            # Case 1: External link
            if ref.scheme:
                items.append({
                    'id': 'menu_%s' % resource.name,
                    'path': str(ref),
                    'real_path': None,
                    'title': title,
                    'description': None,
                    'in_path': False,
                    'active': False,
                    'class': None,
                    'target': target,
                    'items': []
                })
                continue

            # Case 2: Internal link
            # Sub level
            subtabs = resource.get_menu_namespace_level(
                context, url, use_first_child)
            resource = self.get_resource(path, soft=True)
            item_id = 'menu_%s' % resource.name

            # Use first child by default we use the resource itself
            resource_path = path
            # Keep the real path to avoid highlight problems
            resource_original_path = path
            # use first child
            if use_first_child and subtabs:
                sub_path = subtabs[0]['real_path']
                # if the first child is an external link => skip it
                if sub_path is not None:
                    resource_path = sub_path

            # Set active, in_path
            active = in_path = False
            # add default view
            if view:
                resource_method = view[2:]
                item_id += '_%s' % resource_method
            else:
                resource_method = resource.get_default_view_name()
            resource_abspath_and_view = '%s/;%s' % (resource.abspath,
                                                    resource_method)
            if here_abspath_and_view == resource_abspath_and_view:
                active = True
            else:
                # Use the original path for the highlight
                res_abspath = menu_abspath.resolve2(resource_original_path)
                common_prefix = here_abspath.get_prefix(res_abspath)
                # Avoid to always set the root entree 'in_path'
                # If common prefix equals root abspath set in_path to False
                # otherwise compare common_prefix and res_abspath
                if common_prefix != Path('/'):
                    in_path = (common_prefix == res_abspath)

            # Build the new reference with the right path
            ref2 = deepcopy(ref)
            resource = self.get_resource(resource_path)
            ref2.path = context.get_link(resource)
            if view:
                ref2.path += view

            items.append({
                'id': item_id,
                'path': str(ref2),
                'real_path': resource.abspath,
                'title': title,
                'description': None,  # FIXME
                'in_path': active or in_path,
                'active': active,
                'class': None,
                'target': target,
                'items': subtabs
            })

        # Set class
        x = None
        for i, item in enumerate(items):
            if item['active']:
                x = i
                break
            if item['in_path'] and x is None:
                x = i
                break
        if x is not None:
            items[x]['class'] = 'in-path'

        if len(items) > 0:
            # Add class "first" to the first item
            css = items[0]['class'] or ''
            items[0]['class'] = css + ' first'
            # Add class "last" to the last item
            css = items[-1]['class'] or ''
            items[-1]['class'] = css + ' last'

        return items
示例#32
0
class AddMenu(NewResource_Local):

    title = MSG(u'Add item')

    def get_items(self, resource, context):
        return tuple(resource.get_document_types())
示例#33
0
文件: cc.py 项目: staverne/ikaaro
class SubscribeButton(BrowseButton):
    access = True
    name = 'subscribe'
    title = MSG(u"Subscribe")
示例#34
0
 def get_namespace(self, resource, context):
     resource_zones = resource.get_resource('../countries-zones')
     handler_countries = resource.get_resource('../countries').handler
     if self.show_inactive:
         page_title = MSG('Inactives shippings prices')
     else:
         page_title = MSG('Shippings price')
     namespace = {
         'zones': [],
         'msg_if_no_shipping': resource.get_property('msg_if_no_shipping'),
         'page_title': page_title}
     for zone in resource_zones.handler.get_records_in_order():
         countries = []
         for country in handler_countries.search(zone=str(zone.id)):
             title = handler_countries.get_record_value(country, 'title')
             if handler_countries.get_record_value(country, 'enabled') is False:
                 continue
             countries.append(title)
         if len(countries) == 0:
             continue
         zone_title = resource_zones.handler.get_record_value(zone, 'title')
         tarifications = []
         for tarification in resource.get_resources():
             # We show only active or inactives modes, depending on config
             if tarification.get_property('enabled') is self.show_inactive:
                 continue
             mode = tarification.get_property('mode')
             unit = MSG(u'Kg') if mode == 'weight' else MSG(u'Unit')
             prices = []
             min = old_price = 0
             prices_resource = tarification.get_resource('prices')
             prices_handler = prices_resource.handler
             tarif_edit = context.get_link(prices_resource)
             tarif_edit += '/?zone=%i&search=' % zone.id
             records = prices_handler.search(zone=str(zone.id))
             records.sort(key=lambda x: prices_handler.get_record_value(x, 'max-%s' % mode))
             for price in records:
                 max = prices_handler.get_record_value(price, 'max-%s' % mode)
                 price = prices_handler.get_record_value(price, 'price')
                 prices.append(
                   {'title': '%s to %s %s' % (min, max, unit.gettext()),
                    'price': price,
                    'error': price<=old_price})
                 min = max
                 old_price = price
             if len(prices) == 0:
                 continue
             kw = {
                 'name': tarification.name,
                 'models': [],
                 'title': tarification.get_title(),
                 'img': tarification.get_property('logo'),
                 'is_free': tarification.get_property('is_free'),
                 'prices': prices,
                 'description': tarification.get_property('description'),
                 'tarif_edit': tarif_edit}
             models = tarification.get_property('only_this_models')
             for model_abspath in models:
                 model = context.root.get_resource(model_abspath)
                 kw['models'].append(model.get_title())
             tarifications.append(kw)
         zone_edit = '/shop/countries?zone=%i&search=' % zone.id
         has_tax = resource_zones.handler.get_record_value(zone, 'has_tax')
         tax_image = list(bool_to_img(has_tax))
         namespace['zones'].append({'title': zone_title,
                                    'countries': countries,
                                    'tarifications': tarifications,
                                    'zone_edit': zone_edit,
                                    'tax_image': tax_image})
     return namespace
示例#35
0
class ConfigMenu(MenuItem):

    class_id = 'config-menu'
    class_title = MSG(u'Configuration Menu')
    class_description = MSG(u'Edit the global menu.')
    class_icon48 = 'icons/48x48/menu.png'

    def init_resource(self, **kw):
        super(ConfigMenu, self).init_resource(**kw)
        # Menu
        order = []
        menus = [('/', u'Home'), ('/;contact', u'Contact')]
        for path, title in menus:
            name = checkid(title)
            order.append(name)
            self.make_resource(name, MenuItem, path=path, title={'en': title})
        self.set_property('order', order)

    # Configuration
    config_name = 'menu'
    config_group = 'webmaster'

    # Views
    class_views = ['browse_content', 'add_menu', 'edit', 'commit_log']

    def get_menu_namespace(self, context, show_first_child=False, src=None):
        """Return dict with the following structure:

        {'items': [item_dic01, ..., item_dic0N]}

        Where the list of items is the first level
        and item_dic = {'active': True or False,
                        'class': 'active' or 'in_path' or None,
                        'description': MSG(u'About Python'),
                        'id': 'tab_python',
                        'in_path': True or False,
                        'items': [item_dic11, ..., item_dic1N] or None,
                        'name': 'python',
                        'path': '../python',
                        'target': '_top' or '_blank' or None,
                        'title': MSG(u'Python')}

        "items" contains the first level. Each item_dic contains in turn an
        'items' with its children.
        "class" is a CSS class decorating the item when active on within the
        current path.
        "id" is a CSS id to uniquely identify the item, based on the title.
        "target" is the anchor target (opening a new window or not).

        Activate "use_first_child" to automatically point to the first child
        of each item instead of the item itself.
        """
        resource = context.resource
        url = list(context.uri.path)
        if not url or url[-1][0] != ';':
            method = resource.get_default_view_name()
            url.append(';%s' % method)

        # Get the menu
        menu = self
        if src:
            menu = self.get_resource(src, soft=True)
            if menu is None:
                return []

        return menu.get_menu_namespace_level(context, url, show_first_child)
示例#36
0
class OrderButton(BrowseButton):

    access = 'is_allowed_to_edit'
    name = 'add_to_ordered'
    title = MSG(u'Add to ordered list')
示例#37
0
class Application(Folder):

    class_id = 'application'
    class_title = MSG(u"Collection Application")
    class_description = MSG(u"Create from an OpenDocument Spreadsheet file")
    class_views = ['view_admin', 'edit', 'edit_ods', 'register', 'view']

    # FIXME Configuration obsolete ?
    allowed_users = 10

    # Fields
    subscription = Subscription_Field(required=True)
    data = File_Field(title=MSG(u'ODS file'),
                      multilingual=False,
                      required=True)
    filename = Char_Field()
    mimetype = Char_Field()

    def init_resource(self, *args, **kw):
        proxy = super(Application, self)
        proxy.init_resource(*args, **kw)
        # Initial forms answers containers
        self.make_resource('forms', Forms)

    def load_ods_file(self, data, context):
        if self.get_resource('model', soft=True):
            self.del_resource('model')
            context.database.save_changes()
        # Create model container
        self.make_resource('model', FormModel)
        model = self.get_resource('model')
        # Save informations
        filename, mimetype, body = data
        self.set_value('data', body)
        self.set_value('filename', filename)
        self.set_value('mimetype', mimetype)
        # Analyse it
        return model.load_ods_file(context)

    def get_form(self):
        # OBSOLETE METHOD FIXME
        raise NotImplementedError

    def search_forms(self):
        query = AndQuery(PhraseQuery('base_classes', 'form'),
                         get_base_path_query(self.abspath))
        return get_context().search(query)

    def get_forms(self):
        return self.search_forms().get_resources()

    def get_n_forms(self):
        return len(self.search_forms())

    def get_stats(self):
        stats = {}
        stats['registered_users'] = 0
        stats['unconfirmed_users'] = 0
        stats['empty_forms'] = 0
        stats['pending_forms'] = 0
        stats['finished_forms'] = 0
        users = self.get_resource('/users')
        for form in self.get_forms():
            stats['registered_users'] += 1
            user = users.get_resource(form.name, soft=True)
            if user is not None:
                if user.get_value('password') is None:
                    stats['unconfirmed_users'] += 1
                else:
                    state = form.get_value('form_state')
                    if state == EMPTY:
                        stats['empty_forms'] += 1
                    elif state == PENDING:
                        stats['pending_forms'] += 1
                    elif state == FINISHED:
                        stats['finished_forms'] += 1
        return stats

    def get_param_folder(self):
        return self

    def get_admin_url(self, context):
        base_url = context.uri.resolve(self.abspath)
        return base_url.resolve2(';view')

    def get_spread_url(self, context, email=None):
        base_url = context.uri.resolve(self.abspath)
        spread_url = base_url.resolve2(';login')
        if email is not None:
            spread_url.query['username'] = email
        return spread_url

    def subscribe_user(self, user):
        root = self.get_resource('/')
        username = user.name
        # Give the role "guests" to see public resources (logo, etc.)
        if (root.get_user_role(username) is None
                # Except to top-level admins
                and not root.is_admin(user, self)):
            root.set_user_role(username, 'guests')
        # Add the form
        if self.get_resource(username, soft=True) is None:
            self.make_resource(username,
                               Form,
                               title={'en': user.get_title()},
                               form_state=NOT_REGISTERED)

    # Views
    new_instance = Application_NewInstance()
    edit = Application_Edit()
    edit_ods = Application_EditODS()
    view_admin = IconsView()
    register = Application_Register()
示例#38
0
class UnOrderButton(BrowseButton):

    access = 'is_allowed_to_edit'
    name = 'remove_from_ordered'
    title = MSG(u'Remove from ordered list')
示例#39
0
class Payments_History_View(SearchForm):
    """ Shows each payment in history, with a search form.
    """
    title = MSG(u'Payments history')
    access = 'is_admin'

    batch_msg1 = MSG(u"There is 1 payment.")
    batch_msg2 = MSG(u"There are {n} payments.")

    search_template = '/ui/backoffice/payments/history_view_search.xml'
    search_schema = {'ref': String, 'user': String, 'state': Boolean}

    search_widgets = [
        TextWidget('ref', title=MSG(u'Reference')),
        TextWidget('user', title=MSG(u'Customer')),
    ]

    def get_search_namespace(self, resource, context):
        query = context.query
        namespace = {'widgets': []}
        for widget in self.search_widgets:
            value = context.query[widget.name]
            html = widget.to_html(self.search_schema[widget.name], value)
            namespace['widgets'].append({'title': widget.title, 'html': html})
        return namespace

    table_columns = [('complete_id', MSG(u'Id')), ('state', u' '),
                     ('ts', MSG(u'Date and Time')),
                     ('user_title', MSG(u'Customer')), ('ref', MSG(u'Ref')),
                     ('amount', MSG(u'Amount')),
                     ('payment_mode', MSG(u'Payment mode')),
                     ('advance_state', MSG(u'State')), ('buttons', None)]

    buttons_template = """
        <a href=";manage_payment?payment_way={way}&amp;id_payment={id}">
          <img src="/ui/icons/16x16/view.png"/>
        </a>
        """

    def get_items(self, resource, context):
        queries = []
        for key in self.search_schema.keys():
            if context.query[key]:
                queries.append(PhraseQuery(key, context.query[key]))
        return resource.get_payments_items(context, queries=queries)

    def get_item_value(self, resource, context, item, column):
        if column == 'buttons':
            kw = {'id': item['id'], 'way': item['payment_mode']}
            return XMLParser(self.buttons_template.format(**kw))

        if column == 'payment_mode':
            payment_mode = item['payment_mode']
            return PaymentWaysEnumerate.get_value(payment_mode)
        elif column == 'user_title':
            return item['user_title'], '/users/%s' % item['username']
        elif column == 'state':
            return item[column] and MSG(u'OK') or ''
        return item[column]

    def sort_and_batch(self, resource, context, items):
        # Sort
        sort_by = context.query['sort_by']
        reverse = context.query['reverse']
        if sort_by:
            items.sort(key=itemgetter(sort_by), reverse=reverse)

        # Batch
        start = context.query['batch_start']
        size = context.query['batch_size']
        return items[start:start + size]
示例#40
0
class OrderedFolder_BrowseContent(Folder_BrowseContent):

    query_schema = Folder_BrowseContent.query_schema.copy()
    query_schema['sort_by'] = query_schema['sort_by'](default='order')
    query_schema['reverse'] = query_schema['reverse'](default=False)

    table_columns = (Folder_BrowseContent.table_columns +
                     [('order', MSG(u'Order'))])

    def get_table_actions(self, resource, context):
        proxy = super(OrderedFolder_BrowseContent, self)
        buttons = proxy.get_table_actions(resource, context)

        buttons = list(buttons)
        buttons += [OrderUpButton, OrderDownButton, OrderTopButton,
                    OrderBottomButton]
        if resource.allow_to_unorder_items:
            buttons += [OrderButton, UnOrderButton]

        return buttons


    def get_search_query(self, resource, context):
        proxy = super(OrderedFolder_BrowseContent, self)
        query = proxy.get_search_query(resource, context)
        if resource.base_classes:
            query.append(PhraseQuery('base_classes', resource.base_classes))
        return query


    def get_key_sorted_by_order(self):
        context = get_context()
        ordered_names = list(context.resource.get_ordered_values())
        nb_ordered_names = len(ordered_names)
        def key(item):
            try:
                return ordered_names.index(item.name)
            except ValueError:
                return nb_ordered_names

        return key


    def get_item_value(self, resource, context, item, column):
        if column == 'order':
            ordered_ids = list(resource.get_ordered_values())
            if item.name in ordered_ids:
                return ordered_ids.index(item.name) + 1
            return MSG(u'Not ordered')

        proxy = super(OrderedFolder_BrowseContent, self)
        return proxy.get_item_value(resource, context, item, column)


    ######################################################################
    # Actions
    ######################################################################
    def action_remove(self, resource, context, form):
        # Remove from ordered list
        resource.order_remove(form['ids'])
        # Super
        proxy = super(OrderedFolder_BrowseContent, self)
        return proxy.action_remove(resource, context, form)


    def action_order_up(self, resource, context, form):
        ids = form['ids']
        resource.order_up(ids)
        context.message = INFO(u'Resources ordered up.')


    def action_order_down(self, resource, context, form):
        ids = form['ids']
        resource.order_down(ids)
        context.message = INFO(u'Resources ordered down.')


    def action_order_top(self, resource, context, form):
        ids = form['ids']
        resource.order_top(ids)
        context.message = INFO(u'Resources ordered on top.')


    def action_order_bottom(self, resource, context, form):
        ids = form['ids']
        resource.order_bottom(ids)
        context.message = INFO(u'Resources ordered on bottom.')


    def action_add_to_ordered(self, resource, context, form):
        ids = form['ids']
        resource.order_add(ids)
        context.message = INFO(u'Resources ordered on bottom.')


    def action_remove_from_ordered(self, resource, context, form):
        ids = form['ids']
        resource.order_remove(ids)
        context.message = INFO(u'Resources unordered.')
示例#41
0
                options.append({
                    'name': quote(i_abspath),
                    'value': item.get_title(),
                    'selected': i_abspath in value
                })
        # Si 1 option, elle est sélectionnée
        if len(options) == 1:
            options[0]['selected'] = True
        options.sort(key=itemgetter('value'))
        return options


###########################################################################
# Common widgets to reuse
###########################################################################
title_widget = TextWidget('title', title=MSG(u'Title'))
description_widget = MultilineWidget('description',
                                     title=MSG(u'Description'),
                                     rows=8)
subject_widget = TextWidget('subject',
                            title=MSG(u'Keywords'),
                            tip=MSG(u'Separated by comma'))
timestamp_widget = HiddenWidget('timestamp')
file_widget = FileWidget('file', title=MSG(u'Replace file'))
editarea_widget = EditAreaWidget('data', title=MSG(u'Body'))

# Registry with {datatype: widget, ...}
widgets_registry = {
    Boolean: RadioWidget,
    Date: DateWidget,
    DateTime: DatetimeWidget,
示例#42
0
class JS(Text):

    class_id = 'application/x-javascript'
    class_title = MSG(u'Javascript')
    class_icon16 = '/ui/ikaaro/icons/16x16/js.png'
    class_icon48 = '/ui/ikaaro/icons/48x48/js.png'
示例#43
0
文件: cc.py 项目: staverne/ikaaro
class RegisterForm(AutoForm):
    access = 'is_allowed_to_view'
    title = MSG(u"Subscription")
    schema = freeze({'email': Email(mandatory=True)})
    widgets = freeze([TextWidget('email', title=MSG(u"E-mail Address"))])
    query_schema = freeze({'email': Email})
    actions = [RegisterButton, UnregisterButton]

    # Messages
    msg_user_already_subscribed = MSG_USER_ALREADY_SUBSCRIBED
    msg_confirmation_sent = MSG_CONFIRMATION_SENT
    msg_user_subscribed = MSG_USER_SUBSCRIBED
    msg_user_already_unsubscribed = MSG_USER_ALREADY_UNSUBSCRIBED
    msg_user_unsubscribed = MSG_USER_UNSUBSCRIBED

    def get_widgets(self, resource, context):
        widgets = super(RegisterForm, self).get_widgets(resource, context)
        if context.user:
            # E-mail becomes hard coded
            widgets = list(widgets)
            email = widgets[0]
            widgets[0] = ReadOnlyWidget(name=email.name,
                                        focus=True,
                                        title=email.title)
        return widgets

    def get_value(self, resource, context, name, datatype):
        if name == 'email':
            if context.user:
                return context.user.get_value('email')
            return context.query['email']
        proxy = super(RegisterForm, self)
        return proxy.get_value(self, resource, context, name, datatype)

    def action_register(self, resource, context, form):
        root = context.root
        email = form['email']
        existing_user = root.get_user_from_login(email)

        if existing_user is not None:
            username = existing_user.name
            if resource.is_subscribed(username, skip_unconfirmed=False):
                context.message = self.msg_user_already_subscribed
                return

        # Create user anyhow
        user = resource.subscribe_user(email=email, user=existing_user)

        if context.user is None:
            # Anonymous subscription
            resource.send_confirm_register(user, context)
            context.message = self.msg_confirmation_sent
        else:
            resource.after_register(user.name)
            context.message = self.msg_user_subscribed

    def action_unregister(self, resource, context, form):
        user = context.root.get_user_from_login(form['email'])
        if user is None:
            context.message = self.msg_user_already_unsubscribed
            return

        username = user.name
        if not resource.is_subscribed(username, skip_unconfirmed=False):
            context.message = self.msg_user_already_unsubscribed
            return

        if context.user is None:
            # Anonymous subscription
            resource.send_confirm_register(user, context, unregister=True)
            context.message = self.msg_confirmation_sent
        else:
            resource.unsubscribe_user(username)
            resource.after_unregister(username)
            context.message = self.msg_user_unsubscribed
示例#44
0
文件: views.py 项目: hforge/itws
 def get_title(self, context):
     if self.title is not None:
         return self.title
     class_title = self.add_cls.class_title.gettext()
     title = MSG(u'Add {class_title}')
     return title.gettext(class_title=class_title)
示例#45
0
文件: cc.py 项目: staverne/ikaaro
class ConfirmSubscription(AutoForm):

    access = 'is_allowed_to_view'
    title = MSG(u"Subscribe")
    description = MSG(
        u'By confirming your subscription to this resource you will'
        u' receive an email every time this resource is modified.')

    schema = freeze({
        'key': String(mandatory=True),
        'email': Email(mandatory=True)
    })
    widgets = freeze([HiddenWidget('key'), ReadOnlyWidget('email')])
    actions = [Button(access=True, title=MSG(u'Confirm subscription'))]

    key_status = 'S'
    msg_already = MSG_USER_ALREADY_SUBSCRIBED

    def get_value(self, resource, context, name, datatype):
        if name in ('key', 'email'):
            return context.get_query_value(name)
        proxy = super(ConfirmSubscription, self)
        return proxy.get_value(resource, context, name, datatype)

    def get_username(self, resource, context, key):
        # 1. Get the user
        email = context.get_form_value('email')
        user = context.root.get_user_from_login(email)
        if user is None:
            return None, MSG(u'Bad email')

        # 2. Get the user key
        username = user.name
        user_key = resource.get_register_key(username, self.key_status)
        if user_key is None:
            return username, self.msg_already

        # 3. Check the key
        if user_key != key:
            return username, MSG_BAD_KEY

        # 4. Ok
        return username, None

    def get_namespace(self, resource, context):
        key = context.get_form_value('key')
        username, error = self.get_username(resource, context, key)
        if error:
            return context.come_back(error, goto='./')

        proxy = super(ConfirmSubscription, self)
        return proxy.get_namespace(resource, context)

    def action(self, resource, context, form):
        username, error = self.get_username(resource, context, form['key'])
        if error:
            context.message = error
            return

        # Ok
        resource.reset_register_key(username)
        resource.after_register(username)
        return context.come_back(MSG_USER_SUBSCRIBED, goto='./')
示例#46
0
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

# Import from standard library
from datetime import datetime, timedelta
from operator import itemgetter
from traceback import print_exc

# Import from itools
from itools.database import AndQuery, PhraseQuery, RangeQuery
from itools.gettext import MSG
from itools.web import STLView, ERROR

ERROR_MSG = MSG(
    u'Inconsistent class_id "{class_id}", resource version is {resource_version} but cls_version is {cls_version} ({abspath})'
)


def class_version_to_date(version):
    return datetime.strptime(version[:8], '%Y%m%d').date()


def find_versions_to_update(context, force=False):
    database = context.database
    cls_errors = []
    cls_to_update = []
    # Find classes
    for cls in database.get_resource_classes():
        # Class version
        class_version = class_version_to_date(cls.class_version)
示例#47
0
文件: cc.py 项目: staverne/ikaaro
class MassSubscriptionForm(AutoForm):

    access = 'is_admin'
    title = MSG(u"Mass Subscription")
    description = MSG(
        u"An invitation will be sent to every address typen below, one by"
        u" line.")
    schema = freeze({'emails': MultiLinesTokens(mandatory=True)})
    widgets = freeze([MultilineWidget(
        'emails',
        focus=False,
    )])
    actions = [MassSubscribeButton, Button]  # len(actions) > 1

    def get_value(self, resource, context, name, datatype):
        if name == 'emails':
            return ''
        proxy = super(MassSubscriptionForm, self)
        return proxy.get_value(resource, context, name, datatype)

    def action_mass_subscribe(self, resource, context, form):
        root = context.root

        already = []
        unallowed = []
        invited = []
        invalid = []
        subscribed_users = resource.get_subscribed_users()
        for email in form['emails']:
            email = email.strip()
            if not email:
                continue
            # Check if email is valid
            if not Email.is_valid(email):
                invalid.append(email)
                continue

            # Checks
            user = root.get_user_from_login(email)
            if user:
                if user.name in subscribed_users:
                    already.append(user)
                    continue
                if not resource.is_subscription_allowed(user.name):
                    unallowed.append(user)
                    continue

            # Subscribe
            user = resource.subscribe_user(email=email, user=user)
            key = resource.set_register_key(user.name)
            # Send invitation
            subject = resource.invitation_subject.gettext()
            confirm_url = context.uri.resolve(';accept_invitation')
            confirm_url.query = {'key': key, 'email': email}
            text = resource.invitation_text.gettext(uri=confirm_url)
            root.send_email(email, subject, text=text)
            invited.append(user)

        # Ok
        context.message = []
        add_subscribed_message(MSG_ALREADY, already, context)
        add_subscribed_message(MSG_INVALID,
                               invalid,
                               context,
                               users_is_resources=False)
        add_subscribed_message(MSG_INVITED, invited, context)
        add_subscribed_message(MSG_UNALLOWED, unallowed, context)
示例#48
0
文件: messages.py 项目: kennym/itools
 def gettext(self, language=None):
     # Gettext calling was defered
     return MSG.gettext(self, language=language, **self.kw)
示例#49
0
文件: cc.py 项目: staverne/ikaaro
class UnsubscribeButton(SubscribeButton):
    name = 'unsubscribe'
    title = MSG(u"Unsubscribe")
示例#50
0
class Lastname_Field(Text_Field):

    title = MSG(u'Last Name')
    multilingual = False
    indexed = True
    stored = True
示例#51
0
class OrderTopButton(BrowseButton):

    access = 'is_allowed_to_edit'
    name = 'order_top'
    title = MSG(u'Order top')
示例#52
0
def find_versions_to_update(context, force=False):
    database = context.database
    cls_errors = []
    cls_to_update = []
    # Find classes
    for cls in database.get_resource_classes():
        # Class version
        class_version = class_version_to_date(cls.class_version)
        class_version_tomorrow = class_version + timedelta(days=1)
        # Search for code older than the instance
        query = AndQuery(
            PhraseQuery('format', cls.class_id),
            RangeQuery('class_version', class_version_tomorrow, None))
        search = database.search(query)
        if search:
            resource = search.get_resources().next()
            kw = {
                'class_id': resource.class_id,
                'class_title': resource.class_title,
                'abspath': str(resource.abspath),
                'resource_version': resource.metadata.version,
                'cls_version': resource.class_version
            }
            cls_errors.append(kw)
            if force is False:
                break
        # Find out the versions to upgrade
        classes_and_versions = []
        for sub_cls in cls.mro():
            for name in sub_cls.__dict__.keys():
                if not name.startswith('update_'):
                    continue
                kk, version = name.split('_', 1)
                if len(version) != 8:
                    continue
                if not version.isdigit():
                    continue
                class_version = class_version_to_date(version)
                if class_version > class_version_to_date(cls.class_version):
                    msg = "'{0}' class_version is bad ({1} > {2})"
                    msg = msg.format(sub_cls.class_id, version,
                                     cls.class_version)
                    raise ValueError(msg)
                class_version_yesterday = class_version - timedelta(days=1)
                query = AndQuery(
                    PhraseQuery('format', cls.class_id),
                    RangeQuery('class_version', None, class_version_yesterday))
                search = database.search(query)
                if not search:
                    continue
                class_and_version = (cls.class_id, version)
                if class_and_version in classes_and_versions:
                    # Overriden update method in sub classes
                    # So update method should be done one time
                    continue
                classes_and_versions.append(class_and_version)
                update_title_name = 'update_{0}_title'.format(version)
                update_title = getattr(cls, update_title_name, MSG(u'Unknow'))
                if isinstance(update_title, MSG):
                    update_title = update_title.gettext()
                kw = {
                    'class_id': cls.class_id,
                    'class_title': cls.class_title,
                    'class_version': version,
                    'class_version_date': class_version,
                    'class_version_pretty': context.format_date(class_version),
                    'update_title': update_title,
                    'nb_resources': len(search)
                }
                cls_to_update.append(kw)
    # Sort
    cls_to_update.sort(key=itemgetter('class_version_date'))
    # Ok
    return {'cls_to_update': cls_to_update, 'cls_errors': cls_errors}
示例#53
0
def say_hello():
    message = MSG(u'Hello World')
    print message.gettext()
示例#54
0
class OrderBottomButton(BrowseButton):

    access = 'is_allowed_to_edit'
    name = 'order_bottom'
    title = MSG(u'Order bottom')