plankapy/controllers.py
2023-03-23 21:24:46 -04:00

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)