codekingpro/portable-devtools
114k
1"""Parsing and processing of CLI input (args, auth credentials, files, stdin).2 3"""4import enum5import re6 7 8URL_SCHEME_RE = re.compile(r'^[a-z][a-z0-9.+-]*://', re.IGNORECASE)9 10HTTP_POST = 'POST'11HTTP_GET = 'GET'12HTTP_OPTIONS = 'OPTIONS'13 14# Various separators used in args15SEPARATOR_HEADER = ':'16SEPARATOR_HEADER_EMPTY = ';'17SEPARATOR_CREDENTIALS = ':'18SEPARATOR_PROXY = ':'19SEPARATOR_HEADER_EMBED = ':@'20SEPARATOR_DATA_STRING = '='21SEPARATOR_DATA_RAW_JSON = ':='22SEPARATOR_FILE_UPLOAD = '@'23SEPARATOR_FILE_UPLOAD_TYPE = ';type=' # in already parsed file upload path only24SEPARATOR_DATA_EMBED_FILE_CONTENTS = '=@'25SEPARATOR_DATA_EMBED_RAW_JSON_FILE = ':=@'26SEPARATOR_QUERY_PARAM = '=='27SEPARATOR_QUERY_EMBED_FILE = '==@'28 29# Separators that become request data30SEPARATOR_GROUP_DATA_ITEMS = frozenset({31 SEPARATOR_DATA_STRING,32 SEPARATOR_DATA_RAW_JSON,33 SEPARATOR_FILE_UPLOAD,34 SEPARATOR_DATA_EMBED_FILE_CONTENTS,35 SEPARATOR_DATA_EMBED_RAW_JSON_FILE36})37 38SEPARATORS_GROUP_MULTIPART = frozenset({39 SEPARATOR_DATA_STRING,40 SEPARATOR_DATA_EMBED_FILE_CONTENTS,41 SEPARATOR_FILE_UPLOAD,42})43 44# Separators for items whose value is a filename to be embedded45SEPARATOR_GROUP_DATA_EMBED_ITEMS = frozenset({46 SEPARATOR_HEADER_EMBED,47 SEPARATOR_QUERY_EMBED_FILE,48 SEPARATOR_DATA_EMBED_FILE_CONTENTS,49 SEPARATOR_DATA_EMBED_RAW_JSON_FILE,50})51 52# Separators for nested JSON items53SEPARATOR_GROUP_NESTED_JSON_ITEMS = frozenset([54 SEPARATOR_DATA_STRING,55 SEPARATOR_DATA_RAW_JSON,56 SEPARATOR_DATA_EMBED_FILE_CONTENTS,57 SEPARATOR_DATA_EMBED_RAW_JSON_FILE,58])59 60# Separators allowed in ITEM arguments61SEPARATOR_GROUP_ALL_ITEMS = frozenset({62 SEPARATOR_HEADER,63 SEPARATOR_HEADER_EMPTY,64 SEPARATOR_HEADER_EMBED,65 SEPARATOR_QUERY_PARAM,66 SEPARATOR_QUERY_EMBED_FILE,67 SEPARATOR_DATA_STRING,68 SEPARATOR_DATA_RAW_JSON,69 SEPARATOR_FILE_UPLOAD,70 SEPARATOR_DATA_EMBED_FILE_CONTENTS,71 SEPARATOR_DATA_EMBED_RAW_JSON_FILE,72})73 74# Output options75OUT_REQ_HEAD = 'H'76OUT_REQ_BODY = 'B'77OUT_RESP_HEAD = 'h'78OUT_RESP_BODY = 'b'79OUT_RESP_META = 'm'80 81BASE_OUTPUT_OPTIONS = frozenset({82 OUT_REQ_HEAD,83 OUT_REQ_BODY,84 OUT_RESP_HEAD,85 OUT_RESP_BODY,86})87 88OUTPUT_OPTIONS = frozenset({89 *BASE_OUTPUT_OPTIONS,90 OUT_RESP_META,91})92 93# Pretty94 95 96class PrettyOptions(enum.Enum):97 STDOUT_TTY_ONLY = enum.auto()98 99 100PRETTY_MAP = {101 'all': ['format', 'colors'],102 'colors': ['colors'],103 'format': ['format'],104 'none': []105}106PRETTY_STDOUT_TTY_ONLY = PrettyOptions.STDOUT_TTY_ONLY107 108 109DEFAULT_FORMAT_OPTIONS = [110 'headers.sort:true',111 'json.format:true',112 'json.indent:4',113 'json.sort_keys:true',114 'xml.format:true',115 'xml.indent:2',116]117SORTED_FORMAT_OPTIONS = [118 'headers.sort:true',119 'json.sort_keys:true',120]121SORTED_FORMAT_OPTIONS_STRING = ','.join(SORTED_FORMAT_OPTIONS)122UNSORTED_FORMAT_OPTIONS_STRING = ','.join(123 option.replace('true', 'false') for option in SORTED_FORMAT_OPTIONS)124 125# Defaults126OUTPUT_OPTIONS_DEFAULT = OUT_RESP_HEAD + OUT_RESP_BODY127OUTPUT_OPTIONS_DEFAULT_STDOUT_REDIRECTED = OUT_RESP_BODY128OUTPUT_OPTIONS_DEFAULT_OFFLINE = OUT_REQ_HEAD + OUT_REQ_BODY129 130 131class RequestType(enum.Enum):132 FORM = enum.auto()133 MULTIPART = enum.auto()134 JSON = enum.auto()135 