refactor: restructure project for pip packaging
Some checks failed
website / build (push) Failing after 30s
Some checks failed
website / build (push) Failing after 30s
Restructured the entire project directory, making `plankapy` pip-installable, enhancing its modularity and maintainability. This involved moving and renaming Python source files and tests into a dedicated `src/plankapy` structure, introducing a `pyproject.toml` for modern packaging standards, and removing obsolete `setup.py` and `__init__.py` files. Updated CI/CD pipelines to accommodate the new structure, ensuring continued automation efficiency. Added a `test_config.py` for centralized test configuration, improving test reliability and ease of modification. - Migrated project documentation and workflow under new `.forgejo` directory for consistency with Forgejo platform requirements. - Enhanced Docker containerization in CI builds by specifying a node-based container, streamlining the environment setup process. - Expanded `.gitignore` to include `venv/`, promoting local development best practices. - Introduced a comprehensive README update, clarifying the project's forked nature and pip-installation goal, fostering better community understanding and contribution suitability.
This commit is contained in:
parent
5c5d03c309
commit
d5777fac54
12 changed files with 448 additions and 195 deletions
|
@ -16,13 +16,13 @@ permissions:
|
||||||
jobs:
|
jobs:
|
||||||
# Build the documentation and upload the static HTML files as an artifact.
|
# Build the documentation and upload the static HTML files as an artifact.
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
container:
|
||||||
|
image: node:20-bookworm
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- name: Install dependencies
|
||||||
- uses: actions/setup-python@v4
|
run: |
|
||||||
with:
|
apt update
|
||||||
python-version: '3.11'
|
apt install -y python3 python3-pip
|
||||||
|
|
||||||
# ADJUST THIS: install all dependencies (including pdoc)
|
# ADJUST THIS: install all dependencies (including pdoc)
|
||||||
#- run: pip install -e .
|
#- run: pip install -e .
|
||||||
#- run: pip install --upgrade pip
|
#- run: pip install --upgrade pip
|
||||||
|
@ -31,23 +31,9 @@ jobs:
|
||||||
#- run: pip install json
|
#- run: pip install json
|
||||||
# ADJUST THIS: build your documentation into docs/.
|
# ADJUST THIS: build your documentation into docs/.
|
||||||
# We use a custom build script for pdoc itself, ideally you just run `pdoc -o docs/ ...` here.
|
# We use a custom build script for pdoc itself, ideally you just run `pdoc -o docs/ ...` here.
|
||||||
- run: python3 -m pdoc -d markdown -o ../../docs ../../plankapy.py
|
- run: python3 -m pdoc -d markdown -o docs src/plankapy/plankapy.py
|
||||||
|
|
||||||
- uses: actions/upload-pages-artifact@v1
|
- uses: forgejo/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
path: ../../docs
|
path: docs
|
||||||
|
|
||||||
# Deploy the artifact to GitHub pages.
|
|
||||||
# This is a separate job so that only actions/deploy-pages has the necessary permissions.
|
|
||||||
deploy:
|
|
||||||
needs: build
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
pages: write
|
|
||||||
id-token: write
|
|
||||||
environment:
|
|
||||||
name: github-pages
|
|
||||||
url: ${{ steps.deployment.outputs.page_url }}
|
|
||||||
steps:
|
|
||||||
- id: deployment
|
|
||||||
uses: actions/deploy-pages@v2
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -5,3 +5,4 @@
|
||||||
|
|
||||||
# Directories
|
# Directories
|
||||||
__pycache__/
|
__pycache__/
|
||||||
|
venv/
|
|
@ -1,6 +1,10 @@
|
||||||
# plankapy
|
# plankapy
|
||||||
A python 3 based API for controlling a self-hosted Planka instance
|
A python 3 based API for controlling a self-hosted Planka instance
|
||||||
|
|
||||||
|
This is a fork of the original [plankapy](https://github.com/hwelch-fle/plankapy)
|
||||||
|
project by [hwelch-fle](https://github.com/hwelch-fle) that primarily focuses on
|
||||||
|
making the project a pip installable package.
|
||||||
|
|
||||||
[Docs](https://hwelch-fle.github.io/plankapy/plankapy.html)
|
[Docs](https://hwelch-fle.github.io/plankapy/plankapy.html)
|
||||||
|
|
||||||
# Rest API Source
|
# Rest API Source
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
import plankapy
|
|
28
pyproject.toml
Normal file
28
pyproject.toml
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
[build-system]
|
||||||
|
requires = ["hatchling"]
|
||||||
|
build-backend = "hatchling.build"
|
||||||
|
|
||||||
|
[project]
|
||||||
|
name = "plankapy"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = [
|
||||||
|
{ name="hwelch-fle" },
|
||||||
|
{ name="Private.coffee Team", email="support@private.coffee" },
|
||||||
|
]
|
||||||
|
description = "A python 3 based API for controlling a self-hosted Planka instance"
|
||||||
|
readme = "README.md"
|
||||||
|
license = { file="LICENSE" }
|
||||||
|
requires-python = ">=3.10"
|
||||||
|
classifiers = [
|
||||||
|
"Programming Language :: Python :: 3",
|
||||||
|
"License :: OSI Approved :: GNU Affero General Public License v3",
|
||||||
|
"Operating System :: OS Independent",
|
||||||
|
]
|
||||||
|
dependencies = [
|
||||||
|
"requests"
|
||||||
|
]
|
||||||
|
|
||||||
|
[project.urls]
|
||||||
|
"Homepage" = "https://git.private.coffee/PrivateCoffee/plankapy"
|
||||||
|
"Bug Tracker" = "https://git.private.coffee/PrivateCoffee/plankapy/issues"
|
||||||
|
"Source Code" = "https://git.private.coffee/PrivateCoffee/plankapy"
|
1
setup.py
1
setup.py
|
@ -1 +0,0 @@
|
||||||
## TODO
|
|
1
src/plankapy/__init__.py
Normal file
1
src/plankapy/__init__.py
Normal file
|
@ -0,0 +1 @@
|
||||||
|
from .plankapy import *
|
|
@ -1,10 +1,12 @@
|
||||||
import requests
|
import requests
|
||||||
import json
|
import json
|
||||||
|
import os
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
# TODO: Split this into multiple files
|
||||||
|
|
||||||
API_URL = "http://localhost:3000"
|
|
||||||
API_USER = "demo- demo.demo"
|
|
||||||
API_PASS = "demo"
|
|
||||||
OFFSET = 65535
|
|
||||||
|
|
||||||
class Planka:
|
class Planka:
|
||||||
"""API wrapper class for Planka
|
"""API wrapper class for Planka
|
||||||
|
@ -12,16 +14,28 @@ class Planka:
|
||||||
- username: Username of Planka user
|
- username: Username of Planka user
|
||||||
- password: Password of Planka user
|
- password: Password of Planka user
|
||||||
"""
|
"""
|
||||||
def __init__(self, url:str, username:str, password:str, templates="config/templates.json"):
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
url: str,
|
||||||
|
username: str,
|
||||||
|
password: str,
|
||||||
|
templates: Optional[os.PathLike] = None,
|
||||||
|
):
|
||||||
self.url = url
|
self.url = url
|
||||||
self.username = username
|
self.username = username
|
||||||
self.password = password
|
self.password = password
|
||||||
self.auth = None
|
self.auth = None
|
||||||
|
|
||||||
|
if not templates:
|
||||||
|
templates = Path(__file__).parent / "config" / "templates.json"
|
||||||
|
|
||||||
with open(templates) as f:
|
with open(templates) as f:
|
||||||
self.templates = json.load(f)
|
self.templates = json.load(f)
|
||||||
self.authenticate()
|
self.authenticate()
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
# TODO: Should this really include the plain-text password?
|
||||||
return f"<{type(self).__name__}:\n\tBase URL: {self.url}\n\tLogin User: {self.username}\n\tLogin Pass: {self.password}\n\tAPI Token: {self.auth}\n>"
|
return f"<{type(self).__name__}:\n\tBase URL: {self.url}\n\tLogin User: {self.username}\n\tLogin Pass: {self.password}\n\tAPI Token: {self.auth}\n>"
|
||||||
|
|
||||||
def deauthenticate(self) -> bool:
|
def deauthenticate(self) -> bool:
|
||||||
|
@ -33,7 +47,9 @@ class Planka:
|
||||||
self.auth = None
|
self.auth = None
|
||||||
return True
|
return True
|
||||||
except:
|
except:
|
||||||
raise InvalidToken(f"No active access token assigned to this instance\n{self.__repr__()}")
|
raise InvalidToken(
|
||||||
|
f"No active access token assigned to this instance\n{self.__repr__()}"
|
||||||
|
)
|
||||||
|
|
||||||
def validate(self) -> bool:
|
def validate(self) -> bool:
|
||||||
"""Validates the Planka API connection
|
"""Validates the Planka API connection
|
||||||
|
@ -50,15 +66,18 @@ class Planka:
|
||||||
- **return:** True if successful, False if not
|
- **return:** True if successful, False if not
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
request = requests.post(f"{self.url}/api/access-tokens", data={'emailOrUsername': self.username, 'password': self.password})
|
request = requests.post(
|
||||||
self.auth = request.json()['item']
|
f"{self.url}/api/access-tokens",
|
||||||
|
data={"emailOrUsername": self.username, "password": self.password},
|
||||||
|
)
|
||||||
|
self.auth = request.json()["item"]
|
||||||
if not self.auth:
|
if not self.auth:
|
||||||
raise InvalidToken(f"Invalid API credentials\n{self.__repr__()}")
|
raise InvalidToken(f"Invalid API credentials\n{self.__repr__()}")
|
||||||
return True
|
return True
|
||||||
except:
|
except:
|
||||||
raise InvalidToken(f"Invalid API credentials\n{self.__repr__()}")
|
raise InvalidToken(f"Invalid API credentials\n{self.__repr__()}")
|
||||||
|
|
||||||
def request(self, method:str, endpoint:str, data:dict=None) -> dict:
|
def request(self, method: str, endpoint: str, data: Optional[dict] = None) -> dict:
|
||||||
"""Makes a request to the Planka API
|
"""Makes a request to the Planka API
|
||||||
- method: HTTP method
|
- method: HTTP method
|
||||||
- endpoint: API endpoint
|
- endpoint: API endpoint
|
||||||
|
@ -67,10 +86,9 @@ class Planka:
|
||||||
"""
|
"""
|
||||||
if not self.auth:
|
if not self.auth:
|
||||||
self.authenticate()
|
self.authenticate()
|
||||||
headers = \
|
headers = {
|
||||||
{
|
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
"Authorization": f"Bearer {self.auth}"
|
"Authorization": f"Bearer {self.auth}",
|
||||||
}
|
}
|
||||||
url = f"{self.url}{endpoint}"
|
url = f"{self.url}{endpoint}"
|
||||||
response = requests.request(method, url, headers=headers, json=data)
|
response = requests.request(method, url, headers=headers, json=data)
|
||||||
|
@ -79,14 +97,16 @@ class Planka:
|
||||||
raise InvalidToken("Invalid API credentials")
|
raise InvalidToken("Invalid API credentials")
|
||||||
|
|
||||||
if response.status_code not in [200, 201]:
|
if response.status_code not in [200, 201]:
|
||||||
raise InvalidToken(f"Failed to {method} {url} with status code {response.status_code}")
|
raise InvalidToken(
|
||||||
|
f"Failed to {method} {url} with status code {response.status_code}"
|
||||||
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return response.json()
|
return response.json()
|
||||||
except:
|
except:
|
||||||
raise InvalidToken(f"Failed to parse response from {url}")
|
raise InvalidToken(f"Failed to parse response from {url}")
|
||||||
|
|
||||||
def get_template(self, template:str) -> dict:
|
def get_template(self, template: str) -> dict:
|
||||||
"""Returns a template from the templates.json file
|
"""Returns a template from the templates.json file
|
||||||
- template: Name of template to return
|
- template: Name of template to return
|
||||||
- **return:** Template dictionary
|
- **return:** Template dictionary
|
||||||
|
@ -96,21 +116,24 @@ class Planka:
|
||||||
except:
|
except:
|
||||||
raise InvalidToken(f"Template not found: {template}")
|
raise InvalidToken(f"Template not found: {template}")
|
||||||
|
|
||||||
class Controller():
|
|
||||||
def __init__(self, instance:Planka) -> None:
|
class Controller:
|
||||||
|
def __init__(self, instance: Planka) -> None:
|
||||||
"""Controller class for Planka API
|
"""Controller class for Planka API
|
||||||
- instance: Planka API instance
|
- instance: Planka API instance
|
||||||
"""
|
"""
|
||||||
self.instance = instance
|
self.instance = instance
|
||||||
self.template:dict = None
|
self.template: dict = None
|
||||||
self.data:dict = None
|
self.data: dict = None
|
||||||
self.response:dict = None
|
self.response: dict = None
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
"""Returns a string representation of the controller object
|
"""Returns a string representation of the controller object
|
||||||
- **return:** String representation of controller object
|
- **return:** String representation of controller object
|
||||||
"""
|
"""
|
||||||
return f"{type(self).__name__}:\n{json.dumps(self.data, sort_keys=True, indent=4)}"
|
return (
|
||||||
|
f"{type(self).__name__}:\n{json.dumps(self.data, sort_keys=True, indent=4)}"
|
||||||
|
)
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
"""Returns a string representation of the controller object
|
"""Returns a string representation of the controller object
|
||||||
|
@ -129,7 +152,7 @@ class Controller():
|
||||||
self.data = data
|
self.data = data
|
||||||
return self.data
|
return self.data
|
||||||
|
|
||||||
def create(self, route:str, data:dict=None) -> dict:
|
def create(self, route: str, data: dict = None) -> dict:
|
||||||
"""Creates a new controller object (POST)
|
"""Creates a new controller object (POST)
|
||||||
- route: Route for controller object POST request
|
- route: Route for controller object POST request
|
||||||
- **return:** POST response dictionary
|
- **return:** POST response dictionary
|
||||||
|
@ -141,14 +164,14 @@ class Controller():
|
||||||
self.response = self.instance.request("POST", route, data)
|
self.response = self.instance.request("POST", route, data)
|
||||||
return self.response
|
return self.response
|
||||||
|
|
||||||
def get(self, route:str) -> dict:
|
def get(self, route: str) -> dict:
|
||||||
"""Gets a controller object (GET)
|
"""Gets a controller object (GET)
|
||||||
- route: Route for controller object GET request
|
- route: Route for controller object GET request
|
||||||
- **return:** GET response dictionary
|
- **return:** GET response dictionary
|
||||||
"""
|
"""
|
||||||
return self.instance.request("GET", route)
|
return self.instance.request("GET", route)
|
||||||
|
|
||||||
def update(self, route:str, data:dict=None) -> dict:
|
def update(self, route: str, data: Optional[dict] = None) -> dict:
|
||||||
"""Updates a controller object (PATCH)
|
"""Updates a controller object (PATCH)
|
||||||
- route: Route for controller object PATCH request
|
- route: Route for controller object PATCH request
|
||||||
- oid: ID of controller object
|
- oid: ID of controller object
|
||||||
|
@ -161,7 +184,7 @@ class Controller():
|
||||||
self.response = self.instance.request("PATCH", route, data=data)
|
self.response = self.instance.request("PATCH", route, data=data)
|
||||||
return self.response
|
return self.response
|
||||||
|
|
||||||
def delete(self, route:str) -> dict:
|
def delete(self, route: str) -> dict:
|
||||||
"""Deletes a controller object (DELETE)
|
"""Deletes a controller object (DELETE)
|
||||||
- route: Route for controller object DELETE request
|
- route: Route for controller object DELETE request
|
||||||
- oid: ID of controller object
|
- oid: ID of controller object
|
||||||
|
@ -175,13 +198,14 @@ class Controller():
|
||||||
"""
|
"""
|
||||||
return self.response
|
return self.response
|
||||||
|
|
||||||
|
|
||||||
class Project(Controller):
|
class Project(Controller):
|
||||||
def __init__(self, instance:Planka, **kwargs) -> None:
|
def __init__(self, instance: Planka, **kwargs) -> None:
|
||||||
self.instance = instance
|
self.instance = instance
|
||||||
self.template = instance.get_template("project")
|
self.template = instance.get_template("project")
|
||||||
self.data = self.build(**kwargs)
|
self.data = self.build(**kwargs)
|
||||||
|
|
||||||
def get(self, name:str=None, oid:str=None) -> dict:
|
def get(self, name: Optional[str] = None, oid: Optional[str] = None) -> dict:
|
||||||
"""Gets a project by name
|
"""Gets a project by name
|
||||||
- oid: ID of project to get (optional)
|
- oid: ID of project to get (optional)
|
||||||
- name: Name of project if None returns all projects
|
- name: Name of project if None returns all projects
|
||||||
|
@ -202,7 +226,7 @@ class Project(Controller):
|
||||||
"""Gets a list of project names
|
"""Gets a list of project names
|
||||||
- **return:** List of project names
|
- **return:** List of project names
|
||||||
"""
|
"""
|
||||||
return [prj["name"] for prj in self.get()['items']]
|
return [prj["name"] for prj in self.get()["items"]]
|
||||||
|
|
||||||
def create(self) -> dict:
|
def create(self) -> dict:
|
||||||
"""Creates a new project
|
"""Creates a new project
|
||||||
|
@ -210,33 +234,39 @@ class Project(Controller):
|
||||||
"""
|
"""
|
||||||
if not self.data:
|
if not self.data:
|
||||||
raise InvalidToken(f"Please Build a {type(self).__name__} before creating")
|
raise InvalidToken(f"Please Build a {type(self).__name__} before creating")
|
||||||
if self.data["name"] in [prj["name"] for prj in self.get()['items']]:
|
if self.data["name"] in [prj["name"] for prj in self.get()["items"]]:
|
||||||
raise InvalidToken(f"Project {self.data['name']} already exists")
|
raise InvalidToken(f"Project {self.data['name']} already exists")
|
||||||
return super().create("/api/projects")
|
return super().create("/api/projects")
|
||||||
|
|
||||||
def update(self, name:str) -> dict:
|
def update(self, name: str) -> dict:
|
||||||
"""Updates a project
|
"""Updates a project
|
||||||
- name: Name of project to update
|
- name: Name of project to update
|
||||||
- **return:** PATCH response dictionary
|
- **return:** PATCH response dictionary
|
||||||
"""
|
"""
|
||||||
prj_id = prj_id = self.get(name)['item']['id']
|
prj_id = prj_id = self.get(name)["item"]["id"]
|
||||||
return super().update(f"/api/projects/{prj_id}")
|
return super().update(f"/api/projects/{prj_id}")
|
||||||
|
|
||||||
def delete(self, name:str) -> dict:
|
def delete(self, name: str) -> dict:
|
||||||
"""Deletes a project
|
"""Deletes a project
|
||||||
- name: Name of project to delete
|
- name: Name of project to delete
|
||||||
- **return:** DELETE response dictionary
|
- **return:** DELETE response dictionary
|
||||||
"""
|
"""
|
||||||
prj_id = self.get(name)['item']['id']
|
prj_id = self.get(name)["item"]["id"]
|
||||||
return super().delete(f"/api/projects/{prj_id}")
|
return super().delete(f"/api/projects/{prj_id}")
|
||||||
|
|
||||||
|
|
||||||
class Board(Controller):
|
class Board(Controller):
|
||||||
def __init__(self, instance:Planka, **kwargs) -> None:
|
def __init__(self, instance: Planka, **kwargs) -> None:
|
||||||
self.instance = instance
|
self.instance = instance
|
||||||
self.template = instance.get_template("board")
|
self.template = instance.get_template("board")
|
||||||
self.data = self.build(**kwargs)
|
self.data = self.build(**kwargs)
|
||||||
|
|
||||||
def get(self, project_name:str=None, board_name:str=None, oid:str=None) -> dict:
|
def get(
|
||||||
|
self,
|
||||||
|
project_name: Optional[str] = None,
|
||||||
|
board_name: Optionoal[str] = None,
|
||||||
|
oid: Optional[str] = None,
|
||||||
|
) -> dict:
|
||||||
"""Gets a board by name
|
"""Gets a board by name
|
||||||
- oid: ID of board to get (optonal)
|
- oid: ID of board to get (optonal)
|
||||||
- name: Name of board if None returns all boards
|
- name: Name of board if None returns all boards
|
||||||
|
@ -258,7 +288,7 @@ class Board(Controller):
|
||||||
board_id = [board for board in boards if board["name"] == board_name][0]["id"]
|
board_id = [board for board in boards if board["name"] == board_name][0]["id"]
|
||||||
return super().get(f"/api/boards/{board_id}")
|
return super().get(f"/api/boards/{board_id}")
|
||||||
|
|
||||||
def create(self, project_name:str) -> dict:
|
def create(self, project_name: str) -> dict:
|
||||||
"""Creates a new board
|
"""Creates a new board
|
||||||
- prj_name: Name of project to create board in
|
- prj_name: Name of project to create board in
|
||||||
- **return:** POST response dictionary
|
- **return:** POST response dictionary
|
||||||
|
@ -266,10 +296,16 @@ class Board(Controller):
|
||||||
if not self.data:
|
if not self.data:
|
||||||
raise InvalidToken(f"Please Build a {type(self).__name__} before creating")
|
raise InvalidToken(f"Please Build a {type(self).__name__} before creating")
|
||||||
prj_con = Project(self.instance)
|
prj_con = Project(self.instance)
|
||||||
prj_id = prj_con.get(project_name)['item']['id']
|
prj_id = prj_con.get(project_name)["item"]["id"]
|
||||||
return super().create(f"/api/projects/{prj_id}/boards")
|
return super().create(f"/api/projects/{prj_id}/boards")
|
||||||
|
|
||||||
def update(self, project_name:str=None, board_name:str=None, data:dict=None, oid:str=None) -> dict:
|
def update(
|
||||||
|
self,
|
||||||
|
project_name: Optional[str] = None,
|
||||||
|
board_name: Optional[str] = None,
|
||||||
|
data: Optional[dict] = None,
|
||||||
|
oid: Optional[str] = None,
|
||||||
|
) -> dict:
|
||||||
"""Updates a board
|
"""Updates a board
|
||||||
- oid: ID of board to update (optional)
|
- oid: ID of board to update (optional)
|
||||||
- project_name: Name of project to update board in
|
- project_name: Name of project to update board in
|
||||||
|
@ -284,10 +320,15 @@ class Board(Controller):
|
||||||
return super().update(f"/api/boards/{oid}", data=data)
|
return super().update(f"/api/boards/{oid}", data=data)
|
||||||
if not (project_name and board_name):
|
if not (project_name and board_name):
|
||||||
raise InvalidToken("Please provide project and board names")
|
raise InvalidToken("Please provide project and board names")
|
||||||
board_id = self.get(project_name, board_name)['item']['id']
|
board_id = self.get(project_name, board_name)["item"]["id"]
|
||||||
return super().update(f"/api/boards/{board_id}", data=self.data)
|
return super().update(f"/api/boards/{board_id}", data=self.data)
|
||||||
|
|
||||||
def delete(self, project_name:str=None, board_name:str=None, oid:str=None):
|
def delete(
|
||||||
|
self,
|
||||||
|
project_name: Optional[str] = None,
|
||||||
|
board_name: Optional[str] = None,
|
||||||
|
oid: Optional[str] = None,
|
||||||
|
):
|
||||||
"""Deletes a board
|
"""Deletes a board
|
||||||
- oid: ID of board to delete (optional)
|
- oid: ID of board to delete (optional)
|
||||||
- project_name: Name of project to delete board in
|
- project_name: Name of project to delete board in
|
||||||
|
@ -300,16 +341,22 @@ class Board(Controller):
|
||||||
raise InvalidToken("Please provide a project name")
|
raise InvalidToken("Please provide a project name")
|
||||||
if not board_name:
|
if not board_name:
|
||||||
raise InvalidToken("Please provide a board name")
|
raise InvalidToken("Please provide a board name")
|
||||||
board_id = self.get(project_name, board_name)['item']['id']
|
board_id = self.get(project_name, board_name)["item"]["id"]
|
||||||
return super().delete(f"/api/boards/{board_id}")
|
return super().delete(f"/api/boards/{board_id}")
|
||||||
|
|
||||||
|
|
||||||
class List(Controller):
|
class List(Controller):
|
||||||
def __init__(self, instance:Planka, **kwargs) -> None:
|
def __init__(self, instance: Planka, **kwargs) -> None:
|
||||||
self.instance = instance
|
self.instance = instance
|
||||||
self.template = instance.get_template("list")
|
self.template = instance.get_template("list")
|
||||||
self.data = self.build(**kwargs)
|
self.data = self.build(**kwargs)
|
||||||
|
|
||||||
def get(self, project_name:str=None, board_name:str=None, list_name:str=None):
|
def get(
|
||||||
|
self,
|
||||||
|
project_name: Optional[str] = None,
|
||||||
|
board_name: Optional[str] = None,
|
||||||
|
list_name: Optional[str] = None,
|
||||||
|
):
|
||||||
"""Gets a list by name
|
"""Gets a list by name
|
||||||
NOTE: No GET route for list by ID
|
NOTE: No GET route for list by ID
|
||||||
- project_name: Name of project to get list from
|
- project_name: Name of project to get list from
|
||||||
|
@ -329,7 +376,12 @@ class List(Controller):
|
||||||
raise InvalidToken(f"List `{list_name}` not found")
|
raise InvalidToken(f"List `{list_name}` not found")
|
||||||
return [lst for lst in lists if lst["name"] == list_name][0]
|
return [lst for lst in lists if lst["name"] == list_name][0]
|
||||||
|
|
||||||
def create(self, project_name:str=None, board_name:str=None, data:dict=None):
|
def create(
|
||||||
|
self,
|
||||||
|
project_name: Optional[str] = None,
|
||||||
|
board_name: Optional[str] = None,
|
||||||
|
data: Optional[dict] = None,
|
||||||
|
):
|
||||||
"""Creates a new list
|
"""Creates a new list
|
||||||
- project_name: Name of project to create list in
|
- project_name: Name of project to create list in
|
||||||
- board_name: Name of board to create list in
|
- board_name: Name of board to create list in
|
||||||
|
@ -342,10 +394,17 @@ class List(Controller):
|
||||||
if not (project_name and board_name):
|
if not (project_name and board_name):
|
||||||
raise InvalidToken("Please provide project and board name")
|
raise InvalidToken("Please provide project and board name")
|
||||||
board_con = Board(self.instance)
|
board_con = Board(self.instance)
|
||||||
board_id = board_con.get(project_name, board_name)['item']['id']
|
board_id = board_con.get(project_name, board_name)["item"]["id"]
|
||||||
return super().create(f"/api/boards/{board_id}/lists")
|
return super().create(f"/api/boards/{board_id}/lists")
|
||||||
|
|
||||||
def update(self, project_name:str=None, board_name:str=None, list_name:str=None, data:dict=None, oid:str=None):
|
def update(
|
||||||
|
self,
|
||||||
|
project_name: Optional[str] = None,
|
||||||
|
board_name: Optional[str] = None,
|
||||||
|
list_name: Optional[str] = None,
|
||||||
|
data: Optional[dict] = None,
|
||||||
|
oid: Optional[str] = None,
|
||||||
|
):
|
||||||
"""Updates a list
|
"""Updates a list
|
||||||
- oid: ID of list to update (optional)
|
- oid: ID of list to update (optional)
|
||||||
- project_name: Name of project to update list in
|
- project_name: Name of project to update list in
|
||||||
|
@ -364,7 +423,13 @@ class List(Controller):
|
||||||
lst = self.get(project_name, board_name, list_name)
|
lst = self.get(project_name, board_name, list_name)
|
||||||
return super().update(f"/api/lists/{lst['id']}", data=data)
|
return super().update(f"/api/lists/{lst['id']}", data=data)
|
||||||
|
|
||||||
def delete(self, project_name:str=None, board_name:str=None, list_name:str=None, oid:str=None):
|
def delete(
|
||||||
|
self,
|
||||||
|
project_name: Optional[str] = None,
|
||||||
|
board_name: Optional[str] = None,
|
||||||
|
list_name: Optional[str] = None,
|
||||||
|
oid: Optional[str] = None,
|
||||||
|
):
|
||||||
"""Deletes a list
|
"""Deletes a list
|
||||||
- oid: ID of list to delete (optional)
|
- oid: ID of list to delete (optional)
|
||||||
- project_name: Name of project to delete list in
|
- project_name: Name of project to delete list in
|
||||||
|
@ -379,13 +444,21 @@ class List(Controller):
|
||||||
lst = self.get(project_name, board_name, list_name)
|
lst = self.get(project_name, board_name, list_name)
|
||||||
return super().delete(f"/api/lists/{lst['id']}")
|
return super().delete(f"/api/lists/{lst['id']}")
|
||||||
|
|
||||||
|
|
||||||
class Card(Controller):
|
class Card(Controller):
|
||||||
def __init__(self, instance:Planka, **kwargs) -> None:
|
def __init__(self, instance: Planka, **kwargs) -> None:
|
||||||
self.instance = instance
|
self.instance = instance
|
||||||
self.template = instance.get_template("card")
|
self.template = instance.get_template("card")
|
||||||
self.data = self.build(**kwargs)
|
self.data = self.build(**kwargs)
|
||||||
|
|
||||||
def get(self, project_name:str=None, board_name:str=None, list_name:str=None, card_name:str=None, oid:str=None):
|
def get(
|
||||||
|
self,
|
||||||
|
project_name: str = None,
|
||||||
|
board_name: str = None,
|
||||||
|
list_name: str = None,
|
||||||
|
card_name: str = None,
|
||||||
|
oid: str = None,
|
||||||
|
):
|
||||||
"""Gets a card by name
|
"""Gets a card by name
|
||||||
- oid: ID of card to get (optional)
|
- oid: ID of card to get (optional)
|
||||||
- project_name: Name of project to get card from
|
- project_name: Name of project to get card from
|
||||||
|
@ -400,17 +473,27 @@ class Card(Controller):
|
||||||
raise InvalidToken("Please provide project, board, and list names")
|
raise InvalidToken("Please provide project, board, and list names")
|
||||||
board_con = Board(self.instance)
|
board_con = Board(self.instance)
|
||||||
board = board_con.get(project_name, board_name)
|
board = board_con.get(project_name, board_name)
|
||||||
lst_id = [ls for ls in board["included"]["lists"] if ls["name"] == list_name][0]["id"]
|
lst_id = [ls for ls in board["included"]["lists"] if ls["name"] == list_name][
|
||||||
cards = [card for card in board["included"]["cards"] if card["listId"] == lst_id]
|
0
|
||||||
|
]["id"]
|
||||||
|
cards = [
|
||||||
|
card for card in board["included"]["cards"] if card["listId"] == lst_id
|
||||||
|
]
|
||||||
card_names = [card["name"] for card in cards]
|
card_names = [card["name"] for card in cards]
|
||||||
if not card_name:
|
if not card_name:
|
||||||
return [self.get(oid=card["id"]) for card in cards]
|
return [self.get(oid=card["id"]) for card in cards]
|
||||||
if card_name not in card_names:
|
if card_name not in card_names:
|
||||||
raise InvalidToken(f"Card `{card_name}` not found")
|
raise InvalidToken(f"Card `{card_name}` not found")
|
||||||
card_id = [card for card in cards if card["name"] == card_name][0]['id']
|
card_id = [card for card in cards if card["name"] == card_name][0]["id"]
|
||||||
return super().get(f"/api/cards/{card_id}")
|
return super().get(f"/api/cards/{card_id}")
|
||||||
|
|
||||||
def create(self, project_name:str=None, board_name:str=None, list_name:str=None, data:dict=None):
|
def create(
|
||||||
|
self,
|
||||||
|
project_name: str = None,
|
||||||
|
board_name: str = None,
|
||||||
|
list_name: str = None,
|
||||||
|
data: dict = None,
|
||||||
|
):
|
||||||
"""Creates a new card
|
"""Creates a new card
|
||||||
- project_name: Name of project to create card in
|
- project_name: Name of project to create card in
|
||||||
- board_name: Name of board to create card in
|
- board_name: Name of board to create card in
|
||||||
|
@ -425,10 +508,19 @@ class Card(Controller):
|
||||||
raise InvalidToken("Please provide a project, board and list names")
|
raise InvalidToken("Please provide a project, board and list names")
|
||||||
board_con = Board(self.instance)
|
board_con = Board(self.instance)
|
||||||
board = board_con.get(project_name, board_name)
|
board = board_con.get(project_name, board_name)
|
||||||
lst_id = [ls for ls in board["included"]["lists"] if ls["name"] == list_name][0]["id"]
|
lst_id = [ls for ls in board["included"]["lists"] if ls["name"] == list_name][
|
||||||
|
0
|
||||||
|
]["id"]
|
||||||
return super().create(f"/api/lists/{lst_id}/cards")
|
return super().create(f"/api/lists/{lst_id}/cards")
|
||||||
|
|
||||||
def delete(self, project_name:str=None, board_name:str=None, list_name:str=None, card_name:str=None, oid:str=None):
|
def delete(
|
||||||
|
self,
|
||||||
|
project_name: str = None,
|
||||||
|
board_name: str = None,
|
||||||
|
list_name: str = None,
|
||||||
|
card_name: str = None,
|
||||||
|
oid: str = None,
|
||||||
|
):
|
||||||
"""Deletes a card
|
"""Deletes a card
|
||||||
- oid: ID of card to delete (optional)
|
- oid: ID of card to delete (optional)
|
||||||
- project_name: Name of project to delete card in
|
- project_name: Name of project to delete card in
|
||||||
|
@ -444,7 +536,15 @@ class Card(Controller):
|
||||||
card = self.get(project_name, board_name, list_name, card_name)
|
card = self.get(project_name, board_name, list_name, card_name)
|
||||||
return super().delete(f"/api/cards/{card['id']}")
|
return super().delete(f"/api/cards/{card['id']}")
|
||||||
|
|
||||||
def update(self, project_name:str=None, board_name:str=None, list_name:str=None, card_name:str=None, data:dict=None, oid:str=None):
|
def update(
|
||||||
|
self,
|
||||||
|
project_name: str = None,
|
||||||
|
board_name: str = None,
|
||||||
|
list_name: str = None,
|
||||||
|
card_name: str = None,
|
||||||
|
data: dict = None,
|
||||||
|
oid: str = None,
|
||||||
|
):
|
||||||
"""Updates a card
|
"""Updates a card
|
||||||
- oid: ID of card to update (optional)
|
- oid: ID of card to update (optional)
|
||||||
- project_name: Name of project to update card in
|
- project_name: Name of project to update card in
|
||||||
|
@ -464,7 +564,14 @@ class Card(Controller):
|
||||||
card = self.get(project_name, board_name, list_name, card_name)
|
card = self.get(project_name, board_name, list_name, card_name)
|
||||||
return super().update(f"/api/cards/{card['id']}", data=data)
|
return super().update(f"/api/cards/{card['id']}", data=data)
|
||||||
|
|
||||||
def get_labels(self, project_name:str=None, board_name:str=None, list_name:str=None, card_name:str=None, oid:str=None):
|
def get_labels(
|
||||||
|
self,
|
||||||
|
project_name: str = None,
|
||||||
|
board_name: str = None,
|
||||||
|
list_name: str = None,
|
||||||
|
card_name: str = None,
|
||||||
|
oid: str = None,
|
||||||
|
):
|
||||||
"""Gets labels for a card
|
"""Gets labels for a card
|
||||||
- oid: ID of card to get labels from (optional)
|
- oid: ID of card to get labels from (optional)
|
||||||
- project_name: Name of project to get card from
|
- project_name: Name of project to get card from
|
||||||
|
@ -474,14 +581,15 @@ class Card(Controller):
|
||||||
- **return:** GET response dictionary
|
- **return:** GET response dictionary
|
||||||
"""
|
"""
|
||||||
if oid:
|
if oid:
|
||||||
return self.get(oid=oid)['included']['cardLabels']
|
return self.get(oid=oid)["included"]["cardLabels"]
|
||||||
if not (project_name and board_name and list_name and card_name):
|
if not (project_name and board_name and list_name and card_name):
|
||||||
raise InvalidToken("Please provide project, board, list, and card names")
|
raise InvalidToken("Please provide project, board, list, and card names")
|
||||||
card_id = self.get(project_name, board_name, list_name, card_name)['item']['id']
|
card_id = self.get(project_name, board_name, list_name, card_name)["item"]["id"]
|
||||||
return self.get(oid=card_id)['included']['cardLabels']
|
return self.get(oid=card_id)["included"]["cardLabels"]
|
||||||
|
|
||||||
|
|
||||||
class Label(Controller):
|
class Label(Controller):
|
||||||
def __init__(self, instance:Planka, **kwargs) -> None:
|
def __init__(self, instance: Planka, **kwargs) -> None:
|
||||||
self.instance = instance
|
self.instance = instance
|
||||||
self.template = instance.get_template("label")
|
self.template = instance.get_template("label")
|
||||||
self.options = instance.get_template("colors")
|
self.options = instance.get_template("colors")
|
||||||
|
@ -490,7 +598,9 @@ class Label(Controller):
|
||||||
def colors(self) -> list:
|
def colors(self) -> list:
|
||||||
return self.options
|
return self.options
|
||||||
|
|
||||||
def get(self, project_name:str=None, board_name:str=None, label_name:str=None) -> dict:
|
def get(
|
||||||
|
self, project_name: str = None, board_name: str = None, label_name: str = None
|
||||||
|
) -> dict:
|
||||||
"""Gets a label by name
|
"""Gets a label by name
|
||||||
- project_name: Name of project to get label from
|
- project_name: Name of project to get label from
|
||||||
- board_name: Name of board to get label from
|
- board_name: Name of board to get label from
|
||||||
|
@ -509,7 +619,9 @@ class Label(Controller):
|
||||||
raise InvalidToken(f"Label `{label_name}` not found")
|
raise InvalidToken(f"Label `{label_name}` not found")
|
||||||
return [label for label in labels if label["name"] == label_name][0]
|
return [label for label in labels if label["name"] == label_name][0]
|
||||||
|
|
||||||
def create(self, project_name:str=None, board_name:str=None, data:dict=None):
|
def create(
|
||||||
|
self, project_name: str = None, board_name: str = None, data: dict = None
|
||||||
|
):
|
||||||
"""Creates a new label
|
"""Creates a new label
|
||||||
- project_name: Name of project to create label in
|
- project_name: Name of project to create label in
|
||||||
- board_name: Name of board to create label in
|
- board_name: Name of board to create label in
|
||||||
|
@ -522,10 +634,16 @@ class Label(Controller):
|
||||||
if not (project_name and board_name):
|
if not (project_name and board_name):
|
||||||
raise InvalidToken("Please provide project and board names")
|
raise InvalidToken("Please provide project and board names")
|
||||||
board_con = Board(self.instance)
|
board_con = Board(self.instance)
|
||||||
board = board_con.get(project_name, board_name)['item']
|
board = board_con.get(project_name, board_name)["item"]
|
||||||
return super().create(f"/api/boards/{board['id']}/labels")
|
return super().create(f"/api/boards/{board['id']}/labels")
|
||||||
|
|
||||||
def delete(self, project_name:str=None, board_name:str=None, label_name:str=None, oid:str=None):
|
def delete(
|
||||||
|
self,
|
||||||
|
project_name: str = None,
|
||||||
|
board_name: str = None,
|
||||||
|
label_name: str = None,
|
||||||
|
oid: str = None,
|
||||||
|
):
|
||||||
"""Deletes a label
|
"""Deletes a label
|
||||||
- oid: ID of label to delete (optional)
|
- oid: ID of label to delete (optional)
|
||||||
- project_name: Name of project to delete label from
|
- project_name: Name of project to delete label from
|
||||||
|
@ -540,7 +658,16 @@ class Label(Controller):
|
||||||
label = self.get(project_name, board_name, label_name)
|
label = self.get(project_name, board_name, label_name)
|
||||||
return super().delete(f"/api/labels/{label['id']}")
|
return super().delete(f"/api/labels/{label['id']}")
|
||||||
|
|
||||||
def add(self, project_name:str=None, board_name:str=None, list_name:str=None ,card_name:str=None, label_name:str=None, card_id:str=None, label_id:str=None):
|
def add(
|
||||||
|
self,
|
||||||
|
project_name: str = None,
|
||||||
|
board_name: str = None,
|
||||||
|
list_name: str = None,
|
||||||
|
card_name: str = None,
|
||||||
|
label_name: str = None,
|
||||||
|
card_id: str = None,
|
||||||
|
label_id: str = None,
|
||||||
|
):
|
||||||
"""Adds a label to a card
|
"""Adds a label to a card
|
||||||
- project_name: Name of project to add label to card in
|
- project_name: Name of project to add label to card in
|
||||||
- board_name: Name of board to add label to card in
|
- board_name: Name of board to add label to card in
|
||||||
|
@ -550,20 +677,35 @@ class Label(Controller):
|
||||||
- **return:** POST response dictionary
|
- **return:** POST response dictionary
|
||||||
"""
|
"""
|
||||||
if label_id and card_id:
|
if label_id and card_id:
|
||||||
return super().create(f"/api/cards/{card_id}/labels", data={"labelId":label_id})
|
return super().create(
|
||||||
|
f"/api/cards/{card_id}/labels", data={"labelId": label_id}
|
||||||
|
)
|
||||||
if not (project_name and board_name and label_name):
|
if not (project_name and board_name and label_name):
|
||||||
raise InvalidToken("Please provide a project, board, label name")
|
raise InvalidToken("Please provide a project, board, label name")
|
||||||
if card_id:
|
if card_id:
|
||||||
label = self.get(project_name, board_name, label_name)
|
label = self.get(project_name, board_name, label_name)
|
||||||
return super().create(f"/api/cards/{card_id}/labels", data={"labelId":label['item']['id']})
|
return super().create(
|
||||||
|
f"/api/cards/{card_id}/labels", data={"labelId": label["item"]["id"]}
|
||||||
|
)
|
||||||
if not (card_name and list_name):
|
if not (card_name and list_name):
|
||||||
raise InvalidToken("Please provide a card and list name")
|
raise InvalidToken("Please provide a card and list name")
|
||||||
card_con = Card(self.instance)
|
card_con = Card(self.instance)
|
||||||
card = card_con.get(project_name, board_name, list_name, card_name)
|
card = card_con.get(project_name, board_name, list_name, card_name)
|
||||||
label = self.get(project_name, board_name, label_name)
|
label = self.get(project_name, board_name, label_name)
|
||||||
return super().create(f"/api/cards/{card['item']['id']}/labels", {"labelId":label['item']['id']})
|
return super().create(
|
||||||
|
f"/api/cards/{card['item']['id']}/labels", {"labelId": label["item"]["id"]}
|
||||||
|
)
|
||||||
|
|
||||||
def remove(self, project_name:str=None, board_name:str=None, list_name:str=None ,card_name:str=None, label_name:str=None, card_id:str=None, label_id:str=None):
|
def remove(
|
||||||
|
self,
|
||||||
|
project_name: str = None,
|
||||||
|
board_name: str = None,
|
||||||
|
list_name: str = None,
|
||||||
|
card_name: str = None,
|
||||||
|
label_name: str = None,
|
||||||
|
card_id: str = None,
|
||||||
|
label_id: str = None,
|
||||||
|
):
|
||||||
"""Removes a label from a card
|
"""Removes a label from a card
|
||||||
- project_name: Name of project to remove label from card in
|
- project_name: Name of project to remove label from card in
|
||||||
- board_name: Name of board to remove label from card in
|
- board_name: Name of board to remove label from card in
|
||||||
|
@ -577,22 +719,36 @@ class Label(Controller):
|
||||||
if not (project_name and board_name and label_name):
|
if not (project_name and board_name and label_name):
|
||||||
raise InvalidToken("Please provide a project, board, label name")
|
raise InvalidToken("Please provide a project, board, label name")
|
||||||
if card_id:
|
if card_id:
|
||||||
label_id = [label['id'] for label in Card(self.instance).get_labels(oid=card_id) if label['name'] == label_name][0]
|
label_id = [
|
||||||
|
label["id"]
|
||||||
|
for label in Card(self.instance).get_labels(oid=card_id)
|
||||||
|
if label["name"] == label_name
|
||||||
|
][0]
|
||||||
return super().delete(f"/api/cards/{card_id}/labels/{label_id}")
|
return super().delete(f"/api/cards/{card_id}/labels/{label_id}")
|
||||||
if not (card_name and list_name):
|
if not (card_name and list_name):
|
||||||
raise InvalidToken("Please provide a card and list name")
|
raise InvalidToken("Please provide a card and list name")
|
||||||
card_con = Card(self.instance)
|
card_con = Card(self.instance)
|
||||||
card = card_con.get(project_name, board_name, list_name, card_name)
|
card = card_con.get(project_name, board_name, list_name, card_name)
|
||||||
label = self.get(project_name, board_name, label_name)
|
label = self.get(project_name, board_name, label_name)
|
||||||
return super().delete(f"/api/cards/{card['item']['id']}/labels/{label['item']['id']}")
|
return super().delete(
|
||||||
|
f"/api/cards/{card['item']['id']}/labels/{label['item']['id']}"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class Task(Controller):
|
class Task(Controller):
|
||||||
def __init__(self, instance:Planka, **kwargs) -> None:
|
def __init__(self, instance: Planka, **kwargs) -> None:
|
||||||
self.instance = instance
|
self.instance = instance
|
||||||
self.template = instance.get_template("task")
|
self.template = instance.get_template("task")
|
||||||
self.data = self.build(**kwargs)
|
self.data = self.build(**kwargs)
|
||||||
|
|
||||||
def get(self, project_name:str=None, board_name:str=None, list_name:str=None, card_name:str=None, task_name:str=None) -> dict:
|
def get(
|
||||||
|
self,
|
||||||
|
project_name: str = None,
|
||||||
|
board_name: str = None,
|
||||||
|
list_name: str = None,
|
||||||
|
card_name: str = None,
|
||||||
|
task_name: str = None,
|
||||||
|
) -> dict:
|
||||||
"""Gets a task by name
|
"""Gets a task by name
|
||||||
NOTE: No GET route for tasks by OID
|
NOTE: No GET route for tasks by OID
|
||||||
- project_name: Name of project to get task from
|
- project_name: Name of project to get task from
|
||||||
|
@ -606,10 +762,18 @@ class Task(Controller):
|
||||||
raise InvalidToken("Please provide project, board, list, and card names")
|
raise InvalidToken("Please provide project, board, list, and card names")
|
||||||
board_con = Board(self.instance)
|
board_con = Board(self.instance)
|
||||||
board = board_con.get(project_name, board_name)
|
board = board_con.get(project_name, board_name)
|
||||||
list_id = [ls for ls in board["included"]["lists"] if ls["name"] == list_name][0]["id"]
|
list_id = [ls for ls in board["included"]["lists"] if ls["name"] == list_name][
|
||||||
cards = [card for card in board["included"]["cards"] if card["name"] == card_name and card["listId"] == list_id]
|
0
|
||||||
|
]["id"]
|
||||||
|
cards = [
|
||||||
|
card
|
||||||
|
for card in board["included"]["cards"]
|
||||||
|
if card["name"] == card_name and card["listId"] == list_id
|
||||||
|
]
|
||||||
card_id = [card for card in cards if card["name"] == card_name][0]["id"]
|
card_id = [card for card in cards if card["name"] == card_name][0]["id"]
|
||||||
tasks = [task for task in board["included"]["tasks"] if task["cardId"] == card_id]
|
tasks = [
|
||||||
|
task for task in board["included"]["tasks"] if task["cardId"] == card_id
|
||||||
|
]
|
||||||
task_names = [task["name"] for task in tasks]
|
task_names = [task["name"] for task in tasks]
|
||||||
if not task_name:
|
if not task_name:
|
||||||
return tasks
|
return tasks
|
||||||
|
@ -617,7 +781,15 @@ class Task(Controller):
|
||||||
raise InvalidToken(f"Task `{task_name}` not found")
|
raise InvalidToken(f"Task `{task_name}` not found")
|
||||||
return [task for task in tasks if task["name"] == task_name][0]
|
return [task for task in tasks if task["name"] == task_name][0]
|
||||||
|
|
||||||
def create(self, project_name:str=None, board_name:str=None, list_name:str=None, card_name:str=None, data:dict=None, card_id:str=None):
|
def create(
|
||||||
|
self,
|
||||||
|
project_name: str = None,
|
||||||
|
board_name: str = None,
|
||||||
|
list_name: str = None,
|
||||||
|
card_name: str = None,
|
||||||
|
data: dict = None,
|
||||||
|
card_id: str = None,
|
||||||
|
):
|
||||||
"""Creates a new task
|
"""Creates a new task
|
||||||
- card_id: ID of card to create task in (optional)
|
- card_id: ID of card to create task in (optional)
|
||||||
- project_name: Name of project to create task in
|
- project_name: Name of project to create task in
|
||||||
|
@ -636,12 +808,27 @@ class Task(Controller):
|
||||||
raise InvalidToken("Please provide project, board, list, and card names")
|
raise InvalidToken("Please provide project, board, list, and card names")
|
||||||
board_con = Board(self.instance)
|
board_con = Board(self.instance)
|
||||||
board = board_con.get(project_name, board_name)
|
board = board_con.get(project_name, board_name)
|
||||||
list_id = [ls for ls in board["included"]["lists"] if ls["name"] == list_name][0]["id"]
|
list_id = [ls for ls in board["included"]["lists"] if ls["name"] == list_name][
|
||||||
cards = [card for card in board["included"]["cards"] if card["name"] == card_name and card["listId"] == list_id]
|
0
|
||||||
|
]["id"]
|
||||||
|
cards = [
|
||||||
|
card
|
||||||
|
for card in board["included"]["cards"]
|
||||||
|
if card["name"] == card_name and card["listId"] == list_id
|
||||||
|
]
|
||||||
card_id = [card for card in cards if card["name"] == card_name][0]["id"]
|
card_id = [card for card in cards if card["name"] == card_name][0]["id"]
|
||||||
return super().create(f"/api/cards/{card_id}/tasks")
|
return super().create(f"/api/cards/{card_id}/tasks")
|
||||||
|
|
||||||
def update(self, project_name:str=None, board_name:str=None, list_name:str=None, card_name:str=None, task_name:str=None, data:dict=None, oid:str=None):
|
def update(
|
||||||
|
self,
|
||||||
|
project_name: str = None,
|
||||||
|
board_name: str = None,
|
||||||
|
list_name: str = None,
|
||||||
|
card_name: str = None,
|
||||||
|
task_name: str = None,
|
||||||
|
data: dict = None,
|
||||||
|
oid: str = None,
|
||||||
|
):
|
||||||
"""Updates a task
|
"""Updates a task
|
||||||
- oid: Object ID of task to update (optional)
|
- oid: Object ID of task to update (optional)
|
||||||
- project_name: Name of project to update task in
|
- project_name: Name of project to update task in
|
||||||
|
@ -658,11 +845,21 @@ class Task(Controller):
|
||||||
if oid:
|
if oid:
|
||||||
return super().update(f"/api/tasks/{oid}")
|
return super().update(f"/api/tasks/{oid}")
|
||||||
if not (project_name and board_name and list_name and card_name and task_name):
|
if not (project_name and board_name and list_name and card_name and task_name):
|
||||||
raise InvalidToken("Please provide project, board, list, card, and task names")
|
raise InvalidToken(
|
||||||
|
"Please provide project, board, list, card, and task names"
|
||||||
|
)
|
||||||
task = self.get(project_name, board_name, list_name, card_name, task_name)
|
task = self.get(project_name, board_name, list_name, card_name, task_name)
|
||||||
return super().update(f"/api/tasks/{task['id']}")
|
return super().update(f"/api/tasks/{task['id']}")
|
||||||
|
|
||||||
def delete(self, project_name:str=None, board_name:str=None, list_name:str=None, card_name:str=None, task_name:str=None, oid:str=None):
|
def delete(
|
||||||
|
self,
|
||||||
|
project_name: str = None,
|
||||||
|
board_name: str = None,
|
||||||
|
list_name: str = None,
|
||||||
|
card_name: str = None,
|
||||||
|
task_name: str = None,
|
||||||
|
oid: str = None,
|
||||||
|
):
|
||||||
"""Deletes a task
|
"""Deletes a task
|
||||||
- oid: ID of task to delete (Use this if you already have the ID)
|
- oid: ID of task to delete (Use this if you already have the ID)
|
||||||
- project_name: Name of project to delete task from
|
- project_name: Name of project to delete task from
|
||||||
|
@ -675,24 +872,29 @@ class Task(Controller):
|
||||||
if oid:
|
if oid:
|
||||||
return super().delete(f"/api/tasks/{id}")
|
return super().delete(f"/api/tasks/{id}")
|
||||||
if not (project_name and board_name and list_name and card_name and task_name):
|
if not (project_name and board_name and list_name and card_name and task_name):
|
||||||
raise InvalidToken("Please provide project, board, list, card, and task names")
|
raise InvalidToken(
|
||||||
|
"Please provide project, board, list, card, and task names"
|
||||||
|
)
|
||||||
task = self.get(project_name, board_name, list_name, card_name, task_name)
|
task = self.get(project_name, board_name, list_name, card_name, task_name)
|
||||||
return super().delete(f"/api/tasks/{task['id']}")
|
return super().delete(f"/api/tasks/{task['id']}")
|
||||||
|
|
||||||
|
|
||||||
class Attachment(Controller):
|
class Attachment(Controller):
|
||||||
def __init__(self, instance:Planka, **kwargs) -> None:
|
def __init__(self, instance: Planka, **kwargs) -> None:
|
||||||
self.instance = instance
|
self.instance = instance
|
||||||
self.template = instance.get_template("attachment")
|
self.template = instance.get_template("attachment")
|
||||||
self.data = self.build(**kwargs)
|
self.data = self.build(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
class Stopwatch(Controller):
|
class Stopwatch(Controller):
|
||||||
def __init__(self, instance:Planka, **kwargs) -> None:
|
def __init__(self, instance: Planka, **kwargs) -> None:
|
||||||
self.instance = instance
|
self.instance = instance
|
||||||
self.template = instance.get_template("stopwatch")
|
self.template = instance.get_template("stopwatch")
|
||||||
self.data = self.build(**kwargs)
|
self.data = self.build(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
class Background(Controller):
|
class Background(Controller):
|
||||||
def __init__(self, instance:Planka, **kwargs) -> None:
|
def __init__(self, instance: Planka, **kwargs) -> None:
|
||||||
self.instance = instance
|
self.instance = instance
|
||||||
self.template = instance.get_template("background")
|
self.template = instance.get_template("background")
|
||||||
self.options = instance.get_template("gradients")
|
self.options = instance.get_template("gradients")
|
||||||
|
@ -704,7 +906,7 @@ class Background(Controller):
|
||||||
"""
|
"""
|
||||||
return self.options
|
return self.options
|
||||||
|
|
||||||
def apply(self, prj_name:str):
|
def apply(self, prj_name: str):
|
||||||
"""Applies a gradient to a project
|
"""Applies a gradient to a project
|
||||||
- project: Name of project to apply gradient to
|
- project: Name of project to apply gradient to
|
||||||
- **return:** PATCH response dictionary
|
- **return:** PATCH response dictionary
|
||||||
|
@ -714,10 +916,12 @@ class Background(Controller):
|
||||||
if "type" not in self.data.keys():
|
if "type" not in self.data.keys():
|
||||||
raise InvalidToken("Please specify a background type: `gradient` | `image`")
|
raise InvalidToken("Please specify a background type: `gradient` | `image`")
|
||||||
if self.data["type"] == "gradient" and self.data["name"] not in self.options:
|
if self.data["type"] == "gradient" and self.data["name"] not in self.options:
|
||||||
raise InvalidToken(f"Gradient {self.data['name']} not found: please choose from\n{self.options}")
|
raise InvalidToken(
|
||||||
|
f"Gradient {self.data['name']} not found: please choose from\n{self.options}"
|
||||||
|
)
|
||||||
return super().update(f"/api/projects/{prj_id}", data={"background": self.data})
|
return super().update(f"/api/projects/{prj_id}", data={"background": self.data})
|
||||||
|
|
||||||
def clear(self, prj_name:str):
|
def clear(self, prj_name: str):
|
||||||
"""Clears a gradient from a project
|
"""Clears a gradient from a project
|
||||||
- project: Name of project to clear gradient from
|
- project: Name of project to clear gradient from
|
||||||
- **return:** PATCH response dictionary
|
- **return:** PATCH response dictionary
|
||||||
|
@ -726,14 +930,16 @@ class Background(Controller):
|
||||||
prj_id = project.get(prj_name)["item"]["id"]
|
prj_id = project.get(prj_name)["item"]["id"]
|
||||||
return super().update(f"/api/projects/{prj_id}", data={"background": None})
|
return super().update(f"/api/projects/{prj_id}", data={"background": None})
|
||||||
|
|
||||||
|
|
||||||
class Comment(Controller):
|
class Comment(Controller):
|
||||||
def __init__(self, instance:Planka, **kwargs) -> None:
|
def __init__(self, instance: Planka, **kwargs) -> None:
|
||||||
self.instance = instance
|
self.instance = instance
|
||||||
self.template = instance.get_template("comment-action")
|
self.template = instance.get_template("comment-action")
|
||||||
self.data = self.build(**kwargs)
|
self.data = self.build(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
class User(Controller):
|
class User(Controller):
|
||||||
def __init__(self, instance:Planka, **kwargs) -> None:
|
def __init__(self, instance: Planka, **kwargs) -> None:
|
||||||
"""Creates a user
|
"""Creates a user
|
||||||
- username: Username of user to create
|
- username: Username of user to create
|
||||||
- name: Display name of user to create
|
- name: Display name of user to create
|
||||||
|
@ -747,7 +953,7 @@ class User(Controller):
|
||||||
self.template = instance.get_template("user")
|
self.template = instance.get_template("user")
|
||||||
self.data = self.build(**kwargs)
|
self.data = self.build(**kwargs)
|
||||||
|
|
||||||
def get(self, username:str=None):
|
def get(self, username: str = None):
|
||||||
"""Gets a user
|
"""Gets a user
|
||||||
- username: Username of user to get (all if not provided)
|
- username: Username of user to get (all if not provided)
|
||||||
- **return:** GET response dictionary
|
- **return:** GET response dictionary
|
||||||
|
@ -760,7 +966,7 @@ class User(Controller):
|
||||||
raise InvalidToken(f"User {username} not found")
|
raise InvalidToken(f"User {username} not found")
|
||||||
return users[names.index(username)]
|
return users[names.index(username)]
|
||||||
|
|
||||||
def create(self, data:dict=None):
|
def create(self, data: dict = None):
|
||||||
"""Creates a user
|
"""Creates a user
|
||||||
- data: Data dictionary to create user with (optional)
|
- data: Data dictionary to create user with (optional)
|
||||||
- **return:** POST response dictionary
|
- **return:** POST response dictionary
|
||||||
|
@ -768,12 +974,14 @@ class User(Controller):
|
||||||
if not data:
|
if not data:
|
||||||
data = self.data
|
data = self.data
|
||||||
if not data:
|
if not data:
|
||||||
raise InvalidToken("Please either build a user or provide a data dictionary")
|
raise InvalidToken(
|
||||||
|
"Please either build a user or provide a data dictionary"
|
||||||
|
)
|
||||||
if self.data["username"] in [user["username"] for user in self.get()]:
|
if self.data["username"] in [user["username"] for user in self.get()]:
|
||||||
raise InvalidToken(f"User {self.data['username']} already exists")
|
raise InvalidToken(f"User {self.data['username']} already exists")
|
||||||
return super().create("/api/users", data=self.data)
|
return super().create("/api/users", data=self.data)
|
||||||
|
|
||||||
def delete(self, username:str, oid:str=None):
|
def delete(self, username: str, oid: str = None):
|
||||||
"""Deletes a user
|
"""Deletes a user
|
||||||
- username: Username of user to delete
|
- username: Username of user to delete
|
||||||
- oid: ID of user to delete (Use this if you already have the ID)
|
- oid: ID of user to delete (Use this if you already have the ID)
|
||||||
|
@ -785,7 +993,7 @@ class User(Controller):
|
||||||
raise InvalidToken(f"User {username} not found")
|
raise InvalidToken(f"User {username} not found")
|
||||||
return super().delete(f"/api/users/{self.get(username)['id']}")
|
return super().delete(f"/api/users/{self.get(username)['id']}")
|
||||||
|
|
||||||
def update(self, username:str, oid:str=None, data:dict=None):
|
def update(self, username: str, oid: str = None, data: dict = None):
|
||||||
"""Updates a user
|
"""Updates a user
|
||||||
- username: Username of user to update
|
- username: Username of user to update
|
||||||
- oid: ID of user to update (Use this if you already have the ID)
|
- oid: ID of user to update (Use this if you already have the ID)
|
||||||
|
@ -796,10 +1004,13 @@ class User(Controller):
|
||||||
if not data:
|
if not data:
|
||||||
data = self.data
|
data = self.data
|
||||||
if not data:
|
if not data:
|
||||||
raise InvalidToken("Please either build a user or provide a data dictionary")
|
raise InvalidToken(
|
||||||
|
"Please either build a user or provide a data dictionary"
|
||||||
|
)
|
||||||
return super().update(f"/api/users/{user['id']}", data=data)
|
return super().update(f"/api/users/{user['id']}", data=data)
|
||||||
|
|
||||||
|
|
||||||
class InvalidToken(Exception):
|
class InvalidToken(Exception):
|
||||||
"""General Error for invalid API inputs
|
"""General Error for invalid API inputs"""
|
||||||
"""
|
|
||||||
pass
|
pass
|
4
src/plankapy/test_config.py
Normal file
4
src/plankapy/test_config.py
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
API_URL = "http://localhost:3000"
|
||||||
|
API_USER = "demo- demo.demo"
|
||||||
|
API_PASS = "demo"
|
||||||
|
OFFSET = 65535
|
|
@ -7,16 +7,15 @@ API_URL = None
|
||||||
API_USER = None
|
API_USER = None
|
||||||
API_PASS = None
|
API_PASS = None
|
||||||
|
|
||||||
default_tasks = \
|
default_tasks = [
|
||||||
[
|
|
||||||
"LLD",
|
"LLD",
|
||||||
"LLD Invoiced",
|
"LLD Invoiced",
|
||||||
"CD",
|
"CD",
|
||||||
"CD Invoiced",
|
"CD Invoiced",
|
||||||
"PD",
|
"PD",
|
||||||
"PD Invoiced",
|
"PD Invoiced",
|
||||||
"Constructed"
|
"Constructed",
|
||||||
]
|
]
|
||||||
|
|
||||||
prj = input("Project: ")
|
prj = input("Project: ")
|
||||||
brd = input("Board: ")
|
brd = input("Board: ")
|
||||||
|
@ -27,7 +26,9 @@ phase = input("Phase: ")
|
||||||
fdas = input("FDAs (comma seperated or - for range): ")
|
fdas = input("FDAs (comma seperated or - for range): ")
|
||||||
stage = input("Stage (HLD | LLD | PD | CD) enter to match board: ")
|
stage = input("Stage (HLD | LLD | PD | CD) enter to match board: ")
|
||||||
labels = input("Labels (comma seperated) enter to match board: ")
|
labels = input("Labels (comma seperated) enter to match board: ")
|
||||||
print("Default Tasks: HLD, HLD Invoiced, LLD, LLD Invoiced, CD, CD Invoiced, PD, PD Invoiced, Constructed")
|
print(
|
||||||
|
"Default Tasks: HLD, HLD Invoiced, LLD, LLD Invoiced, CD, CD Invoiced, PD, PD Invoiced, Constructed"
|
||||||
|
)
|
||||||
tasks = input("Tasks (comma seperated) enter for default: ")
|
tasks = input("Tasks (comma seperated) enter for default: ")
|
||||||
print(f"cards will be created in\n\t{prj} \n\t |-> {brd} \n\t |-> {lst}")
|
print(f"cards will be created in\n\t{prj} \n\t |-> {brd} \n\t |-> {lst}")
|
||||||
|
|
||||||
|
@ -38,7 +39,7 @@ else:
|
||||||
|
|
||||||
if fdas.__contains__("-"):
|
if fdas.__contains__("-"):
|
||||||
fdas = fdas.split("-")
|
fdas = fdas.split("-")
|
||||||
fdas = list(range(int(fdas[0]), int(fdas[1])+1))
|
fdas = list(range(int(fdas[0]), int(fdas[1]) + 1))
|
||||||
else:
|
else:
|
||||||
fdas = fdas.split(",")
|
fdas = fdas.split(",")
|
||||||
|
|
||||||
|
@ -55,5 +56,15 @@ desc = f"|Billable Footage | Stage | City |\n| -------- | -------- | -------- |\
|
||||||
instance = Planka(API_URL, API_USER, API_PASS)
|
instance = Planka(API_URL, API_USER, API_PASS)
|
||||||
next_pos = OFFSET
|
next_pos = OFFSET
|
||||||
for fda in fdas:
|
for fda in fdas:
|
||||||
build_card(instance, project=prj, board=brd, list=lst, name=f"{mkt} {phase}.{fda}", description=desc, tasks=tasks, labels=labels, position=next_pos)
|
build_card(
|
||||||
|
instance,
|
||||||
|
project=prj,
|
||||||
|
board=brd,
|
||||||
|
list=lst,
|
||||||
|
name=f"{mkt} {phase}.{fda}",
|
||||||
|
description=desc,
|
||||||
|
tasks=tasks,
|
||||||
|
labels=labels,
|
||||||
|
position=next_pos,
|
||||||
|
)
|
||||||
next_pos += OFFSET
|
next_pos += OFFSET
|
|
@ -1,6 +1,9 @@
|
||||||
from plankapy import *
|
from plankapy import *
|
||||||
|
from plankapy.test_config import *
|
||||||
|
|
||||||
import random
|
import random
|
||||||
|
|
||||||
|
|
||||||
def test_planka():
|
def test_planka():
|
||||||
## In no way meant to be efficient code, just a way to test all components
|
## In no way meant to be efficient code, just a way to test all components
|
||||||
## of the API
|
## of the API
|
||||||
|
@ -20,13 +23,12 @@ def test_planka():
|
||||||
if "Plankapy Test Project" in [prj["name"] for prj in project.get()["items"]]:
|
if "Plankapy Test Project" in [prj["name"] for prj in project.get()["items"]]:
|
||||||
project.delete("Plankapy Test Project")
|
project.delete("Plankapy Test Project")
|
||||||
|
|
||||||
|
|
||||||
project.build(name="Plankapy Test Project")
|
project.build(name="Plankapy Test Project")
|
||||||
project.create()
|
project.create()
|
||||||
print("Created Test Project")
|
print("Created Test Project")
|
||||||
|
|
||||||
next_pos = OFFSET
|
next_pos = OFFSET
|
||||||
for i in range(1,5):
|
for i in range(1, 5):
|
||||||
board.build(name=f"Test Board {i}", type="kanban", position=next_pos)
|
board.build(name=f"Test Board {i}", type="kanban", position=next_pos)
|
||||||
board.create("Plankapy Test Project")
|
board.create("Plankapy Test Project")
|
||||||
next_pos += OFFSET
|
next_pos += OFFSET
|
||||||
|
@ -34,59 +36,65 @@ def test_planka():
|
||||||
|
|
||||||
new_labels = {}
|
new_labels = {}
|
||||||
for b in board.get("Plankapy Test Project"):
|
for b in board.get("Plankapy Test Project"):
|
||||||
new_labels[b['name']] = []
|
new_labels[b["name"]] = []
|
||||||
next_pos = OFFSET
|
next_pos = OFFSET
|
||||||
for color in label.colors():
|
for color in label.colors():
|
||||||
label.build(name=f"{color} label", color=color, position=next_pos)
|
label.build(name=f"{color} label", color=color, position=next_pos)
|
||||||
new_labels[b['name']].append(label.create("Plankapy Test Project", b["name"])["item"])
|
new_labels[b["name"]].append(
|
||||||
|
label.create("Plankapy Test Project", b["name"])["item"]
|
||||||
|
)
|
||||||
next_pos += OFFSET
|
next_pos += OFFSET
|
||||||
print(f"Created {color} Label for Board {b['name']}")
|
print(f"Created {color} Label for Board {b['name']}")
|
||||||
|
|
||||||
new_lists = {}
|
new_lists = {}
|
||||||
for b in board.get("Plankapy Test Project"):
|
for b in board.get("Plankapy Test Project"):
|
||||||
new_lists[b['name']] = []
|
new_lists[b["name"]] = []
|
||||||
next_pos = OFFSET
|
next_pos = OFFSET
|
||||||
for i in range(1,5):
|
for i in range(1, 5):
|
||||||
lst.build(name=f"Test List {i}", position=next_pos)
|
lst.build(name=f"Test List {i}", position=next_pos)
|
||||||
new_lists[b['name']].append(lst.create("Plankapy Test Project", b["name"]))
|
new_lists[b["name"]].append(lst.create("Plankapy Test Project", b["name"]))
|
||||||
next_pos += OFFSET
|
next_pos += OFFSET
|
||||||
print(f"Created Test List {i} for Board {b['name']}")
|
print(f"Created Test List {i} for Board {b['name']}")
|
||||||
|
|
||||||
new_cards={}
|
new_cards = {}
|
||||||
for b in board.get("Plankapy Test Project"):
|
for b in board.get("Plankapy Test Project"):
|
||||||
new_cards[b['name']] = []
|
new_cards[b["name"]] = []
|
||||||
next_pos = OFFSET
|
next_pos = OFFSET
|
||||||
for i in range(1, 11):
|
for i in range(1, 11):
|
||||||
card.build(name=f"Test Card {i}", description=f"CHANGE ME {i}", position=next_pos)
|
card.build(
|
||||||
|
name=f"Test Card {i}", description=f"CHANGE ME {i}", position=next_pos
|
||||||
|
)
|
||||||
next_pos += OFFSET
|
next_pos += OFFSET
|
||||||
new_cards[b['name']].append(card.create("Plankapy Test Project", b['name'], "Test List 1")["item"])
|
new_cards[b["name"]].append(
|
||||||
|
card.create("Plankapy Test Project", b["name"], "Test List 1")["item"]
|
||||||
|
)
|
||||||
print(f"Created Test Card {i} for Board {b['name']} in Test List 1")
|
print(f"Created Test Card {i} for Board {b['name']} in Test List 1")
|
||||||
|
|
||||||
for b in board.get("Plankapy Test Project"):
|
for b in board.get("Plankapy Test Project"):
|
||||||
for cd in new_cards[b['name']]:
|
for cd in new_cards[b["name"]]:
|
||||||
lb = random.choice(new_labels[b['name']])
|
lb = random.choice(new_labels[b["name"]])
|
||||||
label.add(label_id=lb["id"], card_id=cd["id"])
|
label.add(label_id=lb["id"], card_id=cd["id"])
|
||||||
print(f"added random labels to cards in board {b['name']}")
|
print(f"added random labels to cards in board {b['name']}")
|
||||||
for _ in range(len(new_cards[b['name']]) // 2):
|
for _ in range(len(new_cards[b["name"]]) // 2):
|
||||||
cd = random.choice(new_cards[b['name']])
|
cd = random.choice(new_cards[b["name"]])
|
||||||
lbs = card.get_labels("Plankapy Test Project", b["name"], oid=cd["id"])
|
lbs = card.get_labels("Plankapy Test Project", b["name"], oid=cd["id"])
|
||||||
for lb in lbs:
|
for lb in lbs:
|
||||||
label.remove(label_id=lb["labelId"], card_id=lb["cardId"])
|
label.remove(label_id=lb["labelId"], card_id=lb["cardId"])
|
||||||
print(f"removed label from {cd['name']}")
|
print(f"removed label from {cd['name']}")
|
||||||
print(f"removed random labels from half the cards in {b['name']}")
|
print(f"removed random labels from half the cards in {b['name']}")
|
||||||
|
|
||||||
new_tasks={}
|
new_tasks = {}
|
||||||
for b in board.get("Plankapy Test Project"):
|
for b in board.get("Plankapy Test Project"):
|
||||||
new_tasks[b['name']] = []
|
new_tasks[b["name"]] = []
|
||||||
for cd in new_cards[b['name']]:
|
for cd in new_cards[b["name"]]:
|
||||||
next_pos=OFFSET
|
next_pos = OFFSET
|
||||||
for i in range(1,5):
|
for i in range(1, 5):
|
||||||
task.build(name=f"Test Task {i}", position=next_pos)
|
task.build(name=f"Test Task {i}", position=next_pos)
|
||||||
next_pos += OFFSET
|
next_pos += OFFSET
|
||||||
new_tasks[b['name']].append(task.create(card_id=cd["id"])["item"])
|
new_tasks[b["name"]].append(task.create(card_id=cd["id"])["item"])
|
||||||
print(f"Created 4 tasks on {cd['name']}")
|
print(f"Created 4 tasks on {cd['name']}")
|
||||||
for b in board.get("Plankapy Test Project"):
|
for b in board.get("Plankapy Test Project"):
|
||||||
for tsk in new_tasks[b['name']]:
|
for tsk in new_tasks[b["name"]]:
|
||||||
task.build(name=f"Updated Task: {tsk['name']}", isCompleted=True)
|
task.build(name=f"Updated Task: {tsk['name']}", isCompleted=True)
|
||||||
task.update(oid=tsk["id"])
|
task.update(oid=tsk["id"])
|
||||||
print("Updated task all tasks")
|
print("Updated task all tasks")
|
||||||
|
@ -103,5 +111,6 @@ def test_planka():
|
||||||
print(f"Username: {us['username']}\nEmail: {us['email']}")
|
print(f"Username: {us['username']}\nEmail: {us['email']}")
|
||||||
print("Tests complete")
|
print("Tests complete")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
test_planka()
|
test_planka()
|
Loading…
Reference in a new issue