From d77d2102ed18b3748c260fcfb78a781af4ee89fe Mon Sep 17 00:00:00 2001 From: Campbell Alden Date: Sat, 19 Jun 2021 11:29:23 +0900 Subject: [PATCH] Initial commit --- .gitignore | 2 ++ base_project_template.yml | 20 +++++++++++ create-template.py | 76 +++++++++++++++++++++++++++++++++++++++ default.nix | 17 +++++++++ 4 files changed, 115 insertions(+) create mode 100644 .gitignore create mode 100644 base_project_template.yml create mode 100644 create-template.py create mode 100644 default.nix diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a208b0d --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +templates/*.yml +run.sh diff --git a/base_project_template.yml b/base_project_template.yml new file mode 100644 index 0000000..186ea6a --- /dev/null +++ b/base_project_template.yml @@ -0,0 +1,20 @@ +# Basic type of template +type: project +description: Describe the type of template here + +area: null # Area to place the project into in Things 3 +title: Title +notes: null +tags: [] +todos: [] + +# Time specific concerns +when: null +deadline: null +creation_date: null +completion_date: null + +# Unlikely to be used but these options exist +completed: false +canceled: false +reveal: true # Shows the value in Things 3 after it is created diff --git a/create-template.py b/create-template.py new file mode 100644 index 0000000..208e03a --- /dev/null +++ b/create-template.py @@ -0,0 +1,76 @@ +import argparse +import yaml +import os +from urllib.parse import urlencode, quote +import webbrowser + +parser = argparse.ArgumentParser(description='Generate projects for Things 3 from templates') +parser.add_argument('--options', help='List available template options', default=False, action='store_true') +parser.add_argument('--template', help='The name of the template to create') +parser.add_argument('--title', help='Override the title field in the template') +parser.add_argument('--notes', help='Override the notes field in the template') +parser.add_argument('--deadline', help='Override the deadline field in the template') +parser.add_argument('--when', help='Override the when field in the template') + + +def formatFiles(tup): + fname, description = tup + fname = fname.split('.')[0] + return '- {}: {}'.format(fname, description) if description is not None else '- {}'.format(fname) + +TEMPLATE_PATH = os.path.join(os.path.dirname(__file__), 'templates') +# Get the names of all the template files +def getTemplateOptions(): + files = os.listdir(TEMPLATE_PATH) + descriptions = [] + for f in files: + with open(os.path.join(TEMPLATE_PATH, f), 'r') as infile: + s = yaml.load(infile, Loader=yaml.FullLoader) + descriptions.append(s['description'] if 'description' in s else None) + return list(map(formatFiles, zip(files, descriptions))) + +def createThings3Project(template, args): + projectTemplate = { + 'title': args.title if args.title is not None else template['title'], + 'notes': args.notes if args.notes is not None else template['notes'], + 'area': template['area'], + 'when': args.when if args.when is not None else template['when'], + 'tags': ','.join(template['tags']), + 'deadline': args.deadline if args.deadline is not None else template['deadline'], + 'to-dos': '\n'.join(template['todos']), + 'completed': template['completed'], + 'canceled': template['canceled'], + 'reveal': template['reveal'], + 'creation-date': template['creation_date'], + 'completion-date': template['completion_date'], + } + params = urlencode({ k: v for k, v in projectTemplate.items() if v is not None }, quote_via=quote) + success = webbrowser.open_new_tab('things:///add-project?{}'.format(params)) + if not success: + print('Failed to create new project') + +def createThings3Template(template, args): + supportedTypes = { + 'project': createThings3Project, + } + if template['type'] in supportedTypes: + return supportedTypes[template['type']](template, args) + else: + raise Exception('Unknown template type: {}'.format(template.type)) + + +ARGS = parser.parse_args() + +if ARGS.template: + try: + with open(os.path.join(TEMPLATE_PATH, ARGS.template + '.yml'), 'r') as infile: + settings = yaml.load(infile, Loader=yaml.FullLoader) + except Exception as e: + print('Could not load template for "{}"'.format(ARGS.title)) + print(e) + + createThings3Template(settings, ARGS) +elif ARGS.options: + print('\n'.join(getTemplateOptions())) +else: + parser.print_help() diff --git a/default.nix b/default.nix new file mode 100644 index 0000000..3ccc223 --- /dev/null +++ b/default.nix @@ -0,0 +1,17 @@ +let + pkgs = import {}; +in pkgs.mkShell { + buildInputs = [ + pkgs.python3 + pkgs.python3.pkgs.requests + pkgs.python3.pkgs.pyyaml + ]; + shellHook = '' + # Tells pip to put packages into $PIP_PREFIX instead of the usual locations. + # See https://pip.pypa.io/en/stable/user_guide/#environment-variables. + export PIP_PREFIX=$(pwd)/_build/pip_packages + export PYTHONPATH="$PIP_PREFIX/${pkgs.python3.sitePackages}:$PYTHONPATH" + export PATH="$PIP_PREFIX/bin:$PATH" + unset SOURCE_DATE_EPOCH + ''; +}