Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
trim_trailing_whitespace = true

[*.md]
trim_trailing_whitespace = false

[*.{yml,yaml}]
indent_size = 2

[docker-compose.yml]
indent_size = 4
54 changes: 54 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:v1QnVEowFRp4C4Ne5jAR9RKM2vp8ytxqmOA/4Ej1R10=
APP_DEBUG=true
APP_URL=http://localhost

LOG_CHANNEL=stack
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debug

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=weather
DB_USERNAME=root
DB_PASSWORD=

BROADCAST_DRIVER=log
CACHE_DRIVER=file
FILESYSTEM_DRIVER=local
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120

MEMCACHED_HOST=127.0.0.1

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_MAILER=smtp
MAIL_HOST=mailhog
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS=null
MAIL_FROM_NAME="${APP_NAME}"

AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
AWS_USE_PATH_STYLE_ENDPOINT=false

PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1

MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"

WEATHER_API_KEY=
10 changes: 10 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
* text=auto

*.blade.php diff=html
*.css diff=css
*.html diff=html
*.md diff=markdown
*.php diff=php

/.github export-ignore
CHANGELOG.md export-ignore
16 changes: 16 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/node_modules
/public/hot
/public/storage
/storage/*.key
/vendor
.env
.env.backup
.phpunit.result.cache
docker-compose.override.yml
Homestead.json
Homestead.yaml
npm-debug.log
yarn-error.log
.idea
/.idea
/.vscode
14 changes: 14 additions & 0 deletions .styleci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
php:
preset: laravel
version: 8
disabled:
- no_unused_imports
finder:
not-name:
- index.php
- server.php
js:
finder:
not-name:
- webpack.mix.js
css: true
68 changes: 10 additions & 58 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,61 +1,13 @@
![This is an image](https://images.unsplash.com/photo-1492011221367-f47e3ccd77a0?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=987&h=400&q=80)
Project Installation
--------------------

# How to do the task
1. composer install
2. Configure .env file, WEATHER_API_KEY should be set.
3. php artisan key:generate
4. php artisan migrate:fresh --seed
5. This is command in being ran on every 2 minutes, the Laravel's schedule should be called in the cron job -> <stong>php artisan update:weather</strong>

Fork the project, work on the solution and send us back a link to your forked GitHub project.
Postman Documentation
---------------------------

# Weather API - Laravel Developer Test Task

We will use [**Open Weather API**](https://openweathermap.org/current) to get current weather data based on latitude/longitude.

- **API Link**: [https://openweathermap.org/current](https://openweathermap.org/current)
- **API Key**: `1077481787381398496a922389d0eea2`
- **Technology: Laravel**

---

# Task

Create a project, that will pull the weather information of cities and will store it in the database every two minutes.

# Data to store

- Store the data about cities in the database
- Store the data about weather information in the database every two minutes

# Rest API Endpoints

- Store the data about cities in the database
- Get the list of the stored weather information
- Ability to filter the weather information by city name ( exact match )

# Data

## Columns that should be stored about city

- City name
- Latitude
- Longitude

## Columns that should be stored about weather information in the table:

- Time
- Name
- Latitude
- Longitude
- Temperature (in Celsius)
- Pressure
- Humidity
- MIN Temperature
- MAX Temperature

# Example Cities

| Name | Latitude | Longitude |
|---------|----------|-----------|
| Yerevan | 40.18 | 44.51 |
| Kapan | 39.21 | 46.41 |

# Note:

In your solution include the readme with the explanation of how to run the project and get the data.
<a target="_blank" href="https://documenter.getpostman.com/view/6660278/2s7YfLfaqN">https://documenter.getpostman.com/view/6660278/2s7YfLfaqN</a>
52 changes: 52 additions & 0 deletions app/Console/Commands/UpdateWeather.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

namespace App\Console\Commands;

use App\Facades\OpenWeatherFacade;
use App\Models\City;
use App\Models\Weather;
use Illuminate\Console\Command;

class UpdateWeather extends Command
{
private $city;

/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'update:weather';

/**
* The console command description.
*
* @var string
*/
protected $description = 'Updated every two minutes';

/**
* Create a new command instance.
*
* @return void
*/
public function __construct(City $city)
{
parent::__construct();
$this->city = $city;
}

/**
* @return void
*/
public function handle():void
{
foreach ($this->city->getAll() as $city) {
$data = OpenWeatherFacade::getByCoordinates($city->latitude, $city->longitude);
Weather::updateOrCreate(
['city_id' => $city->id],
$data,
);
}
}
}
40 changes: 40 additions & 0 deletions app/Console/Kernel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace App\Console;

use App\Console\Commands\UpdateWeather;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* @var array
*/
protected $commands = [
UpdateWeather::class
];

/**
* @param Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
$schedule->command('update:weather')->everyTwoMinutes();
}

/**
* Register the commands for the application.
*
* @return void
*/
protected function commands()
{
$this->load(__DIR__.'/Commands');

require base_path('routes/console.php');
}
}
41 changes: 41 additions & 0 deletions app/Exceptions/Handler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

namespace App\Exceptions;

use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Throwable;

class Handler extends ExceptionHandler
{
/**
* A list of the exception types that are not reported.
*
* @var array<int, class-string<Throwable>>
*/
protected $dontReport = [
//
];

/**
* A list of the inputs that are never flashed for validation exceptions.
*
* @var array<int, string>
*/
protected $dontFlash = [
'current_password',
'password',
'password_confirmation',
];

/**
* Register the exception handling callbacks for the application.
*
* @return void
*/
public function register()
{
$this->reportable(function (Throwable $e) {
//
});
}
}
20 changes: 20 additions & 0 deletions app/Facades/OpenWeatherFacade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

namespace App\Facades;

use Illuminate\Support\Facades\Facade;

/**
* @method static array getByCoordinates(string $lat,string $lon)
*
*/
class OpenWeatherFacade extends Facade
{
/**
* @return string
*/
protected static function getFacadeAccessor(): string
{
return 'open_weather';
}
}
19 changes: 19 additions & 0 deletions app/Facades/ParseCityFacade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace App\Facades;

use Illuminate\Support\Facades\Facade;

/**
* @method static array getCities()
*/
class ParseCityFacade extends Facade
{
/**
* @return string
*/
protected static function getFacadeAccessor(): string
{
return 'parse';
}
}
Loading