fix: 清理脚本按路径是否以 .pem 结尾判定保留/删除俱乐部
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,10 +1,12 @@
|
|||||||
"""清理龙先生重复/空证书俱乐部。
|
"""清理龙先生重复/无 pem 证书俱乐部。
|
||||||
|
|
||||||
规则:
|
规则:
|
||||||
- 候选:club_id=lsx / 名称含「龙先生」 / wx_appid=龙先生小程序
|
- 候选:club_id=lsx / 名称含「龙先生」 / wx_appid=龙先生小程序
|
||||||
- 「有 key」:pay_key_path / pay_cert_path / private_key_path / platform_cert_dir 任一非空
|
- 「有 pem」:pay_key_path / pay_cert_path / private_key_path 任一路径以 .pem 结尾
|
||||||
- 默认 dry-run;--apply 才删除「完全没有 key 路径」的俱乐部行及相关配置表
|
(你后台上传的证书路径都是 *.pem;脚本自动建的/空配置通常没有)
|
||||||
- 若只剩一条且无 key,不会删(避免误删唯一配置);除非 --force-delete-empty-only
|
- 「可删」:上述三个字段都没有以 .pem 结尾的路径
|
||||||
|
- 默认 dry-run;--apply 才删除
|
||||||
|
- 若候选里没有任何「有 pem」的对照,默认不删;加 --force-delete-empty-only 才删
|
||||||
|
|
||||||
用法:
|
用法:
|
||||||
python manage.py cleanup_lsx_empty_club
|
python manage.py cleanup_lsx_empty_club
|
||||||
@@ -37,7 +39,6 @@ from users.models import UserBoss, UserGuanshi, UserZuzhang
|
|||||||
LSX_APPID = 'wx7ff90e9d024fcdb8'
|
LSX_APPID = 'wx7ff90e9d024fcdb8'
|
||||||
SEED_UIDS = ('9910001', '9910002')
|
SEED_UIDS = ('9910001', '9910002')
|
||||||
|
|
||||||
# 删除俱乐部时一并清掉的配置表(按 club_id)
|
|
||||||
RELATED_MODELS = (
|
RELATED_MODELS = (
|
||||||
ClubPaymentChannel,
|
ClubPaymentChannel,
|
||||||
ClubHuiyuanPrice,
|
ClubHuiyuanPrice,
|
||||||
@@ -54,15 +55,33 @@ RELATED_MODELS = (
|
|||||||
ClubDashouExamPass,
|
ClubDashouExamPass,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# 证书「文件」字段(应以 .pem 结尾);platform_cert_dir 是目录,不参与判定
|
||||||
|
_PEM_FILE_FIELDS = ('pay_key_path', 'pay_cert_path', 'private_key_path')
|
||||||
|
|
||||||
def _has_key_paths(club):
|
|
||||||
fields = (
|
def _path_ends_with_pem(path):
|
||||||
getattr(club, 'pay_key_path', '') or '',
|
return str(path or '').strip().lower().endswith('.pem')
|
||||||
getattr(club, 'pay_cert_path', '') or '',
|
|
||||||
getattr(club, 'private_key_path', '') or '',
|
|
||||||
getattr(club, 'platform_cert_dir', '') or '',
|
def _has_pem_paths(club):
|
||||||
)
|
"""后台上传过证书:路径以 .pem 结尾。"""
|
||||||
return any(str(x).strip() for x in fields)
|
return any(_path_ends_with_pem(getattr(club, f, '')) for f in _PEM_FILE_FIELDS)
|
||||||
|
|
||||||
|
|
||||||
|
def _pem_field_summary(club):
|
||||||
|
lines = []
|
||||||
|
for f in _PEM_FILE_FIELDS:
|
||||||
|
val = (getattr(club, f, '') or '').strip()
|
||||||
|
if not val:
|
||||||
|
tag = '空'
|
||||||
|
elif _path_ends_with_pem(val):
|
||||||
|
tag = 'pem✓'
|
||||||
|
else:
|
||||||
|
tag = '非pem✗'
|
||||||
|
lines.append(f'{f}={val or "(空)"} [{tag}]')
|
||||||
|
plat = (getattr(club, 'platform_cert_dir', '') or '').strip()
|
||||||
|
lines.append(f'platform_cert_dir={plat or "(空)"} [目录仅展示]')
|
||||||
|
return lines
|
||||||
|
|
||||||
|
|
||||||
def _candidates():
|
def _candidates():
|
||||||
@@ -86,14 +105,14 @@ def _purge_club_related(club_id, stdout, style):
|
|||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
help = '列出并删除龙先生相关「无证书 key 路径」的重复俱乐部(默认 dry-run)'
|
help = '列出并删除龙先生相关「证书路径不以 .pem 结尾」的重复俱乐部(默认 dry-run)'
|
||||||
|
|
||||||
def add_arguments(self, parser):
|
def add_arguments(self, parser):
|
||||||
parser.add_argument('--apply', action='store_true', help='真正写入删除')
|
parser.add_argument('--apply', action='store_true', help='真正写入删除')
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--force-delete-empty-only',
|
'--force-delete-empty-only',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
help='即使没有「有 key」的对照俱乐部,也允许删除无 key 的候选',
|
help='即使没有「有 .pem」的对照俱乐部,也允许删除非 pem 候选',
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--remove-seed-users',
|
'--remove-seed-users',
|
||||||
@@ -121,35 +140,38 @@ class Command(BaseCommand):
|
|||||||
self.stdout.write(self.style.WARNING('未找到龙先生/lsx 相关俱乐部'))
|
self.stdout.write(self.style.WARNING('未找到龙先生/lsx 相关俱乐部'))
|
||||||
return
|
return
|
||||||
|
|
||||||
with_keys = []
|
with_pem = []
|
||||||
without_keys = []
|
without_pem = []
|
||||||
self.stdout.write(self.style.SUCCESS('=' * 60))
|
self.stdout.write(self.style.SUCCESS('=' * 60))
|
||||||
|
self.stdout.write('判定标准:pay_key_path / pay_cert_path / private_key_path 是否以 .pem 结尾')
|
||||||
self.stdout.write('龙先生相关俱乐部扫描结果:')
|
self.stdout.write('龙先生相关俱乐部扫描结果:')
|
||||||
for c in clubs:
|
for c in clubs:
|
||||||
keyed = _has_key_paths(c)
|
keyed = _has_pem_paths(c)
|
||||||
(with_keys if keyed else without_keys).append(c)
|
(with_pem if keyed else without_pem).append(c)
|
||||||
self.stdout.write('-' * 40)
|
self.stdout.write('-' * 40)
|
||||||
self.stdout.write(f'club_id={c.club_id} name={c.name} status={c.status}')
|
self.stdout.write(f'club_id={c.club_id} name={c.name} status={c.status}')
|
||||||
self.stdout.write(f' wx_appid={c.wx_appid or "(空)"}')
|
self.stdout.write(f' wx_appid={c.wx_appid or "(空)"}')
|
||||||
self.stdout.write(f' pay_key_path={c.pay_key_path or "(空)"}')
|
for line in _pem_field_summary(c):
|
||||||
self.stdout.write(f' pay_cert_path={c.pay_cert_path or "(空)"}')
|
self.stdout.write(f' {line}')
|
||||||
self.stdout.write(f' private_key_path={c.private_key_path or "(空)"}')
|
self.stdout.write(
|
||||||
self.stdout.write(f' platform_cert_dir={c.platform_cert_dir or "(空)"}')
|
f' >>> {"有 .pem 路径(保留)" if keyed else "无 .pem 路径(可删)"}'
|
||||||
self.stdout.write(f' >>> {"有 key 路径(保留)" if keyed else "无 key 路径(可删)"}')
|
)
|
||||||
|
|
||||||
self.stdout.write(self.style.SUCCESS('=' * 60))
|
self.stdout.write(self.style.SUCCESS('=' * 60))
|
||||||
self.stdout.write(f'有 key: {len(with_keys)} 条;无 key: {len(without_keys)} 条')
|
self.stdout.write(f'有 .pem: {len(with_pem)} 条;无 .pem: {len(without_pem)} 条')
|
||||||
|
|
||||||
if not without_keys:
|
if not without_pem:
|
||||||
self.stdout.write(self.style.SUCCESS('没有「无 key 路径」的俱乐部,无需删除。'))
|
self.stdout.write(self.style.SUCCESS('没有「无 .pem 路径」的俱乐部,无需删除。'))
|
||||||
elif not with_keys and not force:
|
elif not with_pem and not force:
|
||||||
self.stdout.write(self.style.ERROR(
|
self.stdout.write(self.style.ERROR(
|
||||||
'全部候选都没有 key 路径。为安全起见不自动删。'
|
'全部候选都没有 .pem 路径。为安全起见不自动删。'
|
||||||
'若确认要删,加 --force-delete-empty-only --apply'
|
'若确认要删,加 --force-delete-empty-only --apply'
|
||||||
))
|
))
|
||||||
else:
|
else:
|
||||||
for c in without_keys:
|
for c in without_pem:
|
||||||
self.stdout.write(self.style.WARNING(f'将删除无 key 俱乐部: {c.club_id} ({c.name})'))
|
self.stdout.write(self.style.WARNING(
|
||||||
|
f'将删除无 .pem 俱乐部: {c.club_id} ({c.name})'
|
||||||
|
))
|
||||||
if not apply:
|
if not apply:
|
||||||
self.stdout.write(' (dry-run,未真正删除;加 --apply 执行)')
|
self.stdout.write(' (dry-run,未真正删除;加 --apply 执行)')
|
||||||
continue
|
continue
|
||||||
|
|||||||
Reference in New Issue
Block a user