Commit 38ccb863 authored by Давид Ли's avatar Давид Ли

completed 38 lesson

parent 28a10bc3
venv
.idea
__pycache__*
\ No newline at end of file
......@@ -2,7 +2,7 @@
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="jdk" jdkName="Python 3.11" jdkType="Python SDK" />
<orderEntry type="jdk" jdkName="Python 3.11 (http_framework)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
......@@ -3,5 +3,5 @@
<component name="MarkdownSettingsMigration">
<option name="stateVersion" value="1" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.11" project-jdk-type="Python SDK" />
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.11 (http_framework)" project-jdk-type="Python SDK" />
</project>
\ No newline at end of file
from request import Request
from response import Response
class BaseController:
def __init__(self, request: Request, response: Response):
self.request = request
self.response = response
from .base import BaseController
class PagesController(BaseController):
def home(self):
self.response.add_header('Content-Type', 'text/html')
self.response.set_body('<h1>This is homepage</h1>')
def about_us(self):
self.response.add_header('Content-Type', 'text/html')
self.response.set_body('<h1>This is about us page</h1>')
from controllers.base import BaseController
def id_generator():
count = 0
while True:
count += 1
yield count
id_gen = id_generator()
class PostsController(BaseController):
posts_db = [
{'id': next(id_gen), 'title': 'This is 1 post'},
{'id': next(id_gen), 'title': 'This is 2 post'},
{'id': next(id_gen), 'title': 'This is 3 post'},
]
def get_list(self):
body = (
'<h1>This is posts page</h1>'
'<br><form action="/posts" method="POST">'
'<label>'
'<input type="text" name="title">'
'</label>'
'<input type="submit">'
'</form><br>'
)
for post in self.posts_db:
body += f'<h3>{post["id"]} - {post["title"]}'
self.response.add_header('Content-Type', 'text/html')
self.response.set_body(body)
def create(self):
id_ = next(id_gen)
self.posts_db.append(
{
'id': id_,
'title': f'This is {id_} post'
}
)
self.response.add_header('Content-Type', 'text/html')
self.response.set_body('<a href="/posts"">Back to posts list</a>')
from request import Request
from response import Response
def not_found(request: Request, response: Response):
response.add_header('Content-Type', 'text/html')
response.set_status(Response.HTTP_NOT_FOUND)
response.set_body('<h1>404 Not Found</h1>')
def internal_server_error(request: Request, response: Response):
response.add_header('Content-Type', 'text/html')
response.set_status(Response.HTTP_INTERNAL_SERVER_ERROR)
response.set_body('<h1>500 Internal Server Error</h1>')
import urllib.parse
from typing import BinaryIO
......@@ -32,4 +33,16 @@ class Request:
def parse_body(self) -> None:
if 'Content-Length' in self.headers:
content_length = int(self.headers['Content-Length'])
body = self.file.read(content_length)
if isinstance(body, bytes):
decoded = body.decode()
parsed = urllib.parse.parse_qs(decoded)
for k, v in parsed.items():
parsed[k] = ' '.join(v) # noqa
self.body = parsed
else:
self.body = self.file.read(content_length)
import errors
from controllers.base import BaseController
from request import Request
from response import Response
class Router:
def __init__(self):
self.routes = {
'get': [],
'post': []
}
def add(self, http_method: str, uri: str, ctrl: BaseController, ctrl_method: str):
self.routes[http_method].append(
{
'uri': uri,
'ctrl': ctrl,
'ctrl_method': ctrl_method
}
)
def get(self, *args):
self.add('get', *args)
def post(self, *args):
self.add('post', *args)
def run(self, request: Request, response: Response):
http_method = request.method.lower() # post
method_routes = self.routes[http_method] # [{'uri': 'some_uri', 'ctrl': Ctrl. 'ctrl_method': 'home'}]
route = None
for r in method_routes:
if r['uri'] == request.uri:
route = r
break
print(route)
if not route:
return errors.not_found(request, response)
try:
ctrl = route['ctrl'](request, response)
getattr(ctrl, route['ctrl_method'])()
except BaseException as e:
print(e)
return errors.internal_server_error(request, response)
import socketserver
from controllers.pages import PagesController
from controllers.posts import PostsController
from request import Request
from response import Response
from router import Router
from static_responder import StaticResponder
import errors
HOST, PORT = '127.0.0.1', 1025
# CRUDL - Create, Read, Update, Delete, List
# /posts
# GET - /posts
# GET - /posts/{id}
# POST - /posts
# PUT/PATCH - /posts/{id}
# DELETE - /posts/{id}
router = Router()
router.get('/', PagesController, 'home')
router.get('/about-us', PagesController, 'about_us')
router.get('/posts', PostsController, 'get_list')
router.post('/posts', PostsController, 'create')
class MyTCPHandler(socketserver.StreamRequestHandler):
def handle(self) -> None:
request = Request(file=self.rfile)
response = Response(file=self.wfile)
static_responder = StaticResponder(request, response, 'static')
if static_responder.file:
static_responder.prepare_response()
else:
response.add_header('Content-Type', 'text/html')
response.add_header('Connection', 'close')
response.set_body('<h1>Hello world!</h1>')
router.run(request, response)
print(
f'Method: {request.method}\n'
......
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Hello world!</h1>
</body>
</html>
\ No newline at end of file
......@@ -2,6 +2,10 @@
text-align: center;
}
h1 {
color: red
}
.container {
margin: 0 auto;
width: 80%;
......
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="../static/styles.css">
<title>Title</title>
</head>
<body>
<h1>Hello {{ user.name|title }} {{ user.surname|title }} </h1>
<h3>Today: {{ user.current_datetime }}</h3>
<h4>Phone: {{ user.phone }}</h4>
<form action="/posts" method="POST">
<label>
<input type="text" name="title">
</label>
</form>
{{ user.contacts|join(', ') }}
<!-- <ol>-->
<!-- {% for i in user.contacts %}-->
<!-- <li>{{ i }}</li>-->
<!-- {% endfor %}-->
<!-- </ol>-->
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Assumenda nostrum quasi voluptate. Ad blanditiis deserunt distinctio error facilis incidunt maxime nostrum, numquam placeat? Error hic obcaecati quas quis saepe velit.</p>
</body>
</html>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment