piknik

Unnamed repository; edit this file 'description' to name the repository.
Info | Log | Files | Refs | README | LICENSE

commit 8d942a7b2191c471de29c839d5ae35f98ad51d56
parent f890b6fa2733f0a585590970930a870d217e8cc5
Author: lash <dev@holbrook.no>
Date:   Tue,  8 Nov 2022 16:07:55 +0000

File add attachment in msg

Diffstat:
Mpiknik/basket.py | 6+++---
Mpiknik/msg.py | 62+++++++++++++++++++++++++++++++++++++++++++++++++++-----------
Atests/one.png | 0
Mtests/test_msg.py | 16+++++++++++++++-
Atests/two.bin | 0
5 files changed, 69 insertions(+), 15 deletions(-)

diff --git a/piknik/basket.py b/piknik/basket.py @@ -141,14 +141,14 @@ class Basket: def __get_msg(self, issue_id): + r = self.state.get(issue_id) + o = Issue.from_str(r) try: v = self.__msg.get(issue_id) - return IssueMessage.from_string(v) + return IssueMessage.parse(o, v.decode('utf-8')) except FileNotFoundError: logg.debug('instantiating new message log for {}'.format(issue_id)) - v = self.state.get(issue_id) - o = Issue.from_str(v) return IssueMessage(o) diff --git a/piknik/msg.py b/piknik/msg.py @@ -1,6 +1,8 @@ # standard imports import logging import uuid +import mimetypes +from base64 import b64encode #from email.message import EmailMessage as Message from email.message import Message @@ -11,20 +13,24 @@ from email.policy import Compat32 logg = logging.getLogger(__name__) -class IssueMessage(Message): +class IssueMessage: #(Message): def __init__(self, issue): - super(IssueMessage, self).__init__() - self.add_header('Subject', issue.title) - self.add_header('X-Piknik-Id', issue.id) - self.set_payload(None) - self.set_type('multipart/mixed') - self.set_boundary(str(uuid.uuid4())) + #super(IssueMessage, self).__init__() + self.__m = Message() + self.__m.add_header('Subject', issue.title) + self.__m.add_header('X-Piknik-Id', issue.id) + self.__m.set_payload(None) + self.__m.set_type('multipart/mixed') + self.__m.set_boundary(str(uuid.uuid4())) - @staticmethod - def from_string(self, v): - return message_from_string(v) + + @classmethod + def parse(cls, issue, v): + o = cls(issue) + o.__m = message_from_string(v) + return o def add_text(self, m, v): @@ -35,6 +41,28 @@ class IssueMessage(Message): m.attach(p) + def detect_file(self, v): + return mimetypes.guess_type(v) + + + def add_file(self, m, v): + mime_type = self.detect_file(v) + + p = Message() + p.set_type(mime_type[0]) + if mime_type[1] != None: + p.set_charset(mime-type[1]) + p.add_header('Content-Transfer-Encoding', 'BASE64') + + f = open(v, 'rb') + r = f.read() + f.close() + r = b64encode(r) + + p.set_payload(str(r)) + m.attach(p) + + def add(self, *args, related_id=None): m_id = uuid.uuid4() m = Message() @@ -51,4 +79,16 @@ class IssueMessage(Message): self.add_file(m, v) elif p == 's:': self.add_text(m, v) - self.attach(m) + self.__m.attach(m) + + + def as_string(self, **kwargs): + return self.__m.as_string(**kwargs) + + + def as_bytes(self, **kwargs): + return self.__m.as_bytes(**kwargs) + + + def __str__(self): + return self.as_string() diff --git a/tests/one.png b/tests/one.png Binary files differ. diff --git a/tests/test_msg.py b/tests/test_msg.py @@ -27,7 +27,6 @@ class TestMsg(unittest.TestCase): def test_basic(self): o = Issue('foo') v = IssueMessage(o) - self.assertEqual(v.get('Subject'), 'foo') def test_single_content(self): @@ -40,6 +39,21 @@ class TestMsg(unittest.TestCase): o = Issue('foo') v = self.b.add(o) m = self.b.msg(v, 's:foo', 's:bar', 's:baz') + + + def test_single_file_content(self): + o = Issue('foo') + v = self.b.add(o) + m = self.b.msg(v, 'f:tests/one.png') + + + def test_mixed_content(self): + o = Issue('foo') + v = self.b.add(o) + m = self.b.msg(v, 's:bar') + m = self.b.msg(v, 'f:tests/one.png') + m = self.b.msg(v, 's:baz') + m = self.b.msg(v, 'f:tests/two.bin') print(m) diff --git a/tests/two.bin b/tests/two.bin Binary files differ.