Beispiel #1
0
    def format_and_send_attachment_notification(self, attachment, action):
        if not self.tickets_notifications:
            return

        args = self.make_args({
            'component': esc(attachment.parent_realm),
            'timestamp': ''
        })

        if action == 'added':
            args['author'] = esc(authorinfo(attachment.author))
            args['url'] = esc(
                get_resource_url(self.env, attachment.resource,
                                 self.env.abs_href))
            desc = attachment.description and (" '" + attachment.description +
                                               "'") or ""
            args['log'] = esc(
                'File ' + attachment.filename +
                ("%s has been attached to " % desc) +
                get_resource_name(self.env, attachment.resource.parent))
            args['version'] = ''
        elif action == 'deleted':
            args['author'] = ''
            args['log'] = esc(
                'File ' + attachment.filename + ' has been deleted from ' +
                get_resource_name(self.env, attachment.resource.parent))
            args['version'] = ''
            args['url'] = esc(
                get_resource_url(self.env, attachment.resource.parent,
                                 self.env.abs_href))
        else:
            raise Exception('Unknown action type')

        self.send_message(message_template % args)
Beispiel #2
0
    def process_request(self, req):
        """Process the request."""

        id = int(req.args.get('id'))

        req.perm('ticket', id).require('TICKET_VIEW')

        if 'TICKET_REMINDER_MODIFY' not in req.perm and \
                'TICKET_ADMIN' not in req.perm:
            raise PermissionError('TICKET_REMINDER_MODIFY', req.perm._resource,
                                  self.env)

        ticket = Ticket(self.env, id)

        if 'cancel' in req.args:
            req.redirect(get_resource_url(self.env, ticket.resource, req.href))

        ticket_name = get_resource_name(self.env, ticket.resource)
        ticket_url = get_resource_url(self.env, ticket.resource, req.href)
        add_link(req, 'up', ticket_url, ticket_name)
        add_ctxtnav(req, _('Back to %(ticket)s', ticket=ticket_name),
                    ticket_url)

        add_stylesheet(req, 'ticketreminder/css/ticketreminder.css')

        if req.args['action'] == "addreminder":
            return self._process_add(req, ticket)
        elif req.args['action'] == "deletereminder":
            return self._process_delete(req, ticket)
        else:
            raise ValueError('Unknown action "%s"' % (req.args['action'], ))
Beispiel #3
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_("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_("Forms (%(parent)s)", parent=parent)
         return tag_("Forms in %(parent)s", parent=parent)
Beispiel #4
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_("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_("Forms (%(parent)s)", parent=parent)
         return tag_("Forms in %(parent)s", parent=parent)
Beispiel #5
0
    def process_request(self, req):
        """Process the request."""

        id = int(req.args.get('id'))

        req.perm('ticket', id).require('TICKET_VIEW')

        if 'TICKET_REMINDER_MODIFY' not in req.perm and \
                'TICKET_ADMIN' not in req.perm:
            raise PermissionError('TICKET_REMINDER_MODIFY',
                                  req.perm._resource, self.env)

        ticket = Ticket(self.env, id)

        if 'cancel' in req.args:
            req.redirect(get_resource_url(self.env, ticket.resource, req.href))

        ticket_name = get_resource_name(self.env, ticket.resource)
        ticket_url = get_resource_url(self.env, ticket.resource, req.href)
        add_link(req, 'up', ticket_url, ticket_name)
        add_ctxtnav(req, _('Back to %(ticket)s', ticket=ticket_name),
                    ticket_url)

        add_stylesheet(req, 'ticketreminder/css/ticketreminder.css')

        if req.args['action'] == "addreminder":
            return self._process_add(req, ticket)
        elif req.args['action'] == "deletereminder":
            return self._process_delete(req, ticket)
        else:
            raise ValueError('Unknown action "%s"' % (req.args['action'],))
Beispiel #6
0
 def render_timeline_event(self, context, field, event):
     resource = event[3][0]
     if field == 'url':
         return get_resource_url(self.env, resource, context.href)
     elif field == 'title':
         name = builder.em(get_resource_name(self.env, resource))
         return tag_("Tag change on %(resource)s", resource=name)
     elif field == 'description':
         return render_tag_changes(event[3][1], event[3][2])
Beispiel #7
0
 def render_timeline_event(self, context, field, event):
     resource = event[3][0]
     if field == 'url':
         return get_resource_url(self.env, resource, context.href)
     elif field == 'title':
         name = builder.em(get_resource_name(self.env, resource))
         return tag_("Tag change on %(resource)s", resource=name)
     elif field == 'description':
         return render_tag_changes(event[3][1], event[3][2])
    def test_global_neighborhood_report(self):
        target = resource.Neighborhood("global", None).child(self.resource)

        self.assertEquals("[global:] report:1", resource.get_resource_description(self.env, target))
        self.assertEquals("[global:] report:1", resource.get_resource_name(self.env, target))
        self.assertEquals("[global:] report:1", resource.get_resource_shortname(self.env, target))
        self.assertEquals("[global:] report:1 at version None", resource.get_resource_summary(self.env, target))
        self.assertEquals(
            "http://example.org/trac.cgi/report/1", resource.get_resource_url(self.env, target, self.env.href)
        )
 def _format_link(self, formatter, ns, target, label, fullmatch=None):
     link, params, fragment = formatter.split_link(target)
     res = DjangoResource(ns, link)
     res.django_request = _get_django_request(req=formatter.req)
     res.django_context = _get_django_context(req=formatter.req)
     try:
         href = resource.get_resource_url(self.env, res, formatter.href)
         title = resource.get_resource_name(self.env, res)
         return tag.a(label, title=title, href=href + params + fragment)
     except resource.ResourceNotFound:
         return tag.a(label + '?', class_='missing', href=target, rel='nofollow')
    def test_product_neighborhood_report(self):
        target = resource.Neighborhood("product", u"xü").child(self.resource)

        self.assertEquals(u"[product:xü] report:1", resource.get_resource_description(self.env, target))
        self.assertEquals(u"[product:xü] report:1", resource.get_resource_name(self.env, target))
        self.assertEquals(u"[product:xü] report:1", resource.get_resource_shortname(self.env, target))
        self.assertEquals(u"[product:xü] report:1 at version None", resource.get_resource_summary(self.env, target))
        self.assertEquals(
            "http://example.org/trac.cgi/products/x%C3%BC/report/1",
            resource.get_resource_url(self.env, target, self.env.href),
        )
    def test_global_neighborhood_milestone(self):
        target = resource.Neighborhood("global", None).child(self.resource)

        self.assertEquals("[global:] Milestone milestone1", resource.get_resource_description(self.env, target))
        self.assertEquals("[global:] Milestone milestone1", resource.get_resource_name(self.env, target))
        self.assertEquals("milestone1", resource.get_resource_shortname(self.env, target))
        self.assertEquals("[global:] Milestone milestone1", resource.get_resource_summary(self.env, target))
        self.assertEquals(
            "http://example.org/trac.cgi/milestone/milestone1",
            resource.get_resource_url(self.env, target, self.env.href),
        )
    def test_product_neighborhood_wiki(self):
        target = resource.Neighborhood("product", u"xü").child(self.resource)

        self.assertEquals(u"TestPage", resource.get_resource_description(self.env, target))
        self.assertEquals(u"TestPage", resource.get_resource_name(self.env, target))
        self.assertEquals(u"TestPage", resource.get_resource_shortname(self.env, target))
        self.assertEquals(u"TestPage", resource.get_resource_summary(self.env, target))
        self.assertEquals(
            "http://example.org/trac.cgi/products/x%C3%BC/wiki/TestPage?version=2",
            resource.get_resource_url(self.env, target, self.env.href),
        )
    def test_global_neighborhood_wiki(self):
        target = resource.Neighborhood("global", None).child(self.resource)

        self.assertEquals("TestPage", resource.get_resource_description(self.env, target))
        self.assertEquals("TestPage", resource.get_resource_name(self.env, target))
        self.assertEquals("TestPage", resource.get_resource_shortname(self.env, target))
        self.assertEquals("TestPage", resource.get_resource_summary(self.env, target))
        self.assertEquals(
            "http://example.org/trac.cgi/wiki/TestPage?version=2",
            resource.get_resource_url(self.env, target, self.env.href),
        )
    def test_global_neighborhood_ticket(self):
        nbh = resource.Neighborhood("global", None)
        data = dict(summary="Ticket summary", description="Ticket description", type="enhancement", status="new")
        target = nbh.child("ticket", self._new_ticket(self.global_env, data))

        self.assertEquals("[global:] Ticket #1", resource.get_resource_description(self.env, target))
        self.assertEquals("[global:] Ticket #1", resource.get_resource_name(self.env, target))
        self.assertEquals("[global:] #1", resource.get_resource_shortname(self.env, target))
        self.assertEquals("enhancement: Ticket summary (new)", resource.get_resource_summary(self.env, target))
        self.assertEquals(
            "http://example.org/trac.cgi/ticket/1", resource.get_resource_url(self.env, target, self.env.href)
        )
    def test_product_neighborhood_ticket(self):
        nbh = resource.Neighborhood("product", u"xü")
        data = dict(summary="Ticket summary", description="Ticket description", type="task", status="accepted")
        target = nbh.child("ticket", self._new_ticket(self.env1, data))

        self.assertEquals(u"[product:xü] Ticket #1", resource.get_resource_description(self.env, target))
        self.assertEquals(u"[product:xü] Ticket #1", resource.get_resource_name(self.env, target))
        self.assertEquals(u"[product:xü] #1", resource.get_resource_shortname(self.env, target))
        self.assertEquals(u"task: Ticket summary (accepted)", resource.get_resource_summary(self.env, target))
        self.assertEquals(
            "http://example.org/trac.cgi/products/x%C3%BC/ticket/1",
            resource.get_resource_url(self.env, target, self.env.href),
        )
Beispiel #16
0
 def __unicode__ (self):
     if self.action:
         if self.resource:
             return _('%(perm)s privileges are required to perform '
                      'this operation on %(resource)s',
                      perm=self.action, 
                      resource=get_resource_name(self.env, self.resource))
         else:
             return _('%(perm)s privileges are required to perform '
                      'this operation', perm=self.action)
     elif self.msg:
         return self.msg
     else:
         return _('Insufficient privileges to perform this operation.')
Beispiel #17
0
    def test_product_neighborhood_attachments(self):
        target = resource.Neighborhood('product', u'xü').child(self.resource)

        self.assertEquals(u"[product:xü] Attachment 'foo.txt' in [product:xü] Ticket #1",
                          resource.get_resource_description(self.env, target))
        self.assertEquals(u"[product:xü] Attachment 'foo.txt' in [product:xü] Ticket #1",
                          resource.get_resource_name(self.env, target))
        self.assertEquals(u"[product:xü] foo.txt ([product:xü] Ticket #1)",
                          resource.get_resource_shortname(self.env, target))
        self.assertEquals('Product Bar',
                          resource.get_resource_summary(self.env, target))
        self.assertEquals('http://example.org/trac.cgi/products/x%C3%BC/attachment/ticket/1/foo.txt',
                          resource.get_resource_url(self.env,
                                                    target, self.env.href))
Beispiel #18
0
 def render_timeline_event(self, context, field, event):
     # Decompose event data.
     id = event[3]
     # Return apropriate content.
     resource = Resource("downloads", id)
     if field == "url":
         if context.req.perm.has_permission("DOWNLOADS_VIEW", resource):
             return get_resource_url(self.env, resource, context.req.href)
         else:
             return "#"
     elif field == "title":
         return tag("New download ", tag.em(get_resource_name(self.env, resource)), " created")
     elif field == "description":
         return get_resource_description(self.env, resource, "summary")
Beispiel #19
0
    def test_global_neighborhood_wiki(self):
        target = resource.Neighborhood('global', None).child(self.resource)

        self.assertEquals("TestPage",
                          resource.get_resource_description(self.env, target))
        self.assertEquals("TestPage",
                          resource.get_resource_name(self.env, target))
        self.assertEquals("TestPage",
                          resource.get_resource_shortname(self.env, target))
        self.assertEquals("TestPage",
                          resource.get_resource_summary(self.env, target))
        self.assertEquals(
            'http://example.org/trac.cgi/wiki/TestPage?version=2',
            resource.get_resource_url(self.env, target, self.env.href))
Beispiel #20
0
    def test_global_neighborhood_milestone(self):
        target = resource.Neighborhood('global', None).child(self.resource)

        self.assertEquals("[global:] Milestone milestone1",
                          resource.get_resource_description(self.env, target))
        self.assertEquals("[global:] Milestone milestone1",
                          resource.get_resource_name(self.env, target))
        self.assertEquals("milestone1",
                          resource.get_resource_shortname(self.env, target))
        self.assertEquals("[global:] Milestone milestone1",
                          resource.get_resource_summary(self.env, target))
        self.assertEquals(
            'http://example.org/trac.cgi/milestone/milestone1',
            resource.get_resource_url(self.env, target, self.env.href))
Beispiel #21
0
    def test_global_neighborhood_attachments(self):
        target = resource.Neighborhood('global', None).child(self.resource)

        self.assertEquals("[global:] Attachment 'foo.txt' in [global:] Ticket #1",
                          resource.get_resource_description(self.env, target))
        self.assertEquals("[global:] Attachment 'foo.txt' in [global:] Ticket #1",
                          resource.get_resource_name(self.env, target))
        self.assertEquals("[global:] foo.txt ([global:] Ticket #1)",
                          resource.get_resource_shortname(self.env, target))
        self.assertEquals('Global Bar',
                          resource.get_resource_summary(self.env, target))
        self.assertEquals('http://example.org/trac.cgi/attachment/ticket/1/foo.txt',
                          resource.get_resource_url(self.env,
                                                    target, self.env.href))
Beispiel #22
0
 def render_timeline_event(self, context, field, event):
     # Decompose event data.
     id = event[3]
     # Return apropriate content.
     resource = Resource('downloads', id)
     if field == 'url':
         if context.req.perm.has_permission('DOWNLOADS_VIEW', resource):
             return get_resource_url(self.env, resource, context.req.href)
         else:
             return '#'
     elif field == 'title':
         return tag('New download ', tag.em(get_resource_name(self.env, resource)), ' created')
     elif field == 'description':
         return get_resource_description(self.env, resource, 'summary')
Beispiel #23
0
    def test_product_neighborhood_milestone(self):
        target = resource.Neighborhood('product', u'xü').child(self.resource)

        self.assertEquals(u"[product:xü] Milestone milestone1",
                          resource.get_resource_description(self.env, target))
        self.assertEquals(u"[product:xü] Milestone milestone1",
                          resource.get_resource_name(self.env, target))
        self.assertEquals(u"milestone1",
                          resource.get_resource_shortname(self.env, target))
        self.assertEquals(u"[product:xü] Milestone milestone1",
                          resource.get_resource_summary(self.env, target))
        self.assertEquals('http://example.org/trac.cgi/products/x%C3%BC/milestone/milestone1',
                          resource.get_resource_url(self.env,
                                                    target, self.env.href))
Beispiel #24
0
    def test_product_neighborhood_wiki(self):
        target = resource.Neighborhood('product', u'xü').child(self.resource)

        self.assertEquals(u"TestPage",
                          resource.get_resource_description(self.env, target))
        self.assertEquals(u"TestPage",
                          resource.get_resource_name(self.env, target))
        self.assertEquals(u"TestPage",
                          resource.get_resource_shortname(self.env, target))
        self.assertEquals(u"TestPage",
                          resource.get_resource_summary(self.env, target))
        self.assertEquals(
            'http://example.org/trac.cgi/products/x%C3%BC/wiki/TestPage?version=2',
            resource.get_resource_url(self.env, target, self.env.href))
Beispiel #25
0
    def test_product_neighborhood_report(self):
        target = resource.Neighborhood('product', u'xü').child(self.resource)

        self.assertEquals(u"[product:xü] report:1",
                          resource.get_resource_description(self.env, target))
        self.assertEquals(u"[product:xü] report:1",
                          resource.get_resource_name(self.env, target))
        self.assertEquals(u"[product:xü] report:1",
                          resource.get_resource_shortname(self.env, target))
        self.assertEquals(u"[product:xü] report:1 at version None",
                          resource.get_resource_summary(self.env, target))
        self.assertEquals(
            'http://example.org/trac.cgi/products/x%C3%BC/report/1',
            resource.get_resource_url(self.env, target, self.env.href))
Beispiel #26
0
    def test_global_neighborhood_report(self):
        target = resource.Neighborhood('global', None).child(self.resource)

        self.assertEquals("[global:] report:1",
                          resource.get_resource_description(self.env, target))
        self.assertEquals("[global:] report:1",
                          resource.get_resource_name(self.env, target))
        self.assertEquals("[global:] report:1",
                          resource.get_resource_shortname(self.env, target))
        self.assertEquals('[global:] report:1 at version None',
                          resource.get_resource_summary(self.env, target))
        self.assertEquals(
            'http://example.org/trac.cgi/report/1',
            resource.get_resource_url(self.env, target, self.env.href))
Beispiel #27
0
 def __unicode__ (self):
     if self.action:
         if self.resource:
             return _('%(perm)s privileges are required to perform '
                      'this operation on %(resource)s. You don\'t have the '
                      'required permissions.',
                      perm=self.action, 
                      resource=get_resource_name(self.env, self.resource))
         else:
             return _('%(perm)s privileges are required to perform this '
                      'operation. You don\'t have the required '
                      'permissions.', perm=self.action)
     elif self.msg:
         return self.msg
     else:
         return _('Insufficient privileges to perform this operation.')
Beispiel #28
0
    def test_global_neighborhood_attachments(self):
        target = resource.Neighborhood('global', None).child(self.resource)

        self.assertEquals(
            "[global:] Attachment 'foo.txt' in [global:] Ticket #1",
            resource.get_resource_description(self.env, target))
        self.assertEquals(
            "[global:] Attachment 'foo.txt' in [global:] Ticket #1",
            resource.get_resource_name(self.env, target))
        self.assertEquals("[global:] foo.txt ([global:] Ticket #1)",
                          resource.get_resource_shortname(self.env, target))
        self.assertEquals('Global Bar',
                          resource.get_resource_summary(self.env, target))
        self.assertEquals(
            'http://example.org/trac.cgi/attachment/ticket/1/foo.txt',
            resource.get_resource_url(self.env, target, self.env.href))
Beispiel #29
0
    def render_timeline_event(self, context, field, event):
        # Decompose event data.
        id = event[3]

        # Return apropriate content.
        resource = Resource('downloads', id)
        if field == 'url':
           if context.req.perm.has_permission('DOWNLOADS_VIEW', resource):
               return get_resource_url(self.env, resource, context.req.href)
           else:
               return '#'
        elif field == 'title':
           return tag('New download ', tag.em(get_resource_name(self.env,
             resource)), ' created')
        elif field == 'description':
           return get_resource_description(self.env, resource, 'summary')
Beispiel #30
0
 def __unicode__ (self):
     if self.action:
         if self.resource:
             return _('%(perm)s privileges are required to perform '
                      'this operation on %(resource)s. You don\'t have the '
                      'required permissions.',
                      perm=self.action, 
                      resource=get_resource_name(self.env, self.resource))
         else:
             return _('%(perm)s privileges are required to perform this '
                      'operation. You don\'t have the required '
                      'permissions.', perm=self.action)
     elif self.msg:
         return self.msg
     else:
         return _('Insufficient privileges to perform this operation.')
Beispiel #31
0
    def test_product_neighborhood_attachments(self):
        target = resource.Neighborhood('product', u'xü').child(self.resource)

        self.assertEquals(
            u"[product:xü] Attachment 'foo.txt' in [product:xü] Ticket #1",
            resource.get_resource_description(self.env, target))
        self.assertEquals(
            u"[product:xü] Attachment 'foo.txt' in [product:xü] Ticket #1",
            resource.get_resource_name(self.env, target))
        self.assertEquals(u"[product:xü] foo.txt ([product:xü] Ticket #1)",
                          resource.get_resource_shortname(self.env, target))
        self.assertEquals('Product Bar',
                          resource.get_resource_summary(self.env, target))
        self.assertEquals(
            'http://example.org/trac.cgi/products/x%C3%BC/attachment/ticket/1/foo.txt',
            resource.get_resource_url(self.env, target, self.env.href))
Beispiel #32
0
    def test_product_neighborhood_ticket(self):
        nbh = resource.Neighborhood('product', u'xü')
        data = dict(summary='Ticket summary', description='Ticket description',
                    type='task', status='accepted')
        target = nbh.child('ticket', self._new_ticket(self.env1, data))

        self.assertEquals(u"[product:xü] Ticket #1",
                          resource.get_resource_description(self.env, target))
        self.assertEquals(u"[product:xü] Ticket #1",
                          resource.get_resource_name(self.env, target))
        self.assertEquals(u"[product:xü] #1",
                          resource.get_resource_shortname(self.env, target))
        self.assertEquals(u"task: Ticket summary (accepted)",
                          resource.get_resource_summary(self.env, target))
        self.assertEquals('http://example.org/trac.cgi/products/x%C3%BC/ticket/1',
                          resource.get_resource_url(self.env,
                                                    target, self.env.href))
Beispiel #33
0
    def test_global_neighborhood_ticket(self):
        nbh = resource.Neighborhood('global', None)
        data = dict(summary='Ticket summary', description='Ticket description',
                    type='enhancement', status='new')
        target = nbh.child('ticket', self._new_ticket(self.global_env, data))

        self.assertEquals("[global:] Ticket #1",
                          resource.get_resource_description(self.env, target))
        self.assertEquals("[global:] Ticket #1",
                          resource.get_resource_name(self.env, target))
        self.assertEquals("[global:] #1",
                          resource.get_resource_shortname(self.env, target))
        self.assertEquals('enhancement: Ticket summary (new)',
                          resource.get_resource_summary(self.env, target))
        self.assertEquals('http://example.org/trac.cgi/ticket/1',
                          resource.get_resource_url(self.env,
                                                    target, self.env.href))
Beispiel #34
0
 def __init__(self, action=None, resource=None, env=None, msg=None):
     self.action = action
     self.resource = resource
     self.env = env
     if self.action:
         if self.resource:
             msg = _("%(perm)s privileges are required to perform "
                     "this operation on %(resource)s. You don't have the "
                     "required permissions.",
                     perm=self.action,
                     resource=get_resource_name(self.env, self.resource))
         else:
             msg = _("%(perm)s privileges are required to perform this "
                     "operation. You don't have the required "
                     "permissions.", perm=self.action)
     elif msg is None:
         msg = _("Insufficient privileges to perform this operation.")
     super(PermissionError, self).__init__(msg)
Beispiel #35
0
    def test_global_neighborhood_ticket(self):
        nbh = resource.Neighborhood('global', None)
        data = dict(summary='Ticket summary',
                    description='Ticket description',
                    type='enhancement',
                    status='new')
        target = nbh.child('ticket', self._new_ticket(self.global_env, data))

        self.assertEquals("[global:] Ticket #1",
                          resource.get_resource_description(self.env, target))
        self.assertEquals("[global:] Ticket #1",
                          resource.get_resource_name(self.env, target))
        self.assertEquals("[global:] #1",
                          resource.get_resource_shortname(self.env, target))
        self.assertEquals('enhancement: Ticket summary (new)',
                          resource.get_resource_summary(self.env, target))
        self.assertEquals(
            'http://example.org/trac.cgi/ticket/1',
            resource.get_resource_url(self.env, target, self.env.href))
Beispiel #36
0
    def test_product_neighborhood_ticket(self):
        nbh = resource.Neighborhood('product', u'xü')
        data = dict(summary='Ticket summary',
                    description='Ticket description',
                    type='task',
                    status='accepted')
        target = nbh.child('ticket', self._new_ticket(self.env1, data))

        self.assertEquals(u"[product:xü] Ticket #1",
                          resource.get_resource_description(self.env, target))
        self.assertEquals(u"[product:xü] Ticket #1",
                          resource.get_resource_name(self.env, target))
        self.assertEquals(u"[product:xü] #1",
                          resource.get_resource_shortname(self.env, target))
        self.assertEquals(u"task: Ticket summary (accepted)",
                          resource.get_resource_summary(self.env, target))
        self.assertEquals(
            'http://example.org/trac.cgi/products/x%C3%BC/ticket/1',
            resource.get_resource_url(self.env, target, self.env.href))
Beispiel #37
0
 def __init__(self, action=None, resource=None, env=None, msg=None):
     self.action = action
     self.resource = resource
     self.env = env
     if self.action:
         if self.resource:
             msg = _("%(perm)s privileges are required to perform "
                     "this operation on %(resource)s. You don't have the "
                     "required permissions.",
                     perm=self.action,
                     resource=get_resource_name(self.env, self.resource))
         else:
             msg = _("%(perm)s privileges are required to perform this "
                     "operation. You don't have the required "
                     "permissions.", perm=self.action)
     elif msg is None:
         msg = _("Insufficient privileges to perform this operation.")
     self.msg = msg
     super(PermissionError, self).__init__(msg)
Beispiel #38
0
    def get_search_results(self, req, terms, filters):
        if not 'milestone' in filters:
            return
        db = self.env.get_db_cnx()
        sql_query, args = search_to_sql(db, ['name', 'description'], terms)
        cursor = db.cursor()
        cursor.execute(
            "SELECT name,due,completed,description "
            "FROM milestone "
            "WHERE " + sql_query, args)

        milestone_realm = Resource('milestone')
        for name, due, completed, description in cursor:
            milestone = milestone_realm(id=name)
            if 'MILESTONE_VIEW' in req.perm(milestone):
                yield (get_resource_url(self.env, milestone, req.href),
                       get_resource_name(self.env, milestone),
                       datetime.fromtimestamp(completed or due, utc), '',
                       shorten_result(description, terms))

        # Attachments
        for result in AttachmentModule(self.env).get_search_results(
                req, milestone_realm, terms):
            yield result
Beispiel #39
0
    def get_search_results(self, req, terms, filters):
        if not 'milestone' in filters:
            return
        db = self.env.get_db_cnx()
        sql_query, args = search_to_sql(db, ['name', 'description'], terms)
        cursor = db.cursor()
        cursor.execute("SELECT name,due,completed,description "
                       "FROM milestone "
                       "WHERE " + sql_query, args)

        milestone_realm = Resource('milestone')
        for name, due, completed, description in cursor:
            milestone = milestone_realm(id=name)
            if 'MILESTONE_VIEW' in req.perm(milestone):
                yield (get_resource_url(self.env, milestone, req.href),
                       get_resource_name(self.env, milestone),
                       datetime.fromtimestamp(
                           completed or due, utc),
                       '', shorten_result(description, terms))
        
        # Attachments
        for result in AttachmentModule(self.env).get_search_results(
            req, milestone_realm, terms):
            yield result
Beispiel #40
0
    def _format_name(self, req, url):
        linkname = url
        name = ""
        missing = False

        path_info = url
        query_string = ''
        idx = path_info.find('?')
        if idx >= 0:
            path_info, query_string = path_info[:idx], path_info[idx:]
        href = req.href(path_info) + query_string

        args = arg_list_to_args(parse_arg_list(query_string.lstrip('?')))
        version = args.get('version', False)

        path = path_info.strip('/').split('/')
        realm = path[0]
        class_ = realm
        if len(path) > 1:
            resource = Resource(realm, path[1])
            if resource:
                if realm == 'ticket':
                    linkname = get_resource_shortname(self.env, resource)
                    try:
                        name = get_resource_summary(self.env, resource)
                    except ResourceNotFound:
                        missing = True
                    else:
                        from trac.ticket.model import Ticket
                        class_ = Ticket(self.env, resource.id)['status'] + \
                            ' ' + class_
                elif realm == 'milestone':
                    linkname = get_resource_name(self.env, resource)
                elif realm == 'wiki':
                    resource = Resource(realm, '/'.join(path[1:]), version)
                    linkname = get_resource_shortname(self.env, resource)
                    if version:
                        linkname += '@' + version
                elif realm == 'report':
                    linkname = "{%s}" % path[1]
                    name = self._format_report_name(path[1])
                elif realm == 'changeset':
                    rev = path[1]
                    parent = Resource('source', '/'.join(path[2:]))
                    resource = Resource(realm, rev, False, parent)
                    linkname = "[%s]" % rev
                    name = get_resource_description(self.env, resource)
                elif realm == 'browser':
                    parent = Resource('source', path[1])
                    resource = Resource('source', '/'.join(path[2:]), False, parent)
                    linkname = get_resource_description(self.env, resource)
                    name = get_resource_summary(self.env, resource)
                elif realm == 'attachment':
                    # Assume a file and check existence
                    parent = Resource(path[1], '/'.join(path[2:-1]))
                    resource = Resource(realm, path[-1], parent=parent)
                    linkname = get_resource_name(self.env, resource)
                    if not resource_exists(self.env, resource):
                        # Assume an attachment list page and check existence
                        parent = Resource(path[1], '/'.join(path[2:]))
                        if resource_exists(self.env, parent):
                            resource = Resource(realm, parent=parent)
                            linkname = get_resource_name(self.env, resource)
                            if not query_string:
                                # Trailing slash needed for Trac < 1.0, t:#10280
                                href += '/'
                        else:
                            # Assume it's a missing attachment
                            missing = True
                else:
                    linkname = get_resource_shortname(self.env, resource)
                    name = get_resource_summary(self.env, resource)
        elif len(path) == 1 and path[0] and path[0] != 'wiki':
            linkname = path[0].capitalize()
        else:
            class_ = 'wiki'
            linkname = 'WikiStart'

        if missing:
            href = None
            class_ = 'missing ' + realm

        return {
            'class_': class_,
            'href': href,
            'linkname': linkname,
            'name': name,
            'delete': req.href.bookmark('delete_in_page', url),
        }
Beispiel #41
0
    def expand_macro(self, formatter, name, content):
        args = None
        if content:
            content = stripws(content)
            # parse arguments
            # we expect the 1st argument to be a filename (filespec)
            args = [stripws(arg) for arg
                                 in self._split_args_re.split(content)[1::2]]
        if not args:
            return ''
        # strip unicode white-spaces and ZWSPs are copied from attachments
        # section (#10668)
        filespec = args.pop(0)

        # style information
        attr = {}
        style = {}
        link = ''
        # helper for the special case `source:`
        #
        from trac.versioncontrol.web_ui import BrowserModule
        # FIXME: somehow use ResourceSystem.get_known_realms()
        #        ... or directly trac.wiki.extract_link
        try:
            browser_links = [res[0] for res in
                             BrowserModule(self.env).get_link_resolvers()]
        except Exception:
            browser_links = []
        while args:
            arg = args.pop(0)
            if self._size_re.match(arg):
                # 'width' keyword
                attr['width'] = arg
            elif arg == 'nolink':
                link = None
            elif arg.startswith('link='):
                val = arg.split('=', 1)[1]
                elt = extract_link(self.env, formatter.context, val.strip())
                elt = find_element(elt, 'href')
                link = None
                if elt is not None:
                    link = elt.attrib.get('href')
            elif arg in ('left', 'right'):
                style['float'] = arg
            elif arg == 'center':
                style['margin-left'] = style['margin-right'] = 'auto'
                style['display'] = 'block'
                style.pop('margin', '')
            elif arg in ('top', 'bottom', 'middle'):
                style['vertical-align'] = arg
            else:
                match = self._attr_re.match(arg)
                if match:
                    key, val = match.groups()
                    if (key == 'align' and
                            val in ('left', 'right', 'center')) or \
                        (key == 'valign' and
                            val in ('top', 'middle', 'bottom')):
                        args.append(val)
                    elif key in ('margin-top', 'margin-bottom'):
                        style[key] = ' %dpx' % _arg_as_int(val, key, min=1)
                    elif key in ('margin', 'margin-left', 'margin-right') \
                             and 'display' not in style:
                        style[key] = ' %dpx' % _arg_as_int(val, key, min=1)
                    elif key == 'border':
                        style['border'] = ' %dpx solid' % _arg_as_int(val, key)
                    else:
                        m = self._quoted_re.search(val)  # unquote "..." and '...'
                        if m:
                            val = m.group(1)
                        attr[str(key)] = val  # will be used as a __call__ kwd

        if self._quoted_re.match(filespec):
            filespec = filespec.strip('\'"')
        # parse filespec argument to get realm and id if contained.
        parts = [i.strip('\'"')
                 for i in self._split_filespec_re.split(filespec)[1::2]]
        realm = parts[0] if parts else None
        url = raw_url = desc = None
        attachment = None
        interwikimap = InterWikiMap(self.env)
        if realm in ('http', 'https', 'ftp', 'data'):  # absolute
            raw_url = url = filespec
            desc = url.rsplit('?')[0]
        elif realm in interwikimap:
            url, desc = interwikimap.url(realm, ':'.join(parts[1:]))
            raw_url = url
        elif filespec.startswith('//'):       # server-relative
            raw_url = url = filespec[1:]
            desc = url.rsplit('?')[0]
        elif filespec.startswith('/'):        # project-relative
            params = ''
            if '?' in filespec:
                filespec, params = filespec.rsplit('?', 1)
            url = formatter.href(filespec)
            if params:
                url += '?' + params
            raw_url, desc = url, filespec
        elif len(parts) == 3:                 # realm:id:attachment-filename
            #                                 # or intertrac:realm:id
            realm, id, filename = parts
            intertrac_target = "%s:%s" % (id, filename)
            it = formatter.get_intertrac_url(realm, intertrac_target)
            if it:
                url, desc = it
                raw_url = url + unicode_quote('?format=raw')
            else:
                attachment = Resource(realm, id).child('attachment', filename)
        elif len(parts) == 2:
            realm, filename = parts
            if realm in browser_links:  # source:path
                # TODO: use context here as well
                rev = None
                if '@' in filename:
                    filename, rev = filename.rsplit('@', 1)
                url = formatter.href.browser(filename, rev=rev)
                raw_url = formatter.href.browser(filename, rev=rev,
                                                 format='raw')
                desc = filespec
            else:  # #ticket:attachment or WikiPage:attachment
                # FIXME: do something generic about shorthand forms...
                realm = None
                id, filename = parts
                if id and id[0] == '#':
                    realm = 'ticket'
                    id = id[1:]
                elif id == 'htdocs':
                    raw_url = url = formatter.href.chrome('site', filename)
                    desc = os.path.basename(filename)
                elif id == 'shared':
                    raw_url = url = formatter.href.chrome('shared', filename)
                    desc = os.path.basename(filename)
                else:
                    realm = 'wiki'
                if realm:
                    attachment = Resource(realm, id).child('attachment',
                                                           filename)
        elif len(parts) == 1:  # it's an attachment of the current resource
            attachment = formatter.resource.child('attachment', filespec)
        else:
            return system_message(_("No filespec given"))
        if attachment:
            try:
                desc = get_resource_summary(self.env, attachment)
            except ResourceNotFound:
                link = None
                raw_url = chrome_resource_path(formatter.context.req,
                                               'common/attachment.png')
                desc = _('No image "%(id)s" attached to %(parent)s',
                         id=attachment.id,
                         parent=get_resource_name(self.env, attachment.parent))
            else:
                if 'ATTACHMENT_VIEW' in formatter.perm(attachment):
                    url = get_resource_url(self.env, attachment,
                                           formatter.href)
                    raw_url = get_resource_url(self.env, attachment,
                                               formatter.href, format='raw')

        for key in ('title', 'alt'):
            if desc and key not in attr:
                attr[key] = desc
        if style:
            attr['style'] = '; '.join('%s:%s' % (k, escape(v))
                                      for k, v in style.iteritems())
        if not WikiSystem(self.env).is_safe_origin(raw_url,
                                                   formatter.context.req):
            attr['crossorigin'] = 'anonymous'  # avoid password prompt
        result = tag.img(src=raw_url, **attr)
        if link is not None:
            result = tag.a(result, href=link or url,
                           style='padding:0; border:none')
        return result
Beispiel #42
0
    def expand_macro(self, formatter, name, content):

        args, kwargs = parse_args(content)
        
        if not args:
            page_name = get_resource_name(self.env, formatter.resource)
            mode = 'normal'
        elif len(args) == 1:
            page_name = args[0]
            mode = 'normal'
        else:
            page_name = args[0]
            mode = 'delta'

        db = self.env.get_db_cnx()
        cursor = db.cursor()
        cursor.execute("SELECT author, time FROM wiki WHERE name = '%s' "
                       "ORDER BY version DESC LIMIT 1" % page_name)
        row = cursor.fetchone()
        if not row:
            raise TracError('Wiki page "%s" not found.' % page_name)

        username = row[0]
        time_int = row[1]
        
        # see if there's a fullname associated with username
        cursor.execute("SELECT value FROM session_attribute "
                       "WHERE sid = '%s' AND name = 'name'" % username)
        row = cursor.fetchone()
        if not row:
            author = username
        else:
            author = row[0]

        if mode == 'delta':
            last_mod = to_datetime(time_int)
            now = to_datetime(None)
            elapsed = now - last_mod
            if elapsed.days == 0:
                if elapsed.seconds / 3600 > 1.5:
                    count = elapsed.seconds / 3600
                    unit = 'hour'
                elif elapsed.seconds / 60 > 1.5:
                    count = elapsed.seconds / 60
                    unit = 'minute'
                else:
                    count = elapsed.seconds
                    unit = 'second'
            elif elapsed.days / 3650 > 1.5:
                count = elapsed.days / 3650
                unit = 'decade'
            elif elapsed.days / 365 > 1.5:
                count = elapsed.days / 365
                unit = 'year'
            elif elapsed.days / 30 > 1.5:
                count = elapsed.days / 30
                unit = 'month'
            elif elapsed.days / 7 > 1.5:
                count = elapsed.days / 7
                unit = 'week'
            else:
                count = elapsed.days
                unit = 'day'
            text = "" + repr(count) + " " + unit
            if (count != 1 and count != -1): text += "s"
        else:
            text = format_datetime(time_int, '%c')

        return Markup(text)
Beispiel #43
0
    def post_process_request(self, req, template, data, content_type):
        if not req or not template or not isinstance(data, dict):
            return template, data, content_type

        model = None
        resource = None
        attachments = None

        if template in ('wiki_view.html', 'wiki_edit.html'):
            model = data.get('page')
        elif template == 'ticket.html':
            model = data.get('ticket')
        elif template in ('milestone_view.html', 'milestone_edit.html'):
            model = data.get('milestone')
        elif template == 'attachment.html':
            attachments = data.get('attachments')
            if attachments:
                resource = attachments['parent']

        if not resource and model and model.exists:
            resource = model.resource
        if not resource:
            return template, data, content_type
        if not attachments:
            attachments = data.get('attachments')
        if not attachments and model and resource:
            context = web_context(req, resource)
            attachments = AttachmentModule(self.env).attachment_data(context)
            # mark appending list of attachments in filter_stream
            attachments['tracdragdrop'] = True
            data['attachments'] = attachments

        if template in ('wiki_edit.html', 'milestone_edit.html'):
            self._add_overlayview(req)
        add_stylesheet(req, 'tracdragdrop/tracdragdrop.css')
        locale = req.locale and str(req.locale)
        if locale in self.messages_files:
            add_script(req, 'tracdragdrop/messages/%s.js' % locale)
        add_script(req, 'common/js/folding.js')
        add_script(req, 'tracdragdrop/tracdragdrop.js')
        script_data = {
            '_tracdragdrop': {
                'base_url':
                req.href().rstrip('/') + '/',
                'new_url':
                req.href('tracdragdrop', 'new', resource.realm, resource.id),
                'raw_parent_url':
                get_resource_url(self.env,
                                 resource.child('attachment'),
                                 req.href,
                                 format='raw'),
                'parent_name':
                get_resource_name(self.env, resource),
                'no_image_msg':
                dgettext('messages',
                         'No image "%(id)s" attached to %(parent)s'),
                'can_create':
                attachments.get('can_create') or False,
                'max_size':
                AttachmentModule(self.env).max_size,
            },
            'form_token': req.form_token,
        }
        add_script_data(req, script_data)

        return template, data, content_type
Beispiel #44
0
    def expand_macro(self, formatter, name, content):

        args, kwargs = parse_args(content)

        if not args:
            page_name = get_resource_name(self.env, formatter.resource)
            mode = 'normal'
        elif len(args) == 1:
            page_name = args[0]
            mode = 'normal'
        else:
            page_name = args[0]
            mode = 'delta'

        db = self.env.get_db_cnx()
        cursor = db.cursor()
        cursor.execute("SELECT author, time FROM wiki WHERE name = '%s' "
                       "ORDER BY version DESC LIMIT 1" % page_name)
        row = cursor.fetchone()
        if not row:
            raise TracError('Wiki page "%s" not found.' % page_name)

        username = row[0]
        time_int = row[1]

        # see if there's a fullname associated with username
        cursor.execute("SELECT value FROM session_attribute "
                       "WHERE sid = '%s' AND name = 'name'" % username)
        row = cursor.fetchone()
        if not row:
            author = username
        else:
            author = row[0]

        if mode == 'delta':
            last_mod = to_datetime(time_int)
            now = to_datetime(None)
            elapsed = now - last_mod
            if elapsed.days == 0:
                if elapsed.seconds / 3600 > 1.5:
                    count = elapsed.seconds / 3600
                    unit = 'hour'
                elif elapsed.seconds / 60 > 1.5:
                    count = elapsed.seconds / 60
                    unit = 'minute'
                else:
                    count = elapsed.seconds
                    unit = 'second'
            elif elapsed.days / 3650 > 1.5:
                count = elapsed.days / 3650
                unit = 'decade'
            elif elapsed.days / 365 > 1.5:
                count = elapsed.days / 365
                unit = 'year'
            elif elapsed.days / 30 > 1.5:
                count = elapsed.days / 30
                unit = 'month'
            elif elapsed.days / 7 > 1.5:
                count = elapsed.days / 7
                unit = 'week'
            else:
                count = elapsed.days
                unit = 'day'
            text = "" + repr(count) + " " + unit
            if (count != 1 and count != -1): text += "s"
        else:
            text = format_datetime(time_int, '%c')

        return Markup(text)
Beispiel #45
0
    def _format_name(self, req, url):
        linkname = url
        name = ""
        missing = False

        path_info = url
        query_string = ''
        idx = path_info.find('?')
        if idx >= 0:
            path_info, query_string = path_info[:idx], path_info[idx:]
        href = req.href(path_info) + query_string

        args = arg_list_to_args(parse_arg_list(query_string.lstrip('?')))
        version = args.get('version', False)

        path = path_info.strip('/').split('/')
        realm = path[0]
        class_ = realm
        if len(path) > 1:
            resource = Resource(realm, path[1])
            if resource:
                if realm == 'ticket':
                    linkname = get_resource_shortname(self.env, resource)
                    try:
                        name = get_resource_summary(self.env, resource)
                    except ResourceNotFound:
                        missing = True
                    else:
                        from trac.ticket.model import Ticket
                        class_ = Ticket(self.env, resource.id)['status'] + \
                            ' ' + class_
                elif realm == 'milestone':
                    linkname = get_resource_name(self.env, resource)
                elif realm == 'wiki':
                    resource = Resource(realm, '/'.join(path[1:]), version)
                    linkname = get_resource_shortname(self.env, resource)
                    if version:
                        linkname += '@' + version
                elif realm == 'report':
                    linkname = "{%s}" % path[1]
                    name = self._format_report_name(path[1])
                elif realm == 'changeset':
                    rev = path[1]
                    parent = Resource('source', '/'.join(path[2:]))
                    resource = Resource(realm, rev, False, parent)
                    linkname = "[%s]" % rev
                    name = get_resource_description(self.env, resource)
                elif realm == 'browser':
                    rm = RepositoryManager(self.env)
                    reponame, repos, path = rm.get_repository_by_path('/'.join(
                        path[1:]))
                    parent = Resource('source', reponame)
                    resource = Resource('source', path, False, parent)
                    linkname = get_resource_description(self.env, resource)
                    name = get_resource_summary(self.env, resource)
                elif realm == 'attachment':
                    # Assume a file and check existence
                    parent = Resource(path[1], '/'.join(path[2:-1]))
                    resource = Resource(realm, path[-1], parent=parent)
                    linkname = get_resource_name(self.env, resource)
                    if not resource_exists(self.env, resource):
                        # Assume an attachment list page and check existence
                        parent = Resource(path[1], '/'.join(path[2:]))
                        if resource_exists(self.env, parent):
                            resource = Resource(realm, parent=parent)
                            linkname = get_resource_name(self.env, resource)
                            if not query_string:
                                # Trailing slash needed for Trac < 1.0, t:#10280
                                href += '/'
                        else:
                            # Assume it's a missing attachment
                            missing = True
                else:
                    linkname = get_resource_shortname(self.env, resource)
                    name = get_resource_summary(self.env, resource)
        elif len(path) == 1 and path[0] and path[0] != 'wiki':
            linkname = path[0].capitalize()
        else:
            class_ = 'wiki'
            linkname = 'WikiStart'

        if missing:
            href = None
            class_ = 'missing ' + realm

        return {
            'class_': class_,
            'href': href,
            'linkname': linkname,
            'name': name,
            'delete': req.href.bookmark('delete_in_page', url),
        }
Beispiel #46
0
    def expand_macro(self, formatter, name, content):
        # args will be null if the macro is called without parenthesis.
        if not content:
            return ''
        # parse arguments
        # we expect the 1st argument to be a filename (filespec)
        args = content.split(',')
        if len(args) == 0:
            raise Exception("No argument.")
        filespec = args.pop(0)

        # style information
        size_re = re.compile('[0-9]+(%|px)?$')
        attr_re = re.compile('(align|valign|border|width|height|alt'
                             '|margin(?:-(?:left|right|top|bottom))?'
                             '|title|longdesc|class|id|usemap)=(.+)')
        quoted_re = re.compile("(?:[\"'])(.*)(?:[\"'])$")
        attr = {}
        style = {}
        link = ''
        while args:
            arg = args.pop(0).strip()
            if size_re.match(arg):
                # 'width' keyword
                attr['width'] = arg
            elif arg == 'nolink':
                link = None
            elif arg.startswith('link='):
                val = arg.split('=', 1)[1]
                elt = extract_link(self.env, formatter.context, val.strip())
                link = None
                if isinstance(elt, Element):
                    link = elt.attrib.get('href')
            elif arg in ('left', 'right'):
                style['float'] = arg
            elif arg == 'center':
                style['margin-left'] = style['margin-right'] = 'auto'
                style['display'] = 'block'
                style.pop('margin', '')
            elif arg in ('top', 'bottom', 'middle'):
                style['vertical-align'] = arg
            else:
                match = attr_re.match(arg)
                if match:
                    key, val = match.groups()
                    if (key == 'align' and 
                            val in ('left', 'right', 'center')) or \
                        (key == 'valign' and \
                            val in ('top', 'middle', 'bottom')):
                        args.append(val)
                    elif key in ('margin-top', 'margin-bottom'):
                        style[key] = ' %dpx' % int(val)
                    elif key in ('margin', 'margin-left', 'margin-right') \
                             and 'display' not in style:
                        style[key] = ' %dpx' % int(val)
                    elif key == 'border':
                        style['border'] = ' %dpx solid' % int(val)
                    else:
                        m = quoted_re.search(val) # unquote "..." and '...'
                        if m:
                            val = m.group(1)
                        attr[str(key)] = val # will be used as a __call__ kwd

        # parse filespec argument to get realm and id if contained.
        parts = filespec.split(':')
        url = raw_url = desc = None
        attachment = None
        if (parts and parts[0] in ('http', 'https', 'ftp')): # absolute
            raw_url = url = desc = filespec
        elif filespec.startswith('//'):       # server-relative
            raw_url = url = desc = filespec[1:]
        elif filespec.startswith('/'):        # project-relative
            # use href, but unquote to allow args (use default html escaping)
            raw_url = url = desc = unquote(formatter.href(filespec))
        elif len(parts) == 3:                 # realm:id:attachment-filename
            realm, id, filename = parts
            attachment = Resource(realm, id).child('attachment', filename)
        elif len(parts) == 2:
            # FIXME: somehow use ResourceSystem.get_known_realms()
            #        ... or directly trac.wiki.extract_link
            from trac.versioncontrol.web_ui import BrowserModule
            try:
                browser_links = [res[0] for res in
                                 BrowserModule(self.env).get_link_resolvers()]
            except Exception:
                browser_links = []
            if parts[0] in browser_links:   # source:path
                # TODO: use context here as well
                realm, filename = parts
                rev = None
                if '@' in filename:
                    filename, rev = filename.split('@')
                url = formatter.href.browser(filename, rev=rev)
                raw_url = formatter.href.browser(filename, rev=rev,
                                                 format='raw')
                desc = filespec
            else: # #ticket:attachment or WikiPage:attachment
                # FIXME: do something generic about shorthand forms...
                realm = None
                id, filename = parts
                if id and id[0] == '#':
                    realm = 'ticket'
                    id = id[1:]
                elif id == 'htdocs':
                    raw_url = url = formatter.href.chrome('site', filename)
                    desc = os.path.basename(filename)
                else:
                    realm = 'wiki'
                if realm:
                    attachment = Resource(realm, id).child('attachment',
                                                           filename)
        elif len(parts) == 1: # it's an attachment of the current resource
            attachment = formatter.resource.child('attachment', filespec)
        else:
            raise TracError('No filespec given')
        if attachment and 'ATTACHMENT_VIEW' in formatter.perm(attachment):
            url = get_resource_url(self.env, attachment, formatter.href)
            raw_url = get_resource_url(self.env, attachment, formatter.href,
                                       format='raw')
            try:
                desc = get_resource_summary(self.env, attachment)
            except ResourceNotFound, e:
                raw_url = formatter.href.chrome('common/attachment.png')
                desc = _('No image "%(id)s" attached to %(parent)s',
                         id=attachment.id,
                         parent=get_resource_name(self.env, attachment.parent))
Beispiel #47
0
    def format_and_send_attachment_notification(self, attachment, action):
        args = self.make_args({
            'component': esc(attachment.parent_realm),
            'timestamp': ''
        })

        if action == 'added':
            args['author'] = esc(authorinfo(attachment.author))
            args['url'] = esc(get_resource_url(self.env, attachment.resource, self.env.abs_href))
            desc = attachment.description and (" '" + attachment.description + "'") or ""
            args['log'] = esc('File ' + attachment.filename + ("%s has been attached to " % desc) + get_resource_name(self.env, attachment.resource.parent))
            args['version'] = ''
        elif action == 'deleted':
            args['author'] = ''
            args['log'] = esc('File ' + attachment.filename + ' has been deleted from ' + get_resource_name(self.env, attachment.resource.parent))
            args['version'] = ''
            args['url'] = esc(get_resource_url(self.env, attachment.resource.parent, self.env.abs_href))
        else:
            raise Exception('Unknown action type')

        self.send_message(message_template % args)
Beispiel #48
0
    def expand_macro(self, formatter, name, content):
        # args will be null if the macro is called without parenthesis.
        if not content:
            return ''
        # parse arguments
        # we expect the 1st argument to be a filename (filespec)
        args = content.split(',')
        if len(args) == 0:
            raise Exception("No argument.")
        # strip unicode white-spaces and ZWSPs are copied from attachments
        # section (#10668)
        filespec = stripws(args.pop(0))

        # style information
        size_re = re.compile('[0-9]+(%|px)?$')
        attr_re = re.compile('(align|valign|border|width|height|alt'
                             '|margin(?:-(?:left|right|top|bottom))?'
                             '|title|longdesc|class|id|usemap)=(.+)')
        quoted_re = re.compile("(?:[\"'])(.*)(?:[\"'])$")
        attr = {}
        style = {}
        link = ''
        # helper for the special case `source:`
        #
        from trac.versioncontrol.web_ui import BrowserModule
        # FIXME: somehow use ResourceSystem.get_known_realms()
        #        ... or directly trac.wiki.extract_link
        try:
            browser_links = [res[0] for res in
                             BrowserModule(self.env).get_link_resolvers()]
        except Exception:
            browser_links = []
        while args:
            arg = args.pop(0).strip()
            if size_re.match(arg):
                # 'width' keyword
                attr['width'] = arg
            elif arg == 'nolink':
                link = None
            elif arg.startswith('link='):
                val = arg.split('=', 1)[1]
                elt = extract_link(self.env, formatter.context, val.strip())
                elt = find_element(elt, 'href')
                link = None
                if elt is not None:
                    link = elt.attrib.get('href')
            elif arg in ('left', 'right'):
                style['float'] = arg
            elif arg == 'center':
                style['margin-left'] = style['margin-right'] = 'auto'
                style['display'] = 'block'
                style.pop('margin', '')
            elif arg in ('top', 'bottom', 'middle'):
                style['vertical-align'] = arg
            else:
                match = attr_re.match(arg)
                if match:
                    key, val = match.groups()
                    if (key == 'align' and
                            val in ('left', 'right', 'center')) or \
                        (key == 'valign' and \
                            val in ('top', 'middle', 'bottom')):
                        args.append(val)
                    elif key in ('margin-top', 'margin-bottom'):
                        style[key] = ' %dpx' % int(val)
                    elif key in ('margin', 'margin-left', 'margin-right') \
                             and 'display' not in style:
                        style[key] = ' %dpx' % int(val)
                    elif key == 'border':
                        style['border'] = ' %dpx solid' % int(val)
                    else:
                        m = quoted_re.search(val) # unquote "..." and '...'
                        if m:
                            val = m.group(1)
                        attr[str(key)] = val # will be used as a __call__ kwd

        # parse filespec argument to get realm and id if contained.
        parts = filespec.split(':')
        url = raw_url = desc = None
        attachment = None
        if (parts and parts[0] in ('http', 'https', 'ftp')): # absolute
            raw_url = url = filespec
            desc = url.rsplit('?')[0]
        elif filespec.startswith('//'):       # server-relative
            raw_url = url = filespec[1:]
            desc = url.rsplit('?')[0]
        elif filespec.startswith('/'):        # project-relative
            params = ''
            if '?' in filespec:
                filespec, params = filespec.rsplit('?', 1)
            url = formatter.href(filespec)
            if params:
                url += '?' + params
            raw_url, desc = url, filespec
        elif len(parts) == 3:                 # realm:id:attachment-filename
            #                                 # or intertrac:realm:id
            realm, id, filename = parts
            intertrac_target = "%s:%s" % (id, filename)
            it = formatter.get_intertrac_url(realm, intertrac_target)
            if it:
                url, desc = it
                raw_url = url + unicode_quote('?format=raw')
            else:
                attachment = Resource(realm, id).child('attachment', filename)
        elif len(parts) == 2:
            realm, filename = parts
            if realm in browser_links:   # source:path
                # TODO: use context here as well
                rev = None
                if '@' in filename:
                    filename, rev = filename.rsplit('@', 1)
                url = formatter.href.browser(filename, rev=rev)
                raw_url = formatter.href.browser(filename, rev=rev,
                                                 format='raw')
                desc = filespec
            else: # #ticket:attachment or WikiPage:attachment
                # FIXME: do something generic about shorthand forms...
                realm = None
                id, filename = parts
                if id and id[0] == '#':
                    realm = 'ticket'
                    id = id[1:]
                elif id == 'htdocs':
                    raw_url = url = formatter.href.chrome('site', filename)
                    desc = os.path.basename(filename)
                else:
                    realm = 'wiki'
                if realm:
                    attachment = Resource(realm, id).child('attachment',
                                                           filename)
        elif len(parts) == 1: # it's an attachment of the current resource
            attachment = formatter.resource.child('attachment', filespec)
        else:
            raise TracError('No filespec given')
        if attachment and 'ATTACHMENT_VIEW' in formatter.perm(attachment):
            url = get_resource_url(self.env, attachment, formatter.href)
            raw_url = get_resource_url(self.env, attachment, formatter.href,
                                       format='raw')
            try:
                desc = get_resource_summary(self.env, attachment)
            except ResourceNotFound, e:
                raw_url = formatter.href.chrome('common/attachment.png')
                desc = _('No image "%(id)s" attached to %(parent)s',
                         id=attachment.id,
                         parent=get_resource_name(self.env, attachment.parent))
Beispiel #49
0
    def expand_macro(self, formatter, name, content):
        # args will be null if the macro is called without parenthesis.
        if not content:
            return ''
        # parse arguments
        # we expect the 1st argument to be a filename (filespec)
        args = content.split(',')
        if len(args) == 0:
            raise Exception("No argument.")
        # strip unicode white-spaces and ZWSPs are copied from attachments
        # section (#10668)
        filespec = stripws(args.pop(0))

        # style information
        size_re = re.compile('[0-9]+(%|px)?$')
        attr_re = re.compile('(align|valign|border|width|height|alt'
                             '|margin(?:-(?:left|right|top|bottom))?'
                             '|title|longdesc|class|id|usemap)=(.+)')
        quoted_re = re.compile("(?:[\"'])(.*)(?:[\"'])$")
        attr = {}
        style = {}
        link = ''
        # helper for the special case `source:`
        #
        from trac.versioncontrol.web_ui import BrowserModule
        # FIXME: somehow use ResourceSystem.get_known_realms()
        #        ... or directly trac.wiki.extract_link
        try:
            browser_links = [
                res[0] for res in BrowserModule(self.env).get_link_resolvers()
            ]
        except Exception:
            browser_links = []
        while args:
            arg = stripws(args.pop(0))
            if size_re.match(arg):
                # 'width' keyword
                attr['width'] = arg
            elif arg == 'nolink':
                link = None
            elif arg.startswith('link='):
                val = arg.split('=', 1)[1]
                elt = extract_link(self.env, formatter.context, val.strip())
                elt = find_element(elt, 'href')
                link = None
                if elt is not None:
                    link = elt.attrib.get('href')
            elif arg in ('left', 'right'):
                style['float'] = arg
            elif arg == 'center':
                style['margin-left'] = style['margin-right'] = 'auto'
                style['display'] = 'block'
                style.pop('margin', '')
            elif arg in ('top', 'bottom', 'middle'):
                style['vertical-align'] = arg
            else:
                match = attr_re.match(arg)
                if match:
                    key, val = match.groups()
                    if (key == 'align' and
                            val in ('left', 'right', 'center')) or \
                        (key == 'valign' and \
                            val in ('top', 'middle', 'bottom')):
                        args.append(val)
                    elif key in ('margin-top', 'margin-bottom'):
                        style[key] = ' %dpx' % int(val)
                    elif key in ('margin', 'margin-left', 'margin-right') \
                             and 'display' not in style:
                        style[key] = ' %dpx' % int(val)
                    elif key == 'border':
                        style['border'] = ' %dpx solid' % int(val)
                    else:
                        m = quoted_re.search(val)  # unquote "..." and '...'
                        if m:
                            val = m.group(1)
                        attr[str(key)] = val  # will be used as a __call__ kwd

        # parse filespec argument to get realm and id if contained.
        parts = [
            i.strip('''['"]''')
            for i in self._split_filespec_re.split(filespec)
        ]
        url = raw_url = desc = None
        attachment = None
        if (parts and parts[0] in ('http', 'https', 'ftp')):  # absolute
            raw_url = url = filespec
            desc = url.rsplit('?')[0]
        elif filespec.startswith('//'):  # server-relative
            raw_url = url = filespec[1:]
            desc = url.rsplit('?')[0]
        elif filespec.startswith('/'):  # project-relative
            params = ''
            if '?' in filespec:
                filespec, params = filespec.rsplit('?', 1)
            url = formatter.href(filespec)
            if params:
                url += '?' + params
            raw_url, desc = url, filespec
        elif len(parts) == 3:  # realm:id:attachment-filename
            #                                 # or intertrac:realm:id
            realm, id, filename = parts
            intertrac_target = "%s:%s" % (id, filename)
            it = formatter.get_intertrac_url(realm, intertrac_target)
            if it:
                url, desc = it
                raw_url = url + unicode_quote('?format=raw')
            else:
                attachment = Resource(realm, id).child('attachment', filename)
        elif len(parts) == 2:
            realm, filename = parts
            if realm in browser_links:  # source:path
                # TODO: use context here as well
                rev = None
                if '@' in filename:
                    filename, rev = filename.rsplit('@', 1)
                url = formatter.href.browser(filename, rev=rev)
                raw_url = formatter.href.browser(filename,
                                                 rev=rev,
                                                 format='raw')
                desc = filespec
            else:  # #ticket:attachment or WikiPage:attachment
                # FIXME: do something generic about shorthand forms...
                realm = None
                id, filename = parts
                if id and id[0] == '#':
                    realm = 'ticket'
                    id = id[1:]
                elif id == 'htdocs':
                    raw_url = url = formatter.href.chrome('site', filename)
                    desc = os.path.basename(filename)
                elif id == 'shared':
                    raw_url = url = formatter.href.chrome('shared', filename)
                    desc = os.path.basename(filename)
                else:
                    realm = 'wiki'
                if realm:
                    attachment = Resource(realm,
                                          id).child('attachment', filename)
        elif len(parts) == 1:  # it's an attachment of the current resource
            attachment = formatter.resource.child('attachment', filespec)
        else:
            raise TracError('No filespec given')
        if attachment and 'ATTACHMENT_VIEW' in formatter.perm(attachment):
            url = get_resource_url(self.env, attachment, formatter.href)
            raw_url = get_resource_url(self.env,
                                       attachment,
                                       formatter.href,
                                       format='raw')
            try:
                desc = get_resource_summary(self.env, attachment)
            except ResourceNotFound as e:
                raw_url = formatter.href.chrome('common/attachment.png')
                desc = _('No image "%(id)s" attached to %(parent)s',
                         id=attachment.id,
                         parent=get_resource_name(self.env, attachment.parent))
        for key in ('title', 'alt'):
            if desc and not key in attr:
                attr[key] = desc
        if style:
            attr['style'] = '; '.join('%s:%s' % (k, escape(v))
                                      for k, v in style.iteritems())
        result = tag.img(src=raw_url, **attr)
        if link is not None:
            result = tag.a(result,
                           href=link or url,
                           style='padding:0; border:none')
        return result
Beispiel #50
0
    def expand_macro(self, formatter, name, content):
        # args will be null if the macro is called without parenthesis.
        if not content:
            return ''
        # parse arguments
        # we expect the 1st argument to be a filename (filespec)
        args = [stripws(arg) for arg
                             in self._split_args_re.split(content)[1::2]]
        # strip unicode white-spaces and ZWSPs are copied from attachments
        # section (#10668)
        filespec = args.pop(0)

        # style information
        attr = {}
        style = {}
        link = ''
        # helper for the special case `source:`
        #
        from trac.versioncontrol.web_ui import BrowserModule
        # FIXME: somehow use ResourceSystem.get_known_realms()
        #        ... or directly trac.wiki.extract_link
        try:
            browser_links = [res[0] for res in
                             BrowserModule(self.env).get_link_resolvers()]
        except Exception:
            browser_links = []
        while args:
            arg = args.pop(0)
            if self._size_re.match(arg):
                # 'width' keyword
                attr['width'] = arg
            elif arg == 'nolink':
                link = None
            elif arg.startswith('link='):
                val = arg.split('=', 1)[1]
                elt = extract_link(self.env, formatter.context, val.strip())
                elt = find_element(elt, 'href')
                link = None
                if elt is not None:
                    link = elt.attrib.get('href')
            elif arg in ('left', 'right'):
                style['float'] = arg
            elif arg == 'center':
                style['margin-left'] = style['margin-right'] = 'auto'
                style['display'] = 'block'
                style.pop('margin', '')
            elif arg in ('top', 'bottom', 'middle'):
                style['vertical-align'] = arg
            else:
                match = self._attr_re.match(arg)
                if match:
                    key, val = match.groups()
                    if (key == 'align' and
                            val in ('left', 'right', 'center')) or \
                        (key == 'valign' and
                            val in ('top', 'middle', 'bottom')):
                        args.append(val)
                    elif key in ('margin-top', 'margin-bottom'):
                        style[key] = ' %dpx' % int(val)
                    elif key in ('margin', 'margin-left', 'margin-right') \
                             and 'display' not in style:
                        style[key] = ' %dpx' % int(val)
                    elif key == 'border':
                        style['border'] = ' %dpx solid' % int(val)
                    else:
                        m = self._quoted_re.search(val)  # unquote "..." and '...'
                        if m:
                            val = m.group(1)
                        attr[str(key)] = val  # will be used as a __call__ kwd

        if self._quoted_re.match(filespec):
            filespec = filespec.strip('\'"')
        # parse filespec argument to get realm and id if contained.
        parts = [i.strip('''['"]''')
                 for i in self._split_filespec_re.split(filespec)[1::2]]
        url = raw_url = desc = None
        attachment = None
        if parts and parts[0] in ('http', 'https', 'ftp', 'data'):  # absolute
            raw_url = url = filespec
            desc = url.rsplit('?')[0]
        elif filespec.startswith('//'):       # server-relative
            raw_url = url = filespec[1:]
            desc = url.rsplit('?')[0]
        elif filespec.startswith('/'):        # project-relative
            params = ''
            if '?' in filespec:
                filespec, params = filespec.rsplit('?', 1)
            url = formatter.href(filespec)
            if params:
                url += '?' + params
            raw_url, desc = url, filespec
        elif len(parts) == 3:                 # realm:id:attachment-filename
            #                                 # or intertrac:realm:id
            realm, id, filename = parts
            intertrac_target = "%s:%s" % (id, filename)
            it = formatter.get_intertrac_url(realm, intertrac_target)
            if it:
                url, desc = it
                raw_url = url + unicode_quote('?format=raw')
            else:
                attachment = Resource(realm, id).child('attachment', filename)
        elif len(parts) == 2:
            realm, filename = parts
            if realm in browser_links:  # source:path
                # TODO: use context here as well
                rev = None
                if '@' in filename:
                    filename, rev = filename.rsplit('@', 1)
                url = formatter.href.browser(filename, rev=rev)
                raw_url = formatter.href.browser(filename, rev=rev,
                                                 format='raw')
                desc = filespec
            else:  # #ticket:attachment or WikiPage:attachment
                # FIXME: do something generic about shorthand forms...
                realm = None
                id, filename = parts
                if id and id[0] == '#':
                    realm = 'ticket'
                    id = id[1:]
                elif id == 'htdocs':
                    raw_url = url = formatter.href.chrome('site', filename)
                    desc = os.path.basename(filename)
                elif id == 'shared':
                    raw_url = url = formatter.href.chrome('shared', filename)
                    desc = os.path.basename(filename)
                else:
                    realm = 'wiki'
                if realm:
                    attachment = Resource(realm, id).child('attachment',
                                                           filename)
        elif len(parts) == 1:  # it's an attachment of the current resource
            attachment = formatter.resource.child('attachment', filespec)
        else:
            raise TracError(_("No filespec given"))
        if attachment and 'ATTACHMENT_VIEW' in formatter.perm(attachment):
            url = get_resource_url(self.env, attachment, formatter.href)
            raw_url = get_resource_url(self.env, attachment, formatter.href,
                                       format='raw')
            try:
                desc = get_resource_summary(self.env, attachment)
            except ResourceNotFound:
                raw_url = chrome_resource_path(formatter.context.req,
                                               'common/attachment.png')
                desc = _('No image "%(id)s" attached to %(parent)s',
                         id=attachment.id,
                         parent=get_resource_name(self.env, attachment.parent))
        for key in ('title', 'alt'):
            if desc and key not in attr:
                attr[key] = desc
        if style:
            attr['style'] = '; '.join('%s:%s' % (k, escape(v))
                                      for k, v in style.iteritems())
        result = tag.img(src=raw_url, **attr)
        if link is not None:
            result = tag.a(result, href=link or url,
                           style='padding:0; border:none')
        return result