game/addons/game_base/models/story.py

59 lines
2.5 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- coding: utf-8 -*-
import os
import sys
import subprocess
import logging
from odoo import models, fields
from odoo.modules.module import get_module_path
_logger = logging.getLogger(__name__)
class GameStoryVolume(models.Model):
_name = 'game.story.volume'
_description = '小说卷'
_order = 'sequence, id'
_rec_name = 'name'
name = fields.Char(string='卷名', required=True, index=True)
sequence = fields.Integer(string='序号', default=10, index=True)
intro = fields.Html(string='卷首语')
chapter_ids = fields.One2many('game.story.chapter', 'volume_id', string='章节')
def action_sync_novel(self):
"""由定时任务ir.cron调用把 novel/ 下的 Markdown 增量同步进数据库。
走独立同步脚本novel/sync_novel.py单一实现来源。
注意:脚本依赖 venv 的 psycopg2而 Odoo 可能跑在系统 Python 上,
因此显式使用项目 venv 的 python 执行,而非 sys.executable。"""
base = get_module_path('game_base')
script = os.path.normpath(os.path.join(base, '..', '..', 'novel', 'sync_novel.py'))
if not os.path.exists(script):
_logger.warning('小说同步脚本不存在: %s', script)
return
# 优先用项目 venv 的 python自带 psycopg2否则退化为当前解释器
venv_py = os.path.normpath(os.path.join(base, '..', '..', '..', '.venv', 'Scripts', 'python.exe'))
python = venv_py if os.path.exists(venv_py) else sys.executable
try:
proc = subprocess.run([python, script],
capture_output=True, text=True, timeout=180)
if proc.returncode != 0:
_logger.error('小说同步失败(%s): %s', proc.returncode, (proc.stderr or '')[-2000:])
else:
last = (proc.stdout or '').strip().splitlines()
_logger.info('小说同步完成: %s', last[-1] if last else 'ok')
except Exception as e:
_logger.exception('小说同步异常: %s', e)
class GameStoryChapter(models.Model):
_name = 'game.story.chapter'
_description = '小说章节'
_order = 'volume_id, sequence, id'
_rec_name = 'name'
volume_id = fields.Many2one('game.story.volume', string='所属卷',
required=True, ondelete='cascade', index=True)
name = fields.Char(string='章名', required=True, index=True)
sequence = fields.Integer(string='序号', default=10, index=True)
body_html = fields.Html(string='正文')