Start writing html generation
This commit is contained in:
parent
858ada9011
commit
149180683d
|
@ -0,0 +1,97 @@
|
||||||
|
import urllib.parse
|
||||||
|
|
||||||
|
import bs4
|
||||||
|
|
||||||
|
# generate_nav(*, soup) → nav_tag
|
||||||
|
def generate_nav(*, soup):
|
||||||
|
# TODO: Don't generate link to a board if we're at the index
|
||||||
|
nav_tag = soup.new_tag('nav')
|
||||||
|
|
||||||
|
for board in ['a', 'b', 'his', 'g']:
|
||||||
|
url = '/' + urllib.parse.quote(board, safe = '') + '/'
|
||||||
|
a_tag = soup.new_tag('a', href = url)
|
||||||
|
a_tag.string = '/' + board + '/'
|
||||||
|
nav_tag.append(a_tag)
|
||||||
|
|
||||||
|
return nav_tag
|
||||||
|
|
||||||
|
# generate_header(*, page_title, soup) → header_tag
|
||||||
|
def generate_header(*, page_title, soup):
|
||||||
|
header_tag = soup.new_tag('header')
|
||||||
|
|
||||||
|
h1_tag = soup.new_tag('h1')
|
||||||
|
h1_tag.string = page_title
|
||||||
|
header_tag.append(h1_tag)
|
||||||
|
|
||||||
|
return header_tag
|
||||||
|
|
||||||
|
# generate_footer(*, soup) → footer_tag
|
||||||
|
def generate_footer(*, soup):
|
||||||
|
# TODO: Add footer generation
|
||||||
|
return soup.new_tag('footer')
|
||||||
|
|
||||||
|
# page_skeleton(*, page_title, contents, soup) → html
|
||||||
|
# Given page title (string) and contents (iteratable of beautifulsoup tags), create the html
|
||||||
|
# Since most pages have same basic structure, it makes sense to factor this out from page creation functions
|
||||||
|
def page_skeleton(*, page_title, contents, soup):
|
||||||
|
# Doctype and head are more or less the same for each page, no need to do anything fancy when adding them
|
||||||
|
soup.append(bs4.Doctype('html'))
|
||||||
|
|
||||||
|
head_tag = soup.new_tag('head')
|
||||||
|
title_tag = soup.new_tag('title')
|
||||||
|
title_tag.string = page_title
|
||||||
|
head_tag.append(title_tag)
|
||||||
|
soup.append(head_tag)
|
||||||
|
|
||||||
|
# Body consists of (more or less same) header and footer, and varying content
|
||||||
|
body_tag = soup.new_tag('body')
|
||||||
|
|
||||||
|
body_tag.append(generate_nav(soup = soup))
|
||||||
|
body_tag.append(generate_header(page_title = page_title, soup = soup))
|
||||||
|
|
||||||
|
# contents is an iterable that can contain several tags
|
||||||
|
for tag in contents:
|
||||||
|
body_tag.append(tag)
|
||||||
|
|
||||||
|
body_tag.append(generate_footer(soup = soup))
|
||||||
|
|
||||||
|
soup.append(body_tag)
|
||||||
|
|
||||||
|
# Use .prettify() to generate nice-looking HTML
|
||||||
|
# We are probably never going to serve enough pages for the additional whitespace to count for data usage
|
||||||
|
return soup.prettify()
|
||||||
|
|
||||||
|
# new_soup() → soup
|
||||||
|
# Since we need a soup object to create tags, split this from page_skeleton
|
||||||
|
def new_soup():
|
||||||
|
# Use python's built-in parser for portability
|
||||||
|
# We'll be constructing the document programmatically, so start with empty tree
|
||||||
|
soup = bs4.BeautifulSoup('', 'html.parser')
|
||||||
|
|
||||||
|
return soup
|
||||||
|
|
||||||
|
# board() → html
|
||||||
|
# Creates the board index page
|
||||||
|
def board(board_name):
|
||||||
|
# TODO: Creae a board index page
|
||||||
|
soup = new_soup()
|
||||||
|
|
||||||
|
page_title = '/' + board_name + '/'
|
||||||
|
|
||||||
|
return page_skeleton(page_title = page_title, contents = [], soup = soup)
|
||||||
|
|
||||||
|
# index() → html
|
||||||
|
# Create the site index
|
||||||
|
def index():
|
||||||
|
# TODO: Create an index page
|
||||||
|
soup = new_soup()
|
||||||
|
return page_skeleton(page_title = 'Buranun', contents = [], soup = soup)
|
||||||
|
|
||||||
|
# error_404(path) → html
|
||||||
|
def error_404(path):
|
||||||
|
soup = new_soup()
|
||||||
|
|
||||||
|
p_tag = soup.new_tag('p')
|
||||||
|
p_tag.string = path + ' does not exist'
|
||||||
|
|
||||||
|
return page_skeleton(page_title = '404 Not Found', contents = [p_tag], soup = soup)
|
35
server.py
35
server.py
|
@ -1,27 +1,46 @@
|
||||||
import http.server
|
import http.server
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
|
|
||||||
|
import generate_html
|
||||||
|
|
||||||
class HTTPRequestHandler(http.server.BaseHTTPRequestHandler):
|
class HTTPRequestHandler(http.server.BaseHTTPRequestHandler):
|
||||||
server_version = 'Buranun/0.0'
|
server_version = 'Buranun/0.0'
|
||||||
protocol_version = 'HTTP/1.1'
|
protocol_version = 'HTTP/1.1'
|
||||||
|
|
||||||
def __send_plaintext(self, string):
|
def __send_html(self, html, *, status_code = 200):
|
||||||
if string[-1:] != '\n':
|
encoded = html.encode('utf-8')
|
||||||
string += '\n'
|
|
||||||
|
|
||||||
encoded = string.encode('utf-8')
|
|
||||||
length = len(encoded)
|
length = len(encoded)
|
||||||
|
|
||||||
self.send_response(200)
|
self.send_response(status_code)
|
||||||
self.send_header('Content-Type', 'text/plain; charset=utf-8')
|
self.send_header('Content-Type', 'text/html; charset=utf-8')
|
||||||
self.send_header('Content-Length', length)
|
self.send_header('Content-Length', length)
|
||||||
self.end_headers()
|
self.end_headers()
|
||||||
|
|
||||||
self.wfile.write(encoded)
|
self.wfile.write(encoded)
|
||||||
|
|
||||||
|
def __send_404(self, path):
|
||||||
|
html = generate_html.error_404(path)
|
||||||
|
self.__send_html(html, status_code = 404)
|
||||||
|
|
||||||
def do_GET(self):
|
def do_GET(self):
|
||||||
path = urllib.parse.unquote(self.path)
|
path = urllib.parse.unquote(self.path)
|
||||||
self.__send_plaintext(path)
|
|
||||||
|
path_components = [component for component in path.split('/') if component != '']
|
||||||
|
|
||||||
|
if len(path_components) == 0:
|
||||||
|
# Path of format / → index
|
||||||
|
html = generate_html.index()
|
||||||
|
self.__send_html(html)
|
||||||
|
|
||||||
|
elif len(path_components) == 1:
|
||||||
|
# Path of format /foo/ → board index
|
||||||
|
board_name = path_components[0]
|
||||||
|
html = generate_html.board(board_name)
|
||||||
|
self.__send_html(html)
|
||||||
|
|
||||||
|
else:
|
||||||
|
# Path not understood, send 404
|
||||||
|
self.__send_404(path)
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
httpd = http.server.HTTPServer(('', 8000), HTTPRequestHandler)
|
httpd = http.server.HTTPServer(('', 8000), HTTPRequestHandler)
|
||||||
|
|
Loading…
Reference in New Issue