Rename Flask template app to pbpl

Signed-off-by: Arija A. <ari@ari.lt>
This commit is contained in:
2025-10-23 20:38:04 +03:00
parent caf4ac7c06
commit 56aee59790
15 changed files with 11 additions and 352 deletions

341
rename.py
View File

@@ -1,341 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Rename the main Flask module to a non-common name"""
import os
import re
import sys
import typing as t
from warnings import filterwarnings as filter_warnings
COMMON_MODULES: t.Final[t.Set[str]] = {
"abc",
"aifc",
"argparse",
"array",
"ast",
"asynchat",
"asyncio",
"asyncore",
"base64",
"bdb",
"bin",
"binascii",
"bisect",
"builtins",
"bz2",
"calendar",
"cgi",
"cgitb",
"chunk",
"cmath",
"cmd",
"code",
"click",
"codecs",
"collections",
"colorsys",
"compileall",
"concurrent",
"configparser",
"contextlib",
"copy",
"copyreg",
"crypt",
"csv",
"ctypes",
"curses",
"dataclasses",
"datetime",
"dbm",
"decimal",
"difflib",
"dis",
"distutils",
"doctest",
"email",
"encodings",
"enum",
"errno",
"faulthandler",
"fcntl",
"filecmp",
"fileinput",
"fnmatch",
"formatter",
"fractions",
"ftplib",
"functools",
"gc",
"getopt",
"getpass",
"gettext",
"glob",
"gzip",
"hashlib",
"heapq",
"hmac",
"html",
"http",
"idlelib",
"imaplib",
"imghdr",
"imp",
"importlib",
"inspect",
"io",
"ipaddress",
"itertools",
"json",
"keyword",
"lib2to3",
"linecache",
"locale",
"logging",
"lzma",
"mailcap",
"marshal",
"math",
"mimetypes",
"mmap",
"modulefinder",
"multiprocessing",
"netrc",
"nis",
"nntplib",
"numbers",
"operator",
"optparse",
"os",
"parser",
"pathlib",
"pdb",
"pickle",
"pickletools",
"pip",
"pkgutil",
"platform",
"plistlib",
"poplib",
"posix",
"pprint",
"profile",
"pstats",
"pty",
"pwd",
"py_compile",
"pyclbr",
"pydoc",
"queue",
"quopri",
"random",
"re",
"readline",
"reprlib",
"resource",
"rlcompleter",
"runpy",
"sched",
"secrets",
"select",
"selectors",
"shelve",
"shlex",
"shutil",
"signal",
"site",
"smtp",
"socket",
"socketserver",
"sqlite3",
"sre_compile",
"sre_constants",
"sre_parse",
"ssl",
"stat",
"statistics",
"string",
"stringprep",
"struct",
"subprocess",
"sunau",
"symtable",
"sys",
"sysconfig",
"tabnanny",
"tarfile",
"telnetlib",
"tempfile",
"termios",
"test",
"textwrap",
"threading",
"time",
"timeit",
"tkinter",
"token",
"tokenize",
"trace",
"traceback",
"tracemalloc",
"tty",
"turtle",
"turtledemo",
"types",
"typing",
"unicodedata",
"unittest",
"urllib",
"uu",
"uuid",
"venv",
"warnings",
"wave",
"weakref",
"webbrowser",
"winreg",
"winsound",
"wsgiref",
"xdrlib",
"xml",
"xmlrpc",
"zipapp",
"zipfile",
"zipimport",
"zlib",
"werkzeug",
"jinja2",
"sqlalchemy",
"requests",
"pytest",
"celery",
"gunicorn",
"alembic",
"bcrypt",
"pillow",
"marshmallow",
"main",
"app",
"init",
"src",
"env",
"dotenv",
"application",
"web",
"www",
"webapp",
"cryptography",
"pycryptodome",
"hashing",
"aes",
"rsa",
"des",
"ssh",
"itsdangerous",
"werkzeug",
"portalocker",
"all",
"any",
"max",
"min",
"pow",
"bleach",
}
def sanitize_module_name(name: str) -> str:
"""Sanitize module name to be a valid Python module name token"""
name = name.strip()
name = name.lower()
name = re.sub(r"[^a-z0-9_]", "_", name)
name = re.sub(r"_+", "_", name)
name = name.strip("_")
if re.match(r"^[0-9]", name):
name = f"_{name}"
return name
def replace_in_file(filepath: str, old: str, new: str) -> None:
"""Read file, replace all occurrences of old with new, write back"""
with open(filepath, "r", encoding="utf-8") as fr:
content: str = fr.read()
new_content: str = content.replace(old, new)
if new_content != content:
with open(filepath, "w", encoding="utf-8") as fw:
fw.write(new_content)
def main() -> int:
"""entry / main function"""
if len(sys.argv) < 2:
print("Rename this template to your preferred name", file=sys.stderr)
print(f"Usage: {sys.argv[0]} <newname>", file=sys.stderr)
return 1
flask_app_dir: str = os.path.join(".", "src", "flask_app")
if not os.path.isdir(flask_app_dir):
print("The application has already been renamed", file=sys.stderr)
return 1
module: str = sanitize_module_name(sys.argv[1])
if not module:
print("The module name must be non-empty", file=sys.stderr)
return 1
if module.startswith("flask"):
print(
"Module name cannot start with 'flask' to avoid conflicts", file=sys.stderr
)
return 1
if module.startswith("_"):
print("Module name cannot start with '_' to avoid conflicts", file=sys.stderr)
return 1
if module in COMMON_MODULES:
print(
f"'{module}' is a reserved module name, please choose another",
file=sys.stderr,
)
return 1
module_dir: str = os.path.join(".", "src", module)
module_file: str = os.path.join(".", "src", f"{module}.py")
if os.path.exists(module_dir) or os.path.exists(module_file):
print(
f"Invalid module name {module} (already exists)", file=sys.stderr
)
return 1
yn: str = input(f"Rename application module to {module}? (y/n) ").strip().lower()
if not yn.startswith("y"):
print("Not renaming the app", file=sys.stderr)
return 1
os.rename(flask_app_dir, module_dir)
for root, _, files in os.walk(os.path.join(".", "src")):
for filename in files:
if filename.endswith(".py"):
filepath: str = os.path.join(root, filename)
replace_in_file(filepath, "flask_app", module)
print(
f"Main module successfully renamed to {module}! You may now remove {sys.argv[0]}"
)
return 0
if __name__ == "__main__":
assert main.__annotations__.get("return") is int, "main() should return an integer"
filter_warnings("error", category=Warning)
raise SystemExit(main())

View File

@@ -6,7 +6,7 @@ from warnings import filterwarnings as filter_warnings
from flask import Flask
from flask_app import create_app
from pbpl import create_app
app: Flask = create_app(__name__)

View File

@@ -8,7 +8,7 @@ Create Date: 2025-07-30 20:21:21.163194
from alembic import op
import sqlalchemy as sa
import flask_app
import pbpl

View File

@@ -9,7 +9,7 @@ import typing as t
import flask
from flask_app import const
from pbpl import const
__all__: t.Tuple[str, str] = (
"proof_of_work_protect_session",

View File

@@ -8,7 +8,7 @@ from flask_wtf import FlaskForm # type: ignore
from wtforms import HiddenField, SubmitField, TextAreaField # type: ignore
from wtforms.validators import DataRequired, Length # type: ignore
from flask_app.const import TEXT_SIZE_MAX
from pbpl.const import TEXT_SIZE_MAX
__all__: t.Tuple[str, ...] = ("TextForm",)

View File

@@ -11,5 +11,5 @@ limiter: Limiter = Limiter(
get_remote_address,
default_limits=["125 per minute", "25 per second"],
storage_uri=f"memcached://{os.environ['MEMCACHED']}",
key_prefix="flask_app_",
key_prefix="pbpl_",
)

View File

@@ -7,8 +7,8 @@ import typing as t
from sqlalchemy import DateTime, Unicode
from flask_app.const import TEXT_SIZE_MAX
from flask_app.db import db
from pbpl.const import TEXT_SIZE_MAX
from pbpl.db import db
__all__: t.Tuple[str] = ("TextModel",)

View File

@@ -7,10 +7,10 @@ import typing as t
import flask
from werkzeug.wrappers import Response
import flask_app.forms.prow as form_pow
import flask_app.forms.text as text_form
from flask_app.db import db
from flask_app.models import TextModel
import pbpl.forms.prow as form_pow
import pbpl.forms.text as text_form
from pbpl.db import db
from pbpl.models import TextModel
from .bp import Bp