fix bugs, update the example interface, and rewrite the example PictureMaker
This commit is contained in:
parent
d03e0c8e82
commit
1fc619fe06
15 changed files with 745 additions and 61 deletions
7
.gitignore
vendored
7
.gitignore
vendored
|
@ -7,3 +7,10 @@ backend/db/id2igid.db
|
||||||
|
|
||||||
test
|
test
|
||||||
testfiles
|
testfiles
|
||||||
|
test.py
|
||||||
|
|
||||||
|
# for sljh
|
||||||
|
utils/sljh
|
||||||
|
PictureMaker/sljh.py
|
||||||
|
interface/sljh.py
|
||||||
|
frontend/sljh
|
14
Dockerfile
14
Dockerfile
|
@ -4,7 +4,15 @@ WORKDIR /app
|
||||||
|
|
||||||
# apt install
|
# apt install
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
DEBAIN_FRONTEND=noninteractive apt-get install -qy ffmpeg libpq-dev libmagic1 libmagic-dev
|
DEBAIN_FRONTEND=noninteractive apt-get install -qy ffmpeg libpq-dev libmagic1 libmagic-dev locales
|
||||||
|
|
||||||
|
# locale
|
||||||
|
COPY ./env/locale.gen /env/locale.gen
|
||||||
|
RUN locale-gen
|
||||||
|
COPY ./env/locale.conf /env/locale.conf
|
||||||
|
|
||||||
|
# timezone
|
||||||
|
COPY ./env/timezone /etc/timezone
|
||||||
|
|
||||||
# pip3 install
|
# pip3 install
|
||||||
COPY ./requirements.txt /app/requirements.txt
|
COPY ./requirements.txt /app/requirements.txt
|
||||||
|
@ -13,4 +21,8 @@ COPY ./ffmpeg_python-0.2.0-py3-none-any.whl /app/ffmpeg_python-0.2.0-py3-none-an
|
||||||
RUN pip3 install ffmpeg_python-0.2.0-py3-none-any.whl
|
RUN pip3 install ffmpeg_python-0.2.0-py3-none-any.whl
|
||||||
RUN pip3 install -r /app/requirements.txt
|
RUN pip3 install -r /app/requirements.txt
|
||||||
|
|
||||||
|
# install playwright
|
||||||
|
RUN playwright install-deps
|
||||||
|
RUN playwright install
|
||||||
|
|
||||||
EXPOSE 50051
|
EXPOSE 50051
|
126
PictureMaker/default.py
Normal file
126
PictureMaker/default.py
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
import datetime
|
||||||
|
import os
|
||||||
|
import hashlib
|
||||||
|
import time
|
||||||
|
|
||||||
|
from playwright.sync_api import sync_playwright
|
||||||
|
from jinja2 import Template
|
||||||
|
|
||||||
|
from config.config import TMP
|
||||||
|
|
||||||
|
# configuration
|
||||||
|
TIMEZONE = 8
|
||||||
|
IMAGE_WIDTH = 1280
|
||||||
|
IMAGE_HEIGHT = 1280
|
||||||
|
|
||||||
|
def render(text, filename, width=IMAGE_WIDTH, height=IMAGE_HEIGHT, font_size=60, text_color="black", margin=50) -> int:
|
||||||
|
err = 0
|
||||||
|
|
||||||
|
browser = None
|
||||||
|
page = None
|
||||||
|
context = None
|
||||||
|
try:
|
||||||
|
with sync_playwright() as p:
|
||||||
|
browser = p.chromium.launch(headless=True)
|
||||||
|
context = browser.new_context()
|
||||||
|
page = context.new_page()
|
||||||
|
|
||||||
|
# template
|
||||||
|
template = Template("{{ text }}")
|
||||||
|
processed_text = template.render(text=text)
|
||||||
|
html_content = f"""
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<style>
|
||||||
|
body {{
|
||||||
|
margin: 0;
|
||||||
|
background-size: {width}px {height}px;
|
||||||
|
width: {width}px;
|
||||||
|
height: {height}px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
overflow: hidden;
|
||||||
|
}}
|
||||||
|
.text-container {{
|
||||||
|
font-size: {font_size}px;
|
||||||
|
color: {text_color};
|
||||||
|
width: calc(100% - {2 * margin}px);
|
||||||
|
text-align: center;
|
||||||
|
line-height: 1.2;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
}}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="text-container">{processed_text}</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
"""
|
||||||
|
page.set_content(html_content)
|
||||||
|
|
||||||
|
# set window size
|
||||||
|
page.set_viewport_size({"width": width, "height": height})
|
||||||
|
|
||||||
|
# screenshot
|
||||||
|
page.screenshot(path=filename)
|
||||||
|
except Exception as e:
|
||||||
|
# exception
|
||||||
|
print(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 err
|
||||||
|
|
||||||
|
|
||||||
|
def gen(context:dict) -> str | None:
|
||||||
|
"""
|
||||||
|
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
|
||||||
|
filename = TMP + hashlib.sha512( str(time.time()).encode() ).hexdigest() + ".jpg"
|
||||||
|
filename = os.path.abspath(filename)
|
||||||
|
err = render(content, filename, width=IMAGE_WIDTH, height=IMAGE_HEIGHT)
|
||||||
|
if err:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return filename
|
||||||
|
|
||||||
|
|
||||||
|
def gen_caption(context:dict) -> str:
|
||||||
|
"""
|
||||||
|
Generate caption of the IG post.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
context (dict): data of a post
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: caption.
|
||||||
|
"""
|
||||||
|
|
||||||
|
caption = f"""[TCIVS Niming #{context["id"]}]
|
||||||
|
{context["content"]["text"]}
|
||||||
|
"""
|
||||||
|
|
||||||
|
return caption
|
|
@ -41,5 +41,5 @@ def gen(context:dict) -> str | None:
|
||||||
|
|
||||||
|
|
||||||
# 文案生成
|
# 文案生成
|
||||||
def gentext(context:dict) -> str:
|
def gen_caption(context:dict) -> str:
|
||||||
return context["content"]["text"]
|
return context["content"]["text"]
|
3
TODO
3
TODO
|
@ -1,4 +1,7 @@
|
||||||
[ ] 改善Traceback的收集
|
[ ] 改善Traceback的收集
|
||||||
|
[ ] GIF Support
|
||||||
|
[ ] api: ID查IGID,IGID反查ID
|
||||||
|
[ ] api: 返回錯誤處理紀錄
|
||||||
[V] 本地儲存ID對IGID表
|
[V] 本地儲存ID對IGID表
|
||||||
|
|
||||||
[ ] 測試
|
[ ] 測試
|
6
app.py
6
app.py
|
@ -2,6 +2,7 @@ import importlib.util
|
||||||
import logging
|
import logging
|
||||||
import threading
|
import threading
|
||||||
import os
|
import os
|
||||||
|
import time
|
||||||
|
|
||||||
from backend import backend
|
from backend import backend
|
||||||
from backend.ig import IG
|
from backend.ig import IG
|
||||||
|
@ -75,6 +76,11 @@ def main():
|
||||||
|
|
||||||
# end
|
# end
|
||||||
loaderlog.info("Loaded")
|
loaderlog.info("Loaded")
|
||||||
|
|
||||||
|
# infinity waiting - prevent main thread from exiting
|
||||||
|
while True:
|
||||||
|
time.sleep(60)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
|
@ -86,10 +86,10 @@ def upload_media(context:str, paths:List[str]) -> dict | None:
|
||||||
if len(paths) == 0:
|
if len(paths) == 0:
|
||||||
return None
|
return None
|
||||||
elif len(paths) == 1:
|
elif len(paths) == 1:
|
||||||
content = ld_picturemaker.picture_maker.gentext(context)
|
content = ld_picturemaker.picture_maker.gen_caption(context)
|
||||||
media = cl.photo_upload(path=paths[0], caption=content).dict()
|
media = cl.photo_upload(path=paths[0], caption=content).dict()
|
||||||
else:
|
else:
|
||||||
content = ld_picturemaker.picture_maker.gentext(context)
|
content = ld_picturemaker.picture_maker.gen_caption(context)
|
||||||
media = cl.album_upload(paths=paths, caption=content).dict()
|
media = cl.album_upload(paths=paths, caption=content).dict()
|
||||||
|
|
||||||
return media
|
return media
|
||||||
|
|
|
@ -26,38 +26,23 @@ def upload(aid:int) -> Tuple[str, int]:
|
||||||
# multimedia -> tmp file
|
# multimedia -> tmp file
|
||||||
tmp_path = []
|
tmp_path = []
|
||||||
for m in article["content"]["media"]:
|
for m in article["content"]["media"]:
|
||||||
|
_binary = m.read()
|
||||||
# check mime type
|
# check mime type
|
||||||
mime = magic.Magic(mime=True)
|
mime = magic.Magic(mime=True)
|
||||||
tp = mime.from_buffer(m.read())
|
tp = mime.from_buffer(_binary)
|
||||||
# save file
|
# save file
|
||||||
filename, err = fileProcessor.file_saver(tp, m.read())
|
filename, err = fileProcessor.file_saver(tp, _binary)
|
||||||
if err:
|
if err:
|
||||||
clean(tmp_path)
|
clean(tmp_path)
|
||||||
return "Error while saving file", 1
|
return "Error while saving file : %s"%filename, 1
|
||||||
tmp_path.append(filename)
|
tmp_path.append(filename)
|
||||||
article["content"]["media"] = []
|
article["content"]["media"] = []
|
||||||
|
|
||||||
"""
|
|
||||||
# 抓取檔案
|
|
||||||
files = []
|
|
||||||
for k in article["files_hash"]:
|
|
||||||
f, code = s3helper.solo_file_fetcher(fnhash=k)
|
|
||||||
if code:
|
|
||||||
return "File not found", 1
|
|
||||||
else:
|
|
||||||
files.append(f)
|
|
||||||
|
|
||||||
# 轉出暫存檔案
|
|
||||||
tmp_path:list = []
|
|
||||||
for t in files:
|
|
||||||
filename, err = fileProcessor.file_saver(t.get("mime"), t.get("binary"))
|
|
||||||
if err: # 如果錯誤
|
|
||||||
return filename, 1
|
|
||||||
tmp_path.append(filename)
|
|
||||||
"""
|
|
||||||
|
|
||||||
# 合成文字圖
|
# 合成文字圖
|
||||||
proma_file = ld_picturemaker.picture_maker.gen(article)
|
proma_file = ld_picturemaker.picture_maker.gen(article)
|
||||||
|
if proma_file is None:
|
||||||
|
clean(tmp_path)
|
||||||
|
return "Error while generating proma_file", 1
|
||||||
tmp_path = [proma_file] + tmp_path
|
tmp_path = [proma_file] + tmp_path
|
||||||
|
|
||||||
# 送交 IG 上傳
|
# 送交 IG 上傳
|
||||||
|
|
|
@ -9,7 +9,7 @@ services:
|
||||||
volumes:
|
volumes:
|
||||||
- ".:/app"
|
- ".:/app"
|
||||||
ports:
|
ports:
|
||||||
- "50051:50051"
|
- "50050:50050" # frontend.grpc
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
working_dir: /app
|
working_dir: /app
|
||||||
command: python3 ./app.py
|
command: python3 ./app.py
|
1
env/locale.conf
vendored
Normal file
1
env/locale.conf
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
LANG="en_US.UTF-8"
|
515
env/locale.gen
vendored
Normal file
515
env/locale.gen
vendored
Normal file
|
@ -0,0 +1,515 @@
|
||||||
|
# This file lists locales that you wish to have built. You can find a list
|
||||||
|
# of valid supported locales at /usr/share/i18n/SUPPORTED, and you can add
|
||||||
|
# user defined locales to /usr/local/share/i18n/SUPPORTED. If you change
|
||||||
|
# this file, you need to rerun locale-gen.
|
||||||
|
|
||||||
|
|
||||||
|
C.UTF-8 UTF-8
|
||||||
|
# aa_DJ ISO-8859-1
|
||||||
|
# aa_DJ.UTF-8 UTF-8
|
||||||
|
# aa_ER UTF-8
|
||||||
|
# aa_ET UTF-8
|
||||||
|
# af_ZA ISO-8859-1
|
||||||
|
# af_ZA.UTF-8 UTF-8
|
||||||
|
# agr_PE UTF-8
|
||||||
|
# ak_GH UTF-8
|
||||||
|
# am_ET UTF-8
|
||||||
|
# an_ES ISO-8859-15
|
||||||
|
# an_ES.UTF-8 UTF-8
|
||||||
|
# anp_IN UTF-8
|
||||||
|
# ar_AE ISO-8859-6
|
||||||
|
# ar_AE.UTF-8 UTF-8
|
||||||
|
# ar_BH ISO-8859-6
|
||||||
|
# ar_BH.UTF-8 UTF-8
|
||||||
|
# ar_DZ ISO-8859-6
|
||||||
|
# ar_DZ.UTF-8 UTF-8
|
||||||
|
# ar_EG ISO-8859-6
|
||||||
|
# ar_EG.UTF-8 UTF-8
|
||||||
|
# ar_IN UTF-8
|
||||||
|
# ar_IQ ISO-8859-6
|
||||||
|
# ar_IQ.UTF-8 UTF-8
|
||||||
|
# ar_JO ISO-8859-6
|
||||||
|
# ar_JO.UTF-8 UTF-8
|
||||||
|
# ar_KW ISO-8859-6
|
||||||
|
# ar_KW.UTF-8 UTF-8
|
||||||
|
# ar_LB ISO-8859-6
|
||||||
|
# ar_LB.UTF-8 UTF-8
|
||||||
|
# ar_LY ISO-8859-6
|
||||||
|
# ar_LY.UTF-8 UTF-8
|
||||||
|
# ar_MA ISO-8859-6
|
||||||
|
# ar_MA.UTF-8 UTF-8
|
||||||
|
# ar_OM ISO-8859-6
|
||||||
|
# ar_OM.UTF-8 UTF-8
|
||||||
|
# ar_QA ISO-8859-6
|
||||||
|
# ar_QA.UTF-8 UTF-8
|
||||||
|
# ar_SA ISO-8859-6
|
||||||
|
# ar_SA.UTF-8 UTF-8
|
||||||
|
# ar_SD ISO-8859-6
|
||||||
|
# ar_SD.UTF-8 UTF-8
|
||||||
|
# ar_SS UTF-8
|
||||||
|
# ar_SY ISO-8859-6
|
||||||
|
# ar_SY.UTF-8 UTF-8
|
||||||
|
# ar_TN ISO-8859-6
|
||||||
|
# ar_TN.UTF-8 UTF-8
|
||||||
|
# ar_YE ISO-8859-6
|
||||||
|
# ar_YE.UTF-8 UTF-8
|
||||||
|
# as_IN UTF-8
|
||||||
|
# ast_ES ISO-8859-15
|
||||||
|
# ast_ES.UTF-8 UTF-8
|
||||||
|
# ayc_PE UTF-8
|
||||||
|
# az_AZ UTF-8
|
||||||
|
# az_IR UTF-8
|
||||||
|
# be_BY CP1251
|
||||||
|
# be_BY.UTF-8 UTF-8
|
||||||
|
# be_BY@latin UTF-8
|
||||||
|
# bem_ZM UTF-8
|
||||||
|
# ber_DZ UTF-8
|
||||||
|
# ber_MA UTF-8
|
||||||
|
# bg_BG CP1251
|
||||||
|
# bg_BG.UTF-8 UTF-8
|
||||||
|
# bhb_IN.UTF-8 UTF-8
|
||||||
|
# bho_IN UTF-8
|
||||||
|
# bho_NP UTF-8
|
||||||
|
# bi_VU UTF-8
|
||||||
|
# bn_BD UTF-8
|
||||||
|
# bn_IN UTF-8
|
||||||
|
# bo_CN UTF-8
|
||||||
|
# bo_IN UTF-8
|
||||||
|
# br_FR ISO-8859-1
|
||||||
|
# br_FR.UTF-8 UTF-8
|
||||||
|
# br_FR@euro ISO-8859-15
|
||||||
|
# brx_IN UTF-8
|
||||||
|
# bs_BA ISO-8859-2
|
||||||
|
# bs_BA.UTF-8 UTF-8
|
||||||
|
# byn_ER UTF-8
|
||||||
|
# ca_AD ISO-8859-15
|
||||||
|
# ca_AD.UTF-8 UTF-8
|
||||||
|
# ca_ES ISO-8859-1
|
||||||
|
# ca_ES.UTF-8 UTF-8
|
||||||
|
# ca_ES@euro ISO-8859-15
|
||||||
|
# ca_ES@valencia UTF-8
|
||||||
|
# ca_FR ISO-8859-15
|
||||||
|
# ca_FR.UTF-8 UTF-8
|
||||||
|
# ca_IT ISO-8859-15
|
||||||
|
# ca_IT.UTF-8 UTF-8
|
||||||
|
# ce_RU UTF-8
|
||||||
|
# chr_US UTF-8
|
||||||
|
# ckb_IQ UTF-8
|
||||||
|
# cmn_TW UTF-8
|
||||||
|
# crh_RU UTF-8
|
||||||
|
# crh_UA UTF-8
|
||||||
|
# cs_CZ ISO-8859-2
|
||||||
|
# cs_CZ.UTF-8 UTF-8
|
||||||
|
# csb_PL UTF-8
|
||||||
|
# cv_RU UTF-8
|
||||||
|
# cy_GB ISO-8859-14
|
||||||
|
# cy_GB.UTF-8 UTF-8
|
||||||
|
# da_DK ISO-8859-1
|
||||||
|
# da_DK.UTF-8 UTF-8
|
||||||
|
# de_AT ISO-8859-1
|
||||||
|
# de_AT.UTF-8 UTF-8
|
||||||
|
# de_AT@euro ISO-8859-15
|
||||||
|
# de_BE ISO-8859-1
|
||||||
|
# de_BE.UTF-8 UTF-8
|
||||||
|
# de_BE@euro ISO-8859-15
|
||||||
|
# de_CH ISO-8859-1
|
||||||
|
# de_CH.UTF-8 UTF-8
|
||||||
|
# de_DE ISO-8859-1
|
||||||
|
# de_DE.UTF-8 UTF-8
|
||||||
|
# de_DE@euro ISO-8859-15
|
||||||
|
# de_IT ISO-8859-1
|
||||||
|
# de_IT.UTF-8 UTF-8
|
||||||
|
# de_LI.UTF-8 UTF-8
|
||||||
|
# de_LU ISO-8859-1
|
||||||
|
# de_LU.UTF-8 UTF-8
|
||||||
|
# de_LU@euro ISO-8859-15
|
||||||
|
# doi_IN UTF-8
|
||||||
|
# dsb_DE UTF-8
|
||||||
|
# dv_MV UTF-8
|
||||||
|
# dz_BT UTF-8
|
||||||
|
# el_CY ISO-8859-7
|
||||||
|
# el_CY.UTF-8 UTF-8
|
||||||
|
# el_GR ISO-8859-7
|
||||||
|
# el_GR.UTF-8 UTF-8
|
||||||
|
# el_GR@euro ISO-8859-7
|
||||||
|
# en_AG UTF-8
|
||||||
|
# en_AU ISO-8859-1
|
||||||
|
# en_AU.UTF-8 UTF-8
|
||||||
|
# en_BW ISO-8859-1
|
||||||
|
# en_BW.UTF-8 UTF-8
|
||||||
|
# en_CA ISO-8859-1
|
||||||
|
# en_CA.UTF-8 UTF-8
|
||||||
|
# en_DK ISO-8859-1
|
||||||
|
# en_DK.ISO-8859-15 ISO-8859-15
|
||||||
|
# en_DK.UTF-8 UTF-8
|
||||||
|
# en_GB ISO-8859-1
|
||||||
|
# en_GB.ISO-8859-15 ISO-8859-15
|
||||||
|
# en_GB.UTF-8 UTF-8
|
||||||
|
# en_HK ISO-8859-1
|
||||||
|
# en_HK.UTF-8 UTF-8
|
||||||
|
# en_IE ISO-8859-1
|
||||||
|
# en_IE.UTF-8 UTF-8
|
||||||
|
# en_IE@euro ISO-8859-15
|
||||||
|
# en_IL UTF-8
|
||||||
|
# en_IN UTF-8
|
||||||
|
# en_NG UTF-8
|
||||||
|
# en_NZ ISO-8859-1
|
||||||
|
# en_NZ.UTF-8 UTF-8
|
||||||
|
# en_PH ISO-8859-1
|
||||||
|
# en_PH.UTF-8 UTF-8
|
||||||
|
# en_SC.UTF-8 UTF-8
|
||||||
|
# en_SG ISO-8859-1
|
||||||
|
# en_SG.UTF-8 UTF-8
|
||||||
|
# en_US ISO-8859-1
|
||||||
|
# en_US.ISO-8859-15 ISO-8859-15
|
||||||
|
en_US.UTF-8 UTF-8
|
||||||
|
# en_ZA ISO-8859-1
|
||||||
|
# en_ZA.UTF-8 UTF-8
|
||||||
|
# en_ZM UTF-8
|
||||||
|
# en_ZW ISO-8859-1
|
||||||
|
# en_ZW.UTF-8 UTF-8
|
||||||
|
# eo UTF-8
|
||||||
|
# eo_US.UTF-8 UTF-8
|
||||||
|
# es_AR ISO-8859-1
|
||||||
|
# es_AR.UTF-8 UTF-8
|
||||||
|
# es_BO ISO-8859-1
|
||||||
|
# es_BO.UTF-8 UTF-8
|
||||||
|
# es_CL ISO-8859-1
|
||||||
|
# es_CL.UTF-8 UTF-8
|
||||||
|
# es_CO ISO-8859-1
|
||||||
|
# es_CO.UTF-8 UTF-8
|
||||||
|
# es_CR ISO-8859-1
|
||||||
|
# es_CR.UTF-8 UTF-8
|
||||||
|
# es_CU UTF-8
|
||||||
|
# es_DO ISO-8859-1
|
||||||
|
# es_DO.UTF-8 UTF-8
|
||||||
|
# es_EC ISO-8859-1
|
||||||
|
# es_EC.UTF-8 UTF-8
|
||||||
|
# es_ES ISO-8859-1
|
||||||
|
# es_ES.UTF-8 UTF-8
|
||||||
|
# es_ES@euro ISO-8859-15
|
||||||
|
# es_GT ISO-8859-1
|
||||||
|
# es_GT.UTF-8 UTF-8
|
||||||
|
# es_HN ISO-8859-1
|
||||||
|
# es_HN.UTF-8 UTF-8
|
||||||
|
# es_MX ISO-8859-1
|
||||||
|
# es_MX.UTF-8 UTF-8
|
||||||
|
# es_NI ISO-8859-1
|
||||||
|
# es_NI.UTF-8 UTF-8
|
||||||
|
# es_PA ISO-8859-1
|
||||||
|
# es_PA.UTF-8 UTF-8
|
||||||
|
# es_PE ISO-8859-1
|
||||||
|
# es_PE.UTF-8 UTF-8
|
||||||
|
# es_PR ISO-8859-1
|
||||||
|
# es_PR.UTF-8 UTF-8
|
||||||
|
# es_PY ISO-8859-1
|
||||||
|
# es_PY.UTF-8 UTF-8
|
||||||
|
# es_SV ISO-8859-1
|
||||||
|
# es_SV.UTF-8 UTF-8
|
||||||
|
# es_US ISO-8859-1
|
||||||
|
# es_US.UTF-8 UTF-8
|
||||||
|
# es_UY ISO-8859-1
|
||||||
|
# es_UY.UTF-8 UTF-8
|
||||||
|
# es_VE ISO-8859-1
|
||||||
|
# es_VE.UTF-8 UTF-8
|
||||||
|
# et_EE ISO-8859-1
|
||||||
|
# et_EE.ISO-8859-15 ISO-8859-15
|
||||||
|
# et_EE.UTF-8 UTF-8
|
||||||
|
# eu_ES ISO-8859-1
|
||||||
|
# eu_ES.UTF-8 UTF-8
|
||||||
|
# eu_ES@euro ISO-8859-15
|
||||||
|
# eu_FR ISO-8859-1
|
||||||
|
# eu_FR.UTF-8 UTF-8
|
||||||
|
# eu_FR@euro ISO-8859-15
|
||||||
|
# fa_IR UTF-8
|
||||||
|
# ff_SN UTF-8
|
||||||
|
# fi_FI ISO-8859-1
|
||||||
|
# fi_FI.UTF-8 UTF-8
|
||||||
|
# fi_FI@euro ISO-8859-15
|
||||||
|
# fil_PH UTF-8
|
||||||
|
# fo_FO ISO-8859-1
|
||||||
|
# fo_FO.UTF-8 UTF-8
|
||||||
|
# fr_BE ISO-8859-1
|
||||||
|
# fr_BE.UTF-8 UTF-8
|
||||||
|
# fr_BE@euro ISO-8859-15
|
||||||
|
# fr_CA ISO-8859-1
|
||||||
|
# fr_CA.UTF-8 UTF-8
|
||||||
|
# fr_CH ISO-8859-1
|
||||||
|
# fr_CH.UTF-8 UTF-8
|
||||||
|
# fr_FR ISO-8859-1
|
||||||
|
# fr_FR.UTF-8 UTF-8
|
||||||
|
# fr_FR@euro ISO-8859-15
|
||||||
|
# fr_LU ISO-8859-1
|
||||||
|
# fr_LU.UTF-8 UTF-8
|
||||||
|
# fr_LU@euro ISO-8859-15
|
||||||
|
# fur_IT UTF-8
|
||||||
|
# fy_DE UTF-8
|
||||||
|
# fy_NL UTF-8
|
||||||
|
# ga_IE ISO-8859-1
|
||||||
|
# ga_IE.UTF-8 UTF-8
|
||||||
|
# ga_IE@euro ISO-8859-15
|
||||||
|
# gbm_IN UTF-8
|
||||||
|
# gd_GB ISO-8859-15
|
||||||
|
# gd_GB.UTF-8 UTF-8
|
||||||
|
# gez_ER UTF-8
|
||||||
|
# gez_ER@abegede UTF-8
|
||||||
|
# gez_ET UTF-8
|
||||||
|
# gez_ET@abegede UTF-8
|
||||||
|
# gl_ES ISO-8859-1
|
||||||
|
# gl_ES.UTF-8 UTF-8
|
||||||
|
# gl_ES@euro ISO-8859-15
|
||||||
|
# gu_IN UTF-8
|
||||||
|
# gv_GB ISO-8859-1
|
||||||
|
# gv_GB.UTF-8 UTF-8
|
||||||
|
# ha_NG UTF-8
|
||||||
|
# hak_TW UTF-8
|
||||||
|
# he_IL ISO-8859-8
|
||||||
|
# he_IL.UTF-8 UTF-8
|
||||||
|
# hi_IN UTF-8
|
||||||
|
# hif_FJ UTF-8
|
||||||
|
# hne_IN UTF-8
|
||||||
|
# hr_HR ISO-8859-2
|
||||||
|
# hr_HR.UTF-8 UTF-8
|
||||||
|
# hsb_DE ISO-8859-2
|
||||||
|
# hsb_DE.UTF-8 UTF-8
|
||||||
|
# ht_HT UTF-8
|
||||||
|
# hu_HU ISO-8859-2
|
||||||
|
# hu_HU.UTF-8 UTF-8
|
||||||
|
# hy_AM UTF-8
|
||||||
|
# hy_AM.ARMSCII-8 ARMSCII-8
|
||||||
|
# ia_FR UTF-8
|
||||||
|
# id_ID ISO-8859-1
|
||||||
|
# id_ID.UTF-8 UTF-8
|
||||||
|
# ig_NG UTF-8
|
||||||
|
# ik_CA UTF-8
|
||||||
|
# is_IS ISO-8859-1
|
||||||
|
# is_IS.UTF-8 UTF-8
|
||||||
|
# it_CH ISO-8859-1
|
||||||
|
# it_CH.UTF-8 UTF-8
|
||||||
|
# it_IT ISO-8859-1
|
||||||
|
# it_IT.UTF-8 UTF-8
|
||||||
|
# it_IT@euro ISO-8859-15
|
||||||
|
# iu_CA UTF-8
|
||||||
|
# ja_JP.EUC-JP EUC-JP
|
||||||
|
ja_JP.UTF-8 UTF-8
|
||||||
|
# ka_GE GEORGIAN-PS
|
||||||
|
# ka_GE.UTF-8 UTF-8
|
||||||
|
# kab_DZ UTF-8
|
||||||
|
# kk_KZ PT154
|
||||||
|
# kk_KZ.RK1048 RK1048
|
||||||
|
# kk_KZ.UTF-8 UTF-8
|
||||||
|
# kl_GL ISO-8859-1
|
||||||
|
# kl_GL.UTF-8 UTF-8
|
||||||
|
# km_KH UTF-8
|
||||||
|
# kn_IN UTF-8
|
||||||
|
# ko_KR.EUC-KR EUC-KR
|
||||||
|
ko_KR.UTF-8 UTF-8
|
||||||
|
# kok_IN UTF-8
|
||||||
|
# ks_IN UTF-8
|
||||||
|
# ks_IN@devanagari UTF-8
|
||||||
|
# ku_TR ISO-8859-9
|
||||||
|
# ku_TR.UTF-8 UTF-8
|
||||||
|
# kv_RU UTF-8
|
||||||
|
# kw_GB ISO-8859-1
|
||||||
|
# kw_GB.UTF-8 UTF-8
|
||||||
|
# ky_KG UTF-8
|
||||||
|
# lb_LU UTF-8
|
||||||
|
# lg_UG ISO-8859-10
|
||||||
|
# lg_UG.UTF-8 UTF-8
|
||||||
|
# li_BE UTF-8
|
||||||
|
# li_NL UTF-8
|
||||||
|
# lij_IT UTF-8
|
||||||
|
# ln_CD UTF-8
|
||||||
|
# lo_LA UTF-8
|
||||||
|
# lt_LT ISO-8859-13
|
||||||
|
# lt_LT.UTF-8 UTF-8
|
||||||
|
# lv_LV ISO-8859-13
|
||||||
|
# lv_LV.UTF-8 UTF-8
|
||||||
|
# lzh_TW UTF-8
|
||||||
|
# mag_IN UTF-8
|
||||||
|
# mai_IN UTF-8
|
||||||
|
# mai_NP UTF-8
|
||||||
|
# mfe_MU UTF-8
|
||||||
|
# mg_MG ISO-8859-15
|
||||||
|
# mg_MG.UTF-8 UTF-8
|
||||||
|
# mhr_RU UTF-8
|
||||||
|
# mi_NZ ISO-8859-13
|
||||||
|
# mi_NZ.UTF-8 UTF-8
|
||||||
|
# miq_NI UTF-8
|
||||||
|
# mjw_IN UTF-8
|
||||||
|
# mk_MK ISO-8859-5
|
||||||
|
# mk_MK.UTF-8 UTF-8
|
||||||
|
# ml_IN UTF-8
|
||||||
|
# mn_MN UTF-8
|
||||||
|
# mni_IN UTF-8
|
||||||
|
# mnw_MM UTF-8
|
||||||
|
# mr_IN UTF-8
|
||||||
|
# ms_MY ISO-8859-1
|
||||||
|
# ms_MY.UTF-8 UTF-8
|
||||||
|
# mt_MT ISO-8859-3
|
||||||
|
# mt_MT.UTF-8 UTF-8
|
||||||
|
# my_MM UTF-8
|
||||||
|
# nan_TW UTF-8
|
||||||
|
# nan_TW@latin UTF-8
|
||||||
|
# nb_NO ISO-8859-1
|
||||||
|
# nb_NO.UTF-8 UTF-8
|
||||||
|
# nds_DE UTF-8
|
||||||
|
# nds_NL UTF-8
|
||||||
|
# ne_NP UTF-8
|
||||||
|
# nhn_MX UTF-8
|
||||||
|
# niu_NU UTF-8
|
||||||
|
# niu_NZ UTF-8
|
||||||
|
# nl_AW UTF-8
|
||||||
|
# nl_BE ISO-8859-1
|
||||||
|
# nl_BE.UTF-8 UTF-8
|
||||||
|
# nl_BE@euro ISO-8859-15
|
||||||
|
# nl_NL ISO-8859-1
|
||||||
|
# nl_NL.UTF-8 UTF-8
|
||||||
|
# nl_NL@euro ISO-8859-15
|
||||||
|
# nn_NO ISO-8859-1
|
||||||
|
# nn_NO.UTF-8 UTF-8
|
||||||
|
# nr_ZA UTF-8
|
||||||
|
# nso_ZA UTF-8
|
||||||
|
# oc_FR ISO-8859-1
|
||||||
|
# oc_FR.UTF-8 UTF-8
|
||||||
|
# om_ET UTF-8
|
||||||
|
# om_KE ISO-8859-1
|
||||||
|
# om_KE.UTF-8 UTF-8
|
||||||
|
# or_IN UTF-8
|
||||||
|
# os_RU UTF-8
|
||||||
|
# pa_IN UTF-8
|
||||||
|
# pa_PK UTF-8
|
||||||
|
# pap_AW UTF-8
|
||||||
|
# pap_CW UTF-8
|
||||||
|
# pl_PL ISO-8859-2
|
||||||
|
# pl_PL.UTF-8 UTF-8
|
||||||
|
# ps_AF UTF-8
|
||||||
|
# pt_BR ISO-8859-1
|
||||||
|
# pt_BR.UTF-8 UTF-8
|
||||||
|
# pt_PT ISO-8859-1
|
||||||
|
# pt_PT.UTF-8 UTF-8
|
||||||
|
# pt_PT@euro ISO-8859-15
|
||||||
|
# quz_PE UTF-8
|
||||||
|
# raj_IN UTF-8
|
||||||
|
# rif_MA UTF-8
|
||||||
|
# ro_RO ISO-8859-2
|
||||||
|
# ro_RO.UTF-8 UTF-8
|
||||||
|
# ru_RU ISO-8859-5
|
||||||
|
# ru_RU.CP1251 CP1251
|
||||||
|
# ru_RU.KOI8-R KOI8-R
|
||||||
|
ru_RU.UTF-8 UTF-8
|
||||||
|
# ru_UA KOI8-U
|
||||||
|
# ru_UA.UTF-8 UTF-8
|
||||||
|
# rw_RW UTF-8
|
||||||
|
# sa_IN UTF-8
|
||||||
|
# sah_RU UTF-8
|
||||||
|
# sat_IN UTF-8
|
||||||
|
# sc_IT UTF-8
|
||||||
|
# sd_IN UTF-8
|
||||||
|
# sd_IN@devanagari UTF-8
|
||||||
|
# sd_PK UTF-8
|
||||||
|
# se_NO UTF-8
|
||||||
|
# sgs_LT UTF-8
|
||||||
|
# shn_MM UTF-8
|
||||||
|
# shs_CA UTF-8
|
||||||
|
# si_LK UTF-8
|
||||||
|
# sid_ET UTF-8
|
||||||
|
# sk_SK ISO-8859-2
|
||||||
|
# sk_SK.UTF-8 UTF-8
|
||||||
|
# sl_SI ISO-8859-2
|
||||||
|
# sl_SI.UTF-8 UTF-8
|
||||||
|
# sm_WS UTF-8
|
||||||
|
# so_DJ ISO-8859-1
|
||||||
|
# so_DJ.UTF-8 UTF-8
|
||||||
|
# so_ET UTF-8
|
||||||
|
# so_KE ISO-8859-1
|
||||||
|
# so_KE.UTF-8 UTF-8
|
||||||
|
# so_SO ISO-8859-1
|
||||||
|
# so_SO.UTF-8 UTF-8
|
||||||
|
# sq_AL ISO-8859-1
|
||||||
|
# sq_AL.UTF-8 UTF-8
|
||||||
|
# sq_MK UTF-8
|
||||||
|
# sr_ME UTF-8
|
||||||
|
# sr_RS UTF-8
|
||||||
|
# sr_RS@latin UTF-8
|
||||||
|
# ss_ZA UTF-8
|
||||||
|
# ssy_ER UTF-8
|
||||||
|
# st_ZA ISO-8859-1
|
||||||
|
# st_ZA.UTF-8 UTF-8
|
||||||
|
# su_ID UTF-8
|
||||||
|
# sv_FI ISO-8859-1
|
||||||
|
# sv_FI.UTF-8 UTF-8
|
||||||
|
# sv_FI@euro ISO-8859-15
|
||||||
|
# sv_SE ISO-8859-1
|
||||||
|
# sv_SE.ISO-8859-15 ISO-8859-15
|
||||||
|
# sv_SE.UTF-8 UTF-8
|
||||||
|
# sw_KE UTF-8
|
||||||
|
# sw_TZ UTF-8
|
||||||
|
# syr UTF-8
|
||||||
|
# szl_PL UTF-8
|
||||||
|
# ta_IN UTF-8
|
||||||
|
# ta_LK UTF-8
|
||||||
|
# tcy_IN.UTF-8 UTF-8
|
||||||
|
# te_IN UTF-8
|
||||||
|
# tg_TJ KOI8-T
|
||||||
|
# tg_TJ.UTF-8 UTF-8
|
||||||
|
# th_TH TIS-620
|
||||||
|
th_TH.UTF-8 UTF-8
|
||||||
|
# the_NP UTF-8
|
||||||
|
# ti_ER UTF-8
|
||||||
|
# ti_ET UTF-8
|
||||||
|
# tig_ER UTF-8
|
||||||
|
# tk_TM UTF-8
|
||||||
|
# tl_PH ISO-8859-1
|
||||||
|
# tl_PH.UTF-8 UTF-8
|
||||||
|
# tn_ZA UTF-8
|
||||||
|
# to_TO UTF-8
|
||||||
|
# tok UTF-8
|
||||||
|
# tpi_PG UTF-8
|
||||||
|
# tr_CY ISO-8859-9
|
||||||
|
# tr_CY.UTF-8 UTF-8
|
||||||
|
# tr_TR ISO-8859-9
|
||||||
|
# tr_TR.UTF-8 UTF-8
|
||||||
|
# ts_ZA UTF-8
|
||||||
|
# tt_RU UTF-8
|
||||||
|
# tt_RU@iqtelif UTF-8
|
||||||
|
# ug_CN UTF-8
|
||||||
|
# ug_CN@latin UTF-8
|
||||||
|
# uk_UA KOI8-U
|
||||||
|
# uk_UA.UTF-8 UTF-8
|
||||||
|
# unm_US UTF-8
|
||||||
|
# ur_IN UTF-8
|
||||||
|
# ur_PK UTF-8
|
||||||
|
# uz_UZ ISO-8859-1
|
||||||
|
# uz_UZ.UTF-8 UTF-8
|
||||||
|
# uz_UZ@cyrillic UTF-8
|
||||||
|
# ve_ZA UTF-8
|
||||||
|
# vi_VN UTF-8
|
||||||
|
# wa_BE ISO-8859-1
|
||||||
|
# wa_BE.UTF-8 UTF-8
|
||||||
|
# wa_BE@euro ISO-8859-15
|
||||||
|
# wae_CH UTF-8
|
||||||
|
# wal_ET UTF-8
|
||||||
|
# wo_SN UTF-8
|
||||||
|
# xh_ZA ISO-8859-1
|
||||||
|
# xh_ZA.UTF-8 UTF-8
|
||||||
|
# yi_US CP1255
|
||||||
|
# yi_US.UTF-8 UTF-8
|
||||||
|
# yo_NG UTF-8
|
||||||
|
# yue_HK UTF-8
|
||||||
|
# yuw_PG UTF-8
|
||||||
|
# zgh_MA UTF-8
|
||||||
|
# zh_CN GB2312
|
||||||
|
# zh_CN.GB18030 GB18030
|
||||||
|
# zh_CN.GBK GBK
|
||||||
|
zh_CN.UTF-8 UTF-8
|
||||||
|
# zh_HK BIG5-HKSCS
|
||||||
|
# zh_HK.UTF-8 UTF-8
|
||||||
|
# zh_SG GB2312
|
||||||
|
# zh_SG.GBK GBK
|
||||||
|
# zh_SG.UTF-8 UTF-8
|
||||||
|
# zh_TW BIG5
|
||||||
|
# zh_TW.EUC-TW EUC-TW
|
||||||
|
zh_TW.UTF-8 UTF-8
|
||||||
|
# zu_ZA ISO-8859-1
|
||||||
|
# zu_ZA.UTF-8 UTF-8
|
1
env/timezone
vendored
Normal file
1
env/timezone
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Asia/Taipei
|
|
@ -7,6 +7,9 @@ from backend import api
|
||||||
from frontend.grpc.protobuf import igapi_pb2_grpc, igapi_pb2
|
from frontend.grpc.protobuf import igapi_pb2_grpc, igapi_pb2
|
||||||
from frontend.grpc.protobuf.igapi_pb2 import Request, Reply
|
from frontend.grpc.protobuf.igapi_pb2 import Request, Reply
|
||||||
|
|
||||||
|
# configuration
|
||||||
|
PORT = 50050
|
||||||
|
|
||||||
# logging
|
# logging
|
||||||
grpclog = logging.getLogger("frontend.grpc")
|
grpclog = logging.getLogger("frontend.grpc")
|
||||||
grpclog.setLevel(level=logging.INFO)
|
grpclog.setLevel(level=logging.INFO)
|
||||||
|
@ -77,9 +80,9 @@ async def serve() -> None:
|
||||||
igapi_pb2_grpc.add_IGAPIServicer_to_server(
|
igapi_pb2_grpc.add_IGAPIServicer_to_server(
|
||||||
IGAPI_Server(), server
|
IGAPI_Server(), server
|
||||||
)
|
)
|
||||||
server.add_insecure_port("[::]:50051")
|
server.add_insecure_port(f"[::]:{PORT}")
|
||||||
await server.start()
|
await server.start()
|
||||||
grpclog.info("gRPC Server listening on 0.0.0.0:50051")
|
grpclog.info(f"gRPC Server listening on 0.0.0.0:{PORT}")
|
||||||
await server.wait_for_termination()
|
await server.wait_for_termination()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,50 +1,46 @@
|
||||||
from hashlib import sha512
|
import datetime
|
||||||
import secrets
|
|
||||||
import time
|
|
||||||
import requests
|
import requests
|
||||||
import io
|
import io
|
||||||
|
|
||||||
from config.config import TMP
|
"""
|
||||||
|
Interface
|
||||||
|
|
||||||
# define
|
The bridge between web application(niming) and igapi.
|
||||||
an_example_of_context = {
|
An interface should have a get() function.
|
||||||
"id": int,
|
"""
|
||||||
"metadata": {
|
|
||||||
"create_time": int,
|
|
||||||
"author": str,
|
|
||||||
"tags": list[str],
|
|
||||||
"category": str
|
|
||||||
},
|
|
||||||
"content": {
|
|
||||||
"text": str,
|
|
||||||
"media": [
|
|
||||||
io.BytesIO
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def get(index:int, media:bool=True) -> dict | None:
|
def get(index:int, media:bool=True) -> dict | None:
|
||||||
|
"""
|
||||||
|
Every interface should have this function.
|
||||||
|
Backend calls this function to get data of a post.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
index (int): ID of the post
|
||||||
|
media (bool): Send media or not
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: Data of a post. Formatted as shown in Note 1 (an_example_of_context)
|
||||||
|
None: An error occurred, and nothing was returned.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# get data
|
||||||
|
## fake server in localhost
|
||||||
|
### where is the api of web application?
|
||||||
res = requests.get("http://localhost:5000/article/%d?media_count=1"%index)
|
res = requests.get("http://localhost:5000/article/%d?media_count=1"%index)
|
||||||
if res.status_code != 200:
|
if res.status_code != 200:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
rj = res.json()
|
rj = res.json()
|
||||||
media = []
|
media = []
|
||||||
bytesio = 0
|
|
||||||
|
|
||||||
|
# get media
|
||||||
if media:
|
if media:
|
||||||
for m in rj["media"]:
|
for m in rj["media"]:
|
||||||
_m = requests.get(m)
|
_m = requests.get(m)
|
||||||
if _m.status_code == 200:
|
if _m.status_code == 200:
|
||||||
#if bytesio: # save in memory
|
media.append(io.BytesIO(_m.content))
|
||||||
media.append(io.BytesIO(_m.content))
|
|
||||||
#else: # save in file
|
|
||||||
# filename = sha512( (str(time.time())+secrets.token_urlsafe(nbytes=16)).encode() ).hexdigest()
|
|
||||||
# filename = f"./{TMP}/{filename}"
|
|
||||||
# with open(filename, "wb") as f:
|
|
||||||
# f.write(_m.content)
|
|
||||||
# media.append(filename)
|
|
||||||
|
|
||||||
|
# return
|
||||||
result = {
|
result = {
|
||||||
"id": rj["id"],
|
"id": rj["id"],
|
||||||
"metadata": {
|
"metadata": {
|
||||||
|
@ -60,3 +56,21 @@ def get(index:int, media:bool=True) -> dict | None:
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
# Note 1
|
||||||
|
an_example_of_context = {
|
||||||
|
"id": int,
|
||||||
|
"metadata": {
|
||||||
|
"create_time": int | datetime.datetime,
|
||||||
|
"author": str,
|
||||||
|
"tags": list[str],
|
||||||
|
"category": str
|
||||||
|
},
|
||||||
|
"content": {
|
||||||
|
"text": str,
|
||||||
|
"media": [
|
||||||
|
io.BytesIO
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,11 +1,22 @@
|
||||||
|
# backend
|
||||||
moviepy==1.0.3
|
moviepy==1.0.3
|
||||||
instagrapi
|
instagrapi
|
||||||
sqlalchemy
|
sqlalchemy
|
||||||
sqlalchemy_utils
|
sqlalchemy_utils
|
||||||
protobuf==5.28.3
|
|
||||||
Pillow
|
Pillow
|
||||||
pillow-heif
|
pillow-heif
|
||||||
asyncio
|
asyncio
|
||||||
grpcio
|
|
||||||
cachetools
|
cachetools
|
||||||
python-magic
|
python-magic
|
||||||
|
|
||||||
|
# frontend.grpc
|
||||||
|
grpcio
|
||||||
|
protobuf==5.28.3
|
||||||
|
|
||||||
|
# PictureMaker
|
||||||
|
playwright
|
||||||
|
jinja2
|
||||||
|
|
||||||
|
# other
|
||||||
|
#pymysql
|
||||||
|
#cryptography
|
Loading…
Add table
Reference in a new issue