import os import hashlib import time from typing import List import secrets from playwright.sync_api import sync_playwright from jinja2 import Environment, FileSystemLoader, StrictUndefined from jinja2.sandbox import SandboxedEnvironment from config.config import TMP, TZINFO from utils.err import easyExceptionHandler # configuration IMAGE_WIDTH = 1080 IMAGE_HEIGHT = 1350 TEMPLATE_DIR = "./PictureMaker/templates" TARGET_COMMENT_SYSTEM = True # set this to False if your platform not have comment system def render(post_context:dict) -> tuple[list[str], int]: err = 0 browser = None page = None context = None fnlist = [] try: with sync_playwright() as p: # open a browser browser = p.chromium.launch(headless=True) context = browser.new_context() page = context.new_page() # render template env = SandboxedEnvironment( # sandbox -> 降低SSTI的影響範圍 loader=FileSystemLoader(TEMPLATE_DIR), autoescape=True # auto escape -> prevent xss ) env.undefined = StrictUndefined template = env.get_template('index.jinja2') main = { "id": post_context["id"], "content": post_context["content"]["text"], "time": post_context["metadata"]["create_time"].astimezone(tz=TZINFO).strftime("%Y-%m-%d %H:%M:%S") } ## (optional) parent article of comment parent = None if TARGET_COMMENT_SYSTEM: from backend.utils import ld_interface parent_id = post_context["metadata"]["parent"] if parent_id is not None: parent_context = ld_interface.inf.get(index=parent_id, media=False) parent = { "id": parent_context["id"], "content": parent_context["content"]["text"] } rendered_html = template.render(main=main, parent=parent) #print(rendered_html) page.set_content(rendered_html) # set window size page.set_viewport_size({"width": IMAGE_WIDTH, "height": IMAGE_HEIGHT}) # screen shot time.sleep(0.1) while True: filename = TMP + hashlib.sha512( (str(time.time()) + secrets.token_urlsafe(nbytes=24)).encode() ).hexdigest() + ".jpg" filename = os.path.abspath(filename) page.screenshot(path=filename) fnlist.append(filename) result = page.evaluate("scrollPage()") if result == 1: break except Exception as e: # exception easyExceptionHandler(e) err = 1 finally: if page: try: page.close() except: pass if context: try: context.close() except: pass if browser: try: browser.close() except: pass return fnlist, err def gen(context:dict) -> List[str]: """ Generate a image that has the content of the post in it. Args: context (dict): data of a post Returns: str: filename of the generated image. None: An error occurred, and nothing was returned. """ # data preparation # content = context["content"]["text"] # generate image files, err = render(context) if err: return [] return files def gen_caption(context:dict) -> str: """ Generate caption of the IG post. Args: context (dict): data of a post Returns: str: caption. """ caption = f"""中工匿名#{context["id"]} 🔧 {context["content"]["text"]} 發布匿名貼文 > niming.tcivs.live """ return caption