Ejemplo n.º 1
0
    def expand_macro(self, formatter, name, content):
        args, kw = parse_args(content)
        prefix = args[0].strip() if args else None
        hideprefix = args and len(args) > 1 and args[1].strip() == 'hideprefix'
        minsize = _arg_as_int(kw.get('min', 1), 'min', min=1)
        minsize_group = max(minsize, 2)
        depth = _arg_as_int(kw.get('depth', -1), 'depth', min=-1)
        format = kw.get('format', '')

        def parse_list(name):
            return [inc.strip() for inc in kw.get(name, '').split(':')
                    if inc.strip()]

        includes = parse_list('include') or ['*']
        excludes = parse_list('exclude')

        wiki = formatter.wiki
        resource = formatter.resource
        if prefix and resource and resource.realm == 'wiki':
            prefix = wiki.resolve_relative_name(prefix, resource.id)

        start = prefix.count('/') if prefix else 0

        if hideprefix:
            omitprefix = lambda page: page[len(prefix):]
        else:
            omitprefix = lambda page: page

        pages = sorted(page for page in wiki.get_pages(prefix)
                       if (depth < 0 or depth >= page.count('/') - start)
                       and 'WIKI_VIEW' in formatter.perm('wiki', page)
                       and any(fnmatchcase(page, inc) for inc in includes)
                       and not any(fnmatchcase(page, exc) for exc in excludes))

        if format == 'compact':
            return tag(
                separated((tag.a(wiki.format_page_name(omitprefix(p)),
                                 href=formatter.href.wiki(p)) for p in pages),
                          ', '))

        # the function definitions for the different format styles

        # the different page split formats, each corresponding to its rendering
        def split_pages_group(pages):
            """Return a list of (path elements, page_name) pairs,
            where path elements correspond to the page name (without prefix)
            splitted at Camel Case word boundaries, numbers and '/'.
            """
            page_paths = []
            for page in pages:
                path = [elt.strip() for elt in self.SPLIT_RE.split(
                        self.NUM_SPLIT_RE.sub(r" \1 ",
                        wiki.format_page_name(omitprefix(page), split=True)))]
                page_paths.append(([elt for elt in path if elt], page))
            return page_paths

        def split_pages_hierarchy(pages):
            """Return a list of (path elements, page_name) pairs,
            where path elements correspond to the page name (without prefix)
            splitted according to the '/' hierarchy.
            """
            return [(wiki.format_page_name(omitprefix(page)).split("/"), page)
                    for page in pages]

        # the different tree structures, each corresponding to its rendering
        def tree_group(entries):
            """Transform a flat list of entries into a tree structure.

            `entries` is a list of `(path_elements, page_name)` pairs

            Return a list organized in a tree structure, in which:
              - a leaf is a page name
              - a node is a `(key, nodes)` pairs, where:
                - `key` is the leftmost of the path elements, common to the
                  grouped (path element, page_name) entries
                - `nodes` is a list of nodes or leaves
            """
            groups = []

            for key, grouper in groupby(entries, lambda (elts, name):
                                                    elts[0] if elts else ''):
                # remove key from path_elements in grouped entries for further
                # grouping
                grouped_entries = [(path_elements[1:], page_name)
                                   for path_elements, page_name in grouper]

                if key and len(grouped_entries) >= minsize_group:
                    subnodes = tree_group(sorted(grouped_entries))
                    if len(subnodes) == 1:
                        subkey, subnodes = subnodes[0]
                        node = (key + subkey, subnodes)
                        groups.append(node)
                    elif self.SPLIT_RE.match(key):
                        for elt in subnodes:
                            if isinstance(elt, tuple):
                                subkey, subnodes = elt
                                elt = (key + subkey, subnodes)
                            groups.append(elt)
                    else:
                        node = (key, subnodes)
                        groups.append(node)
                else:
                    for path_elements, page_name in grouped_entries:
                        groups.append(page_name)
            return groups
Ejemplo n.º 2
0
 def _format_ctxtnav(self, items):
     """Prepare context navigation items for display on login page."""
     return list(separated(items, '|'))
