fixed # 修复astrbot日志未使用logging.basicConfig

This commit is contained in:
2026-10-27 11:40:59 +08:00
parent b3455ded58
commit d05b2e5765
20 changed files with 333 additions and 46 deletions
+33 -1
View File
@@ -15,6 +15,33 @@ from verify_zhenxun import read_package as read_shared
from help_image import build_help_image
def host_logging(content):
"""仅替换日志入口,保留共享业务源码和注释;未知用法交给包校验拒绝。"""
lines = content.decode('utf-8').splitlines(keepends=True)
edits = []
for node in ast.parse(content).body:
if (isinstance(node, ast.Import)
and any(alias.name == 'logging' for alias in node.names)):
if len(node.names) != 1 or node.names[0].asname:
raise ValueError('Unsupported logging import')
edits.append((node.lineno, node.end_lineno, ''))
if (isinstance(node, ast.Assign) and len(node.targets) == 1
and isinstance(node.targets[0], ast.Name)
and isinstance(node.value, ast.Call)
and isinstance(node.value.func, ast.Attribute)
and isinstance(node.value.func.value, ast.Name)
and node.value.func.value.id == 'logging'
and node.value.func.attr == 'getLogger'):
alias = node.targets[0].id
statement = 'from astrbot.api import logger'
if alias != 'logger':
statement += ' as ' + alias
edits.append((node.lineno, node.end_lineno, statement + '\n'))
for start, end, replacement in sorted(edits, reverse=True):
lines[start-1:end] = [replacement]
return ''.join(lines).encode('utf-8')
def render_readme(root):
template = (root / 'readme/astrbot.md').read_text(encoding='utf-8')
marker = '<!-- FARM_COMMANDS -->'
@@ -49,7 +76,7 @@ def build(root, output, *, help_image=None):
files = {name: content for name, content in shared.items()
if name.startswith('_vendor/') or name in (
'_version.py', 'version.txt', 'LICENSE',
)}
) if not name.endswith('/__main__.py')}
source = root / 'integrations/astrbot'
for name in ('main.py', 'avatars.py', '_conf_schema.json',
'requirements.txt', 'CHANGELOG.md'):
@@ -65,6 +92,9 @@ def build(root, output, *, help_image=None):
files['runtime.py'] = (
root / 'integrations/shared/runtime.py'
).read_bytes()
files['runtime_logging.py'] = (
source / 'runtime_logging.py'
).read_bytes()
files['verify_package.py'] = (
root / 'scripts/verify_astrbot.py'
).read_bytes()
@@ -82,6 +112,8 @@ def build(root, output, *, help_image=None):
}, ensure_ascii=False, indent=2) + '\n').encode()
for name, content in files.items():
if name.endswith('.py'):
content = host_logging(content)
files[name] = content
ast.parse(content, filename=name, feature_version=(3, 10))
manifest = {
'schema': 1, 'target': 'astrbot', 'plugin': ROOT_NAME,
+3
View File
@@ -32,6 +32,9 @@ def build(root, output, *, help_image=None):
files[prefix + "runtime.py"] = (
root / "integrations/shared/runtime.py"
).read_bytes()
files[prefix + 'runtime_logging.py'] = (
root / 'integrations/shared/runtime_logging.py'
).read_bytes()
files[prefix + "_vendor/__init__.py"] = b'"""Private farm modules."""\n'
for package in ("farm_core", "farm_render"):
source = root / "src" / package
+3
View File
@@ -57,6 +57,9 @@ def build(root, output, *, help_image=None):
files["runtime.py"] = (
root / "integrations/shared/runtime.py"
).read_bytes()
files['runtime_logging.py'] = (
root / 'integrations/shared/runtime_logging.py'
).read_bytes()
files["_vendor/__init__.py"] = b'"""Private shared farm modules."""\n'
for package in ("farm_core", "farm_render"):
source = root / "src" / package
+33 -1
View File
@@ -1,6 +1,7 @@
"""AstrBot插件ZIP的独立完整性校验;只使用标准库。"""
import argparse
import ast
import hashlib
import json
from pathlib import Path, PurePosixPath
@@ -37,8 +38,39 @@ def verify_files(files):
safe_path(name)
if hashlib.sha256(files[name]).hexdigest() != digest:
raise ValueError('Package checksum mismatch')
if name.endswith('/__main__.py'):
raise ValueError('Development CLI must not be in AstrBot plugin')
if name.endswith('.py'):
tree = ast.parse(files[name], filename=name)
host_loggers = {
alias.asname or alias.name
for node in ast.walk(tree)
if isinstance(node, ast.ImportFrom)
and node.module == 'astrbot.api'
for alias in node.names if alias.name == 'logger'
}
for node in ast.walk(tree):
if (isinstance(node, ast.Import) and any(
alias.name.split('.')[0] == 'logging'
for alias in node.names)) or (
isinstance(node, ast.ImportFrom)
and (node.module or '').split('.')[0] == 'logging'):
raise ValueError('AstrBot plugin must not import logging')
if isinstance(node, ast.Attribute) and node.attr in {
'basicConfig', 'FileHandler', 'StreamHandler',
'getLogger', 'setLevel', 'addHandler', 'removeHandler'}:
raise ValueError('AstrBot must own logging configuration')
if (isinstance(node, ast.Call)
and isinstance(node.func, ast.Attribute)
and isinstance(node.func.value, ast.Name)
and node.func.value.id in {'logger', 'LOGGER'}
and node.func.value.id not in host_loggers):
raise ValueError(
'AstrBot logger must come from astrbot.api',
)
required = {'main.py', 'avatars.py', 'metadata.yaml', '_conf_schema.json',
'runtime.py', 'README.md', 'CHANGELOG.md', 'logo.png',
'runtime.py', 'runtime_logging.py', 'README.md',
'CHANGELOG.md', 'logo.png',
'logo-readme.png',
'images/farm-preview.png',
'requirements.txt', 'LICENSE', 'version.txt', '_version.py',