feedwarrior

Slim, portable tooling for creating and distributing decentralized append logs
git clone git://git.defalsify.org/logwarrior.git
Log | Files | Refs | README | LICENSE

commit 3b4f8956edaad90f152ceaa33c89d882d85a7e95
parent 7c5ac645dfab2ff2ef5ee3f30e532f48caac5fe7
Author: nolash <dev@holbrook.no>
Date:   Sun, 28 Jun 2020 15:34:52 +0200

Add log create routine

Diffstat:
Aconfig.ini | 2++
Mdraft.txt | 5++---
Afeedwarrior.py | 114+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 118 insertions(+), 3 deletions(-)

diff --git a/config.ini b/config.ini @@ -0,0 +1,2 @@ +[FEEDWARRIOR] +datadir = /tmp/feedwarrior diff --git a/draft.txt b/draft.txt @@ -13,8 +13,7 @@ format of log format of log entry { "id": <uuid>, - "caption": <base64>, - "contents": [<multipart/mixed>], + "body": <multipart/mixed>, } # if set, server should generate random challenge to be signed by key @@ -41,10 +40,10 @@ each folder must have an ini-formatted file .log with a [LOG] section defining - child uuid (optional) each log entry is in folder entries named by uuid +(date, subject and all content is retrieved from multipart) each folder much have an ini-formatted file .entry with: - an [ENTRY] section with: log=<uuid> - a [TASKWARRIOR] section with: uuid=<'*'|task-url> - each folder must have a file _content which will be the main text body and the first entry of the multipart each folder MAY have additional files which will be folded down into the multipart (for now a perl script will be used to generate the multiparts) diff --git a/feedwarrior.py b/feedwarrior.py @@ -0,0 +1,114 @@ +#!/usr/bin/python + +# Author: Louis Holbrook <dev@holbrook.no> (https://holbrook.no) +# License: GPLv3 +# Description: Work log tool + +# standard imports +import copy +import os +import sys +import argparse +import configparser +import json +import logging +import uuid +import time + +logging.basicConfig(level=logging.ERROR) +logg = logging.getLogger() + +DATA_DIR='/dev/null' + + +argparser = argparse.ArgumentParser(description='create and manipulate feedwarrior logs') +argparser.add_argument('-p', type=str, help='parent log uuid') +argparser.add_argument('-c', required=True, type=str, help='configuration file') +argparser.add_argument('-v', action='store_true', help='be verbose') +sub = argparser.add_subparsers() +sub.dest = 'command' + +args = argparser.parse_args(sys.argv[1:]) +if args.v: + logging.getLogger().setLevel(logging.DEBUG) + +logg.debug('loading config {}'.format(args.c)) +cp = configparser.ConfigParser() +cp.read(args.c) +DATA_DIR = cp['FEEDWARRIOR']['datadir'] + +try: + os.mkdir(DATA_DIR) + logg.debug('creating datadir {}'.format(DATA_DIR)) +except FileExistsError as e: + logg.debug('using datadir {}'.format(DATA_DIR)) + + +# TODO: move to submodule asap + +def parse_uuid(uu): + if type(uu).__name__ == 'str': + return uuid.UUID('urn:uuid:' + uu) + elif type(uu).__name__ == 'UUID': + return uu + raise ValueError('invalid uuid') + +class Feed: + + def __init__(self, uu=None, parent=None, created=None, updated=None): + if uu == None: + self.uuid = uuid.uuid4() + else: + self.uuid = parse_uuid(uu) + + self.parent = None + if parent != None: + if type(parent).__name__ != 'Feed': + raise ValueError('wrong type for parent: {}'.format(type(parent).__name__)) + self.parent = parent + + if created != None: + self.created = created + if updated == None: + self.updated = copy.copy(created) + else: + self.created = int(time.time()) + self.updated = copy.copy(self.created) + + if self.updated == None: + self.updated = updated + + self.entries = [] + + + def serialize(self): + o = { + 'uuid': str(self.uuid), + 'created': self.created, + 'updated': self.updated, + } + if self.parent != None: + o['parent_uuid'] = str(self.parent.uuid) + + return o + +feed_parent = None +if args.p != None: + try: + feed_parent = Feed(args.p) + except ValueError as e: + logg.error('invalid parent {}: {}'.format(args.p, e)) + sys.exit(1) + +if args.command == None: + feed_current = Feed(parent=feed_parent) + uu = str(feed_current.uuid) + logg.debug('new log {}'.format(uu)) + log_path = os.path.join(DATA_DIR, str(uu)) + os.mkdir(log_path) + + log_meta_path = os.path.join(log_path, '.log') + f = open(log_meta_path, 'x') + json.dump(feed_current.serialize(), f) + f.close() + sys.exit(0)