Changeset 3040

Show
Ignore:
Timestamp:
01/11/08 20:34:40 (10 months ago)
Author:
ixokai
Message:

Adds experimental plain text and HTML formatters; allllmoooost theeere.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • announcerplugin/0.11/announcerplugin/api.py

    r3026 r3040  
    332332            for sp in supported_subscribers: 
    333333                subscriptions.update( 
    334                     x for x in sp.check_event(evt) if x 
     334                    x for x in sp.get_subscriptions_for_event(evt) if x 
    335335                ) 
    336336         
  • announcerplugin/0.11/announcerplugin/distributors/email.py

    r3026 r3040  
    77from announcerplugin.api import IAnnouncementAddressResolver 
    88from announcerplugin.api import AnnouncementSystem 
     9 
     10from email.MIMEMultipart import MIMEMultipart 
     11from email.MIMEText import MIMEText 
    912 
    1013class EmailDistributor(Component): 
     
    161164            return self._get_default_format() 
    162165             
    163     def _do_send(self, transport, event, format, recipients, formatter): 
    164         print "SENDING", recipients 
     166    def _do_send(self, transport, event, format, recipients, formatter, backup=None): 
     167        output = formatter.format(transport, event.realm, format, event) 
     168         
     169        parentMessage = MIMEMultipart("related") 
     170        parentMessage['Subject'] = "Message Subject" 
     171        parentMessage['From'] = 'Bob' 
     172        parentMessage['To'] = 'Sam' 
     173        parentMessage.preamble = 'This is a multi-part message in MIME format.' 
     174         
     175        msgText = MIMEText(output, 'html') 
     176        parentMessage.attach(msgText) 
     177         
     178        import smtplib 
     179        smtp = smtplib.SMTP() 
     180        smtp.connect(self.smtp_server) 
     181        smtp.login(self.smtp_user, self.smtp_password) 
    165182        for name, address in recipients: 
    166             print name, address 
    167             print self.resolvers 
    168         output = formatter.format(transport, event.realm, format, event) 
    169         print "THE OUTPUT IS", output 
    170          
    171          
     183            smtp.sendmail(self.smtp_from, address, parentMessage.as_string) 
     184        smtp.quit() 
     185 
    172186    # IAnnouncementDistributor 
    173187    def get_announcement_preference_boxes(self, req): 
  • announcerplugin/0.11/announcerplugin/formatters/ticket_email.py

    r3026 r3040  
    22from announcerplugin.api import IAnnouncementFormatter 
    33from trac.config import Option, IntOption 
     4from genshi.template import NewTextTemplate, MarkupTemplate 
     5from genshi import HTML 
     6from trac.web.href import Href 
     7from trac.web.chrome import Chrome 
     8from genshi.template import TemplateLoader 
     9from trac.util.text import wrap 
     10from trac.versioncontrol.diff import diff_blocks 
     11import difflib 
     12 
     13def diff_cleanup(gen): 
     14    for value in gen: 
     15        if value.startswith('---'): 
     16            continue 
     17         
     18        if value.startswith('+++'): 
     19            continue 
     20             
     21        if value.startswith('@@'): 
     22            yield '\n' 
     23        else: 
     24            yield value 
     25 
     26def lineup(gen): 
     27    for value in gen: 
     28        yield ' ' + value 
    429 
    530class TicketEmailFormatter(Component): 
     
    2853            if hasattr(self, '_format_%s' % style): 
    2954                return getattr(self, '_format_%s' % style)(event) 
     55 
     56    def _load_text_template(self, chrome, filename): 
     57        # print 'Load', chrome.templates 
     58        if not chrome.templates: 
     59            return None 
     60             
     61        return chrome.templates.load(filename, cls=NewTextTemplate) 
     62 
     63    def _format_plaintext(self, event): 
     64        ticket = event.target 
     65        short_changes = {} 
     66        long_changes = {} 
    3067         
    31     def _format_plaintext(self, event): 
    32         return "PLAIN -\n\t%s\n\t%s\n\t%s" % (event.author, event.comment, event.changes) 
     68        for field, old_value in event.changes.items(): 
     69            new_value = ticket[field] 
     70            if ('\n' in new_value) or ('\n' in old_value): 
     71                # long_changes[field.capitalize()] = \ 
     72                # '\n'.join( 
     73                #     diff_cleanup( 
     74                #         difflib.context_diff( 
     75                #             old_value.split('\r\n'), new_value.split('\r\n'), 
     76                #             lineterm='', n=2 
     77                #         ) 
     78                #     ) 
     79                # ) 
     80                long_changes[field.capitalize()] = '\n'.join( 
     81                    lineup( 
     82                        wrap(new_value, cols=67).split('\n') 
     83                    ) 
     84                ) 
     85            else: 
     86                short_changes[field.capitalize()] = (old_value, new_value) 
     87         
     88        data = dict( 
     89            ticket = ticket, 
     90            author = event.author, 
     91            comment = event.comment, 
     92            category = event.category, 
     93            ticket_link = self.env.abs_href('ticket', ticket.id), 
     94            project_name = self.env.project_name, 
     95            project_desc = self.env.project_description, 
     96            project_link = self.env.project_url, 
     97            has_changes = short_changes or long_changes, 
     98            long_changes = long_changes, 
     99            short_changes = short_changes, 
     100        ) 
     101         
     102        chrome = Chrome(self.env)         
     103        dirs = [] 
     104        for provider in chrome.template_providers: 
     105            dirs += provider.get_templates_dirs() 
     106 
     107        templates = TemplateLoader(dirs, variable_lookup='lenient') 
     108 
     109        template = templates.load('ticket_email_plaintext.txt', cls=NewTextTemplate) 
     110 
     111        if template: 
     112            stream = template.generate(**data) 
     113            output = stream.render('text') 
     114 
     115        return output 
    33116         
    34117    def _format_html(self, event): 
    35         return "HTML -\n\t%s\n\t%s\n\t%s" % (event.author, event.comment, event.changes) 
     118        ticket = event.target 
     119        short_changes = {} 
     120        long_changes = {} 
     121        chrome = Chrome(self.env)         
    36122         
    37     def _get_format(self, sid): 
    38         db = self.env.get_db_cnx() 
    39         cursor = db.cursor() 
     123        for field, old_value in event.changes.items(): 
     124            new_value = ticket[field] 
     125            if ('\n' in new_value) or ('\n' in old_value): 
     126                long_changes[field.capitalize()] = HTML( 
     127                    "<pre>\n%s\n</pre>" % ( 
     128                        '\n'.join( 
     129                            diff_cleanup( 
     130                                difflib.unified_diff( 
     131                                    wrap(old_value, cols=60).split('\n'),  
     132                                    wrap(new_value, cols=60).split('\n'), 
     133                                    lineterm='', n=3 
     134                                ) 
     135                            ) 
     136                        ) 
     137                    ) 
     138                ) 
    40139 
    41         cursor.execute(""" 
    42             SELECT value  
    43               FROM session_attribute 
    44              WHERE sid=%s 
    45                AND authenticated=1 
    46                AND name=%s 
    47         """, (sid, 'announcer_email_format_ticket')) 
     140            else: 
     141                short_changes[field.capitalize()] = (old_value, new_value) 
    48142 
    49         result = cursor.fetchone() 
    50         if result: 
    51             r = result[0] 
    52             self.log.debug("TicketEmailFormatter fetched email format preference from '%s' as: %s" % (sid, r)) 
    53             return r 
    54  
    55         return self.default_email_format 
     143        data = dict( 
     144            ticket = ticket, 
     145            author = event.author, 
     146            comment = event.comment, 
     147            category = event.category, 
     148            ticket_link = self.env.abs_href('ticket', ticket.id), 
     149            project_name = self.env.project_name, 
     150            project_desc = self.env.project_description, 
     151            project_link = self.env.project_url, 
     152            has_changes = short_changes or long_changes, 
     153            long_changes = long_changes, 
     154            short_changes = short_changes, 
     155        ) 
     156         
     157        output = chrome.render_template(None, "ticket_email_mimic.html", data, content_type="text/html", fragment = True) 
     158         
     159        return output.render() 
  • announcerplugin/0.11/announcerplugin/resolvers/specified.py

    r3015 r3040  
    3636 
    3737        if req.method == "POST": 
    38             for realm in supported_realms: 
    39                 opt = req.args.get('specified_email', False) 
    40                 if opt: 
    41                     sess['announcer_specified_email'] = opt 
    42          
     38            opt = req.args.get('specified_email', '') 
     39            sess['announcer_specified_email'] = opt 
     40 
     41        specified = sess.get('announcer_specified_email', '') 
     42             
    4343        data = dict( 
    44             specified_email = sess.get('announcer_specified_email', None)
     44            specified_email = specified
    4545        ) 
    4646         
  • announcerplugin/0.11/announcerplugin/subscribers/ticket_compat.py

    r3026 r3040  
    2626        return self._returnval 
    2727         
    28     def check_event(self, event): 
     28    def get_subscriptions_for_event(self, event): 
    2929        self.log.debug("StaticTicketSubscriber added '%s' because of rule: smtp_always_bcc" % self.bcc) 
    3030        yield ('email', None, self.bcc) 
     
    146146        return ('changed', ) 
    147147         
    148     def check_event(self, event): 
     148    def get_subscriptions_for_event(self, event): 
    149149        if event.realm == 'ticket': 
    150150            if event.category == 'changed': 
  • announcerplugin/0.11/announcerplugin/templates/prefs_announcer_emailaddress.html

    r3015 r3040  
    77  <ul> 
    88    <li> 
    9       Email address: <input type="text" name="specified_email" checked="${specified_email}" value="1" width="400"/> 
     9      Email address: <input type="text" name="specified_email" value="${specified_email}" width="500"/> 
    1010    </li>         
    1111  </ul> 
  • announcerplugin/0.11/announcerplugin/templates/ticket_email_plaintext.txt

    r3015 r3040  
    1 $ticket_body_hdr 
    2 $ticket_props 
    3 #choose ticket.new 
    4   #when True 
    5 $ticket.description 
    6   #end 
    7   #otherwise 
    8     #if changes_body 
    9 Changes (by $change.author): 
     1#${ticket.id}: ${ticket['summary']} 
     2${ticket['status']} ${ticket['type']} 
     3--------------------------------------------------------------------- 
     4Owner: {% choose %}\ 
     5{% when ticket['owner'] %}\ 
     6${ticket['owner']}\ 
     7{% end %}\ 
     8{% otherwise %}\ 
     9(None)\ 
     10{% end %}\ 
     11{% end %} 
     12Reporter: ${ticket['reporter']} 
     13{% if ticket['milestone'] %}Milestone: ${ticket['milestone']} {% end %} 
     14{% if ticket['priority'] %}Priority: ${ticket['priority']} {% end %} 
     15{% if ticket['severity'] %}Severity: ${ticket['severity']} {% end %} 
     16{% if category == 'created' %}\ 
     17--------------------------------------------------------------------- 
     18${ticket['description']} 
     19{% end %}\ 
     20{% if has_changes %}\ 
     21--------------------------------------------------------------------- 
     22Changes (by ${author}):  
     23{% for change in short_changes %} 
     24 * ${change} from '${short_changes[change][0]}' to \ 
     25{% choose %}\ 
     26{% when short_changes[change][1] %}\ 
     27'${short_changes[change][1]}'{% end %}\ 
     28{% otherwise %}\ 
     29(deleted){% end %}\ 
     30{% end %}\ 
     31{% end %}\ 
     32{% for change in long_changes %}\ 
    1033 
    11 $changes_body 
    12     #end 
    13     #if changes_descr 
    14       #if not changes_body and not change.comment and change.author 
    15 Description changed by $change.author: 
    16       #end 
    17 $changes_descr 
     34 * ${change}: 
     35${long_changes[change]} 
     36{% end %}\ 
     37{% end %} 
     38{% if comment %}\ 
     39--------------------------------------------------------------------- 
     40Comment{% if not has_changes %} (by ${author}){% end %}: 
     41 
     42${comment}\ 
     43{% end %}\ 
     44 
    1845-- 
    19     #end 
    20     #if change.comment 
    21  
    22 Comment${not changes_body and '(by %s)' % change.author or ''}: 
    23  
    24 $change.comment 
    25     #end 
    26   #end 
    27 #end 
    28  
    29 --  
    30 Ticket URL: <$ticket.link> 
    31 $project.name <URL:${abs_href()}> 
    32 $project.descr 
     46Ticket URL: <URL:${ticket_link}> 
     47${project_name} <URL:${project_link}> 
     48${project_desc}