Esempio n. 1
0
    def get_timeline_events(self, req, start, stop, filters):
        # timeline动作的输入
        if 'wiki' in filters:
            wiki = WikiSystem(self.env)
            format = req.args.get('format')
            href = format == 'rss' and req.abs_href or req.href
            db = self.env.get_db_cnx()
            cursor = db.cursor()
            cursor.execute("SELECT time,name,comment,author,version "
                           "FROM wiki WHERE time>=%s AND time<=%s",
                           (start, stop))
            for t,name,comment,author,version in cursor:
                title = Markup('<em>%s</em> '+ u"编辑者 %s",
                               wiki.format_page_name(name), author)
                diff_link = html.A(u'变化', href=href.wiki(name, action='diff',
                                                          version=version))
                if format == 'rss':
                    comment = wiki_to_html(comment or '--', self.env, req, db,
                                           absurls=True)
                else:
                    comment = wiki_to_oneliner(comment, self.env, db,
                                               shorten=True)
                if version > 1:
                    comment = Markup('%s (%s)', comment, diff_link)
                yield 'wiki', href.wiki(name), title, t, author, comment

            # Attachments
            att = AttachmentModule(self.env)
            for event in att.get_timeline_events(req, db, 'wiki', format,
                                                 start, stop,
                                                 lambda id: html.EM(id)):
                yield event
Esempio n. 2
0
 def _create_html_body(self, chrome, req, ticket, cnum, link):
     tktmod = TicketModule(self.env)
     attmod = AttachmentModule(self.env)
     data = tktmod._prepare_data(req, ticket)
     tktmod._insert_ticket_data(req, ticket, data, req.authname, {})
     data['ticket']['link'] = link
     changes = data.get('changes')
     if cnum is None:
         changes = []
     else:
         changes = [
             change for change in (changes or [])
             if change.get('cnum') == cnum
         ]
     data['changes'] = changes
     context = Context.from_request(req, ticket.resource, absurls=True)
     data.update({
         'can_append': False,
         'show_editor': False,
         'start_time': ticket['changetime'],
         'context': context,
         'alist': attmod.attachment_data(context),
         'styles': self._get_styles(chrome),
         'link': tag.a(link, href=link),
         'tag_': tag_,
     })
     rendered = chrome.render_template(req,
                                       'htmlnotification_ticket.html',
                                       data,
                                       fragment=True)
     return unicode(rendered)
Esempio n. 3
0
    def test_download_zip(self):
        att = Attachment(self.env, 'parent_realm', 'parent_id')
        att.description = 'Blah blah'
        att.insert('foo.txt', StringIO('foo'), 3,
                   datetime(2016, 9, 23, 12, 34, 56, tzinfo=utc))
        att = Attachment(self.env, 'parent_realm', 'parent_id')
        att.insert('bar.jpg', StringIO('bar'), 3,
                   datetime(2016, 12, 14, 23, 56, 30, tzinfo=utc))
        module = AttachmentModule(self.env)
        req = MockRequest(self.env,
                          args={'format': 'zip'},
                          path_info='/attachment/parent_realm/parent_id/')

        self.assertTrue(module.match_request(req))
        self.assertRaises(RequestDone, module.process_request, req)
        z = zipfile.ZipFile(req.response_sent, 'r')
        self.assertEqual(['bar.jpg', 'foo.txt'],
                         sorted(i.filename for i in z.infolist()))

        zinfo = z.getinfo('foo.txt')
        self.assertEqual('foo', z.read('foo.txt'))
        self.assertEqual(3, zinfo.file_size)
        self.assertEqual((2016, 9, 23, 12, 34, 56), zinfo.date_time)
        self.assertEqual('Blah blah', zinfo.comment)

        zinfo = z.getinfo('bar.jpg')
        self.assertEqual('bar', z.read('bar.jpg'))
        self.assertEqual(3, zinfo.file_size)
        self.assertEqual((2016, 12, 14, 23, 56, 30), zinfo.date_time)
        self.assertEqual('', zinfo.comment)
Esempio n. 4
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)
            data['attachments'] = attachments

        if template in ('wiki_edit.html', 'milestone_edit.html'):
            self._add_overlayview(req)
        add_stylesheet(req, 'tracdragdrop/tracdragdrop.css')
        if hasattr(req, 'locale'):
            locale = 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),
                'can_create':
                attachments.get('can_create') or False,
                'max_size':
                AttachmentModule(self.env).max_size,
            },
            'form_token': req.form_token,
        }
        if add_script_data:
            add_script_data(req, script_data)
        else:
            setattr(req, '_tracdragdrop_data', script_data)

        return template, data, content_type
Esempio n. 5
0
    def test_attachment_parent_realm_raises_exception(self):
        """TracError is raised when 'attachment' is the resource parent
        realm.
        """
        path_info = '/attachment/attachment/parent_id/attachment_id'
        req = MockRequest(self.env, path_info=path_info)
        module = AttachmentModule(self.env)

        self.assertTrue(module.match_request(req))
        self.assertRaises(TracError, module.process_request, req)
Esempio n. 6
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)
            data['attachments'] = attachments

        if template in ('wiki_edit.html', 'milestone_edit.html'):
            self._add_overlayview(req)
        add_stylesheet(req, 'tracdragdrop/tracdragdrop.css')
        if hasattr(req, 'locale'):
            locale = 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),
                'can_create': attachments.get('can_create') or False,
                'max_size': AttachmentModule(self.env).max_size,
            },
            'form_token': req.form_token,
        }
        if add_script_data:
            add_script_data(req, script_data)
        else:
            setattr(req, '_tracdragdrop_data', script_data)

        return template, data, content_type
Esempio n. 7
0
    def test_post_request_without_attachment_raises_exception(self):
        """TracError is raised for POST request with no file."""
        path_info = '/attachment/parent_realm/parent_id'
        req = MockRequest(self.env, path_info=path_info, method='POST',
                          args={'action': 'new'})
        module = AttachmentModule(self.env)

        self.assertTrue(module.match_request(req))
        with self.assertRaises(TracError) as cm:
            module.process_request(req)
        self.assertEqual("No file uploaded", unicode(cm.exception))
Esempio n. 8
0
    def test_invalid_post_request_raises_exception(self):

        path_info = '/attachment/parent_realm/parent_id/attachment_id'
        attachment = Attachment(self.env, 'parent_realm', 'parent_id')
        attachment.insert('attachment_id', io.BytesIO(), 0, 1)
        req = MockRequest(self.env, method='POST', action=None,
                          path_info=path_info)
        module = AttachmentModule(self.env)

        self.assertTrue(module.match_request(req))
        self.assertRaises(HTTPBadRequest, module.process_request, req)
Esempio n. 9
0
    def test_post_request_without_attachment_raises_exception(self):
        """TracError is raised when a POST request is submitted
        without an attachment.
        """
        path_info = '/attachment/parent_realm/parent_id'
        req = MockRequest(self.env, path_info=path_info, method='POST',
                          args={'action': 'new'})
        module = AttachmentModule(self.env)

        self.assertTrue(module.match_request(req))
        self.assertRaises(TracError, module.process_request, req)
Esempio n. 10
0
    def test_post_request_with_empty_attachment_raises_exception(self):
        """TracError is raised for POST request with empty file."""
        module = AttachmentModule(self.env)
        path_info = '/attachment/parent_realm/parent_id'
        with tempfile.NamedTemporaryFile('rb', dir=self.env.path) as file_:
            upload = Mock(filename=file_.name, file=file_)
            req = MockRequest(self.env, path_info=path_info, method='POST',
                              args={'action': 'new', 'attachment': upload})

            self.assertTrue(module.match_request(req))
            with self.assertRaises(TracError) as cm:
                module.process_request(req)
        self.assertEqual("Can't upload empty file", unicode(cm.exception))
