summaryrefslogtreecommitdiff
path: root/bin/ups
blob: 50e35ba24dfceb45efc6d1c6b36c67c440f253ca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#!/usr/bin/python3
# ups.khirnov.net uploader

import argparse
from   http import HTTPStatus
import os.path
import shutil
import ssl
import subprocess
import sys
from urllib import parse, request, error as urlerror

try:
    import magic
    have_magic = True
except ImportError:
    have_magic = False

progname = os.path.basename(sys.argv[0])
service  = 'up' if progname == 'up' else 'ups'
server    = 'https://%s.khirnov.net/' % service
cert_path = os.path.expanduser('~/.local/var/up/cert')

parser = argparse.ArgumentParser()
parser.add_argument('-n', '--name')
parser.add_argument('path', nargs = '?', default = '-')

args = parser.parse_args()

if args.path == '-' and not args.name:
    dst_name = 'stdin'

    # try to guess the extension when name is not provided
    if have_magic:
        m = magic.Magic(extension = True)
        e = m.from_buffer(sys.stdin.buffer.peek(2048))
        if e != '???':
            dst_name += '.' + e.split('/')[0]
else:
    dst_name = args.name or os.path.basename(args.path)

ssl_ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ssl_ctx.verify_mode = ssl.CERT_REQUIRED
ssl_ctx.load_cert_chain(cert_path)
ssl_ctx.load_default_certs()

src = sys.stdin.buffer if args.path == '-' else open(args.path, 'rb')

req  = request.Request(server + parse.quote(dst_name),
                       data = src, method = 'POST')
try:
    resp = request.urlopen(req, context = ssl_ctx)
except KeyboardInterrupt:
    sys.stderr.write('Interrupted\n')
    sys.exit(1)
except urlerror.URLError as e:
    sys.stderr.write('Error submitting the file: %s\n' % str(e.reason))
    sys.exit(1)

if resp.status in (HTTPStatus.OK, HTTPStatus.CREATED):
    sys.stdout.write(resp.read().decode('ascii') + '\n')
else:
    sys.stderr.write('The server returned unexpected code: %d %s\n' %
                     (resp.status, resp.reason))
    sys.exit(1)