Fix/metar reading (#353)

* Fix reading of the METAR information for AviationWeather. Fix the DI

* StyleCI fixes
This commit is contained in:
Nabeel S
2019-08-08 14:52:34 -04:00
committed by GitHub
parent becf6c95f0
commit 5cafebe4d6
11 changed files with 121 additions and 100 deletions

View File

@@ -7,6 +7,7 @@ use App\Models\Acars;
use App\Models\Airline;
use App\Models\Pirep;
use App\Models\User;
use App\Services\AirportService;
use App\Services\AwardService;
use App\Services\DatabaseService;
use Illuminate\Database\QueryException;
@@ -55,6 +56,7 @@ class DevCommands extends Command
'db-attrs' => 'dbAttrs',
'list-awards' => 'listAwardClasses',
'manual-insert' => 'manualInsert',
'metar' => 'getMetar',
'reset-install' => 'resetInstall',
'xml-to-yaml' => 'xmlToYaml',
];
@@ -187,6 +189,19 @@ class DevCommands extends Command
$this->info('Writing yaml to storage: '.$file_name);
}
protected function getMetar(): void
{
$icao = $this->argument('param');
if (!$icao) {
$this->error('Enter an ICAO!');
exit();
}
$airportSvc = app(AirportService::class);
$metar = $airportSvc->getMetar($icao);
$this->info($metar->raw);
}
/**
* Insert the rows from the file, manually advancing each row
*/

View File

