Skip to content

Commit 7e4a138

Browse files
committed
Add program arguments and new features.
See `hastebin --help` for a complete list of options. This update was made to align hastebin with it's brother, sprunge (https://github.com/kevr/sprunge). Signed-off-by: Kevin Morris <kevr@0cost.org>
1 parent 1e8eb19 commit 7e4a138

File tree

1 file changed

+73
-23
lines changed

1 file changed

+73
-23
lines changed

hastebin

Lines changed: 73 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,107 @@
11
#!/usr/bin/env python3
22
# Project: hastebin
3-
# Author: kevr <kevin.morris@codestruct.net>
3+
# Author: Kevin Morris <kevr@0cost.org>
44
# Description: A tool which uploads data from stdin to hastebin.com
5-
# Copyright (C) 2017 Kevin Morris
5+
# Copyright (C) 2017 Kevin Morris <kevr@0cost.org>
66
# Copyright (C) 2020 Denis Zheleztsov <difrex@lessmore.pw>
7-
87
import sys
98
import os
109
import requests
1110
import json
1211
from select import select
12+
import argparse
13+
from subprocess import Popen
1314

14-
15-
# Hastebin server url
1615
url = os.environ.get("HASTEBIN_SERVER_URL", "https://hastebin.com")
17-
# Connection timeout
1816
timeout = int(os.environ.get("HASTEBIN_SERVER_TIMEOUT", 5))
1917

20-
2118
def has_data(fd):
2219
"""Immediately timed out select poll"""
2320
return select([fd], [], [], 0.0) == ([fd], [], [])
2421

25-
2622
def quit(code, msg):
2723
"""Print message to the STDERR and returns exit code"""
2824
sys.stderr.write(msg + "\n")
2925
return code
3026

27+
def get_paste(id):
28+
paste_url = f"{url}/raw/{id}"
29+
response = requests.get(paste_url, timeout=timeout)
3130

32-
## Sorry for the C-style functions, I prefer them
33-
def main():
34-
if not has_data(sys.stdin):
35-
return quit(1, "hastebin: no data given via stdin")
31+
if response.status_code != requests.codes.ok:
32+
return 3, "error: bad response from '{}'".format(paste_url)
3633

37-
try:
38-
stdin = sys.stdin.read()
39-
except UnicodeDecodeError:
40-
return quit(2, "hastebin: an error occured reading stdin")
41-
34+
return 0, response.content.decode().rstrip()
35+
36+
def post_paste(text):
4237
response = requests.post("%s/documents" % url, headers={
43-
"Accept": "application/json"}, data=stdin)
38+
"Accept": "application/json"}, data=text,
39+
timeout=timeout)
40+
4441
if response.status_code != requests.codes.ok:
45-
return quit(3, "hastebin: error submitting POST data to hastebin")
42+
return 3, "error: bad response from '{}'".format(paste_url)
43+
44+
return 0, response.content.decode().rstrip()
4645

47-
content = response.content.decode("UTF-8").rstrip()
48-
data = json.loads(content)
46+
def main():
47+
help_description = "Upload text from stdin to HASTEBIN_SERVER_URL. If "
48+
help_description += "[id] is provided, the corresponding paste is fetched "
49+
help_description += "and displayed."
50+
parser = argparse.ArgumentParser(description=help_description)
51+
parser.add_argument("--clip-command", "-cc",
52+
metavar="clip_command",
53+
default="xclip -sel primary",
54+
help="clipboard pipe command (default: 'xclip -sel primary')")
55+
parser.add_argument("--clipboard", "-c",
56+
metavar="clipboard",
57+
action="store_const",
58+
const=True,
59+
default=False,
60+
help="pipe stdout to --clip-command")
61+
parser.add_argument("id",
62+
nargs="?",
63+
help="when provided, fetches and displays a hastebin paste")
64+
args = parser.parse_args()
65+
66+
if args.id is not None:
67+
if args.id[:4] == "http" and args.id[:len(url)] != url:
68+
return quit(1,
69+
f"error: invalid id provided; URLs must begin with '{url}'")
70+
71+
paste_id = args.id.split("/")[-1]
72+
if not paste_id:
73+
return quit(1, "error: no id provided")
74+
75+
return_code, response = get_paste(paste_id)
76+
if return_code != 0:
77+
return quit(return_code, response)
78+
print(response)
79+
else:
80+
if not has_data(sys.stdin):
81+
return quit(1, "error: no data given via stdin")
82+
83+
try:
84+
stdin = sys.stdin.read()
85+
except UnicodeDecodeError:
86+
return quit(2, "error: an error occured reading stdin")
87+
88+
return_code, response = post_paste(stdin)
89+
if return_code != 0:
90+
return quit(return_code, response)
91+
92+
data = json.loads(response)
93+
uri = f'{url}/{data["key"]}'
94+
print(uri)
4995

50-
print("%s/%s" % (url, data["key"]))
96+
if args.clipboard:
97+
proc = Popen([
98+
"/bin/sh", "-c",
99+
f'echo -n "{uri}" | {args.clip_command}'
100+
])
101+
proc.wait()
51102

52103
return 0
53104

54-
55105
# main execution
56106
if __name__ == "__main__":
57107
e = main()

0 commit comments

Comments
 (0)