Beispiel #1
0
 def _wiki_link(self, req, args, kwargs, wiki, label, a_class, check=None):
     """Build links to wiki pages."""
     check_sign = None
     url = self.env.href.wiki(wiki)
     if WikiSystem(self.env).has_page(wiki.lstrip("/")):
         a_class += " page"
         title = _("Go to page %s") % wiki
         if check and check[0] == "link":
             chrome_path = "/".join([req.base_path, "chrome"])
             ok_img = "wikicalendar/check_ok.png"
             ok = tag.image(src="/".join([chrome_path, ok_img]), alt="ok", title="ok")
             nok_img = "wikicalendar/check_nok.png"
             nok = tag.image(src="/".join([chrome_path, nok_img]), alt="X", title="X")
             unk_img = "wikicalendar/check_unknown.png"
             unk = tag.image(src="/".join([chrome_path, unk_img]), alt="?", title="?")
             result = self._do_check(check[1], wiki)
             check_sign = result and (result == 1 and ok or nok) or unk
     else:
         # The default (empty page) is used, if template name is invalid.
         url += "?action=edit"
         # Add page template to create new wiki pages, if specified.
         template = None
         if len(args) >= 6 or kwargs.has_key("base"):
             try:
                 template = kwargs["base"]
             except KeyError:
                 template = args[5]
         if template:
             url += "&template=" + template
         title = _("Create page %s") % wiki
     link = tag.a(tag(label), href=url)
     link(class_=a_class, title_=title)
     return tag(link, check_sign)
Beispiel #2
0
def _render_change(old, new):
    rendered = None
    if old and not new:
        rendered = tag(
            Markup(_("%(value)s reset to default value", value=tag.em(old))))
    elif new and not old:
        rendered = tag(
            Markup(_("from default value set to %(value)s",
                     value=tag.em(new))))
    elif old and new:
        if len(old) < 20 and len(new) < 20:
            rendered = tag(
                Markup(
                    _("changed from %(old)s to %(new)s",
                      old=tag.em(old),
                      new=tag.em(new))))
        else:
            nbsp = tag.br()
            # TRANSLATOR: same as before, but with additional line breaks
            rendered = tag(
                Markup(
                    _("changed from %(old)s to %(new)s",
                      old=tag.em(nbsp, old),
                      new=tag.em(nbsp, new))))
    return rendered
Beispiel #3
0
    def render_registration_fields(self, req, data):
        """Add a hidden text input field to the registration form, and
        a visible one with mandatory input as well, if token is configured.
        """
        if self.reg_basic_token:
            # Preserve last input for editing on failure instead of typing
            # everything again.
            old_value = req.args.get('basic_token', '')

            # TRANSLATOR: Hint for visible bot trap registration input field.
            hint = tag.p(Markup(
                _("""Please type [%(token)s] as verification token,
                exactly replicating everything within the braces.""",
                  token=tag.b(self.reg_basic_token))),
                         class_='hint')
            insert = tag(
                tag.label(
                    _("Parole:"),
                    tag.input(type='text',
                              name='basic_token',
                              size=20,
                              class_='textwidget',
                              value=old_value)), hint)
        else:
            insert = None
        # TRANSLATOR: Registration form hint for hidden bot trap input field.
        insert = tag(
            insert,
            tag.input(type='hidden',
                      name='sentinel',
                      title=_("Better do not fill this field.")))
        return insert, data
Beispiel #4
0
 def format_search_results(self, res):
     title = res['hilited_name'] or res['name']
     product = res.get('product')
     if product:
         return tag(u'[', product, u'] ', title)
     else:
         return tag(title)
Beispiel #5
0
 def render_timeline_event(self, context, field, event):
     bp_resource, bp, bc = event[3]
     compat_format_0_11_2 = 'oneliner'
     if hasattr(context, '_hints'):
         compat_format_0_11_2 = None
     if bc:  # A blog comment
         if field == 'url':
             return context.href.blog(bp.name) + '#comment-%d' % bc.number
         elif field == 'title':
             return tag('Blog: ', tag.em(bp.title), ' comment added')
         elif field == 'description':
             comment = compat_format_0_11_2 and shorten_line(bc.comment) \
                         or bc.comment
             return format_to(self.env, compat_format_0_11_2,
                              context(resource=bp_resource), comment)
     else:  # A blog post
         if field == 'url':
             return context.href.blog(bp.name)
         elif field == 'title':
             return tag('Blog: ', tag.em(bp.title),
                        bp.version > 1 and ' edited' or ' created')
         elif field == 'description':
             comment = compat_format_0_11_2 and shorten_line(bp.version_comment) \
                         or bp.version_comment
             return format_to(self.env, compat_format_0_11_2,
                              context(resource=bp_resource), comment)
Beispiel #6
0
 def render_timeline_event(self, context, field, event):
     # Decompose event data.
     title, description, path = event[3]
     # Return apropriate content.
     if field == 'url':
         if not path:
             # method is DELETE
             return ''
         files_core = FilesCoreComponent(self.env)
         req = None
         try:
             req = context.req
         except AttributeError as e:
             pass
         download_config = files_core.files_download_config(req=req)
         node = FileSystemNode(download_config.base_path)
         node.populate_file_data(get_normalized_relative_path(node.base_path, path,
             assume_relative_path=True))
         if node.exists():
             return context.href.files(node.relative_path)
         else:
             return ""
     elif field == 'title':
         return tag(title)
     elif field == 'description':
         return tag(description)
 def render_timeline_event(self, context, field, event):
     # Decompose event data.
     title, description, path = event[3]
     # Return apropriate content.
     if field == 'url':
         if not path:
             # method is DELETE
             return ''
         files_core = FilesCoreComponent(self.env)
         req = None
         try:
             req = context.req
         except AttributeError as e:
             pass
         download_config = files_core.files_download_config(req=req)
         node = FileSystemNode(download_config.base_path)
         node.populate_file_data(
             get_normalized_relative_path(node.base_path,
                                          path,
                                          assume_relative_path=True))
         if node.exists():
             return context.href.files(node.relative_path)
         else:
             return ""
     elif field == 'title':
         return tag(title)
     elif field == 'description':
         return tag(description)
