auto update from Flowseal/tg-ws-proxy

This commit is contained in:
kek.of 2026-03-15 23:12:15 +05:00 committed by GitHub
parent 99fcdfee0c
commit 01396dae78
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 127 additions and 1 deletions

View File

@ -21,6 +21,7 @@ import rumps
# ── proxy core is a sibling package ──────────────────────────────────────── # ── proxy core is a sibling package ────────────────────────────────────────
sys.path.insert(0, str(Path(__file__).parent)) sys.path.insert(0, str(Path(__file__).parent))
import proxy.tg_ws_proxy as tg_ws_proxy import proxy.tg_ws_proxy as tg_ws_proxy
import updater
# ── paths ─────────────────────────────────────────────────────────────────── # ── paths ───────────────────────────────────────────────────────────────────
APP_NAME = "TgWsProxy" APP_NAME = "TgWsProxy"
@ -363,8 +364,32 @@ def main():
log.info("Config: %s", _config) log.info("Config: %s", _config)
log.info("Log file: %s", LOG_FILE) log.info("Log file: %s", LOG_FILE)
# ── Auto-update proxy core at startup ────────────────────────────────
def _do_update():
updated = updater.check_and_update()
if updated:
log.info("Proxy core updated — reloading and restarting proxy")
import importlib
global tg_ws_proxy
try:
import proxy.tg_ws_proxy as _fresh
importlib.reload(_fresh)
tg_ws_proxy = _fresh
except Exception as exc:
log.error("Failed to reload proxy core after update: %s", exc)
restart_proxy()
rumps.notification(
APP_NAME,
"Обновление установлено",
"Proxy core обновлён и перезапущен.",
sound=False,
)
else:
start_proxy(_config) start_proxy(_config)
threading.Thread(target=_do_update, daemon=True).start()
# ─────────────────────────────────────────────────────────────────────
if not FIRST_RUN_MARKER.exists(): if not FIRST_RUN_MARKER.exists():
threading.Thread(target=show_first_run, daemon=True).start() threading.Thread(target=show_first_run, daemon=True).start()

View File

@ -14,6 +14,7 @@ a = Analysis(
datas=[], datas=[],
hiddenimports=[ hiddenimports=[
'proxy.tg_ws_proxy', 'proxy.tg_ws_proxy',
'updater',
'cryptography', 'cryptography',
'cryptography.hazmat.primitives.ciphers', 'cryptography.hazmat.primitives.ciphers',
'cryptography.hazmat.primitives.ciphers.algorithms', 'cryptography.hazmat.primitives.ciphers.algorithms',

100
updater.py Normal file
View File

@ -0,0 +1,100 @@
"""
updater.py автообновление proxy/tg_ws_proxy.py с GitHub main ветки.
Логика:
1. Скачивает актуальный файл с GitHub raw
2. Сравнивает SHA-256 с локальной копией
3. Если отличается сохраняет новую версию, возвращает True
4. Вся работа синхронная (вызывается из фонового потока)
"""
from __future__ import annotations
import hashlib
import logging
import shutil
import sys
import urllib.request
from pathlib import Path
from typing import Optional
log = logging.getLogger("tg-ws-updater")
RAW_URL = (
"https://raw.githubusercontent.com/"
"Flowseal/tg-ws-proxy/main/proxy/tg_ws_proxy.py"
)
# Локальный путь к файлу ядра (рядом с этим скриптом)
_HERE = Path(__file__).parent
PROXY_CORE = _HERE / "proxy" / "tg_ws_proxy.py"
TIMEOUT = 15 # секунд на скачивание
def _sha256(path: Path) -> Optional[str]:
"""SHA-256 файла или None если файл не существует."""
if not path.exists():
return None
h = hashlib.sha256()
with open(path, "rb") as fh:
for chunk in iter(lambda: fh.read(65536), b""):
h.update(chunk)
return h.hexdigest()
def _fetch(url: str) -> bytes:
"""Скачать URL, вернуть содержимое как bytes."""
req = urllib.request.Request(
url,
headers={"User-Agent": "tg-ws-proxy-macos-updater/1.0"},
)
with urllib.request.urlopen(req, timeout=TIMEOUT) as resp:
return resp.read()
def check_and_update() -> bool:
"""
Проверить обновление proxy core.
Возвращает True если файл был обновлён, False если уже актуален
или произошла ошибка (ошибки логируются, не бросаются).
"""
log.info("Checking for proxy core update: %s", RAW_URL)
try:
new_content = _fetch(RAW_URL)
except Exception as exc:
log.warning("Update check failed (network): %s", exc)
return False
new_hash = hashlib.sha256(new_content).hexdigest()
old_hash = _sha256(PROXY_CORE)
if new_hash == old_hash:
log.info("Proxy core is up to date (sha256: %s…)", new_hash[:12])
return False
log.info(
"Proxy core update detected: %s… → %s",
(old_hash or "none")[:12],
new_hash[:12],
)
# Атомарная замена: пишем во временный файл, потом переименовываем
tmp = PROXY_CORE.with_suffix(".py.tmp")
try:
PROXY_CORE.parent.mkdir(parents=True, exist_ok=True)
tmp.write_bytes(new_content)
shutil.move(str(tmp), str(PROXY_CORE))
except Exception as exc:
log.error("Failed to write updated proxy core: %s", exc)
tmp.unlink(missing_ok=True)
return False
# Выгрузить старый модуль из sys.modules, чтобы следующий import
# подхватил новый файл с диска
for key in list(sys.modules.keys()):
if "tg_ws_proxy" in key:
del sys.modules[key]
log.info("Proxy core updated successfully")
return True