-
Notifications
You must be signed in to change notification settings - Fork 0
/
pastebin.py
118 lines (110 loc) · 4 KB
/
pastebin.py
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import server, urllib.parse, os
BaseTemplate = """\
<!doctype html>
<html>
<head>
<title>Pastebin{title}</title>
</head>
<body>
{body}
</body>
</html>
"""
IndexTemplate = BaseTemplate.format(title="", body="""\
<h1>Pastebin</h1>
<hr/>
<form action="/" method="post">
<textarea name="paste"></textarea><br/>
<input type="submit" value="Submit">
</form>
""")
PasteTemplate = BaseTemplate.format(title=" - paste {paste_id}", body="""\
<h1>Paste {paste_id}</h1>
<hr/>
<pre>{paste_content}</pre>
""")
StatsTemplate = BaseTemplate.format(title=" - statistics", body="""\
<h1>Statistics</h1>
<hr/>
<p>{no_pastes} paste(s)</p>
""")
def html_encode(string):
return string.replace("<", "<").replace(">", ">")
class Pastebin(server.BaseServer):
def __init__(self, *args, **kwargs):
super(Pastebin, self).__init__(*args, **kwargs)
self.pastes = []
def do_HEAD(self, request):
response = self.do_GET(request)
if response.status == 200:
#TODO: Is this compliant with the standard?
return server.Response(self.config["VERSION"], 200, "OK",
headers={
"Content-type": response.headers["Content-type"],
"Content-length": len(response.content)
})
else:
return response
def do_GET(self, request):
if request.uri == "/":
return self.serve_file("text/html",
content=IndexTemplate)
elif request.uri == "/stats":
return self.serve_file("text/html",
content=StatsTemplate.format(
no_pastes=self.number_of_pastes())
)
return self.get_paste(request.uri[1:])
def number_of_pastes(self):
return len(self.pastes)
def get_paste(self, id):
try:
paste_id = int(id)
paste_content = self.pastes[paste_id]
paste_content = html_encode(paste_content)
return self.serve_file("text/html",
content=PasteTemplate.format(
paste_id=paste_id,
paste_content=paste_content)
)
except (ValueError, IndexError):
return self.make_error(404, "Not Found")
def do_POST(self, request):
if request.uri == "/":
data = urllib.parse.parse_qs(request.content.decode())
paste_id = self.create_paste("".join(data["paste"]))
return self.make_redirect("/{0}".format(paste_id))
return self.make_error(400, "Bad Request")
def create_paste(self, data):
self.pastes.append(data)
return len(self.pastes) - 1
class PersistentPastebin(Pastebin):
def __init__(self, *args, **kwargs):
super(PersistentPastebin, self).__init__(*args, **kwargs)
def get_paste(self, id):
try:
paste_id = int(id)
with open(os.path.join(self.basedir, "%s" % paste_id)) as file:
paste_content = html_encode(file.read())
return self.serve_file("text/html",
content=PasteTemplate.format(
paste_id=paste_id,
paste_content=paste_content)
)
except (ValueError, FileNotFoundError):
return self.make_error(404, "Not Found")
def number_of_pastes(self):
try:
with open(os.path.join(self.basedir, "ID"), "r") as id_file:
return int(id_file.read())
except (ValueError, FileNotFoundError):
return 0
def create_paste(self, data):
paste_id = self.number_of_pastes()
with open(os.path.join(self.basedir, "ID"), "w") as id_file:
id_file.write(str(paste_id + 1))
with open(os.path.join(self.basedir, "%s" % paste_id), "w") as file:
file.write(data)
return paste_id
if __name__ == "__main__":
PersistentPastebin(address="", port=8888).serve_forever()