fpaste: add --all flag and expiry countdown to list

This commit is contained in:
Username
2025-12-21 21:43:48 +01:00
parent 40873434c3
commit 3fe631f6b9

48
fpaste
View File

@@ -10,6 +10,7 @@ import json
import os import os
import ssl import ssl
import sys import sys
import time
import urllib.error import urllib.error
import urllib.request import urllib.request
from datetime import UTC, datetime, timedelta 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") 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: def parse_date(date_str: str) -> int:
"""Parse date string to Unix timestamp.""" """Parse date string to Unix timestamp."""
if not date_str: if not date_str:
@@ -359,22 +382,27 @@ def get_extension_for_mime(mime_type: str) -> str:
return MIME_EXTENSIONS.get(mime_type, ".bin") 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.""" """Format a paste as a table row."""
paste_id = paste["id"] paste_id = paste["id"]
mime_type = paste.get("mime_type", "unknown")[:16] mime_type = paste.get("mime_type", "unknown")[:16]
size = format_size(paste.get("size", 0)) size = format_size(paste.get("size", 0))
created = format_timestamp(paste.get("created_at", 0)) created = format_timestamp(paste.get("created_at", 0))
# Time remaining until expiry
expires = format_time_remaining(paste.get("expires_at"))
flags = [] flags = []
if paste.get("burn_after_read"): if paste.get("burn_after_read"):
flags.append("burn") flags.append("burn")
if paste.get("password_protected"): if paste.get("password_protected"):
flags.append("pass") 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( def print_paste_list(
@@ -392,9 +420,14 @@ def print_paste_list(
print("no pastes found") print("no pastes found")
return 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: for paste in pastes:
print(format_paste_row(paste)) print(format_paste_row(paste, show_owner=show_owner))
print(f"\n{summary}") print(f"\n{summary}")
@@ -653,6 +686,8 @@ def cmd_list(args: argparse.Namespace, config: dict[str, Any]) -> None:
require_auth(config) require_auth(config)
params = [] params = []
if getattr(args, "all", False):
params.append("all=1")
if args.limit: if args.limit:
params.append(f"limit={args.limit}") params.append(f"limit={args.limit}")
if args.offset: if args.offset:
@@ -1258,6 +1293,7 @@ def build_parser() -> argparse.ArgumentParser:
# list # list
p_list = subparsers.add_parser("list", aliases=["ls"], help="list your pastes") 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("-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("-o", "--offset", type=int, metavar="N", help="skip first N pastes")
p_list.add_argument("--json", action="store_true", help="output as JSON") p_list.add_argument("--json", action="store_true", help="output as JSON")