From ff659db77f5270c480c1e4582f1d43d027f57951 Mon Sep 17 00:00:00 2001 From: Sage Vaillancourt Date: Fri, 23 Sep 2022 11:35:56 -0400 Subject: [PATCH] Some project re-org, and add pytest. Rename flaskr/ to undercover/ Rename writing_templates/ to letter_templates/ Put db testing code into __main__ check Break css optimization into its own file and add simple testing. Rename writing.py to routes.py. Move cached index directly into routes.py --- flaskr/__init__.py | 51 ------------------- .../base.tex | 0 .../default.tex | 0 pyproject.toml | 4 ++ requirements.txt | 3 +- start | 4 +- tests/test_css.py | 23 +++++++++ undercover/__init__.py | 29 +++++++++++ undercover/css.py | 22 ++++++++ {flaskr => undercover}/db.py | 36 ++++++------- latty.py => undercover/latty.py | 3 +- writing.py => undercover/routes.py | 21 ++++---- {flaskr => undercover}/static/styles.css | 0 .../templates/_formhelpers.jinja2 | 0 .../templates/writing.jinja2 | 0 15 files changed, 114 insertions(+), 82 deletions(-) delete mode 100644 flaskr/__init__.py rename {writing_templates => letter_templates}/base.tex (100%) rename {writing_templates => letter_templates}/default.tex (100%) create mode 100644 pyproject.toml create mode 100644 tests/test_css.py create mode 100644 undercover/__init__.py create mode 100644 undercover/css.py rename {flaskr => undercover}/db.py (81%) rename latty.py => undercover/latty.py (97%) rename writing.py => undercover/routes.py (94%) rename {flaskr => undercover}/static/styles.css (100%) rename {flaskr => undercover}/templates/_formhelpers.jinja2 (100%) rename {flaskr => undercover}/templates/writing.jinja2 (100%) diff --git a/flaskr/__init__.py b/flaskr/__init__.py deleted file mode 100644 index a00cc28..0000000 --- a/flaskr/__init__.py +++ /dev/null @@ -1,51 +0,0 @@ -# Copyright Sage Vaillancourt 2021 - -import os -from flask import Flask - -import writing - -INDEX = None - - -def optimize_css(css: str) -> str: - import re - minified_with_comments = "".join(list(map( - lambda line: re.sub(r'\s*([:{])\s*', '\1', re.sub(r'^\s*', '', line)), - css.split('\n') - ))) - return re.sub(r'/\*[\s\S]*?\*/', "", minified_with_comments) - - -def optimize_css_file(): - root = os.path.dirname(os.getcwd()) - static_dir = root + '/undercover/flaskr/static/' - css = open(static_dir + 'styles.css', 'r').read() - minified = optimize_css(css) - minified_file = open(static_dir + 'styles_min.css', 'w') - minified_file.write(minified) - minified_file.close() - - -def create_app(test_config=None): - optimize_css_file() - - app = Flask(__name__, instance_relative_config=True) - app.config.from_mapping( - SECRET_KEY='dev', - DATABASE=os.path.join(app.instance_path, 'flaskr.sqlite'), - ) - - if test_config is None: - app.config.from_pyfile('config.py', silent=True) - else: - app.config.from_mapping(test_config) - - os.makedirs(app.instance_path, exist_ok=True) - - app.register_blueprint( - writing.writing_blueprint, - # url_prefix='/writing', - ) - - return app diff --git a/writing_templates/base.tex b/letter_templates/base.tex similarity index 100% rename from writing_templates/base.tex rename to letter_templates/base.tex diff --git a/writing_templates/default.tex b/letter_templates/default.tex similarity index 100% rename from writing_templates/default.tex rename to letter_templates/default.tex diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..6a58c0c --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,4 @@ +[tool.pytest.ini_options] +pythonpath = [ + "." +] \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 5d9fa7b..d67bd53 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,6 +7,7 @@ gunicorn==20.1.0 itsdangerous==2.1.2 Jinja2==3.1.2 MarkupSafe==2.1.1 -psycopg==3.1.1 +psycopg==3.1.2 +pytest==7.1.3 Werkzeug==2.2.2 WTForms==3.0.1 diff --git a/start b/start index 8f5cf27..baf1702 100755 --- a/start +++ b/start @@ -14,10 +14,10 @@ fi if [[ "$1" == "prod" ]]; then echo "Starting gunicorn production server..." - gunicorn -b 0.0.0.0:443 "flaskr:create_app()" + gunicorn -b 0.0.0.0:443 "undercover:create_app()" else echo "Starting local dev server..." export FLASK_ENV=development - export FLASK_APP=flaskr + export FLASK_APP=undercover flask run --host=0.0.0.0 fi diff --git a/tests/test_css.py b/tests/test_css.py new file mode 100644 index 0000000..af9dc40 --- /dev/null +++ b/tests/test_css.py @@ -0,0 +1,23 @@ +from undercover import css + + +def test_empty_string(): + assert css.optimize_css("") == "" + + +def test_simple_definition(): + simple_definition = """ + div { + width: 100%; + } + """ + assert css.optimize_css(simple_definition) == "div{width:100%;}" + + +def test_multi_part_property(): + simple_definition = """ + div { + padding: 1em 2em 3em 4em; + } + """ + assert css.optimize_css(simple_definition) == "div{padding:1em 2em 3em 4em;}" diff --git a/undercover/__init__.py b/undercover/__init__.py new file mode 100644 index 0000000..9e24620 --- /dev/null +++ b/undercover/__init__.py @@ -0,0 +1,29 @@ +# Copyright Sage Vaillancourt 2021 + +import os + +from flask import Flask + +import undercover.routes +from undercover.css import optimize_css_file + + +def create_app(test_config=None): + optimize_css_file() + + app = Flask(__name__, instance_relative_config=True) + app.config.from_mapping( + SECRET_KEY='dev', + DATABASE=os.path.join(app.instance_path, 'undercover.sqlite'), + ) + + if test_config is None: + app.config.from_pyfile('config.py', silent=True) + else: + app.config.from_mapping(test_config) + + os.makedirs(app.instance_path, exist_ok=True) + + app.register_blueprint(routes.writing_blueprint) + + return app diff --git a/undercover/css.py b/undercover/css.py new file mode 100644 index 0000000..69b0ca1 --- /dev/null +++ b/undercover/css.py @@ -0,0 +1,22 @@ +import os + + +def optimize_css(css: str) -> str: + import re + minified_with_comments = "".join(list(map( + lambda line: re.sub(r'\s*([:{])\s*', r'\1', re.sub(r'^\s*', '', line)), + css.split('\n') + ))) + return re.sub(r'/\*[\s\S]*?\*/', "", minified_with_comments) + + +def optimize_css_file(): + root = os.path.dirname(os.getcwd()) + static_dir = root + '/undercover/undercover/static/' + css = open(static_dir + 'styles.css', 'r').read() + minified = optimize_css(css) + minified_file = open(static_dir + 'styles_min.css', 'w') + minified_file.write(minified) + minified_file.close() + + diff --git a/flaskr/db.py b/undercover/db.py similarity index 81% rename from flaskr/db.py rename to undercover/db.py index 82a6e17..d69d519 100644 --- a/flaskr/db.py +++ b/undercover/db.py @@ -1,8 +1,9 @@ -import bcrypt import os -import psycopg from dataclasses import dataclass +import bcrypt +import psycopg + @dataclass class Letter: @@ -118,22 +119,23 @@ def get_users() -> [UserWithHash]: return map(lambda row: UserWithHash(row[0], row[1], row[2]), cur.fetchall()) -add_user("hash_man", "hashword") -print("Can pull correctly: " + str(login("hash_man", "hashword"))) -delete_user("hash_man") -# add_letter(1, "Dynamically-added", "This is a letter added from Python!") -# edit_letter(3, "Dynamically edited!", "This letter was dynamically edited from Python!") +if __name__ == "__main__": + add_user("hash_man", "hashword") + print("Can pull correctly: " + str(login("hash_man", "hashword"))) + delete_user("hash_man") + # add_letter(1, "Dynamically-added", "This is a letter added from Python!") + # edit_letter(3, "Dynamically edited!", "This letter was dynamically edited from Python!") -# for letter in get_user_letters(1): -# print("\'" + letter.title + "\"" + ":") -# print(" id: " + str(letter.id)) -# print(" letter-data: " + letter.contents) -# print() + # for letter in get_user_letters(1): + # print("\'" + letter.title + "\"" + ":") + # print(" id: " + str(letter.id)) + # print(" letter-data: " + letter.contents) + # print() -# for user in get_users(): -# print(user.email + ":") -# print(" id: " + str(user.id)) -# print(" password: " + user.password_hash) -# print() + # for user in get_users(): + # print(user.email + ":") + # print(" id: " + str(user.id)) + # print(" password: " + user.password_hash) + # print() diff --git a/latty.py b/undercover/latty.py similarity index 97% rename from latty.py rename to undercover/latty.py index 7d994bf..064e974 100644 --- a/latty.py +++ b/undercover/latty.py @@ -3,6 +3,7 @@ import os import subprocess from dataclasses import dataclass + from flask import send_from_directory @@ -21,7 +22,7 @@ def get_datetime(): root_dir = os.path.dirname(os.getcwd()) proj_dir = root_dir + '/undercover/' output_dir = proj_dir + 'outputs/' -base_tex_text = open(proj_dir + "/writing_templates/base.tex", "r").read() +base_tex_text = open(proj_dir + "/letter_templates/base.tex", "r").read() @dataclass diff --git a/writing.py b/undercover/routes.py similarity index 94% rename from writing.py rename to undercover/routes.py index a85ab05..9508201 100644 --- a/writing.py +++ b/undercover/routes.py @@ -1,17 +1,17 @@ # Copyright Sage Vaillancourt 2021 -from flask import (Blueprint, render_template, request, make_response) -from wtforms import Form, StringField, TextAreaField, validators -import urllib.parse - -from latty import CLData -import flaskr -import flaskr.db as db import os import subprocess import threading +import urllib.parse +from flask import (Blueprint, render_template, request, make_response) +from wtforms import Form, StringField, TextAreaField, validators +import undercover.db as db +from undercover.latty import CLData + +index_cache = None writing_blueprint = Blueprint('writing', __name__,) @@ -65,12 +65,13 @@ class CLForm(Form): @writing_blueprint.route('/', methods=['GET']) def index_get(): - if flaskr.INDEX is None: - flaskr.INDEX = render_template( + global index_cache + if not index_cache: + index_cache = render_template( 'writing.jinja2', form=CLForm() ) - return flaskr.INDEX + return index_cache @writing_blueprint.route('/dbtest', methods=['GET']) diff --git a/flaskr/static/styles.css b/undercover/static/styles.css similarity index 100% rename from flaskr/static/styles.css rename to undercover/static/styles.css diff --git a/flaskr/templates/_formhelpers.jinja2 b/undercover/templates/_formhelpers.jinja2 similarity index 100% rename from flaskr/templates/_formhelpers.jinja2 rename to undercover/templates/_formhelpers.jinja2 diff --git a/flaskr/templates/writing.jinja2 b/undercover/templates/writing.jinja2 similarity index 100% rename from flaskr/templates/writing.jinja2 rename to undercover/templates/writing.jinja2