fpaste: add --all flag and expiry countdown to list
This commit is contained in:
48
fpaste
48
fpaste
@@ -10,6 +10,7 @@ import json
|
||||
import os
|
||||
import ssl
|
||||
import sys
|
||||
import time
|
||||
import urllib.error
|
||||
import urllib.request
|
||||
from datetime import UTC, datetime, timedelta
|
||||
@@ -336,6 +337,28 @@ def format_timestamp(ts: int | float) -> str:
|
||||
return dt.strftime("%Y-%m-%d %H:%M")
|
||||
|
||||
|
||||
def format_time_remaining(expires_at: int | float | None) -> str:
|
||||
"""Format time remaining until expiry."""
|
||||
if not expires_at:
|
||||
return ""
|
||||
now = time.time()
|
||||
remaining = expires_at - now
|
||||
if remaining <= 0:
|
||||
return "expired"
|
||||
if remaining < 60:
|
||||
return f"{int(remaining)}s"
|
||||
if remaining < 3600:
|
||||
return f"{int(remaining / 60)}m"
|
||||
if remaining < 86400:
|
||||
hours = int(remaining / 3600)
|
||||
return f"{hours}h"
|
||||
days = int(remaining / 86400)
|
||||
if days >= 365:
|
||||
years = days // 365
|
||||
return f"{years}y"
|
||||
return f"{days}d"
|
||||
|
||||
|
||||
def parse_date(date_str: str) -> int:
|
||||
"""Parse date string to Unix timestamp."""
|
||||
if not date_str:
|
||||
@@ -359,22 +382,27 @@ def get_extension_for_mime(mime_type: str) -> str:
|
||||
return MIME_EXTENSIONS.get(mime_type, ".bin")
|
||||
|
||||
|
||||
def format_paste_row(paste: dict[str, Any]) -> str:
|
||||
def format_paste_row(paste: dict[str, Any], show_owner: bool = False) -> str:
|
||||
"""Format a paste as a table row."""
|
||||
paste_id = paste["id"]
|
||||
mime_type = paste.get("mime_type", "unknown")[:16]
|
||||
size = format_size(paste.get("size", 0))
|
||||
created = format_timestamp(paste.get("created_at", 0))
|
||||
|
||||
# Time remaining until expiry
|
||||
expires = format_time_remaining(paste.get("expires_at"))
|
||||
|
||||
flags = []
|
||||
if paste.get("burn_after_read"):
|
||||
flags.append("burn")
|
||||
if paste.get("password_protected"):
|
||||
flags.append("pass")
|
||||
if paste.get("expires_at"):
|
||||
flags.append("exp")
|
||||
|
||||
return f"{paste_id:<12} {mime_type:<16} {size:>6} {created:<16} {' '.join(flags)}"
|
||||
flags_str = " ".join(flags)
|
||||
row = f"{paste_id:<12} {mime_type:<16} {size:>6} {created:<16} {expires:<8} {flags_str}"
|
||||
if show_owner and paste.get("owner"):
|
||||
row += f" {paste['owner'][:12]}"
|
||||
return row
|
||||
|
||||
|
||||
def print_paste_list(
|
||||
@@ -392,9 +420,14 @@ def print_paste_list(
|
||||
print("no pastes found")
|
||||
return
|
||||
|
||||
print(f"{'ID':<12} {'TYPE':<16} {'SIZE':>6} {'CREATED':<16} FLAGS")
|
||||
# Check if owner data is present (admin view)
|
||||
show_owner = any(paste.get("owner") for paste in pastes)
|
||||
header = f"{'ID':<12} {'TYPE':<16} {'SIZE':>6} {'CREATED':<16} {'EXPIRES':<8} FLAGS"
|
||||
if show_owner:
|
||||
header += " OWNER"
|
||||
print(header)
|
||||
for paste in pastes:
|
||||
print(format_paste_row(paste))
|
||||
print(format_paste_row(paste, show_owner=show_owner))
|
||||
print(f"\n{summary}")
|
||||
|
||||
|
||||
@@ -653,6 +686,8 @@ def cmd_list(args: argparse.Namespace, config: dict[str, Any]) -> None:
|
||||
require_auth(config)
|
||||
|
||||
params = []
|
||||
if getattr(args, "all", False):
|
||||
params.append("all=1")
|
||||
if args.limit:
|
||||
params.append(f"limit={args.limit}")
|
||||
if args.offset:
|
||||
@@ -1258,6 +1293,7 @@ def build_parser() -> argparse.ArgumentParser:
|
||||
|
||||
# list
|
||||
p_list = subparsers.add_parser("list", aliases=["ls"], help="list your pastes")
|
||||
p_list.add_argument("-a", "--all", action="store_true", help="list all pastes (admin only)")
|
||||
p_list.add_argument("-l", "--limit", type=int, metavar="N", help="max pastes (default: 50)")
|
||||
p_list.add_argument("-o", "--offset", type=int, metavar="N", help="skip first N pastes")
|
||||
p_list.add_argument("--json", action="store_true", help="output as JSON")
|
||||
|
||||
Reference in New Issue
Block a user