Add new Wunderground-backed cities and source links
This commit is contained in:
@@ -92,6 +92,23 @@ const CITY_SPECIFIC_SOURCES: Record<string, OfficialSourceLink[]> = {
|
||||
kind: "metar",
|
||||
},
|
||||
],
|
||||
busan: [
|
||||
{
|
||||
label: "Wunderground RKPK",
|
||||
href: "https://www.wunderground.com/history/daily/kr/busan/RKPK",
|
||||
kind: "agency",
|
||||
},
|
||||
{
|
||||
label: "金海国际机场",
|
||||
href: "https://www.airport.co.kr/gimhaeeng/index.do",
|
||||
kind: "airport",
|
||||
},
|
||||
{
|
||||
label: "RKPK METAR",
|
||||
href: "https://aviationweather.gov/data/metar/?id=RKPK&decoded=1&taf=1",
|
||||
kind: "metar",
|
||||
},
|
||||
],
|
||||
istanbul: [
|
||||
{
|
||||
label: "MGM",
|
||||
@@ -526,6 +543,91 @@ const CITY_SPECIFIC_SOURCES: Record<string, OfficialSourceLink[]> = {
|
||||
kind: "metar",
|
||||
},
|
||||
],
|
||||
"kuala lumpur": [
|
||||
{
|
||||
label: "Wunderground WMKK",
|
||||
href: "https://www.wunderground.com/history/daily/my/sepang-district/WMKK",
|
||||
kind: "agency",
|
||||
},
|
||||
{
|
||||
label: "吉隆坡国际机场",
|
||||
href: "https://airports.malaysiaairports.com.my/klia",
|
||||
kind: "airport",
|
||||
},
|
||||
{
|
||||
label: "WMKK METAR",
|
||||
href: "https://aviationweather.gov/data/metar/?id=WMKK&decoded=1&taf=1",
|
||||
kind: "metar",
|
||||
},
|
||||
],
|
||||
jakarta: [
|
||||
{
|
||||
label: "Wunderground WIHH",
|
||||
href: "https://www.wunderground.com/history/daily/id/jakarta/WIHH",
|
||||
kind: "agency",
|
||||
},
|
||||
{
|
||||
label: "Halim Perdanakusuma Airport",
|
||||
href: "https://www.angkasapura2.co.id/en/airport/read/HLP",
|
||||
kind: "airport",
|
||||
},
|
||||
{
|
||||
label: "WIHH METAR",
|
||||
href: "https://aviationweather.gov/data/metar/?id=WIHH&decoded=1&taf=1",
|
||||
kind: "metar",
|
||||
},
|
||||
],
|
||||
helsinki: [
|
||||
{
|
||||
label: "Wunderground EFHK",
|
||||
href: "https://www.wunderground.com/history/daily/fi/vantaa/EFHK",
|
||||
kind: "agency",
|
||||
},
|
||||
{
|
||||
label: "Helsinki Airport",
|
||||
href: "https://www.finavia.fi/en/airports/helsinki-airport",
|
||||
kind: "airport",
|
||||
},
|
||||
{
|
||||
label: "EFHK METAR",
|
||||
href: "https://aviationweather.gov/data/metar/?id=EFHK&decoded=1&taf=1",
|
||||
kind: "metar",
|
||||
},
|
||||
],
|
||||
amsterdam: [
|
||||
{
|
||||
label: "Wunderground EHAM",
|
||||
href: "https://www.wunderground.com/history/daily/nl/schiphol/EHAM",
|
||||
kind: "agency",
|
||||
},
|
||||
{
|
||||
label: "Amsterdam Airport Schiphol",
|
||||
href: "https://www.schiphol.nl/en/",
|
||||
kind: "airport",
|
||||
},
|
||||
{
|
||||
label: "EHAM METAR",
|
||||
href: "https://aviationweather.gov/data/metar/?id=EHAM&decoded=1&taf=1",
|
||||
kind: "metar",
|
||||
},
|
||||
],
|
||||
"panama city": [
|
||||
{
|
||||
label: "Wunderground MPMG",
|
||||
href: "https://www.wunderground.com/history/daily/pa/panama-city/MPMG",
|
||||
kind: "agency",
|
||||
},
|
||||
{
|
||||
label: "Marcos A. Gelabert Airport",
|
||||
href: "https://www.aeropuertos.net/aeropuerto-internacional-marcos-a-gelabert/",
|
||||
kind: "airport",
|
||||
},
|
||||
{
|
||||
label: "MPMG METAR",
|
||||
href: "https://aviationweather.gov/data/metar/?id=MPMG&decoded=1&taf=1",
|
||||
kind: "metar",
|
||||
},
|
||||
],
|
||||
beijing: [
|
||||
{
|
||||
label: "中国天气网",
|
||||
|
||||
@@ -92,6 +92,24 @@ CITY_REGISTRY = {
|
||||
"distance_km": 48.8,
|
||||
"warning": "距离太远,海洋性vs大陆性气候差异大。",
|
||||
},
|
||||
"busan": {
|
||||
"name": "Busan",
|
||||
"lat": 35.1795,
|
||||
"lon": 128.9382,
|
||||
"icao": "RKPK",
|
||||
"settlement_source": "wunderground",
|
||||
"settlement_station_code": "RKPK",
|
||||
"settlement_station_label": "Busan/Gimhae International Airport Station",
|
||||
"settlement_url": "https://www.wunderground.com/history/daily/kr/busan/RKPK",
|
||||
"tz_offset": 32400,
|
||||
"use_fahrenheit": False,
|
||||
"is_major": True,
|
||||
"risk_level": "medium",
|
||||
"risk_emoji": "🟡",
|
||||
"airport_name": "金海国际机场",
|
||||
"distance_km": 14.0,
|
||||
"warning": "市场现按 Wunderground 金海国际机场站整度°C口径结算;海风与沿海云量会影响午后峰值。",
|
||||
},
|
||||
"hong kong": {
|
||||
"name": "Hong Kong",
|
||||
"lat": 22.3019,
|
||||
@@ -175,6 +193,42 @@ CITY_REGISTRY = {
|
||||
"distance_km": 17.5,
|
||||
"warning": "全年温度振幅较小,主要受午后阵雨时段影响。",
|
||||
},
|
||||
"kuala lumpur": {
|
||||
"name": "Kuala Lumpur",
|
||||
"lat": 2.7456,
|
||||
"lon": 101.7072,
|
||||
"icao": "WMKK",
|
||||
"settlement_source": "wunderground",
|
||||
"settlement_station_code": "WMKK",
|
||||
"settlement_station_label": "Kuala Lumpur International Airport Station",
|
||||
"settlement_url": "https://www.wunderground.com/history/daily/my/sepang-district/WMKK",
|
||||
"tz_offset": 28800,
|
||||
"use_fahrenheit": False,
|
||||
"is_major": True,
|
||||
"risk_level": "medium",
|
||||
"risk_emoji": "🟡",
|
||||
"airport_name": "吉隆坡国际机场",
|
||||
"distance_km": 45.0,
|
||||
"warning": "市场现按 Wunderground 吉隆坡国际机场站整度°C口径结算;午后对流和热带湿热会让峰值窗口偏短。",
|
||||
},
|
||||
"jakarta": {
|
||||
"name": "Jakarta",
|
||||
"lat": -6.2666,
|
||||
"lon": 106.8910,
|
||||
"icao": "WIHH",
|
||||
"settlement_source": "wunderground",
|
||||
"settlement_station_code": "WIHH",
|
||||
"settlement_station_label": "Jakarta/Halim Perdanakusuma Airport Station",
|
||||
"settlement_url": "https://www.wunderground.com/history/daily/id/jakarta/WIHH",
|
||||
"tz_offset": 25200,
|
||||
"use_fahrenheit": False,
|
||||
"is_major": True,
|
||||
"risk_level": "medium",
|
||||
"risk_emoji": "🟡",
|
||||
"airport_name": "Halim Perdanakusuma Airport",
|
||||
"distance_km": 12.0,
|
||||
"warning": "市场现按 Wunderground Halim 机场站整度°C口径结算;热带午后阵雨常在峰值前后快速压制气温。",
|
||||
},
|
||||
"tokyo": {
|
||||
"name": "Tokyo",
|
||||
"lat": 35.5523,
|
||||
@@ -486,6 +540,42 @@ CITY_REGISTRY = {
|
||||
"distance_km": 10.0,
|
||||
"warning": "平原地形下辐射冷却显著,清晨与夜间温度回落可能偏快。",
|
||||
},
|
||||
"helsinki": {
|
||||
"name": "Helsinki",
|
||||
"lat": 60.3172,
|
||||
"lon": 24.9633,
|
||||
"icao": "EFHK",
|
||||
"settlement_source": "wunderground",
|
||||
"settlement_station_code": "EFHK",
|
||||
"settlement_station_label": "Helsinki Airport Station",
|
||||
"settlement_url": "https://www.wunderground.com/history/daily/fi/vantaa/EFHK",
|
||||
"tz_offset": 7200,
|
||||
"use_fahrenheit": False,
|
||||
"is_major": True,
|
||||
"risk_level": "medium",
|
||||
"risk_emoji": "🟡",
|
||||
"airport_name": "赫尔辛基机场",
|
||||
"distance_km": 17.0,
|
||||
"warning": "市场现按 Wunderground 赫尔辛基机场站整度°C口径结算;高纬度日照变化快,冷平流会明显影响日峰值。",
|
||||
},
|
||||
"amsterdam": {
|
||||
"name": "Amsterdam",
|
||||
"lat": 52.3086,
|
||||
"lon": 4.7639,
|
||||
"icao": "EHAM",
|
||||
"settlement_source": "wunderground",
|
||||
"settlement_station_code": "EHAM",
|
||||
"settlement_station_label": "Amsterdam Airport Schiphol Station",
|
||||
"settlement_url": "https://www.wunderground.com/history/daily/nl/schiphol/EHAM",
|
||||
"tz_offset": 3600,
|
||||
"use_fahrenheit": False,
|
||||
"is_major": True,
|
||||
"risk_level": "medium",
|
||||
"risk_emoji": "🟡",
|
||||
"airport_name": "阿姆斯特丹史基浦机场",
|
||||
"distance_km": 17.0,
|
||||
"warning": "市场现按 Wunderground 史基浦机场站整度°C口径结算;北海海风和平流层云容易限制午后升温。",
|
||||
},
|
||||
"madrid": {
|
||||
"name": "Madrid",
|
||||
"lat": 40.4722,
|
||||
@@ -576,6 +666,24 @@ CITY_REGISTRY = {
|
||||
"distance_km": 26.0,
|
||||
"warning": "江汉平原,水汽充足,夏季常现长时闷热高温。",
|
||||
},
|
||||
"panama city": {
|
||||
"name": "Panama City",
|
||||
"lat": 8.9733,
|
||||
"lon": -79.5556,
|
||||
"icao": "MPMG",
|
||||
"settlement_source": "wunderground",
|
||||
"settlement_station_code": "MPMG",
|
||||
"settlement_station_label": "Panama City/Marcos A. Gelabert Airport Station",
|
||||
"settlement_url": "https://www.wunderground.com/history/daily/pa/panama-city/MPMG",
|
||||
"tz_offset": -18000,
|
||||
"use_fahrenheit": False,
|
||||
"is_major": True,
|
||||
"risk_level": "medium",
|
||||
"risk_emoji": "🟡",
|
||||
"airport_name": "Marcos A. Gelabert Airport",
|
||||
"distance_km": 6.0,
|
||||
"warning": "市场现按 Wunderground Marcos A. Gelabert 机场站整度°C口径结算;热带对流常让峰值在午后被快速截断。",
|
||||
},
|
||||
}
|
||||
|
||||
ALIASES = {
|
||||
@@ -593,8 +701,14 @@ ALIASES = {
|
||||
"seo": "seoul", "hkg": "hong kong", "hk": "hong kong",
|
||||
"lfs": "lau fau shan", "laufaushan": "lau fau shan",
|
||||
"tpe": "taipei", "tp": "taipei", "taipei": "taipei",
|
||||
"pus": "busan", "bus": "busan", "rkpk": "busan",
|
||||
"sha": "shanghai", "sh": "shanghai", "sin": "singapore",
|
||||
"sg": "singapore", "tok": "tokyo", "tyo": "tokyo",
|
||||
"kul": "kuala lumpur", "wmkk": "kuala lumpur", "sepang": "kuala lumpur",
|
||||
"jkt": "jakarta", "wihh": "jakarta", "halim": "jakarta",
|
||||
"hel": "helsinki", "efhk": "helsinki", "vantaa": "helsinki",
|
||||
"ams": "amsterdam", "eham": "amsterdam", "schiphol": "amsterdam",
|
||||
"pty": "panama city", "mpmg": "panama city", "panamacity": "panama city",
|
||||
"tlv": "tel aviv", "telaviv": "tel aviv",
|
||||
"ba": "buenos aires", "wel": "wellington",
|
||||
"luc": "lucknow", "sp": "sao paulo", "mun": "munich",
|
||||
@@ -626,8 +740,12 @@ ALIASES = {
|
||||
"流浮山": "lau fau shan",
|
||||
"台北": "taipei",
|
||||
"臺北": "taipei",
|
||||
"釜山": "busan",
|
||||
"上海": "shanghai",
|
||||
"新加坡": "singapore",
|
||||
"吉隆坡": "kuala lumpur",
|
||||
"雅加达": "jakarta",
|
||||
"雅加達": "jakarta",
|
||||
"东京": "tokyo",
|
||||
"東京": "tokyo",
|
||||
"特拉维夫": "tel aviv",
|
||||
@@ -640,6 +758,10 @@ ALIASES = {
|
||||
"米蘭": "milan",
|
||||
"华沙": "warsaw",
|
||||
"華沙": "warsaw",
|
||||
"赫尔辛基": "helsinki",
|
||||
"赫爾辛基": "helsinki",
|
||||
"阿姆斯特丹": "amsterdam",
|
||||
"巴拿马城": "panama city",
|
||||
"马德里": "madrid",
|
||||
"馬德里": "madrid",
|
||||
"ctu": "chengdu", "cd": "chengdu",
|
||||
|
||||
@@ -44,6 +44,7 @@ class WeatherDataCollector(OpenMeteoCacheMixin, SettlementSourceMixin, MetarSour
|
||||
"mexico city": ["MMMX", "MMSM", "MMTO"],
|
||||
"paris": ["LFPG", "LFPO", "LFPB"],
|
||||
"seoul": ["RKSI", "RKSS"],
|
||||
"busan": ["RKPK", "RKSS"],
|
||||
"hong kong": ["VHHH", "VMMC", "ZGSZ"],
|
||||
"taipei": ["RCSS", "RCTP"],
|
||||
"chengdu": ["ZUUU", "ZUTF"],
|
||||
@@ -53,11 +54,16 @@ class WeatherDataCollector(OpenMeteoCacheMixin, SettlementSourceMixin, MetarSour
|
||||
"wuhan": ["ZHHH", "ZHES"],
|
||||
"shanghai": ["ZSPD", "ZSSS", "ZSNB", "ZSHC"],
|
||||
"singapore": ["WSSS", "WSAP", "WMKK"],
|
||||
"kuala lumpur": ["WMKK", "WMSA"],
|
||||
"jakarta": ["WIHH", "WIII"],
|
||||
"tokyo": ["RJTT", "RJAA", "RJAH", "RJTJ"],
|
||||
"tel aviv": ["LLBG"],
|
||||
"milan": ["LIMC", "LIML", "LIME", "LIPO"],
|
||||
"toronto": ["CYYZ", "CYTZ", "CYKF"],
|
||||
"warsaw": ["EPWA", "EPMO", "EPLL"],
|
||||
"helsinki": ["EFHK", "EETN"],
|
||||
"amsterdam": ["EHAM", "EHRD"],
|
||||
"panama city": ["MPMG", "MPTO"],
|
||||
"madrid": ["LEMD", "LETO", "LEGT"],
|
||||
"chicago": ["KORD", "KMDW", "KPWK", "KDPA"],
|
||||
"dallas": ["KDAL", "KDFW", "KADS", "KGKY"],
|
||||
@@ -445,6 +451,9 @@ class WeatherDataCollector(OpenMeteoCacheMixin, SettlementSourceMixin, MetarSour
|
||||
"伊斯坦布尔": "Istanbul",
|
||||
"seoul": "Seoul",
|
||||
"首尔": "Seoul",
|
||||
"busan": "Busan",
|
||||
"pusan": "Busan",
|
||||
"釜山": "Busan",
|
||||
"hong kong": "Hong Kong",
|
||||
"hong kong international airport": "Hong Kong",
|
||||
"香港": "Hong Kong",
|
||||
@@ -472,6 +481,21 @@ class WeatherDataCollector(OpenMeteoCacheMixin, SettlementSourceMixin, MetarSour
|
||||
"上海": "Shanghai",
|
||||
"singapore": "Singapore",
|
||||
"新加坡": "Singapore",
|
||||
"kuala lumpur": "Kuala Lumpur",
|
||||
"sepang": "Kuala Lumpur",
|
||||
"吉隆坡": "Kuala Lumpur",
|
||||
"jakarta": "Jakarta",
|
||||
"雅加达": "Jakarta",
|
||||
"雅加達": "Jakarta",
|
||||
"helsinki": "Helsinki",
|
||||
"vantaa": "Helsinki",
|
||||
"赫尔辛基": "Helsinki",
|
||||
"赫爾辛基": "Helsinki",
|
||||
"amsterdam": "Amsterdam",
|
||||
"schiphol": "Amsterdam",
|
||||
"阿姆斯特丹": "Amsterdam",
|
||||
"panama city": "Panama City",
|
||||
"巴拿马城": "Panama City",
|
||||
"tokyo": "Tokyo",
|
||||
"东京": "Tokyo",
|
||||
"東京": "Tokyo",
|
||||
|
||||
@@ -54,6 +54,21 @@ def test_cities_endpoint_uses_denver_display_name_for_aurora_market():
|
||||
assert aurora["display_name"] == "Denver"
|
||||
|
||||
|
||||
def test_cities_endpoint_includes_new_wunderground_cities():
|
||||
response = client.get("/api/cities")
|
||||
assert response.status_code == 200
|
||||
payload = response.json()
|
||||
names = {item["name"] for item in payload["cities"]}
|
||||
assert {
|
||||
"busan",
|
||||
"panama city",
|
||||
"kuala lumpur",
|
||||
"jakarta",
|
||||
"helsinki",
|
||||
"amsterdam",
|
||||
}.issubset(names)
|
||||
|
||||
|
||||
def test_payment_runtime_endpoint_returns_shape():
|
||||
response = client.get('/api/payments/runtime')
|
||||
assert response.status_code == 200
|
||||
|
||||
Reference in New Issue
Block a user