Initial commit

This commit is contained in:
Zhongwei Li
2025-11-30 08:49:56 +08:00
commit a250e458a9
14 changed files with 1221 additions and 0 deletions

View File

@@ -0,0 +1,48 @@
#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.11"
# dependencies = [
# "httpx",
# "typer",
# ]
# ///
"""Delete a document from the document sync server."""
import typer
from pathlib import Path
import json
import sys
# Add lib directory to path for imports
sys.path.insert(0, str(Path(__file__).parent / "lib"))
from config import Config
from client import DocumentClient
app = typer.Typer(add_completion=False)
@app.command()
def main(
document_id: str = typer.Argument(..., help="ID of the document to delete"),
):
"""Delete a document from the document sync server."""
try:
# Create client and delete document
config = Config()
client = DocumentClient(config)
result = client.delete_document(document_id)
# Output success result as JSON
print(json.dumps(result, indent=2))
except Exception as e:
# Output error as JSON to stderr
error = {"error": str(e)}
print(json.dumps(error), file=sys.stderr)
raise typer.Exit(1)
if __name__ == "__main__":
app()

View File

@@ -0,0 +1,48 @@
#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.11"
# dependencies = [
# "httpx",
# "typer",
# ]
# ///
"""Retrieve metadata for a document from the document sync server."""
import typer
from pathlib import Path
import json
import sys
# Add lib directory to path for imports
sys.path.insert(0, str(Path(__file__).parent / "lib"))
from config import Config
from client import DocumentClient
app = typer.Typer(add_completion=False)
@app.command()
def main(
document_id: str = typer.Argument(..., help="Document ID to retrieve metadata for"),
):
"""Retrieve metadata for a document without downloading the file."""
try:
# Create client and get document info
config = Config()
client = DocumentClient(config)
result = client.get_document_info(document_id)
# Output metadata as JSON
print(json.dumps(result, indent=2))
except Exception as e:
# Output error as JSON to stderr
error = {"error": str(e)}
print(json.dumps(error), file=sys.stderr)
raise typer.Exit(1)
if __name__ == "__main__":
app()

View File

@@ -0,0 +1,61 @@
#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.11"
# dependencies = [
# "httpx",
# "typer",
# ]
# ///
"""Download a document from the document sync server."""
import typer
from pathlib import Path
import json
import sys
# Add lib directory to path for imports
sys.path.insert(0, str(Path(__file__).parent / "lib"))
from config import Config
from client import DocumentClient
app = typer.Typer(add_completion=False)
@app.command()
def main(
document_id: str = typer.Argument(..., help="ID of the document to download"),
output: str = typer.Option(None, "--output", "-o", help="Output file path (defaults to original filename)"),
):
"""Download a document from the document sync server."""
try:
# Create client and pull document
config = Config()
client = DocumentClient(config)
content, filename = client.pull_document(document_id)
# Determine output path
output_path = Path(output) if output else Path(filename)
# Write content to file
output_path.write_bytes(content)
# Output success message as JSON
result = {
"success": True,
"document_id": document_id,
"filename": str(output_path),
"size_bytes": len(content)
}
print(json.dumps(result, indent=2))
except Exception as e:
# Output error as JSON to stderr
error = {"error": str(e)}
print(json.dumps(error), file=sys.stderr)
raise typer.Exit(1)
if __name__ == "__main__":
app()

View File

@@ -0,0 +1,68 @@
#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.11"
# dependencies = [
# "httpx",
# "typer",
# ]
# ///
"""Upload a document to the document sync server."""
import typer
from pathlib import Path
import json
import sys
# Add lib directory to path for imports
sys.path.insert(0, str(Path(__file__).parent / "lib"))
from config import Config
from client import DocumentClient
app = typer.Typer(add_completion=False)
@app.command()
def main(
file_path: str = typer.Argument(..., help="Path to the file to upload"),
name: str = typer.Option(None, "--name", help="Custom name for the document (defaults to filename)"),
tags: str = typer.Option(None, "--tags", help="Comma-separated list of tags"),
description: str = typer.Option(None, "--description", help="Description of the document"),
):
"""Upload a document to the document sync server."""
try:
# Validate file exists
path = Path(file_path)
if not path.exists():
error = {"error": f"File not found: {file_path}"}
print(json.dumps(error), file=sys.stderr)
raise typer.Exit(1)
# Parse tags from comma-separated string
parsed_tags = None
if tags:
parsed_tags = [tag.strip() for tag in tags.split(",") if tag.strip()]
# Create client and push document
config = Config()
client = DocumentClient(config)
result = client.push_document(
file_path=path,
name=name,
tags=parsed_tags,
description=description
)
# Output success result as JSON
print(json.dumps(result, indent=2))
except Exception as e:
# Output error as JSON to stderr
error = {"error": str(e)}
print(json.dumps(error), file=sys.stderr)
raise typer.Exit(1)
if __name__ == "__main__":
app()

View File

@@ -0,0 +1,59 @@
#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.11"
# dependencies = [
# "httpx",
# "typer",
# ]
# ///
"""Query documents from the document sync server."""
import typer
from pathlib import Path
import json
import sys
# Add lib directory to path for imports
sys.path.insert(0, str(Path(__file__).parent / "lib"))
from config import Config
from client import DocumentClient
app = typer.Typer(add_completion=False)
@app.command()
def main(
name: str = typer.Option(None, "--name", help="Filter by filename pattern"),
tags: str = typer.Option(None, "--tags", help="Comma-separated list of tags (AND logic)"),
limit: int = typer.Option(None, "--limit", help="Maximum number of results"),
):
"""Query documents from the document sync server."""
try:
# Parse tags from comma-separated string
parsed_tags = None
if tags:
parsed_tags = [tag.strip() for tag in tags.split(",") if tag.strip()]
# Create client and query documents
config = Config()
client = DocumentClient(config)
results = client.query_documents(
name=name,
tags=parsed_tags,
limit=limit
)
# Output results as JSON array
print(json.dumps(results, indent=2))
except Exception as e:
# Output error as JSON to stderr
error = {"error": str(e)}
print(json.dumps(error), file=sys.stderr)
raise typer.Exit(1)
if __name__ == "__main__":
app()

View File

@@ -0,0 +1,48 @@
#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.11"
# dependencies = [
# "httpx",
# "typer",
# ]
# ///
"""Read text document content from the document sync server."""
import typer
from pathlib import Path
import json
import sys
# Add lib directory to path for imports
sys.path.insert(0, str(Path(__file__).parent / "lib"))
from config import Config
from client import DocumentClient
app = typer.Typer(add_completion=False)
@app.command()
def main(
document_id: str = typer.Argument(..., help="Document ID to read content from"),
):
"""Read text document content directly to stdout (text files only)."""
try:
# Create client and read document
config = Config()
client = DocumentClient(config)
content = client.read_document(document_id)
# Output raw content to stdout (no JSON wrapper)
print(content, end="")
except Exception as e:
# Output error as JSON to stderr
error = {"error": str(e)}
print(json.dumps(error), file=sys.stderr)
raise typer.Exit(1)
if __name__ == "__main__":
app()