Beispiel #8
0
 def get_resource_description(self, resource, format=None, **kwargs):
     env = self.env
     href = kwargs.get('href')
     if resource.parent is None:
         return _("Unparented form %(id)s", id=resource.id)
     parent_name = get_resource_name(env, resource.parent)
     parent_url = href and \
                  get_resource_url(env, resource.parent, href) or None
     parent = parent_url is not None and \
              tag.a(parent_name, href=parent_url) or parent_name
     # DEVEL: resource description not implemented yet
     #if format == 'summary':
     #    return Form(self.env, resource).description
     if resource.id:
         if format == 'compact':
             return _("Form %(form_id)s (%(parent)s)", form_id=resource.id,
                      parent=get_resource_shortname(env, resource.parent))
         # TRANSLATOR: Most verbose title, i.e. for form history page
         return tag(Markup(_("Form %(form_id)s (in %(parent)s)",
                     form_id=resource.id, parent=parent)))
     else:
         # TRANSLATOR: Title printed i.e. in form select page
         if format == 'compact':
             return tag(Markup(_("Forms (%(parent)s)", parent=parent)))
         return tag(Markup(_("Forms in %(parent)s", parent=parent)))
 def serializeNode(self, node, indent):
     if node.type == simpletree.TextNode.type:
         if (node.parent.name not in html5lib.constants.rcdataElements
             and node.parent.name != "plaintext"):
             value = cgi.escape(node.value, True)
         else:
             value = node.value
         if node.parent.name in ("pre", "textarea"):
             value = "\n" + value
         rv = tag.code(value, class_="text")
     elif node.type == simpletree.Element.type:
         rv = tag("")
         rv.append(tag.code("<" + node.name, class_=tagClasses["element"]))
         if node.attributes:
             for key, value in node.attributes.iteritems():
                 value = cgi.escape(value, True)
                 rv.append(tag(" ", tag.code(key,
                                             class_=tagClasses["attr_name"]),
                           "=", tag.code("\""+value+"\"",
                                         class_=tagClasses["attr_value"])))
         rv.append(tag.code(">", class_=tagClasses["element"]))    
     elif node.type == simpletree.CommentNode.type:
         rv = tag.code("<!--"+node.data+"-->", class_=tagClasses["comment"])
     elif node.type == simpletree.DocumentType.type:
         rv = tag.code("<!DOCTYPE " + node.name + ">", class_=tagClasses["doctype"])
     return rv
Beispiel #10
0
 def render_timeline_event(self, context, field, event):
     bp_resource, bp, bc = event[3]
     compat_format_0_11_2 = 'oneliner'
     if hasattr(context, '_hints'):
          compat_format_0_11_2 = None
     if bc: # A blog comment
         if field == 'url':
             return context.href.blog(bp.name) + '#comment-%d' % bc.number
         elif field == 'title':
             return tag('Blog: ', tag.em(bp.title), ' comment added')
         elif field == 'description':
             comment = compat_format_0_11_2 and shorten_line(bc.comment) \
                         or bc.comment
             return format_to(self.env, compat_format_0_11_2,
                         context(resource=bp_resource), comment)
     else: # A blog post
         if field == 'url':
             return context.href.blog(bp.name)
         elif field == 'title':
             return tag('Blog: ', tag.em(bp.title),
                     bp.version > 1 and ' edited' or ' created')
         elif field == 'description':
             comment = compat_format_0_11_2 and shorten_line(bp.version_comment) \
                         or bp.version_comment
             return format_to(self.env, compat_format_0_11_2,
                     context(resource=bp_resource), comment)
Beispiel #11
0
    def _render_ticket_event(self, field, context):
        if (field == 'url'):
            self._read_idx += 1  #next index now

        #call the original render function
        output = self._old_render_fn[self._read_idx](field, context)

        if field == 'title':  #now it's time to insert the project name
            #split the whole string until we can insert
            splitted_output = to_unicode(output).split("</em>")
            tooltip = splitted_output[0].split('\"')
            ticket_no = splitted_output[0].split('>')
            if len(tooltip) == 3:  #it's a ticket
                #now rebuild the puzzle by inserting the name
                output = tag(
                    'Ticket' + ' ', tag.em(ticket_no[1],
                                           title=tooltip[1]), ' ',
                    tag.span(self._current_project[self._read_idx],
                             style="background-color: #ffffd0;"),
                    splitted_output[1])
            elif len(tooltip) == 1 and len(
                    splitted_output) == 3:  #it's an attachment
                output += tag(
                    ' ',
                    tag.span(self._current_project[self._read_idx],
                             style="background-color: #ffffd0;"))
        return output
Beispiel #12
0
 def render_registration_fields(self, req, data):
     """Add an email address text input field to the registration form."""
     # Preserve last input for editing on failure instead of typing
     # everything again.
     old_value = req.args.get('email', '').strip()
     insert = tag.label(_("Email:"),
                        tag.input(type='text', name='email', size=20,
                                  class_='textwidget', value=old_value)
              )
     # Deferred import required to aviod circular import dependencies.
     from acct_mgr.web_ui import AccountModule
     reset_password = AccountModule(self.env).reset_password_enabled
     verify_account = is_enabled(self.env, EmailVerificationModule) and \
                      EmailVerificationModule(self.env).verify_email
     if verify_account:
         # TRANSLATOR: Registration form hints for a mandatory input field.
         hint = tag.p(_("""The email address is required for Trac to send
                        you a verification token."""), class_='hint')
         if reset_password:
             hint = tag(hint, tag.p(_(
                        """Entering your email address will also enable you
                        to reset your password if you ever forget it."""),
                        class_='hint')
                    )
         return tag(insert, hint), data
     elif reset_password:
         # TRANSLATOR: Registration form hint, if email input is optional.
         hint = tag.p(_("""Entering your email address will enable you to
                        reset your password if you ever forget it."""),
                      class_='hint')
         return dict(optional=tag(insert, hint)), data
     else:
         # Always return the email text input itself as optional field.
         return dict(optional=insert), data
Beispiel #13
0
 def _render_property(self, name, mode, context, props):
     repos, revs = props[name]
     def link(rev):
         chgset = repos.get_changeset(rev)
         return tag.a(rev, class_="changeset",
                      title=shorten_line(chgset.message),
                      href=context.href.changeset(rev, repos.reponame))
     if name == 'Parents' and len(revs) == 2: # merge
         new = context.resource.id
         parent_links = [
                 (link(rev), ' (',
                  tag.a('diff', title=_("Diff against this parent "
                        "(show the changes merged from the other parents)"),
                        href=context.href.changeset(new, repos.reponame, 
                                                    old=rev)), ')')
                        for rev in revs]
         return tag([(parent, ', ') for parent in parent_links[:-1]],
                    parent_links[-1], tag.br(),
                    tag.span(tag_("Note: this is a %(merge)s changeset, "
                                  "the changes displayed below correspond "
                                  "to the merge itself.",
                                  merge=tag.strong('merge')),
                             class_='hint'), tag.br(), 
                    # TODO: only keep chunks present in both parents 
                    #       (conflicts) or in none (extra changes)
                    # tag.span('No changes means the merge was clean.',
                    #         class_='hint'), tag.br(), 
                    tag.span(tag_("Use the %(diff)s links above to see all "
                                  "the changes relative to each parent.",
                                  diff=tag.tt('(diff)')),
                             class_='hint'))
     return tag([tag(link(rev), ', ') for rev in revs[:-1]],
                link(revs[-1]))
 def render_registration_fields(self, req, data):
     """Add an email address text input field to the registration form."""
     # Preserve last input for editing on failure instead of typing
     # everything again.
     old_value = req.args.get('email', '').strip()
     insert = tag.label(_("Email:"),
                        tag.input(type='text', name='email', size=20,
                                  class_='textwidget', value=old_value)
              )
     # Deferred import required to aviod circular import dependencies.
     from acct_mgr.web_ui import AccountModule
     reset_password = AccountModule(self.env).reset_password_enabled
     verify_account = is_enabled(self.env, EmailVerificationModule) and \
                      EmailVerificationModule(self.env).verify_email
     if verify_account:
         # TRANSLATOR: Registration form hints for a mandatory input field.
         hint = tag.p(_("""The email address is required for Trac to send
                        you a verification token."""), class_='hint')
         if reset_password:
             hint = tag(hint, tag.p(_(
                        """Entering your email address will also enable you
                        to reset your password if you ever forget it."""),
                        class_='hint')
                    )
         return tag(insert, hint), data
     elif reset_password:
         # TRANSLATOR: Registration form hint, if email input is optional.
         hint = tag.p(_("""Entering your email address will enable you to
                        reset your password if you ever forget it."""),
                      class_='hint')
         return dict(optional=tag(insert, hint)), data
     else:
         # Always return the email text input itself as optional field.
         return dict(optional=insert), data
