Skip to content

Commit

Permalink
Avoid "File name too long" error (#1128)
Browse files Browse the repository at this point in the history
* Avoid "File name too long" error

Any file error will be ignored and jump straight to treating var as CSS text.
fixes #1127

* Add docstring and update import order

* Add unit test

* Remove trailing whitespace

* Log a warning if var looks like a filename but can't load

The login page calls load_custom_css() twice with an empty var, so this now returns early for that.

* Update code style test

load_custom_css() now returns an empty string for a file that does not exist, so test_get_css_is_code() has been updated to test CSS code.

* Apply black formatting

* Remove unnecessary pass statement

Co-authored-by: Nathan Swain <[email protected]>

* Add comment for is_file

Co-authored-by: Nathan Swain <[email protected]>

* Add comment about long CSS string causing OSError

Co-authored-by: Nathan Swain <[email protected]>

* Add comment about determining if it is a CSS string

Co-authored-by: Nathan Swain <[email protected]>

* Apply black/flake8 formatting

---------

Co-authored-by: Nathan Swain <[email protected]>
  • Loading branch information
araglu and swainn authored Dec 30, 2024
1 parent eebdefc commit e95effb
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 7 deletions.
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:
oserror_exception = ": " + str(e)
else:
oserror_exception = ""

# Verify the string is CSS and log warning if it is not
common_css_chars = "{};,"
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>"

0 comments on commit e95effb

Please sign in to comment.