junikimm717
2 years ago
commit
1f9aa50769
14 changed files with 728 additions and 0 deletions
-
162.gitignore
-
3.vscode/.gitignore
-
17.vscode/settings.json
-
117app.py
-
11errors.py
-
295poetry.lock
-
19pyproject.toml
-
5templates/admin.html
-
28templates/base.html
-
3templates/errors/403.html
-
3templates/errors/404.html
-
3templates/index.html
-
18templates/login.html
-
44templates/register.html
@ -0,0 +1,162 @@ |
|||
.idea |
|||
/instance |
|||
# Byte-compiled / optimized / DLL files |
|||
__pycache__/ |
|||
*.py[cod] |
|||
*$py.class |
|||
|
|||
# C extensions |
|||
*.so |
|||
|
|||
# Distribution / packaging |
|||
.Python |
|||
build/ |
|||
develop-eggs/ |
|||
dist/ |
|||
downloads/ |
|||
eggs/ |
|||
.eggs/ |
|||
lib/ |
|||
lib64/ |
|||
parts/ |
|||
sdist/ |
|||
var/ |
|||
wheels/ |
|||
share/python-wheels/ |
|||
*.egg-info/ |
|||
.installed.cfg |
|||
*.egg |
|||
MANIFEST |
|||
|
|||
# PyInstaller |
|||
# Usually these files are written by a python script from a template |
|||
# before PyInstaller builds the exe, so as to inject date/other infos into it. |
|||
*.manifest |
|||
*.spec |
|||
|
|||
# Installer logs |
|||
pip-log.txt |
|||
pip-delete-this-directory.txt |
|||
|
|||
# Unit test / coverage reports |
|||
htmlcov/ |
|||
.tox/ |
|||
.nox/ |
|||
.coverage |
|||
.coverage.* |
|||
.cache |
|||
nosetests.xml |
|||
coverage.xml |
|||
*.cover |
|||
*.py,cover |
|||
.hypothesis/ |
|||
.pytest_cache/ |
|||
cover/ |
|||
|
|||
# Translations |
|||
*.mo |
|||
*.pot |
|||
|
|||
# Django stuff: |
|||
*.log |
|||
local_settings.py |
|||
db.sqlite3 |
|||
db.sqlite3-journal |
|||
|
|||
# Flask stuff: |
|||
instance/ |
|||
.webassets-cache |
|||
|
|||
# Scrapy stuff: |
|||
.scrapy |
|||
|
|||
# Sphinx documentation |
|||
docs/_build/ |
|||
|
|||
# PyBuilder |
|||
.pybuilder/ |
|||
target/ |
|||
|
|||
# Jupyter Notebook |
|||
.ipynb_checkpoints |
|||
|
|||
# IPython |
|||
profile_default/ |
|||
ipython_config.py |
|||
|
|||
# pyenv |
|||
# For a library or package, you might want to ignore these files since the code is |
|||
# intended to run in multiple environments; otherwise, check them in: |
|||
# .python-version |
|||
|
|||
# pipenv |
|||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. |
|||
# However, in case of collaboration, if having platform-specific dependencies or dependencies |
|||
# having no cross-platform support, pipenv may install dependencies that don't work, or not |
|||
# install all needed dependencies. |
|||
#Pipfile.lock |
|||
|
|||
# poetry |
|||
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. |
|||
# This is especially recommended for binary packages to ensure reproducibility, and is more |
|||
# commonly ignored for libraries. |
|||
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control |
|||
#poetry.lock |
|||
|
|||
# pdm |
|||
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. |
|||
#pdm.lock |
|||
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it |
|||
# in version control. |
|||
# https://pdm.fming.dev/#use-with-ide |
|||
.pdm.toml |
|||
|
|||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm |
|||
__pypackages__/ |
|||
|
|||
# Celery stuff |
|||
celerybeat-schedule |
|||
celerybeat.pid |
|||
|
|||
# SageMath parsed files |
|||
*.sage.py |
|||
|
|||
# Environments |
|||
.env |
|||
.venv |
|||
env/ |
|||
venv/ |
|||
ENV/ |
|||
env.bak/ |
|||
venv.bak/ |
|||
|
|||
# Spyder project settings |
|||
.spyderproject |
|||
.spyproject |
|||
|
|||
# Rope project settings |
|||
.ropeproject |
|||
|
|||
# mkdocs documentation |
|||
/site |
|||
|
|||
# mypy |
|||
.mypy_cache/ |
|||
.dmypy.json |
|||
dmypy.json |
|||
|
|||
# Pyre type checker |
|||
.pyre/ |
|||
|
|||
# pytype static type analyzer |
|||
.pytype/ |
|||
|
|||
# Cython debug symbols |
|||
cython_debug/ |
|||
|
|||
# PyCharm |
|||
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can |
|||
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore |
|||
# and can be added to the global gitignore or merged into this file. For a more nuclear |
|||
# option (not recommended) you can uncomment the following to ignore the entire idea folder. |
|||
#.idea/ |
@ -0,0 +1,3 @@ |
|||
* |
|||
!settings.json |
|||
!.gitignore |
@ -0,0 +1,17 @@ |
|||
{ |
|||
"editor.defaultFormatter": "esbenp.prettier-vscode", |
|||
"editor.tabSize": 4, |
|||
"[python]": { |
|||
"editor.wordBasedSuggestions": false, |
|||
"editor.defaultFormatter": null |
|||
}, |
|||
/* |
|||
"python.formatting.provider": "autopep8", |
|||
"python.formatting.autopep8Args": [ |
|||
"--max-line-length", |
|||
"120", |
|||
"--experimental" |
|||
], |
|||
*/ |
|||
"editor.bracketPairColorization.enabled": true |
|||
} |
@ -0,0 +1,117 @@ |
|||
#!/usr/bin/env python3 |
|||
|
|||
from flask import Flask, render_template, session, request, abort, redirect, url_for |
|||
from flask_sqlalchemy import SQLAlchemy |
|||
import bcrypt |
|||
|
|||
db: SQLAlchemy = SQLAlchemy() |
|||
app = Flask(__name__) |
|||
|
|||
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///project.db" |
|||
app.secret_key = '98d31240f9fbe14c8083586db49c19c3a8d3f726' |
|||
|
|||
|
|||
class Admin(db.Model): |
|||
id = db.Column(db.Integer, primary_key=True) |
|||
username = db.Column(db.String, unique=True, nullable=False) |
|||
password = db.Column(db.String, nullable=False) |
|||
query: db.Query |
|||
|
|||
@classmethod |
|||
def generate_password(cls, pw: str): |
|||
return bcrypt.hashpw(pw, bcrypt.gensalt(12)) |
|||
|
|||
@classmethod |
|||
def authenticate(cls, username: str, pw: str): |
|||
user = Admin.query.filter_by(username=username).one_or_none() |
|||
if user and bcrypt.checkpw(pw, user.password): |
|||
session['admin'] = user.username |
|||
return user |
|||
else: |
|||
return None |
|||
|
|||
@classmethod |
|||
def exists(cls): |
|||
user = Admin.query.one_or_none() |
|||
return True if user else False |
|||
|
|||
@classmethod |
|||
def authorize(cls): |
|||
if not session.get('admin'): |
|||
return redirect(url_for("admin_login")) |
|||
|
|||
# Error Handlers |
|||
|
|||
@app.errorhandler(404) |
|||
def handler_404(msg): |
|||
return render_template("errors/404.html") |
|||
|
|||
|
|||
@app.errorhandler(403) |
|||
def handler_403(msg): |
|||
return render_template("errors/403.html") |
|||
|
|||
|
|||
# Admin routes |
|||
@app.route('/admin') |
|||
def admin_root(): |
|||
if login := Admin.authorize(): |
|||
return login |
|||
return render_template("admin.html", user=session.get("admin")) |
|||
|
|||
|
|||
@app.route('/admin/create', methods=['GET', 'POST']) |
|||
def admin_create(): |
|||
if Admin.exists(): |
|||
if login := Admin.authorize(): |
|||
return login |
|||
if request.method == "GET": |
|||
return render_template("register.html") |
|||
else: |
|||
username, pw = request.form.get('username'), request.form.get('password') |
|||
if username is None or pw is None: |
|||
return render_template("register.html", fail="Invalid Input.") |
|||
elif db.session.execute(db.select(Admin).filter_by(username=username)).fetchone(): |
|||
return render_template("register.html", fail="Username already exists.") |
|||
else: |
|||
db.session.add(Admin(username=username, password=Admin.generate_password(pw))) |
|||
db.session.commit() |
|||
return render_template("register.html", success=True) |
|||
|
|||
|
|||
@app.route('/admin/login', methods=['GET', 'POST']) |
|||
def admin_login(): |
|||
if request.method == "POST": |
|||
username, pw = request.form.get('username', ''), request.form.get('password', '') |
|||
if Admin.authenticate(username, pw): |
|||
return render_template("login.html", success=True) |
|||
else: |
|||
return render_template("login.html", fail="Could not authenticate.") |
|||
else: |
|||
return render_template("login.html") |
|||
|
|||
|
|||
@app.route('/admin/logout', methods=['GET']) |
|||
def admin_logout(): |
|||
session.pop('admin') |
|||
return redirect(url_for('home')) |
|||
|
|||
|
|||
@app.route("/") |
|||
def home(): |
|||
if Admin.exists(): |
|||
return render_template("index.html") |
|||
else: |
|||
return redirect(url_for("admin_create")) |
|||
|
|||
|
|||
@app.route("/search") |
|||
def search(): |
|||
return "searching url" |
|||
|
|||
|
|||
if __name__ == "__main__": |
|||
db.init_app(app) |
|||
with app.app_context(): |
|||
db.create_all() |
|||
app.run(debug=True) |
@ -0,0 +1,11 @@ |
|||
from flask import render_template, Flask |
|||
|
|||
|
|||
def configure_app(app: Flask): |
|||
@app.errorhandler(404) |
|||
def handler_404(msg): |
|||
return render_template("errors/404.html") |
|||
|
|||
@app.errorhandler(403) |
|||
def handler_403(msg): |
|||
return render_template("errors/403.html") |
@ -0,0 +1,295 @@ |
|||
[[package]] |
|||
name = "autopep8" |
|||
version = "2.0.1" |
|||
description = "A tool that automatically formats Python code to conform to the PEP 8 style guide" |
|||
category = "dev" |
|||
optional = false |
|||
python-versions = ">=3.6" |
|||
|
|||
[package.dependencies] |
|||
pycodestyle = ">=2.10.0" |
|||
tomli = {version = "*", markers = "python_version < \"3.11\""} |
|||
|
|||
[[package]] |
|||
name = "click" |
|||
version = "8.1.3" |
|||
description = "Composable command line interface toolkit" |
|||
category = "main" |
|||
optional = false |
|||
python-versions = ">=3.7" |
|||
|
|||
[package.dependencies] |
|||
colorama = {version = "*", markers = "platform_system == \"Windows\""} |
|||
|
|||
[[package]] |
|||
name = "colorama" |
|||
version = "0.4.6" |
|||
description = "Cross-platform colored terminal text." |
|||
category = "main" |
|||
optional = false |
|||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" |
|||
|
|||
[[package]] |
|||
name = "flask" |
|||
version = "2.2.2" |
|||
description = "A simple framework for building complex web applications." |
|||
category = "main" |
|||
optional = false |
|||
python-versions = ">=3.7" |
|||
|
|||
[package.dependencies] |
|||
click = ">=8.0" |
|||
importlib-metadata = {version = ">=3.6.0", markers = "python_version < \"3.10\""} |
|||
itsdangerous = ">=2.0" |
|||
Jinja2 = ">=3.0" |
|||
Werkzeug = ">=2.2.2" |
|||
|
|||
[package.extras] |
|||
async = ["asgiref (>=3.2)"] |
|||
dotenv = ["python-dotenv"] |
|||
|
|||
[[package]] |
|||
name = "flask-sqlalchemy" |
|||
version = "3.0.2" |
|||
description = "Add SQLAlchemy support to your Flask application." |
|||
category = "main" |
|||
optional = false |
|||
python-versions = ">=3.7" |
|||
|
|||
[package.dependencies] |
|||
Flask = ">=2.2" |
|||
SQLAlchemy = ">=1.4.18" |
|||
|
|||
[[package]] |
|||
name = "greenlet" |
|||
version = "2.0.1" |
|||
description = "Lightweight in-process concurrent programming" |
|||
category = "main" |
|||
optional = false |
|||
python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" |
|||
|
|||
[package.extras] |
|||
docs = ["sphinx", "docutils (<0.18)"] |
|||
test = ["objgraph", "psutil", "faulthandler"] |
|||
|
|||
[[package]] |
|||
name = "importlib-metadata" |
|||
version = "5.2.0" |
|||
description = "Read metadata from Python packages" |
|||
category = "main" |
|||
optional = false |
|||
python-versions = ">=3.7" |
|||
|
|||
[package.dependencies] |
|||
zipp = ">=0.5" |
|||
|
|||
[package.extras] |
|||
docs = ["sphinx (>=3.5)", "jaraco.packaging (>=9)", "rst.linker (>=1.9)", "furo", "sphinx-lint", "jaraco.tidelift (>=1.4)"] |
|||
perf = ["ipython"] |
|||
testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "flake8 (<5)", "pytest-cov", "pytest-enabler (>=1.3)", "packaging", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)", "pytest-flake8", "importlib-resources (>=1.3)"] |
|||
|
|||
[[package]] |
|||
name = "itsdangerous" |
|||
version = "2.1.2" |
|||
description = "Safely pass data to untrusted environments and back." |
|||
category = "main" |
|||
optional = false |
|||
python-versions = ">=3.7" |
|||
|
|||
[[package]] |
|||
name = "jinja2" |
|||
version = "3.1.2" |
|||
description = "A very fast and expressive template engine." |
|||
category = "main" |
|||
optional = false |
|||
python-versions = ">=3.7" |
|||
|
|||
[package.dependencies] |
|||
MarkupSafe = ">=2.0" |
|||
|
|||
[package.extras] |
|||
i18n = ["Babel (>=2.7)"] |
|||
|
|||
[[package]] |
|||
name = "markupsafe" |
|||
version = "2.1.1" |
|||
description = "Safely add untrusted strings to HTML/XML markup." |
|||
category = "main" |
|||
optional = false |
|||
python-versions = ">=3.7" |
|||
|
|||
[[package]] |
|||
name = "py-bcrypt" |
|||
version = "0.4" |
|||
description = "bcrypt password hashing and key derivation" |
|||
category = "main" |
|||
optional = false |
|||
python-versions = "*" |
|||
|
|||
[[package]] |
|||
name = "pycodestyle" |
|||
version = "2.10.0" |
|||
description = "Python style guide checker" |
|||
category = "dev" |
|||
optional = false |
|||
python-versions = ">=3.6" |
|||
|
|||
[[package]] |
|||
name = "sqlalchemy" |
|||
version = "1.4.45" |
|||
description = "Database Abstraction Library" |
|||
category = "main" |
|||
optional = false |
|||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" |
|||
|
|||
[package.dependencies] |
|||
greenlet = {version = "!=0.4.17", markers = "python_version >= \"3\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\")"} |
|||
|
|||
[package.extras] |
|||
aiomysql = ["greenlet (!=0.4.17)", "aiomysql"] |
|||
aiosqlite = ["typing_extensions (!=3.10.0.1)", "greenlet (!=0.4.17)", "aiosqlite"] |
|||
asyncio = ["greenlet (!=0.4.17)"] |
|||
asyncmy = ["greenlet (!=0.4.17)", "asyncmy (>=0.2.3,!=0.2.4)"] |
|||
mariadb_connector = ["mariadb (>=1.0.1,!=1.1.2)"] |
|||
mssql = ["pyodbc"] |
|||
mssql_pymssql = ["pymssql"] |
|||
mssql_pyodbc = ["pyodbc"] |
|||
mypy = ["sqlalchemy2-stubs", "mypy (>=0.910)"] |
|||
mysql = ["mysqlclient (>=1.4.0,<2)", "mysqlclient (>=1.4.0)"] |
|||
mysql_connector = ["mysql-connector-python"] |
|||
oracle = ["cx_oracle (>=7,<8)", "cx_oracle (>=7)"] |
|||
postgresql = ["psycopg2 (>=2.7)"] |
|||
postgresql_asyncpg = ["greenlet (!=0.4.17)", "asyncpg"] |
|||
postgresql_pg8000 = ["pg8000 (>=1.16.6,!=1.29.0)"] |
|||
postgresql_psycopg2binary = ["psycopg2-binary"] |
|||
postgresql_psycopg2cffi = ["psycopg2cffi"] |
|||
pymysql = ["pymysql (<1)", "pymysql"] |
|||
sqlcipher = ["sqlcipher3-binary"] |
|||
|
|||
[[package]] |
|||
name = "tomli" |
|||
version = "2.0.1" |
|||
description = "A lil' TOML parser" |
|||
category = "dev" |
|||
optional = false |
|||
python-versions = ">=3.7" |
|||
|
|||
[[package]] |
|||
name = "types-flask-sqlalchemy" |
|||
version = "2.5.9" |
|||
description = "Typing stubs for Flask-SQLAlchemy" |
|||
category = "dev" |
|||
optional = false |
|||
python-versions = "*" |
|||
|
|||
[package.dependencies] |
|||
types-SQLAlchemy = "*" |
|||
|
|||
[[package]] |
|||
name = "types-sqlalchemy" |
|||
version = "1.4.53.19" |
|||
description = "Typing stubs for SQLAlchemy" |
|||
category = "dev" |
|||
optional = false |
|||
python-versions = "*" |
|||
|
|||
[[package]] |
|||
name = "werkzeug" |
|||
version = "2.2.2" |
|||
description = "The comprehensive WSGI web application library." |
|||
category = "main" |
|||
optional = false |
|||
python-versions = ">=3.7" |
|||
|
|||
[package.dependencies] |
|||
MarkupSafe = ">=2.1.1" |
|||
|
|||
[package.extras] |
|||
watchdog = ["watchdog"] |
|||
|
|||
[[package]] |
|||
name = "zipp" |
|||
version = "3.11.0" |
|||
description = "Backport of pathlib-compatible object wrapper for zip files" |
|||
category = "main" |
|||
optional = false |
|||
python-versions = ">=3.7" |
|||
|
|||
[package.extras] |
|||
docs = ["sphinx (>=3.5)", "jaraco.packaging (>=9)", "rst.linker (>=1.9)", "furo", "jaraco.tidelift (>=1.4)"] |
|||
testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "flake8 (<5)", "pytest-cov", "pytest-enabler (>=1.3)", "jaraco.itertools", "func-timeout", "jaraco.functools", "more-itertools", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)", "pytest-flake8"] |
|||
|
|||
[metadata] |
|||
lock-version = "1.1" |
|||
python-versions = "^3.9" |
|||
content-hash = "54b3e8cb9fa3e9c6b85642bc519182772dac7ede4030fa8209e2510ccdbcd90c" |
|||
|
|||
[metadata.files] |
|||
autopep8 = [] |
|||
click = [ |
|||
{file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, |
|||
{file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, |
|||
] |
|||
colorama = [] |
|||
flask = [] |
|||
flask-sqlalchemy = [] |
|||
greenlet = [] |
|||
importlib-metadata = [] |
|||
itsdangerous = [] |
|||
jinja2 = [ |
|||
{file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, |
|||
{file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, |
|||
] |
|||
markupsafe = [ |
|||
{file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812"}, |
|||
{file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a"}, |
|||
{file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e"}, |
|||
{file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5"}, |
|||
{file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4"}, |
|||
{file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f"}, |
|||
{file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e"}, |
|||
{file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933"}, |
|||
{file = "MarkupSafe-2.1.1-cp310-cp310-win32.whl", hash = "sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6"}, |
|||
{file = "MarkupSafe-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417"}, |
|||
{file = "MarkupSafe-2.1.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02"}, |
|||
{file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a"}, |
|||
{file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37"}, |
|||
{file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980"}, |
|||
{file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a"}, |
|||
{file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3"}, |
|||
{file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a"}, |
|||
{file = "MarkupSafe-2.1.1-cp37-cp37m-win32.whl", hash = "sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff"}, |
|||
{file = "MarkupSafe-2.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a"}, |
|||
{file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452"}, |
|||
{file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003"}, |
|||
{file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1"}, |
|||
{file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601"}, |
|||
{file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925"}, |
|||
{file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f"}, |
|||
{file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88"}, |
|||
{file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63"}, |
|||
{file = "MarkupSafe-2.1.1-cp38-cp38-win32.whl", hash = "sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1"}, |
|||
{file = "MarkupSafe-2.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7"}, |
|||
{file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a"}, |
|||
{file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f"}, |
|||
{file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6"}, |
|||
{file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77"}, |
|||
{file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603"}, |
|||
{file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7"}, |
|||
{file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135"}, |
|||
{file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96"}, |
|||
{file = "MarkupSafe-2.1.1-cp39-cp39-win32.whl", hash = "sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c"}, |
|||
{file = "MarkupSafe-2.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247"}, |
|||
{file = "MarkupSafe-2.1.1.tar.gz", hash = "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b"}, |
|||
] |
|||
py-bcrypt = [] |
|||
pycodestyle = [] |
|||
sqlalchemy = [] |
|||
tomli = [ |
|||
{file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, |
|||
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, |
|||
] |
|||
types-flask-sqlalchemy = [] |
|||
types-sqlalchemy = [] |
|||
werkzeug = [] |
|||
zipp = [] |
@ -0,0 +1,19 @@ |
|||
[tool.poetry] |
|||
name = "flask-sample" |
|||
version = "0.1.0" |
|||
description = "" |
|||
authors = ["junikimm717 <68165832+junikimm717@users.noreply.github.com>"] |
|||
|
|||
[tool.poetry.dependencies] |
|||
python = "^3.9" |
|||
flask-sqlalchemy = "^3.0.2" |
|||
Flask = "^2.2.2" |
|||
py-bcrypt = "^0.4" |
|||
|
|||
[tool.poetry.dev-dependencies] |
|||
autopep8 = "^2.0.1" |
|||
types-Flask-SQLAlchemy = "^2.5.9" |
|||
|
|||
[build-system] |
|||
requires = ["poetry-core>=1.0.0"] |
|||
build-backend = "poetry.core.masonry.api" |
@ -0,0 +1,5 @@ |
|||
{% extends "base.html" %} |
|||
{% block content %} |
|||
<h1>Admin Dashboard</h1> |
|||
<p>You are {{user}}</p> |
|||
{% endblock %} |
@ -0,0 +1,28 @@ |
|||
<!DOCTYPE html> |
|||
<html lang="en"> |
|||
<head> |
|||
<meta charset="UTF-8" /> |
|||
<meta http-equiv="X-UA-Compatible" content="IE=edge" /> |
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
|||
<title>DWalker Website</title> |
|||
<meta |
|||
name="description" |
|||
content="A website for aggregating and searching exposome data" |
|||
/> |
|||
<link rel="stylesheet" href="https://cdn.simplecss.org/simple.min.css" /> |
|||
</head> |
|||
<body> |
|||
<header> |
|||
<nav> |
|||
<a href="{{ url_for('home') }}">Home</a> |
|||
{% if session.admin %} |
|||
<a href="{{ url_for('admin_root') }}">Admin</a> |
|||
<a href="{{ url_for('admin_logout') }}">Logout</a> |
|||
{% else %} |
|||
<a href="{{ url_for('admin_login') }}">Login</a> |
|||
{% endif %} |
|||
</nav> |
|||
</header> |
|||
<main>{% block content %} {% endblock %}</main> |
|||
</body> |
|||
</html> |
@ -0,0 +1,3 @@ |
|||
{% extends 'base.html' %} {%block content%} |
|||
<h1>403 Forbidden</h1> |
|||
{%endblock%} |
@ -0,0 +1,3 @@ |
|||
{% extends 'base.html' %} {%block content%} |
|||
<h1>404 Not Found</h1> |
|||
{%endblock%} |
@ -0,0 +1,3 @@ |
|||
{% extends 'base.html' %} {%block content%} |
|||
<h1>Exposome Database Website</h1> |
|||
{%endblock%} |
@ -0,0 +1,18 @@ |
|||
{% extends "base.html" %} |
|||
{% block content %} |
|||
<h1>Admin Login</h1> |
|||
<form method="post"> |
|||
<label for="username">Username:</label> |
|||
<input id="username" name="username" type="text" required="required"> |
|||
<br> |
|||
<label for="password">Password:</label> |
|||
<input id="password" name="password" type="password" required="required"> |
|||
<br> |
|||
<input type="submit" value="Submit"> |
|||
</form> |
|||
{% if success %} |
|||
<p style="color:darkgreen">Login Successful!</p> |
|||
{% elif fail %} |
|||
<p style="color:darkred">Login Failed. Please try again.</p> |
|||
{% endif %} |
|||
{% endblock %} |
@ -0,0 +1,44 @@ |
|||
{% extends "base.html" %} |
|||
{% block content %} |
|||
<h1>Admin Login</h1> |
|||
<script defer> |
|||
window.onload = () => { |
|||
const uname_el = document.getElementById("username") |
|||
const pw_el = document.getElementById("password") |
|||
const rec_el = document.getElementById("reconfirm") |
|||
function check_equal() { |
|||
const uname = uname_el.value |
|||
const pw = pw_el.value |
|||
const rec = rec_el.value |
|||
if (pw.length > 0 && rec === pw && uname.length > 0) { |
|||
console.log("happens!") |
|||
document.getElementById("matches").innerHTML = `<div style='color:darkgreen'>Matches!</div>` |
|||
document.getElementById("submit").disabled = false |
|||
} else { |
|||
document.getElementById("matches").innerHTML = `<div style='color:darkred'>Does not Match!</div>` |
|||
document.getElementById("submit").disabled = true |
|||
} |
|||
} |
|||
uname_el.addEventListener("input", check_equal) |
|||
pw_el.addEventListener("input", check_equal) |
|||
rec_el.addEventListener("input", check_equal) |
|||
} |
|||
</script> |
|||
<form method="post"> |
|||
<label for="username">Username:</label> |
|||
<input id="username" name="username" type="text" required="required"> |
|||
<br> |
|||
<label for="password">Password:</label> |
|||
<input id="password" name="password" type="password" required="required"> |
|||
<br> |
|||
<label for="reconfirm">Reconfirm Password: <span id="matches"></span></label> |
|||
<input id="reconfirm" name="reconfirm" type="password" required="required"> |
|||
<br> |
|||
<input type="submit" value="Submit" disabled="disabled" id="submit"> |
|||
</form> |
|||
{% if success %} |
|||
<p style="color:darkgreen">Login Successful!</p> |
|||
{% elif fail %} |
|||
<p style="color:darkred">Login Failed. Please try again. {{fail}}</p> |
|||
{% endif %} |
|||
{% endblock %} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue