Browse Source

json output for send command (closes #39)

Signed-off-by: R4SAS <r4sas@i2pmail.org>
master
R4SAS 3 months ago
parent
commit
88ea07dba2
Signed by: r4sas
GPG Key ID: 66F6C87B98EBCFE2
  1. 1
      README.md
  2. 3
      README.rst
  3. 129
      pbincli/actions.py
  4. 14
      pbincli/api.py
  5. 16
      pbincli/cli.py
  6. 1
      requirements.txt

1
README.md

@ -62,6 +62,7 @@ proxy=http://127.0.0.1:3128
| auth_user | None | Basic authorization username | | auth_user | None | Basic authorization username |
| auth_pass | None | Basic authorization password | | auth_pass | None | Basic authorization password |
| auth_custom | None | Custom authorization headers in JSON format, like `{'Authorization': 'Bearer token'}` | | auth_custom | None | Custom authorization headers in JSON format, like `{'Authorization': 'Bearer token'}` |
| json | False | Print sending result in JSON format |
# Usage # Usage

3
README.rst

@ -128,6 +128,9 @@ List of OPTIONS available
* - auth_custom * - auth_custom
- None - None
- Custom authorization headers in JSON format, like ``{'Authorization': 'Bearer token'}`` - Custom authorization headers in JSON format, like ``{'Authorization': 'Bearer token'}``
* - json
- False
- Print sending result in JSON format
Usage Usage

129
pbincli/actions.py

@ -21,20 +21,20 @@ def send(args, api_client, settings=None):
if args.text: if args.text:
text = args.text text = args.text
elif args.stdin: elif args.stdin:
print("Reading text from stdin…") if not args.json: print("Reading text from stdin…")
text = args.stdin.read() text = args.stdin.read()
elif not args.file: elif not args.file:
PBinCLIError("Nothing to send!") PBinCLIError("Nothing to send!")
else: else:
text = "" text = ""
print("Preparing paste…") if not args.json: print("Preparing paste…")
paste = Paste(args.debug) paste = Paste(args.debug)
if args.verbose: print("Used server: {}".format(api_client.getServer())) if args.verbose: print("Used server: {}".format(api_client.getServer()))
# get from server supported paste format version and update object # get from server supported paste format version and update object
if args.verbose: print("Getting supported paste format version from server…") if args.debug: print("Getting supported paste format version from server…")
version = api_client.getVersion() version = api_client.getVersion()
paste.setVersion(version) paste.setVersion(version)
@ -61,15 +61,17 @@ def send(args, api_client, settings=None):
discussion = settings['discus'], discussion = settings['discus'],
expiration = settings['expire']) expiration = settings['expire'])
if args.verbose: print("Sending request to server…") if args.verbose: print("Preparing request to server…")
request = paste.getJSON() request = paste.getJSON()
if args.debug: print("Passphrase:\t{}\nRequest:\t{}".format(paste.getHash(), request)) if args.debug: print("Passphrase:\t{}\nRequest:\t{}".format(paste.getHash(), request))
# If we use dry option, exit now # If we use dry option, exit now
if args.dry: sys.exit(0) if args.dry:
if not args.json: print("Dry mode: paste will not be uploaded. Exiting…")
sys.exit(0)
print("Uploading paste…") if not args.json: print("Uploading paste…")
result = api_client.post(request) result = api_client.post(request)
if args.debug: print("Response:\t{}\n".format(result)) if args.debug: print("Response:\t{}\n".format(result))
@ -78,47 +80,92 @@ def send(args, api_client, settings=None):
if not result['status']: # return code is zero if not result['status']: # return code is zero
passphrase = paste.getHash() passphrase = paste.getHash()
# Paste information if args.json: # JSON output
print("Paste uploaded!\nPasteID:\t{}\nPassword:\t{}\nDelete token:\t{}".format( response = {
result['id'], 'status': result['status'],
passphrase, 'result': {
result['deletetoken'])) 'id': result['id'],
'password': passphrase,
# Paste link 'deletetoken': result['deletetoken'],
print("\nLink:\t\t{}?{}#{}".format( 'link': "{}?{}#{}".format(
settings['server'], settings['server'],
result['id'], result['id'],
passphrase)) passphrase),
'deletelink': "{}?pasteid={}&deletetoken={}".format(
# Paste deletion link settings['server'],
print("Delete Link:\t{}?pasteid={}&deletetoken={}".format( result['id'],
settings['server'], result['deletetoken']),
result['id'], }
result['deletetoken'])) }
# Print links to mirrors if present if settings['mirrors']:
if settings['mirrors']: urls = settings['mirrors'].split(',')
print("\nMirrors:") mirrors = []
urls = settings['mirrors'].split(',') for x in urls:
for x in urls: mirrors.append("{}?{}#{}".format(
print("\t\t{}?{}#{}".format( validate_url_ending(x),
validate_url_ending(x), result['id'],
result['id'], passphrase)
passphrase)) )
response['result']['mirrors'] = mirrors
if settings['short']:
try:
response['result']['short'] = shortener.getlink("{}?{}#{}".format(
settings['server'],
result['id'],
passphrase))
except Exception as ex:
response['result']['short_error'] = ex
print(json_encode(response))
sys.exit(0)
else:
# Paste information
print("Paste uploaded!\nPasteID:\t{}\nPassword:\t{}\nDelete token:\t{}".format(
result['id'],
passphrase,
result['deletetoken']))
# Paste link
print("\nLink:\t\t{}?{}#{}".format(
settings['server'],
result['id'],
passphrase))
# Paste deletion link
print("Delete Link:\t{}?pasteid={}&deletetoken={}".format(
settings['server'],
result['id'],
result['deletetoken']))
# Print links to mirrors if present
if settings['mirrors']:
print("\nMirrors:")
urls = settings['mirrors'].split(',')
for x in urls:
print("\t\t{}?{}#{}".format(
validate_url_ending(x),
result['id'],
passphrase))
if settings['short']:
print("\nQuerying URL shortening service…")
try:
link = shortener.getlink("{}?{}#{}".format(
settings['server'],
result['id'],
passphrase))
print("Short Link:\t{}".format(link))
except Exception as ex:
PBinCLIError("Something went wrong…\nError:\t\t{}".format(ex))
sys.exit(0)
elif result['status']: # return code is other then zero elif result['status']: # return code is other then zero
PBinCLIError("Something went wrong…\nError:\t\t{}".format(result['message'])) PBinCLIError("Something went wrong…\nError:\t\t{}".format(result['message']))
else: # or here no status field in response or it is empty else: # or here no status field in response or it is empty
PBinCLIError("Something went wrong…\nError: Empty response.") PBinCLIError("Something went wrong…\nError: Empty response.")
if settings['short']:
print("\nQuerying URL shortening service…")
shortener.getlink("{}?{}#{}".format(
settings['server'],
result['id'],
passphrase))
def get(args, api_client, settings=None): def get(args, api_client, settings=None):
parseduri, isuri = uri_validator(args.pasteinfo) parseduri, isuri = uri_validator(args.pasteinfo)

14
pbincli/api.py

@ -167,7 +167,7 @@ class Shortener:
'custom': self._custom 'custom': self._custom
} }
# run function selected by choosen API # run function selected by choosen API
servicesList[self.api](url) return servicesList[self.api](url)
def _yourls(self,url): def _yourls(self,url):
@ -196,7 +196,7 @@ class Shortener:
if not 'shorturl' in response: if not 'shorturl' in response:
PBinCLIError("YOURLS: Unknown error: {}".format(response['message'])) PBinCLIError("YOURLS: Unknown error: {}".format(response['message']))
else: else:
print("Short Link:\t{}".format(response['shorturl'])) return response['shorturl']
else: else:
PBinCLIError("YOURLS: No status, statusCode or message fields in response! Received:\n{}".format(response)) PBinCLIError("YOURLS: No status, statusCode or message fields in response! Received:\n{}".format(response))
@ -208,7 +208,7 @@ class Shortener:
result = self.session.post( result = self.session.post(
url = "https://clck.ru/--", url = "https://clck.ru/--",
data = request) data = request)
print("Short Link:\t{}".format(result.text)) return result.text
except Exception as ex: except Exception as ex:
PBinCLIError("clck.ru: unexcepted behavior: {}".format(ex)) PBinCLIError("clck.ru: unexcepted behavior: {}".format(ex))
@ -220,7 +220,7 @@ class Shortener:
result = self.session.post( result = self.session.post(
url = "https://tinyurl.com/api-create.php", url = "https://tinyurl.com/api-create.php",
data = request) data = request)
print("Short Link:\t{}".format(result.text)) return result.text
except Exception as ex: except Exception as ex:
PBinCLIError("TinyURL: unexcepted behavior: {}".format(ex)) PBinCLIError("TinyURL: unexcepted behavior: {}".format(ex))
@ -242,7 +242,7 @@ class Shortener:
response = result.json() response = result.json()
if 'shorturl' in response: if 'shorturl' in response:
print("Short Link:\t{}".format(response['shorturl'])) return response['shorturl']
else: else:
PBinCLIError("{}: got error {} from API: {}".format( PBinCLIError("{}: got error {} from API: {}".format(
"is.gd" if self.api == 'isgd' else 'v.gd', "is.gd" if self.api == 'isgd' else 'v.gd',
@ -265,7 +265,7 @@ class Shortener:
result = self.session.post( result = self.session.post(
url = "https://cutt.ly/scripts/shortenUrl.php", url = "https://cutt.ly/scripts/shortenUrl.php",
data = request) data = request)
print("Short Link:\t{}".format(result.text)) return result.text
except Exception as ex: except Exception as ex:
PBinCLIError("cutt.ly: unexcepted behavior: {}".format(ex)) PBinCLIError("cutt.ly: unexcepted behavior: {}".format(ex))
@ -281,6 +281,6 @@ class Shortener:
try: try:
result = self.session.get( result = self.session.get(
url = rUrl) url = rUrl)
print("Short Link:\t{}".format(result.text)) return result.text
except Exception as ex: except Exception as ex:
PBinCLIError("Shorter: unexcepted behavior: {}".format(ex)) PBinCLIError("Shorter: unexcepted behavior: {}".format(ex))

16
pbincli/cli.py

@ -90,7 +90,8 @@ def main():
## ##
send_parser.add_argument("-L", "--mirrors", default=argparse.SUPPRESS, help="Comma-separated list of mirrors of service with scheme (default: None)") send_parser.add_argument("-L", "--mirrors", default=argparse.SUPPRESS, help="Comma-separated list of mirrors of service with scheme (default: None)")
send_parser.add_argument("-v", "--verbose", default=False, action="store_true", help="Enable verbose output") send_parser.add_argument("-v", "--verbose", default=False, action="store_true", help="Enable verbose output")
send_parser.add_argument("-d", "--debug", default=False, action="store_true", help="Enable debug output") send_parser.add_argument("-d", "--debug", default=False, action="store_true", help="Enable debug output. Includes verbose output")
send_parser.add_argument("--json", default=False, action="store_true", help="Print result in JSON format")
send_parser.add_argument("--dry", default=False, action="store_true", help="Invoke dry run") send_parser.add_argument("--dry", default=False, action="store_true", help="Invoke dry run")
send_parser.add_argument("stdin", help="Input paste text from stdin", nargs="?", type=argparse.FileType("r"), default=sys.stdin) send_parser.add_argument("stdin", help="Input paste text from stdin", nargs="?", type=argparse.FileType("r"), default=sys.stdin)
send_parser.set_defaults(func=pbincli.actions.send) send_parser.set_defaults(func=pbincli.actions.send)
@ -114,7 +115,8 @@ def main():
get_parser.add_argument("--auth-custom", default=argparse.SUPPRESS, help="Custom authorization header in JSON format") get_parser.add_argument("--auth-custom", default=argparse.SUPPRESS, help="Custom authorization header in JSON format")
## ##
get_parser.add_argument("-v", "--verbose", default=False, action="store_true", help="Enable verbose output") get_parser.add_argument("-v", "--verbose", default=False, action="store_true", help="Enable verbose output")
get_parser.add_argument("-d", "--debug", default=False, action="store_true", help="Enable debug output") get_parser.add_argument("-d", "--debug", default=False, action="store_true", help="Enable debug output. Includes verbose output")
get_parser.add_argument("--json", default=False, action="store_true", help="Print result in JSON format")
get_parser.set_defaults(func=pbincli.actions.get) get_parser.set_defaults(func=pbincli.actions.get)
# a delete command # a delete command
@ -133,7 +135,8 @@ def main():
delete_parser.add_argument("--auth-custom", default=argparse.SUPPRESS, help="Custom authorization header in JSON format") delete_parser.add_argument("--auth-custom", default=argparse.SUPPRESS, help="Custom authorization header in JSON format")
## ##
delete_parser.add_argument("-v", "--verbose", default=False, action="store_true", help="Enable verbose output") delete_parser.add_argument("-v", "--verbose", default=False, action="store_true", help="Enable verbose output")
delete_parser.add_argument("-d", "--debug", default=False, action="store_true", help="Enable debug output") delete_parser.add_argument("-d", "--debug", default=False, action="store_true", help="Enable debug output. Includes verbose output")
delete_parser.add_argument("--json", default=False, action="store_true", help="Print result in JSON format")
delete_parser.set_defaults(func=pbincli.actions.delete) delete_parser.set_defaults(func=pbincli.actions.delete)
# Add argcomplete trigger # Add argcomplete trigger
@ -164,7 +167,8 @@ def main():
'auth': None, 'auth': None,
'auth_user': None, 'auth_user': None,
'auth_pass': None, 'auth_pass': None,
'auth_custom': None 'auth_custom': None,
'json': False
} }
# Configuration preference order: # Configuration preference order:
@ -191,7 +195,9 @@ def main():
# Re-validate PrivateBin instance URL # Re-validate PrivateBin instance URL
CONFIG['server'] = validate_url_ending(CONFIG['server']) CONFIG['server'] = validate_url_ending(CONFIG['server'])
if args.debug: print("Whole configuration:\n{}\n".format(CONFIG)) if args.debug:
print("Whole configuration:\n{}\n".format(CONFIG))
args.verbose = True
api_client = PrivateBin(CONFIG) api_client = PrivateBin(CONFIG)
if hasattr(args, "func"): if hasattr(args, "func"):

1
requirements.txt

@ -3,3 +3,4 @@ sjcl
base58 base58
requests requests
argcomplete argcomplete
pysocks
Loading…
Cancel
Save