Ejemplo n.º 3
0
    def render_ticket_action_control(self, req, ticket, action):

        self.log.debug('render_ticket_action_control: action "%s"', action)

        this_action = self.actions[action]
        status = this_action['newstate']
        operations = this_action['operations']
        ticket_owner = ticket._old.get('owner', ticket['owner'])
        ticket_status = ticket._old.get('status', ticket['status'])
        author = get_reporter_id(req, 'author')
        author_info = partial(Chrome(self.env).authorinfo, req,
                              resource=ticket.resource)
        format_author = partial(Chrome(self.env).format_author, req,
                                resource=ticket.resource)
        formatted_current_owner = author_info(ticket_owner)
        exists = ticket_status is not None

        ticket_system = TicketSystem(self.env)
        control = []  # default to nothing
        hints = []
        if 'reset_workflow' in operations:
            control.append(_("from invalid state"))
            hints.append(_("Current state no longer exists"))
        if 'del_owner' in operations:
            hints.append(_("The ticket will be disowned"))
        if 'set_owner' in operations or 'may_set_owner' in operations:
            owners = self.get_allowed_owners(req, ticket, this_action)

            if 'set_owner' in operations:
                default_owner = author
            elif 'may_set_owner' in operations:
                if not exists:
                    default_owner = ticket_system.default_owner
                else:
                    default_owner = ticket_owner or None
                if owners is not None and default_owner not in owners:
                    owners.insert(0, default_owner)
            else:
                # Protect against future modification for case that another
                # operation is added to the outer conditional
                raise AssertionError(operations)

            id = 'action_%s_reassign_owner' % action

            if not owners:
                owner = req.args.get(id, default_owner)
                control.append(
                    tag_("to %(owner)s",
                         owner=tag.input(type='text', id=id, name=id,
                                         value=owner)))
                if not exists or ticket_owner is None:
                    hints.append(_("The owner will be the specified user"))
                else:
                    hints.append(tag_("The owner will be changed from "
                                      "%(current_owner)s to the specified "
                                      "user",
                                      current_owner=formatted_current_owner))
            elif len(owners) == 1:
                owner = tag.input(type='hidden', id=id, name=id,
                                  value=owners[0])
                formatted_new_owner = author_info(owners[0])
                control.append(tag_("to %(owner)s",
                                    owner=tag(formatted_new_owner, owner)))
                if not exists or ticket_owner is None:
                    hints.append(tag_("The owner will be %(new_owner)s",
                                      new_owner=formatted_new_owner))
                elif ticket['owner'] != owners[0]:
                    hints.append(tag_("The owner will be changed from "
                                      "%(current_owner)s to %(new_owner)s",
                                      current_owner=formatted_current_owner,
                                      new_owner=formatted_new_owner))
            else:
                selected_owner = req.args.get(id, default_owner)
                control.append(tag_("to %(owner)s", owner=tag.select(
                    [tag.option(label, value=value if value is not None else '',
                                selected=(value == selected_owner or None))
                     for label, value in sorted((format_author(owner), owner)
                                                for owner in owners)],
                    id=id, name=id)))
                if not exists or ticket_owner is None:
                    hints.append(_("The owner will be the selected user"))
                else:
                    hints.append(tag_("The owner will be changed from "
                                      "%(current_owner)s to the selected user",
                                      current_owner=formatted_current_owner))
        elif 'set_owner_to_self' in operations:
            formatted_author = author_info(author)
            if not exists or ticket_owner is None:
                hints.append(tag_("The owner will be %(new_owner)s",
                                  new_owner=formatted_author))
            elif ticket_owner != author:
                hints.append(tag_("The owner will be changed from "
                                  "%(current_owner)s to %(new_owner)s",
                                  current_owner=formatted_current_owner,
                                  new_owner=formatted_author))
            elif ticket_status != status:
                hints.append(tag_("The owner will remain %(current_owner)s",
                                  current_owner=formatted_current_owner))
        if 'set_resolution' in operations:
            resolutions = [r.name for r in Resolution.select(self.env)]
            if 'set_resolution' in this_action:
                valid_resolutions = set(resolutions)
                resolutions = this_action['set_resolution']
                if any(x not in valid_resolutions for x in resolutions):
                    raise ConfigurationError(_(
                        "Your workflow attempts to set a resolution but uses "
                        "undefined resolutions (configuration issue, please "
                        "contact your Trac admin)."))
            if not resolutions:
                raise ConfigurationError(_(
                    "Your workflow attempts to set a resolution but none is "
                    "defined (configuration issue, please contact your Trac "
                    "admin)."))
            id = 'action_%s_resolve_resolution' % action
            if len(resolutions) == 1:
                resolution = tag.input(type='hidden', id=id, name=id,
                                       value=resolutions[0])
                control.append(tag_("as %(resolution)s",
                                    resolution=tag(resolutions[0],
                                                   resolution)))
                hints.append(tag_("The resolution will be set to %(name)s",
                                  name=resolutions[0]))
            else:
                selected_option = req.args.get(id,
                                               ticket_system.default_resolution)
                control.append(tag_("as %(resolution)s",
                                    resolution=tag.select(
                    [tag.option(x, value=x,
                                selected=(x == selected_option or None))
                     for x in resolutions],
                    id=id, name=id)))
                hints.append(_("The resolution will be set"))
        if 'del_resolution' in operations:
            hints.append(_("The resolution will be deleted"))
        if 'leave_status' in operations:
            control.append(tag_("as %(status)s", status=ticket_status))
            if len(operations) == 1:
                hints.append(tag_("The owner will remain %(current_owner)s",
                                  current_owner=formatted_current_owner)
                             if ticket_owner else
                             _("The ticket will remain with no owner"))
        elif not operations:
            if status != '*':
                if ticket['status'] is None:
                    hints.append(tag_("The status will be '%(name)s'",
                                      name=status))
                else:
                    hints.append(tag_("Next status will be '%(name)s'",
                                      name=status))
        return (this_action['label'], tag(separated(control, ' ')),
                tag(separated(hints, '. ', '.') if hints else ''))
Ejemplo n.º 4
0
    def expand_macro(self, formatter, name, content):
        args, kw = parse_args(content)
        prefix = args and args[0].strip() or None
        hideprefix = args and len(args) > 1 and args[1].strip() == 'hideprefix'
        minsize = max(int(kw.get('min', 2)), 2)
        depth = int(kw.get('depth', -1))
        start = prefix and prefix.count('/') or 0
        format = kw.get('format', '')

        if hideprefix:
            omitprefix = lambda page: page[len(prefix):]
        else:
            omitprefix = lambda page: page

        wiki = formatter.wiki

        pages = sorted(page for page in wiki.get_pages(prefix) \
                       if (depth < 0 or depth >= page.count('/') - start)
                       and 'WIKI_VIEW' in formatter.perm('wiki', page))

        if format == 'compact':
            return tag(
                separated((tag.a(wiki.format_page_name(omitprefix(p)),
                                 href=formatter.href.wiki(p)) for p in pages),
                          ', '))

        # the function definitions for the different format styles

        # the different page split formats, each corresponding to its rendering
        def split_pages_group(pages):
            """Return a list of (path elements, page_name) pairs,
            where path elements correspond to the page name (without prefix)
            splitted at Camel Case word boundaries, numbers and '/'.
            """
            page_paths = []
            for page in pages:
                path = [elt.rstrip('/').strip() for elt in self.SPLIT_RE.split(
                        wiki.format_page_name(omitprefix(page), split=True))]
                page_paths.append(([elt for elt in path if elt], page))
            return page_paths

        def split_pages_hierarchy(pages):
            """Return a list of (path elements, page_name) pairs,
            where path elements correspond to the page name (without prefix)
            splitted according to the '/' hierarchy.
            """
            return [(wiki.format_page_name(omitprefix(page)).split("/"), page)
                    for page in pages]

        # create the group hierarchy (same for group and hierarchy formats)
        def split_in_groups(entries):
            """Transform a flat list of entries into a tree structure.
            
            `entries` is a list of `(path_elements, page_name)` pairs
            
            Return a list organized in a tree structure, in which:
              - a leaf is a page name
              - a node is a `(key, nodes)` pairs, where:
                - `key` is the leftmost of the path elements, common to the
                  grouped (path element, page_name) entries
                - `nodes` is a list of nodes or leaves
            """
            groups = []

            for key, grouper in groupby(entries, lambda (elts, name):
                                                elts and elts[0] or ''):
                # remove key from path_elements in grouped entries for further
                # grouping
                grouped_entries = [(path_elements[1:], page_name)
                                   for path_elements, page_name in grouper]
                if key and len(grouped_entries) >= minsize:
                    subnodes = split_in_groups(sorted(grouped_entries))
                    if len(subnodes) == 1:
                        subkey, subnodes = subnodes[0]
                        node = (key + subkey, subnodes) # FIXME
                    else:
                        node = (key, subnodes)
                    groups.append(node)
                else:
                    for path_elements, page_name in grouped_entries:
                        groups.append(page_name)
            return groups
Ejemplo n.º 5
0
    def render_ticket_action_control(self, req, ticket, action):

        self.log.debug('render_ticket_action_control: action "%s"', action)

        this_action = self.actions[action]
        status = this_action['newstate']
        operations = this_action['operations']
        current_owner = ticket._old.get('owner', ticket['owner'])
        author = get_reporter_id(req, 'author')
        format_author = partial(Chrome(self.env).format_author, req)
        formatted_current_owner = format_author(current_owner or _("(none)"))

        control = []  # default to nothing
        hints = []
        if 'reset_workflow' in operations:
            control.append(_("from invalid state"))
            hints.append(_("Current state no longer exists"))
        if 'del_owner' in operations:
            hints.append(_("The ticket will be disowned"))
        if 'set_owner' in operations:
            id = 'action_%s_reassign_owner' % action

            if 'set_owner' in this_action:
                owners = [x.strip() for x in
                          this_action['set_owner'].split(',')]
            elif self.config.getbool('ticket', 'restrict_owner'):
                perm = PermissionSystem(self.env)
                owners = perm.get_users_with_permission('TICKET_MODIFY')
                owners.sort()
            else:
                owners = None

            if owners is None:
                owner = req.args.get(id, author)
                control.append(tag_("to %(owner)s",
                                    owner=tag.input(type='text', id=id,
                                                    name=id, value=owner)))
                hints.append(_("The owner will be changed from "
                               "%(current_owner)s to the specified user",
                               current_owner=formatted_current_owner))
            elif len(owners) == 1:
                owner = tag.input(type='hidden', id=id, name=id,
                                  value=owners[0])
                formatted_new_owner = format_author(owners[0])
                control.append(tag_("to %(owner)s",
                                    owner=tag(formatted_new_owner, owner)))
                if ticket['owner'] != owners[0]:
                    hints.append(_("The owner will be changed from "
                                   "%(current_owner)s to %(selected_owner)s",
                                   current_owner=formatted_current_owner,
                                   selected_owner=formatted_new_owner))
            else:
                selected_owner = req.args.get(id, req.authname)
                control.append(tag_("to %(owner)s", owner=tag.select(
                    [tag.option(x, value=x,
                                selected=(x == selected_owner or None))
                     for x in owners],
                    id=id, name=id)))
                hints.append(_("The owner will be changed from "
                               "%(current_owner)s to the selected user",
                               current_owner=formatted_current_owner))
        elif 'set_owner_to_self' in operations and \
                ticket._old.get('owner', ticket['owner']) != author:
            hints.append(_("The owner will be changed from %(current_owner)s "
                           "to %(authname)s",
                           current_owner=formatted_current_owner,
                           authname=format_author(author)))
        if 'set_resolution' in operations:
            if 'set_resolution' in this_action:
                resolutions = [x.strip() for x in
                               this_action['set_resolution'].split(',')]
            else:
                resolutions = [r.name for r in Resolution.select(self.env)]
            if not resolutions:
                raise TracError(_("Your workflow attempts to set a resolution "
                                  "but none is defined (configuration issue, "
                                  "please contact your Trac admin)."))
            id = 'action_%s_resolve_resolution' % action
            if len(resolutions) == 1:
                resolution = tag.input(type='hidden', id=id, name=id,
                                       value=resolutions[0])
                control.append(tag_("as %(resolution)s",
                                    resolution=tag(resolutions[0],
                                                   resolution)))
                hints.append(_("The resolution will be set to %(name)s",
                               name=resolutions[0]))
            else:
                selected_option = req.args.get(id,
                        TicketSystem(self.env).default_resolution)
                control.append(tag_("as %(resolution)s",
                                    resolution=tag.select(
                    [tag.option(x, value=x,
                                selected=(x == selected_option or None))
                     for x in resolutions],
                    id=id, name=id)))
                hints.append(_("The resolution will be set"))
        if 'del_resolution' in operations:
            hints.append(_("The resolution will be deleted"))
        if 'leave_status' in operations:
            control.append(_("as %(status)s",
                             status= ticket._old.get('status',
                                                     ticket['status'])))
            if len(operations) == 1:
                hints.append(_("The owner will remain %(current_owner)s",
                               current_owner=formatted_current_owner)
                             if current_owner else
                             _("The ticket will remain with no owner"))
        else:
            if status != '*':
                hints.append(_("Next status will be '%(name)s'", name=status))
        return (this_action.get('name', action), tag(separated(control, ' ')),
                '. '.join(hints) + '.' if hints else '')
Ejemplo n.º 6
0
    def render_ticket_action_control(self, req, ticket, action):

        self.log.debug('render_ticket_action_control: action "%s"', action)

        this_action = self.actions[action]
        status = this_action['newstate']
        operations = this_action['operations']
        current_owner = ticket._old.get('owner', ticket['owner'])
        author = get_reporter_id(req, 'author')
        author_info = partial(Chrome(self.env).authorinfo,
                              req,
                              resource=ticket.resource)
        formatted_current_owner = author_info(current_owner)
        exists = ticket._old.get('status', ticket['status']) is not None

        control = []  # default to nothing
        hints = []
        if 'reset_workflow' in operations:
            control.append(_("from invalid state"))
            hints.append(_("Current state no longer exists"))
        if 'del_owner' in operations:
            hints.append(_("The ticket will be disowned"))
        if 'set_owner' in operations or 'may_set_owner' in operations:
            if 'set_owner' in this_action:
                owners = self._to_users(this_action['set_owner'], ticket)
            elif self.config.getbool('ticket', 'restrict_owner'):
                perm = PermissionSystem(self.env)
                owners = perm.get_users_with_permission('TICKET_MODIFY')
                owners = [
                    user for user in owners
                    if 'TICKET_MODIFY' in PermissionCache(
                        self.env, user, ticket.resource)
                ]
                owners = sorted(owners)
            else:
                owners = None

            if 'set_owner' in operations:
                default_owner = author
            elif 'may_set_owner' in operations:
                if not exists:
                    default_owner = TicketSystem(self.env).default_owner
                else:
                    default_owner = ticket._old.get('owner', ticket['owner']
                                                    or None)
                if owners is not None and default_owner not in owners:
                    owners.insert(0, default_owner)
            else:
                # Protect against future modification for case that another
                # operation is added to the outer conditional
                raise AssertionError(operations)

            id = 'action_%s_reassign_owner' % action

            if not owners:
                owner = req.args.get(id, default_owner)
                control.append(
                    tag_("to %(owner)s",
                         owner=tag.input(type='text',
                                         id=id,
                                         name=id,
                                         value=owner)))
                if not exists or current_owner is None:
                    hints.append(_("The owner will be the specified user"))
                else:
                    hints.append(
                        tag_(
                            "The owner will be changed from "
                            "%(current_owner)s to the specified "
                            "user",
                            current_owner=formatted_current_owner))
            elif len(owners) == 1:
                owner = tag.input(type='hidden',
                                  id=id,
                                  name=id,
                                  value=owners[0])
                formatted_new_owner = author_info(owners[0])
                control.append(
                    tag_("to %(owner)s", owner=tag(formatted_new_owner,
                                                   owner)))
                if not exists or current_owner is None:
                    hints.append(
                        tag_("The owner will be %(new_owner)s",
                             new_owner=formatted_new_owner))
                elif ticket['owner'] != owners[0]:
                    hints.append(
                        tag_(
                            "The owner will be changed from "
                            "%(current_owner)s to %(new_owner)s",
                            current_owner=formatted_current_owner,
                            new_owner=formatted_new_owner))
            else:
                selected_owner = req.args.get(id, default_owner)
                control.append(
                    tag_("to %(owner)s",
                         owner=tag.select([
                             tag.option(x if x is not None else _("(none)"),
                                        value=x if x is not None else '',
                                        selected=(x == selected_owner or None))
                             for x in owners
                         ],
                                          id=id,
                                          name=id)))
                if not exists or current_owner is None:
                    hints.append(_("The owner will be the selected user"))
                else:
                    hints.append(
                        tag_(
                            "The owner will be changed from "
                            "%(current_owner)s to the selected user",
                            current_owner=formatted_current_owner))
        elif 'set_owner_to_self' in operations and \
                ticket._old.get('owner', ticket['owner']) != author:
            formatted_author = author_info(author)
            if not exists or current_owner is None:
                hints.append(
                    tag_("The owner will be %(new_owner)s",
                         new_owner=formatted_author))
            else:
                hints.append(
                    tag_(
                        "The owner will be changed from "
                        "%(current_owner)s to %(new_owner)s",
                        current_owner=formatted_current_owner,
                        new_owner=formatted_author))
        if 'set_resolution' in operations:
            if 'set_resolution' in this_action:
                resolutions = this_action['set_resolution']
            else:
                resolutions = [r.name for r in Resolution.select(self.env)]
            if not resolutions:
                raise TracError(
                    _("Your workflow attempts to set a resolution "
                      "but none is defined (configuration issue, "
                      "please contact your Trac admin)."))
            id = 'action_%s_resolve_resolution' % action
            if len(resolutions) == 1:
                resolution = tag.input(type='hidden',
                                       id=id,
                                       name=id,
                                       value=resolutions[0])
                control.append(
                    tag_("as %(resolution)s",
                         resolution=tag(resolutions[0], resolution)))
                hints.append(
                    tag_("The resolution will be set to %(name)s",
                         name=resolutions[0]))
            else:
                selected_option = req.args.get(
                    id,
                    TicketSystem(self.env).default_resolution)
                control.append(
                    tag_(
                        "as %(resolution)s",
                        resolution=tag.select([
                            tag.option(x,
                                       value=x,
                                       selected=(x == selected_option or None))
                            for x in resolutions
                        ],
                                              id=id,
                                              name=id)))
                hints.append(_("The resolution will be set"))
        if 'del_resolution' in operations:
            hints.append(_("The resolution will be deleted"))
        if 'leave_status' in operations:
            control.append(
                tag_("as %(status)s",
                     status=ticket._old.get('status', ticket['status'])))
            if len(operations) == 1:
                hints.append(
                    tag_("The owner will remain %(current_owner)s",
                         current_owner=formatted_current_owner) if
                    current_owner else _("The ticket will remain with no owner"
                                         ))
        else:
            if ticket['status'] is None:
                hints.append(tag_("The status will be '%(name)s'",
                                  name=status))
            elif status != '*':
                hints.append(
                    tag_("Next status will be '%(name)s'", name=status))
        return (this_action['label'], tag(separated(control, ' ')),
                tag(separated(hints, '. ', '.') if hints else ''))
