forked from purplebored/purplebored.pl
341
rename.py
341
rename.py
@@ -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())
|
|
||||||
@@ -6,7 +6,7 @@ from warnings import filterwarnings as filter_warnings
|
|||||||
|
|
||||||
from flask import Flask
|
from flask import Flask
|
||||||
|
|
||||||
from flask_app import create_app
|
from pbpl import create_app
|
||||||
|
|
||||||
app: Flask = create_app(__name__)
|
app: Flask = create_app(__name__)
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ Create Date: 2025-07-30 20:21:21.163194
|
|||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
|
||||||
import flask_app
|
import pbpl
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import typing as t
|
|||||||
|
|
||||||
import flask
|
import flask
|
||||||
|
|
||||||
from flask_app import const
|
from pbpl import const
|
||||||
|
|
||||||
__all__: t.Tuple[str, str] = (
|
__all__: t.Tuple[str, str] = (
|
||||||
"proof_of_work_protect_session",
|
"proof_of_work_protect_session",
|
||||||
@@ -8,7 +8,7 @@ from flask_wtf import FlaskForm # type: ignore
|
|||||||
from wtforms import HiddenField, SubmitField, TextAreaField # type: ignore
|
from wtforms import HiddenField, SubmitField, TextAreaField # type: ignore
|
||||||
from wtforms.validators import DataRequired, Length # 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",)
|
__all__: t.Tuple[str, ...] = ("TextForm",)
|
||||||
|
|
||||||
@@ -11,5 +11,5 @@ limiter: Limiter = Limiter(
|
|||||||
get_remote_address,
|
get_remote_address,
|
||||||
default_limits=["125 per minute", "25 per second"],
|
default_limits=["125 per minute", "25 per second"],
|
||||||
storage_uri=f"memcached://{os.environ['MEMCACHED']}",
|
storage_uri=f"memcached://{os.environ['MEMCACHED']}",
|
||||||
key_prefix="flask_app_",
|
key_prefix="pbpl_",
|
||||||
)
|
)
|
||||||
@@ -7,8 +7,8 @@ import typing as t
|
|||||||
|
|
||||||
from sqlalchemy import DateTime, Unicode
|
from sqlalchemy import DateTime, Unicode
|
||||||
|
|
||||||
from flask_app.const import TEXT_SIZE_MAX
|
from pbpl.const import TEXT_SIZE_MAX
|
||||||
from flask_app.db import db
|
from pbpl.db import db
|
||||||
|
|
||||||
__all__: t.Tuple[str] = ("TextModel",)
|
__all__: t.Tuple[str] = ("TextModel",)
|
||||||
|
|
||||||
@@ -7,10 +7,10 @@ import typing as t
|
|||||||
import flask
|
import flask
|
||||||
from werkzeug.wrappers import Response
|
from werkzeug.wrappers import Response
|
||||||
|
|
||||||
import flask_app.forms.prow as form_pow
|
import pbpl.forms.prow as form_pow
|
||||||
import flask_app.forms.text as text_form
|
import pbpl.forms.text as text_form
|
||||||
from flask_app.db import db
|
from pbpl.db import db
|
||||||
from flask_app.models import TextModel
|
from pbpl.models import TextModel
|
||||||
|
|
||||||
from .bp import Bp
|
from .bp import Bp
|
||||||
|
|
||||||
Reference in New Issue
Block a user