diff --git a/cloudflare_error_page/__init__.py b/cloudflare_error_page/__init__.py
index db47b0f..6f6d0c3 100644
--- a/cloudflare_error_page/__init__.py
+++ b/cloudflare_error_page/__init__.py
@@ -14,13 +14,6 @@ env = Environment(
default_template = env.get_template("error.html")
-def get_resources_folder() -> str:
- """
- Get resources folder that contains stylesheet and icons for the error page.
- If you pass resources_use_cdn=True to render(), local resources are not used.
- """
- return os.path.join(os.path.dirname(os.path.abspath(__file__)), 'resources')
-
def fill_params(params: dict):
if not params.get('time'):
@@ -30,7 +23,7 @@ def fill_params(params: dict):
params['ray_id'] = secrets.token_hex(8)
-def render(params: dict, allow_html: bool=True, use_cdn: bool=True) -> str:
+def render(params: dict, allow_html: bool=True) -> str:
"""
Render a customized Cloudflare error page.
"""
@@ -40,4 +33,4 @@ def render(params: dict, allow_html: bool=True, use_cdn: bool=True) -> str:
params['what_happened'] = html.escape(params.get('what_happened', ''))
params['what_can_i_do'] = html.escape(params.get('what_can_i_do', ''))
- return default_template.render(params=params, resources_use_cdn=use_cdn)
+ return default_template.render(params=params)
diff --git a/cloudflare_error_page/templates/error.html b/cloudflare_error_page/templates/error.html
index 22953ec..7cb6511 100644
--- a/cloudflare_error_page/templates/error.html
+++ b/cloudflare_error_page/templates/error.html
@@ -1,5 +1,4 @@
-{% set resources_cdn = 'https://cloudflare.com' if resources_use_cdn else '' %}
-
+{# Note: This is generated with scripts/inline_resources.py. Please do not edit this file manually. #}
@@ -16,7 +15,8 @@
{% block header %}{% endblock %}
-
+
diff --git a/editor/resources/index.html b/editor/resources/index.html
index be4e41d..c81cbc4 100644
--- a/editor/resources/index.html
+++ b/editor/resources/index.html
@@ -299,10 +299,9 @@
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds} UTC`;
}
- function renderEjs(params, use_cdn = true) {
+ function renderEjs(params) {
return template({
params: params,
- resources_use_cdn: use_cdn
})
}
diff --git a/editor/resources/template.ejs b/editor/resources/template.ejs
index 84f0f30..5346a48 100644
--- a/editor/resources/template.ejs
+++ b/editor/resources/template.ejs
@@ -1,6 +1,4 @@
-<%
-let resources_cdn = resources_use_cdn ? 'https://cloudflare.com' : '';
-%>
+<%# Note: This is generated with scripts/inline_resources.py. Please do not edit this file manually. %>
@@ -18,7 +16,8 @@ let html_title_output = params.html_title || (error_code + ': ' + title);
-
+
diff --git a/editor/server/examples.py b/editor/server/examples.py
index bc3f80f..e98c41e 100644
--- a/editor/server/examples.py
+++ b/editor/server/examples.py
@@ -53,4 +53,4 @@ def index(name: str):
fill_cf_template_params(params)
# Render the error page
- return render_cf_error_page(params, use_cdn=True)
+ return render_cf_error_page(params)
diff --git a/editor/server/share.py b/editor/server/share.py
index f13253e..42df085 100644
--- a/editor/server/share.py
+++ b/editor/server/share.py
@@ -125,5 +125,4 @@ def get(name: str):
return template.render(base=cf_template,
params=params,
url=request.url,
- description='Cloudflare error page',
- resources_use_cdn=True)
+ description='Cloudflare error page')
diff --git a/examples/flask_demo.py b/examples/flask_demo.py
index 0dd9727..e05367f 100755
--- a/examples/flask_demo.py
+++ b/examples/flask_demo.py
@@ -14,22 +14,10 @@ from flask import (
examples_dir = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.dirname(examples_dir))
-from cloudflare_error_page import get_resources_folder, render as render_cf_error_page
+from cloudflare_error_page import render as render_cf_error_page
app = Flask(__name__)
-# Resources required for the error page can be loaded from Cloudflare CDN. But in case of changes, you can set use_cdn = False to use bundled resources.
-use_cdn = True
-
-if not use_cdn:
- res_folder = get_resources_folder()
-
- # This handler is used to provide stylesheet and icon resources for the error page. If you pass use_cdn=True to render_cf_error_page
- # or if your site is under proxy of Cloudflare (the cdn-cgi folder is already provided by Cloudflare), this handler can be removed.
- @app.route('/cdn-cgi/
')
- def cdn_cgi(path: str):
- return send_from_directory(res_folder, path)
-
@app.route('/')
def index():
@@ -66,7 +54,7 @@ def index():
})
# Render the error page
- return render_cf_error_page(params, use_cdn=use_cdn), 500
+ return render_cf_error_page(params), 500
if __name__ == '__main__':
diff --git a/pyproject.toml b/pyproject.toml
index b837fdf..81aa0c5 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -20,6 +20,5 @@ Homepage = "https://github.com/donlon/cloudflare-error-page"
[tool.hatch.build]
include = [
"cloudflare_error_page/*.py",
- "cloudflare_error_page/resources/*",
"cloudflare_error_page/templates/*",
]
diff --git a/cloudflare_error_page/resources/images/cf-icon-browser.svg b/resources/images/cf-icon-browser.svg
similarity index 100%
rename from cloudflare_error_page/resources/images/cf-icon-browser.svg
rename to resources/images/cf-icon-browser.svg
diff --git a/cloudflare_error_page/resources/images/cf-icon-cloud.svg b/resources/images/cf-icon-cloud.svg
similarity index 100%
rename from cloudflare_error_page/resources/images/cf-icon-cloud.svg
rename to resources/images/cf-icon-cloud.svg
diff --git a/cloudflare_error_page/resources/images/cf-icon-error.svg b/resources/images/cf-icon-error.svg
similarity index 100%
rename from cloudflare_error_page/resources/images/cf-icon-error.svg
rename to resources/images/cf-icon-error.svg
diff --git a/cloudflare_error_page/resources/images/cf-icon-ok.svg b/resources/images/cf-icon-ok.svg
similarity index 100%
rename from cloudflare_error_page/resources/images/cf-icon-ok.svg
rename to resources/images/cf-icon-ok.svg
diff --git a/cloudflare_error_page/resources/images/cf-icon-server.svg b/resources/images/cf-icon-server.svg
similarity index 100%
rename from cloudflare_error_page/resources/images/cf-icon-server.svg
rename to resources/images/cf-icon-server.svg
diff --git a/resources/styles/.gitignore b/resources/styles/.gitignore
new file mode 100644
index 0000000..5f93228
--- /dev/null
+++ b/resources/styles/.gitignore
@@ -0,0 +1 @@
+main.css
\ No newline at end of file
diff --git a/cloudflare_error_page/resources/styles/main.css b/resources/styles/main-original.css
similarity index 100%
rename from cloudflare_error_page/resources/styles/main.css
rename to resources/styles/main-original.css
diff --git a/resources/templates/error.ejs b/resources/templates/error.ejs
new file mode 100644
index 0000000..af806b4
--- /dev/null
+++ b/resources/templates/error.ejs
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+<%
+let error_code = params.error_code || 500;
+let title = params.title || 'Internal server error';
+let html_title_output = params.html_title || (error_code + ': ' + title);
+%>
+<%= html_title_output %>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <% for (let item_id of ['browser', 'cloudflare', 'host']) { %>
+ <%
+ let icon, default_location, default_name, text_color, status_text;
+
+ if (item_id === 'browser') {
+ icon = 'browser';
+ default_location = 'You';
+ default_name = 'Browser';
+ } else if (item_id === 'cloudflare') {
+ icon = 'cloud';
+ default_location = 'San Francisco';
+ default_name = 'Cloudflare';
+ } else {
+ icon = 'server';
+ default_location = 'Website';
+ default_name = 'Host';
+ }
+
+ let item = params[item_id + '_status'] || {};
+ let status = item.status || 'ok';
+
+ if (item.status_text_color) {
+ text_color = item.status_text_color;
+ } else if (status === 'ok') {
+ text_color = '#9bca3e'; // text-green-success
+ } else if (status === 'error') {
+ text_color = '#bd2426'; // text-red-error
+ }
+
+ status_text = item.status_text || (status === 'ok' ? 'Working' : 'Error');
+ %>
+
+
+
+
+
+
<%= item.location || default_location %>
+ <%
+ let _name_style;
+ if ((item.name || default_name) === 'Cloudflare') {
+ _name_style = 'style="color: #2f7bbf;"'
+ } else{
+ _name_style = ''
+ }
+ %>
+
><%= item.name || default_name %>
+
<%= status_text %>
+
+ <% } %>
+
+
+
+
+
+
+
+
What happened?
+ <%= (params.what_happened || 'There is an internal server error on Cloudflare\'s network.') %>
+
+
+
What can I do?
+ <%= (params.what_can_i_do || 'Please try again in a few minutes.') %>
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/resources/templates/error.html b/resources/templates/error.html
new file mode 100644
index 0000000..2f4d37e
--- /dev/null
+++ b/resources/templates/error.html
@@ -0,0 +1,114 @@
+
+
+
+
+
+
+{% set error_code = params.error_code or 500 %}
+{% set title = params.title or 'Internal server error' %}
+{% set html_title = params.html_title or ((error_code | string) + ': ' + title) %}
+{{ html_title }}
+
+
+
+
+
+{% block header %}{% endblock %}
+
+
+
+
+
+
+
+
+
+ {% for item_id in ['browser', 'cloudflare', 'host'] %}
+ {% if item_id == 'browser' %}
+ {% set icon = 'browser' %}
+ {% set default_location = 'You' %}
+ {% set default_name = 'Browser' %}
+ {% elif item_id == 'cloudflare' %}
+ {% set icon = 'cloud' %}
+ {% set default_location = 'San Francisco' %}
+ {% set default_name = 'Cloudflare' %}
+ {% else %}
+ {% set icon = 'server' %}
+ {% set default_location = 'Website' %}
+ {% set default_name = 'Host' %}
+ {% endif %}
+ {% set item = params.get(item_id + '_status', {}) %}
+ {% set status = item.status or 'ok' %}
+ {% if item.status_text_color %}
+ {% set text_color = item.status_text_color %}
+ {% elif status == 'ok' %}
+ {% set text_color = '#9bca3e' %}{# text-green-success #}
+ {% elif status == 'error' %}
+ {% set text_color = '#bd2426' %}{# text-red-error #}
+ {% endif %}
+ {% set status_text = item.status_text or ('Working' if status == 'ok' else 'Error') %}
+
+
+
+
+
+
{{item.location or default_location}}
+ {% set _name_style = 'style="color: #2f7bbf;"' if ((item.name or default_name) == 'Cloudflare') else '' %}
+
{{item.name or default_name}}
+
{{status_text}}
+
+ {% endfor %}
+
+
+
+
+
+
+
+
What happened?
+ {{ (params.what_happened or '
There is an internal server error on Cloudflare\'s network.
') | safe }}
+
+
+
What can I do?
+ {{ (params.what_can_i_do or '
Please try again in a few minutes.
') | safe }}
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/scripts/inline_resources.py b/scripts/inline_resources.py
new file mode 100644
index 0000000..b6a5823
--- /dev/null
+++ b/scripts/inline_resources.py
@@ -0,0 +1,73 @@
+import os
+import re
+from urllib.parse import quote
+
+
+root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+resources_folder = os.path.join(root,'resources')
+
+
+def read_file(path: str) -> str:
+ with open(path, 'r', encoding='utf-8') as f:
+ return f.read()
+
+
+def write_file(path: str, data: str):
+ with open(path, 'w', encoding='utf-8') as f:
+ f.write(data)
+
+
+def convert_svg_to_data_uri(data: str) -> str:
+ data = data.replace('', '')
+ data = re.sub(r'\n\s*', '', data, flags=re.DOTALL)
+ uri = 'data:image/svg+xml;utf8,'
+ uri += quote(data)
+ return uri
+
+
+def inline_svg_resources(css_file: str, svg_files: list[str], output_file: str):
+ css_data = read_file(css_file)
+ for svg_file in svg_files:
+ svg_data = read_file(os.path.join(os.path.dirname(css_file), svg_file))
+ svg_uri = convert_svg_to_data_uri(svg_data)
+ css_data = css_data.replace(svg_file, svg_uri)
+ print(f'inline_svg_resources writing to {output_file}')
+ write_file(output_file, css_data)
+
+
+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('',
+ f'')
+ note = 'Note: This is generated with scripts/inline_resources.py. Please do not edit this file manually.'
+ if original_file.endswith('.ejs'):
+ original_data = f'<%# {note} %>\n' + original_data
+ else:
+ original_data = f'{{# {note} #}}\n' + original_data
+ print(f'inline_css_resource writing to {output_file}')
+ write_file(output_file, original_data)
+
+
+if __name__ == '__main__':
+ inline_svg_resources(
+ os.path.join(resources_folder, 'styles/main-original.css'),
+ [
+ '../images/cf-icon-browser.svg',
+ '../images/cf-icon-cloud.svg',
+ '../images/cf-icon-server.svg',
+ '../images/cf-icon-ok.svg',
+ '../images/cf-icon-error.svg',
+ ],
+ os.path.join(resources_folder, 'styles/main.css'),
+ )
+ inline_css_resource(
+ os.path.join(resources_folder, 'templates/error.html'),
+ os.path.join(resources_folder, 'styles/main.css'),
+ os.path.join(root, 'cloudflare_error_page/templates/error.html'),
+ )
+ inline_css_resource(
+ os.path.join(resources_folder, 'templates/error.ejs'),
+ os.path.join(resources_folder, 'styles/main.css'),
+ os.path.join(root, 'editor/resources/template.ejs'),
+ )