Ejemplo n.º 7
0
    def render_property_diff(env,
                             req,
                             ticket,
                             field,
                             old,
                             new,
                             resource_new=None):
        "Version for Trac 0.12"
        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(env,
                                        resource_new,
                                        req.href,
                                        action='diff')
                # TRANSLATOR: modified ('diff') (link)
                diff = tag.a(_("diff"), href=href)
                rendered = tag_("modified (%(diff)s)", diff=diff)

        # per name special rendering of diffs
        old_list, new_list = None, None
        render_elt = lambda x: x
        sep = ', '
        if field == 'cc':
            chrome = Chrome(env)
            old_list, new_list = chrome.cc_list(old), chrome.cc_list(new)
            if not (Chrome(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.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 tagn_("%(items)s added",
                                    "%(items)s added",
                                    len(added),
                                    items=separated(added, sep))
            remvd = remvd and tagn_("%(items)s removed",
                                    "%(items)s removed",
                                    len(remvd),
                                    items=separated(remvd, sep))
            if added or remvd:
                rendered = tag(added, added and remvd and _("; "), remvd)
                return rendered
        if field in ('reporter', 'owner'):
            if not (Chrome(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
        # The `wtag_` is the `tag_` from tracwatchlist.translation, e.g.
        # using its translation domain.
        if field == 'attachment':
            rendered = wtag_("%(value)s added", value=tag.em(new))
        # changed 'if' to 'elif':
        elif old and not new:
            rendered = tag_("%(value)s deleted", value=tag.em(old))
        elif new and not old:
            rendered = tag_("set to %(value)s", value=tag.em(new))
        elif old and new:
            rendered = tag_("changed from %(old)s to %(new)s",
                            old=tag.em(old),
                            new=tag.em(new))
        return rendered
Ejemplo n.º 8
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