Esempio n. 11
0
def attachment_to_hdf(env, req, db, attachment):
    """
    This function have been removed from 0.11, this is copied from 0.10, then modified to 
    work with 0.11
    """
    if not db:
        db = env.get_db_cnx()
    hdf = {
        'filename':
        attachment.filename,
        'description':
        wiki_to_oneliner(attachment.description, env, db, req=req),
        'author':
        attachment.author,
        'ipnr':
        attachment.ipnr,
        'size':
        pretty_size(attachment.size),
        'time':
        format_datetime(attachment.date),
        'age':
        pretty_timedelta(attachment.date),
        'href':
        AttachmentModule(env).get_resource_url(attachment.resource, req.href)
    }
    return hdf
Esempio n. 12
0
    def test_preview_valid_xhtml(self):
        chrome = Chrome(self.env)
        module = AttachmentModule(self.env)

        def render(attachment):
            path_info = '/attachment/%s/%s/%s' % (attachment.parent_realm,
                                                  attachment.parent_id,
                                                  attachment.filename)
            req = MockRequest(self.env, path_info=path_info)
            self.assertTrue(module.match_request(req))
            template, data = module.process_request(req)
            return chrome.render_template(req, template, data,
                                          {'fragment': True})

        # empty file
        attachment = Attachment(self.env, 'parent_realm', 'parent_id')
        attachment.insert('empty', io.BytesIO(), 0, 1)
        result = render(attachment)
        self.assertIn('<strong>(The file is empty)</strong>', result)
        xml = minidom.parseString(result)

        # text file
        attachment = Attachment(self.env, 'parent_realm', 'parent_id')
        attachment.insert('foo.txt', io.BytesIO(b'text'), 4, 1)
        result = render(attachment)
        self.assertIn('<tr><th id="L1"><a href="#L1">1</a></th>'
                      '<td>text</td></tr>', result)
        xml = minidom.parseString(result)

        # preview unavailable
        attachment = Attachment(self.env, 'parent_realm', 'parent_id')
        attachment.insert('foo.dat', io.BytesIO(b'\x00\x00\x01\xb3'), 4, 1)
        result = render(attachment)
        self.assertIn('<strong>HTML preview not available</strong>', result)
        xml = minidom.parseString(result)
Esempio n. 13
0
    def get_search_results(self, req, terms, filters):
        if not 'wiki' in filters:
            return
        with self.env.db_query as db:
            sql_query, args = search_to_sql(
                db, ['w1.name', 'w1.author', 'w1.text'], terms)
            wiki_realm = Resource('wiki')
            for name, ts, author, text in db(
                    """
                    SELECT w1.name, w1.time, w1.author, w1.text
                    FROM wiki w1,(SELECT name, max(version) AS ver
                                  FROM wiki GROUP BY name) w2
                    WHERE w1.version = w2.ver AND w1.name = w2.name
                    AND """ + sql_query, args):
                page = wiki_realm(id=name)
                if 'WIKI_VIEW' in req.perm(page):
                    yield (get_resource_url(self.env, page, req.href),
                           '%s: %s' % (name, shorten_line(text)),
                           from_utimestamp(ts), author,
                           shorten_result(text, terms))

        # Attachments
        for result in AttachmentModule(self.env).get_search_results(
                req, wiki_realm, terms):
            yield result
Esempio n. 14
0
    def filter_stream(self, req, method, filename, stream, data):
        """Return a filtered Genshi event stream, or the original unfiltered
        stream if no match.
        """

        if filename == "ticket.html" and \
                ('TICKET_REMINDER_VIEW' in req.perm or
                 'TICKET_REMINDER_MODIFY' in req.perm or
                 'TICKET_ADMIN' in req.perm):
            tags = self._reminder_tags(req, data)
            if tags:
                ticket_resource = data['ticket'].resource
                context = Context.from_request(req, ticket_resource)
                attachments_data = AttachmentModule(
                    self.env).attachment_data(context)

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

                # Will attachments section be displayed?
                attachments_or_ticket = Transformer(
                    '//div[@id="attachments"]'
                ) if attachments_data['can_create'] or attachments_data[
                    'attachments'] else Transformer('//div[@id="ticket"]')
                trac_nav = Transformer(
                    '//form[@id="propertyform"]/div[@class="trac-nav"]')

                return stream | attachments_or_ticket.after(
                    tags) | trac_nav.append(self._reminder_trac_nav(req, data))

        return stream
Esempio n. 15
0
    def _render_editor(self, req, db, milestone):
        data = {
            'milestone': milestone,
            'ticket': milestone.ticket,
            'datefields': self.date_fields,
            'date_hint': get_date_format_hint(),
            'datetime_hint': get_datetime_format_hint(),
            'milestone_groups': [],
            'jump_to': req.args.get('jump_to') or referer_module(req)
        }

        if milestone.exists:
            req.perm(milestone.resource).require('MILESTONE_VIEW')
            milestones = [
                m for m in StructuredMilestone.select(self.env, db=db)
                if m.name != milestone.name
                and 'MILESTONE_VIEW' in req.perm(m.resource)
            ]
            data['milestone_groups'] = group_milestones(
                milestones, 'TICKET_ADMIN' in req.perm)
        else:
            req.perm(milestone.resource).require('MILESTONE_CREATE')

        TicketModule(self.env)._insert_ticket_data(
            req, milestone.ticket, data, get_reporter_id(req, 'author'), {})
        self._add_tickets_report_data(milestone, req, data)
        context = Context.from_request(req, milestone.resource)

        data['attachments'] = AttachmentModule(
            self.env).attachment_data(context)

        return 'itteco_milestone_edit.html', data, None
Esempio n. 16
0
 def get_timeline_events(self, req, start, stop, filters):
     if 'blog' in filters:
         blog_realm = Resource('blog')
         if not 'BLOG_VIEW' in req.perm(blog_realm):
             return
         add_stylesheet(req, 'tracfullblog/css/fullblog.css')
         # Blog posts
         blog_posts = get_blog_posts(self.env, from_dt=start, to_dt=stop,
                                     all_versions=True)
         for name, version, time, author, title, body, category_list \
                 in blog_posts:
             bp_resource = blog_realm(id=name, version=version)
             if 'BLOG_VIEW' not in req.perm(bp_resource):
                 continue
             bp = BlogPost(self.env, name, version=version)
             yield ('blog', bp.version_time, bp.version_author,
                         (bp_resource, bp, None))
         # Attachments (will be rendered by attachment module)
         for event in AttachmentModule(self.env).get_timeline_events(
             req, blog_realm, start, stop):
             yield event
         # Blog comments
         blog_comments = get_blog_comments(self.env, from_dt=start, to_dt=stop)
         blog_comments = sorted(blog_comments, key=operator.itemgetter(4),
                                reverse=True)
         for post_name, number, comment, author, time in blog_comments:
             bp_resource = blog_realm(id=post_name)
             if 'BLOG_VIEW' not in req.perm(bp_resource):
                 continue
             bp = BlogPost(self.env, post_name)
             bc = BlogComment(self.env, post_name, number=number)
             yield 'blog', time, author, (bp_resource, bp, bc)
Esempio n. 17
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):
                dt = (completed and from_utimestamp(completed)
                      or due and from_utimestamp(due) or datetime.now(utc))
                yield (get_resource_url(self.env, milestone, req.href),
                       get_resource_name(self.env, milestone), dt, '',
                       shorten_result(description, terms))

        # Attachments
        for result in AttachmentModule(self.env).get_search_results(
                req, milestone_realm, terms):
            yield result
Esempio n. 18
0
    def test_post_request_exceeding_max_size_raises_exception(self):
        """TracError is raised for file exceeding max size"""
        self.env.config.set('attachment', 'max_size', 10)
        module = AttachmentModule(self.env)
        path_info = '/attachment/parent_realm/parent_id'
        with tempfile.NamedTemporaryFile('w+b', dir=self.env.path) as file_:
            file_.write(b' ' * (module.max_size + 1))
            file_.flush()
            upload = Mock(filename=file_.name, file=file_)
            req = MockRequest(self.env, path_info=path_info, method='POST',
                              args={'action': 'new', 'attachment': upload})

            self.assertTrue(module.match_request(req))
            with self.assertRaises(TracError) as cm:
                module.process_request(req)
        self.assertEqual("Maximum attachment size: 10 bytes",
                         unicode(cm.exception))
Esempio n. 19
0
    def _delegate_new_request(self, req):
        attachments = req.args.get('attachment')
        if not isinstance(attachments, list):
            attachments = [attachments]

        mod = AttachmentModule(self.env)
        for val in attachments:
            req.args['attachment'] = val
            try:
                mod.process_request(req)
            except OSError, e:
                if e.args[0] == errno.ENAMETOOLONG:
                    raise TracError(_("File name too long"))
                if os.name == 'nt' and e.args[0] == errno.ENOENT:
                    raise TracError(_("File name too long"))
                raise TracError(os.strerror(e.args[0]))
            except RedirectListened:
                pass
Esempio n. 20
0
    def test_wiki_link_foreign(self):
        attachment = Attachment(self.env, 'ticket', 123)
        attachment.insert('foo.txt', tempfile.TemporaryFile(), 0)

        ns, func = AttachmentModule(self.env).get_link_resolvers().next()
        self.assertEqual('attachment', ns)

        req = Mock(path_info='/wiki')
        formatter = Formatter(self.env, req)
        self.assertEqual('<a class="attachment" title="Attachment #123: '
                         'foo.txt" href="/trac.cgi/attachment/ticket/123/'
                         'foo.txt">Foo</a>',
                         func(formatter, ns, 'ticket:123:foo.txt', 'Foo'))
Esempio n. 21
0
 def __init__(self, env, req):
     max_size = AttachmentModule(env).max_size
     size = self.__get_content_length(req)
     self.__verify_size(size, max_size)
     tempfile = TemporaryFile()
     try:
         self.__read_content(req, tempfile, size, max_size)
     except:
         tempfile.close()
         raise
     self.file = tempfile
     filename = req.get_header('X-TracDragDrop-Filename')
     self.filename = unicode_unquote(filename or '').encode('utf-8')
Esempio n. 22
0
    def get_timeline_events(self, req, start, stop, filters):
        # timeline动作的输入
        if 'wiki' in filters:
            wiki = WikiSystem(self.env)
            format = req.args.get('format')
            href = format == 'rss' and req.abs_href or req.href
            db = self.env.get_db_cnx()
            cursor = db.cursor()
            cursor.execute(
                "SELECT time,name,comment,author,version "
                "FROM wiki WHERE time>=%s AND time<=%s", (start, stop))
            for t, name, comment, author, version in cursor:
                title = Markup('<em>%s</em> ' + u"编辑者 %s",
                               wiki.format_page_name(name), author)
                diff_link = html.A(u'变化',
                                   href=href.wiki(name,
                                                  action='diff',
                                                  version=version))
                if format == 'rss':
                    comment = wiki_to_html(comment or '--',
                                           self.env,
                                           req,
                                           db,
                                           absurls=True)
                else:
                    comment = wiki_to_oneliner(comment,
                                               self.env,
                                               db,
                                               shorten=True)
                if version > 1:
                    comment = Markup('%s (%s)', comment, diff_link)
                yield 'wiki', href.wiki(name), title, t, author, comment

            # Attachments
            att = AttachmentModule(self.env)
            for event in att.get_timeline_events(req, db, 'wiki', format,
                                                 start, stop,
                                                 lambda id: html.EM(id)):
                yield event
Esempio n. 23
0
    def test_wiki_link_subpage(self):
        attachment = Attachment(self.env, 'wiki', 'SomePage/SubPage')
        attachment.insert('foo.txt', tempfile.TemporaryFile(), 0)

        ns, func = AttachmentModule(self.env).get_link_resolvers().next()
        self.assertEqual('attachment', ns)

        req = Mock(path_info='/wiki/SomePage/SubPage')
        formatter = Formatter(self.env, req)
        self.assertEqual(
            '<a class="attachment" '
            'title="Attachment SomePage/SubPage: foo.txt" '
            'href="/trac.cgi/attachment/wiki/SomePage/SubPage/'
            'foo.txt">Foo</a>', func(formatter, ns, 'foo.txt', 'Foo'))
