from flask import Flask, request, render_template_string import requests app = Flask(__name__) INDEX_HTML = """ 入力フォーム

⇂名前を入力

本名は絶対に入力しないでください





""" MAP_HTML = """ 現在地マップ
""" ########################################## # 汎用リクエスト関数: CORS/エラー対策 ########################################## CORS_PROXY = "https://cors.isomorphic-git.org/" def safe_request_json(url, timeout=2, use_proxy_on_fail=True): """ 安全に GET JSON を取得する。 失敗時は CORS プロキシで再試行する。 """ try: res = requests.get(url, timeout=timeout) if res.status_code == 200: return res.json() else: raise Exception(f"HTTP {res.status_code}") except Exception: if use_proxy_on_fail: try: proxy_url = CORS_PROXY + url res = requests.get(proxy_url, timeout=timeout) if res.status_code == 200: return res.json() except Exception: pass return None ########################################## # 既存 API(エラーハンドリング強化 + CORS fallback) ########################################## def get_geo_ipapi(ip): url = f"http://ip-api.com/json/{ip}?lang=ja" res = safe_request_json(url) if res and res.get("status") == "success": return { "prefecture": res.get("regionName", ""), "city": res.get("city", ""), "lat": res.get("lat"), "lon": res.get("lon") } return fallback() def get_geo_ipwho(ip): url = f"https://api.ipwho.org/ip/{ip}?format=json" res = safe_request_json(url) if res and res.get("success") is True: data = res.get("data", {}) return { "prefecture": data.get("region", ""), "city": data.get("city", ""), "lat": data.get("latitude"), "lon": data.get("longitude"), "capital": data.get("capital", "") } return fallback(capital="") ########################################## # 新規追加 API(エラーハンドリング統一) ########################################## def get_geo_reallyfreegeoip(ip): url = f"https://reallyfreegeoip.org/json/{ip}" res = safe_request_json(url) if res: return { "prefecture": res.get("region_name", ""), "city": res.get("city", ""), "lat": res.get("latitude"), "lon": res.get("longitude") } return fallback() def get_geo_ipapico(ip): url = f"https://ipapi.co/{ip}/json/" res = safe_request_json(url) if res: return { "prefecture": res.get("region_name", res.get("region", "")), "city": res.get("city", ""), "lat": res.get("latitude"), "lon": res.get("longitude") } return fallback() def get_geo_iplocalize(ip): url = f"https://iplocalize.com/api/v1/lookup/{ip}" res = safe_request_json(url) if res: return { "prefecture": res.get("region", ""), "city": res.get("city", ""), "lat": res.get("latitude"), "lon": res.get("longitude") } return fallback() ########################################## # Fallback 共通 ########################################## def fallback(capital=None): base = { "prefecture": "", "city": "", "lat": 35.681236, "lon": 139.767125 } if capital is not None: base["capital"] = capital return base ########################################## # Flask Routes ########################################## @app.route("/", methods=["GET"]) def index(): return render_template_string(INDEX_HTML) @app.route("/next", methods=["POST"]) def next_page(): name = request.form.get("name", "").strip() mode = request.form.get("send_mode") xff = request.headers.get("X-Forwarded-For") if xff: ip = xff.split(",")[0].strip() # 先頭のクライアント IP を使う else: ip = request.remote_addr print(ip) # 各 API を使用 api1 = get_geo_ipapi(ip) api2 = get_geo_ipwho(ip) api3 = get_geo_reallyfreegeoip(ip) api5 = get_geo_ipapico(ip) api6 = get_geo_iplocalize(ip) # マスク処理 def mask(mode, prefecture, city): if mode == "all": return prefecture, city elif mode == "pref_only": return prefecture, "" else: return "", "" apis = [api1, api2, api3, api5, api6] names = ["ip-api", "IPWho", "ReallyFreeGeoIP", "ipapi.co", "iplocalize"] for api, name_api in zip(apis, names): pref, city = mask(mode, api.get("prefecture", ""), api.get("city", "")) print(f"[{name_api}] 名前:{name} {pref} {city}") # 地図表示は ip-api を優先 return render_template_string( MAP_HTML, lat=api1["lat"], lon=api1["lon"], prefecture=api1["prefecture"], city=api1["city"] ) if __name__ == "__main__": app.run(host="0.0.0.0", port=7860)