Changeset 1609

Show
Ignore:
Timestamp:
11/29/06 16:56:34 (2 years ago)
Author:
coderanger
Message:

PrivateTicketsPlugin:

Filter other formats on queries. (refs #920)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • privateticketsplugin/0.10/privatetickets/query.py

    r1469 r1609  
    11from trac.core import * 
    22from trac.web.api import IRequestFilter 
    3 from trac.ticket.query import QueryModule 
     3from trac.ticket.query import QueryModule, Query 
     4from trac.mimeview.api import Mimeview, IContentConverter 
     5from trac.wiki import wiki_to_html 
     6from trac.util.datefmt import http_date 
     7from trac.util.text import CRLF 
     8 
     9from StringIO import StringIO 
    410 
    511from api import PrivateTicketsSystem 
     
    1420    # IRequestFilter methods 
    1521    def pre_process_request(self, req, handler): 
     22        if isinstance(handler, QueryModule) and req.args.get('format'): 
     23            self.log.debug('PrivateTickets: Intercepting formatted query') 
     24            return self # XXX: Hack due to IContentConverter being b0rked <NPK> 
    1625        return handler 
    1726       
     
    4352             
    4453            self.log.debug('PrivateTickets: new_results = %r', new_results) 
    45              
     54 
    4655            # Reinsert the data 
    4756            req.hdf['query.results'] = new_results 
    4857                 
    4958        return template, content_type 
     59 
     60    # Content conversion insanity 
     61    def process_request(self, req): 
     62        constraints = QueryModule(self.env)._get_constraints(req) 
     63        if not constraints and not req.args.has_key('order'): 
     64            # avoid displaying all tickets when the query module is invoked 
     65            # with no parameters. Instead show only open tickets, possibly 
     66            # associated with the user 
     67            constraints = {'status': ('new', 'assigned', 'reopened')} 
     68            if req.authname and req.authname != 'anonymous': 
     69                constraints['owner'] = (req.authname,) 
     70            else: 
     71                email = req.session.get('email') 
     72                name = req.session.get('name') 
     73                if email or name: 
     74                    constraints['cc'] = ('~%s' % email or name,) 
     75 
     76        query = Query(self.env, constraints, req.args.get('order'), 
     77                      req.args.has_key('desc'), req.args.get('group'), 
     78                      req.args.has_key('groupdesc'), 
     79                      req.args.has_key('verbose')) 
     80                       
     81        format = req.args.get('format') 
     82        self.send_converted(req, 'trac.ticket.Query', query, format, 'query') 
     83     
     84    def get_supported_conversions(self): 
     85        yield ('csv', 'Comma-delimited Text', 'csv', 
     86               'trac.ticket.Query', 'text/csv', 9) 
     87                
     88    def convert_content(self, req, mimetype, query, key): 
     89        if key == 'rss': 
     90            return self.export_rss(req, query) + ('rss',) 
     91        elif key == 'csv': 
     92            return self.export_csv(req, query, mimetype='text/csv') + ('csv',) 
     93        elif key == 'tab': 
     94            return self.export_csv(req, query, '\t', 'text/tab-separated-values') + ('tsv',) 
     95 
     96    def send_converted(self, req, in_type, content, selector, filename='file'): # Stolen from Mimetype 
     97        """Helper method for converting `content` and sending it directly. 
     98 
     99        `selector` can be either a key or a MIME Type.""" 
     100        from trac.web import RequestDone 
     101        content, output_type, ext = self.convert_content(req, in_type, 
     102                                                         content, selector) 
     103        req.send_response(200) 
     104        req.send_header('Content-Type', output_type) 
     105        req.send_header('Content-Disposition', 'filename=%s.%s' % (filename, 
     106                                                                   ext)) 
     107        req.end_headers() 
     108        req.write(content) 
     109        raise RequestDone  
     110 
     111    # Hacked content converters 
     112    def export_csv(self, req, query, sep=',', mimetype='text/plain'): 
     113        self.log.debug('PrivateTicket: Running hacked CSV converter') 
     114        content = StringIO() 
     115        cols = query.get_columns() 
     116        content.write(sep.join([col for col in cols]) + CRLF) 
     117 
     118        fn = PrivateTicketsSystem(self.env).check_ticket_access 
     119        results = query.execute(req, self.env.get_db_cnx()) 
     120        for result in results: 
     121            # Filter data 
     122            if not fn(req, result['id']): 
     123                continue 
     124         
     125            content.write(sep.join([unicode(result[col]).replace(sep, '_') 
     126                                                        .replace('\n', ' ') 
     127                                                        .replace('\r', ' ') 
     128                                    for col in cols]) + CRLF) 
     129        return (content.getvalue(), '%s;charset=utf-8' % mimetype) 
     130 
     131    def export_rss(self, req, query): 
     132        query.verbose = True 
     133        db = self.env.get_db_cnx() 
     134        fn = PrivateTicketsSystem(self.env).check_ticket_access 
     135        results = [r for r in query.execute(req, db) if fn(req, r['id'])] 
     136        for result in results: 
     137            result['href'] = req.abs_href.ticket(result['id']) 
     138            if result['reporter'].find('@') == -1: 
     139                result['reporter'] = '' 
     140            if result['description']: 
     141                # unicode() cancels out the Markup() returned by wiki_to_html 
     142                descr = wiki_to_html(result['description'], self.env, req, db, 
     143                                     absurls=True) 
     144                result['description'] = unicode(descr) 
     145            if result['time']: 
     146                result['time'] = http_date(result['time']) 
     147        req.hdf['query.results'] = results 
     148        req.hdf['query.href'] = req.abs_href.query(group=query.group, 
     149                groupdesc=query.groupdesc and 1 or None, 
     150                verbose=query.verbose and 1 or None, 
     151                **query.constraints) 
     152        return (req.hdf.render('query_rss.cs'), 'application/rss+xml')