diff options
| author | Andrew <saintruler@gmail.com> | 2019-05-24 16:29:03 +0400 |
|---|---|---|
| committer | Andrew <saintruler@gmail.com> | 2019-05-24 16:29:03 +0400 |
| commit | 0f0e815ad1b775ff93699b695f290c562c57962f (patch) | |
| tree | 2d41e2d3b3ede86b6fb18a176b201920d6681dfa /day7/backend.py | |
| parent | 402d0d2b9ebd76b8e99eddceeb85c4a66030b51b (diff) | |
Модули для обработки http-запросов, базовый обработчик url-путей. Обертка для работы с shelve базами данных, html-шаблонизатор.
Diffstat (limited to 'day7/backend.py')
| -rw-r--r-- | day7/backend.py | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/day7/backend.py b/day7/backend.py new file mode 100644 index 0000000..9f9b118 --- /dev/null +++ b/day7/backend.py @@ -0,0 +1,180 @@ +import re + +from templater import render_template +from utils import parse_cookies, add_headers, SUCCESS, BAD_REQUEST, NOT_FOUND +from config import TEXT_TEMPLATE_NAME +import db + + +_router_tree = {} + + +# url_format - регулярное выражение +def route(url_format, methods=None): + if methods is None: + methods = ['GET'] + + def wrapper(func): + def inner(url, query, *args, **kwargs): + pattern = re.compile(url_format) + match = re.match(pattern, url) + + if match is None or len(match.groups()) != pattern.groups: + return BAD_REQUEST, '400 BAD REQUEST' + + return func(query, *match.groups(), *args, **kwargs) + + _router_tree[url_format] = _router_tree.get(url_format, {}) + for method in methods: + _router_tree[url_format][method] = inner + + return inner + + return wrapper + + +def run(method, url: str, cookies: dict, query): + res = NOT_FOUND, NOT_FOUND + 'KAVO' + for key, value in cookies.items(): + db.set_cookie(key, value) + + for url_pattern in _router_tree: + if re.fullmatch(url_pattern, url) and method in _router_tree[url_pattern]: + res = _router_tree[url_pattern][method](url, query) + + return add_headers(*res) + + +@route('/') +def index_get(query, *args): + return SUCCESS, render_template('form', color=get_color()) + + +@route('/', ['POST']) +def index_post(query, *args): + return SUCCESS, str(query) + +# Хотелось попробовать сделать что-то высокоуровневое с декораторами. +# Если в этом коде есть какие-то серьезные проблемы, то скажите сразу. +@route(r'/div/(\d+)/to/(\d+)/?') +def divide_get(query, *args): + color = get_color() + + try: + text = str(int(args[0]) / int(args[1])) + return SUCCESS, render_template(TEXT_TEMPLATE_NAME, text=text, color=color) + + except ZeroDivisionError as e: + return BAD_REQUEST, render_template( + TEXT_TEMPLATE_NAME, color=color, + text=BAD_REQUEST + ('<br>' + str(e) if db.get_config_entry('show_errors') else '') + ) + + +@route(r'/div/?', ['POST']) +def divide_post(query, *args): + color = get_color() + + try: + text = str(int(query['numerator']) / int(query['denominator'])) + return SUCCESS, render_template(TEXT_TEMPLATE_NAME, text=text, color=color) + + except KeyError: + field = 'числитель' if 'numerator' not in query else 'знаменатель' + return BAD_REQUEST, render_template( + TEXT_TEMPLATE_NAME, color=color, + text=BAD_REQUEST + ('<br>' + f'Указан неверный {field}') + ) + + except (ValueError, ZeroDivisionError) as e: + return BAD_REQUEST, render_template( + TEXT_TEMPLATE_NAME, color=color, + text=BAD_REQUEST + ('<br>' + str(e) if db.get_config_entry('show_errors') else '') + ) + + +@route(r'/show_errors/(\d{1})/?') +def show_errors_get(query, *args): + color = get_color() + + if args[0] == '1': + db.set_config_entry('show_errors', 1) + return SUCCESS, render_template(TEXT_TEMPLATE_NAME, color=color, text='Опция show_errors включена') + + elif args[0] == '0': + db.set_config_entry('show_errors', 0) + return SUCCESS, render_template(TEXT_TEMPLATE_NAME, color=color, text='Опция show_errors выключена') + + else: + return BAD_REQUEST, render_template( + TEXT_TEMPLATE_NAME, color=color, + text='Опция show_errors не может принимать такое значение' + ) + + +@route(r'/show_errors/?', ['POST']) +def show_errors_post(query, *args): + color = get_color() + + if 'show_errors' not in query: + db.set_config_entry('show_errors', 0) + return SUCCESS, render_template(TEXT_TEMPLATE_NAME, color=color, text='Опция show_errors выключена') + + elif query['show_errors'] == '1': + db.set_config_entry('show_errors', 1) + return SUCCESS, render_template(TEXT_TEMPLATE_NAME, color=color, text='Опция show_errors включена') + + else: + return BAD_REQUEST, render_template( + TEXT_TEMPLATE_NAME, color=color, + text='Опция show_errors не может принимать такое значение' + ) + + +@route(r'/set_cookie/=/(.*)/?') +def set_cookie_get(query, *args): + cookie_line = args[0] + color = get_color() + try: + cookies = parse_cookies(cookie_line) + for key, value in cookies.items(): + db.set_cookie(key, value) + + return SUCCESS, render_template(TEXT_TEMPLATE_NAME, color=color, text='Cookie-файл обновлен') + + except ValueError as e: + return BAD_REQUEST, render_template( + TEXT_TEMPLATE_NAME, color=color, + text=BAD_REQUEST + ('<br>' + str(e) if db.get_config_entry('show_errors') else '') + ) + + +@route(r'/set_cookie/=/?', ['POST']) +def set_cookie_post(query, *args): + color = get_color() + try: + cookie_line = query['cookie_line'] + cookies = parse_cookies(cookie_line) + for key, value in cookies.items(): + db.set_cookie(key, value) + + return SUCCESS, render_template(TEXT_TEMPLATE_NAME, color=color, text='Cookie-файл обновлен') + + except KeyError: + return BAD_REQUEST, render_template( + TEXT_TEMPLATE_NAME, color=color, + text=BAD_REQUEST + ('<br>' + f'Не указана строка с cookie') + ) + + except ValueError as e: + return BAD_REQUEST, render_template( + TEXT_TEMPLATE_NAME, color=color, + text=BAD_REQUEST + ('<br>' + str(e) if db.get_config_entry('show_errors') else '') + ) + + +def get_color(): + color = db.get_cookie('bg_color', 'white') + if color not in ['green', 'white']: + color = 'white' + return color |