Created
February 4, 2015 14:15
-
-
Save arpanpal010/6ed939b81764c264338c to your computer and use it in GitHub Desktop.
minimal text based bulletin board using http.server, single threaded, auto refreshes. exactly 100 loc.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from __future__ import print_function #from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler | |
import http.server, urllib, datetime | |
#================================================================= | |
sUrl="/chatbox" #server url | |
port=8080 #server port | |
timedRefresh="15" #time before page refreshes | |
msgBox=[] #messages held here as dict objects | |
#================================================================= | |
# create html | |
#================================================================= | |
def makeHtml(): | |
msgHtml="" #html from msgbox | |
for item in msgBox: | |
msgHtml+= "<div><b class='alias'>" + item['alias'] + "</b>: <span class='timestamp'>" + str(item['created']).split(".")[0] +"</span><p class='message'>" + item['message'] + "</p></div>" | |
#html to render in page | |
htmlIndex="""<!doctype html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<title>Chatbox!</title> | |
<!--meta http-equiv="refresh" content="10"/--> | |
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"> | |
<style> | |
@import url(http://fonts.googleapis.com/css?family=Open+Sans:300,400); | |
body{ font-family: "Open Sans", sans; font-weight: 300; font-size: 15px; padding: 0 2em; max-width: 960px; margin: 0 auto;} | |
h1 { font-weight: 300; text-align: center;} | |
textarea {overflow: auto; resize: vertical; margin-top: 0.5em; display: block; width: 100%;} | |
#form-wrapper {padding: 0;} | |
#update-wrapper {padding: 0.3em 0;} | |
#messages-wrapper {padding: 1em 0;} | |
#messages-wrapper div { border-bottom: 1px solid #F5F5F5; padding: 0.5em;} | |
#messages-wrapper div .alias {font-weight: 400; display: inline; border-bottom: 1px solid #9E9E9E;} | |
#messages-wrapper div .message { display: inline-block; word-wrap: break-word; padding: 2emi 0;} | |
#messages-wrapper div .timestamp { display: inline-block; float: right; margin-top: 0em;} | |
</style> | |
</head> | |
<body> | |
<h1 style="margin-bottom: 0;"><a href='""" + sUrl + """' style="color: #39c; text-decoration: none;">Chatbox!</a></h1> | |
<p style="text-align: center; margin: 0;">Anonymous text board for small groups.</p> | |
<div id="form-wrapper"> | |
<div id="update-wrapper"> | |
<input type="checkbox" id="updateCheck" checked/> | |
<span id="countdown"></span> | |
</div> | |
<form method="post" action=""> | |
<input type="text" name="alias" placeholder="alias(optional)" style="display: block; width: 100%;"/> | |
<textarea name="message" placeholder="message" autofocus required></textarea> | |
<button type="submit">Submit</button> | |
</form> | |
</div> | |
<div id="messages-wrapper"> """ + msgHtml + """ </div> | |
<!--auto refresh with js + counter--> | |
<script>(function countdown(remaining) { | |
if (document.getElementById('updateCheck').checked != false) { //if remaining zero, reload page | |
if(remaining <= 0) | |
location.reload(true); | |
document.getElementById('countdown').innerHTML = "Updating in: " + remaining; | |
setTimeout(function(){ countdown(remaining - 1); }, 1000); | |
} else { //check status in a bit | |
document.getElementById('countdown').innerHTML = "Check to autoupdate."; | |
setTimeout(function(){countdown(remaining);}, 2000); | |
} })(""" + timedRefresh + """); // seconds | |
</script> | |
</body> | |
</html> """ | |
return htmlIndex | |
#================================================================= | |
# request handler | |
#================================================================= | |
class ChatHandler(http.server.BaseHTTPRequestHandler): #handler here | |
def do_GET(self): #show form and messages | |
html=makeHtml() | |
self.send_response(200) | |
self.send_header('Content-type', 'text/html') | |
self.send_header('Content-length', len(html)) | |
self.end_headers() | |
self.wfile.write(bytes(html, 'utf-8')) | |
return | |
def do_POST(self): #add message to list, redirect to base page | |
l=int(self.headers['Content-length']) | |
pdata=urllib.parse.parse_qs(self.rfile.read(l).decode('utf-8')) | |
if pdata: | |
alias="".join(pdata.get('alias', "anonymous")) #sometimes returning list | |
message="".join(pdata.get('message')) # message required to do post | |
if message: | |
global msgBox | |
msgBox.append({'alias':alias, 'message': message, 'created': datetime.datetime.now()}) | |
self.send_response(302) | |
self.send_header("Location", sUrl) #redirect | |
self.end_headers() | |
return | |
#================================================================= | |
# run server | |
#================================================================= | |
print("Server running on port: ", port) | |
httpd=http.server.HTTPServer(("", port), ChatHandler) | |
try: httpd.serve_forever() | |
except KeyboardInterrupt: | |
print("Shutting down server"); | |
httpd.socket.close() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment