From cfd15eafd1fd7ea3ec4f4ae1dac730d57ccf566f Mon Sep 17 00:00:00 2001 From: Ada Date: Mon, 25 Sep 2023 15:30:27 +0200 Subject: [PATCH] first commit --- .gitignore | 3 ++ paste/__init__.py | 0 paste/app.py | 13 ++++++++ paste/config.py | 8 +++++ paste/db.py | 40 ++++++++++++++++++++++ paste/home.py | 51 ++++++++++++++++++++++++++++ paste/templates/home.html.j2 | 4 +++ paste/utils.py | 15 +++++++++ pyproject.toml | 65 ++++++++++++++++++++++++++++++++++++ requirements.txt | 2 ++ 10 files changed, 201 insertions(+) create mode 100644 .gitignore create mode 100644 paste/__init__.py create mode 100644 paste/app.py create mode 100644 paste/config.py create mode 100644 paste/db.py create mode 100644 paste/home.py create mode 100644 paste/templates/home.html.j2 create mode 100644 paste/utils.py create mode 100644 pyproject.toml create mode 100644 requirements.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2cf0aab --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.ruff_cache/ +venv/ +.idea/ diff --git a/paste/__init__.py b/paste/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/paste/app.py b/paste/app.py new file mode 100644 index 0000000..f168b73 --- /dev/null +++ b/paste/app.py @@ -0,0 +1,13 @@ +"""Main app file.""" + +from flask import Flask + +from paste.home import home + +app = Flask(__name__) + + +app.register_blueprint(home) + +if __name__ == "__main__": + app.run() diff --git a/paste/config.py b/paste/config.py new file mode 100644 index 0000000..b7280d1 --- /dev/null +++ b/paste/config.py @@ -0,0 +1,8 @@ +"""Manage app config from env.""" +from os import getenv + +REDIS_HOST = getenv("PASTE_REDIS_HOST") or "localhost" +REDIS_PORT = getenv("PASTE_REDIS_HOST") or "6379" +REDIS_USER = getenv("PASTE_REDIS_USER") or None +REDIS_PASSWORD = getenv("PASTE_REDIS_PASSWORD") or None +URL_LENGTH = getenv("PASTE_URL_LENGTH") or 4 diff --git a/paste/db.py b/paste/db.py new file mode 100644 index 0000000..24e2dfa --- /dev/null +++ b/paste/db.py @@ -0,0 +1,40 @@ +"""Manage db connection and insert.""" +import logging + +from redis import Redis + +from paste import config + + +def connect_redis() -> Redis: + """ + Connect to redis. + :return: Redis connection object. + """ + return Redis(host=config.REDIS_HOST, port=config.REDIS_PORT) + + +def check_content_exist(key: str) -> bool: + """ + Verify if key already exist in redis db. + :param key: Key to check. + :return: True if existed, else false. + """ + db = connect_redis() + return db.exists(key) + + +def insert_content_db(url_id: str, expiration: int, content: str) -> None: + """ + + :param url_id: key for access to content. + :param expiration: Content expiration in second. + :param content: Paste content + :return: None + """ + if check_content_exist(url_id): + db = connect_redis() + db.set(url_id, content) + db.expire(url_id, expiration) + else: + logging.error(f"Key : {url_id} already exist") diff --git a/paste/home.py b/paste/home.py new file mode 100644 index 0000000..fc4e1a0 --- /dev/null +++ b/paste/home.py @@ -0,0 +1,51 @@ +"""Manage view and create paste.""" +from flask import Blueprint, redirect, render_template, request, url_for + +from paste.db import check_content_exist, connect_redis, insert_content_db +from paste.utils import generate_id + +home = Blueprint("home", __name__, url_prefix="/") + + +def create_paste(content: str) -> None: + """ + Create paste in DB. + :param content: Content to add in redis. + :return: None. + """ + url_id = generate_id() + while check_content_exist(url_id): + url_id = generate_id() + insert_content_db(url_id, 3600, content) + + +@home.route("/") +def homepage() -> str: + """ + Homepage. + :return: Homepage. + """ + return render_template("home.html.j2") + + +@home.route("/create", methods=["POST"]) +def create() -> str: + """ + Receive POST data for create paste. + :return: Redirection to homapage. + """ + content = request.form.get("content") + create_paste(content) + return redirect(url_for("home.homepage")) + + +@home.route("/") +def get_content(path: str) -> str: + """ + Return paste for asked url. + :param path: Requested path. + :return: Paste content. + """ + db = connect_redis() + print(db.get(path)) + return "hello" diff --git a/paste/templates/home.html.j2 b/paste/templates/home.html.j2 new file mode 100644 index 0000000..af1d88d --- /dev/null +++ b/paste/templates/home.html.j2 @@ -0,0 +1,4 @@ +
+ + +
\ No newline at end of file diff --git a/paste/utils.py b/paste/utils.py new file mode 100644 index 0000000..d128385 --- /dev/null +++ b/paste/utils.py @@ -0,0 +1,15 @@ +"""Shared utils function.""" +import random +import string + +from paste import config + + +def generate_id() -> str: + """ + Generate url id format. + :return: Url id. + """ + return "".join( + random.choices(string.ascii_letters + string.digits, k=config.URL_LENGTH) + ) diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..006ee48 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,65 @@ +[tool.ruff] +target-version = "py311" +line-length = 88 +ignore = [ + "D107", # Missing docstring in `__init__` + "D205", # 1 blank line required between summary line and description + "D401", # First line of docstring should be in imperative mood: "X" + "D203", # one-blank-line-before-class + "D212", # multi-line-summary-second-line + "PLR2004", # magic-value-comparison +] +select = [ + "F", # Pyflakes + "E", # pycodestyle + "C90", # mccabe + "I", # isort + "N", # pep8-naming + "D", # pydocstyle + "UP", # pyupgrade + "ANN", # flake8-annotations + "S", # flake8-bandit + "BLE", # flake8-blind-except + "FBT", # flake8-boolean-trap + "B", # flake8-bugbear + "A", # flake8-builtins + "C4", # flake8-comprehensions + "EM", # flake8-errmsg + "ISC", # flake8-implicit-str-concat + "ICN", # flake8-import-conventions + "G", # flake8-logging-format + "INP", # flake8-no-pep420 + "PIE", # flake8-pie + "T20", # flake8-print + "PYI", # flake8-pyi + "Q", # flake8-quotes + "RSE", # flake8-raise + "RET", # flake8-return + "SLOT", # flake8-slots + "SIM", # flake8-simplify + "TID", # flake8-tidy-imports + "TCH", # flake8-type-checking + "ARG", # flake8-unused-arguments + "PTH", # flake8-use-pathlib + "TD", # flake8-todos + "FIX", # flake8-fixme + "ERA", # eradicate + "PGH", # pygrep-hooks + "PL", # Pylint + "TRY", # tryceratops + "FLY", # flynt + "PERF", # Perflint + "RUF", # Ruff-specific rules +] + +exclude = [ + ".git", + ".ruff_cache", + "venv", + "instances", + "schema.sql" +] +format = "grouped" + +[tool.isort] +profile = "black" diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..2810508 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +flask==2.3.3 +redis==5.0.0