aboutsummaryrefslogtreecommitdiffstats
path: root/apps/weather_status/lib/Service/WeatherStatusService.php
diff options
context:
space:
mode:
Diffstat (limited to 'apps/weather_status/lib/Service/WeatherStatusService.php')
-rw-r--r--apps/weather_status/lib/Service/WeatherStatusService.php171
1 files changed, 60 insertions, 111 deletions
diff --git a/apps/weather_status/lib/Service/WeatherStatusService.php b/apps/weather_status/lib/Service/WeatherStatusService.php
index fa3177b20f6..c93010e7f58 100644
--- a/apps/weather_status/lib/Service/WeatherStatusService.php
+++ b/apps/weather_status/lib/Service/WeatherStatusService.php
@@ -3,116 +3,55 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Julien Veyssier
- *
- * @author Julien Veyssier <eneiluj@posteo.net>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\WeatherStatus\Service;
-use OCP\IConfig;
-use OCP\IL10N;
-use OCP\App\IAppManager;
+use OCA\WeatherStatus\AppInfo\Application;
+use OCA\WeatherStatus\ResponseDefinitions;
use OCP\Accounts\IAccountManager;
use OCP\Accounts\PropertyDoesNotExistException;
-use OCP\IUserManager;
-use OCP\Http\Client\IClientService;
+use OCP\App\IAppManager;
use OCP\Http\Client\IClient;
-use OCP\ICacheFactory;
+use OCP\Http\Client\IClientService;
use OCP\ICache;
-use OCP\ILogger;
-
-use OCA\WeatherStatus\AppInfo\Application;
+use OCP\ICacheFactory;
+use OCP\IConfig;
+use OCP\IL10N;
+use OCP\IUserManager;
+use Psr\Log\LoggerInterface;
/**
* Class WeatherStatusService
*
* @package OCA\WeatherStatus\Service
+ *
+ * @psalm-import-type WeatherStatusForecast from ResponseDefinitions
+ * @psalm-import-type WeatherStatusSuccess from ResponseDefinitions
+ * @psalm-import-type WeatherStatusLocationWithSuccess from ResponseDefinitions
+ * @psalm-import-type WeatherStatusLocationWithMode from ResponseDefinitions
*/
class WeatherStatusService {
public const MODE_BROWSER_LOCATION = 1;
public const MODE_MANUAL_LOCATION = 2;
- /** @var IClientService */
- private $clientService;
-
- /** @var IClient */
- private $client;
-
- /** @var IConfig */
- private $config;
-
- /** @var IL10N */
- private $l10n;
-
- /** @var ILogger */
- private $logger;
-
- /** @var IAccountManager */
- private $accountManager;
-
- /** @var IUserManager */
- private $userManager;
-
- /** @var IAppManager */
- private $appManager;
-
- /** @var ICache */
- private $cache;
-
- /** @var string */
- private $userId;
-
- /** @var string */
- private $version;
-
- /**
- * WeatherStatusService constructor
- *
- * @param IClientService $clientService
- * @param IConfig $config
- * @param IL10N $l10n
- * @param ILogger $logger
- * @param IAccountManager $accountManager
- * @param IUserManager $userManager
- * @param IAppManager $appManager
- * @param ICacheFactory $cacheFactory
- * @param string $userId
- */
- public function __construct(IClientService $clientService,
- IConfig $config,
- IL10N $l10n,
- ILogger $logger,
- IAccountManager $accountManager,
- IUserManager $userManager,
- IAppManager $appManager,
- ICacheFactory $cacheFactory,
- ?string $userId) {
- $this->config = $config;
- $this->userId = $userId;
- $this->l10n = $l10n;
- $this->logger = $logger;
- $this->accountManager = $accountManager;
- $this->userManager = $userManager;
- $this->appManager = $appManager;
+ private IClient $client;
+ private ICache $cache;
+ private string $version;
+
+ public function __construct(
+ private IClientService $clientService,
+ private IConfig $config,
+ private IL10N $l10n,
+ private LoggerInterface $logger,
+ private IAccountManager $accountManager,
+ private IUserManager $userManager,
+ private IAppManager $appManager,
+ private ICacheFactory $cacheFactory,
+ private ?string $userId,
+ ) {
$this->version = $appManager->getAppVersion(Application::APP_ID);
- $this->clientService = $clientService;
$this->client = $clientService->newClient();
$this->cache = $cacheFactory->createDistributed('weatherstatus');
}
@@ -122,7 +61,7 @@ class WeatherStatusService {
* - ask the browser
* - use the user defined address
* @param int $mode New mode
- * @return array success state
+ * @return WeatherStatusSuccess success state
*/
public function setMode(int $mode): array {
$this->config->setUserValue($this->userId, Application::APP_ID, 'mode', strval($mode));
@@ -131,8 +70,7 @@ class WeatherStatusService {
/**
* Get favorites list
- * @param array $favorites
- * @return array success state
+ * @return list<string>
*/
public function getFavorites(): array {
$favoritesJson = $this->config->getUserValue($this->userId, Application::APP_ID, 'favorites', '');
@@ -141,8 +79,8 @@ class WeatherStatusService {
/**
* Set favorites list
- * @param array $favorites
- * @return array success state
+ * @param list<string> $favorites
+ * @return WeatherStatusSuccess success state
*/
public function setFavorites(array $favorites): array {
$this->config->setUserValue($this->userId, Application::APP_ID, 'favorites', json_encode($favorites));
@@ -152,7 +90,7 @@ class WeatherStatusService {
/**
* Try to use the address set in user personal settings as weather location
*
- * @return array with success state and address information
+ * @return WeatherStatusLocationWithSuccess with success state and address information
*/
public function usePersonalAddress(): array {
$account = $this->accountManager->getAccount($this->userManager->get($this->userId));
@@ -174,7 +112,7 @@ class WeatherStatusService {
* @param string|null $address Any approximative or exact address
* @param float|null $lat Latitude in decimal degree format
* @param float|null $lon Longitude in decimal degree format
- * @return array with success state and address information
+ * @return WeatherStatusLocationWithSuccess with success state and address information
*/
public function setLocation(?string $address, ?float $lat, ?float $lon): array {
if (!is_null($lat) && !is_null($lon)) {
@@ -183,7 +121,7 @@ class WeatherStatusService {
$this->config->setUserValue($this->userId, Application::APP_ID, 'lon', strval($lon));
// resolve and store formatted address
$address = $this->resolveLocation($lat, $lon);
- $address = $address ? $address : $this->l10n->t('Unknown address');
+ $address = $address ?: $this->l10n->t('Unknown address');
$this->config->setUserValue($this->userId, Application::APP_ID, 'address', $address);
// get and store altitude
$altitude = $this->getAltitude($lat, $lon);
@@ -278,7 +216,7 @@ class WeatherStatusService {
* Set address and resolve it to get coordinates
*
* @param string $address Any approximative or exact address
- * @return array with success state and address information (coordinates and formatted address)
+ * @return WeatherStatusLocationWithSuccess with success state and address information (coordinates and formatted address)
*/
public function setAddress(string $address): array {
$addressInfo = $this->searchForAddress($address);
@@ -306,28 +244,39 @@ class WeatherStatusService {
* Ask nominatim information about an unformatted address
*
* @param string Unformatted address
- * @return array Full Nominatim result for the given address
+ * @return array{display_name?: string, lat?: string, lon?: string, error?: string} Full Nominatim result for the given address
*/
private function searchForAddress(string $address): array {
$params = [
+ 'q' => $address,
'format' => 'json',
'addressdetails' => '1',
'extratags' => '1',
'namedetails' => '1',
'limit' => '1',
];
- $url = 'https://nominatim.openstreetmap.org/search/' . $address;
+ $url = 'https://nominatim.openstreetmap.org/search';
$results = $this->requestJSON($url, $params);
- if (count($results) > 0) {
- return $results[0];
+
+ if (isset($results['error'])) {
+ return ['error' => (string)$results['error']];
}
+
+ if (count($results) > 0 && is_array($results[0])) {
+ return [
+ 'display_name' => (string)($results[0]['display_name'] ?? null),
+ 'lat' => (string)($results[0]['lat'] ?? null),
+ 'lon' => (string)($results[0]['lon'] ?? null),
+ ];
+ }
+
return ['error' => $this->l10n->t('No result.')];
}
/**
* Get stored user location
*
- * @return array which contains coordinates, formatted address and current weather status mode
+ * @return WeatherStatusLocationWithMode which contains coordinates, formatted address and current weather status mode
*/
public function getLocation(): array {
$lat = $this->config->getUserValue($this->userId, Application::APP_ID, 'lat', '');
@@ -345,7 +294,7 @@ class WeatherStatusService {
/**
* Get forecast for current location
*
- * @return array which contains success state and filtered forecast data
+ * @return list<WeatherStatusForecast>|array{error: string}|WeatherStatusSuccess which contains success state and filtered forecast data
*/
public function getForecast(): array {
$lat = $this->config->getUserValue($this->userId, Application::APP_ID, 'lat', '');
@@ -368,7 +317,7 @@ class WeatherStatusService {
* @param float $lon Longitude of requested forecast, in decimal degree format
* @param float $altitude Altitude of requested forecast, in meter
* @param int $nbValues Number of forecast values (hours)
- * @return array Filtered forecast data
+ * @return list<WeatherStatusForecast>|array{error: string} Filtered forecast data
*/
private function forecastRequest(float $lat, float $lon, float $altitude, int $nbValues = 10): array {
$params = [
@@ -426,8 +375,8 @@ class WeatherStatusService {
$cacheDuration = 60 * 60;
if (isset($headers['Expires']) && count($headers['Expires']) > 0) {
// if the Expires response header is set, use it to define cache duration
- $expireTs = (new \Datetime($headers['Expires'][0]))->getTimestamp();
- $nowTs = (new \Datetime())->getTimestamp();
+ $expireTs = (new \DateTime($headers['Expires'][0]))->getTimestamp();
+ $nowTs = (new \DateTime())->getTimestamp();
$duration = $expireTs - $nowTs;
if ($duration > $cacheDuration) {
$cacheDuration = $duration;
@@ -438,7 +387,7 @@ class WeatherStatusService {
return $json;
}
} catch (\Exception $e) {
- $this->logger->warning($url . 'API error : ' . $e, ['app' => Application::APP_ID]);
+ $this->logger->warning($url . ' API error : ' . $e->getMessage(), ['exception' => $e]);
return ['error' => $e->getMessage()];
}
}