import aiohttp from datetime import datetime async def get_coords_by_city(city_name: str): """Ищет координаты по названию города.""" url = f"https://geocoding-api.open-meteo.com/v1/search?name={city_name}&count=1&language=ru&format=json" async with aiohttp.ClientSession() as session: try: async with session.get(url, timeout=5) as response: if response.status != 200: return None, None, None data = await response.json() results = data.get("results") if not results: return None, None, None city_data = results[0] return city_data.get("latitude"), city_data.get("longitude"), city_data.get("name", city_name) except Exception: return None, None, None async def fetch_weather_data(lat: float, lon: float, days: int): """Базовая функция для запроса данных о погоде на N дней.""" url = ( f"https://api.open-meteo.com/v1/forecast?latitude={lat}&longitude={lon}" f"¤t=temperature_2m" f"&daily=temperature_2m_max,temperature_2m_min,precipitation_probability_max" f"&timezone=auto&forecast_days={days}" ) async with aiohttp.ClientSession() as session: try: async with session.get(url, timeout=5) as response: if response.status != 200: return None return await response.json() except Exception: return None async def get_daily_weather_summary(lat: float, lon: float) -> str: """Прогноз на сегодня.""" data = await fetch_weather_data(lat, lon, 1) if not data or "daily" not in data or "current" not in data: return "Не удалось получить данные о погоде от сервера." current_temp = data["current"].get("temperature_2m", "N/A") temp_max = data["daily"]["temperature_2m_max"][0] temp_min = data["daily"]["temperature_2m_min"][0] precip_prob = data["daily"]["precipitation_probability_max"][0] temp_diff = round(temp_max - temp_min, 1) return ( f"🌤 **Погода на сегодня:**\n\n" f"🌡 **Сейчас:** {current_temp}°C\n" f"📊 **Дневная норма:** от {temp_min}°C до {temp_max}°C\n" f"📉 **Перепад температур за день:** {temp_diff}°C\n" f"🌧 **Макс. вероятность осадков:** {precip_prob}%\n\n" f"Одевайтесь по погоде и хорошего дня!" ) async def get_tomorrow_weather_summary(lat: float, lon: float) -> str: """Прогноз на завтра (берем индекс [1] из массивов).""" data = await fetch_weather_data(lat, lon, 2) if not data or "daily" not in data: return "Не удалось получить данные о погоде от сервера." temp_max = data["daily"]["temperature_2m_max"][1] temp_min = data["daily"]["temperature_2m_min"][1] precip_prob = data["daily"]["precipitation_probability_max"][1] temp_diff = round(temp_max - temp_min, 1) return ( f"📅 **Погода на завтра:**\n\n" f"📊 **Дневная норма:** от {temp_min}°C до {temp_max}°C\n" f"📉 **Перепад температур:** {temp_diff}°C\n" f"🌧 **Макс. вероятность осадков:** {precip_prob}%\n\n" f"Запланируйте свой день с учетом прогноза!" ) async def get_weekly_weather_summary(lat: float, lon: float) -> str: """Прогноз на 7 дней.""" data = await fetch_weather_data(lat, lon, 7) if not data or "daily" not in data: return "Не удалось получить данные о погоде от сервера." dates = data["daily"]["time"] max_temps = data["daily"]["temperature_2m_max"] min_temps = data["daily"]["temperature_2m_min"] precips = data["daily"]["precipitation_probability_max"] week_days = ["Пн", "Вт", "Ср", "Чт", "Пт", "Сб", "Вс"] summary = "📆 **Прогноз на неделю:**\n\n" for i in range(7): # Преобразуем дату "YYYY-MM-DD" в красивый формат "DD.MM (День недели)" date_obj = datetime.strptime(dates[i], "%Y-%m-%d") day_name = week_days[date_obj.weekday()] formatted_date = date_obj.strftime("%d.%m") t_min = min_temps[i] t_max = max_temps[i] prob = precips[i] # Эмодзи для осадков, чтобы легче читалось precip_emoji = "☔️" if prob > 40 else ("☁️" if prob > 10 else "☀️") summary += f"🔹 **{formatted_date} ({day_name}):** от {t_min}°C до {t_max}°C | {precip_emoji} {prob}%\n" return summary