summaryrefslogtreecommitdiff
path: root/day7/backend.py
diff options
context:
space:
mode:
authorAndrew <saintruler@gmail.com>2019-05-24 16:29:03 +0400
committerAndrew <saintruler@gmail.com>2019-05-24 16:29:03 +0400
commit0f0e815ad1b775ff93699b695f290c562c57962f (patch)
tree2d41e2d3b3ede86b6fb18a176b201920d6681dfa /day7/backend.py
parent402d0d2b9ebd76b8e99eddceeb85c4a66030b51b (diff)
Модули для обработки http-запросов, базовый обработчик url-путей. Обертка для работы с shelve базами данных, html-шаблонизатор.
Diffstat (limited to 'day7/backend.py')
-rw-r--r--day7/backend.py180
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