359 lines
15 KiB
Python
359 lines
15 KiB
Python
|
from plankapy import Planka
|
||
|
import time
|
||
|
|
||
|
OFFSET = 65535
|
||
|
REFRESH = 10 # Seconds
|
||
|
|
||
|
class Controller(object):
|
||
|
def __init__(self, instance:Planka, **kwargs:dict):
|
||
|
self.instance:Planka = instance
|
||
|
self.kwargs:dict = kwargs
|
||
|
self.template:dict = None
|
||
|
self.routes:dict = None
|
||
|
self.active:dict = None
|
||
|
|
||
|
def get_route(self, method:str, action:str) -> str:
|
||
|
"""Gets the routes for the controller
|
||
|
@return: Routes
|
||
|
"""
|
||
|
if self.routes == None:
|
||
|
raise Exception("Routes not loaded")
|
||
|
if method not in self.routes:
|
||
|
raise Exception(f"Invalid method {method} for route {action}")
|
||
|
return self.routes[method][action]
|
||
|
|
||
|
def parse_route(self, method:str=None, action:str=None ,id:str=None, parent:object=None, req_id:bool=False) -> str:
|
||
|
"""Generates a route string from parameters
|
||
|
@method: HTTP method
|
||
|
@action: HTTP action
|
||
|
@id(optional): ID to use in route
|
||
|
@parent: Parent controller
|
||
|
@req_id: Whether or not the route requires an ID
|
||
|
(Parent ID will be used if needed)
|
||
|
@return: Route string
|
||
|
"""
|
||
|
route = self.get_route(method, action)
|
||
|
if route.count(":id:") > 1:
|
||
|
if parent == None:
|
||
|
raise Exception(f"Parent required for route '{route}'")
|
||
|
route = route.replace(":id:", str(parent.active()["id"]), 1)
|
||
|
if req_id:
|
||
|
route = route.replace(":id:", str(id), 1)
|
||
|
return route
|
||
|
|
||
|
def get_active(self) -> dict:
|
||
|
"""Gets the active object for the controller
|
||
|
@return: Active object
|
||
|
"""
|
||
|
if self.active:
|
||
|
return self.active
|
||
|
|
||
|
def set_active(self, active:dict) -> dict:
|
||
|
"""Sets the active object for the controller
|
||
|
@active: Active object
|
||
|
@return: Previous active object
|
||
|
"""
|
||
|
old = self.active
|
||
|
self.active = active
|
||
|
return old
|
||
|
|
||
|
def clear_active(self) -> None:
|
||
|
"""Clears the active object for the controller
|
||
|
@return: None
|
||
|
"""
|
||
|
self.active = None
|
||
|
return self.active
|
||
|
|
||
|
def get_template(self) -> dict:
|
||
|
"""Gets the template for the controller
|
||
|
@return: Template
|
||
|
"""
|
||
|
raise NotImplementedError("get_template() not implemented")
|
||
|
|
||
|
def build(self) -> dict:
|
||
|
"""Builds the object to be sent to the Planka API
|
||
|
@return: Object to be sent to Planka API
|
||
|
"""
|
||
|
keys = list(self.template.keys())
|
||
|
for key in self.kwargs:
|
||
|
if key in self.template:
|
||
|
self.template[key] = self.kwargs[key]
|
||
|
keys.remove(key)
|
||
|
if len(keys) > 0:
|
||
|
for key in keys:
|
||
|
self.template[key] = None
|
||
|
return self.template
|
||
|
|
||
|
def create(self, **kwargs) -> dict:
|
||
|
"""Creates an object in Planka
|
||
|
@return: Object created in Planka
|
||
|
"""
|
||
|
self.active = self.instance.request("POST", self.parse_route(method="POST", **kwargs), data=self.build())
|
||
|
return self.active
|
||
|
|
||
|
def update(self, data:dict=None, **kwargs) -> dict:
|
||
|
"""Patches an object in Planka
|
||
|
@data: Data to patch
|
||
|
@return: Object patched in Planka
|
||
|
"""
|
||
|
return self.instance.request("PATCH", self.parse_route(method="PATCH", **kwargs), data=data)
|
||
|
|
||
|
def delete(self, **kwargs) -> None:
|
||
|
"""Deletes an object in Planka
|
||
|
@return: None
|
||
|
"""
|
||
|
return self.instance.request("DELETE", self.parse_route(method="DELETE", **kwargs))
|
||
|
|
||
|
def get(self, **kwargs) -> dict:
|
||
|
"""Gets an object by ID
|
||
|
@kwargs: Additional arguments passed to _parse_route()
|
||
|
: @id: ID of object
|
||
|
: @route_parent(str): The dictionary key for the route parent in planka_routes.json\n
|
||
|
: @route_key(str): The dictionary key for the route in planka_routes.json\n
|
||
|
: @parent(Controller): Parent controller object\n
|
||
|
: @req_id(bool): Whether or not the route requires an ID\n
|
||
|
@return: Object
|
||
|
"""
|
||
|
return self.instance.request("GET", self.parse_route(method="GET", **kwargs))
|
||
|
|
||
|
class Project(Controller):
|
||
|
def __init__(self, instance:Planka=None, **kwargs):
|
||
|
self.instance = instance
|
||
|
self.kwargs = kwargs
|
||
|
self.template = self.instance.templates["project"]
|
||
|
self.routes = self.instance.routes["project"]
|
||
|
self.project_dict = None
|
||
|
self.last_updated = None
|
||
|
self.active = {"name": None, "id": None, "content": None}
|
||
|
|
||
|
def create(self) -> dict:
|
||
|
if self.kwargs['name'] in self.get_project_names():
|
||
|
self.active=self.get_project_by_name(self.kwargs['name'])
|
||
|
print(Exception(f"Project '{self.kwargs['name']}' already exists, setting active project to '{self.kwargs['name']}'"))
|
||
|
return self.active
|
||
|
project_item = super().create(action="project")['item']
|
||
|
self.active['name'] = self.kwargs['name']
|
||
|
self.active['id'] = project_item['id']
|
||
|
self.active['content'] = None
|
||
|
self.get_project_dictionary()
|
||
|
return self.active
|
||
|
|
||
|
def delete(self, id:str=None) -> None:
|
||
|
if id == None:
|
||
|
id = self.active["id"]
|
||
|
deleted = super().delete(id=id, action="project", req_id=True)
|
||
|
self.get_project_dictionary()
|
||
|
return deleted
|
||
|
|
||
|
def update(self, id:str=None, data:dict=None) -> dict:
|
||
|
if id == None:
|
||
|
id = self.active["id"]
|
||
|
return super().update(id=id, action="project",data=data, req_id=True)
|
||
|
|
||
|
def set_active(self, name:str) -> dict:
|
||
|
active = self.get_project_by_name(name)
|
||
|
return super().set_active(active)
|
||
|
|
||
|
def get_project(self, id:str=None) -> dict:
|
||
|
if id == None:
|
||
|
id = self.active()["id"]
|
||
|
return super().get(id=id, action="project", req_id=True)['included']
|
||
|
|
||
|
def get_projects(self) -> list:
|
||
|
return super().get(action="projects")
|
||
|
|
||
|
def get_project_names(self):
|
||
|
if self.project_dict == None:
|
||
|
self.project_dict = self.get_project_dictionary()
|
||
|
return list(self.project_dict.keys())
|
||
|
|
||
|
def get_project_dictionary(self) -> dict:
|
||
|
if self.last_updated == None or time.time() - self.last_updated > REFRESH:
|
||
|
self.last_updated = time.time()
|
||
|
self.project_dict = self.get_project_dictionary()
|
||
|
self.project_dict = {project['name']: {"name": project['name'] ,"id": project['id'], "content":self.get_project(project['id'])} for project in self.get_projects()['items']}
|
||
|
return self.project_dict
|
||
|
|
||
|
def get_project_by_name(self, name:str=None) -> dict:
|
||
|
return self.get_project_dictionary()[name]
|
||
|
|
||
|
def get_project_boards(self, name:str=None) -> list:
|
||
|
if name == None:
|
||
|
name = self.active["name"]
|
||
|
return self.get_project_dictionary()[name]["content"]['boards']
|
||
|
|
||
|
def get_project_users(self, name:str=None) -> list:
|
||
|
if name == None:
|
||
|
name = self.active["name"]
|
||
|
return self.get_project_dictionary()[name]["content"]['users']
|
||
|
|
||
|
def get_project_board_memberships(self, name:str=None) -> list:
|
||
|
if name == None:
|
||
|
name = self.active["name"]
|
||
|
return self.get_project_dictionary()[name]["content"]['boardMemberships']
|
||
|
|
||
|
def get_project_managers(self, name:str=None) -> list:
|
||
|
if name == None:
|
||
|
name = self.active["name"]
|
||
|
return self.get_project_dictionary()[name]["content"]['projectManagers']
|
||
|
|
||
|
def get_project_board_names(self, name:str=None) -> list:
|
||
|
if name == None:
|
||
|
name = self.active["name"]
|
||
|
return [board['name'] for board in self.get_project_boards(name)]
|
||
|
|
||
|
class Board(Controller):
|
||
|
def __init__(self, instance:Planka=None, **kwargs):
|
||
|
self.instance = instance
|
||
|
self.kwargs = kwargs
|
||
|
self.template = self.instance.templates["board"]
|
||
|
self.routes = self.instance.routes["board"]
|
||
|
self.board_dict = None
|
||
|
self.active = {"name": None, "id": None, "project": None, "content": None}
|
||
|
|
||
|
def set_project(self, project:str) -> dict:
|
||
|
self.active['project'] = project
|
||
|
return self.active
|
||
|
|
||
|
def set_active(self, active: dict) -> dict:
|
||
|
self.active["name"] = active["name"]
|
||
|
self.active["id"] = active["id"]
|
||
|
self.active["project"] = active["project"]
|
||
|
self.active["content"] = active["content"]
|
||
|
return self.active
|
||
|
|
||
|
def get_board(self, name:str=None, projectName:str=None, projectController:Project=None) -> dict:
|
||
|
if name == None and self.active["name"] != None:
|
||
|
name = self.active["name"]
|
||
|
if name == None:
|
||
|
raise Exception("No board provided")
|
||
|
if projectController == None:
|
||
|
projectController = Project(instance=self.instance)
|
||
|
if projectName == None and projectController.active["name"] != None:
|
||
|
projectName = projectController.active["name"]
|
||
|
if projectName == None:
|
||
|
raise Exception("No project provided")
|
||
|
valid_names = projectController.get_project_board_names(projectName)
|
||
|
if name not in valid_names:
|
||
|
raise Exception(f"Board '{name}' not found in project '{projectName}'")
|
||
|
board_id = [board for board in projectController.get_project_boards(projectName) if board['name'] == name][0]['id']
|
||
|
board = super().get(id=board_id, action="board", req_id=True)['item']
|
||
|
return self.get(id=board_id, action="board", req_id=True)
|
||
|
|
||
|
def get_boards(self, projectController:Project=None, name:str=None) -> list:
|
||
|
if name == None and projectController.active["name"] != None:
|
||
|
name = projectController.active["name"]
|
||
|
projectController.get_project_boards(name)
|
||
|
|
||
|
class List(Controller):
|
||
|
def __init__(self, instance:Planka=None, **kwargs):
|
||
|
self.instance = instance
|
||
|
self.kwargs = kwargs
|
||
|
self.template = self.instance.templates["list"]
|
||
|
self.routes = self.instance.routes["list"]
|
||
|
self.active = {"name": None, "id": None, "board": None ,"content": None}
|
||
|
|
||
|
class Stopwatch(Controller):
|
||
|
def __init__(self, instance:Planka=None, **kwargs):
|
||
|
self.instance = instance
|
||
|
self.kwargs = kwargs
|
||
|
self.template = self.instance.templates["stopwatch"]
|
||
|
self.active = {"name": None, "id": None, "project": None, "board": None , "card": None ,"content": None}
|
||
|
|
||
|
class Card(Controller):
|
||
|
def __init__(self, instance:Planka=None, **kwargs):
|
||
|
self.instance = instance
|
||
|
self.kwargs = kwargs
|
||
|
self.template = self.instance.templates["card"]
|
||
|
self.routes = self.instance.routes["card"]
|
||
|
self.active = {"name": None, "id": None, "project": None, "board": None , "list": None ,"content": None}
|
||
|
|
||
|
class Label(Controller):
|
||
|
def __init__(self, instance:Planka=None, **kwargs):
|
||
|
self.instance = instance
|
||
|
self.kwargs = kwargs
|
||
|
self.template = self.instance.templates["label"]
|
||
|
self.routes = self.instance.routes["label"]
|
||
|
self.active = {"name": None, "id": None, "project": None, "board": None , "list": None , "card": None ,"content": None}
|
||
|
|
||
|
class Task(Controller):
|
||
|
def __init__(self, instance:Planka=None, **kwargs):
|
||
|
self.instance = instance
|
||
|
self.kwargs = kwargs
|
||
|
self.template = self.instance.templates["task"]
|
||
|
self.routes = self.instance.routes["task"]
|
||
|
self.active = {"name": None, "id": None, "project": None, "board": None , "list": None , "card": None ,"content": None}
|
||
|
|
||
|
class CommentAction(Controller):
|
||
|
def __init__(self, instance:Planka=None, **kwargs):
|
||
|
self.instance = instance
|
||
|
self.kwargs = kwargs
|
||
|
self.template = self.instance.templates["comment-action"]
|
||
|
self.routes = self.instance.routes["comment-action"]
|
||
|
self.active = {"name": None, "id": None, "project": None, "board": None , "list": None , "card": None ,"content": None}
|
||
|
|
||
|
class Attachment(Controller):
|
||
|
def __init__(self, instance:Planka=None, **kwargs):
|
||
|
self.instance = instance
|
||
|
self.kwargs = kwargs
|
||
|
self.template = self.instance.templates["attachment"]
|
||
|
self.routes = self.instance.routes["attachment"]
|
||
|
|
||
|
class User(Controller):
|
||
|
def __init__(self, instance:Planka=None, **kwargs):
|
||
|
self.instance = instance
|
||
|
self.kwargs = kwargs
|
||
|
self.template = self.instance.templates["user"]
|
||
|
self.routes = self.instance.routes["user"]
|
||
|
self.active = {"name": None, "id": None, "content": None}
|
||
|
|
||
|
class CardMembership(Controller):
|
||
|
def __init__(self,instance:Planka=None, **kwargs):
|
||
|
self.instance = instance
|
||
|
self.kwargs = kwargs
|
||
|
self.template = self.instance.templates["card-membership"]
|
||
|
self.routes = self.instance.routes["card-membership"]
|
||
|
self.active = {"name": None, "id": None, "project": None, "board": None , "list": None , "card": None ,"content": None}
|
||
|
|
||
|
class BoardMembership(Controller):
|
||
|
def __init__(self, instance:Planka=None, **kwargs):
|
||
|
self.instance = instance
|
||
|
self.kwargs = kwargs
|
||
|
self.template = self.instance.templates["board-membership"]
|
||
|
self.routes = self.instance.routes["board-membership"]
|
||
|
self.active = {"name": None, "id": None, "project": None, "board": None , "content": None}
|
||
|
|
||
|
class CardLabel(Controller):
|
||
|
def __init__(self, instance:Planka=None, **kwargs):
|
||
|
self.instance = instance
|
||
|
self.kwargs = kwargs
|
||
|
self.template = self.instance.templates["card-label"]
|
||
|
self.routes = self.instance.routes["label"]
|
||
|
self.active = {"name": None, "id": None, "project": None, "board": None , "list": None , "card": None ,"content": None}
|
||
|
|
||
|
class ProjectManager(Controller):
|
||
|
def __init__(self, instance:Planka=None, **kwargs):
|
||
|
self.instance = instance
|
||
|
self.kwargs = kwargs
|
||
|
self.template = self.instance.templates["project-manager"]
|
||
|
self.routes = self.instance.routes["project-manager"]
|
||
|
self.active = {"name": None, "id": None, "user": None ,"project": None, "content": None}
|
||
|
|
||
|
class Background(Controller):
|
||
|
def __init__(self, instance:Planka=None, **kwargs):
|
||
|
self.instance:Planka = instance
|
||
|
self.kwargs:dict = kwargs
|
||
|
self.template:dict = self.instance.templates["background"]
|
||
|
self.gradients:list = self.instance.templates["gradients"]
|
||
|
|
||
|
planka = Planka("http://planka.corp.finelines-engineering.com", "hwelch", "Fiber4u!")
|
||
|
|
||
|
projectController = Project(planka)
|
||
|
|
||
|
projectController.set_active("Management API")
|
||
|
|
||
|
boardController = Board(planka)
|
||
|
|
||
|
boards = projectController.get_project_boards()
|
||
|
|
||
|
boardController.get_board(name=boards[0]['name'], projectController=projectController)
|