diff options
-rw-r--r-- | pypaste/client/__init__.py | 10 | ||||
-rw-r--r-- | pypaste/client/__main__.py | 84 | ||||
-rw-r--r-- | pypaste/client/plugins/__init__.py | 7 | ||||
-rw-r--r-- | pypaste/client/plugins/pgz/__init__.py | 17 | ||||
-rw-r--r-- | pypaste/client/plugins/zen/__init__.py | 19 |
5 files changed, 91 insertions, 46 deletions
diff --git a/pypaste/client/__init__.py b/pypaste/client/__init__.py index 0456110..6c57e29 100644 --- a/pypaste/client/__init__.py +++ b/pypaste/client/__init__.py @@ -1,10 +1,14 @@ -from typing import Protocol, List, Optional +from argparse import ArgumentParser +from typing import Protocol, Dict, List class PasteService(Protocol): - def paste(self, text: str, syntax: Optional[str], raw: bool) -> str: + def args(self, argparser: ArgumentParser): pass - def supported_syntaxes(self) -> List[str]: + def paste(self, text: str, opts: Dict[str, str]) -> str: + pass + + def syntaxes(self) -> List[str]: pass diff --git a/pypaste/client/__main__.py b/pypaste/client/__main__.py index 441c3f2..d424603 100644 --- a/pypaste/client/__main__.py +++ b/pypaste/client/__main__.py @@ -1,8 +1,11 @@ import sys import pkgutil +import subprocess +import shlex import pypaste.client.plugins as plugins from importlib import import_module from argparse import ArgumentParser +from pathlib import Path def register_services(): @@ -13,61 +16,80 @@ def register_services(): def main() -> int: - parser = ArgumentParser() - subparsers = parser.add_subparsers(dest="command") + parser = ArgumentParser(prog="pypaste") + subparsers = parser.add_subparsers(dest="action") _ = subparsers.add_parser("list-services") list_syntaxes_parser = subparsers.add_parser("list-syntaxes") list_syntaxes_parser.add_argument("service") - paste_parser = subparsers.add_parser("paste") - paste_parser.add_argument("service") - paste_parser.add_argument("--syntax") - paste_parser.add_argument("--raw") + register_services() - args = parser.parse_args() + for name, service in plugins.services.items(): + subparser = subparsers.add_parser(name) + subparser.add_argument("--command") + subparser.add_argument("--file", type=Path) + service.args(subparser) - register_services() + args = parser.parse_args() - match args.command: + match args.action: case "list-services": - for service in plugins.services.keys(): - print(service) + for name in plugins.services.keys(): + print(name, file=sys.stderr) return 0 case "list-syntaxes": - service = plugins.services[args.service]() + try: + service = plugins.services[args.service] + except KeyError: + print(f"{args.service} is not a registered service", file=sys.stderr) + return 1 - for syntax in service.supported_syntaxes(): - print(syntax) + for s in service.syntaxes(): + print(s, file=sys.stderr) return 0 - case "paste": - service = plugins.services[args.service]() - - if ( - syntax := args.syntax - ) is not None and syntax not in service.supported_syntaxes(): - print( - f"{syntax} is not supported for service {args.service}", - file=sys.stderr, - ) - return 1 + case str(name): + service = plugins.services[name] try: - text = sys.stdin.read() - except UnicodeError: - print("failed to decode stdin", file=sys.stderr) + syntax = vars(args)["syntax"] + except KeyError: + syntax = None + pass + + if syntax is not None and syntax not in service.syntaxes(): + print(f"unsupported syntax for {name}: {syntax}", file=sys.stderr) return 1 + if (file := args.file) is not None: + if file == "-": + try: + text = sys.stdin.read() + except Exception as e: + print(f"failed to read from stdin: {e}") + return 1 + else: + try: + text = file.read_text() + except Exception as e: + print(f"failed to read {file}: {e}") + elif (command := args.command) is not None: + cmd = shlex.split(command, posix=True) + proc = subprocess.run(cmd, capture_output=True, text=True, shell=True) + text = f"# {command}\n{proc.stdout}" + else: + return 0 + try: - url = service.paste(text, syntax, args.raw) + output = service.paste(text, vars(args)) except Exception as e: - print(e, file=sys.stderr) + print(f"failed to paste to {name}: {e}", file=sys.stderr) return 1 - print(url) + print(output) return 0 diff --git a/pypaste/client/plugins/__init__.py b/pypaste/client/plugins/__init__.py index 79e9d50..c7238bd 100644 --- a/pypaste/client/plugins/__init__.py +++ b/pypaste/client/plugins/__init__.py @@ -1,9 +1,12 @@ -services = {} +from typing import Dict +from pypaste.client import PasteService + +services: Dict[str, PasteService] = {} def register_service(name): def register(plugin): - services[name] = plugin + services[name] = plugin() return register diff --git a/pypaste/client/plugins/pgz/__init__.py b/pypaste/client/plugins/pgz/__init__.py index 834ae96..d7c2d78 100644 --- a/pypaste/client/plugins/pgz/__init__.py +++ b/pypaste/client/plugins/pgz/__init__.py @@ -1,7 +1,8 @@ import io import requests +from argparse import ArgumentParser from pypaste.client.plugins import register_service -from typing import Optional, List +from typing import Optional, List, Dict URL: str = "https://paste.gentoo.zip" @@ -9,8 +10,16 @@ URL: str = "https://paste.gentoo.zip" @register_service("pgz") class Pgz: - def paste(self, text: str, syntax: Optional[str], raw: bool) -> str: - files = {"file": ("pypaste-upload", io.StringIO(text), "multipart/form-data")} + def args(self, parser: ArgumentParser) -> None: + pass + + def paste(self, text: str, opts: Dict[str, str]) -> str: + try: + filename = opts["filename"] + except KeyError: + filename = "pypaste-upload.txt" + + files = {"file": (filename, io.StringIO(text), "multipart/form-data")} req = requests.post(URL, files=files) @@ -19,5 +28,5 @@ class Pgz: return req.text.strip() - def supported_syntaxes(self) -> List[str]: + def syntaxes(self) -> List[str]: return [] diff --git a/pypaste/client/plugins/zen/__init__.py b/pypaste/client/plugins/zen/__init__.py index 53a4673..6ba5aa0 100644 --- a/pypaste/client/plugins/zen/__init__.py +++ b/pypaste/client/plugins/zen/__init__.py @@ -1,6 +1,7 @@ import requests +from argparse import ArgumentParser from pypaste.client.plugins import register_service -from typing import Optional, List +from typing import Dict, List SYNTAXES = [ "ABAP", @@ -613,13 +614,19 @@ URL: str = "https://zen.jturnerusa.dev/paste" @register_service("zen") class Zen: - def paste(self, text: str, syntax: Optional[str], raw: bool) -> str: + def args(self, parser: ArgumentParser) -> None: + parser.add_argument("--syntax") + parser.add_argument("--raw") + + def paste(self, text: str, opts: Dict[str, str]) -> str: params = {} - if syntax is not None: - params["syntax"] = syntax + try: + params["syntax"] = opts["syntax"] + except KeyError: + pass - if raw: + if "raw" in opts.keys(): params["raw"] = "true" req = requests.post(URL, params=params, data=text) @@ -631,5 +638,5 @@ class Zen: return req.text - def supported_syntaxes(self) -> List[str]: + def syntaxes(self) -> List[str]: return SYNTAXES |