piknik

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

commit 10abb4bf1144082dc8eaa63b07af053b58f8eb46
parent 7f57f34ee98594d188b9ca452da6f8672d57d3c1
Author: lash <dev@holbrook.no>
Date:   Thu, 17 Nov 2022 22:05:20 +0000

Option to dump file contents to custom dir

Diffstat:
MCHANGELOG | 2+-
Mpiknik/runnable/show.py | 33+++++++++++++++++++++++++++++----
2 files changed, 30 insertions(+), 5 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG @@ -4,7 +4,7 @@ * View message log in show command * Show signature status with show command * Add message grouping for messages added in the same comment call - ? Option to dump comment attachment files when viewing with show + * Option to dump comment attachment files when viewing with show - 0.1.3 * Add command for adding MIME Multipart comments - 0.1.2 diff --git a/piknik/runnable/show.py b/piknik/runnable/show.py @@ -3,6 +3,7 @@ import os import sys import argparse import logging +import tempfile from base64 import b64decode from email.utils import parsedate_to_datetime @@ -20,6 +21,8 @@ logg = logging.getLogger() argp = argparse.ArgumentParser() argp.add_argument('-d', type=str, help='Data directory') +argp.add_argument('-f', '--files', dest='f', action='store_true', help='Save attachments to filesystem') +argp.add_argument('-o', '--files-dir', dest='files_dir', type=str, default='.', help='Directory to output saved files to') argp.add_argument('-r', '--renderer', type=str, default='default', help='Renderer module for output') argp.add_argument('issue_id', type=str, help='Issue id to show') arg = argp.parse_args(sys.argv[1:]) @@ -28,6 +31,20 @@ store_factory = FileStoreFactory(arg.d) basket = Basket(store_factory) +def to_suffixed_file(d, s, data): + (v, ext) = os.path.splitext(s) + r = tempfile.mkstemp(suffix=ext, dir=d) + + f = os.fdopen(r[0], 'wb') + try: + f.write(data) + except TypeError: + f.write(data.encode('utf-8')) + f.close() + + return r[1] + + # TODO can implement as email parser api instead? class PGPWrapper(PGPSigner): @@ -40,7 +57,7 @@ class PGPWrapper(PGPSigner): self.valid = False - def render_message(self, envelope, messages, message_id, w=sys.stdout): + def render_message(self, envelope, messages, message_id, w=sys.stdout, dump_dir=None): r = '' for message in messages: m = parse_mime_type(message.get_content_type()) @@ -54,10 +71,16 @@ class PGPWrapper(PGPSigner): else: v = '[rich text]' else: + filename = message.get_filename() + if dump_dir != None: + v = message.get_payload() + if message.get('Content-Transfer-Encoding') == 'BASE64': + v = b64decode(v).decode() + filename = to_suffixed_file(dump_dir, filename, v) sz = message.get('Content-Length') if sz == None: sz = 'unknown' - v = '[file: ' + message.get_filename() + ', size: ' + sz + ']' + v = '[file: ' + filename + ', size: ' + sz + ']' valid = '[++]' if not self.valid: @@ -85,8 +108,10 @@ class PGPWrapper(PGPSigner): if message.get('X-Piknik-Msg-Id') == None: if message.get('Content-Type') == 'application/pgp-signature': - #return - self.render_message(envelope, self.message, self.message_id) + dump_dir = None + if arg.f: + dump_dir = arg.files_dir + self.render_message(envelope, self.message, self.message_id, dump_dir=dump_dir) self.message = [] self.message_id = None else: