Files
nextcloud-deck-tools/list_stacks.py
2025-09-11 23:31:07 +03:00

91 lines
2.6 KiB
Python

#!/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()