Esempio n. 24
0
    def _render_view(self, req, db, version):

        db = self.env.get_db_cnx()
        sql = "SELECT name FROM milestone " \
              "INNER JOIN milestone_version ON (name = milestone) " \
              "WHERE version = %s " \
              "ORDER BY due"
        cursor = db.cursor()
        cursor.execute(sql, (version.name,))

        milestones = []
        tickets = []
        milestone_stats = []

        for row in cursor:
            milestone = Milestone(self.env, row[0])
            milestones.append(milestone)

            mtickets = get_tickets_for_milestone(self.env, db, milestone.name,
                                                 'owner')
            mtickets = apply_ticket_permissions(self.env, req, mtickets)
            tickets += mtickets
            stat = get_ticket_stats(self.milestone_stats_provider, mtickets)
            milestone_stats.append(milestone_stats_data(self.env, req, stat, milestone.name))

        stats = get_ticket_stats(self.version_stats_provider, tickets)
        interval_hrefs = version_interval_hrefs(self.env, req, stats,
                                                [milestone.name for milestone in milestones])

        version.resource = Resource('version', version.name)
        context = Context.from_request(req, version.resource)

        version.is_released = version.time and version.time.date() < date.today()
        version.stats = stats
        version.interval_hrefs = interval_hrefs
        version.stats_href = [] # Not implemented yet, see th:#10349
        data = {
            'context': context,
            'version': version,
            'attachments': AttachmentModule(self.env).attachment_data(context),
            'milestones': milestones,
            'milestone_stats': milestone_stats,
            'show_milestone_description': self.show_milestone_description # Not implemented yet
        }

        add_stylesheet(req, 'extendedversion/css/version.css')
        add_script(req, 'common/js/folding.js')
        add_ctxtnav(req, _("Back to Versions"), req.href.versions())
        return 'version_view.html', data, None
Esempio n. 25
0
    def _alter_req(self, req):
        alter = False
        if req.path_info.startswith('/wiki/'):
            if not req.perm.has_permission('WIKI_DELETE_SELF') or \
               req.perm.has_permission('WIKI_DELETE'):
                return  # Not allowed

            pagename = req.path_info[6:] or 'WikiStart'
            page = WikiPage(self.env, pagename, version=1)

            if not page.exists: return  # Sanity check

            if req.authname == page.author:
                alter = 'WIKI_DELETE'
        elif AttachmentModule(self.env).match_request(req):
            parent_type = req.args.get('type')
            path = req.args.get('path')
            if req.args.get('action') == 'new':
                return  # Delete permissions don't matter for this anyway

            needed_perm = {
                'ticket': 'TICKET_DELETE',
                'wiki': 'WIKI_DELETE'
            }[parent_type]
            if not req.perm.has_permission(needed_perm+'_SELF') or \
               req.perm.has_permission(needed_perm):
                return  # Not allowed

            segments = path.split('/')
            parent_id = '/'.join(segments[:-1])
            last_segment = segments[-1]
            if len(segments) == 1:
                return  # List view, don't care about this

            try:
                attachment = Attachment(self.env, parent_type, parent_id,
                                        last_segment)
            except TracError:
                return  # Sanity check

            if req.authname == attachment.author:
                alter = needed_perm

        if alter:
            self.log.info(
                'SelfDeleteModule: Allowing user %s to delete the resource at %s.',
                req.authname, req.path_info)
            req.perm.perms[alter] = True
            req.hdf['trac.acl.%s' % alter] = '1'
Esempio n. 26
0
    def _render_view(self, req, version):
        milestones = []
        tickets = []
        milestone_stats = []

        for name, in self.env.db_query(
                """
                SELECT name FROM milestone
                 INNER JOIN milestone_version ON (name = milestone)
                WHERE version = %s
                ORDER BY due
                """, (version.name, )):
            milestone = Milestone(self.env, name)
            milestones.append(milestone)

            mtickets = get_tickets_for_milestone(self.env, milestone.name,
                                                 'owner')
            mtickets = apply_ticket_permissions(self.env, req, mtickets)
            tickets += mtickets
            stat = get_ticket_stats(self.milestone_stats_provider, mtickets)
            milestone_stats.append(
                milestone_stats_data(self.env, req, stat, milestone.name))

        stats = get_ticket_stats(self.version_stats_provider, tickets)
        interval_hrefs = version_interval_hrefs(
            self.env, req, stats, [milestone.name for milestone in milestones])

        version.resource = Resource('version', version.name)
        context = web_context(req, version.resource)

        version.is_released = version.time \
            and version.time < datetime.now(utc)
        version.stats = stats
        version.interval_hrefs = interval_hrefs
        names = [milestone.name for milestone in milestones]
        version.stats_href = version_stats_href(self.env, req, names)
        data = {
            'version': version,
            'attachments': AttachmentModule(self.env).attachment_data(context),
            'milestones': milestones,
            'milestone_stats': milestone_stats,
            'show_milestone_description':
            self.show_milestone_description  # Not implemented yet
        }

        add_stylesheet(req, 'extendedversion/css/version.css')
        add_script(req, 'common/js/folding.js')
        add_ctxtnav(req, _("Back to Versions"), req.href.versions())
        return 'version_view.html', data, None
Esempio n. 27
0
    def get_search_results(self, req, terms, filters):
        """Overriding search results for Tickets"""
        if not 'ticket' in filters:
            return
        ticket_realm = Resource('ticket')
        with self.env.db_query as db:
            sql, args = search_to_sql(db, [
                'summary', 'keywords', 'description', 'reporter', 'cc',
                db.cast('id', 'text')
            ], terms)
            sql2, args2 = search_to_sql(db, ['newvalue'], terms)
            sql3, args3 = search_to_sql(db, ['value'], terms)
            ticketsystem = TicketSystem(self.env)
            if req.args.get('product'):
                productsql = "product='%s' AND" % req.args.get('product')
            else:
                productsql = ""

            for summary, desc, author, type, tid, ts, status, resolution in \
                    db("""SELECT summary, description, reporter, type, id,
                                 time, status, resolution
                          FROM ticket
                          WHERE (%s id IN (
                              SELECT id FROM ticket WHERE %s
                            UNION
                              SELECT ticket FROM ticket_change
                              WHERE field='comment' AND %s
                            UNION
                              SELECT ticket FROM ticket_custom WHERE %s
                          ))
                          """ % (productsql, sql, sql2, sql3),
                          args + args2 + args3):
                t = ticket_realm(id=tid)
                if 'TICKET_VIEW' in req.perm(t):
                    yield (req.href.ticket(tid),
                           tag_("%(title)s: %(message)s",
                                title=tag.span(get_resource_shortname(
                                    self.env, t),
                                               class_=status),
                                message=ticketsystem.format_summary(
                                    summary, status, resolution,
                                    type)), from_utimestamp(ts), author,
                           shorten_result(desc, terms))

        # Attachments
        for result in AttachmentModule(self.env) \
                      .get_search_results(req, ticket_realm, terms):
            yield result
Esempio n. 28
0
    def process_request(self, req):
        if req.get_header('X-Requested-With') != 'XMLHttpRequest':
            req.send('', status=204)

        cmd = req.args.get('cmd')
        try:
            if cmd == 'attachment':
                req.environ['PATH_INFO'] = req.path_info[len('/overlayview'):] \
                                           .encode('utf-8')
                template, data, content_type = \
                    AttachmentModule(self.env).process_request(req)
                return 'overlayview_attachment.html', data, content_type
        except RequestDone:
            raise
        except (PermissionError, HTTPForbidden), e:
            self._send_exception(req, e, 403)