@@ -2,7 +2,6 @@
namespace App\Contracts;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
@@ -12,9 +11,8 @@ use Illuminate\Support\Facades\Log;
abstract class Metar
{
/**
* Implement retrieving the METAR- Return the string
* Needs to be protected, since this shouldn't be
* directly called. Call `get_metar($icao)` instead
* Implement retrieving the METAR - return the METAR string. Needs to be protected,
* since this shouldn't be directly called. Call `get_metar($icao)` instead
*
* @param $icao
*
@@ -22,13 +20,6 @@ abstract class Metar
*/
abstract protected function metar($icao): string;
/**
* @param $icao
*
* @return string
*/
//abstract protected function taf($icao): string;
/**
* Download the METAR, wrap in caching
*
@@ -41,17 +32,23 @@ abstract class Metar
$cache = config('cache.keys.WEATHER_LOOKUP');
$key = $cache['key'].$icao;
$raw_metar = Cache::remember($key, $cache['time'], function () use ($icao) {
try {
return $this->metar($icao);
} catch (GuzzleException $e) {
Log::error('Error getting METAR: '.$e->getMessage(), $e->getTrace());
return '';
} catch (\Exception $e) {
Log::error('Error getting METAR: '.$e->getMessage(), $e->getTrace());
return '';
if (Cache::has($key)) {
$raw_metar = Cache::get($key);
if ($raw_metar !== '') {
return $raw_metar;
}
});
}
try {
$raw_metar = $this->metar($icao);
} catch (\Exception $e) {
Log::error('Error getting METAR: '.$e->getMessage(), $e->getTrace());
return '';
}
if ($raw_metar !== '') {
Cache::put($key, $raw_metar, $cache['time']);
}
return $raw_metar;
}

View File

@@ -0,0 +1,17 @@
<?php
namespace App\Providers;
use App\Contracts\Metar;
use Illuminate\Support\ServiceProvider;
class WeatherServiceProvider extends ServiceProvider
{
public function boot(): void
{
$this->app->bind(
Metar::class,
config('phpvms.metar')
);
}
}

View File

@@ -0,0 +1,41 @@
<?php
namespace App\Services;
use App\Contracts\Metar as MetarProvider;
use App\Contracts\Service;
use App\Support\Metar;
/**
* Class AnalyticsService
*/
class AirportService extends Service
{
private $metarProvider;
public function __construct(
MetarProvider $metarProvider
) {
$this->metarProvider = $metarProvider;
}
/**
* Return the METAR for a given airport
*
* @param $icao
*
* @return Metar|null
*/
public function getMetar($icao): Metar
{
$metar = null;
$wind = null;
$raw_metar = $this->metarProvider->get_metar($icao);
if ($raw_metar && $raw_metar !== '') {
return new Metar($raw_metar);
}
return null;
}
}

View File

@@ -3,8 +3,7 @@
namespace App\Services\Metar;
use App\Contracts\Metar;
use App\Support\Http;
use Illuminate\Support\Facades\Cache;
use App\Support\HttpClient;
use Illuminate\Support\Facades\Log;
/**
@@ -17,35 +16,39 @@ class AviationWeather extends Metar
.'dataSource=metars&requestType=retrieve&format=xml&hoursBeforeNow=3'
.'&mostRecent=true&fields=raw_text&stationString=';
private $httpClient;
public function __construct(HttpClient $httpClient)
{
$this->httpClient = $httpClient;
}
/**
* Implement the METAR - Return the string
*
* @param $icao
*
* @throws \Exception
* @throws \GuzzleHttp\Exception\GuzzleException
*
* @return string
*/
protected function metar($icao): string
{
$metar = Cache::remember(
config('cache.keys.WEATHER_LOOKUP.key').$icao,
config('cache.keys.WEATHER_LOOKUP.time'),
function () use ($icao) {
$url = static::METAR_URL.$icao;
$url = static::METAR_URL.$icao;
try {
$res = Http::get($url, []);
$xml = simplexml_load_string($res);
if (\count($xml->data->METAR->raw_text) === 0) {
return '';
}
return $xml->data->METAR->raw_text->__toString();
} catch (\Exception $e) {
Log::error('Error reading METAR: '.$e->getMessage());
return '';
}
try {
$res = $this->httpClient->get($url, []);
$xml = simplexml_load_string($res);
if (\count($xml->data->METAR->raw_text) === 0) {
return '';
}
);
return $metar;
return $xml->data->METAR->raw_text->__toString();
} catch (\Exception $e) {
Log::error('Error reading METAR: '.$e->getMessage());
throw $e;
}
}
}

View File

@@ -1,39 +0,0 @@
<?php
namespace App\Support;
use GuzzleHttp\Client;
/**
* Helper for HTTP stuff
*/
class Http
{
/**
* Download a URI. If a file is given, it will save the downloaded
* content into that file
*
* @param $uri
* @param array $opts
*
* @throws \GuzzleHttp\Exception\GuzzleException
*
* @return string
*/
public static function get($uri, array $opts = [])
{
$opts = array_merge([
'connect_timeout' => 2, // wait two seconds by default
], $opts);
$client = new Client();
$responseSeederService = $client->request('GET', $uri, $opts);
$body = $response->getBody()->getContents();
if ($response->getHeader('content-type') === 'application/json') {
$body = \GuzzleHttp\json_decode($body);
}
return $body;
}
}

View File

@@ -2,7 +2,7 @@
namespace App\Support;
use GuzzleHttp\Client;
use GuzzleHttp\Client as GuzzleClient;
/**
* Helper for HTTP stuff
@@ -12,7 +12,7 @@ class HttpClient
private $httpClient;
public function __construct(
Client $httpClient
GuzzleClient $httpClient
) {
$this->httpClient = $httpClient;
}

View File

@@ -310,7 +310,7 @@ class Metar implements \ArrayAccess
/*
* Other variables.
*/
private $raw;
public $raw;
private $raw_parts = [];

View File

@@ -3,7 +3,7 @@
namespace App\Widgets;
use App\Contracts\Widget;
use App\Support\Metar;
use App\Services\AirportService;
/**
* This is a widget for the 3rd party CheckWX service
@@ -14,26 +14,13 @@ class Weather extends Widget
'icao' => null,
];
public const URL = 'https://avwx.rest/api/metar/';
/**
* Attempt to get the data from the CheckWX API
*/
public function run()
{
/**
* @var \App\Contracts\Metar
*/
$klass = config('phpvms.metar');
$metar_class = new $klass();
$metar = null;
$wind = null;
$raw_metar = $metar_class->get_metar($this->config['icao']);
if ($raw_metar && $raw_metar !== '') {
$metar = new Metar($raw_metar);
}
$airportSvc = app(AirportService::class);
$metar = $airportSvc->getMetar($this->config['icao']);
return view('widgets.weather', [
'config' => $this->config,

View File

@@ -87,6 +87,7 @@ return [
App\Providers\vaCentralServiceProvider::class,
App\Providers\ExtendedTimezonelistProvider::class,
App\Providers\MeasurementsProvider::class,
App\Providers\WeatherServiceProvider::class,
],
'aliases' => [

View File

@@ -24,7 +24,6 @@ class VersionTest extends TestCase
'7.0.0-beta' => '7.0.0-alpha',
'7.0.0-beta.1' => '7.0.0-beta',
'7.0.0-beta.2' => '7.0.0-beta.1',
'7.0.0-beta.1' => '7.0.0-alpha',
];
$versionSvc = app(VersionService::class);