"""国内三网探针 ping VPS，每轮每网 2 个探针 × 16 包。用法：gp_ping.py <csv> <轮数> <间隔秒> [开始时间 HH:MM 北京]"""
import csv, json, os, sys, time, urllib.request
from datetime import datetime, timedelta, timezone
BJ = timezone(timedelta(hours=8))
API = 'https://api.globalping.io/v1/measurements'
out, n, gap = sys.argv[1], int(sys.argv[2]), int(sys.argv[3])
if len(sys.argv) > 4:  # 等到北京时间某点再开始
    h, m = map(int, sys.argv[4].split(':'))
    now = datetime.now(BJ); start = now.replace(hour=h, minute=m, second=0, microsecond=0)
    if start < now: start += timedelta(days=1)
    time.sleep((start - now).total_seconds())
def req(url, body=None):
    r = urllib.request.Request(url, json.dumps(body).encode() if body else None, {'content-type': 'application/json'})
    return json.load(urllib.request.urlopen(r, timeout=30))
new = not os.path.exists(out)
for i in range(n):
    try:
        mid = req(API, {'type': 'ping', 'target': 'VPS_IP', 'measurementOptions': {'packets': 16},
                        'locations': [{'magic': a, 'limit': 2} for a in ('AS4134', 'AS4837', 'AS9808')]})['id']
        time.sleep(30)
        d = req(f'{API}/{mid}'); t = datetime.now(BJ).strftime('%Y-%m-%d %H:%M')
        with open(out, 'a', newline='') as f:
            w = csv.writer(f)
            if new: w.writerow(['bj_time', 'asn', 'isp', 'city', 'sent', 'loss_pct', 'avg_ms']); new = False
            for r in d['results']:
                p, s = r['probe'], r['result'].get('stats') or {}
                w.writerow([t, p['asn'], p['network'][:30], p['city'], s.get('total'), s.get('loss'), s.get('avg')])
    except Exception as e:
        print('round', i, 'failed:', e, flush=True)
    if i < n - 1: time.sleep(gap)
