blck

ephemeral pastebin/url shortener
git clone https://git.parazyd.org/blck
Log | Files | Refs | README | LICENSE

blck.py (2396B)


      1 #!/usr/bin/env python3
      2 # copyleft (c) 2017-2021 parazyd <parazyd@dyne.org>
      3 # see LICENSE file for copyright and license details.
      4 
      5 from io import BytesIO
      6 from os import remove, rename
      7 from os.path import isfile
      8 from random import choice
      9 from string import ascii_uppercase, ascii_lowercase
     10 
     11 from flask import (Flask, Blueprint, render_template, request, safe_join,
     12                    send_file, abort)
     13 import magic
     14 
     15 bp = Blueprint('blck', __name__, template_folder='templates')
     16 
     17 
     18 @bp.route("/", methods=['GET', 'POST'])
     19 def index():
     20     if request.method == 'GET':
     21         return render_template('index.html', root=args.r)
     22     return short(request.files)
     23 
     24 
     25 @bp.route("<urlshort>")
     26 def urlget(urlshort):
     27     fp = safe_join('files', urlshort)
     28     if not isfile(fp):
     29         abort(404)
     30     r = BytesIO()
     31     mime = magic.from_file(fp, mime=True)
     32     with open(fp, 'rb') as fo:
     33         r.write(fo.read())
     34     r.seek(0)
     35     remove(fp)
     36     return send_file(r, mimetype=mime)
     37 
     38 
     39 def short(c):
     40     if not c or not c['c']:
     41         return abort(400)
     42 
     43     s = genid()
     44     f = c['c']
     45     f.save(safe_join('files', s))
     46 
     47     mimetype = f.mimetype
     48     if not mimetype:
     49         mimetype = magic.from_file(safe_join('files', s), mime=True)
     50 
     51     if mimetype:
     52         t, s = s, '.'.join([s, mimetype.split('/')[1]])
     53         rename(safe_join('files', t), safe_join('files', s))
     54 
     55     if request.headers.get('X-Forwarded-Proto') == 'https':
     56         return ''.join([
     57             request.url_root.replace('http://', 'https://'),
     58             args.r.lstrip('/'), s, '\n'
     59         ])
     60     return ''.join([request.url_root + args.r.lstrip('/'), s, '\n'])
     61 
     62 
     63 def genid(size=4, chars=ascii_uppercase + ascii_lowercase):
     64     return ''.join(choice(chars) for i in range(size))
     65 
     66 
     67 if __name__ == '__main__':
     68     from argparse import ArgumentParser
     69     parser = ArgumentParser()
     70     parser.add_argument('-r', default='/', help='application root')
     71     parser.add_argument('-l', default='localhost', help='listen host')
     72     parser.add_argument('-p', default=13321, help='listen port')
     73     parser.add_argument('-d', default=False, action='store_true', help='debug')
     74     args = parser.parse_args()
     75 
     76     app = Flask(__name__)
     77     app.register_blueprint(bp, url_prefix=args.r)
     78 
     79     if args.d:
     80         app.run(host=args.l, port=args.p, threaded=True, debug=args.d)
     81     else:
     82         from bjoern import run
     83         run(app, args.l, int(args.p))