Gitlab Community Edition Instance

Commit df61c5a0 authored by Marcel Hellkamp's avatar Marcel Hellkamp
Browse files

Refactoring and typos

parent 29a9ab91
......@@ -3,7 +3,7 @@ import os
import requests
from requests_toolbelt import MultipartEncoder
__all__ = ("CDStar", "PostUpdate")
__all__ = ("CDStar", "FormUpdate", "ApiError")
class CDStar:
......
"""
CDSTAR command-line client
"""
import argparse
import configparser
import importlib
import json
import os
import re
import sys
from ..cdstar import ApiError
from pycdstar import __version__ as VERSION
from pycdstar.cdstar import ApiError
from pycdstar.cli._utils import Printer
from pycdstar.cli.commands import BUILDIN_COMMANDS
from pycdstar.cli.context import CliContext
__ALL__ = ["main", "register_subcommand", "printer"]
__ALL__ = ["main", "printer"]
#: Commands to load automatically. The module pycdstar.cli.NAME must have register() defined.
BUILDIN_COMMANDS = {"init", "put", "get", "acl"}
parser = argparse.ArgumentParser(description='CDSTAR command-line client')
parser.add_argument("-C", default=".", help="Change the current working directory before executing the command")
parser.add_argument("-c", "--config", help="Path to config file (default: find automatically)")
parser = argparse.ArgumentParser(prog="pycdstar")
parser.add_argument("-C", metavar="DIR", default=".",
help="Change the current working directory before executing the command")
parser.add_argument("-c", "--config", metavar="FILE",
help="Path to config file (default: find automatically)")
parser.add_argument("--version", action="store_true", help="Print version and exit")
_grp = parser.add_mutually_exclusive_group()
_grp.add_argument("-v", "--verbose", action="count", default=0,
help="Print more info. Repeat to increase verbosity")
_grp.add_argument("-q", "--quiet", action="store_true", help="Be quiet. Only print errors.")
subparsers = parser.add_subparsers(help='sub-command help')
def register_subcommand(name, aliases=None, help=None, description=None):
""" Register a sub-command and return an argparse parser for command-specific parameters. """
return subparsers.add_parser(name, aliases=aliases or [], help=help, description=description)
class Printer:
""" Helper class to print to stderr based on verbosity levels."""
__slots__ = ("verbosity", "quiet", "file")
def __init__(self, level=0, file=sys.stderr):
self.verbosity = level
self.quiet = level <= -1
self.file = file
set_verbosity = __init__
def _print(self, msg, *args, **kwargs):
hr = kwargs.pop("highlight", None)
indent = kwargs.pop("indent", 0)
if args:
msg = msg.format(*args)
if indent:
msg = ''.join(' '*indent + line for line in msg.splitlines(True))
if hr:
ncols = self._ncols()
msg = (hr*ncols) + '\n' + msg + ('' if msg.endswith('\n') else '\n') + (hr*ncols)
print(msg, file=self.file, **kwargs)
def _ncols(self):
import shutil
return shutil.get_terminal_size((40, 20))[0]
def __call__(self, msg, *args, **kwargs):
""" Print only if -q (--quiet) was NOT passed as a command-line parameter """
if self.verbosity >= 0:
self._print(msg, *args, **kwargs)
def v(self, msg, *args, **kwargs):
""" Print only if -v was passed as a command-line parameter """
if self.verbosity >= 1:
self._print(msg, *args, **kwargs)
def vv(self, msg, *args, **kwargs):
""" Print only if -vv was passed as a command-line parameter """
if self.verbosity >= 2:
self._print(msg, *args, **kwargs)
def vvv(self, msg, *args, **kwargs):
""" Print only if -vvv was passed as a command-line parameter """
if self.verbosity >= 3:
self._print(msg, *args, **kwargs)
def error(self, msg, *args, **kwargs):
""" Print an error message (if not quiet) and optionally (-vv or higher) a stacktrace."""
self._print("ERROR: " + msg, *args, **kwargs)
if self.verbosity >= 2:
import traceback
self._print(traceback.format_exc(), highlight="=")
def fatal(self, msg, *args, **kwargs):
""" Print an error message (even if quiet) and optionally (-vv or higher) a stacktrace."""
self._print("FATAL: " + msg, *args, **kwargs)
if self.verbosity >= 2:
import traceback
self._print(traceback.format_exc(), highlight="=")
else:
self("Stacktrace not shown. Add -vv to print a full stacktrace.")
subparsers = parser.add_subparsers(title="available commands",
description='Run "COMAMND -h" to get help for a specific command.',
metavar="COMMAND")
#: This should be used to print optional messages to the user.
#: Messages are printed to stderr, so only use it for complementary information, not for the primary results.
......@@ -99,11 +37,15 @@ printer = Printer(level=0, file=sys.stderr)
def main(args=None):
# Load and register all built-in commands
for name in BUILDIN_COMMANDS:
importlib.import_module(".commands."+name, __name__).register()
importlib.import_module(".commands." + name, __name__).register(subparsers)
# Parse command line arguments (may fail)
opts = parser.parse_args(args)
if opts.version:
print("pycdstar-" + VERSION)
sys.exit(0)
# Set root logging level based on verbosity setting
if opts.quiet:
printer.set_verbosity(-1)
......@@ -147,5 +89,3 @@ class CliError(Exception):
def __init__(self, *args, status=1):
super().__init__(*args)
self.return_code = status
from .context import CliContext
......@@ -58,3 +58,67 @@ class FileProgress:
yield chunk
pbar.close()
class Printer:
""" Helper class to print to stderr based on verbosity levels."""
__slots__ = ("verbosity", "quiet", "file")
def __init__(self, level=0, file=sys.stderr):
self.verbosity = level
self.quiet = level <= -1
self.file = file
set_verbosity = __init__
def _print(self, msg, *args, **kwargs):
hr = kwargs.pop("highlight", None)
indent = kwargs.pop("indent", 0)
if args:
msg = msg.format(*args)
if indent:
msg = ''.join(' ' * indent + line for line in msg.splitlines(True))
if hr:
ncols = self._ncols()
msg = (hr * ncols) + '\n' + msg + ('' if msg.endswith('\n') else '\n') + (hr * ncols)
print(msg, file=self.file, **kwargs)
def _ncols(self):
import shutil
return shutil.get_terminal_size((40, 20))[0]
def __call__(self, msg, *args, **kwargs):
""" Print only if -q (--quiet) was NOT passed as a command-line parameter """
if self.verbosity >= 0:
self._print(msg, *args, **kwargs)
def v(self, msg, *args, **kwargs):
""" Print only if -v was passed as a command-line parameter """
if self.verbosity >= 1:
self._print(msg, *args, **kwargs)
def vv(self, msg, *args, **kwargs):
""" Print only if -vv was passed as a command-line parameter """
if self.verbosity >= 2:
self._print(msg, *args, **kwargs)
def vvv(self, msg, *args, **kwargs):
""" Print only if -vvv was passed as a command-line parameter """
if self.verbosity >= 3:
self._print(msg, *args, **kwargs)
def error(self, msg, *args, **kwargs):
""" Print an error message (if not quiet) and optionally (-vv or higher) a stacktrace."""
self._print("ERROR: " + msg, *args, **kwargs)
if self.verbosity >= 2:
import traceback
self._print(traceback.format_exc(), highlight="=")
def fatal(self, msg, *args, **kwargs):
""" Print an error message (even if quiet) and optionally (-vv or higher) a stacktrace."""
self._print("FATAL: " + msg, *args, **kwargs)
if self.verbosity >= 2:
import traceback
self._print(traceback.format_exc(), highlight="=")
else:
self("Stacktrace not shown. Add -vv to print a full stacktrace.")
#: Commands to load automatically. The module pycdstar.cli.NAME must have register(subparsers) defined.
BUILDIN_COMMANDS = ["init", "put", "get", "acl"]
......@@ -4,11 +4,11 @@ Manage access control lists (ACL)
import os
from ...cdstar import FormUpdate
from .. import register_subcommand, printer, CliError
from .. import printer, CliError
def register():
parser = register_subcommand("acl", help=__doc__.splitlines()[0], description=__doc__)
def register(subparsers):
parser = subparsers.add_parser("acl", help=__doc__.strip().splitlines()[0], description=__doc__)
sub = parser.add_subparsers()
pset = sub.add_parser("set")
......
"""
Get (download) a single file from an archive
Get (download) a single file from an archive.
"""
import os
import sys
from .._utils import hbytes
from .. import register_subcommand, printer, CliError
from .. import printer, CliError
def register():
parser = register_subcommand("get", help=__doc__.splitlines()[0], description=__doc__)
def register(subparsers):
parser = subparsers.add_parser("get", help=__doc__.strip().splitlines()[0], description=__doc__)
parser.add_argument("-%", "-p", "--progress", action="store_true",
help="Show progress bar for large files or slow downloads")
parser.add_argument("--resume", action="store_true",
help="If a <DST>.part file exists, try to resume an interrupted download."
help="If a <DST>.part file exists, try to resume an interrupted download. "
"Also, keep the *.part file on any errors.")
parser.add_argument("-f", "--force", action="store_true", help="Overwrite existing files without asking")
parser.add_argument("-f", "--force", action="store_true", help="Overwrite local files without asking")
parser.add_argument("SRC", help="File identifier")
parser.add_argument("DST", nargs="?", help="Destination filename, directory or '-' for stdout. (default '-')")
parser.add_argument("DST", nargs="?", help="Destination filename, directory or '-' for stdout. (default: '-')")
parser.set_defaults(main=get)
......
......@@ -2,9 +2,9 @@
Initialize a cdstar working directory.
Create a config file in the current directory, so it can be found by future invocations of cdstar-cli commands.
Settings nor provided as command line arguments ar asked for interactively.
Settings not provided as command line arguments are asked for interactively.
If the main --config parameter is set, the configuration is saved at the specified location,
If the main --config parameter is set, the configuration is saved at the specified location
instead of the current working directory.
"""
......@@ -12,12 +12,12 @@ import configparser
import os
import re
from .. import register_subcommand, printer
from .. import printer
from ..context import CONFIG_NAMES
def register():
parser = register_subcommand("init", help=__doc__.splitlines()[0], description=__doc__)
def register(subparsers):
parser = subparsers.add_parser("init", help=__doc__.strip().splitlines()[0], description=__doc__)
parser.add_argument("--server", help="CDSTAR server URI (usually ends in '/v3')")
parser.add_argument("--vault", help="Name of the default vault")
grp = parser.add_mutually_exclusive_group()
......@@ -27,18 +27,6 @@ def register():
def command(ctx, args):
def ask(q, default=None, rx=None):
while True:
val = input("{}? [{}] ".format(q, default) if default else "{}? ".format(q)).strip()
if not val:
if default:
return default
print("No input. Try again...")
continue
if rx and not re.match(rx, val):
print("This does not look right. Try again...")
continue
return val
target = os.path.abspath(args.config or CONFIG_NAMES[0])
if os.path.exists(target):
......@@ -51,18 +39,34 @@ def command(ctx, args):
elif args.auth:
auth = ("basic", args.auth)
else:
if ask("Auth method (basic or token)", "basic", r"^(basic|token)$") == "basic":
auth = ("basic", ask("Username") + ":" + ask("Password"))
method = ask("Auth method (basic or token)", "basic", r"^(basic|token)$");
if method == "basic":
auth = (method, ask("Username") + ":" + ask("Password"))
else:
auth = (method, ask("Token"))
config = configparser.ConfigParser()
config["DEFAULT"]["server"] = server
config["DEFAULT"]["vault"] = vault
config["DEFAULT"]["auth"] = ':'.join(auth)
if auth:
config["DEFAULT"]["auth"] = ':'.join(auth)
with open(target, 'w') as fp:
with open(target, 'x') as fp:
fp.write("# cdstar-cli config. See https://cdstar.gwdg.de/\n")
config.write(fp)
printer("Okay!")
printer("")
printer("Config file written to: {}", target)
def ask(q, default=None, rx=None):
while True:
val = input("{}? [{}] ".format(q, default) if default else "{}? ".format(q)).strip()
if not val:
if default:
return default
print("No input. Try again...")
continue
if rx and not re.match(rx, val):
print("This does not look right. Try again...")
continue
return val
\ No newline at end of file
......@@ -3,12 +3,12 @@ Upload one or more files to an existing archive.
"""
import os
from .. import register_subcommand, printer, CliError
from .. import printer, CliError
from .._utils import compile_glob, hbytes
def register():
parser = register_subcommand("put", help=__doc__.splitlines()[0], description=__doc__)
def register(subparsers):
parser = subparsers.add_parser("put", help=__doc__.strip().splitlines()[0], description=__doc__)
parser.add_argument("-a", "--all", action="store_true", help="Include hidden files (skipped by default)")
parser.add_argument("-n", "--dry-run", action="store_true",
help="Do not upload anything, just print what would have been uploaded")
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment