From 245253cd9e0ebaad3b9b4efbfae8c0e3090afc9b Mon Sep 17 00:00:00 2001
From: wangzhibo <wangzhibo@shsening.com>
Date: 星期三, 30 七月 2025 22:00:53 +0800
Subject: [PATCH] 添加 AI 生成/改写 docx ;添加微信公众号自动发布

---
 auto_media_publisher/modifiers/rewriter/docx_rewriter_gemini.py |   81 +++++++++++++++++++++++++++-------------
 1 files changed, 55 insertions(+), 26 deletions(-)

diff --git a/auto_media_publisher/modifiers/rewriter/docx_rewriter_gemini.py b/auto_media_publisher/modifiers/rewriter/docx_rewriter_gemini.py
index d9cf694..efacf93 100644
--- a/auto_media_publisher/modifiers/rewriter/docx_rewriter_gemini.py
+++ b/auto_media_publisher/modifiers/rewriter/docx_rewriter_gemini.py
@@ -1,7 +1,8 @@
 from docx import Document
-from docx.shared import Inches
-from docx.enum.text import WD_ALIGN_PARAGRAPH
+from docx.shared import Pt, Inches
 from docx.oxml.ns import qn
+from io import BytesIO
+from docx.enum.text import WD_ALIGN_PARAGRAPH
 import random
 import threading
 import re
@@ -11,20 +12,23 @@
 from io import BytesIO
 from PIL import Image
 import google.generativeai as genai
-from auto_media_publisher.config.conf_base import GOOGLE_API_KEY,GOOGLE_MODEL,GOOGLE_CHAT_MIN_INTERVAL
-from auto_media_publisher.config.conf_base import GOOGLE_GEMINI_TEMPERATURE_MIN,GOOGLE_GEMINI_TEMPERATURE_MAX,GOOGLE_REWRITE_STYLE_MAP,GEMINI_PROMPT_INIT_DEFAULT
+from auto_media_publisher.config.conf_base import GOOGLE_API_KEY,GOOGLE_MODEL,GOOGLE_CHAT_MIN_INTERVAL,DEFAULT_PREFIX_MAP,DEFAULT_SURFIX_MAP
+from auto_media_publisher.config.conf_base import GOOGLE_GEMINI_TEMPERATURE_MIN,GOOGLE_GEMINI_TEMPERATURE_MAX,GOOGLE_GEMINI_TOPN_MIN,GOOGLE_GEMINI_TOPN_MAX,GOOGLE_REWRITE_STYLE_MAP,GEMINI_PROMPT_INIT_DEFAULT
 from auto_media_publisher.config.conf_base import GEMINI_PROMPT_TITLE,GEMINI_PROMPT_DESCRIPTION,GEMINI_PROMPT_TAG
 from auto_media_publisher.utils.logger import get_logger
 from auto_media_publisher.utils.utils_text2image_pollinations import Text2ImageGenerator
 
-class GeminiDocxRewriter:
-    def __init__(self,rewrite_style="default" ):
+
+class DocxRewriterGemini:
+    def __init__(self,rewrite_style="default" ,docx_author="鎴�"):
         genai.configure(api_key=GOOGLE_API_KEY)
         self.temperature = round(random.uniform(GOOGLE_GEMINI_TEMPERATURE_MIN, GOOGLE_GEMINI_TEMPERATURE_MAX), 2)
+        self.top_n = round(random.uniform(GOOGLE_GEMINI_TOPN_MIN, GOOGLE_GEMINI_TOPN_MAX), 2)
         self.model = genai.GenerativeModel(GOOGLE_MODEL,
             generation_config=genai.types.GenerationConfig(
                 temperature=self.temperature,
-                top_p=1.0
+                top_p=self.top_n,
+                top_k=random.choice([40, 50, 80, 100])
             )
         )
         if rewrite_style =="random":
@@ -32,11 +36,16 @@
         else:
             self.rewrite_style = rewrite_style
         
+        self.prefix_text = f"鎴戞槸{docx_author}锛寋random.choice(DEFAULT_PREFIX_MAP)}"
+        self.surfix_text = random.choice(DEFAULT_SURFIX_MAP)
+
         self.last_call_time = 0
         self.min_interval = GOOGLE_CHAT_MIN_INTERVAL  # 闄愬埗鏈�鐭姹傞棿闅旓紙绉掞級
         self.lock = threading.Lock()  # 澶氱嚎绋嬪苟鍙戞椂涔熷畨鍏�
         self.logger = get_logger(self.__class__.__name__,"admin")