Beispiel #15
0
 def _do_account(self, req):
     if not req.authname or req.authname == 'anonymous':
         req.redirect(req.href.wiki())
     action = req.args.get('action')
     delete_enabled = AccountManager(self.env).supports('delete_user')
     data = {'delete_enabled': delete_enabled}
     force_change_password = req.session.get('force_change_passwd', False)
     if req.method == 'POST':
         if action == 'save':
             data.update(self._do_change_password(req))
             if force_change_password:
                 del(req.session['force_change_passwd'])
                 req.session.save()
                 chrome.add_notice(req, Markup(tag(
                     "Thank you for taking the time to update your password."
                 )))
                 force_change_password = False
         elif action == 'delete' and delete_enabled:
             data.update(self._do_delete(req))
         else:
             data.update({'error': 'Invalid action'})
     if force_change_password:
         chrome.add_warning(req, Markup(tag(
             "You are required to change password because of a recent "
             "password change request. ",
             tag.b("Please change your password now."))))
     return data
Beispiel #16
0
    def render_registration_fields(self, req, data):
        """Add a hidden text input field to the registration form, and
        a visible one with mandatory input as well, if token is configured.
        """
        if self.reg_basic_token:
            # Preserve last input for editing on failure instead of typing
            # everything again.
            old_value = req.args.get('basic_token', '')

            # TRANSLATOR: Hint for visible bot trap registration input field.
            hint = tag.p(Markup(_(
                """Apologies for the inconvenience, but please use the Sugarlabs Wiki,
                find the page referring to find the gold in the pot, and insert here
                the four words on the second line, or send mail to systems mailing list.""",
                token=tag.b(self.reg_basic_token))), class_='hint')
            insert = tag(
                tag.label(_("Parole:"),
                          tag.input(type='text', name='basic_token', size=20,
                                    class_='textwidget', value=old_value)),
                          hint
                )
        else:
            insert = None
        # TRANSLATOR: Registration form hint for hidden bot trap input field.
        insert = tag(insert,
                     tag.input(type='hidden', name='sentinel',
                               title=_("Better do not fill this field."))
                 )
        return insert, data
Beispiel #17
0
 def format_search_results(self, res):
     title = res['hilited_name'] or res['name']
     product = res.get('product')
     if product:
         return tag(u'[', product, u'] ', title)
     else:
         return tag(title)
Beispiel #18
0
 def _gen_wiki_links(self, wiki, label, a_class, url, wiki_page_template,
                     check=None):
     check_sign = None
     if WikiSystem(self.env).has_page(wiki.lstrip('/')):
         a_class += " page"
         title = _("Go to page %s") % wiki
         if check and check[0] == 'link':
             chrome_path = '/'.join([self.ref.req.base_path, 'chrome'])
             ok_img = 'wikicalendar/check_ok.png'
             ok = tag.image(src='/'.join([chrome_path, ok_img]),
                            alt='ok', title='ok')
             nok_img = 'wikicalendar/check_nok.png'
             nok = tag.image(src='/'.join([chrome_path, nok_img]),
                             alt='X', title='X')
             unk_img = 'wikicalendar/check_unknown.png'
             unk = tag.image(src='/'.join([chrome_path, unk_img]),
                             alt='?', title='?')
             result = self._do_check(check[1], wiki)
             check_sign = result and (result == 1 and ok or nok) or unk
     else:
         url += "?action=edit"
         # adding template name, if specified
         if wiki_page_template != "":
             url += "&template=" + wiki_page_template
         title = _("Create page %s") % wiki
     link = tag.a(tag(label), href=url)
     link(class_=a_class, title_=title)
     return tag(link, check_sign)
Beispiel #19
0
    def _format_reminder(self,
                         req,
                         ticket,
                         id,
                         time,
                         author,
                         origin,
                         description,
                         delete_button=True):
        now = to_datetime(None)
        time = to_datetime(time)
        if now >= time:
            when = tag(tag.strong("Right now"), " (pending)")
        else:
            when = tag("In ", tag.strong(pretty_timedelta(time)), " (",
                       format_date(time), ")")

        if description:
            context = Context.from_request(req, ticket.resource)
            desc = tag.div(format_to_oneliner(self.env, context, description),
                           class_="description")
        else:
            desc = tag()

        return tag(
            self._reminder_delete_form(req, id) if delete_button else None,
            when, " - added by ",
            tag.em(Chrome(self.env).authorinfo(req, author)), " ",
            tag.span(pretty_timedelta(origin),
                     title=format_datetime(
                         origin, req.session.get('datefmt', 'iso8601'),
                         req.tz)), " ago.", desc)
Beispiel #20
0
    def render_registration_fields(self, req, data):
        """Add a hidden text input field to the registration form, and
        a visible one with mandatory input as well, if token is configured.
        """
        if self.reg_basic_token:
            # Preserve last input for editing on failure instead of typing
            # everything again.
            old_value = req.args.get('basic_token', '')

            # TRANSLATOR: Hint for visible bot trap registration input field.
            hint = tag.p(Markup(_(
                """Please type [%(token)s] as verification token,
                exactly replicating everything within the braces.""",
                token=tag.b(self.reg_basic_token))), class_='hint')
            insert = tag(
                tag.label(_("Parole:"),
                          tag.input(type='text', name='basic_token', size=20,
                                    class_='textwidget', value=old_value)),
                          hint
                )
        else:
            insert = None
        # TRANSLATOR: Registration form hint for hidden bot trap input field.
        insert = tag(insert,
                     tag.input(type='hidden', name='sentinel',
                               title=_("Better do not fill this field."))
                 )
        return insert, data
