niming_igapi/PictureMaker/default.py

135 lines
No EOL
3.8 KiB
Python

import os
import hashlib
import time
from typing import List
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()).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