mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-06-26 06:54:38 +03:00
163 lines
6.3 KiB
Python
163 lines
6.3 KiB
Python
#!/usr/bin/env python3
|
|
# web-unpublish v1.0 — Remove 1C web publication
|
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
|
|
|
"""
|
|
Удаление веб-публикации 1С из Apache.
|
|
Удаляет маркерный блок из httpd.conf и каталог публикации.
|
|
Если Apache запущен — перезапускает для применения.
|
|
С флагом -All удаляет все публикации и останавливает Apache.
|
|
"""
|
|
|
|
import argparse
|
|
import os
|
|
import re
|
|
import shutil
|
|
import subprocess
|
|
import sys
|
|
import time
|
|
|
|
import psutil
|
|
|
|
|
|
def get_our_httpd(httpd_exe_norm):
|
|
"""Filter httpd processes by our ApachePath."""
|
|
result = []
|
|
if not httpd_exe_norm:
|
|
return result
|
|
for p in psutil.process_iter(['pid', 'name', 'exe']):
|
|
try:
|
|
if p.info['name'] and 'httpd' in p.info['name'].lower():
|
|
if p.info['exe'] and os.path.normcase(os.path.normpath(p.info['exe'])) == httpd_exe_norm:
|
|
result.append(p)
|
|
except (psutil.NoSuchProcess, psutil.AccessDenied):
|
|
pass
|
|
return result
|
|
|
|
|
|
def main():
|
|
sys.stdout.reconfigure(encoding="utf-8")
|
|
sys.stderr.reconfigure(encoding="utf-8")
|
|
parser = argparse.ArgumentParser(description='Remove 1C web publication', allow_abbrev=False)
|
|
parser.add_argument('-AppName', type=str, default='', help='Publication name')
|
|
parser.add_argument('-ApachePath', type=str, default='', help='Apache root (default: tools\\apache24)')
|
|
parser.add_argument('-All', action='store_true', help='Remove all publications')
|
|
args = parser.parse_args()
|
|
|
|
# --- Resolve ApachePath ---
|
|
apache_path = args.ApachePath
|
|
if not apache_path:
|
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
|
project_root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(script_dir))))
|
|
apache_path = os.path.join(project_root, 'tools', 'apache24')
|
|
|
|
# --- Validate params ---
|
|
if not args.All and not args.AppName:
|
|
print('Error: укажите -AppName или -All', file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
# --- Read httpd.conf ---
|
|
conf_file = os.path.join(apache_path, 'conf', 'httpd.conf')
|
|
if not os.path.exists(conf_file):
|
|
print(f'Error: httpd.conf не найден: {conf_file}', file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
with open(conf_file, 'r', encoding='utf-8-sig') as f:
|
|
conf_content = f.read()
|
|
|
|
# --- Helper: our httpd process ---
|
|
httpd_exe = os.path.join(apache_path, 'bin', 'httpd.exe')
|
|
if os.path.exists(httpd_exe):
|
|
httpd_exe_norm = os.path.normcase(os.path.normpath(os.path.realpath(httpd_exe)))
|
|
else:
|
|
httpd_exe_norm = os.path.normcase(os.path.normpath(httpd_exe))
|
|
|
|
# --- Collect app names to remove ---
|
|
if args.All:
|
|
pub_pattern = r'# --- 1C Publication: (.+?) ---'
|
|
pub_matches = re.findall(pub_pattern, conf_content)
|
|
if not pub_matches:
|
|
print('Нет публикаций для удаления')
|
|
sys.exit(0)
|
|
app_names = pub_matches
|
|
print(f'Удаление всех публикаций: {", ".join(app_names)}')
|
|
else:
|
|
app_names = [args.AppName]
|
|
|
|
# --- Remove marker blocks ---
|
|
for name in app_names:
|
|
pub_marker_start = f'# --- 1C Publication: {name} ---'
|
|
pub_marker_end = f'# --- End: {name} ---'
|
|
|
|
if re.search(re.escape(pub_marker_start), conf_content):
|
|
pattern = r'\r?\n?' + re.escape(pub_marker_start) + r'[\s\S]*?' + re.escape(pub_marker_end) + r'\r?\n?'
|
|
conf_content = re.sub(pattern, '\n', conf_content)
|
|
print(f"httpd.conf: блок публикации '{name}' удалён")
|
|
else:
|
|
print(f"Публикация '{name}' не найдена в httpd.conf")
|
|
|
|
# --- Check if any publications remain; if not, remove global block ---
|
|
remaining_pubs = re.findall(r'# --- 1C Publication: .+? ---', conf_content)
|
|
if not remaining_pubs:
|
|
global_marker_start = '# --- 1C: global ---'
|
|
global_marker_end = '# --- End: global ---'
|
|
if re.search(re.escape(global_marker_start), conf_content):
|
|
global_pattern = r'\r?\n?' + re.escape(global_marker_start) + r'[\s\S]*?' + re.escape(global_marker_end) + r'\r?\n?'
|
|
conf_content = re.sub(global_pattern, '\n', conf_content)
|
|
print('httpd.conf: глобальный блок 1C удалён (нет публикаций)')
|
|
|
|
with open(conf_file, 'w', encoding='utf-8') as f:
|
|
f.write(conf_content)
|
|
|
|
# --- Remove publish directories ---
|
|
for name in app_names:
|
|
publish_dir = os.path.join(apache_path, 'publish', name)
|
|
if os.path.exists(publish_dir):
|
|
shutil.rmtree(publish_dir, ignore_errors=True)
|
|
print(f'Каталог удалён: {publish_dir}')
|
|
else:
|
|
print(f'Каталог не найден: {publish_dir}')
|
|
|
|
# --- Restart/Stop Apache if running (only our instance) ---
|
|
httpd_proc = get_our_httpd(httpd_exe_norm)
|
|
if httpd_proc:
|
|
if remaining_pubs:
|
|
print('Перезапуск Apache...')
|
|
for p in httpd_proc:
|
|
try:
|
|
p.kill()
|
|
except (psutil.NoSuchProcess, psutil.AccessDenied):
|
|
pass
|
|
time.sleep(1)
|
|
subprocess.Popen(
|
|
[httpd_exe],
|
|
cwd=apache_path,
|
|
creationflags=subprocess.CREATE_NO_WINDOW,
|
|
)
|
|
time.sleep(2)
|
|
check = get_our_httpd(httpd_exe_norm)
|
|
if check:
|
|
print('Apache перезапущен')
|
|
else:
|
|
print('Error: Apache не удалось перезапустить', file=sys.stderr)
|
|
sys.exit(1)
|
|
else:
|
|
print('Публикаций не осталось — останавливаю Apache...')
|
|
for p in httpd_proc:
|
|
try:
|
|
p.kill()
|
|
except (psutil.NoSuchProcess, psutil.AccessDenied):
|
|
pass
|
|
time.sleep(1)
|
|
print('Apache остановлен')
|
|
|
|
print('')
|
|
if args.All:
|
|
print(f'Все публикации удалены ({len(app_names)} шт.)')
|
|
else:
|
|
print(f"Публикация '{args.AppName}' удалена")
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|