Fix: weather uses open-meteo directly (wttr.in hangs)

This commit is contained in:
Cosmo
2026-04-15 21:47:48 +00:00
parent 9c6d9e0fdb
commit 0039132aec
2 changed files with 50 additions and 50 deletions

View File

@@ -1,71 +1,40 @@
export const dynamic = "force-dynamic";
import { NextResponse } from "next/server";
const WMO_DESCRIPTIONS: Record<number, string> = {
0: "Ясно", 1: "Преимущественно ясно", 2: "Переменная облачность", 3: "Пасмурно",
45: "Туман", 48: "Ледяной туман", 51: "Лёгкая морось", 53: "Морось", 55: "Сильная морось",
61: "Лёгкий дождь", 63: "Дождь", 65: "Сильный дождь",
71: "Лёгкий снег", 73: "Снег", 75: "Сильный снег",
80: "Небольшой ливень", 81: "Ливень", 82: "Сильный ливень", 95: "Гроза",
};
export async function GET() {
try {
// Попробовать несколько источников
const sources = [
"https://wttr.in/Saint+Petersburg?format=j1",
"https://wttr.in/Saint%20Petersburg?format=j1",
"http://wttr.in/Saint+Petersburg?format=j1",
];
let lastError: Error | null = null;
for (const url of sources) {
try {
const res = await fetch(url, {
headers: {
"User-Agent": "curl/7.74.0",
"Accept": "application/json",
},
signal: AbortSignal.timeout(5000),
});
if (res.ok) {
const data = await res.json();
return NextResponse.json(data);
}
} catch (e) {
lastError = e as Error;
continue;
}
}
// Fallback: open-meteo (не через Cloudflare)
const geoRes = await fetch("https://geocoding-api.open-meteo.com/v1/search?name=Saint+Petersburg&country=Russia&count=1", {
signal: AbortSignal.timeout(5000),
});
const geoData = await geoRes.json();
const loc = geoData.results?.[0];
if (!loc) throw new Error("Geocoding failed");
// Open-Meteo: координаты Санкт-Петербурга
const lat = 59.9343;
const lon = 30.3351;
const meteoRes = await fetch(
`https://api.open-meteo.com/v1/forecast?latitude=${loc.latitude}&longitude=${loc.longitude}&current=temperature_2m,apparent_temperature,relative_humidity_2m,wind_speed_10m,weather_code&wind_speed_unit=kmh`,
{ signal: AbortSignal.timeout(5000) }
`https://api.open-meteo.com/v1/forecast?latitude=${lat}&longitude=${lon}&current=temperature_2m,apparent_temperature,relative_humidity_2m,wind_speed_10m,weather_code&wind_speed_unit=kmh`,
{ signal: AbortSignal.timeout(6000) }
);
if (!meteoRes.ok) throw new Error("Open-Meteo error");
const meteoData = await meteoRes.json();
// Нормализовать в формат wttr.in
const wmoDescriptions: Record<number, string> = {
0: "Clear sky", 1: "Mainly clear", 2: "Partly cloudy", 3: "Overcast",
45: "Foggy", 48: "Icy fog", 51: "Light drizzle", 53: "Drizzle", 55: "Heavy drizzle",
61: "Light rain", 63: "Rain", 65: "Heavy rain", 71: "Light snow", 73: "Snow", 75: "Heavy snow",
80: "Light showers", 81: "Showers", 82: "Heavy showers", 95: "Thunderstorm",
};
const c = meteoData.current;
const normalized = {
current_condition: [{
temp_C: Math.round(c.temperature_2m).toString(),
FeelsLikeC: Math.round(c.apparent_temperature).toString(),
humidity: Math.round(c.relative_humidity_2m).toString(),
windspeedKmph: Math.round(c.wind_speed_10m).toString(),
weatherDesc: [{ value: wmoDescriptions[c.weather_code] || "Unknown" }],
weatherDesc: [{ value: WMO_DESCRIPTIONS[c.weather_code] ?? "Неизвестно" }],
}],
source: "open-meteo",
};
return NextResponse.json(normalized);
} catch (e) {
return NextResponse.json({ error: "Failed to fetch weather" }, { status: 500 });