Skip to content

Commit

Permalink
Merge pull request #12 from caarmen/issue-11-integrate-weatherapi
Browse files Browse the repository at this point in the history
Issue #11: Add weatherapi support
  • Loading branch information
caarmen authored Feb 3, 2024
2 parents 417374a + facb179 commit 3cf2f0d
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 19 deletions.
6 changes: 4 additions & 2 deletions config.toml.template
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,7 @@ workspace="myotherworkspace.slack.com"
token="xoxc-01234567890-012345678912-0123456789123-0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
cookie_d="xoxd-00000000000000000000000%2B0000000000000000000000000%2B000000000000000000000000000000000000000000000000%2F0000000000%2B0000000000000000000000000000000000%2F000%2F0000000000000000000000000000000000%3D"

[weatherstack]
api_access_key="0123456789abcdef0123456789abcdef"
[weatherprovider]
# Supported names are "weatherstack" and "weatherapi"
name="weatherstack"
api_access_key="0123456789abcdef0123456789abcdef"
8 changes: 3 additions & 5 deletions wspp/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from threading import Event
from typing import Optional

from wspp import image, schedule, slack, weatherstack
from wspp import image, schedule, slack, weather
from wspp.settings import settings
from wspp.sunrisesunset import SunriseSunset

Expand Down Expand Up @@ -40,10 +40,8 @@ def update_profile_photo_from_weather():
sunrise_sunset = SunriseSunset.create(
latitude=settings.wspp.latitude, longitude=settings.wspp.longitude
)
weather_code = weatherstack.get_current_weather_code(
settings=settings.weatherstack,
latitude=settings.wspp.latitude,
longitude=settings.wspp.longitude,
weather_code = weather.get_current_weather_code(
settings=settings,
is_day=sunrise_sunset.is_day_now,
)
if cache.last_weather_code != weather_code:
Expand Down
15 changes: 13 additions & 2 deletions wspp/settings.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import enum
import tomllib
from pathlib import Path
from typing import Any
Expand All @@ -11,7 +12,7 @@
)
from typing_extensions import Annotated

from wspp import slack, weatherstack
from wspp import slack


class WsppSettings(BaseModel):
Expand All @@ -21,6 +22,16 @@ class WsppSettings(BaseModel):
polling_interval_s: PositiveInt = 7200


class ProviderName(enum.Enum):
WEATHERSTACK = "weatherstack"
WEATHERAPI = "weatherapi"


class WeatherproviderSettings(BaseModel):
name: ProviderName
api_access_key: str


# https://github.com/pydantic/pydantic/issues/2335
class TOMLConfigSettingsSource(PydanticBaseSettingsSource):
def get_field_value(
Expand All @@ -34,7 +45,7 @@ def __call__(self) -> dict[str, Any]:

class Settings(BaseSettings):
wspp: WsppSettings
weatherstack: weatherstack.WeatherstackSettings
weatherprovider: WeatherproviderSettings
slack: list[slack.SlackSettings]

@classmethod
Expand Down
25 changes: 25 additions & 0 deletions wspp/weather.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from wspp import weatherapi, weatherstack
from wspp.settings import ProviderName, Settings


def get_current_weather_code(
settings: Settings,
is_day: bool,
) -> int:
"""
:return: The weather_code for the current condition at the location defined
in the environment variable.
"""
if not is_day:
return 999

if settings.weatherprovider.name == ProviderName.WEATHERSTACK:
provider_function = weatherstack.get_current_weather_code
else:
provider_function = weatherapi.get_current_weather_code

return provider_function(
api_access_key=settings.weatherprovider.api_access_key,
latitude=settings.wspp.latitude,
longitude=settings.wspp.longitude,
)
32 changes: 32 additions & 0 deletions wspp/weatherapi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import re

import requests


def get_current_weather_code(
api_access_key: str,
latitude: float,
longitude: float,
) -> int:
"""
:return: The weather_code for the current condition at the location defined
in the environment variable.
"""
response = requests.get(
url="http://api.weatherapi.com/v1/current.json",
params={
"key": api_access_key,
"q": f"{latitude},{longitude}",
"aqi": "no",
},
)
if not response.ok:
raise Exception(response.text)
response_data: dict = response.json()
# ex: //cdn.weatherapi.com/weather/64x64/day/248.png
icon = response_data["current"]["condition"]["icon"]
pattern = re.compile(r"^.*/([0-9]*).png$")
tokens = pattern.findall(icon)
code = tokens[-1]

return code
12 changes: 2 additions & 10 deletions wspp/weatherstack.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,19 @@
import requests
from pydantic import BaseModel


class WeatherstackSettings(BaseModel):
api_access_key: str


def get_current_weather_code(
settings: WeatherstackSettings,
api_access_key: str,
latitude: float,
longitude: float,
is_day: bool,
) -> int:
"""
:return: The weather_code for the current condition at the location defined
in the environment variable.
"""
if not is_day:
return 999
response = requests.get(
url="http://api.weatherstack.com/current",
params={
"access_key": settings.api_access_key,
"access_key": api_access_key,
"query": f"{latitude},{longitude}",
},
)
Expand Down

0 comments on commit 3cf2f0d

Please sign in to comment.