##// END OF EJS Templates
templates: rename email_templates to email...
Thomas De Schampheleire -
r8418:d379e2c3 default
parent child Browse files
Show More
@@ -1,235 +1,235 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 # This program is free software: you can redistribute it and/or modify
2 # This program is free software: you can redistribute it and/or modify
3 # it under the terms of the GNU General Public License as published by
3 # it under the terms of the GNU General Public License as published by
4 # the Free Software Foundation, either version 3 of the License, or
4 # the Free Software Foundation, either version 3 of the License, or
5 # (at your option) any later version.
5 # (at your option) any later version.
6 #
6 #
7 # This program is distributed in the hope that it will be useful,
7 # This program is distributed in the hope that it will be useful,
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # GNU General Public License for more details.
10 # GNU General Public License for more details.
11 #
11 #
12 # You should have received a copy of the GNU General Public License
12 # You should have received a copy of the GNU General Public License
13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 """
14 """
15 kallithea.model.notification
15 kallithea.model.notification
16 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
16 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
17
17
18 Model for notifications
18 Model for notifications
19
19
20
20
21 This file was forked by the Kallithea project in July 2014.
21 This file was forked by the Kallithea project in July 2014.
22 Original author and date, and relevant copyright and licensing information is below:
22 Original author and date, and relevant copyright and licensing information is below:
23 :created_on: Nov 20, 2011
23 :created_on: Nov 20, 2011
24 :author: marcink
24 :author: marcink
25 :copyright: (c) 2013 RhodeCode GmbH, and others.
25 :copyright: (c) 2013 RhodeCode GmbH, and others.
26 :license: GPLv3, see LICENSE.md for more details.
26 :license: GPLv3, see LICENSE.md for more details.
27 """
27 """
28
28
29 import datetime
29 import datetime
30 import logging
30 import logging
31
31
32 from tg import app_globals
32 from tg import app_globals
33 from tg import tmpl_context as c
33 from tg import tmpl_context as c
34 from tg.i18n import ugettext as _
34 from tg.i18n import ugettext as _
35
35
36 from kallithea.lib import helpers as h
36 from kallithea.lib import helpers as h
37 from kallithea.model.db import User
37 from kallithea.model.db import User
38
38
39
39
40 log = logging.getLogger(__name__)
40 log = logging.getLogger(__name__)
41
41
42
42
43 class NotificationModel(object):
43 class NotificationModel(object):
44
44
45 TYPE_CHANGESET_COMMENT = 'cs_comment'
45 TYPE_CHANGESET_COMMENT = 'cs_comment'
46 TYPE_MESSAGE = 'message'
46 TYPE_MESSAGE = 'message'
47 TYPE_MENTION = 'mention' # not used
47 TYPE_MENTION = 'mention' # not used
48 TYPE_REGISTRATION = 'registration'
48 TYPE_REGISTRATION = 'registration'
49 TYPE_PULL_REQUEST = 'pull_request'
49 TYPE_PULL_REQUEST = 'pull_request'
50 TYPE_PULL_REQUEST_COMMENT = 'pull_request_comment'
50 TYPE_PULL_REQUEST_COMMENT = 'pull_request_comment'
51
51
52 def create(self, created_by, subject, body, recipients=None,
52 def create(self, created_by, subject, body, recipients=None,
53 type_=TYPE_MESSAGE, with_email=True,
53 type_=TYPE_MESSAGE, with_email=True,
54 email_kwargs=None, repo_name=None):
54 email_kwargs=None, repo_name=None):
55 """
55 """
56
56
57 Creates notification of given type
57 Creates notification of given type
58
58
59 :param created_by: int, str or User instance. User who created this
59 :param created_by: int, str or User instance. User who created this
60 notification
60 notification
61 :param subject:
61 :param subject:
62 :param body:
62 :param body:
63 :param recipients: list of int, str or User objects, when None
63 :param recipients: list of int, str or User objects, when None
64 is given send to all admins
64 is given send to all admins
65 :param type_: type of notification
65 :param type_: type of notification
66 :param with_email: send email with this notification
66 :param with_email: send email with this notification
67 :param email_kwargs: additional dict to pass as args to email template
67 :param email_kwargs: additional dict to pass as args to email template
68 """
68 """
69 from kallithea.lib.celerylib import tasks
69 from kallithea.lib.celerylib import tasks
70 email_kwargs = email_kwargs or {}
70 email_kwargs = email_kwargs or {}
71 if recipients and not getattr(recipients, '__iter__', False):
71 if recipients and not getattr(recipients, '__iter__', False):
72 raise Exception('recipients must be a list or iterable')
72 raise Exception('recipients must be a list or iterable')
73
73
74 created_by_obj = User.guess_instance(created_by)
74 created_by_obj = User.guess_instance(created_by)
75
75
76 recipients_objs = set()
76 recipients_objs = set()
77 if recipients:
77 if recipients:
78 for u in recipients:
78 for u in recipients:
79 obj = User.guess_instance(u)
79 obj = User.guess_instance(u)
80 if obj is not None:
80 if obj is not None:
81 recipients_objs.add(obj)
81 recipients_objs.add(obj)
82 else:
82 else:
83 # TODO: inform user that requested operation couldn't be completed
83 # TODO: inform user that requested operation couldn't be completed
84 log.error('cannot email unknown user %r', u)
84 log.error('cannot email unknown user %r', u)
85 log.debug('sending notifications %s to %s',
85 log.debug('sending notifications %s to %s',
86 type_, recipients_objs
86 type_, recipients_objs
87 )
87 )
88 elif recipients is None:
88 elif recipients is None:
89 # empty recipients means to all admins
89 # empty recipients means to all admins
90 recipients_objs = User.query().filter(User.admin == True).all()
90 recipients_objs = User.query().filter(User.admin == True).all()
91 log.debug('sending notifications %s to admins: %s',
91 log.debug('sending notifications %s to admins: %s',
92 type_, recipients_objs
92 type_, recipients_objs
93 )
93 )
94 #else: silently skip notification mails?
94 #else: silently skip notification mails?
95
95
96 if not with_email:
96 if not with_email:
97 return
97 return
98
98
99 headers = {}
99 headers = {}
100 headers['X-Kallithea-Notification-Type'] = type_
100 headers['X-Kallithea-Notification-Type'] = type_
101 if 'threading' in email_kwargs:
101 if 'threading' in email_kwargs:
102 headers['References'] = ' '.join('<%s>' % x for x in email_kwargs['threading'])
102 headers['References'] = ' '.join('<%s>' % x for x in email_kwargs['threading'])
103
103
104 # this is passed into template
104 # this is passed into template
105 created_on = h.fmt_date(datetime.datetime.now())
105 created_on = h.fmt_date(datetime.datetime.now())
106 html_kwargs = {
106 html_kwargs = {
107 'subject': subject,
107 'subject': subject,
108 'body': h.render_w_mentions(body, repo_name),
108 'body': h.render_w_mentions(body, repo_name),
109 'when': created_on,
109 'when': created_on,
110 'user': created_by_obj.username,
110 'user': created_by_obj.username,
111 }
111 }
112
112
113 txt_kwargs = {
113 txt_kwargs = {
114 'subject': subject,
114 'subject': subject,
115 'body': body,
115 'body': body,
116 'when': created_on,
116 'when': created_on,
117 'user': created_by_obj.username,
117 'user': created_by_obj.username,
118 }
118 }
119
119
120 html_kwargs.update(email_kwargs)
120 html_kwargs.update(email_kwargs)
121 txt_kwargs.update(email_kwargs)
121 txt_kwargs.update(email_kwargs)
122 email_subject = EmailNotificationModel() \
122 email_subject = EmailNotificationModel() \
123 .get_email_description(type_, **txt_kwargs)
123 .get_email_description(type_, **txt_kwargs)
124 email_txt_body = EmailNotificationModel() \
124 email_txt_body = EmailNotificationModel() \
125 .get_email_tmpl(type_, 'txt', **txt_kwargs)
125 .get_email_tmpl(type_, 'txt', **txt_kwargs)
126 email_html_body = EmailNotificationModel() \
126 email_html_body = EmailNotificationModel() \
127 .get_email_tmpl(type_, 'html', **html_kwargs)
127 .get_email_tmpl(type_, 'html', **html_kwargs)
128
128
129 # don't send email to the person who caused the notification, except for
129 # don't send email to the person who caused the notification, except for
130 # notifications about new pull requests where the author is explicitly
130 # notifications about new pull requests where the author is explicitly
131 # added.
131 # added.
132 rec_mails = set(obj.email for obj in recipients_objs)
132 rec_mails = set(obj.email for obj in recipients_objs)
133 if type_ == NotificationModel.TYPE_PULL_REQUEST:
133 if type_ == NotificationModel.TYPE_PULL_REQUEST:
134 rec_mails.add(created_by_obj.email)
134 rec_mails.add(created_by_obj.email)
135 else:
135 else:
136 rec_mails.discard(created_by_obj.email)
136 rec_mails.discard(created_by_obj.email)
137
137
138 # send email with notification to participants
138 # send email with notification to participants
139 for rec_mail in sorted(rec_mails):
139 for rec_mail in sorted(rec_mails):
140 tasks.send_email([rec_mail], email_subject, email_txt_body,
140 tasks.send_email([rec_mail], email_subject, email_txt_body,
141 email_html_body, headers,
141 email_html_body, headers,
142 from_name=created_by_obj.full_name_or_username)
142 from_name=created_by_obj.full_name_or_username)
143
143
144
144
145 class EmailNotificationModel(object):
145 class EmailNotificationModel(object):
146
146
147 TYPE_CHANGESET_COMMENT = NotificationModel.TYPE_CHANGESET_COMMENT
147 TYPE_CHANGESET_COMMENT = NotificationModel.TYPE_CHANGESET_COMMENT
148 TYPE_MESSAGE = NotificationModel.TYPE_MESSAGE # only used for testing
148 TYPE_MESSAGE = NotificationModel.TYPE_MESSAGE # only used for testing
149 # NotificationModel.TYPE_MENTION is not used
149 # NotificationModel.TYPE_MENTION is not used
150 TYPE_PASSWORD_RESET = 'password_link'
150 TYPE_PASSWORD_RESET = 'password_link'
151 TYPE_REGISTRATION = NotificationModel.TYPE_REGISTRATION
151 TYPE_REGISTRATION = NotificationModel.TYPE_REGISTRATION
152 TYPE_PULL_REQUEST = NotificationModel.TYPE_PULL_REQUEST
152 TYPE_PULL_REQUEST = NotificationModel.TYPE_PULL_REQUEST
153 TYPE_PULL_REQUEST_COMMENT = NotificationModel.TYPE_PULL_REQUEST_COMMENT
153 TYPE_PULL_REQUEST_COMMENT = NotificationModel.TYPE_PULL_REQUEST_COMMENT
154 TYPE_DEFAULT = 'default'
154 TYPE_DEFAULT = 'default'
155
155
156 def __init__(self):
156 def __init__(self):
157 super(EmailNotificationModel, self).__init__()
157 super(EmailNotificationModel, self).__init__()
158 self._tmpl_lookup = app_globals.mako_lookup
158 self._tmpl_lookup = app_globals.mako_lookup
159 self.email_types = {
159 self.email_types = {
160 self.TYPE_CHANGESET_COMMENT: 'changeset_comment',
160 self.TYPE_CHANGESET_COMMENT: 'changeset_comment',
161 self.TYPE_PASSWORD_RESET: 'password_reset',
161 self.TYPE_PASSWORD_RESET: 'password_reset',
162 self.TYPE_REGISTRATION: 'registration',
162 self.TYPE_REGISTRATION: 'registration',
163 self.TYPE_DEFAULT: 'default',
163 self.TYPE_DEFAULT: 'default',
164 self.TYPE_PULL_REQUEST: 'pull_request',
164 self.TYPE_PULL_REQUEST: 'pull_request',
165 self.TYPE_PULL_REQUEST_COMMENT: 'pull_request_comment',
165 self.TYPE_PULL_REQUEST_COMMENT: 'pull_request_comment',
166 }
166 }
167 self._subj_map = {
167 self._subj_map = {
168 self.TYPE_CHANGESET_COMMENT: _('[Comment] %(repo_name)s changeset %(short_id)s "%(message_short)s" on %(branch)s by %(cs_author_username)s'),
168 self.TYPE_CHANGESET_COMMENT: _('[Comment] %(repo_name)s changeset %(short_id)s "%(message_short)s" on %(branch)s by %(cs_author_username)s'),
169 self.TYPE_MESSAGE: 'Test Message',
169 self.TYPE_MESSAGE: 'Test Message',
170 # self.TYPE_PASSWORD_RESET
170 # self.TYPE_PASSWORD_RESET
171 self.TYPE_REGISTRATION: _('New user %(new_username)s registered'),
171 self.TYPE_REGISTRATION: _('New user %(new_username)s registered'),
172 # self.TYPE_DEFAULT
172 # self.TYPE_DEFAULT
173 self.TYPE_PULL_REQUEST: _('[Review] %(repo_name)s PR %(pr_nice_id)s "%(pr_title_short)s" from %(pr_source_branch)s by %(pr_owner_username)s'),
173 self.TYPE_PULL_REQUEST: _('[Review] %(repo_name)s PR %(pr_nice_id)s "%(pr_title_short)s" from %(pr_source_branch)s by %(pr_owner_username)s'),
174 self.TYPE_PULL_REQUEST_COMMENT: _('[Comment] %(repo_name)s PR %(pr_nice_id)s "%(pr_title_short)s" from %(pr_source_branch)s by %(pr_owner_username)s'),
174 self.TYPE_PULL_REQUEST_COMMENT: _('[Comment] %(repo_name)s PR %(pr_nice_id)s "%(pr_title_short)s" from %(pr_source_branch)s by %(pr_owner_username)s'),
175 }
175 }
176
176
177 def get_email_description(self, type_, **kwargs):
177 def get_email_description(self, type_, **kwargs):
178 """
178 """
179 return subject for email based on given type
179 return subject for email based on given type
180 """
180 """
181 tmpl = self._subj_map[type_]
181 tmpl = self._subj_map[type_]
182 try:
182 try:
183 subj = tmpl % kwargs
183 subj = tmpl % kwargs
184 except KeyError as e:
184 except KeyError as e:
185 log.error('error generating email subject for %r from %s: %s', type_, ', '.join(self._subj_map), e)
185 log.error('error generating email subject for %r from %s: %s', type_, ', '.join(self._subj_map), e)
186 raise
186 raise
187 # gmail doesn't do proper threading but will ignore leading square
187 # gmail doesn't do proper threading but will ignore leading square
188 # bracket content ... so that is where we put status info
188 # bracket content ... so that is where we put status info
189 bracket_tags = []
189 bracket_tags = []
190 status_change = kwargs.get('status_change')
190 status_change = kwargs.get('status_change')
191 if status_change:
191 if status_change:
192 bracket_tags.append(str(status_change)) # apply str to evaluate LazyString before .join
192 bracket_tags.append(str(status_change)) # apply str to evaluate LazyString before .join
193 if kwargs.get('closing_pr'):
193 if kwargs.get('closing_pr'):
194 bracket_tags.append(_('Closing'))
194 bracket_tags.append(_('Closing'))
195 if bracket_tags:
195 if bracket_tags:
196 if subj.startswith('['):
196 if subj.startswith('['):
197 subj = '[' + ', '.join(bracket_tags) + ': ' + subj[1:]
197 subj = '[' + ', '.join(bracket_tags) + ': ' + subj[1:]
198 else:
198 else:
199 subj = '[' + ', '.join(bracket_tags) + '] ' + subj
199 subj = '[' + ', '.join(bracket_tags) + '] ' + subj
200 return subj
200 return subj
201
201
202 def get_email_tmpl(self, type_, content_type, **kwargs):
202 def get_email_tmpl(self, type_, content_type, **kwargs):
203 """
203 """
204 return generated template for email based on given type
204 return generated template for email based on given type
205 """
205 """
206
206
207 base = 'email_templates/' + self.email_types.get(type_, self.email_types[self.TYPE_DEFAULT]) + '.' + content_type
207 base = 'email/' + self.email_types.get(type_, self.email_types[self.TYPE_DEFAULT]) + '.' + content_type
208 email_template = self._tmpl_lookup.get_template(base)
208 email_template = self._tmpl_lookup.get_template(base)
209 # translator and helpers inject
209 # translator and helpers inject
210 _kwargs = {'_': _,
210 _kwargs = {'_': _,
211 'h': h,
211 'h': h,
212 'c': c}
212 'c': c}
213 _kwargs.update(kwargs)
213 _kwargs.update(kwargs)
214 if content_type == 'html':
214 if content_type == 'html':
215 _kwargs.update({
215 _kwargs.update({
216 "color_text": "#202020",
216 "color_text": "#202020",
217 "color_emph": "#395fa0",
217 "color_emph": "#395fa0",
218 "color_link": "#395fa0",
218 "color_link": "#395fa0",
219 "color_border": "#ddd",
219 "color_border": "#ddd",
220 "color_background_grey": "#f9f9f9",
220 "color_background_grey": "#f9f9f9",
221 "color_button": "#395fa0",
221 "color_button": "#395fa0",
222 "monospace_style": "font-family:Lucida Console,Consolas,Monaco,Inconsolata,Liberation Mono,monospace",
222 "monospace_style": "font-family:Lucida Console,Consolas,Monaco,Inconsolata,Liberation Mono,monospace",
223 "sans_style": "font-family:Helvetica,Arial,sans-serif",
223 "sans_style": "font-family:Helvetica,Arial,sans-serif",
224 })
224 })
225 _kwargs.update({
225 _kwargs.update({
226 "default_style": "%(sans_style)s;font-weight:200;font-size:14px;line-height:17px;color:%(color_text)s" % _kwargs,
226 "default_style": "%(sans_style)s;font-weight:200;font-size:14px;line-height:17px;color:%(color_text)s" % _kwargs,
227 "comment_style": "%(monospace_style)s;white-space:pre-wrap" % _kwargs,
227 "comment_style": "%(monospace_style)s;white-space:pre-wrap" % _kwargs,
228 "data_style": "border:%(color_border)s 1px solid;background:%(color_background_grey)s" % _kwargs,
228 "data_style": "border:%(color_border)s 1px solid;background:%(color_background_grey)s" % _kwargs,
229 "emph_style": "font-weight:600;color:%(color_emph)s" % _kwargs,
229 "emph_style": "font-weight:600;color:%(color_emph)s" % _kwargs,
230 "link_style": "color:%(color_link)s;text-decoration:none" % _kwargs,
230 "link_style": "color:%(color_link)s;text-decoration:none" % _kwargs,
231 "link_text_style": "color:%(color_text)s;text-decoration:none;border:%(color_border)s 1px solid;background:%(color_background_grey)s" % _kwargs,
231 "link_text_style": "color:%(color_text)s;text-decoration:none;border:%(color_border)s 1px solid;background:%(color_background_grey)s" % _kwargs,
232 })
232 })
233
233
234 log.debug('rendering tmpl %s with kwargs %s', base, _kwargs)
234 log.debug('rendering tmpl %s with kwargs %s', base, _kwargs)
235 return email_template.render_unicode(**_kwargs)
235 return email_template.render_unicode(**_kwargs)
1 NO CONTENT: file renamed from kallithea/templates/email_templates/button.html to kallithea/templates/email/button.html
NO CONTENT: file renamed from kallithea/templates/email_templates/button.html to kallithea/templates/email/button.html
1 NO CONTENT: file renamed from kallithea/templates/email_templates/button.txt to kallithea/templates/email/button.txt
NO CONTENT: file renamed from kallithea/templates/email_templates/button.txt to kallithea/templates/email/button.txt
1 NO CONTENT: file renamed from kallithea/templates/email_templates/changeset_comment.html to kallithea/templates/email/changeset_comment.html
NO CONTENT: file renamed from kallithea/templates/email_templates/changeset_comment.html to kallithea/templates/email/changeset_comment.html
1 NO CONTENT: file renamed from kallithea/templates/email_templates/changeset_comment.txt to kallithea/templates/email/changeset_comment.txt
NO CONTENT: file renamed from kallithea/templates/email_templates/changeset_comment.txt to kallithea/templates/email/changeset_comment.txt
1 NO CONTENT: file renamed from kallithea/templates/email_templates/comment.html to kallithea/templates/email/comment.html
NO CONTENT: file renamed from kallithea/templates/email_templates/comment.html to kallithea/templates/email/comment.html
1 NO CONTENT: file renamed from kallithea/templates/email_templates/comment.txt to kallithea/templates/email/comment.txt
NO CONTENT: file renamed from kallithea/templates/email_templates/comment.txt to kallithea/templates/email/comment.txt
1 NO CONTENT: file renamed from kallithea/templates/email_templates/default.html to kallithea/templates/email/default.html
NO CONTENT: file renamed from kallithea/templates/email_templates/default.html to kallithea/templates/email/default.html
1 NO CONTENT: file renamed from kallithea/templates/email_templates/default.txt to kallithea/templates/email/default.txt
NO CONTENT: file renamed from kallithea/templates/email_templates/default.txt to kallithea/templates/email/default.txt
1 NO CONTENT: file renamed from kallithea/templates/email_templates/header.html to kallithea/templates/email/header.html
NO CONTENT: file renamed from kallithea/templates/email_templates/header.html to kallithea/templates/email/header.html
1 NO CONTENT: file renamed from kallithea/templates/email_templates/header.txt to kallithea/templates/email/header.txt
NO CONTENT: file renamed from kallithea/templates/email_templates/header.txt to kallithea/templates/email/header.txt
1 NO CONTENT: file renamed from kallithea/templates/email_templates/main.html to kallithea/templates/email/main.html
NO CONTENT: file renamed from kallithea/templates/email_templates/main.html to kallithea/templates/email/main.html
1 NO CONTENT: file renamed from kallithea/templates/email_templates/password_reset.html to kallithea/templates/email/password_reset.html
NO CONTENT: file renamed from kallithea/templates/email_templates/password_reset.html to kallithea/templates/email/password_reset.html
1 NO CONTENT: file renamed from kallithea/templates/email_templates/password_reset.txt to kallithea/templates/email/password_reset.txt
NO CONTENT: file renamed from kallithea/templates/email_templates/password_reset.txt to kallithea/templates/email/password_reset.txt
1 NO CONTENT: file renamed from kallithea/templates/email_templates/pull_request.html to kallithea/templates/email/pull_request.html
NO CONTENT: file renamed from kallithea/templates/email_templates/pull_request.html to kallithea/templates/email/pull_request.html
1 NO CONTENT: file renamed from kallithea/templates/email_templates/pull_request.txt to kallithea/templates/email/pull_request.txt
NO CONTENT: file renamed from kallithea/templates/email_templates/pull_request.txt to kallithea/templates/email/pull_request.txt
1 NO CONTENT: file renamed from kallithea/templates/email_templates/pull_request_comment.html to kallithea/templates/email/pull_request_comment.html
NO CONTENT: file renamed from kallithea/templates/email_templates/pull_request_comment.html to kallithea/templates/email/pull_request_comment.html
1 NO CONTENT: file renamed from kallithea/templates/email_templates/pull_request_comment.txt to kallithea/templates/email/pull_request_comment.txt
NO CONTENT: file renamed from kallithea/templates/email_templates/pull_request_comment.txt to kallithea/templates/email/pull_request_comment.txt
1 NO CONTENT: file renamed from kallithea/templates/email_templates/registration.html to kallithea/templates/email/registration.html
NO CONTENT: file renamed from kallithea/templates/email_templates/registration.html to kallithea/templates/email/registration.html
1 NO CONTENT: file renamed from kallithea/templates/email_templates/registration.txt to kallithea/templates/email/registration.txt
NO CONTENT: file renamed from kallithea/templates/email_templates/registration.txt to kallithea/templates/email/registration.txt
@@ -1,24 +1,24 b''
1 #!/bin/bash -xe
1 #!/bin/bash -xe
2
2
3 # Enforce some consistency in whitespace - just to avoid spurious whitespaces changes
3 # Enforce some consistency in whitespace - just to avoid spurious whitespaces changes
4
4
5 files=`hg mani | egrep -v '/fontello/|/email_templates/|(^LICENSE-MERGELY.html|^docs/Makefile|^scripts/whitespacecleanup.sh|/(graph|mergely|native.history)\.js|/test_dump_html_mails.ref.html|\.png|\.gif|\.ico|\.pot|\.po|\.mo|\.tar\.gz|\.diff)$'`
5 files=`hg mani | egrep -v '/fontello/|/templates/email/|(^LICENSE-MERGELY.html|^docs/Makefile|^scripts/whitespacecleanup.sh|/(graph|mergely|native.history)\.js|/test_dump_html_mails.ref.html|\.png|\.gif|\.ico|\.pot|\.po|\.mo|\.tar\.gz|\.diff)$'`
6
6
7 sed -i "s/`printf '\r'`//g" $files
7 sed -i "s/`printf '\r'`//g" $files
8 sed -i -e "s,`printf '\t'`, ,g" $files
8 sed -i -e "s,`printf '\t'`, ,g" $files
9 sed -i -e "s, *$,,g" $files
9 sed -i -e "s, *$,,g" $files
10 sed -i -e 's,\([^ ]\)\\$,\1 \\,g' -e 's,\(["'"'"']["'"'"']["'"'"']\) \\$,\1\\,g' $files
10 sed -i -e 's,\([^ ]\)\\$,\1 \\,g' -e 's,\(["'"'"']["'"'"']["'"'"']\) \\$,\1\\,g' $files
11 # ensure one trailing newline - remove empty last line and make last line include trailing newline:
11 # ensure one trailing newline - remove empty last line and make last line include trailing newline:
12 sed -i -e '$,${/^$/d}' -e '$a\' $files
12 sed -i -e '$,${/^$/d}' -e '$a\' $files
13
13
14 sed -i -e 's,\([^ /]\){,\1 {,g' `hg loc '*.css'`
14 sed -i -e 's,\([^ /]\){,\1 {,g' `hg loc '*.css'`
15 sed -i -e 's|^\([^ /].*,\)\([^ ]\)|\1 \2|g' `hg loc '*.css'`
15 sed -i -e 's|^\([^ /].*,\)\([^ ]\)|\1 \2|g' `hg loc '*.css'`
16
16
17 hg mani | xargs chmod -x
17 hg mani | xargs chmod -x
18 hg loc 'set:!binary()&grep("^#!")&!(**_tmpl.py)&!(**/template**)' | xargs chmod +x
18 hg loc 'set:!binary()&grep("^#!")&!(**_tmpl.py)&!(**/template**)' | xargs chmod +x
19
19
20 # isort is installed from dev_requirements.txt
20 # isort is installed from dev_requirements.txt
21 hg loc 'set:!binary()&grep("^#!.*python")' '*.py' | xargs isort --line-width 160 --lines-after-imports 2
21 hg loc 'set:!binary()&grep("^#!.*python")' '*.py' | xargs isort --line-width 160 --lines-after-imports 2
22
22
23 echo "diff after $0:"
23 echo "diff after $0:"
24 hg diff
24 hg diff
General Comments 0
You need to be logged in to leave comments. Login now