mirror of
https://github.com/chenasraf/nextcloud-deck-tools.git
synced 2026-05-17 17:28:07 +00:00
feat: initial commit
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
poetry.lock
|
||||
92
import.py
Normal file
92
import.py
Normal file
@@ -0,0 +1,92 @@
|
||||
#!/usr/bin/env python3
|
||||
import csv
|
||||
import requests
|
||||
import json
|
||||
import argparse
|
||||
import getpass
|
||||
|
||||
|
||||
def create_card(session, domain, board_id, stack_id, title, description):
|
||||
url = f"https://{domain}/index.php/apps/deck/api/v1.0/boards/{board_id}/stacks/{stack_id}/cards"
|
||||
headers = {"OCS-APIRequest": "true", "Content-Type": "application/json"}
|
||||
payload = {
|
||||
"title": title,
|
||||
"type": "plain",
|
||||
"order": 0,
|
||||
"description": description,
|
||||
"duedate": None,
|
||||
}
|
||||
|
||||
response = session.post(url, headers=headers, data=json.dumps(payload))
|
||||
return response
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Import tasks from a CSV file into Nextcloud Deck"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--domain",
|
||||
required=True,
|
||||
help="Nextcloud instance domain (e.g., example.com or https://example.com)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--board-id",
|
||||
required=True,
|
||||
type=int,
|
||||
help="Board ID where the cards will be created",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--stack-id",
|
||||
required=True,
|
||||
type=int,
|
||||
help="Stack ID where the cards will be added",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--csv-file", required=True, help="Path to the CSV file containing tasks"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--username", help="Nextcloud username (if not provided, will be prompted)"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--password",
|
||||
help="Nextcloud password or app password (if not provided, will be prompted)",
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Prompt for credentials if missing
|
||||
username = args.username or input("Nextcloud username: ")
|
||||
password = args.password or getpass.getpass(
|
||||
"Nextcloud password (or app password): "
|
||||
)
|
||||
|
||||
session = requests.Session()
|
||||
session.auth = (username, password)
|
||||
|
||||
with open(args.csv_file, newline="", encoding="utf-8") as csvfile:
|
||||
reader = csv.DictReader(csvfile)
|
||||
|
||||
for row in reader:
|
||||
title = row.get("title", "").strip()
|
||||
description = row.get("description", "").strip()
|
||||
|
||||
if not title:
|
||||
print(f"Skipping row with missing title: {row}")
|
||||
continue
|
||||
|
||||
response = create_card(
|
||||
session, args.domain, args.board_id, args.stack_id, title, description
|
||||
)
|
||||
|
||||
if response.status_code in (200, 201):
|
||||
print(f"✔️ Successfully created card: {title}")
|
||||
else:
|
||||
print(
|
||||
f"❌ Failed to create card: {title} - Error: {response.status_code} {response.text}"
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
90
list_stacks.py
Normal file
90
list_stacks.py
Normal file
@@ -0,0 +1,90 @@
|
||||
#!/usr/bin/env python3
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
import requests
|
||||
from urllib.parse import urlparse
|
||||
import getpass
|
||||
|
||||
|
||||
def normalize_base_url(domain_or_url: str) -> str:
|
||||
parsed = urlparse(domain_or_url)
|
||||
if parsed.scheme in ("http", "https"):
|
||||
return domain_or_url.rstrip("/")
|
||||
return f"https://{domain_or_url.strip().strip('/')}"
|
||||
|
||||
|
||||
def list_stacks(session: requests.Session, base_url: str, board_id: int):
|
||||
url = f"{base_url}/index.php/apps/deck/api/v1.0/boards/{board_id}/stacks"
|
||||
headers = {"OCS-APIRequest": "true", "Accept": "application/json"}
|
||||
resp = session.get(url, headers=headers)
|
||||
if resp.status_code != 200:
|
||||
raise RuntimeError(f"Deck API error: {resp.status_code} {resp.text}")
|
||||
return resp.json()
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="List stacks (id + name) for a Nextcloud Deck board."
|
||||
)
|
||||
parser.add_argument(
|
||||
"--domain",
|
||||
required=True,
|
||||
help="Nextcloud instance (e.g., example.com or https://example.com)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--board-id", required=True, type=int, help="Deck Board ID to list stacks from"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--username", help="Nextcloud username (if not provided, will be prompted)"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--password",
|
||||
help="Nextcloud password or app password (if not provided, will be prompted)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--json", action="store_true", help="Output raw JSON instead of a table"
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Prompt for missing creds
|
||||
username = args.username or input("Nextcloud username: ")
|
||||
password = args.password or getpass.getpass(
|
||||
"Nextcloud password (or app password): "
|
||||
)
|
||||
|
||||
base_url = normalize_base_url(args.domain)
|
||||
|
||||
session = requests.Session()
|
||||
session.auth = (username, password)
|
||||
|
||||
try:
|
||||
stacks = list_stacks(session, base_url, args.board_id)
|
||||
except Exception as e:
|
||||
print(f"❌ Failed to fetch stacks: {e}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
if args.json:
|
||||
print(json.dumps(stacks, ensure_ascii=False, indent=2))
|
||||
return
|
||||
|
||||
if not stacks:
|
||||
print("No stacks found.")
|
||||
return
|
||||
|
||||
print(f"Stacks for board {args.board_id} at {base_url}:")
|
||||
print("-" * 60)
|
||||
print(f"{'ID':<8} {'NAME'}")
|
||||
print("-" * 60)
|
||||
for s in stacks:
|
||||
sid = s.get("id")
|
||||
title = s.get("title", "")
|
||||
print(f"{str(sid):<8} {title}")
|
||||
print("-" * 60)
|
||||
print("Tip: use the ID in your importer script's --stack-id.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
17
pyproject.toml
Normal file
17
pyproject.toml
Normal file
@@ -0,0 +1,17 @@
|
||||
[project]
|
||||
name = "nextcloud-deck-tools"
|
||||
version = "0.1.0"
|
||||
description = ""
|
||||
authors = [
|
||||
{name = "Chen Asraf",email = "casraf@pm.me"}
|
||||
]
|
||||
readme = "README.md"
|
||||
requires-python = "^3.11"
|
||||
dependencies = [
|
||||
"requests (>=2.32.5,<3.0.0)"
|
||||
]
|
||||
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core>=2.0.0,<3.0.0"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
Reference in New Issue
Block a user