##// END OF EJS Templates
Migrate to Mergely 3.3.4....
Migrate to Mergely 3.3.4. RhodeCode 2.2.5 distributed Mergely 3.3.4 with some of the changes that Mergely 3.3.3 in RhodeCode 1.7.2 also had. That do however not seem to be changes we want for Kallithea this way and we take the 3.3.4 files as they are. I've also included the Mergely license file, as downloaded from: http://www.mergely.com/license.php That LICENSE file is kept in HTML just as it was downloaded from their website. While it's a bit annoying to keep the license file in HTML, this is the way it came from upstream so we'll leave it that way. Since the Javascript code is used with other GPLv3 Javascript, we are using the GPL option of Mergely's tri-license. Finally, note that previously, this was incorrectly called "mergerly", so the opportunity is taken here to correct the name. That required changes to diff_2way.html. As commands:: $ wget -N --output-document LICENSE-MERGELY.html http://www.mergely.com/license.php $ hg add LICENSE-MERGELY.html $ hg mv rhodecode/public/css/mergerly.css rhodecode/public/css/mergely.css $ hg mv rhodecode/public/js/mergerly.js rhodecode/public/js/mergely.js $ sed -i 's,mergerly\.,mergely,g' rhodecode/templates/files/diff_2way.html $ ( cd /tmp; \ wget -N http://www.mergely.com/releases/mergely-3.3.4.zip; \ unzip mergely-3.3.4.zip ) $ sha256sum /tmp/mergely-3.3.4.zip 87415d30494bbe829c248881aa7cdc0303f7e70b458a5f687615564d4498cc82 mergely-3.3.4.zip $ cp /tmp/mergely-3.3.4/lib/mergely.js rhodecode/public/js/mergely.js $ cp /tmp/mergely-3.3.4/lib/mergely.css rhodecode/public/css/mergely.css $ sed -i -e '/^ \* Version/a\ *\n * NOTE by bkuhn@sfconservancy.org for Kallithea:\n * Mergely license appears at http://www.mergely.com/license.php and in LICENSE-MERGELY.html' rhodecode/public/js/mergely.js rhodecode/public/css/mergely.css

File last commit:

r2452:d95ef658 beta
r4125:aa3b5594 rhodecode-2.2.5-gpl
Show More
message.py
183 lines | 4.9 KiB | text/x-python | PythonLexer
from rhodecode.lib.rcmail.response import MailResponse
from rhodecode.lib.rcmail.exceptions import BadHeaders
from rhodecode.lib.rcmail.exceptions import InvalidMessage
class Attachment(object):
"""
Encapsulates file attachment information.
:param filename: filename of attachment
:param content_type: file mimetype
:param data: the raw file data, either as string or file obj
:param disposition: content-disposition (if any)
"""
def __init__(self,
filename=None,
content_type=None,
data=None,
disposition=None):
self.filename = filename
self.content_type = content_type
self.disposition = disposition or 'attachment'
self._data = data
@property
def data(self):
if isinstance(self._data, basestring):
return self._data
self._data = self._data.read()
return self._data
class Message(object):
"""
Encapsulates an email message.
:param subject: email subject header
:param recipients: list of email addresses
:param body: plain text message
:param html: HTML message
:param sender: email sender address
:param cc: CC list
:param bcc: BCC list
:param extra_headers: dict of extra email headers
:param attachments: list of Attachment instances
:param recipients_separator: alternative separator for any of
'From', 'To', 'Delivered-To', 'Cc', 'Bcc' fields
"""
def __init__(self,
subject=None,
recipients=None,
body=None,
html=None,
sender=None,
cc=None,
bcc=None,
extra_headers=None,
attachments=None,
recipients_separator="; "):
self.subject = subject or ''
self.sender = sender
self.body = body
self.html = html
self.recipients = recipients or []
self.attachments = attachments or []
self.cc = cc or []
self.bcc = bcc or []
self.extra_headers = extra_headers or {}
self.recipients_separator = recipients_separator
@property
def send_to(self):
return set(self.recipients) | set(self.bcc or ()) | set(self.cc or ())
def to_message(self):
"""
Returns raw email.Message instance.Validates message first.
"""
self.validate()
return self.get_response().to_message()
def get_response(self):
"""
Creates a Lamson MailResponse instance
"""
response = MailResponse(Subject=self.subject,
To=self.recipients,
From=self.sender,
Body=self.body,
Html=self.html,
separator=self.recipients_separator)
if self.cc:
response.base['Cc'] = self.cc
for attachment in self.attachments:
response.attach(attachment.filename,
attachment.content_type,
attachment.data,
attachment.disposition)
response.update(self.extra_headers)
return response
def is_bad_headers(self):
"""
Checks for bad headers i.e. newlines in subject, sender or recipients.
"""
headers = [self.subject, self.sender]
headers += list(self.send_to)
headers += self.extra_headers.values()
for val in headers:
for c in '\r\n':
if c in val:
return True
return False
def validate(self):
"""
Checks if message is valid and raises appropriate exception.
"""
if not self.recipients:
raise InvalidMessage("No recipients have been added")
if not self.body and not self.html:
raise InvalidMessage("No body has been set")
if not self.sender:
raise InvalidMessage("No sender address has been set")
if self.is_bad_headers():
raise BadHeaders
def add_recipient(self, recipient):
"""
Adds another recipient to the message.
:param recipient: email address of recipient.
"""
self.recipients.append(recipient)
def add_cc(self, recipient):
"""
Adds an email address to the CC list.
:param recipient: email address of recipient.
"""
self.cc.append(recipient)
def add_bcc(self, recipient):
"""
Adds an email address to the BCC list.
:param recipient: email address of recipient.
"""
self.bcc.append(recipient)
def attach(self, attachment):
"""
Adds an attachment to the message.
:param attachment: an **Attachment** instance.
"""
self.attachments.append(attachment)