9
0
mirror of https://github.com/donlon/cloudflare-error-page.git synced 2026-01-06 15:41:45 +00:00

format Python files with ruff

This commit is contained in:
Anthony Donlon
2025-12-28 23:05:51 +08:00
parent 51cfa6aebc
commit e92ffaf506
9 changed files with 92 additions and 57 deletions

1
.gitignore vendored
View File

@@ -9,5 +9,6 @@ build/
dist/
*.egg-info/
__pycache__/
.ruff_cache/
instance/

View File

@@ -8,6 +8,7 @@ if sys.version_info >= (3, 11):
from typing import NotRequired
else:
from typing import _SpecialForm
NotRequired: _SpecialForm
@@ -69,12 +70,14 @@ class ErrorPageParams(TypedDict):
creator_info: NotRequired[CreatorInfo]
def render(params: ErrorPageParams,
allow_html: bool = True,
template: Template | None = None,
*args: Any,
**kwargs: Any) -> str:
'''Render a customized Cloudflare error page.
def render(
params: ErrorPageParams,
allow_html: bool = True,
template: Template | None = None,
*args: Any,
**kwargs: Any,
) -> str:
"""Render a customized Cloudflare error page.
:param params: Parameters passed to the template. Refer to the project homepage for more information.
:param allow_html: Allow output raw HTML content from parameters. Set to False if you don't trust the source of the params.
@@ -83,7 +86,7 @@ def render(params: ErrorPageParams,
:param args: Additional positional arguments passed to ``Template.render`` function.
:param kwargs: Additional keyword arguments passed to ``Template.render`` function.
:return: The rendered error page as a string.
'''
"""
if not template:
template = base_template
@@ -106,5 +109,6 @@ def render(params: ErrorPageParams,
return template.render(params=params, *args, **kwargs)
__version__ = '0.2.0'
__all__ = ['jinja_env', 'base_template', 'render']

View File

@@ -1,11 +1,10 @@
# SPDX-License-Identifier: MIT
import os
from pathlib import Path
import secrets
import string
import sys
import tomllib
from pathlib import Path
from flask import Flask, redirect, url_for
from flask_limiter import Limiter
@@ -16,17 +15,24 @@ from werkzeug.middleware.proxy_fix import ProxyFix
root_dir = Path(__file__).parent.parent.parent.parent
class Base(DeclarativeBase):
pass
db: SQLAlchemy = SQLAlchemy(model_class=Base, session_options={
# 'autobegin': False,
# 'expire_on_commit': False,
})
db: SQLAlchemy = SQLAlchemy(
model_class=Base,
session_options={
# 'autobegin': False,
# 'expire_on_commit': False,
},
)
limiter: Limiter = Limiter(
key_func=get_remote_address, # Uses client's IP address by default
)
static_dir: str | None = None
def _generate_secret(length=32) -> str:
characters = string.ascii_letters + string.digits # A-Z, a-z, 0-9
@@ -34,10 +40,9 @@ def _generate_secret(length=32) -> str:
def _initialize_app_config(app: Flask):
global static_dir
if app.config.get('BEHIND_PROXY', True):
app.wsgi_app = ProxyFix(
app.wsgi_app, x_for=1, x_proto=1
)
app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1)
secret_key = app.config.get('SECRET_KEY', '')
if secret_key:
app.secret_key = secret_key
@@ -45,12 +50,14 @@ def _initialize_app_config(app: Flask):
app.logger.info('Using generated secret')
app.secret_key = _generate_secret()
app.config["SQLALCHEMY_DATABASE_URI"] = app.config.get('SQLALCHEMY_DATABASE_URI', 'sqlite:///example.db')
if app.config["SQLALCHEMY_DATABASE_URI"].startswith('sqlite'):
app.config["SQLALCHEMY_ENGINE_OPTIONS"] = {
app.config['SQLALCHEMY_DATABASE_URI'] = app.config.get('SQLALCHEMY_DATABASE_URI', 'sqlite:///example.db')
if app.config['SQLALCHEMY_DATABASE_URI'].startswith('sqlite'):
app.config['SQLALCHEMY_ENGINE_OPTIONS'] = {
'isolation_level': 'SERIALIZABLE',
# "execution_options": {"autobegin": False}
}
static_dir = os.path.join(app.instance_path, app.config.get('STATIC_DIR', '../../web/dist'))
app.logger.info(f'Static directory: {static_dir}')
def create_app(test_config=None) -> Flask:
@@ -60,16 +67,12 @@ def create_app(test_config=None) -> Flask:
os.makedirs(instance_path, exist_ok=True)
print(f'App instance path: {instance_path}')
app = Flask(__name__,
instance_path=instance_path,
instance_relative_config=True
)
app.config.from_file("config.toml", load=tomllib.load, text=False)
app = Flask(__name__, instance_path=instance_path, instance_relative_config=True)
app.config.from_file('config.toml', load=tomllib.load, text=False)
_initialize_app_config(app)
from . import utils
from . import models
from . import utils # noqa: F401
from . import models # noqa: F401
from . import examples
from . import editor
from . import share

View File

@@ -30,13 +30,14 @@ bp_short = Blueprint('share_short', __name__, url_prefix='/')
rand_charset = string.ascii_lowercase + string.digits
def get_rand_name(digits=8):
return ''.join(random.choice(rand_charset) for _ in range(digits))
@bp.post('/create')
@limiter.limit("20 per minute")
@limiter.limit("500 per hour")
@limiter.limit('20 per minute')
@limiter.limit('500 per hour')
def create():
if len(request.data) > 4096:
abort(413)
@@ -82,9 +83,7 @@ def get(name: str):
item = db.session.query(models.Item).filter_by(name=name).first()
if not item:
if is_json:
return {
'status': 'notfound'
}
return {'status': 'notfound'}
else:
return abort(404)
params = cast(ErrorPageParams, item.params)
@@ -104,8 +103,7 @@ def get(name: str):
'link': request.host_url[:-1] + url_for('editor.index') + f'#from={name}',
}
sanitize_page_param_links(params)
return render_extended_template(params=params,
allow_html=False)
return render_extended_template(params=params, allow_html=False)
@bp.get('/<name>')

View File

@@ -17,7 +17,7 @@ env = Environment(
trim_blocks=True,
lstrip_blocks=True,
)
template = env.from_string('''{% extends base %}
template = env.from_string("""{% extends base %}
{% block html_head %}
{% if page_icon_url %}
@@ -45,11 +45,12 @@ template = env.from_string('''{% extends base %}
<meta property="twitter:image" content="{{ page_image_url }}" />
{% endif %}
{% endblock %}
''')
""")
loc_data: dict = None
def read_loc_file(path: str):
try:
with open(os.path.join(Path(__file__).parent / path)) as f:
@@ -117,11 +118,9 @@ def sanitize_page_param_links(param: ErrorPageParams):
perf_sec_by['link'] = sanitize_user_link(link)
def render_extended_template(params: ErrorPageParams,
*args: Any,
**kwargs: Any) -> str:
def render_extended_template(params: ErrorPageParams, *args: Any, **kwargs: Any) -> str:
fill_cf_template_params(params)
description = params.get('what_happened') or 'There is an internal server error on Cloudflare\'s network.'
description = params.get('what_happened') or "There is an internal server error on Cloudflare's network."
description = re.sub(r'<\/?.*?>', '', description).strip()
status = 'ok'
@@ -133,13 +132,15 @@ def render_extended_template(params: ErrorPageParams,
page_icon_url = current_app.config.get('PAGE_ICON_URL', '').replace('{status}', status)
page_icon_type = current_app.config.get('PAGE_ICON_TYPE')
page_image_url = current_app.config.get('PAGE_IMAGE_URL', '').replace('{status}', status)
return render_cf_error_page(params=params,
template=template,
base=base_template,
page_icon_url=page_icon_url,
page_icon_type=page_icon_type,
page_url=request.url,
page_description=description,
page_image_url=page_image_url,
*args,
**kwargs)
return render_cf_error_page(
params=params,
template=template,
base=base_template,
page_icon_url=page_icon_url,
page_icon_type=page_icon_type,
page_url=request.url,
page_description=description,
page_image_url=page_image_url,
*args,
**kwargs,
)

View File

@@ -24,3 +24,15 @@ include = ["app/**/*"]
[tool.hatch.build.targets.wheel.hooks.custom]
path = "hatch_build.py"
[tool.ruff]
line-length = 120
target-version = "py313"
[tool.ruff.lint]
ignore = [
'E722', # Bare-except
]
[tool.ruff.format]
quote-style = "single"

View File

@@ -46,3 +46,19 @@ path = "scripts/hatch_build.py"
[tool.hatch.version]
path = "cloudflare_error_page/__init__.py"
[tool.ruff]
line-length = 120
target-version = "py310"
include = [
"cloudflare_error_page/**/*.py",
"scripts/**/*.py",
]
[tool.ruff.lint]
ignore = [
'E722', # Bare-except
]
[tool.ruff.format]
quote-style = "single"

View File

@@ -9,6 +9,7 @@ from hatchling.builders.hooks.plugin.interface import BuildHookInterface
sys.path.append(os.path.dirname(__file__))
from inline_resources import generate_inlined_css
class CustomBuildHook(BuildHookInterface):
def initialize(self, version: str, build_data: dict[str, Any]):
generate_inlined_css()

View File

@@ -38,8 +38,7 @@ def inline_svg_resources(css_file: str, svg_files: list[str], output_file: str):
def inline_css_resource(original_file: str, css_file: str, output_file: str):
css_data = read_file(css_file)
original_data = read_file(original_file)
original_data = original_data.replace('<!-- @INLINE_CSS_HERE@ -->',
f'<style>{css_data}</style>')
original_data = original_data.replace('<!-- @INLINE_CSS_HERE@ -->', f'<style>{css_data}</style>')
note = 'Note: This file is generated with scripts/inline_resources.py. Please do not edit manually.'
if original_file.endswith('.ejs'):
original_data = f'<%# {note} %>\n' + original_data
@@ -60,7 +59,7 @@ def generate_inlined_css():
'../images/cf-icon-error.svg',
],
os.path.join(resources_folder, 'styles/main.css'),
)
)
if __name__ == '__main__':