Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid "File name too long" error #1128

Merged
merged 12 commits into from
Dec 30, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,23 @@ def test_get_css_is_code(self, mock_isfile, mock_settings):
mock_settings.STATIC_ROOT = "test_base_path1"
mock_settings.STATICFILES_DIRS = ["test_base_path2"]

ret = ss.load_custom_css("test.css")
self.assertEqual(ret, "<style>test.css</style>")
ret = ss.load_custom_css(".navbar-brand { background-color: darkred; }")
self.assertEqual(
ret, "<style>.navbar-brand { background-color: darkred; }</style>"
)

def test_long_css_text(self):
long_css_text = """
.site-header { margin: 0 50px 0 0; background-color: red; }
.site-header .navbar-brand {
background-color: darkred;
color: black;
font-style: italic;
font-variant: small-caps;
font-family: cursive;
font-size: 24px;
}
"""

ret = ss.load_custom_css(long_css_text)
self.assertEqual(ret, f"<style>{long_css_text}</style>")
41 changes: 36 additions & 5 deletions tethys_apps/templatetags/site_settings.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,59 @@
import logging
from pathlib import Path

from django import template
from django.template.defaultfilters import stringfilter
from django.conf import settings

from pathlib import Path

from ..static_finders import TethysStaticFinder

static_finder = TethysStaticFinder()

register = template.Library()

log = logging.getLogger(f"tethys.{__name__}")


@register.filter
@stringfilter
def load_custom_css(var):
"""Load Custom Styles defined in Tethys Portal -> Site Settings

Args:
var: a filename of CSS to load or CSS text to embed into the page

Returns:
a string of HTML that either embeds CSS text or points to a file

"""
if not var.strip():
return ""
if var.startswith("/"):
var = var.lstrip("/")

if (Path(settings.STATIC_ROOT) / var).is_file() or static_finder.find(var):
return f'<link href="/static/{var}" rel="stylesheet" />'
try:
# Check if var is a path to a file, if so return a link tag to the file
if (Path(settings.STATIC_ROOT) / var).is_file() or static_finder.find(var):
return f'<link href="/static/{var}" rel="stylesheet" />'

else:
for path in settings.STATICFILES_DIRS:
if (Path(path) / var).is_file():
return f'<link href="/static/{var}" rel="stylesheet" />'
# If the string is too long for a file path, which could happen if it is CSS,
# an OSError will be raised during the file path checks. This could also happen
# if a lengthy file path is given or is otherwise invalid.
except OSError as e:
araglu marked this conversation as resolved.
Show resolved Hide resolved
oserror_exception = ": " + str(e)
else:
oserror_exception = ""

# Verify the string is CSS and log warning if it is not
common_css_chars = "{};,"
araglu marked this conversation as resolved.
Show resolved Hide resolved
if not any(c in var for c in common_css_chars):
# This appears to be a filename and not a CSS string
log.warning(
"Could not load file '%s' for custom styles%s", var, oserror_exception
)
return ""

return "<style>" + var + "</style>"
Loading