publish update.py
This commit is contained in:
parent
e2a7ae4a75
commit
f49d3632e8
1 changed files with 108 additions and 42 deletions
150
update.py
150
update.py
|
|
@ -1,23 +1,23 @@
|
|||
#!/usr/bin/env python3
|
||||
"""One command to set up AND update the Eve watchers — `python update.py`.
|
||||
"""Self-installing / self-updating entry point — `python update.py`.
|
||||
|
||||
This folder is a clone of the public repo
|
||||
https://git.armoredarmadillo.com/brockdarnold/eve-watcher.git
|
||||
so updates are just a `git pull`. Run this any time to:
|
||||
Run it once (the install one-liner does this for you). From then on a Windows
|
||||
Scheduled Task runs it automatically **at logon and once a day**, so the watchers
|
||||
stay up to date and running with zero further thought. Each run it:
|
||||
|
||||
1. create config.ini from the example on first run (your webhook is prefilled;
|
||||
config.ini is gitignored so your edits + OCR snip survive every update),
|
||||
2. pull the latest watcher code,
|
||||
3. install/upgrade python deps,
|
||||
4. (re)start the headless watchers.
|
||||
1. makes config.ini on first run (webhook prefilled; gitignored so your edits
|
||||
and OCR snip survive every update),
|
||||
2. `git pull`s the latest watcher code,
|
||||
3. installs/upgrades deps only when something changed,
|
||||
4. (re)starts the watchers ONLY if the code changed or they aren't running —
|
||||
so the daily run never interrupts an active session for nothing,
|
||||
5. ensures the daily+logon Scheduled Task exists (idempotent).
|
||||
|
||||
First time on a new PC:
|
||||
First time on a new PC (or just paste the install one-liner):
|
||||
git clone https://git.armoredarmadillo.com/brockdarnold/eve-watcher.git
|
||||
cd eve-watcher
|
||||
python update.py
|
||||
python eve_orehold_watcher.py --snip # one-time: aim OCR at the ore-hold bar
|
||||
|
||||
After that, to get my latest changes, just: python update.py
|
||||
python eve_orehold_watcher.py --snip # one-time GUI step for OCR hold alerts
|
||||
"""
|
||||
import configparser
|
||||
import os
|
||||
|
|
@ -27,6 +27,8 @@ import sys
|
|||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
WIN = os.name == "nt"
|
||||
TASK = "EveWatcher"
|
||||
WATCHER_SCRIPTS = ("eve_combat_watcher.py", "eve_chat_watcher.py", "eve_orehold_watcher.py")
|
||||
|
||||
|
||||
def run(cmd, **kw):
|
||||
|
|
@ -34,26 +36,38 @@ def run(cmd, **kw):
|
|||
return subprocess.run(cmd, cwd=HERE, **kw)
|
||||
|
||||
|
||||
def ps(script):
|
||||
"""Run a PowerShell snippet, return (rc, stdout)."""
|
||||
r = subprocess.run(["powershell", "-NoProfile", "-ExecutionPolicy", "Bypass",
|
||||
"-Command", script], cwd=HERE, capture_output=True, text=True)
|
||||
return r.returncode, (r.stdout or "").strip()
|
||||
|
||||
|
||||
def ensure_config():
|
||||
cfg = os.path.join(HERE, "config.ini")
|
||||
ex = os.path.join(HERE, "config.ini.example")
|
||||
if not os.path.exists(cfg):
|
||||
shutil.copyfile(ex, cfg)
|
||||
print("• created config.ini from config.ini.example (webhook prefilled).")
|
||||
first = not os.path.exists(cfg)
|
||||
if first:
|
||||
shutil.copyfile(os.path.join(HERE, "config.ini.example"), cfg)
|
||||
print("• created config.ini from example (webhook prefilled).")
|
||||
else:
|
||||
print("• config.ini already exists — leaving your settings + snip untouched.")
|
||||
return cfg
|
||||
print("• config.ini exists — your settings + OCR snip left untouched.")
|
||||
return cfg, first
|
||||
|
||||
|
||||
def git_pull():
|
||||
"""Return True if new commits were pulled."""
|
||||
if not os.path.isdir(os.path.join(HERE, ".git")):
|
||||
print("• not a git clone — skipping pull. To get updates in future, install "
|
||||
"via:\n git clone https://git.armoredarmadillo.com/brockdarnold/"
|
||||
"eve-watcher.git")
|
||||
return
|
||||
if run(["git", "pull", "--ff-only"]).returncode != 0:
|
||||
print("! git pull failed (local edits to tracked files?). Stash or commit "
|
||||
"them, then re-run. Your config.ini is safe (gitignored).")
|
||||
print("• not a git clone — can't auto-update. Reinstall via:\n"
|
||||
" git clone https://git.armoredarmadillo.com/brockdarnold/eve-watcher.git")
|
||||
return False
|
||||
r = subprocess.run(["git", "pull", "--ff-only"], cwd=HERE,
|
||||
capture_output=True, text=True)
|
||||
out = (r.stdout + r.stderr).strip()
|
||||
print(f" git: {out.splitlines()[-1] if out else '(no output)'}")
|
||||
if r.returncode != 0:
|
||||
print("! git pull failed (local edits to tracked files?). config.ini is safe.")
|
||||
return False
|
||||
return "Already up to date" not in out and "Already up-to-date" not in out
|
||||
|
||||
|
||||
def deps():
|
||||
|
|
@ -62,33 +76,85 @@ def deps():
|
|||
run([sys.executable, "-m", "pip", "install", "--quiet", "-r", req])
|
||||
|
||||
|
||||
def restart_watchers(cfg_path):
|
||||
def watchers_running():
|
||||
if not WIN:
|
||||
print("• non-Windows — start watchers manually (this is a Goliath/Windows tool).")
|
||||
return 0
|
||||
_, out = ps("(Get-CimInstance Win32_Process -Filter \"Name='pythonw.exe'\" "
|
||||
"| Where-Object { $_.CommandLine -like '*watcher*' }).Count")
|
||||
try:
|
||||
return int(out or "0")
|
||||
except ValueError:
|
||||
return 0
|
||||
|
||||
|
||||
def stop_watchers():
|
||||
ps("Get-CimInstance Win32_Process -Filter \"Name='pythonw.exe'\" | "
|
||||
"Where-Object { $_.CommandLine -like '*watcher*' } | "
|
||||
"ForEach-Object { Stop-Process -Id $_.ProcessId -Force }")
|
||||
|
||||
|
||||
def start_watchers(cfg_path):
|
||||
if not WIN:
|
||||
print("• non-Windows — start watchers manually (this is a Windows tool).")
|
||||
return
|
||||
# stop any running watchers, then relaunch via start-all.ps1
|
||||
subprocess.run(["powershell", "-NoProfile", "-Command",
|
||||
"Get-Process pythonw -ErrorAction SilentlyContinue | Stop-Process -Force"],
|
||||
cwd=HERE)
|
||||
stop_watchers()
|
||||
run(["powershell", "-ExecutionPolicy", "Bypass", "-File",
|
||||
os.path.join(HERE, "start-all.ps1")])
|
||||
# nudge if OCR region not snipped yet
|
||||
cp = configparser.ConfigParser()
|
||||
cp.read(cfg_path)
|
||||
if cp.get("watcher", "mode", fallback="ocr") == "ocr" and \
|
||||
not cp.get("ocr", "region", fallback="").strip():
|
||||
print("\n >> ONE-TIME STEP: the OCR hold/compress/stall watcher needs its "
|
||||
"region.\n Run: python eve_orehold_watcher.py --snip\n"
|
||||
" (drag a box around the Ore Hold fill bar; it persists after that.)")
|
||||
print("\n >> ONE-TIME (per PC) for hold/compress/stall alerts, run once:\n"
|
||||
" python eve_orehold_watcher.py --snip\n"
|
||||
" (drag a box around the Ore Hold fill bar; saved forever after.)")
|
||||
|
||||
|
||||
def ensure_task():
|
||||
"""Register a daily + at-logon Scheduled Task so this runs itself forever.
|
||||
Idempotent: only creates it if missing."""
|
||||
if not WIN:
|
||||
return
|
||||
rc, _ = ps(f"Get-ScheduledTask -TaskName '{TASK}' -ErrorAction SilentlyContinue")
|
||||
if rc == 0:
|
||||
print(f"• Scheduled Task '{TASK}' already set (auto-update at logon + daily).")
|
||||
return
|
||||
pyw = os.path.join(os.path.dirname(sys.executable), "pythonw.exe")
|
||||
if not os.path.exists(pyw):
|
||||
pyw = "pythonw.exe"
|
||||
here = HERE.replace("'", "''")
|
||||
pyw_e = pyw.replace("'", "''")
|
||||
snippet = (
|
||||
f"$a = New-ScheduledTaskAction -Execute '{pyw_e}' "
|
||||
f"-Argument '\"{here}\\update.py\"' -WorkingDirectory '{here}';"
|
||||
"$t1 = New-ScheduledTaskTrigger -AtLogOn;"
|
||||
"$t2 = New-ScheduledTaskTrigger -Daily -At 5am;"
|
||||
"$s = New-ScheduledTaskSettingsSet -StartWhenAvailable "
|
||||
"-AllowStartIfOnBatteries -DontStopIfGoingOnBatteries "
|
||||
"-ExecutionTimeLimit (New-TimeSpan -Hours 1);"
|
||||
"$p = New-ScheduledTaskPrincipal -UserId $env:USERNAME "
|
||||
"-LogonType Interactive -RunLevel Limited;"
|
||||
f"Register-ScheduledTask -TaskName '{TASK}' -Action $a -Trigger $t1,$t2 "
|
||||
"-Settings $s -Principal $p -Force | Out-Null")
|
||||
rc, out = ps(snippet)
|
||||
if rc == 0:
|
||||
print(f"• Scheduled Task '{TASK}' created — auto-updates at logon + daily 5am. "
|
||||
"You never have to run this again.")
|
||||
else:
|
||||
print(f"! couldn't register Scheduled Task: {out}")
|
||||
|
||||
|
||||
def main():
|
||||
print("=== Eve watcher setup / update ===")
|
||||
cfg = ensure_config()
|
||||
git_pull()
|
||||
deps()
|
||||
restart_watchers(cfg)
|
||||
print("\nDone. Watchers running. Stop them with: Get-Process pythonw | Stop-Process")
|
||||
print("=== Eve watcher setup / auto-update ===")
|
||||
cfg, first = ensure_config()
|
||||
changed = git_pull()
|
||||
if changed or first:
|
||||
deps()
|
||||
if changed or first or watchers_running() == 0:
|
||||
start_watchers(cfg)
|
||||
else:
|
||||
print("• up to date and watchers already running — nothing to restart.")
|
||||
ensure_task()
|
||||
print("\nDone. Hands-off from here: it updates + keeps itself running automatically.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue