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 | ||||
| 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 | ||||
| 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 | ||||
| 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 -r /app/requirements.txt | ||||
| 
 | ||||
| # install playwright | ||||
| RUN playwright install-deps | ||||
| RUN playwright install | ||||
| 
 | ||||
| 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"] | ||||
							
								
								
									
										3
									
								
								TODO
									
										
									
									
									
								
							
							
						
						
									
										3
									
								
								TODO
									
										
									
									
									
								
							|  | @ -1,4 +1,7 @@ | |||
| [ ] 改善Traceback的收集 | ||||
| [ ] GIF Support | ||||
| [ ] api: ID查IGID,IGID反查ID | ||||
| [ ] api: 返回錯誤處理紀錄 | ||||
| [V] 本地儲存ID對IGID表 | ||||
| 
 | ||||
| [ ] 測試 | ||||
							
								
								
									
										6
									
								
								app.py
									
										
									
									
									
								
							
							
						
						
									
										6
									
								
								app.py
									
										
									
									
									
								
							|  | @ -2,6 +2,7 @@ import importlib.util | |||
| import logging | ||||
| import threading | ||||
| import os | ||||
| import time | ||||
| 
 | ||||
| from backend import backend | ||||
| from backend.ig import IG | ||||
|  | @ -75,6 +76,11 @@ def main(): | |||
| 
 | ||||
|     # end | ||||
|     loaderlog.info("Loaded") | ||||
|      | ||||
|     # infinity waiting - prevent main thread from exiting | ||||
|     while True: | ||||
|         time.sleep(60) | ||||
|      | ||||
| 
 | ||||
| if __name__ == "__main__": | ||||
|     main() | ||||
|  | @ -86,10 +86,10 @@ def upload_media(context:str, paths:List[str]) -> dict | None: | |||
|         if len(paths) == 0: | ||||
|             return None | ||||
|         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() | ||||
|         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() | ||||
|              | ||||
|         return media | ||||
|  |  | |||
|  | @ -26,38 +26,23 @@ def upload(aid:int) -> Tuple[str, int]: | |||
|     # multimedia -> tmp file | ||||
|     tmp_path = [] | ||||
|     for m in article["content"]["media"]: | ||||
|         _binary = m.read() | ||||
|         # check mime type | ||||
|         mime = magic.Magic(mime=True) | ||||
|         tp = mime.from_buffer(m.read()) | ||||
|         tp = mime.from_buffer(_binary) | ||||
|         # save file | ||||
|         filename, err = fileProcessor.file_saver(tp, m.read()) | ||||
|         filename, err = fileProcessor.file_saver(tp, _binary) | ||||
|         if err: | ||||
|             clean(tmp_path) | ||||
|             return "Error while saving file", 1 | ||||
|             return "Error while saving file : %s"%filename, 1 | ||||
|         tmp_path.append(filename) | ||||
|     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) | ||||
|     if proma_file is None: | ||||
|         clean(tmp_path) | ||||
|         return "Error while generating proma_file", 1 | ||||
|     tmp_path = [proma_file] + tmp_path | ||||
| 
 | ||||
|     # 送交 IG 上傳 | ||||
|  |  | |||
|  | @ -9,7 +9,7 @@ services: | |||
|     volumes: | ||||
|       - ".:/app" | ||||
|     ports: | ||||
|       - "50051:50051" | ||||
|       - "50050:50050" # frontend.grpc | ||||
|     restart: unless-stopped | ||||
|     working_dir: /app | ||||
|     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.igapi_pb2 import Request, Reply | ||||
| 
 | ||||
| # configuration | ||||
| PORT = 50050 | ||||
| 
 | ||||
| # logging | ||||
| grpclog = logging.getLogger("frontend.grpc") | ||||
| grpclog.setLevel(level=logging.INFO) | ||||
|  | @ -77,9 +80,9 @@ async def serve() -> None: | |||
|     igapi_pb2_grpc.add_IGAPIServicer_to_server( | ||||
|         IGAPI_Server(), server | ||||
|     ) | ||||
|     server.add_insecure_port("[::]:50051") | ||||
|     server.add_insecure_port(f"[::]:{PORT}") | ||||
|     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() | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,50 +1,46 @@ | |||
| from hashlib import sha512 | ||||
| import secrets | ||||
| import time | ||||
| import datetime | ||||
| import requests | ||||
| import io | ||||
| 
 | ||||
| from config.config import TMP | ||||
| """ | ||||
| Interface | ||||
| 
 | ||||
| # define | ||||
| an_example_of_context = { | ||||
|     "id": int, | ||||
|     "metadata": { | ||||
|         "create_time": int, | ||||
|         "author": str, | ||||
|         "tags": list[str], | ||||
|         "category": str | ||||
|     }, | ||||
|     "content": { | ||||
|         "text": str, | ||||
|         "media": [ | ||||
|             io.BytesIO | ||||
|         ] | ||||
|     } | ||||
| } | ||||
| The bridge between web application(niming) and igapi. | ||||
| An interface should have a get() function. | ||||
| """ | ||||
| 
 | ||||
| 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) | ||||
|     if res.status_code != 200: | ||||
|         return None | ||||
|      | ||||
|     rj = res.json() | ||||
|     media = [] | ||||
|     bytesio = 0 | ||||
|      | ||||
|     # get media | ||||
|     if media: | ||||
|         for m in rj["media"]: | ||||
|             _m = requests.get(m) | ||||
|             if _m.status_code == 200: | ||||
|                 #if bytesio: # save in memory | ||||
|                     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) | ||||
|                 media.append(io.BytesIO(_m.content)) | ||||
|      | ||||
|     # return | ||||
|     result = { | ||||
|         "id": rj["id"], | ||||
|         "metadata": { | ||||
|  | @ -60,3 +56,21 @@ def get(index:int, media:bool=True) -> dict | None: | |||
|     } | ||||
|      | ||||
|     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 | ||||
| instagrapi | ||||
| sqlalchemy | ||||
| sqlalchemy_utils | ||||
| protobuf==5.28.3 | ||||
| Pillow | ||||
| pillow-heif | ||||
| asyncio | ||||
| grpcio | ||||
| 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