99a9d3996205bfb9bf7bcdeed76a79870649e34f
[bzrirker.git] / irkerhook.py
1 # -*- coding: utf-8 -*-
2 # vim:fileencoding=utf-8 ai ts=4 sts=4 et sw=4
3 # Copyright 2012 Neil Muller
4 # GPL 2+ - see COPYING for details
5
6 from bzrlib import (
7     errors,
8     revision as _mod_revision,
9     )
10 from bzrlib.config import (
11     ListOption,
12     Option,
13     bool_from_store,
14     int_from_store,
15     )
16
17
18 class IrkerSender(object):
19     """An irker message sender."""
20
21     def __init__(self, branch, revision_id, config, local_branch=None,
22         op='commit'):
23         self.config = config
24         self.branch = branch
25         self.repository = branch.repository
26         if (local_branch is not None and
27             local_branch.repository.has_revision(revision_id)):
28             self.repository = local_branch.repository
29         self._revision_id = revision_id
30         self.revision = None
31         self.revno = None
32         self.op = op
33
34     def _setup_revision_and_revno(self):
35         self.revision = self.repository.get_revision(self._revision_id)
36         self.revno = self.branch.revision_id_to_revno(self._revision_id)
37
38     def _format(self):
39         fields = {
40             'project': self.project(),
41             'committer': self.revision.committer,
42             'repo': '',
43             'rev': '%d' % self.revno,
44             'files': '',
45             'logmsg': self.revision.get_summary(),
46             'url': self.url(),
47         }
48         for name, value in self.colours():
49             fields[name] = value
50         text = ('%(bold)s%(project)s:%(reset)s '
51                 '%(green)s%(committer)s%(reset)s '
52                 '%(repo)s * %(bold)s%(rev)s%(reset)s / '
53                 ' %(bold)s%(files)s%(reset)s: %(logmsg)s '
54                 '%(brown)s%(url)s%(reset)s' % fields)
55         return text
56
57     def body(self):
58         from bzrlib import log
59
60         rev1 = rev2 = self.revno
61         if rev1 == 0:
62             rev1 = None
63             rev2 = None
64
65         # use 'replace' so that we don't abort if trying to write out
66         # in e.g. the default C locale.
67
68         # Following bzr-email, we use StringIO.StringIO to minimise possible
69         # unicode issues.
70         from StringIO import StringIO
71         outf = StringIO()
72
73         lf = log.log_formatter('line',
74                                show_ids=True,
75                                to_file=outf
76                                )
77
78         if len(self.revision.parent_ids) <= 1:
79             # This is not a merge, so we can special case the display of one
80             # revision, and not have to encur the show_log overhead.
81             lr = log.LogRevision(self.revision, self.revno, 0, None)
82             lf.log_revision(lr)
83         else:
84             # let the show_log code figure out what revisions need to be
85             # displayed, as this is a merge
86             log.show_log(self.branch,
87                          lf,
88                          start_revision=rev1,
89                          end_revision=rev2,
90                          verbose=True
91                          )
92
93         return outf.getvalue()
94
95     def url(self):
96         """What URL to display in the subject of the mail"""
97         url = self.config.get('irker_url')
98         if url is None:
99             url = self.config.get('public_branch')
100         if url is None:
101             url = self.branch.base
102         return url
103
104     def colours(self):
105         colour_style = self.config.get('irker_colors')
106         colours = {
107                 'bold': '',
108                 'green': '',
109                 'blue': '',
110                 'red': '',
111                 'yellow': '',
112                 'brown': '',
113                 'magenta': '',
114                 'cyan': '',
115                 'reset': '',
116                 }
117         # Vaues taken from irker's irkerhook.py
118         if colour_style == 'ANSI':
119             colours = {
120                     'bold': '\x1b[1m'
121                     'green': '\x1b[1;32m'
122                     'blue': '\x1b[1;34m'
123                     'red':  '\x1b[1;31m'
124                     'yellow': '\x1b[1;33m'
125                     'brown': '\x1b[33m'
126                     'magenta': '\x1b[35m'
127                     'cyan': '\x1b[36m'
128                     'reset': '\x1b[0m'
129                     }
130         elif colour_style == 'mIRC':
131             colours = {
132                     'bold': '\x02'
133                     'green': '\x0303'
134                     'blue': '\x0302'
135                     'red': '\x0305'
136                     'yellow': '\x0307'
137                     'brown': '\x0305'
138                     'magenta': '\x0306'
139                     'cyan': '\x0310'
140                     'reset': '\x0F'
141                     }
142         return colours
143
144     def project(self):
145         projet = self.config.get('irker_project')
146         if project is None:
147             project = 'No Project name set'
148         return project
149
150     def send(self):
151         """Send the info to irkerd.
152         """
153         self.branch.lock_read()
154         self.repository.lock_read()
155         try:
156             # Do this after we have locked, to make things faster.
157             self._setup_revision_and_revno()
158         finally:
159             self.repository.unlock()
160             self.branch.unlock()
161
162 opt_irker_url = Option('irker_url',
163     help='URL to mention for branch in messages.')
164 opt_irker_channels = Option('irker_channels',
165     help='Channel(s) to post commit messages to.')
166 opt_irker_colours = Option('irker_colours',
167     help='Colour option for irker.')
168 opt_irker_project = Option('irker_project',
169     help='Project name to use.')