1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
|
"""Nextcloud API for working with weather statuses."""
import dataclasses
import enum
from ._misc import check_capabilities, require_capabilities
from ._session import AsyncNcSessionBasic, NcSessionBasic
class WeatherLocationMode(enum.IntEnum):
"""Source from where Nextcloud should determine user's location."""
UNKNOWN = 0
"""Source is not defined"""
MODE_BROWSER_LOCATION = 1
"""User location taken from the browser"""
MODE_MANUAL_LOCATION = 2
"""User has set their location manually"""
@dataclasses.dataclass
class WeatherLocation:
"""Class representing information about the user's location."""
latitude: float
"""Latitude in decimal degree format"""
longitude: float
"""Longitude in decimal degree format"""
address: str
"""Any approximate or exact address"""
mode: WeatherLocationMode
"""Weather status mode"""
def __init__(self, raw_location: dict):
lat = raw_location.get("lat", "")
lon = raw_location.get("lon", "")
self.latitude = float(lat if lat else "0")
self.longitude = float(lon if lon else "0")
self.address = raw_location.get("address", "")
self.mode = WeatherLocationMode(int(raw_location.get("mode", 0)))
class _WeatherStatusAPI:
"""Class providing the weather status management API on the Nextcloud server."""
_ep_base: str = "/ocs/v1.php/apps/weather_status/api/v1"
def __init__(self, session: NcSessionBasic):
self._session = session
@property
def available(self) -> bool:
"""Returns True if the Nextcloud instance supports this feature, False otherwise."""
return not check_capabilities("weather_status.enabled", self._session.capabilities)
def get_location(self) -> WeatherLocation:
"""Returns the current location set on the Nextcloud server for the user."""
require_capabilities("weather_status.enabled", self._session.capabilities)
return WeatherLocation(self._session.ocs("GET", f"{self._ep_base}/location"))
def set_location(
self,
latitude: float | None = None,
longitude: float | None = None,
address: str | None = None,
) -> bool:
"""Sets the user's location on the Nextcloud server.
:param latitude: north-south position of a point on the surface of the Earth.
:param longitude: east-west position of a point on the surface of the Earth.
:param address: city, index(*optional*) and country, e.g. "Paris, 75007, France"
"""
require_capabilities("weather_status.enabled", self._session.capabilities)
params: dict[str, str | float] = {}
if latitude is not None and longitude is not None:
params.update({"lat": latitude, "lon": longitude})
elif address:
params["address"] = address
else:
raise ValueError("latitude & longitude or address should be present")
result = self._session.ocs("PUT", f"{self._ep_base}/location", params=params)
return result.get("success", False)
def get_forecast(self) -> list[dict]:
"""Get forecast for the current location."""
require_capabilities("weather_status.enabled", self._session.capabilities)
return self._session.ocs("GET", f"{self._ep_base}/forecast")
def get_favorites(self) -> list[str]:
"""Returns favorites addresses list."""
require_capabilities("weather_status.enabled", self._session.capabilities)
return self._session.ocs("GET", f"{self._ep_base}/favorites")
def set_favorites(self, favorites: list[str]) -> bool:
"""Sets favorites addresses list."""
require_capabilities("weather_status.enabled", self._session.capabilities)
result = self._session.ocs("PUT", f"{self._ep_base}/favorites", json={"favorites": favorites})
return result.get("success", False)
def set_mode(self, mode: WeatherLocationMode) -> bool:
"""Change the weather status mode."""
if int(mode) == WeatherLocationMode.UNKNOWN.value:
raise ValueError("This mode can not be set")
require_capabilities("weather_status.enabled", self._session.capabilities)
result = self._session.ocs("PUT", f"{self._ep_base}/mode", params={"mode": int(mode)})
return result.get("success", False)
class _AsyncWeatherStatusAPI:
"""Class provides async weather status management API on the Nextcloud server."""
_ep_base: str = "/ocs/v1.php/apps/weather_status/api/v1"
def __init__(self, session: AsyncNcSessionBasic):
self._session = session
@property
async def available(self) -> bool:
"""Returns True if the Nextcloud instance supports this feature, False otherwise."""
return not check_capabilities("weather_status.enabled", await self._session.capabilities)
async def get_location(self) -> WeatherLocation:
"""Returns the current location set on the Nextcloud server for the user."""
require_capabilities("weather_status.enabled", await self._session.capabilities)
return WeatherLocation(await self._session.ocs("GET", f"{self._ep_base}/location"))
async def set_location(
self,
latitude: float | None = None,
longitude: float | None = None,
address: str | None = None,
) -> bool:
"""Sets the user's location on the Nextcloud server.
:param latitude: north-south position of a point on the surface of the Earth.
:param longitude: east-west position of a point on the surface of the Earth.
:param address: city, index(*optional*) and country, e.g. "Paris, 75007, France"
"""
require_capabilities("weather_status.enabled", await self._session.capabilities)
params: dict[str, str | float] = {}
if latitude is not None and longitude is not None:
params.update({"lat": latitude, "lon": longitude})
elif address:
params["address"] = address
else:
raise ValueError("latitude & longitude or address should be present")
result = await self._session.ocs("PUT", f"{self._ep_base}/location", params=params)
return result.get("success", False)
async def get_forecast(self) -> list[dict]:
"""Get forecast for the current location."""
require_capabilities("weather_status.enabled", await self._session.capabilities)
return await self._session.ocs("GET", f"{self._ep_base}/forecast")
async def get_favorites(self) -> list[str]:
"""Returns favorites addresses list."""
require_capabilities("weather_status.enabled", await self._session.capabilities)
return await self._session.ocs("GET", f"{self._ep_base}/favorites")
async def set_favorites(self, favorites: list[str]) -> bool:
"""Sets favorites addresses list."""
require_capabilities("weather_status.enabled", await self._session.capabilities)
result = await self._session.ocs("PUT", f"{self._ep_base}/favorites", json={"favorites": favorites})
return result.get("success", False)
async def set_mode(self, mode: WeatherLocationMode) -> bool:
"""Change the weather status mode."""
if int(mode) == WeatherLocationMode.UNKNOWN.value:
raise ValueError("This mode can not be set")
require_capabilities("weather_status.enabled", await self._session.capabilities)
result = await self._session.ocs("PUT", f"{self._ep_base}/mode", params={"mode": int(mode)})
return result.get("success", False)
|