first commit

This commit is contained in:
Ada 2023-09-25 15:30:27 +02:00
commit cfd15eafd1
10 changed files with 201 additions and 0 deletions

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
.ruff_cache/
venv/
.idea/

0
paste/__init__.py Normal file
View file

13
paste/app.py Normal file
View file

@ -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()

8
paste/config.py Normal file
View file

@ -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

40
paste/db.py Normal file
View file

@ -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")

51
paste/home.py Normal file
View file

@ -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("/<path:path>")
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"

View file

@ -0,0 +1,4 @@
<form id="paste-content" method="POST" accept-charset="UTF-8" action="{{ url_for('home.create') }}">
<input name="content">
<button>Create</button>
</form>

15
paste/utils.py Normal file
View file

@ -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)
)

65
pyproject.toml Normal file
View file

@ -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"

2
requirements.txt Normal file
View file

@ -0,0 +1,2 @@
flask==2.3.3
redis==5.0.0