feat: added cli skeleton and orm for REST
added impl grocy service
This commit is contained in:
parent
7cfc8e5a41
commit
d7120ac60b
@ -1,13 +1,84 @@
|
|||||||
|
import requests
|
||||||
class TaskService(object):
|
class TaskService(object):
|
||||||
def __init__(self, config):
|
def __init__(self, config):
|
||||||
self.config = config
|
self.config = config
|
||||||
|
|
||||||
def add():
|
def findAll():
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
def modify():
|
def modify():
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
class RestService(object):
|
||||||
|
def __init__(self, api_url, json):
|
||||||
|
self.api_url = api_url
|
||||||
|
self.headers = {}
|
||||||
|
self.json
|
||||||
|
|
||||||
|
def get(self, path):
|
||||||
|
api_url = self.api_url
|
||||||
|
|
||||||
|
if api_url.endswith('/'):
|
||||||
|
url = '{0}{1}'.format(api_url, path)
|
||||||
|
else
|
||||||
|
url = '{0}/{1}'.format(api_url, path)
|
||||||
|
|
||||||
|
|
||||||
|
r = requests.get(url, headers=self.headers)
|
||||||
|
|
||||||
|
if self.json:
|
||||||
|
|
||||||
|
|
||||||
|
return r.json()
|
||||||
|
|
||||||
|
return r.content
|
||||||
|
|
||||||
|
def delete(self, id):
|
||||||
|
api_url = self.api_url
|
||||||
|
|
||||||
|
if api_url.endswith('/'):
|
||||||
|
url = '{0}{1}'.format(api_url, path)
|
||||||
|
else
|
||||||
|
url = '{0}/{1}'.format(api_url, path)
|
||||||
|
|
||||||
|
|
||||||
|
r = requests.get(url, headers=self.headers)
|
||||||
|
|
||||||
|
if self.json:
|
||||||
|
|
||||||
|
|
||||||
|
return r.json()
|
||||||
|
|
||||||
|
return r.content
|
||||||
|
|
||||||
|
def post(self, data):
|
||||||
|
api_url = self.api_url
|
||||||
|
|
||||||
|
if api_url.endswith('/'):
|
||||||
|
url = '{0}{1}'.format(api_url, path)
|
||||||
|
else
|
||||||
|
url = '{0}/{1}'.format(api_url, path)
|
||||||
|
|
||||||
|
|
||||||
|
r = requests.post(url, data, headers=self.headers)
|
||||||
|
|
||||||
|
if self.json:
|
||||||
|
|
||||||
|
|
||||||
|
return r.json()
|
||||||
|
|
||||||
|
return r.content
|
||||||
|
|
||||||
|
|
||||||
|
def addHeader(self, type, value):
|
||||||
|
self.header[type] = value
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
108
apps/grocy.py
108
apps/grocy.py
@ -1,14 +1,116 @@
|
|||||||
from twservices.apps import TaskService
|
from twservices.apps import TaskService
|
||||||
|
from datetime import datetime
|
||||||
|
from twservices.apps import RestService
|
||||||
|
|
||||||
|
GROCY_API_KEY_HEADER = 'GROCY_API_KEY'
|
||||||
|
|
||||||
|
# Endpoints
|
||||||
|
GROCY_FIND_ALL_TASKS_ENDPOINT = '/get-objects/tasks'
|
||||||
|
GROCY_DELTE_TASK_ENDPOINT = '/delete-object/tasks/{0}'
|
||||||
|
GROCY_ADD_TASK_ENDPOINT = '/add-object/tasks'
|
||||||
class Grocy(TaskService):
|
class Grocy(TaskService):
|
||||||
|
|
||||||
def __init__(self, config):
|
def __init__(self, config):
|
||||||
self.api_token = config.api_token
|
if config['api'] == None:
|
||||||
self.logger = config.logger
|
raise Exception('api url for Grocy is not defined')
|
||||||
|
# TODO: check if api is a url
|
||||||
|
self.api = config['api']
|
||||||
|
|
||||||
|
if config['token'] == None:
|
||||||
|
raise Exception('token for Grocy is not defined')
|
||||||
|
self.token = config['token']
|
||||||
|
self.rest_service = self.__initRestService()
|
||||||
|
|
||||||
|
def __convertToGrocyTask(self, task):
|
||||||
|
grocy_task = {}
|
||||||
|
grocy_task['id'] = int(task['id'])
|
||||||
|
|
||||||
|
if task['description']:
|
||||||
|
grocy_task['name'] = str(task['description'])
|
||||||
|
|
||||||
|
if task['annotations']
|
||||||
|
grocy_task['description'] = ''
|
||||||
|
for note in task['annotations']:
|
||||||
|
grocy_task['description'] += '{}\n'.format(note)
|
||||||
|
|
||||||
|
if task['entry'] and type(task['entry']) is datettime:
|
||||||
|
grocy_task['row_created_timestamp'] = task['entry'].format('%Y-%m-%d')
|
||||||
|
|
||||||
|
if task['due'] and type(task['due']) is datetime:
|
||||||
|
grocy_task['due_date'] = task['due'].format('%Y-%m-%d')
|
||||||
|
|
||||||
|
if task['done']:
|
||||||
|
grocy_task['done'] = task['done']
|
||||||
|
|
||||||
|
return grocy_task
|
||||||
|
|
||||||
|
|
||||||
|
def __initRestService(self):
|
||||||
|
if self.api.startswith == '/':
|
||||||
|
api_url = self.api_url[1:]
|
||||||
|
if self.api.endswith == '/':
|
||||||
|
api_url =
|
||||||
|
pruned_api_url = self.api
|
||||||
|
rest_service = RestService(self.api, json=True)
|
||||||
|
rest_service.addHeader('Authorization', self.token)
|
||||||
|
return rest_service
|
||||||
|
|
||||||
|
def findAll(self):
|
||||||
|
# Get all tasks as json
|
||||||
|
try:
|
||||||
|
response = self.rest_service.get(GROCY_FIND_ALL_TASKS_ENDPOINT)
|
||||||
|
except Exception as e:
|
||||||
|
print(str(e))
|
||||||
|
raise e
|
||||||
|
return response
|
||||||
|
|
||||||
|
def delete(self, id):
|
||||||
|
if not id:
|
||||||
|
raise Exception('id is not defined')
|
||||||
|
# Delete a task
|
||||||
|
try:
|
||||||
|
response = self.rest_service.get(GROCY_DELTE_TASK_ENDPOINT, id)
|
||||||
|
except Exception as e:
|
||||||
|
print(str(e))
|
||||||
|
raise e
|
||||||
|
return response
|
||||||
|
|
||||||
|
def add(self, task):
|
||||||
|
responses = []
|
||||||
|
if not task:
|
||||||
|
raise Exception('task is not defined')
|
||||||
|
if not type(task) is list:
|
||||||
|
tasks = [task]
|
||||||
|
else:
|
||||||
|
tasks = task
|
||||||
|
|
||||||
|
try:
|
||||||
|
for next_task in tasks:
|
||||||
|
self.__convertToGrocyTask(next_task)
|
||||||
|
response = self.rest_service.post(GROCY_ADD_TASK_ENDPOINT, task)
|
||||||
|
responses.append(response)
|
||||||
|
except Exception as e:
|
||||||
|
print(str(e))
|
||||||
|
raise e
|
||||||
|
return responses
|
||||||
|
|
||||||
|
|
||||||
|
def modify(self, task);
|
||||||
|
response = []
|
||||||
|
if not task:
|
||||||
|
raise Exception('task is not defined')
|
||||||
|
if not type(task) is list:
|
||||||
|
tasks = [task]
|
||||||
|
else:
|
||||||
|
tasks = task
|
||||||
|
try:
|
||||||
|
for next_task in tasks:
|
||||||
|
self.__convertToGrocyTask(next_task)
|
||||||
|
response = self.rest_service.patch(GROCY_MODIFY_TASK_ENDPOINT, task['id'], task)
|
||||||
|
responses.append(response)
|
||||||
|
except Exception as e:
|
||||||
|
print(str(e))
|
||||||
|
raise e
|
||||||
|
return responses
|
||||||
|
|
||||||
|
|
||||||
|
36
cli.py
Normal file
36
cli.py
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import click
|
||||||
|
from os import path
|
||||||
|
|
||||||
|
APP_NAME = 'twservices'
|
||||||
|
|
||||||
|
def __create_config_file():
|
||||||
|
|
||||||
|
@click.command()
|
||||||
|
@click.group()
|
||||||
|
def main():
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_config_file()
|
||||||
|
no_config_msg = 'A config file was not found ' +
|
||||||
|
'and will be created under {0}. Is that Ok?'.format(click.get_app_dir(APP_NAME))
|
||||||
|
cfg_file = path.join(click.get_app_dir(APP_NAME), 'config.yml')
|
||||||
|
if not path.exists(cfg_file):
|
||||||
|
create_config_app_dir = click.confirm(no_config_msg)
|
||||||
|
if create_config_app_dir:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@main.command()
|
||||||
|
def sync():
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
6
sample.config.yml
Normal file
6
sample.config.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
logger:
|
||||||
|
level: debug
|
||||||
|
grocy:
|
||||||
|
api: 'https://aerex.me/grocy/api'
|
||||||
|
token: 'McaeCf5FrT9Sqr96tPcZg9l4uUCexR1fGVGIfDR6qNQxsWECpv'
|
||||||
|
|
13
setup.py
13
setup.py
@ -10,18 +10,23 @@ def read(fname):
|
|||||||
return open(os.path.join(os.path.dirname(__file__), fname)).read()
|
return open(os.path.join(os.path.dirname(__file__), fname)).read()
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name = "taskwarrior-grocy",
|
name = "taskwarrior-services",
|
||||||
version = "0.0.1",
|
version = "0.0.1",
|
||||||
author = "Aer=ex",
|
author = "Aerex",
|
||||||
author_email = "aerex@aerex.me",
|
author_email = "aerex@aerex.me",
|
||||||
description = ("A plugin to create, delete, and modify tasks from and to grocy"),
|
description = ("A plugin to create, delete, and modify tasks across various services "),
|
||||||
keywords = "taskwarrior, grocy",
|
keywords = "taskwarrior, grocy",
|
||||||
url = "http://packages.python.org/an_example_pypi_project",
|
url = "http://packages.python.org/an_example_pypi_project",
|
||||||
packages=['requests', 'taskw', 'pytz'],
|
packages=['requests', 'pyyaml', 'taskw', 'pytz', 'click'],
|
||||||
|
install_requires=['Click'],
|
||||||
long_description=read('README'),
|
long_description=read('README'),
|
||||||
classifiers=[
|
classifiers=[
|
||||||
"Development Status :: 3 - Alpha",
|
"Development Status :: 3 - Alpha",
|
||||||
"Topic :: Utilities",
|
"Topic :: Utilities",
|
||||||
"License :: OSI Approved :: BSD License",
|
"License :: OSI Approved :: BSD License",
|
||||||
],
|
],
|
||||||
|
entry_points="
|
||||||
|
[console_scripts]
|
||||||
|
twservices = cli:main
|
||||||
|
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user