Beispiel #21
0
 def get_resource_description(self, resource, format=None, **kwargs):
     env = self.env
     href = kwargs.get('href')
     if resource.parent is None:
         return _("Unparented form %(id)s", id=resource.id)
     parent_name = get_resource_name(env, resource.parent)
     parent_url = href and \
                  get_resource_url(env, resource.parent, href) or None
     parent = parent_url is not None and \
              tag.a(parent_name, href=parent_url) or parent_name
     # DEVEL: resource description not implemented yet
     #if format == 'summary':
     #    return Form(self.env, resource).description
     if resource.id:
         if format == 'compact':
             return _("Form %(form_id)s (%(parent)s)", form_id=resource.id,
                      parent=get_resource_shortname(env, resource.parent))
         # TRANSLATOR: Most verbose title, i.e. for form history page
         return tag(Markup(_("Form %(form_id)s (in %(parent)s)",
                     form_id=resource.id, parent=parent)))
     else:
         # TRANSLATOR: Title printed i.e. in form select page
         if format == 'compact':
             return tag(Markup(_("Forms (%(parent)s)", parent=parent)))
         return tag(Markup(_("Forms in %(parent)s", parent=parent)))
Beispiel #22
0
    def handle_edit_locale_admins(self, req, locale_id):
        if not locale_id:
            req.redirect(req.href.admin('translations', 'locales'))

        Session = session(self.env)
        locale = Session.query(Locale).get(int(locale_id))
        known_users = self.env.get_known_users()
        errors = []
        perm = PermissionSystem(self.env)
        sids_without_necessary_perms = []
        for admin in locale.admins:
            if not 'L10N_MODERATE' in perm.get_user_permissions(admin.sid):
                sids_without_necessary_perms.append(admin.sid)

        if sids_without_necessary_perms:
            msg = ngettext(
                "%s does not have the required permissions to administrate." % \
                ', '.join(["'%s'" % s for s in sids_without_necessary_perms]),
                "%s don't have the required permissions to administrate." % \
                ', '.join(["'%s'" % s for s in sids_without_necessary_perms]),
                 len(sids_without_necessary_perms))
            errors.append(
                tag(msg, _(" Don't forget to "),
                    tag.a(_('update permissions'),
                          href=req.href.admin('general', 'perm')), '.'))

        if req.method == 'POST' and len(req.args.getlist('admins')) >= 1:
            current_admins = req.args.getlist('current_admins')
            selected = req.args.getlist('admins')

            self.log.debug('Current Admins: %s', current_admins)
            self.log.debug('Selected Admins: %s', selected)

            allow_delete_admins = len(selected) >= 1
            if not allow_delete_admins:
                errors.append(
                    tag(_("There must be at least on admin for each locale.")))

            for admin in current_admins:
                if not allow_delete_admins:
                    break
                if admin not in selected:
                    locale_admin = Session.query(LocaleAdmin). \
                        filter(locale_admin_table.c.sid==admin).first()
                    Session.delete(locale_admin)
            for admin in selected:
                if admin not in locale.admins:
                    locale.admins.append(LocaleAdmin(locale, admin))
            Session.commit()
            req.redirect(req.href.admin('translations', 'locales'))
        elif req.method == 'POST' and len(req.args.getlist('admins')) < 1:
            errors.append(
                tag(_("There must be at least on admin for each locale.")))

        data = {'locale': locale, 'known_users': known_users}
        if errors:
            data['error'] = tag.ul(*[tag.li(e) for e in errors if e])

        return 'l10n_admin_locale_admins.html', data
Beispiel #23
0
    def validate_registration(self, req):
        if req.path_info == '/prefs':
            return

        acctmgr = AccountManager(self.env)
        username = acctmgr.handle_username_casing(
            req.args.get('username', '').strip())

        if not username:
            raise RegistrationError(N_("Username cannot be empty."))

        # Always exclude some special characters, i.e.
        #   ':' can't be used in HtPasswdStore
        #   '[' and ']' can't be used in SvnServePasswordStore
        blacklist = acctmgr.username_char_blacklist
        if containsAny(username, blacklist):
            pretty_blacklist = ''
            for c in blacklist:
                if pretty_blacklist == '':
                    pretty_blacklist = tag(' \'', tag.b(c), '\'')
                else:
                    pretty_blacklist = tag(pretty_blacklist, ', \'', tag.b(c),
                                           '\'')
            raise RegistrationError(
                N_("The username must not contain any of these characters: %s"
                   ), tag.b(pretty_blacklist))

        # All upper-cased names are reserved for permission action names.
        if username.isupper():
            raise RegistrationError(
                N_("A username with only upper-cased characters is not allowed."
                   ))

        # Prohibit some user names, that are important for Trac and therefor
        # reserved, even if not in the permission store for some reason.
        if username.lower() in ['anonymous', 'authenticated']:
            raise RegistrationError(N_("Username %s is not allowed."),
                                    tag.b(username))

        # NOTE: A user may exist in a password store but not in the permission
        #   store.  I.e. this happens, when the user (from the password store)
        #   never logged in into Trac.  So we have to perform this test here
        #   and cannot just check for the user being in the permission store.
        #   And better obfuscate whether an existing user or group name
        #   was responsible for rejection of this user name.
        for store_user in acctmgr.get_users():
            # Do it carefully by disregarding case.
            if store_user.lower() == username.lower():
                raise RegistrationError(
                    N_("Another account or group already exists, who's name "
                       "differs from %s only by case or is identical."),
                    tag.b(username))

        # Password consistency checks follow.
        password = req.args.get('password')
        if not password:
            raise RegistrationError(N_("Password cannot be empty."))
        elif password != req.args.get('password_confirm'):
            raise RegistrationError(N_("The passwords must match."))
