from dataclasses import dataclass from socket import socket from datetime import datetime from functools import reduce from typing import List, Callable, Tuple from .method import Method from .response import Response from .responsecodes import ResponseCode from .content import * from .patchers import patchers from .logger import log import os import traceback @dataclass class Route: matcher: Callable methods: List[Method] handler: Callable[['Request', socket, Tuple[str, int]], Response] def method_is_allowed(self, method: Method) -> bool: return method in self.methods def execute(self, *args): try: response = self.handler(*args) for patcher in patchers: response = patcher(response, args[0]) return response except Exception as e: log.error(traceback.format_exc()) return error_page(500) def matches(self, request: 'Request') -> bool: if not self.method_is_allowed(request.method): return False return self.matcher(request.path) routes = [ Route( lambda request: request.path == '/style.css', [Method.GET], lambda request, *_: Response( ResponseCode.OK, *raw_file_contents('./style.css') ) ), Route( lambda request: request.path == '/', [Method.GET, Method.POST], lambda request, *_: Response( ResponseCode.OK, {'Content-Type': 'text/html'}, (parse_file('./home.html', dict(prev='\\/')).encode('utf-8') if request.method == Method.GET else ( [ (lambda form_data: ( (lambda time: ( f:=open(f'./files/posts-to-homepage/post_{time}.txt', 'w'), f.write(f"{form_data['name']}@{time}
{form_data['text']}

"), f.close() ))(datetime.now().strftime('%Y-%m-%d_%H:%M:%S-%f')[:-3]) if set(form_data.keys()) == set(['text', 'name']) else None ))( reduce( lambda acc, d: acc.update(d) or acc, map(lambda key_value_pair: {key_value_pair[0]: remove_html_tags(key_value_pair[1])}, request.body.data.items()), {} )), parse_file('./home.html').encode('utf-8') ][1] )) ) if len(request.body.data) > 0 or request.method != Method.POST else error_page(400) ), Route( lambda path: os.path.isdir('.' + path.path), [Method.GET], lambda request, *_: Response( ResponseCode.OK, {'Content-Type': 'text/html'}, parse_file('./dir_index.html', dict(path='.' + request.path.path, prev=request.headers.get('Referer').replace('/', '\\/') if request.headers.has('Referer') else '')).encode('utf-8') ) ), Route( lambda path: os.path.isfile('.' + path.path) and path.path.startswith('/html/') and (path.path.endswith('.html') or '/thoughts/' in path.path), [Method.GET], lambda request, *_: Response( ResponseCode.OK, {'Content-Type': 'text/html'}, parse_file('.' + request.path.path, dict(prev=request.headers.get('Referer').replace('/', '\\/') if request.headers.has('Referer') else '')).encode('utf-8') ) ), Route( lambda path: os.path.isfile('.' + path.path) and (path.path.startswith('/font/') or path.path.startswith('/files/')), [Method.GET], lambda request, *_: Response( ResponseCode.OK, *raw_file_contents('.' + request.path.path) ) ), Route( lambda request: request.path == '/status', [Method.GET], lambda *_: Response( ResponseCode.OK, {'Content-Type': 'text/html'}, parse('$[neofetch | ansi2html]').encode('utf-8') ) ), Route( lambda request: request.path == '/stats/is-its-computer-online', [Method.GET], lambda *_: Response( ResponseCode.OK, {'Content-Type': 'text/html'}, page("online-p", """ seconds since last heartbeat message (less than 60: online; less than 120: maybe; more than 120: probably not): $[echo $(( $(date +%s) - $(stat -c %Y ./files/stats/heartbeat) ))] """) ) ), Route( lambda request: request.path == '/stats/what-song-is-it-listening-to', [Method.GET], lambda *_: Response( ResponseCode.OK, {'Content-type': 'text/html'}, page("song?", """ it is listening to $[cat ./files/stats/song] as of $[echo $(( $(date +%s) - $(stat -c %Y ./files/stats/song) ))] seconds ago. """) ) ), Route( lambda request: request.path == '/stats/is-this-server-online', [Method.GET], lambda *_: Response( ResponseCode.OK, {'Content-type': 'text/html'}, page("server online-p", """ I think so. """) ) ), Route( lambda request: request.path == '/stats/what-is-its-servers-uptime', [Method.GET], lambda *_: Response( ResponseCode.OK, {'Content-type': 'text/html'}, page("uptime", """ $[uptime] """) ) ), Route( lambda request: request.path == '/stats/what-vim-buffers-does-it-have-open', [Method.GET], lambda *_: Response( ResponseCode.OK, {'Content-type': 'text/html'}, page("vim bufs", """ $[cat ./files/stats/vim-bufs | xargs -I% echo %'
'] """) ) ), Route( lambda request: request.path == '/stats', [Method.GET], lambda request, *_: Response( ResponseCode.OK, {'Content-Type': 'text/html'}, parse_file('./html/stats.html', dict(prev=request.headers.get('Referer').replace('/', '\\/') if request.headers.has('Referer') else '')).encode('utf-8') ) ), Route( lambda _: True, [Method.GET], lambda *_: error_page(404) ) ]