commit 52a296abfb5ae51894631b07f7f9f75639175f27
parent 1e3dc968ff9e1ced72ff5c413469a0fb2f6c79da
Author: lash <dev@holbrook.no>
Date: Wed, 9 Nov 2022 12:08:56 +0000
Add message wrapper hook
Diffstat:
7 files changed, 58 insertions(+), 4 deletions(-)
diff --git a/ROADMAP b/ROADMAP
@@ -0,0 +1,13 @@
+- 0.4.0
+ * HTTP server for making state edits for issues locally (e.g. drag).
+- 0.3.0
+ * Automatially embed VCS target and source hash to issue and issue messages.
+ - target: current hash target to merge into (var)
+ - source: current hash source to merge (var)
+ * Target alias for issue, e.g. version, revision, may be:
+ - inherit from other issue
+ - target hash above
+ - git tag
+ - arbitrary string identifier
+- 0.2.0
+ * GPG signing of issue messages.
diff --git a/ROADMAP.gui b/ROADMAP.gui
@@ -0,0 +1,5 @@
+GUI is simple browser javascript.
+
+Initial implementation should use file:/// scheme and be read-only.
+
+GUI needs to be separate repo.
diff --git a/piknik/basket.py b/piknik/basket.py
@@ -14,7 +14,7 @@ logg = logging.getLogger(__name__)
class Basket:
- def __init__(self, state_factory):
+ def __init__(self, state_factory, message_wrapper=None):
self.no_resurrect = True
self.state = state_factory.create_states(default_state='proposed', verifier=self.__check_resurrect)
self.state.add('backlog')
@@ -32,6 +32,7 @@ class Basket:
self.__tags.sync(ignore_auto=False)
self.__msg = state_factory.create_messages()
+ self.__msg_wrap = message_wrapper
self.issues_rev = {}
@@ -142,6 +143,7 @@ class Basket:
def __get_msg(self, issue_id):
r = self.state.get(issue_id)
+ print('issue {}'.format(r))
o = Issue.from_str(r)
try:
v = self.__msg.get(issue_id)
@@ -154,7 +156,7 @@ class Basket:
def msg(self, issue_id, *args):
m = self.__get_msg(issue_id)
- m.add(*args)
+ m.add(*args, wrapper=self.__msg_wrap)
ms = m.as_bytes()
self.__msg.put(issue_id, ms)
return m
diff --git a/piknik/crypto.py b/piknik/crypto.py
@@ -0,0 +1,13 @@
+# external imports
+import gnupg
+
+
+class Signer:
+
+ def __init__(self, home_dir=None, default_key=None):
+ self.gpg = gnupg.GPG(gnupghome=home_dir)
+ self.default_key = default_key
+
+
+ def sign(self, issue_msg):
+ pass
diff --git a/piknik/msg.py b/piknik/msg.py
@@ -3,11 +3,13 @@ import logging
import uuid
import mimetypes
from base64 import b64encode
+import time
#from email.message import EmailMessage as Message
from email.message import Message
from email import message_from_string
from email.policy import Compat32
+from email.utils import formatdate
logg = logging.getLogger(__name__)
@@ -20,6 +22,7 @@ class IssueMessage:
self.__m.add_header('Subject', issue.title)
self.__m.add_header('X-Piknik-Id', issue.id)
+ self.__m.add_header('Date', formatdate(time.time()))
self.__m.set_payload(None)
self.__m.set_type('multipart/mixed')
self.__m.set_boundary(str(uuid.uuid4()))
@@ -62,10 +65,11 @@ class IssueMessage:
m.attach(p)
- def add(self, *args, related_id=None):
+ def add(self, *args, related_id=None, wrapper=None):
m_id = uuid.uuid4()
m = Message()
m.add_header('X-Piknik-Msg-Id', str(m_id))
+ m.add_header('Date', formatdate(time.time()))
if related_id != None:
m.add_header('In-Reply-To', related_id)
m.set_payload(None)
@@ -78,6 +82,8 @@ class IssueMessage:
self.add_file(m, v)
elif p == 's:':
self.add_text(m, v)
+ if wrapper:
+ m = wrapper(m)
self.__m.attach(m)
diff --git a/requirements.txt b/requirements.txt
@@ -1,2 +1,3 @@
shep~=0.2.11
leveldir~=0.3.1
+python-gnupg~=0.5.0
diff --git a/tests/test_msg.py b/tests/test_msg.py
@@ -2,6 +2,7 @@
import unittest
import logging
import json
+from email.message import Message
# local imports
from piknik import (
@@ -18,6 +19,13 @@ logging.basicConfig(level=logging.DEBUG)
logg = logging.getLogger()
+def test_wrapper(p):
+ m = Message()
+ m.add_header('Foo', 'bar')
+ m.set_type('multipart/relative')
+ m.set_payload(p)
+ return m
+
class TestMsg(unittest.TestCase):
@@ -56,9 +64,15 @@ class TestMsg(unittest.TestCase):
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)
+ def test_wrapper(self):
+ b = Basket(self.store, message_wrapper=test_wrapper)
+ o = Issue('bar')
+ v = b.add(o)
+ m = b.msg(v, 's:foo')
+ print(m)
+
if __name__ == '__main__':
unittest.main()