add.py (3305B)
1 # standard imports 2 import sys 3 import os 4 from email.message import EmailMessage 5 from email.mime.multipart import MIMEMultipart 6 import email 7 import logging 8 import uuid 9 import json 10 import gzip 11 import tempfile 12 import base64 13 import uuid 14 import getpass 15 16 # local imports 17 import feedwarrior 18 from feedwarrior import entry as feedentry 19 from feedwarrior.adapters import fileadapter 20 from feedwarrior.entry import extension 21 from feedwarrior.common import task_ids_to_uuids, check_task_uuids 22 from feedwarrior.crypto import PGPSigner 23 24 logg = logging.getLogger() 25 26 27 def get_editor(): 28 return 'vim' 29 30 def parse_args(argparser): 31 argparser.add_argument('-z', action='store_true', help='compress entry with gzip') 32 argparser.add_argument('--task-id', dest='task_id', type=int, action='append', help='add taskwarrior task id relations translated to uuis (cannot be used with --task-uuid') 33 argparser.add_argument('--task-uuid', dest='task_uuid', type=str, action='append', help='add taskwarrior task uuid relations (cannot be used with --task-id') 34 argparser.add_argument('-s', type=str, help='entry subject') 35 argparser.add_argument('-y', '--sign', dest='y', action='store_true', help='sign entry with pgp key') 36 return True 37 38 39 def check_args(args): 40 pass 41 42 43 # TODO: move logic to package to get symmetry with the show.py logic 44 def execute(config, feed, args): 45 signer = None 46 if args.y: 47 signer = PGPSigner() 48 49 task_uuids = [] 50 if args.task_id != None: 51 task_uuids += task_ids_to_uuids(config.task_dir, args.task_id) 52 53 if args.task_uuid != None: 54 task_uuids += check_task_uuids(config.task_dir, args.task_uuid) 55 56 d = tempfile.TemporaryDirectory() 57 t = tempfile.NamedTemporaryFile(mode='w+', dir=d.name) 58 editor_path = get_editor() 59 os.system('{} {}'.format(get_editor(), t.name)) 60 f = open(t.name, 'rb') 61 s = os.stat(t.name) 62 t.close() 63 logg.debug('file {} {}'.format(t.name, s.st_size)) 64 if s.st_size == 0: 65 logg.error('empty input') 66 sys.stderr.write('No input. aborting.\n') 67 sys.exit(1) 68 content = f.read(s.st_size) 69 f.close() 70 71 entry_date = str(email.utils.formatdate()) 72 subject = args.s 73 if subject == None: 74 subject = entry_date 75 m = EmailMessage() 76 m.add_header('Content-Type', 'text/plain') 77 m.add_header('Content-Disposition', 'inline') 78 m.add_header('Content-Transfer-Encoding', 'base64') 79 m.set_param('filename', subject) 80 m.set_param('filename', subject, 'Content-Disposition') 81 bsf = base64.encodebytes(content) 82 m.set_payload(bsf.decode('utf-8')) 83 84 85 mm = MIMEMultipart() 86 mm.attach(m) 87 mm.add_header('Subject', subject) 88 mm.add_header('Date', entry_date) 89 90 entry = feedentry.from_multipart(mm) 91 for t in task_uuids: 92 uu = feedwarrior.common.parse_uuid(t) 93 entry.add_extension(feedwarrior.extension.TASKWARRIOR, uu) 94 95 uu = str(entry.uuid) 96 logg.debug('adding entry {}'.format(uu)) 97 98 if args.y: 99 passphrase = getpass.getpass('passphrase: ') 100 if len(passphrase) == 0: 101 passphrase = None 102 signer.sign(entry, passphrase=passphrase) 103 104 fa = fileadapter(config.data_dir, feed.uuid) 105 fa.put(entry.uuid, entry, compress=args.z) 106 107 feed.add(entry) 108 return str(entry.uuid)