feat: 轻雪天气实时天气功能已更新

This commit is contained in:
2024-04-15 18:04:19 +08:00
parent 7d0b9662f4
commit 79d8063b5d
87 changed files with 474 additions and 29 deletions

View File

@ -0,0 +1,142 @@
from .qw_models import *
import httpx
language_map = {
"zh-CN" : "zh",
"zh-HK" : "zh-hant",
"en-US" : "en",
"ja-JP" : "ja",
"ko-KR" : "ko",
"fr-FR" : "fr",
"es-ES" : "es",
"de-DE" : "de",
"it-IT" : "it",
"ru-RU" : "ru",
"ar-SA" : "ar",
"pt-BR" : "pt",
"nl-NL" : "nl",
"pl-PL" : "pl",
"tr-TR" : "tr",
"th-TH" : "th",
"vi-VN" : "vi",
"id-ID" : "id",
"ms-MY" : "ms",
"fil-PH": "fil",
} # 其他使用默认对应
dev_url = "https://devapi.qweather.com/" # 开发HBa
com_url = "https://api.qweather.com/" # 正式环境
async def city_lookup(
location: str,
key: str,
adm: str = "",
number: int = 20,
lang: str = "zh",
) -> CityLookup:
"""
通过关键字搜索城市信息
Args:
location:
key:
adm:
number:
lang: 可传入标准i18n语言代码如zh-CN、en-US等
Returns:
"""
url = "https://geoapi.qweather.com/v2/city/lookup?"
params = {
"location": location,
"adm" : adm,
"number" : number,
"key" : key,
"lang" : language_map.get(lang, lang),
}
async with httpx.AsyncClient() as client:
resp = await client.get(url, params=params)
return CityLookup.parse_obj(resp.json())
async def get_weather_now(
key: str,
location: str,
lang: str = "zh",
unit: str = "m",
dev: bool = True,
) -> dict:
url_path = "v7/weather/now?"
url = dev_url + url_path if dev else com_url + url_path
params = {
"location": location,
"key" : key,
"lang" : language_map.get(lang, lang),
"unit" : unit,
}
async with httpx.AsyncClient() as client:
resp = await client.get(url, params=params)
return resp.json()
async def get_weather_daily(
key: str,
location: str,
lang: str = "zh",
unit: str = "m",
dev: bool = True,
) -> dict:
url_path = "v7/weather/%dd?" % (7 if dev else 30)
url = dev_url + url_path if dev else com_url + url_path
params = {
"location": location,
"key" : key,
"lang" : language_map.get(lang, lang),
"unit" : unit,
}
async with httpx.AsyncClient() as client:
resp = await client.get(url, params=params)
return resp.json()
async def get_weather_hourly(
key: str,
location: str,
lang: str = "zh",
unit: str = "m",
dev: bool = True,
) -> dict:
url_path = "v7/weather/%dh?" % (24 if dev else 168)
url = dev_url + url_path if dev else com_url + url_path
params = {
"location": location,
"key" : key,
"lang" : language_map.get(lang, lang),
"unit" : unit,
}
async with httpx.AsyncClient() as client:
resp = await client.get(url, params=params)
return resp.json()
async def get_airquality(
key: str,
location: str,
lang: str,
pollutant: bool = False,
station: bool = False,
dev: bool = True
) -> dict:
url_path = f"airquality/v1/now/{location}?"
url = dev_url + url_path if dev else com_url + url_path
params = {
"key" : key,
"lang" : language_map.get(lang, lang),
"pollutant": pollutant,
"station" : station,
}
async with httpx.AsyncClient() as client:
resp = await client.get(url, params=params)
return resp.json()

View File

@ -19,12 +19,12 @@ class Location(LiteModel):
license: str = ""
class CityLookupResponse(LiteModel):
class CityLookup(LiteModel):
code: str = ""
location: Location = Location()
location: list[Location] = [Location()]
class WeatherNow(LiteModel):
class Now(LiteModel):
obsTime: str = ""
temp: str = ""
feelsLike: str = ""
@ -44,8 +44,19 @@ class WeatherNow(LiteModel):
license: str = ""
class WeatherNowResponse(LiteModel):
class WeatherNow(LiteModel):
code: str = ""
updateTime: str = ""
fxLink: str = ""
now: WeatherNow = WeatherNow()
now: Now = Now()
class Daily(LiteModel):
pass
class WeatherDaily(LiteModel):
code: str = ""
updateTime: str = ""
fxLink: str = ""
daily: list[str] = []

View File

@ -1,7 +1,16 @@
from nonebot import require
from nonebot.adapters.onebot.v11 import MessageSegment
from nonebot.internal.matcher import Matcher
from liteyuki.utils.base.config import get_config
from liteyuki.utils.base.ly_typing import T_MessageEvent
from .qw_api import *
from ...utils.base.data_manager import User, user_db
from ...utils.base.language import get_user_lang
from ...utils.base.resource import get_path
from ...utils.message.html_tool import template2image
require("nonebot_plugin_alconna")
from nonebot_plugin_alconna import on_alconna, Alconna, Args, MultiVar, Arparma
@ -10,11 +19,67 @@ from nonebot_plugin_alconna import on_alconna, Alconna, Args, MultiVar, Arparma
aliases={"天气"},
command=Alconna(
"weather",
Args["keywords", MultiVar(str)],
Args["keywords", MultiVar(str), []],
),
).handle()
async def _(result: Arparma, event: T_MessageEvent):
async def _(result: Arparma, event: T_MessageEvent, matcher: Matcher):
"""await alconna.send("weather", city)"""
print(result["keywords"])
if len(result["keywords"]) == 0:
pass
ulang = get_user_lang(str(event.user_id))
qw_lang = language_map.get(ulang.lang_code, ulang.lang_code)
key = get_config("weather_key")
is_dev = get_config("weather_dev")
user: User = user_db.first(User(), "user_id = ?", str(event.user_id), default=User())
# params
unit = user.profile.get("unit", "m")
stored_location = user.profile.get("location", None)
if not key:
await matcher.finish(ulang.get("weather.no_key"))
kws = result.main_args.get("keywords")
if kws:
if len(kws) >= 2:
adm = kws[0]
city = kws[-1]
else:
adm = ""
city = kws[0]
city_info = await city_lookup(city, key, adm=adm, lang=qw_lang)
city_name = " ".join(kws)
else:
if not stored_location:
await matcher.finish(ulang.get("liteyuki.invalid_command", TEXT="location"))
city_info = await city_lookup(stored_location, key, lang=qw_lang)
city_name = stored_location
if city_info.code == "200":
location_data = city_info.location[0]
else:
await matcher.finish(ulang.get("weather.city_not_found", CITY=city_name))
weather_now = await get_weather_now(key, location_data.id, lang=qw_lang, unit=unit, dev=is_dev)
weather_daily = await get_weather_daily(key, location_data.id, lang=qw_lang, unit=unit, dev=is_dev)
weather_hourly = await get_weather_hourly(key, location_data.id, lang=qw_lang, unit=unit, dev=is_dev)
aqi = await get_airquality(key, location_data.id, lang=qw_lang, dev=is_dev)
image = await template2image(
template=get_path("templates/weather_now.html", abs_path=True),
templates={
"data": {
"params" : {
"unit": unit,
"lang": ulang.lang_code,
},
"weatherNow" : weather_now,
"weatherDaily" : weather_daily,
"weatherHourly": weather_hourly,
"aqi" : aqi,
"location" : location_data.dump(),
}
},
debug=True,
wait=1
)
await matcher.finish(MessageSegment.image(image))