Esempio n. 29
0
    def get_timeline_events(self, req, start, stop, filters):
        if 'build' not in filters:
            return

        # Attachments (will be rendered by attachment module)
        for event in AttachmentModule(self.env).get_timeline_events(
                req, Resource('build'), start, stop):
            yield event

        start = to_timestamp(start)
        stop = to_timestamp(stop)

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

        db = self.env.get_db_cnx()
        cursor = db.cursor()
        cursor.execute(
            "SELECT b.id,b.config,c.label,c.path, b.rev,p.name,"
            "b.stopped,b.status FROM bitten_build AS b"
            "  INNER JOIN bitten_config AS c ON (c.name=b.config) "
            "  INNER JOIN bitten_platform AS p ON (p.id=b.platform) "
            "WHERE b.stopped>=%s AND b.stopped<=%s "
            "AND b.status IN (%s, %s) ORDER BY b.stopped",
            (start, stop, Build.SUCCESS, Build.FAILURE))

        repos = self.env.get_repository(authname=req.authname)
        assert repos, 'No "(default)" Repository: Add a repository or alias ' \
                      'named "(default)" to Trac.'

        event_kinds = {
            Build.SUCCESS: 'successbuild',
            Build.FAILURE: 'failedbuild'
        }

        for id_, config, label, path, rev, platform, stopped, status in cursor:
            if not _has_permission(req.perm, repos, path, rev=rev):
                continue
            errors = []
            if status == Build.FAILURE:
                for step in BuildStep.select(self.env,
                                             build=id_,
                                             status=BuildStep.FAILURE,
                                             db=db):
                    errors += [(step.name, error) for error in step.errors]
            display_rev = repos.normalize_rev(rev)
            yield (event_kinds[status], to_datetime(stopped, utc), None,
                   (id_, config, label, display_rev, platform, status, errors))
Esempio n. 30
0
    def get_timeline_events(self, req, start, stop, filters):
        if 'wiki' in filters:
            wiki_realm = Resource(self.realm)
            for ts, name, comment, author, version in self.env.db_query("""
                    SELECT time, name, comment, author, version FROM wiki
                    WHERE time>=%s AND time<=%s
                    """, (to_utimestamp(start), to_utimestamp(stop))):
                wiki_page = wiki_realm(id=name, version=version)
                if 'WIKI_VIEW' not in req.perm(wiki_page):
                    continue
                yield ('wiki', from_utimestamp(ts), author,
                       (wiki_page, comment))

            # Attachments
            for event in AttachmentModule(self.env).get_timeline_events(
                    req, wiki_realm, start, stop):
                yield event
Esempio n. 31
0
    def get_timeline_events(self, req, start, stop, filters):
        if 'milestone' in filters:
            milestone_realm = Resource(self.realm)
            for name, due, completed, description \
                    in MilestoneCache(self.env).milestones.itervalues():
                if completed and start <= completed <= stop:
                    # TODO: creation and (later) modifications should also be
                    #       reported
                    milestone = milestone_realm(id=name)
                    if 'MILESTONE_VIEW' in req.perm(milestone):
                        yield ('milestone', completed, '',  # FIXME: author?
                               (milestone, description))

            # Attachments
            for event in AttachmentModule(self.env).get_timeline_events(
                    req, milestone_realm, start, stop):
                yield event
Esempio n. 32
0
    def get_timeline_events(self, req, start, stop, filters):
        if 'milestone' in filters:
            milestone_realm = Resource('milestone')
            for completed, name, description in self.env.db_query("""
                    SELECT completed, name, description FROM milestone
                    WHERE completed>=%s AND completed<=%s
                    """, (to_utimestamp(start), to_utimestamp(stop))):
                # TODO: creation and (later) modifications should also be
                #       reported
                milestone = milestone_realm(id=name)
                if 'MILESTONE_VIEW' in req.perm(milestone):
                    yield ('milestone', from_utimestamp(completed),
                           '', (milestone, description)) # FIXME: author?

            # Attachments
            for event in AttachmentModule(self.env).get_timeline_events(
                req, milestone_realm, start, stop):
                yield event