-        self.text2imager = Text2ImageGenerator()
+        self.text2imager = Text2ImageGenerator(width=900,height=383)
+
+        self.summary_info = {}
     
     #@retry(stop=stop_after_attempt(3), wait=wait_fixed(2))  # 鑷姩閲嶈瘯鏈哄埗
     def safe_send_message(self, content: str):
@@ -59,16 +68,11 @@
             rewritten = self._rewrite_blocks(blocks)
             self._save_to_new_docx(rewritten, output_path)
             
-        summary_info = self.summarize_title_intro_keywords()
-        print(summary_info)
-        self.text2imager.generate_image(summary_info["summary"],output_path.replace(".docx",".jpg"))
-        summary_info["cover_image"] = output_path.replace(".docx",".jpg")
+        self.summary_info = self._summarize_title_intro_keywords()
+        print(self.summary_info)
+        self.text2imager.generate_image(self.summary_info["description"],output_path.replace(".docx",".png"))
+        self.summary_info["path_cover"] = output_path.replace(".docx",".png")
 
-        # 3. 鍐欏叆纾佺洏
-        with open(output_path.replace(".docx",".json"), "w", encoding="utf-8") as f:
-            json.dump(summary_info, f, ensure_ascii=False, indent=4)
-
-        return summary_info
     
     def extract_docx_blocks_by_order(self,docx_path):
         doc = Document(docx_path)
@@ -146,28 +150,53 @@
 
     def _save_to_new_docx(self, blocks, output_path):
         doc = Document()
+        # 璁剧疆榛樿鏍峰紡
+        style = doc.styles['Normal']
+        font = style.font
+        font.name = '妤蜂綋'  # 瑗挎枃瀛椾綋璁剧疆涓烘シ浣�
+        font.size = Pt(10.5)  # 灏忓洓瀛椾綋
+        style._element.rPr.rFonts.set(qn('w:eastAsia'), '妤蜂綋')  # 涓枃瀛椾綋璁惧畾
+
+        # 鍓嶈█
+        para = doc.add_paragraph(self.prefix_text)
+        para.paragraph_format.line_spacing = 1.5
+        para.paragraph_format.space_before = Pt(0)
+        para.paragraph_format.space_after = Pt(0)
+
+
         for block in blocks:
-            if block["type"]=="text":
+            if block["type"] == "text":
                 for line in block["content"].split("\n"):
-                    doc.add_paragraph(line.strip())
+                    para = doc.add_paragraph(line.strip())
+                    para.paragraph_format.line_spacing = 1.5  # 琛岃窛1.5鍊�
+                    para.paragraph_format.space_before = Pt(0)  # 娈靛墠0纾�
+                    para.paragraph_format.space_after = Pt(0)   # 娈靛悗0纾�
             elif block["type"] == "image":
                 image_data = block["content"]
                 image_stream = BytesIO(image_data)
                 paragraph = doc.add_paragraph()
                 run = paragraph.add_run()
-                run.add_picture(image_stream, width=Inches(5.5))  # 閫傚綋璋冩暣瀹藉害
+                run.add_picture(image_stream, width=Inches(5.5))
                 paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER
 
-        doc.save(output_path)
+        
+        # 缁撹
+        para2 = doc.add_paragraph(self.surfix_text)
+        para2.paragraph_format.line_spacing = 1.5
+        para2.paragraph_format.space_before = Pt(12)
+        para2.paragraph_format.space_after = Pt(0)
 
-    def summarize_title_intro_keywords(self) -> dict:
+        doc.save(output_path)
+       
+
+    def _summarize_title_intro_keywords(self) -> dict:
         title = self.safe_send_message(GEMINI_PROMPT_TITLE).text.strip()
-        summary = self.safe_send_message(GEMINI_PROMPT_DESCRIPTION).text.strip()
+        description = self.safe_send_message(GEMINI_PROMPT_DESCRIPTION).text.strip()
         keywords = self.safe_send_message(GEMINI_PROMPT_TAG).text.strip()
 
         return {
-            "title": title,
-            "summary": summary,
-            "keywords": re.split(r'[銆�,\s]+', keywords.strip("銆�"))
+            "title": title.splitlines()[0].strip()[:64],
+            "description": description[:120],
+            "tags": re.split(r'[銆�,\s]+', keywords.strip("銆�"))
         }
 

--
Gitblit v1.9.1