fixes to HTML head
This commit is contained in:
@@ -675,3 +675,7 @@ fabric.properties
|
|||||||
.env
|
.env
|
||||||
lvenv
|
lvenv
|
||||||
wvenv
|
wvenv
|
||||||
|
|
||||||
|
## html doc
|
||||||
|
|
||||||
|
*.html
|
||||||
@@ -198,6 +198,27 @@ This is what the programm outputted to the stdout file (inserted into out.html):
|
|||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Fix (22/04/26):
|
||||||
|
|
||||||
|
rewrite of sanizizer.py
|
||||||
|
|
||||||
|
now output looks like this:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<!-- sanigi-html parsed @ 2026-04-22 20:23:01.043256 -->
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta content="width=device-width, initial-scale=1.0" name="viewport">
|
||||||
|
<title>Document</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Test</h1>
|
||||||
|
<p>This is a test</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
|
||||||
|
|||||||
+6
-2
@@ -71,7 +71,7 @@ def build_profiles_from_cfg(cfg: Optional[Dict[str, Any]] = None) -> Dict[str, D
|
|||||||
# like daddy :3
|
# like daddy :3
|
||||||
STRICT = {
|
STRICT = {
|
||||||
"tags": [
|
"tags": [
|
||||||
"html", "body", "header", "main", "footer", "section", "article", "nav",
|
"html", "body", "header", "head", "title", "meta", "link", "body", "main", "footer", "section", "article", "nav",
|
||||||
"aside", "h1", "h2", "h3", "h4", "h5", "h6",
|
"aside", "h1", "h2", "h3", "h4", "h5", "h6",
|
||||||
"p", "pre", "code", "blockquote",
|
"p", "pre", "code", "blockquote",
|
||||||
"ul", "ol", "li", "dl", "dt", "dd",
|
"ul", "ol", "li", "dl", "dt", "dd",
|
||||||
@@ -90,6 +90,8 @@ def build_profiles_from_cfg(cfg: Optional[Dict[str, Any]] = None) -> Dict[str, D
|
|||||||
"th": ["scope", "colspan", "rowspan"],
|
"th": ["scope", "colspan", "rowspan"],
|
||||||
"td": ["colspan", "rowspan"],
|
"td": ["colspan", "rowspan"],
|
||||||
"time": ["datetime"],
|
"time": ["datetime"],
|
||||||
|
"meta": ["charset", "name", "content"],
|
||||||
|
"html": ["lang"],
|
||||||
"*": ["class", "id"] # limit
|
"*": ["class", "id"] # limit
|
||||||
},
|
},
|
||||||
"protocols": ["http", "https", "mailto"],
|
"protocols": ["http", "https", "mailto"],
|
||||||
@@ -99,7 +101,7 @@ def build_profiles_from_cfg(cfg: Optional[Dict[str, Any]] = None) -> Dict[str, D
|
|||||||
# like my ass :3
|
# like my ass :3
|
||||||
LOOSE = {
|
LOOSE = {
|
||||||
"tags": [
|
"tags": [
|
||||||
"html", "body", "header", "main", "footer", "section", "article", "nav",
|
"html", "body", "header", "head", "title", "meta", "link", "body", "main", "footer", "section", "article", "nav",
|
||||||
"aside", "h1", "h2", "h3", "h4", "h5", "h6",
|
"aside", "h1", "h2", "h3", "h4", "h5", "h6",
|
||||||
"p", "pre", "code", "blockquote", "q",
|
"p", "pre", "code", "blockquote", "q",
|
||||||
"ul", "ol", "li", "dl", "dt", "dd",
|
"ul", "ol", "li", "dl", "dt", "dd",
|
||||||
@@ -127,6 +129,8 @@ def build_profiles_from_cfg(cfg: Optional[Dict[str, Any]] = None) -> Dict[str, D
|
|||||||
"span": ["class", "id", "style"],
|
"span": ["class", "id", "style"],
|
||||||
"pre": ["class"],
|
"pre": ["class"],
|
||||||
"code": ["class"],
|
"code": ["class"],
|
||||||
|
"meta": ["charset", "name", "content"],
|
||||||
|
"html": ["lang"],
|
||||||
"*": ["class", "id", "style"]
|
"*": ["class", "id", "style"]
|
||||||
},
|
},
|
||||||
"protocols": ["http", "https", "mailto", "data"],
|
"protocols": ["http", "https", "mailto", "data"],
|
||||||
|
|||||||
+57
-35
@@ -4,66 +4,88 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
import bleach
|
import bleach
|
||||||
from bs4 import BeautifulSoup, Tag
|
|
||||||
import datetime
|
import datetime
|
||||||
from log.Logger import *
|
from bs4 import BeautifulSoup
|
||||||
|
from log.Logger import Logger
|
||||||
|
|
||||||
logger = Logger()
|
logger = Logger()
|
||||||
|
|
||||||
|
|
||||||
def sanitize(html: str, mode: str, profiles: dict) -> str:
|
def sanitize(html: str, mode: str, profiles: dict) -> str:
|
||||||
|
"""
|
||||||
|
Arguments:
|
||||||
|
html : str -> input html
|
||||||
|
mode : str -> the defined mode which is from profiles.py ; or PROFILES variable
|
||||||
|
|
||||||
|
Functionality:
|
||||||
|
This function takes in HTML sanitzies it with bleach and returns clean HTML
|
||||||
|
"""
|
||||||
|
|
||||||
if mode == "passthrough":
|
if mode == "passthrough":
|
||||||
logger.log_warning("You are about to not care about sanitizing ANY HTML. You are in passthrough mode.")
|
logger.log_warning("You are about to not care about sanitizing ANY HTML. You are in passthrough mode.")
|
||||||
return _wrap_document(html) # still wrap passthrough output
|
return _wrap_document(html)
|
||||||
|
|
||||||
config = profiles.get(mode)
|
config = profiles.get(mode)
|
||||||
if not config:
|
if not config:
|
||||||
raise ValueError(f"Unknown mode! : {mode}")
|
raise ValueError(f"Unknown mode: {mode}")
|
||||||
allowed = set(config.get("tags", []))
|
|
||||||
good_soup = BeautifulSoup(html, "html.parser")
|
soup = BeautifulSoup(html, "html.parser")
|
||||||
def has_allowed_child(node: Tag) -> bool:
|
|
||||||
for child in node.descendants:
|
original_head = soup.find("head")
|
||||||
if isinstance(child, Tag) and child.name.lower() in allowed:
|
original_body = soup.find("body")
|
||||||
return True
|
|
||||||
return False
|
head_html = str(original_head) if original_head else ""
|
||||||
for child in list(good_soup.find_all()):
|
body_html = str(original_body) if original_body else html
|
||||||
name = child.name.lower()
|
|
||||||
if name in allowed:
|
head_tags = {"title", "meta", "link", "base", "style"}
|
||||||
continue
|
head_allowed = set(config.get("tags", [])) & head_tags
|
||||||
if has_allowed_child(child):
|
|
||||||
child.unwrap()
|
cleaned_head_content = bleach.clean(
|
||||||
else:
|
head_html,
|
||||||
child.decompose()
|
tags=head_allowed,
|
||||||
bs_parsed = str(good_soup)
|
attributes=config.get("attributes"),
|
||||||
logger.log_debug(
|
protocols=config.get("protocols"),
|
||||||
"called sanitizer! using this as args: \n" +
|
strip=config.get("strip"),
|
||||||
str(bs_parsed) +
|
|
||||||
str(config.get("tags")) + "\n" +
|
|
||||||
str(config.get("protocols")) + "\n" +
|
|
||||||
str(config.get("strip"))
|
|
||||||
)
|
)
|
||||||
cleaned = bleach.clean(
|
|
||||||
bs_parsed,
|
cleaned_body_content = bleach.clean(
|
||||||
|
body_html,
|
||||||
tags=config.get("tags"),
|
tags=config.get("tags"),
|
||||||
attributes=config.get("attributes"),
|
attributes=config.get("attributes"),
|
||||||
protocols=config.get("protocols"),
|
protocols=config.get("protocols"),
|
||||||
strip=config.get("strip"),
|
strip=config.get("strip"),
|
||||||
)
|
)
|
||||||
return _wrap_document(cleaned)
|
|
||||||
|
pretty_body = BeautifulSoup(cleaned_body_content, "html.parser").prettify()
|
||||||
|
pretty_head = BeautifulSoup(cleaned_head_content, "html.parser").prettify()
|
||||||
|
|
||||||
|
return f"""
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<!-- sanigi-html parsed @ {datetime.datetime.now()} (version: python) -->
|
||||||
|
<head>{pretty_head}</head>
|
||||||
|
<body>{pretty_body}</body>
|
||||||
|
</html>
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
def _wrap_document(content: str) -> str:
|
def _wrap_document(content: str) -> str:
|
||||||
|
logger.log_debug("Content:" + content)
|
||||||
soup = BeautifulSoup(content, "html.parser")
|
soup = BeautifulSoup(content, "html.parser")
|
||||||
|
|
||||||
existing_head = soup.find("head")
|
existing_head = soup.find("head")
|
||||||
|
logger.log_debug("Existing Head?:" + str(existing_head))
|
||||||
existing_body = soup.find("body")
|
existing_body = soup.find("body")
|
||||||
|
logger.log_debug("Existing Body?:" + str(existing_body))
|
||||||
|
|
||||||
head_content = str(existing_head) if existing_head else "<head></head>"
|
head_content = str(existing_head) if existing_head else "<head></head>"
|
||||||
body_content = str(existing_body) if existing_body else f"<body>{content}</body>"
|
body_content = str(existing_body) if existing_body else f"<body>{content}</body>"
|
||||||
|
|
||||||
return f"""
|
return f"""
|
||||||
<!DOCTYPE html>\n
|
<!DOCTYPE html>
|
||||||
<html>\n
|
<html>
|
||||||
<!-- sanigi-html parsed @ {str(datetime.datetime.now())}-->
|
<!-- sanigi-html parsed @ {datetime.datetime.now()} -->
|
||||||
{head_content}\n
|
{head_content}
|
||||||
{body_content}\n
|
{body_content}
|
||||||
</html>
|
</html>
|
||||||
"""
|
"""
|
||||||
|
|||||||
Reference in New Issue
Block a user