aboutsummaryrefslogtreecommitdiff
path: root/flakes/paste/paste/paste.py
diff options
context:
space:
mode:
Diffstat (limited to 'flakes/paste/paste/paste.py')
-rw-r--r--flakes/paste/paste/paste.py124
1 files changed, 124 insertions, 0 deletions
diff --git a/flakes/paste/paste/paste.py b/flakes/paste/paste/paste.py
new file mode 100644
index 0000000..86666b8
--- /dev/null
+++ b/flakes/paste/paste/paste.py
@@ -0,0 +1,124 @@
1import os
2import secrets
3from flask import Flask, abort, request, Response, url_for
4from pygments.formatters.html import HtmlFormatter
5from pygments import highlight
6import pygments.lexers as lexers
7import base64
8import magic
9import mimetypes
10
11magic = magic.Magic(mime=True)
12
13config = {
14 "directory": os.environ["PASTE_DIRECTORY"],
15 "self_paste_id": "abcd123",
16 "max_content_length": 16 * 1000 * 1000
17 }
18
19app = Flask(__name__)
20app.config['MAX_CONTENT_LENGTH'] = config["max_content_length"]
21
22def file_location(paste_id):
23 if paste_id == config["self_paste_id"]:
24 return os.path.realpath(__file__)
25 else:
26 return os.path.join(config['directory'], paste_id + ".dat")
27
28def read_paste(paste_id):
29 file = file_location(paste_id)
30 if os.path.isfile(file):
31 content = open(file, "rb").read()
32 mime = magic.from_buffer(content)
33 if mime.startswith("text/x-script."):
34 mime="text/plain"
35 return (content, mime)
36 else:
37 abort(404)
38
39def generate_paste_id(n=3, attempts=0):
40 path = secrets.token_hex(n)[:n]
41 file = file_location(path)
42 if os.path.isfile(file):
43 attempts = attempts + 1
44 if attempts > 5:
45 n = n + 1
46 return generate_paste_id(n, attempts)
47 return path
48
49@app.route('/', methods=["GET"])
50def index():
51 return Response('''<pre>
52$ curl -X POST --data-binary @{self} {host}
53{paste}
54
55-> GET {paste}
56 guesses mimetype
57-> GET {paste}/raw
58 text/plain
59-> GET {paste}/bin
60 application/octet-stream
61-> GET {paste}/b64
62 base64 encoded
63-> GET {paste}/ub64
64 tries to decode base64
65-> GET {paste}/python
66 pretty-print python (replace with anything known by pygments)
67-> GET {paste}/guess
68 pretty-print (language guessed by pygments)
69-> GET {paste}/download
70 force download of file
71</pre>
72<a href="{paste}/py">Get the source</a>
73'''.format(host=url_for('post_paste', _external=True, _scheme="https"),
74 paste=url_for('get_paste', _external=True, _scheme="https", paste_id=config["self_paste_id"]),
75 self=os.path.basename(__file__)
76 ), mimetype="text/html")
77
78@app.route('/', methods=["POST"])
79def post_paste():
80 content = request.get_data()
81 paste_id = generate_paste_id()
82 with open(file_location(paste_id), "wb") as f:
83 f.write(content)
84 return url_for('get_paste', _external=True, _scheme="https", paste_id=paste_id) + "\n"
85
86
87@app.route('/<paste_id>', methods=["GET"])
88def get_paste(paste_id):
89 content, mime = read_paste(paste_id)
90 return Response(content, mimetype=mime)
91
92@app.route('/<paste_id>/<lang>', methods=["GET"])
93def get_paste_with(paste_id, lang):
94 content, mime = read_paste(paste_id)
95 if lang == "raw":
96 return Response(content, mimetype="text/plain")
97 elif lang == "bin":
98 return Response(content, mimetype="application/octet-stream")
99 elif lang == "b64":
100 return Response(base64.encodebytes(content), mimetype="text/plain")
101 elif lang == "download":
102 extension = mimetypes.guess_extension(mime, strict=False)
103 if extension is None:
104 cd = "attachment"
105 else:
106 cd = 'attachment; filename="{}{}"'.format(paste_id, extension)
107 return Response(content, mimetype=mime,
108 headers={"Content-Disposition": cd})
109 elif lang == "ub64":
110 try:
111 return base64.b64decode(content)
112 except:
113 abort(400)
114 try:
115 if lang == "guess":
116 lexer = lexers.guess_lexer(content)
117 else:
118 lexer = lexers.find_lexer_class_by_name(lang)()
119 except:
120 abort(400)
121 fmter = HtmlFormatter(
122 noclasses=True, full=True, style="colorful", linenos="table")
123
124 return Response(highlight(content, lexer, fmter), mimetype="text/html")