diff options
Diffstat (limited to 'day9')
| -rw-r--r-- | day9/task5/core.py | 82 | ||||
| -rw-r--r-- | day9/task5/server.py | 65 | ||||
| -rw-r--r-- | day9/task5/utils.py | 131 | ||||
| -rw-r--r-- | day9/task5_vue/backend/views.py | 18 |
4 files changed, 12 insertions, 284 deletions
diff --git a/day9/task5/core.py b/day9/task5/core.py deleted file mode 100644 index 2bf9cf5..0000000 --- a/day9/task5/core.py +++ /dev/null @@ -1,82 +0,0 @@ -from abc import ABC, abstractmethod -import json - -from utils import HTTP_STATUS_CODES - - -class Response(ABC): - @property - def status_code(self) -> int: - """ - По дефолту возвращается статус 200 - """ - return 200 - - @property - @abstractmethod - def content_type(self) -> str: - pass - - @property - @abstractmethod - def content(self) -> bytes: - pass - - -class HtmlResponse(Response): - def __init__(self, html, status_code=200): - self._html: str = html - self._code = status_code - - @property - def status_code(self) -> int: - return self._code - - @property - def content_type(self) -> str: - return 'text/html' - - @property - def content(self) -> bytes: - return self._html.encode() - - -class TextFileResponse(Response): - def __init__(self, path, extension): - with open(path, 'rb') as f: - self._content = f.read() - - self._extension = extension - - @property - def content_type(self) -> str: - return f'text/{self._extension}' - - @property - def content(self) -> bytes: - return self._content - - -class ImageResponse(TextFileResponse): - @property - def content_type(self) -> str: - return f'image/{self._extension}' - - -class JsonResponse(Response): - def __init__(self, json_object): - self._json_str = json.dumps(json_object, ensure_ascii=False) - - @property - def content_type(self) -> str: - return 'application/json' - - @property - def content(self) -> bytes: - return self._json_str.encode() - - -class ErrorResponse(HtmlResponse): - def __init__(self, http_code, message=''): - html = f'<center><h1>ERROR {http_code} {HTTP_STATUS_CODES[http_code].upper()}</h1></center><br>{message}' - super().__init__(html, http_code) diff --git a/day9/task5/server.py b/day9/task5/server.py deleted file mode 100644 index 86b3e4c..0000000 --- a/day9/task5/server.py +++ /dev/null @@ -1,65 +0,0 @@ -from http.server import HTTPServer, BaseHTTPRequestHandler -from urllib.parse import parse_qs - -from day9.task5_vue.router import run -from day9.task5_vue.utils import parse_multipart_form - -import logging - - -class MyHTTPRequestHandler(BaseHTTPRequestHandler): - def _set_response(self, code, content_type): - self.send_response(code) - self.send_header('Content-type', content_type) - self.end_headers() - - def do_GET(self): - try: - content_length = int(self.headers['Content-Length']) - get_data = parse_qs(self.rfile.read(content_length).decode('utf-8')) - except TypeError: - get_data = {} - - for key in get_data: - get_data[key] = get_data[key][0] - - self.finalize_request(run({ - 'url': self.path, - 'method': 'GET', - 'query': get_data - })) - - def do_POST(self): - content_length = int(self.headers['Content-Length']) - content_type = self.headers['Content-type'] - post_data = self.rfile.read(content_length) - - if content_type.split(';')[0] == 'multipart/form-data': - files = parse_multipart_form(post_data) - self.finalize_request(run({ - 'url': self.path, - 'method': 'POST', - 'query': {'files': files} - })) - - elif content_type.split(';')[0] in ['text/plain', 'application/x-www-form-urlencoded']: - post_data = parse_qs(post_data.decode('utf-8')) - for key in post_data: - post_data[key] = post_data[key][0] - - self.finalize_request(run({ - 'url': self.path, - 'method': 'POST', - 'query': post_data - })) - - def finalize_request(self, response): - self._set_response(response.status_code, response.content_type) - self.wfile.write(response.content) - - -def start_server(host, port): - server_address = (host, port) - httpd = HTTPServer(server_address, MyHTTPRequestHandler) - logging.getLogger('tableApp').info(f'Server started on {host}:{port}') - httpd.serve_forever() diff --git a/day9/task5/utils.py b/day9/task5/utils.py deleted file mode 100644 index c1b3a04..0000000 --- a/day9/task5/utils.py +++ /dev/null @@ -1,131 +0,0 @@ -from io import BytesIO - - -CHUNK_SIZE = 49600 - -HTTP_STATUS_CODES = { - 100: "Continue", - 101: "Switching Protocols", - 102: "Processing", - 200: "OK", - 201: "Created", - 202: "Accepted", - 203: "Non Authoritative Information", - 204: "No Content", - 205: "Reset Content", - 206: "Partial Content", - 207: "Multi Status", - 226: "IM Used", # see RFC 3229 - 300: "Multiple Choices", - 301: "Moved Permanently", - 302: "Found", - 303: "See Other", - 304: "Not Modified", - 305: "Use Proxy", - 307: "Temporary Redirect", - 308: "Permanent Redirect", - 400: "Bad Request", - 401: "Unauthorized", - 402: "Payment Required", # unused - 403: "Forbidden", - 404: "Not Found", - 405: "Method Not Allowed", - 406: "Not Acceptable", - 407: "Proxy Authentication Required", - 408: "Request Timeout", - 409: "Conflict", - 410: "Gone", - 411: "Length Required", - 412: "Precondition Failed", - 413: "Request Entity Too Large", - 414: "Request URI Too Long", - 415: "Unsupported Media Type", - 416: "Requested Range Not Satisfiable", - 417: "Expectation Failed", - 418: "I'm a teapot", # see RFC 2324 - 421: "Misdirected Request", # see RFC 7540 - 422: "Unprocessable Entity", - 423: "Locked", - 424: "Failed Dependency", - 426: "Upgrade Required", - 428: "Precondition Required", # see RFC 6585 - 429: "Too Many Requests", - 431: "Request Header Fields Too Large", - 449: "Retry With", # proprietary MS extension - 451: "Unavailable For Legal Reasons", - 500: "Internal Server Error", - 501: "Not Implemented", - 502: "Bad Gateway", - 503: "Service Unavailable", - 504: "Gateway Timeout", - 505: "HTTP Version Not Supported", - 507: "Insufficient Storage", - 510: "Not Extended", -} - -SUCCESS_CODE = 200 -BAD_REQUEST_CODE = 400 -NOT_FOUND_CODE = 404 -METHOD_NOT_ALLOWED_CODE = 405 - - -def render_template(path, **kwargs): - with open(path, encoding='utf-8') as f: - template = f.read() - - for key in kwargs: - template = template.replace(f'%%{key}%%', kwargs[key]) - - return template - - -def parse_multipart_form(data: bytes): - b = BytesIO(data) - separator = b.readline().strip() - - files = [] - - while True: - line = b.readline().strip().strip(b'-') - if not line: - break - - headers_raw = [] - while not line.strip() == b'': - headers_raw.append(line.strip().decode()) - line = b.readline() - - headers = {'Content-Type': headers_raw[1].split(': ')[1]} - for pair in headers_raw[0].split(': ')[1].split('; ')[1:]: - key, value = pair.split('=') - headers[key] = value[1:-1] - - data = b'' - prev_chunk = b.read(CHUNK_SIZE) - chunk = b.read(CHUNK_SIZE) - while separator not in (prev_chunk + chunk): - data += prev_chunk - prev_chunk = chunk - chunk = b.read(CHUNK_SIZE) - - if not chunk: - break - - chunk = (prev_chunk + chunk) - if chunk.startswith(separator) or chunk.endswith(separator): - with_sep = chunk.strip(separator) - else: - if separator in chunk: - with_sep, buffer = chunk.split(separator) - b = BytesIO(buffer + b.read()) - b.readline() - - else: - with_sep = chunk - - data += with_sep - headers['data'] = data - - files.append(headers) - - return files diff --git a/day9/task5_vue/backend/views.py b/day9/task5_vue/backend/views.py index d6d9351..ab8b628 100644 --- a/day9/task5_vue/backend/views.py +++ b/day9/task5_vue/backend/views.py @@ -67,16 +67,22 @@ def validate(query, *args): def update_post(query, *args): wrapper = get_wrapper_for('mysql') - service_id = query['service_id'] + scheme = wrapper.schemes['table_task1'] + permitted_fields = wrapper.get_column_names() permitted_fields.remove('service_id') - query_set = [] - for field_name, value in query.items(): - if field_name in permitted_fields: - query_set.append(f'{field_name}="{value}"') + validation_results = scheme.validate(query) + if not validation_results['error']: + expressions = {} + for key, value in query.items(): + if key in permitted_fields: + expressions[key] = value + + wrapper.update('table_task1', expressions, {'service_id': query['service_id']}) + else: + return ErrorResponse(500) - wrapper.update('table_task1', query_set, {'service_id': service_id}) return HtmlResponse('<a href="/">Return to main page</a><br><h1>Database Updated</h1>') |