Beispiel #24
0
    def validate_registration(self, req):
        acctmgr = AccountManager(self.env)
        username = acctmgr.handle_username_casing(
            req.args.get('username', '').strip())

        if not username:
            raise RegistrationError(N_("Username cannot be empty."))

        # Always exclude some special characters, i.e. 
        #   ':' can't be used in HtPasswdStore
        #   '[' and ']' can't be used in SvnServePasswordStore
        blacklist = acctmgr.username_char_blacklist
        if containsAny(username, blacklist):
            pretty_blacklist = ''
            for c in blacklist:
                if pretty_blacklist == '':
                    pretty_blacklist = tag(' \'', tag.b(c), '\'')
                else:
                    pretty_blacklist = tag(pretty_blacklist,
                                           ', \'', tag.b(c), '\'')
            raise RegistrationError(N_(
                "The username must not contain any of these characters: %s"),
                tag.b(pretty_blacklist)
            )

        # All upper-cased names are reserved for permission action names.
        if username.isupper():
            raise RegistrationError(N_(
                "A username with only upper-cased characters is not allowed.")
            )
 
        # Prohibit some user names, that are important for Trac and therefor
        # reserved, even if not in the permission store for some reason.
        if username.lower() in ['anonymous', 'authenticated']:
            raise RegistrationError(N_("Username %s is not allowed."),
                                    tag.b(username)
            )

        # NOTE: A user may exist in a password store but not in the permission
        #   store.  I.e. this happens, when the user (from the password store)
        #   never logged in into Trac.  So we have to perform this test here
        #   and cannot just check for the user being in the permission store.
        #   And better obfuscate whether an existing user or group name
        #   was responsible for rejection of this user name.
        for store_user in acctmgr.get_users():
            # Do it carefully by disregarding case.
            if store_user.lower() == username.lower():
                raise RegistrationError(N_(
                    "Another account or group already exists, who's name "
                    "differs from %s only by case or is identical."),
                    tag.b(username)
                )

        # Password consistency checks follow.
        password = req.args.get('password')
        if not password:
            raise RegistrationError(N_("Password cannot be empty."))
        elif password != req.args.get('password_confirm'):
            raise RegistrationError(N_("The passwords must match."))
Beispiel #25
0
    def render_timeline_event(self, context, field, event):
        codereview_page, name, notes, reviewersList = event[3]

        if field == 'url':
            return context.href.peerReviewView(Review=codereview_page.id)
        if field == 'title':
            return tag('Code review ', tag.em(name), ' has been raised')
        if field == 'description':
            return tag('Assigned to: ', reviewersList, tag.br(), ' Additional notes: ', notes)
Beispiel #26
0
 def render_hierarchy(group):
     return tag.ul(
         tag.li(tag(tag.a(elt[0], href=formatter.href.wiki(elt[1]))
                    if elt[1] else tag(elt[0]),
                    render_hierarchy(elt[2]))
                if len(elt) == 3 else
                tag.a('/'.join(elt[0]),
                      href=formatter.href.wiki(elt[1])))
         for elt in group)
Beispiel #27
0
    def format_search_results(self, res):
        #TODO: add better milestone rendering

        name = res['hilited_name'] or res['name']
        product = res.get('product')
        if product:
            return tag(u'[', product, u'] Milestone:', name)
        else:
            return tag(u'Milestone:', name)
Beispiel #28
0
    def format_search_results(self, res):
        #TODO: add better milestone rendering

        name = res['hilited_name'] or res['name']
        product = res.get('product')
        if product:
            return tag(u'[', product, u'] Milestone:', name)
        else:
            return tag(u'Milestone:', name)
Beispiel #29
0
 def render_hierarchy(group):
     return tag.ul(
         tag.li(tag(tag.a(elt[0], href=formatter.href.wiki(elt[1]))
                    if elt[1] else tag(elt[0]),
                    render_hierarchy(elt[2]))
                if len(elt) == 3 else
                tag.a('/'.join(elt[0]),
                      href=formatter.href.wiki(elt[1])))
         for elt in group)
Beispiel #30
0
def moreless(text, length):
    """Turns `text` into HTML code where everything behind `length` can be uncovered using a ''show more'' link
       and later covered again with a ''show less'' link."""
    try:
        if len(text) <= length:
            return tag(text)
    except:
        return tag(text)
    return tag(tag.span(text[:length]),tag.a(' [', tag.strong(Markup('&hellip;')), ']', class_="more"),
        tag.span(text[length:],class_="moretext"),tag.a(' [', tag.strong('-'), ']', class_="less"))
Beispiel #31
0
    def render_timeline_event(self, context, field, event):
        # Decompose event data.
        id, name, description = event[3]

        # Return apropriate content.
        if field == 'url':
            return context.href.screenshots(id)
        elif field == 'title':
            return tag('New screenshot ', tag.em(name), ' created')
        elif field == 'description':
            return tag('%s' % (description, ))
Beispiel #32
0
 def render_timeline_event(self, context, field, event):
     (start, sprint) = event[3]
     if field == 'url':
         return context.href.sprint(sprint.name)
     elif field == 'title':
         if start:
             return tag('Sprint ', tag.em(sprint.name), ' started')
         return tag('Sprint ', tag.em(sprint.name), ' finished')
     elif field == 'description':
         return format_to(self.env, None, context(resource=sprint),
                          sprint.description)
Beispiel #33
0
 def render_property(self, name, mode, context, props):
     import string
     from genshi.builder import tag
     fragments = []
     vals = string.split(props[name], ' ')
     for val in vals[1:]:
         title = "ticket %s" % (val)
         fragments.append(tag.a("#%s" % val, class_="ticket",
                                title=title,
                                href=context.href.ticket(val)))
     return tag([tag(f, ', ') for f in fragments[:-1]], fragments[-1])
Beispiel #34
0
 def render_timeline_event(self, context, field, event):
     (start, sprint) = event[3]
     if field == 'url':
         return context.href.sprint(sprint.name)
     elif field == 'title':
         if start:
             return tag('Sprint ', tag.em(sprint.name), ' started')
         return tag('Sprint ', tag.em(sprint.name), ' finished')
     elif field == 'description':
         return format_to(self.env, None, context(resource=sprint),
                          sprint.description)
Beispiel #35
0
    def render_timeline_event(self, context, field, event):
        # Decompose event data.
        id, name, description = event[3]

        # Return apropriate content.
        if field == 'url':
           return context.href.screenshots(id)
        elif field == 'title':
           return tag('New screenshot ', tag.em(name), ' created')
        elif field == 'description':
           return tag('%s' % (description,))
Beispiel #36
0
    def render_timeline_event(self, context, field, event):
        # Decompose event data.
        id, name, description, size = event[3]

        # Return apropriate content.
        if field == 'url':
           return context.req.href.downloads(id)
        elif field == 'title':
           return tag('New download ', tag.em(name), ' created')
        elif field == 'description':
           return tag('(%s) ' % (pretty_size(size),), format_to_oneliner(
             self.env, context, description))
Beispiel #37
0
def moreless(text, length):
    """Turns `text` into HTML code where everything behind `length` can be uncovered using a ''show more'' link
       and later covered again with a ''show less'' link."""
    try:
        if len(text) <= length:
            return tag(text)
    except:
        return tag(text)
    return tag(tag.span(text[:length]),
               tag.a(' [', tag.strong(Markup('&hellip;')), ']', class_="more"),
               tag.span(text[length:], class_="moretext"),
               tag.a(' [', tag.strong('-'), ']', class_="less"))
Beispiel #38
0
    def render_timeline_event(self, context, field, event):
        # Decompose event data.
        id, name, description, size = event[3]

        # Return apropriate content.
        if field == 'url':
            return context.req.href.downloads(id)
        elif field == 'title':
            return tag('New download ', tag.em(name), ' created')
        elif field == 'description':
            return tag('(%s) ' % (pretty_size(size), ),
                       format_to_oneliner(self.env, context, description))
Beispiel #39
0
 def render_property(self, name, mode, context, props):
     import string
     from genshi.builder import tag
     fragments = []
     vals = string.split(props[name], ' ')
     for val in vals[1:]:
         title = "ticket %s" % (val)
         fragments.append(
             tag.a("#%s" % val,
                   class_="ticket",
                   title=title,
                   href=context.href.ticket(val)))
     return tag([tag(f, ', ') for f in fragments[:-1]], fragments[-1])
 def serializeNode(self, node, indent):
     rv = tag(" "*indent+"|")
     if node.type == simpletree.TextNode.type:
         text = node.value.split("\n")
         rv.append(tag(tag.code("#text: ", class_=tagClasses["text_marker"]),
                   tag.code(text[0], class_=tagClasses["text"])))
         for line in text[1:]:
             rv.append(tag(tag("\n" + " "*indent+"|"),
                           tag.code(line, class_=tagClasses["text"])))
     elif node.type == simpletree.Element.type:
         rv.append(tag.code(node.name, class_=tagClasses["element"]))
         if node.attributes:
             for key, value in node.attributes.iteritems():
                 rv.append(tag(" ", tag.code(key,
                                             class_=tagClasses["attr_name"]),
                           "=", tag.code("\""+value+"\"",
                                         class_=tagClasses["attr_value"])))
     elif node.type == simpletree.CommentNode.type:
         rv.append(tag(tag.code("#comment: ", class_=tagClasses["comment_marker"]),
                   tag.code(node.data, class_=tagClasses["comment"])))
     elif node.type == simpletree.DocumentType.type:
         rv.append(tag(tag.code("DOCTYPE: ", class_=tagClasses["doctype_marker"]),
                       tag.code(node.name, class_=tagClasses["doctype"])))
     rv.append(tag("\n"))
     return rv
Beispiel #41
0
    def render_timeline_event(self, context, field, event):
        # Decompose event data.
        title, description, ids = event[3]

        # Return apropriate content.
        if field == 'url':
           url = context.href.discussion(*ids)
           if len(ids) == 3:
               url = '%s#%s' % (url, ids[2])
           return url
        elif field == 'title':
           return tag(title)
        elif field == 'description':
           return tag(description)
Beispiel #42
0
    def render_property_diff(self, req, ticket, field, old, new,
                              resource_new=None):
        "Version for Trac 0.11"
        rendered = None
        # per type special rendering of diffs
        type_ = None
        for f in ticket.fields:
            if f['name'] == field:
                type_ = f['type']
                break
        if type_ == 'checkbox':
            rendered = new == '1' and "set" or "unset"
        elif type_ == 'textarea':
            if not resource_new:
                rendered = _('modified')
            else:
                href = get_resource_url(self.env, resource_new, req.href,
                                        action='diff')
                rendered = tag('modified (', tag.a('diff', href=href), ')')

        # per name special rendering of diffs
        old_list, new_list = None, None
        render_elt = lambda x: x
        sep = ', '
        if field == 'cc':
            chrome = Chrome(self.env)
            old_list, new_list = chrome.cc_list(old), chrome.cc_list(new)
            if not (Chrome(self.env).show_email_addresses or
                    'EMAIL_VIEW' in req.perm(resource_new or ticket.resource)):
                render_elt = obfuscate_email_address
        elif field == 'keywords':
            old_list, new_list = (old or '').split(), new.split()
            sep = ' '
        if (old_list, new_list) != (None, None):
            added = [tag.em(render_elt(x)) for x in new_list
                     if x not in old_list]
            remvd = [tag.em(render_elt(x)) for x in old_list
                     if x not in new_list]
            added = added and tag(separated(added, sep), " added")
            remvd = remvd and tag(separated(remvd, sep), " removed")
            if added or remvd:
                rendered = tag(added, added and remvd and '; ', remvd)
                return rendered
        if field in ('reporter', 'owner'):
            if not (Chrome(self.env).show_email_addresses or
                    'EMAIL_VIEW' in req.perm(resource_new or ticket.resource)):
                old = obfuscate_email_address(old)
                new = obfuscate_email_address(new)
        # Added by MS
        if field == 'attachment':
            rendered = tag(tag.em(new), " added")
        # changed 'if' to 'elif':
        elif old and not new:
            rendered = tag(tag.em(old), " deleted")
        elif new and not old:
            rendered = tag("set to ", tag.em(new))
        elif old and new:
            rendered = tag("changed from ", tag.em(old),
                            " to ", tag.em(new))
        return rendered
Beispiel #43
0
 def _get_template_values(self):
     html_attrs = self.document.settings.html_tag_attr
     html_attrs = html_attrs and ' ' + ' '.join(html_attrs) or ''
     self.head = self.metatags + self.stylesheets + self.scripts
     for key, value in self.docinfo.items():
         self.head.append(tag.meta(name=key, content=value))
     self.indent_head()
     self.head = ''.join(XHTMLSerializer()(tag(*self.head)))
     self.body = ''.join(XHTMLSerializer()(tag(*self.context.stack)))
     values = {}
     values['html_attr'] = html_attrs
     values['head'] = self.head
     values['body'] = self.body
     return values
Beispiel #44
0
 def _get_template_values(self):
     html_attrs = self.document.settings.html_tag_attr
     html_attrs = html_attrs and ' ' + ' '.join(html_attrs) or ''
     self.head = self.metatags + self.stylesheets + self.scripts
     for key, value in self.docinfo.items():
         self.head.append(tag.meta(name=key, content=value))
     self.indent_head()
     self.head = ''.join(XHTMLSerializer()(tag(*self.head)))
     self.body = ''.join(XHTMLSerializer()(tag(*self.context.stack)))
     values = {}
     values['html_attr'] = html_attrs
     values['head'] = self.head
     values['body'] = self.body
     return values
Beispiel #45
0
 def format_change(field,oldvalue,newvalue):
     """Formats tickets changes."""
     fieldtag = tag.strong(field)
     if field == 'cc':
         oldvalues = set(oldvalue and oldvalue.split(', ') or [])
         newvalues = set(newvalue and newvalue.split(', ') or [])
         added   = newvalues.difference(oldvalues)
         removed = oldvalues.difference(newvalues)
         strng = fieldtag
         if added:
             strng += tag(" ", tag.em(', '.join(added)),
                          _(" added"))
         if removed:
             if added:
                 strng += tag(', ')
             strng += tag(" ", tag.em(', '.join(removed)),
                          _(" removed"))
         return strng
     elif field == 'description':
         return fieldtag + tag(_(" modified"), " (", tag.a(_("diff"),
             href=req.href('ticket',id,action='diff',
             version=self.commentnum)), ")")
     elif field == 'comment':
         self.commentnum = oldvalue
         self.comment    = newvalue
         return tag("")
     elif not oldvalue:
         return fieldtag + tag(" ", tag.em(newvalue), _(" added"))
     elif not newvalue:
         return fieldtag + tag(" ", tag.em(oldvalue), _(" deleted"))
     else:
         return fieldtag + tag(_(" changed from "), tag.em(oldvalue),
                               _(" to "), tag.em(newvalue))
Beispiel #46
0
 def format_change(field, oldvalue, newvalue):
     """Formats tickets changes."""
     fieldtag = tag.strong(field)
     if field == "cc":
         oldvalues = set(oldvalue and oldvalue.split(", ") or [])
         newvalues = set(newvalue and newvalue.split(", ") or [])
         added = newvalues.difference(oldvalues)
         removed = oldvalues.difference(newvalues)
         strng = fieldtag
         if added:
             strng += tag(" ", tag.em(", ".join(added)), " added")
         if removed:
             if added:
                 strng += tag(", ")
             strng += tag(" ", tag.em(", ".join(removed)), " removed")
         return strng
     elif field == "description":
         return fieldtag + tag(
             " modified (",
             tag.a("diff", href=href("ticket", id, action="diff", version=self.commentnum)),
             ")",
         )
     elif field == "comment":
         self.commentnum = oldvalue
         self.comment = newvalue
         return tag("")
     elif not oldvalue:
         return fieldtag + tag(" ", tag.em(newvalue), " added")
     elif not newvalue:
         return fieldtag + tag(" ", tag.em(oldvalue), " deleted")
     else:
         return fieldtag + tag(" changed from ", tag.em(oldvalue), " to ", tag.em(newvalue))
Beispiel #47
0
    def _do_update(self, req):
        """Update component enable state."""
        components = req.args.getlist('component')
        enabled = req.args.getlist('enable')
        added, removed = [], []

        # FIXME: this needs to be more intelligent and minimize multiple
        # component names to prefix rules

        for component in components:
            is_enabled = bool(self.env.is_component_enabled(component))
            must_enable = component in enabled
            if is_enabled != must_enable:
                self.config.set('components', component,
                                'disabled' if is_enabled else 'enabled')
                self.log.info("%sabling component %s",
                              "Dis" if is_enabled else "En", component)
                if must_enable:
                    added.append(component)
                else:
                    removed.append(component)

        if added or removed:

            def make_list(items):
                parts = [item.rsplit('.', 1) for item in items]
                return tag.table(tag.tbody(
                    tag.tr(tag.td(c, class_='trac-name'),
                           tag.td('(%s.*)' % m, class_='trac-name'))
                    for m, c in parts),
                                 class_='trac-pluglist')

            added.sort()
            removed.sort()
            notices = []
            if removed:
                msg = ngettext("The following component has been disabled:",
                               "The following components have been disabled:",
                               len(removed))
                notices.append(tag(msg, make_list(removed)))
            if added:
                msg = ngettext("The following component has been enabled:",
                               "The following components have been enabled:",
                               len(added))
                notices.append(tag(msg, make_list(added)))

            # set the default value of options for only the enabled components
            for component in added:
                self.config.set_defaults(component=component)
            _save_config(self.config, req, self.log, notices)
Beispiel #48
0
    def filter_stream(self, req, method, filename, stream, data):
        if req.path_info.startswith('/report/'):
            link_builder = req.href.chrome
            debug = IttecoEvnSetup(self.env).debug
            def script_tag(path=None, content=None):
                kw = { 'type' : "text/javascript"}
                if path:
                    kw['src'] = link_builder(map_script(path, debug))
                return tag.script(content , **kw)

            stream |= Transformer("//head").prepend(
                        tag.link(type="text/css", rel="stylesheet", href=link_builder("itteco/css/report.css"))
                ).append(
                    tag(
                        script_tag('stuff/plugins/jquery.rpc.js'),
                        script_tag('stuff/ui/plugins/jquery.jeditable.js'),
                        script_tag("editable_report.js"),
                        script_tag(
                            content=
                            "$(document).ready(function(){"+
                                "$('#main').editableReport("+
                                    "{"+
                                        "rpcurl: '"+req.href('login','xmlrpc')+"',"+
                                        "fields: "+self.fields_dict(data.get('header_groups',[]))+"})"+
                            "});"
                        )
                    )
                )
            try:
                stream |= Transformer("//head").prepend(
                        tag(
                            # TODO fix scripts base path
                            tag.link(type="text/css", rel="stylesheet", href=link_builder("itteco/css/common.css")),
                            tag.link(type="text/css", rel="stylesheet", href=link_builder("itteco/css/report.css")),
                            #tag.link(type="text/css", rel="stylesheet", href=link_builder("itteco/css/colorbox/colorbox.css"))
                        )
                    ).append(
                        tag(
                            script_tag("stuff/ui/ui.core.js"),
                            script_tag("stuff/ui/ui.draggable.js"),
                            script_tag("stuff/ui/ui.droppable.js"),
                            script_tag("stuff/ui/ui.resizable.js"),
                            script_tag('stuff/ui/plugins/jquery.colorbox.js'),
                            script_tag('custom_select.js')
                        )
                    )
            except ValueError,e:
                #we do not fail the report it self, may be it works in read only mode
                self.env.log.debug('Report decoration failed: %s' % e)
Beispiel #49
0
 def render_timeline_event(self, context, field, event):
     wiki_page, comment = event[3]
     if field == 'url':
         return context.href.wiki(wiki_page.id, version=wiki_page.version)
     elif field == 'title':
         return tag(tag.em(get_resource_name(self.env, wiki_page)),
                    wiki_page.version > 1 and ' edited' or ' created')
     elif field == 'description':
         markup = format_to(self.env, None, context(resource=wiki_page),
                            comment)
         if wiki_page.version > 1:
             diff_href = context.href.wiki(
                 wiki_page.id, version=wiki_page.version, action='diff')
             markup = tag(markup, ' ', tag.a('(diff)', href=diff_href))
         return markup
Beispiel #50
0
    def render_timeline_event(self, context, field, event):
        # Decompose event data.
        title, description, ids = event[3]

        # Return apropriate content.
        if field == 'url':
           url = context.href.discussion(*ids)
           if len(ids) == 3:
               url = context.href.discussion(*ids[0])
               url = '%s#%s%s' % (url,ids[1], ids[2])
           return url
        elif field == 'title':
           return tag(title)
        elif field == 'description':
           return tag(description)
Beispiel #51
0
    def macroFactory(self, macro_name, arg_string, body, context,wiki):
        if macro_name == 'html':
            return self.getFragment(body)
        elif macro_name == 'title':
            return wiki.page_title
#        elif macro_name == 'span':
#            return builder.tag.span(self.parse.generate(body,context='inline'),id_=arg_string.strip())
#        elif macro_name == 'div':
#            return builder.tag.div(self.parse.generate(body),id_=arg_string.strip())
        elif macro_name == 'html2':
            return Markup(body)
        elif macro_name == 'htmlblock':
            return self.getStream(body)
        elif macro_name == 'pre':
            return builder.tag.pre('**' + body + '**')
        elif macro_name == 'steve':
            return '**' + arg_string + '**'
#        elif macro_name == 'luca':
#            return builder.tag.strong(arg_string)
        elif macro_name == 'mateo':
            return builder.tag.em(body)
        elif macro_name == 'ReverseFrag':
            return builder.tag(body[::-1])
        elif macro_name == 'Reverse':
            return body[::-1]
        elif macro_name == 'Reverse-it':
            return body[::-1]
        elif macro_name == 'ReverseIt':
            return body[::-1]
        elif macro_name == 'lib.ReverseIt-now':
            return body[::-1]
        elif macro_name == 'ifloggedin':
            return body
        elif macro_name == 'username':
            return 'Joe Blow'
        elif macro_name == 'center':
            return builder.tag.span(body, class_='centered')
        elif macro_name == 'footer':
            return '<<center>>This is a footer.<</center>>'
        elif macro_name == 'footer2':
            return '<<center>>\nThis is a footer.\n<</center>>'
        elif macro_name == 'reverse-lines':
            if body is not None:
                l = reversed(body.rstrip().split('\n'))
                if arg_string.strip() == 'output=wiki':
                    return '\n'.join(l) + '\n'
                else:
                    return builder.tag('\n'.join(l) + '\n')
Beispiel #52
0
    def post_process_request(self, req, template, data, content_type):
        page_path = req.args.get('page', None)
        if not page_path or page_path == 'WikiStart':
            return template, data, content_type

        href = req.href
        nav = req.chrome['ctxtnav']
        wikiStartIndex = None
        for i, elm in enumerate(nav):
            if type(elm) == Element and elm.tag == 'a' and elm.attrib.get(
                    'href') == href.wiki('WikiStart'):
                wikiStartIndex = i
                break

        if wikiStartIndex is None:
            return template, data, content_type

        page_paths = page_path.split('/')
        # reverse it so we can .pop() in the necessary order
        page_paths.reverse()

        _links = []
        _prev_path = ""
        while page_paths:
            page_path = page_paths.pop()
            _prev_path += "/" + page_path
            _link = None
            if page_paths:
                _link = href.wiki(_prev_path)
            t = (page_path, _link)
            _links.append(t)
        # always prepend the default start page link
        _links = [('Start Page', href.wiki('WikiStart'))] + _links

        r = []
        for link in _links:
            text, _href = link
            if _href:
                r += tag(tag.a(text, href=_href), ' %s ' % self.sep_character)
            else:
                # last entry in list
                #  ..so _href is None
                #  ..so no sep char appended
                r += tag(text)

        nav[i] = r

        return template, data, content_type
Beispiel #53
0
    def notify(self, resid, subject, author=None):
        self.subject = subject
        config = self.config['notification']
        if not config.getbool('smtp_enabled'):
            return
        from_email, from_name = '', ''
        if author and config.getbool('smtp_from_author'):
            from_email = self.get_smtp_address(author)
            if from_email:
                from_name = self.name_map.get(author, '')
                if not from_name:
                    mo = self.longaddr_re.search(author)
                    if mo:
                        from_name = mo.group(1)
        if not from_email:
            from_email = config.get('smtp_from')
            from_name = config.get('smtp_from_name') or self.env.project_name
        self.replyto_email = config.get('smtp_replyto')
        self.from_email = from_email or self.replyto_email
        self.from_name = from_name
        if not self.from_email and not self.replyto_email:
            message = tag(
                tag.p(_('Unable to send email due to identity crisis.')),
                # convert explicitly to `Fragment` to avoid breaking message
                # when passing `LazyProxy` object to `Fragment`
                tag.p(to_fragment(tag_(
                    "Neither %(from_)s nor %(reply_to)s are specified in the "
                    "configuration.",
                    from_=tag.strong("[notification] smtp_from"),
                    reply_to=tag.strong("[notification] smtp_replyto")))))
            raise TracError(message, _("SMTP Notification Error"))

        Notify.notify(self, resid)
Beispiel #54
0
    def render_ticket_action_control(self, req, ticket, action):
        id, grade = self._get_grade(req, action)

        review_options = self._get_review_options(action)
        actions = ConfigurableTicketWorkflow(self.env).actions

        selected_value = grade or review_options[0][0]

        label = actions[action]['name']
        control = tag([
            "as: ",
            tag.select([
                tag.option(option, selected=(option == selected_value or None))
                for option, status in review_options
            ],
                       name=id,
                       id=id)
        ])
        if grade:
            new_status = self._get_new_status(req, ticket, action,
                                              review_options)
            hint = "Next status will be '%s'" % new_status
        else:
            hint = "Next status will be one of " + \
                   ', '.join(["'%s'" % status
                              for option, status in review_options])
        return (label, control, hint)
Beispiel #55
0
 def render_group(group):
     return tag.ul(
         tag.li(tag(tag.strong(elt[0].strip('/')), render_group(elt[1]))
                if isinstance(elt, tuple) else
                tag.a(wiki.format_page_name(omitprefix(elt)),
                      href=formatter.href.wiki(elt)))
         for elt in group)
Beispiel #56
0
 def test_tracerror_with_tracerror_with_fragment(self):
     message = tag('Powered by ',
                   tag.a('Trac', href='http://trac.edgewall.org/'))
     rv = to_fragment(TracError(TracError(message)))
     self.assertEqual(Fragment, type(rv))
     self.assertEqual('Powered by <a href="http://trac.edgewall.org/">Trac'
                      '</a>', unicode(rv))
Beispiel #57
0
    def __get__(self, instance, owner):
        if instance is None:
            return self
        order = ListOption.__get__(self, instance, owner)
        components = []
        implementing_classes = []
        for impl in self.xtnpt.extensions(instance):
            implementing_classes.append(impl.__class__.__name__)
            if self.include_missing or impl.__class__.__name__ in order:
                components.append(impl)
        not_found = sorted(set(order) - set(implementing_classes))
        if not_found:
            raise ConfigurationError(
                tag_(
                    "Cannot find implementation(s) of the %(interface)s "
                    "interface named %(implementation)s. Please check "
                    "that the Component is enabled or update the option "
                    "%(option)s in trac.ini.",
                    interface=tag.code(self.xtnpt.interface.__name__),
                    implementation=tag(
                        (', ' if idx != 0 else None, tag.code(impl))
                        for idx, impl in enumerate(not_found)),
                    option=tag.code("[%s] %s" % (self.section, self.name))))

        def compare(x, y):
            x, y = x.__class__.__name__, y.__class__.__name__
            if x not in order:
                return int(y in order)
            if y not in order:
                return -int(x in order)
            return cmp(order.index(x), order.index(y))

        components.sort(compare)
        return components