home · contact · privacy
Display HandledException as HTML message with appropriate status code.
[plomtask] / task.py
1 #!/usr/bin/env python3
2 """plom's task manager"""
3 from http.server import BaseHTTPRequestHandler
4 from http.server import HTTPServer
5 from urllib.parse import urlparse
6 from os.path import split as path_split
7 from jinja2 import Environment as JinjaEnv, FileSystemLoader as JinjaFSLoader
8 from days import Day
9
10 HTTP_PORT = 8082
11 TEMPLATES_DIR = 'templates'
12
13
14 class HandledException(Exception):
15     """To identify Exceptions based on expected (if faulty) user behavior."""
16
17
18 class TaskHandler(BaseHTTPRequestHandler):
19     """Handles single HTTP request."""
20
21     def send_html(self, html, code=200):
22         """Send HTML as proper HTTP response."""
23         self.send_response(code)
24         self.end_headers()
25         self.wfile.write(bytes(html, 'utf-8'))
26
27     def send_msg(self, msg, code=400):
28         """Send message in HTML formatting as HTTP response."""
29         html = self.server.jinja.get_template('msg.html').render(msg=msg)
30         self.send_html(html, code)
31
32     def do_GET(self):
33         """Handle any GET request."""
34         try:
35             parsed_url = urlparse(self.path)
36             site = path_split(parsed_url.path)[1]
37             if 'calendar' == site:
38                 html = self.do_GET_calendar()
39             else:
40                 raise HandledException('Test!')
41             self.send_html(html)
42         except HandledException as error:
43             self.send_msg(error)
44
45     def do_GET_calendar(self):
46         """Show sorted Days."""
47         days = [Day('2024-01-03'), Day('2024-01-01'), Day('2024-01-02')]
48         days.sort()
49         return self.server.jinja.get_template('calendar.html').render(
50                 days=days)
51
52
53 def main():
54     """Main loop."""
55     server = HTTPServer(('localhost', HTTP_PORT), TaskHandler)
56     server.jinja = JinjaEnv(loader=JinjaFSLoader(TEMPLATES_DIR))
57     print(f'running at port {HTTP_PORT}')
58     try:
59         server.serve_forever()
60     except KeyboardInterrupt:
61         print('aborting due to keyboard interrupt')
62     server.server_close()
63
64
65 if __name__ == '__main__':
66     from sys import exit as sys_exit
67     try:
68         main()
69     except HandledException as e:
70         print(f'Aborting due to: {e}')
71         sys_exit(1)