117 lines
3.5 KiB
Python
117 lines
3.5 KiB
Python
|
'''
|
||
|
I wrote this to make tasks for the tasks.org app with an etebase sync server.
|
||
|
|
||
|
It's not feature comprehensive but it's helpful for bulk task making.
|
||
|
|
||
|
The CLI is not great, it's easier to do python -i pytasks.py and code up
|
||
|
whatever you want.
|
||
|
|
||
|
https://github.com/tasks/tasks
|
||
|
https://github.com/etesync
|
||
|
'''
|
||
|
import argparse
|
||
|
import datetime
|
||
|
import etebase
|
||
|
import sys
|
||
|
import tasks_credentials
|
||
|
import time
|
||
|
|
||
|
from voussoirkit import betterhelp
|
||
|
from voussoirkit import passwordy
|
||
|
from voussoirkit import pipeable
|
||
|
from voussoirkit import timetools
|
||
|
from voussoirkit import vlogging
|
||
|
|
||
|
log = vlogging.getLogger(__name__, '')
|
||
|
|
||
|
PRODID = 'voussoir/pytasks'
|
||
|
|
||
|
client = etebase.Client(tasks_credentials.CLIENT_NAME, tasks_credentials.SERVER)
|
||
|
account = etebase.Account.login(client, tasks_credentials.USERNAME, tasks_credentials.PASSWORD)
|
||
|
collection_manager = account.get_collection_manager()
|
||
|
collections = collection_manager.list('etebase.vtodo', etebase.FetchOptions().limit(500000))
|
||
|
collections = [c for c in collections.data if not c.deleted]
|
||
|
|
||
|
todo = collections[0]
|
||
|
item_manager = collection_manager.get_item_manager(todo)
|
||
|
|
||
|
def make_vcal(text, *, categories=[], due=None):
|
||
|
now = timetools.now().strftime('%Y%m%dT%H%M%SZ')
|
||
|
|
||
|
if due is None:
|
||
|
due = ''
|
||
|
elif isinstance(due, datetime.date):
|
||
|
due = 'DUE;VALUE=DATE:' + due.strftime('%Y%m%d')
|
||
|
elif isinstance(due, datetime.datetime):
|
||
|
due = 'DUE:' + due.strftime('%Y%m%dT%H%M%S')
|
||
|
else:
|
||
|
raise TypeError(due)
|
||
|
|
||
|
lines = [
|
||
|
'BEGIN:VCALENDAR',
|
||
|
'VERSION:2.0',
|
||
|
'PRODID:' + PRODID,
|
||
|
'BEGIN:VTODO',
|
||
|
'DTSTAMP:' + now,
|
||
|
'UID:' + passwordy.random_digits(32),
|
||
|
due,
|
||
|
'CREATED:' + now,
|
||
|
'LAST-MODIFIED:' + now,
|
||
|
'SUMMARY:' + text,
|
||
|
('CATEGORIES:' + ','.join(categories)) if len(categories) > 0 else '',
|
||
|
'END:VTODO',
|
||
|
'END:VCALENDAR',
|
||
|
]
|
||
|
lines = [l for l in lines if l]
|
||
|
vcal = '\r\n'.join(lines) + '\r\n'
|
||
|
return vcal.encode('utf-8')
|
||
|
|
||
|
def make_item(*args, **kwargs):
|
||
|
item = item_manager.create({}, make_vcal(*args, **kwargs))
|
||
|
return item
|
||
|
|
||
|
def publish_items(items):
|
||
|
if isinstance(items, etebase.Item):
|
||
|
item_manager.batch([items])
|
||
|
else:
|
||
|
item_manager.batch(list(items))
|
||
|
|
||
|
def export_argparse(args):
|
||
|
items = item_manager.list(etebase.FetchOptions().limit(50000000))
|
||
|
items = list(items.data)
|
||
|
for item in items:
|
||
|
pipeable.stdout(item.content.decode('utf-8'))
|
||
|
pipeable.stdout()
|
||
|
return 0
|
||
|
|
||
|
def make_tasks_argparse(args):
|
||
|
titles = pipeable.input_many(args.titles, strip=True, skip_blank=True)
|
||
|
items = []
|
||
|
for title in titles:
|
||
|
log.info('Creating task %s.', title)
|
||
|
item = make_item(title)
|
||
|
items.append(item)
|
||
|
publish_items(items)
|
||
|
return 0
|
||
|
|
||
|
@vlogging.main_decorator
|
||
|
def main(argv):
|
||
|
parser = argparse.ArgumentParser()
|
||
|
subparsers = parser.add_subparsers()
|
||
|
|
||
|
################################################################################################
|
||
|
|
||
|
p_make_tasks = subparsers.add_parser('make_tasks', aliases=['make-tasks', 'maketasks', 'maketask'])
|
||
|
p_make_tasks.add_argument('titles', nargs='+')
|
||
|
p_make_tasks.set_defaults(func=make_tasks_argparse)
|
||
|
|
||
|
################################################################################################
|
||
|
|
||
|
p_export = subparsers.add_parser('export')
|
||
|
p_export.set_defaults(func=export_argparse)
|
||
|
|
||
|
return betterhelp.go(parser, argv)
|
||
|
|
||
|
if __name__ == '__main__':
|
||
|
raise SystemExit(main(sys.argv[1:]))
|