piknik

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

commit cd524efb73a70d065dad740b891cf93c8125dda1
parent f538f58df8c52e37511c84eedb5cd11467dcbf2d
Author: lash <dev@holbrook.no>
Date:   Sun, 19 Mar 2023 11:43:04 +0000

Implement subcommand for cli

Diffstat:
Mpiknik/cli/__init__.py | 9+++++++--
Apiknik/cli/comment.py | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpiknik/cli/mod.py | 5+++++
Mpiknik/crypto.py | 1+
Dpiknik/runnable/add.py | 32--------------------------------
Apiknik/runnable/cmd.py | 50++++++++++++++++++++++++++++++++++++++++++++++++++
Dpiknik/runnable/comment.py | 64----------------------------------------------------------------
Dpiknik/runnable/mod.py | 77-----------------------------------------------------------------------------
Dpiknik/runnable/show.py | 46----------------------------------------------
Mpiknik/store/__init__.py | 5++++-
10 files changed, 125 insertions(+), 222 deletions(-)

diff --git a/piknik/cli/__init__.py b/piknik/cli/__init__.py @@ -4,7 +4,7 @@ import os # local imports from piknik import Basket from piknik.store import FileStoreFactory - +from piknik.crypto import PGPSigner class Context: @@ -13,6 +13,11 @@ class Context: self.files_dir = arg.files_dir #self.store_factory = FileStoreFactory(arg.d) store_factory = FileStoreFactory(arg.d) - self.basket = Basket(store_factory) + self.signer = None + sign_fn = None + if hasattr(arg, 's'): + self.signer = PGPSigner(default_key=arg.s, use_agent=True) + sign_fn = self.signer.sign + self.basket = Basket(store_factory, message_wrapper=sign_fn) self.gpg_home = gpg_home assembler(self, arg) diff --git a/piknik/cli/comment.py b/piknik/cli/comment.py @@ -0,0 +1,58 @@ +# standard imports +import sys +import logging + +logg = logging.getLogger(__name__) + +ctx = None + + +def subparser(argp): + arg = argp.add_parser('comment') + arg.add_argument('-s', '--sign-as', dest='s', type=str, help='PGP fingerprint of key to sign issue update with') + arg.add_argument('-r', type=str, action='append', default=[], help='Add literal message text') + arg.add_argument('-f', type=str, action='append', default=[], help='Add arbitrary file as content') + return argp + + +def assembler(o, arg): + o.r = arg.r + o.f = arg.f + + +next_i = 1 +def next_message_arg(): + global next_i + + r = sys.argv[next_i] + + if r[0] != '-': + next_i += 1 + return None + + if r[1] not in ['r', 'i', 't', 'f']: + next_i += 1 + return None + + v = sys.argv[next_i+1] + next_i += 2 + return (r[1], v,) + + +def main(): + messages = [] + while True: + try: + r = next_message_arg() + except IndexError: + break + if r == None: + continue + + if r[0] == 'r': + messages.append('s:' + r[1]) + elif r[0] == 'f': + messages.append('f:' + r[1]) + + ctx.basket.msg(ctx.issue_id, *messages) + diff --git a/piknik/cli/mod.py b/piknik/cli/mod.py @@ -1,3 +1,8 @@ +# standard imports +import logging + +logg = logging.getLogger(__name__) + ctx = None diff --git a/piknik/crypto.py b/piknik/crypto.py @@ -9,6 +9,7 @@ import gnupg # local imports from piknik.error import VerifyError +from piknik.error import UnknownIdentityError from piknik.wrap import Wrapper logg = logging.getLogger(__name__) diff --git a/piknik/runnable/add.py b/piknik/runnable/add.py @@ -1,32 +0,0 @@ -import sys -import argparse - -from piknik import Basket -from piknik import Issue -from piknik.store import FileStoreFactory - - -argp = argparse.ArgumentParser() -argp.add_argument('-d', type=str, help='Data directory') -argp.add_argument('title', type=str, nargs='*', help='issue title') -arg = argp.parse_args(sys.argv[1:]) - -store_factory = FileStoreFactory(arg.d) -basket = Basket(store_factory) - - -def main(): - title = '' - for s in arg.title: - if s == ' ': - continue - if title != '': - title += ' ' - title += s - o = Issue(title) - v = basket.add(o) - sys.stdout.write(v + '\n') - - -if __name__ == '__main__': - main() diff --git a/piknik/runnable/cmd.py b/piknik/runnable/cmd.py @@ -0,0 +1,50 @@ +# standard imports +import io +import os +import sys +import argparse +import logging +import tempfile +from base64 import b64decode +from email.utils import parsedate_to_datetime +import importlib + +# local imports +from piknik.cli import Context +from piknik.cli.show import subparser as subparser_show +from piknik.cli.mod import subparser as subparser_mod +from piknik.cli.add import subparser as subparser_add +from piknik.cli.comment import subparser as subparser_comment + +logging.basicConfig(level=logging.DEBUG) +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, help='Directory to output saved files to') +argp.add_argument('-i','--issue-id', type=str, help='Issue id to show') + +argsub = argp.add_subparsers(title='subcommand', dest='subcmd') +argsub = subparser_show(argsub) +argsub = subparser_mod(argsub) +argsub = subparser_add(argsub) +argsub = subparser_comment(argsub) +arg = argp.parse_args(sys.argv[1:]) + +m = None +if arg.subcmd == 'show': + m = importlib.import_module('piknik.cli.show') +elif arg.subcmd == 'mod': + m = importlib.import_module('piknik.cli.mod') +elif arg.subcmd == 'add': + m = importlib.import_module('piknik.cli.add') +elif arg.subcmd == 'comment': + m = importlib.import_module('piknik.cli.comment') +else: + raise ValueError('invalid subcommand: ' + arg.subcmd) + +m.ctx = Context(arg, m.assembler) + +if __name__ == '__main__': + m.main() diff --git a/piknik/runnable/comment.py b/piknik/runnable/comment.py @@ -1,64 +0,0 @@ -# standard imports -import sys -import argparse -import logging - -# local imports -from piknik import Basket -from piknik import Issue -from piknik.store import FileStoreFactory -from piknik.crypto import PGPSigner - -logging.basicConfig(level=logging.DEBUG) - -next_i = 1 -def next_message_arg(): - global next_i - - r = sys.argv[next_i] - - if r[0] != '-': - next_i += 1 - return None - - if r[1] not in ['r', 'i', 't', 'f']: - next_i += 1 - return None - - v = sys.argv[next_i+1] - next_i += 2 - return (r[1], v,) - - -argp = argparse.ArgumentParser() -argp.add_argument('-d', type=str, help='Data directory') -argp.add_argument('-s', '--sign-as', dest='s', type=str, help='PGP fingerprint of key to sign issue update with') -argp.add_argument('-r', type=str, action='append', default=[], help='Add literal message text') -argp.add_argument('-f', type=str, action='append', default=[], help='Add arbitrary file as content') -argp.add_argument('issue_id', type=str, help='Issue id to modify') -arg = argp.parse_args(sys.argv[1:]) - -signer = PGPSigner(default_key=arg.s, use_agent=True) -store_factory = FileStoreFactory(arg.d) -basket = Basket(store_factory, message_wrapper=signer.sign) - - -def main(): - messages = [] - while True: - try: - r = next_message_arg() - except IndexError: - break - if r == None: - continue - - if r[0] == 'r': - messages.append('s:' + r[1]) - elif r[0] == 'f': - messages.append('f:' + r[1]) - - basket.msg(arg.issue_id, *messages) - -if __name__ == '__main__': - main() diff --git a/piknik/runnable/mod.py b/piknik/runnable/mod.py @@ -1,77 +0,0 @@ -import sys -import argparse -import logging - -from piknik import Basket -from piknik import Issue -from piknik.store import FileStoreFactory - -logging.basicConfig(level=logging.DEBUG) -logg = logging.getLogger() - - -argp = argparse.ArgumentParser() -argp.add_argument('-d', type=str, help='Data directory') -argp.add_argument('--accept', action='store_true', help='Accept proposed issue') -argp.add_argument('--block', action='store_true', help='Set issue as blocked') -argp.add_argument('--unblock', action='store_true', help='Set issue as unblocked') -argp.add_argument('--finish', action='store_true', help='Set issue as finished (alias of -s finish)') -argp.add_argument('-s', '--state', type=str, help='Move to state') -argp.add_argument('-t', '--tag', type=str, action='append', default=[], help='Add tag to issue') -argp.add_argument('-u', '--untag', type=str, action='append', default=[], help='Remove tag from issue') -#argp.add_argument('-f', '--file', type=str, action='append', help='Add message file part') -#argp.add_argument('-m', '--message', type=str, action='append', default=[], help='Add message text part') -argp.add_argument('-a', '--assign', type=str, action='append', default=[], help='Assign given identity to issue') -argp.add_argument('--unassign', type=str, action='append', default=[], help='Unassign given identity from issue') -argp.add_argument('-o', '--owner', type=str, help='Set given identity as owner of issue') -argp.add_argument('--dep', action='append', default=[], type=str, help='Set issue dependency') -argp.add_argument('--undep', action='append', default=[], type=str, help='Remove issue dependency') -argp.add_argument('issue_id', type=str, help='Issue id to modify') -arg = argp.parse_args(sys.argv[1:]) - -store_factory = FileStoreFactory(arg.d) -basket = Basket(store_factory) - - -def main(): - o = basket.get(arg.issue_id) - - if arg.block: - basket.block(arg.issue_id) - elif arg.unblock: - basket.unblock(arg.issue_id) - - if arg.state != None: - m = getattr(basket, 'state_' + arg.state) - m(arg.issue_id) - elif arg.finish: - basket.state_finish(arg.issue_id) - elif arg.accept: - if basket.get_state(arg.issue_id) != 'PROPOSED': - raise ValueError('Issue already accepted') - basket.advance(arg.issue_id) - - for v in arg.tag: - basket.tag(arg.issue_id, v) - - for v in arg.untag: - basket.untag(arg.issue_id, v) - - for v in arg.unassign: - basket.unassign(arg.issue_id, v) - - for v in arg.assign: - basket.assign(arg.issue_id, v) - - for v in arg.undep: - basket.undep(arg.issue_id, v) - - for v in arg.dep: - basket.dep(arg.issue_id, v) - - if arg.owner: - basket.owner(arg.issue_id, arg.owner) - - -if __name__ == '__main__': - main() diff --git a/piknik/runnable/show.py b/piknik/runnable/show.py @@ -1,46 +0,0 @@ -# standard imports -import io -import os -import sys -import argparse -import logging -import tempfile -from base64 import b64decode -from email.utils import parsedate_to_datetime -import importlib - -# local imports -from piknik.cli import Context -from piknik.cli.show import subparser as subparser_show -from piknik.cli.mod import subparser as subparser_mod -from piknik.cli.add import subparser as subparser_add - -logging.basicConfig(level=logging.WARNING) -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, help='Directory to output saved files to') -argp.add_argument('-i','--issue-id', type=str, help='Issue id to show') - -argsub = argp.add_subparsers(title='subcommand', dest='subcmd') -argsub = subparser_show(argsub) -argsub = subparser_mod(argsub) -argsub = subparser_add(argsub) -arg = argp.parse_args(sys.argv[1:]) - -m = None -if arg.subcmd == 'show': - m = importlib.import_module('piknik.cli.show') -elif arg.subcmd == 'mod': - m = importlib.import_module('piknik.cli.mod') -elif arg.subcmd == 'add': - m = importlib.import_module('piknik.cli.add') -else: - raise ValueError('invalid subcommand: ' + arg.subcmd) - -m.ctx = Context(arg, m.assembler) - -if __name__ == '__main__': - m.main() diff --git a/piknik/store/__init__.py b/piknik/store/__init__.py @@ -1,12 +1,15 @@ # standard imports import os import uuid +import logging # external imports from shep.store.file import SimpleFileStoreFactory from shep.persist import PersistedState from leveldir.hex import HexDir +logg = logging.getLogger(__name__) + def default_formatter(hx): return hx.lower() @@ -39,7 +42,7 @@ class MsgDir(HexDir): def put(self, k, v): u = uuid.UUID(k) - print('putting {}'.format(u.bytes.hex())) + logg.debug('putting {}'.format(u.bytes.hex())) return self.add(u.bytes, v)