Spaces:
Sleeping
Sleeping
| """Shared helpers for templateify services (daily + special events).""" | |
| import logging | |
| from typing import Callable, Dict, List | |
| from bs4 import BeautifulSoup | |
| from bs4.element import NavigableString, Tag | |
| logger = logging.getLogger(__name__) | |
| class TemplateifyHelpers: | |
| """Holds soup/tokens state and provides shared templateify operations.""" | |
| def __init__(self, soup: BeautifulSoup) -> None: | |
| self.soup = soup | |
| self.tokens: List[Dict[str, str]] = [] | |
| self._seen: set = set() | |
| def register(self, name: str, description: str) -> None: | |
| if name not in self._seen: | |
| self.tokens.append({"name": name, "description": description}) | |
| self._seen.add(name) | |
| def set_text(self, selector: str, token: str, description: str) -> None: | |
| node = self.soup.select_one(selector) | |
| if not node: | |
| return | |
| node.clear() | |
| node.append(token) | |
| self.register(token, description) | |
| def set_attr(self, parent: Tag, selector: str, attr: str, token: str, description: str) -> None: | |
| node = parent.select_one(selector) | |
| if not node: | |
| return | |
| node[attr] = token | |
| self.register(token, description) | |
| def set_child_text(self, parent: Tag, selector: str, token: str, description: str) -> None: | |
| node = parent.select_one(selector) | |
| if not node: | |
| return | |
| node.clear() | |
| node.append(token) | |
| self.register(token, description) | |
| def loopify(self, selector: str, loop_name: str, transformer: Callable[[Tag], None], description: str) -> None: | |
| nodes = self.soup.select(selector) | |
| if not nodes: | |
| return | |
| template_node = nodes[0] | |
| for extra in nodes[1:]: | |
| extra.decompose() | |
| transformer(template_node) | |
| self.register(loop_name, description) | |
| # Determine which element to wrap (the node, or its parent anchor) | |
| if template_node.parent and template_node.parent.name == "a": | |
| target = template_node.parent | |
| else: | |
| target = template_node | |
| parent = target.parent | |
| if not parent: | |
| logger.warning(f"Template node {selector} has no parent, cannot wrap in loop") | |
| return | |
| try: | |
| idx = parent.index(target) | |
| parent.insert(idx, NavigableString(f"{{{{#{loop_name}}}}}")) | |
| parent.insert(idx + 2, NavigableString(f"{{{{/{loop_name}}}}}")) | |
| except ValueError: | |
| logger.warning(f"Could not find index for {selector}, node may have been moved") | |
| def wrap_images_in_anchors(self, header_alt: str = "Polygraph by Polymarket", footer_alt: str = "Polymarket", link_url: str = "https://poly.market/0d7VvzI") -> None: | |
| """Wrap header and footer logo images in anchor tags if not already linked.""" | |
| for alt_text in (header_alt, footer_alt): | |
| for table in self.soup.find_all("table", role="presentation"): | |
| img = table.find("img", alt=alt_text) | |
| if img and not img.find_parent("a"): | |
| link = self.soup.new_tag("a", href=link_url, target="_blank", rel="noopener noreferrer") | |
| img.wrap(link) | |
| break | |