Compare commits
1 Commits
feature/or
...
laravel_8
Author | SHA1 | Date | |
---|---|---|---|
a3a9a1f6cc |
@@ -3,9 +3,7 @@
|
|||||||
namespace App\Console\Commands;
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
use App\Parser;
|
use App\Parser;
|
||||||
use GuzzleHttp\Exception\InvalidArgumentException;
|
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use function GuzzleHttp\json_encode;
|
|
||||||
|
|
||||||
class ParseLinkCommand extends Command
|
class ParseLinkCommand extends Command
|
||||||
{
|
{
|
||||||
@@ -41,11 +39,7 @@ class ParseLinkCommand extends Command
|
|||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
$parser = Parser::factory($this->argument('url'));
|
$parser = Parser::factory($this->argument('url'));
|
||||||
try {
|
$parser->parse();
|
||||||
$this->info(json_encode($parser->parse(), true));
|
|
||||||
} catch (InvalidArgumentException $e) {
|
|
||||||
$this->error($e->getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -1,8 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Exceptions;
|
|
||||||
|
|
||||||
class UnknownParser extends Exception
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
namespace App;
|
namespace App;
|
||||||
|
|
||||||
use App\Exceptions\UnknownParser;
|
|
||||||
use GuzzleHttp\Client;
|
use GuzzleHttp\Client;
|
||||||
use Illuminate\Support\Facades\Config;
|
use Illuminate\Support\Facades\Config;
|
||||||
|
|
||||||
@@ -37,11 +36,7 @@ abstract class Parser
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new UnknownParser(sprintf(
|
return null;
|
||||||
'Can\'t find an url in «%s» file with the following URL «%s». Please update the file accordingly.',
|
|
||||||
'parser.php',
|
|
||||||
$url
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -1,192 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Parser;
|
|
||||||
|
|
||||||
use App\ParsedHome;
|
|
||||||
use App\Parser;
|
|
||||||
use GuzzleHttp\Exception\InvalidArgumentException;
|
|
||||||
use Symfony\Component\DomCrawler\Crawler;
|
|
||||||
use function GuzzleHttp\json_decode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class Orpi
|
|
||||||
* @package App\Parser
|
|
||||||
*/
|
|
||||||
class Orpi extends Parser
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function parse(): ParsedHome
|
|
||||||
{
|
|
||||||
$request = $this->client->get($this->url);
|
|
||||||
$body = $request->getBody()->getContents();
|
|
||||||
$crawler = new Crawler($body);
|
|
||||||
$parsedHome = new ParsedHome();
|
|
||||||
/**
|
|
||||||
* Orpi ads can be parsed 2 ways :
|
|
||||||
* * sometimes, a JSON is included in the page so it's just a reading/feeding object
|
|
||||||
* * else, we must crawl the webpage…
|
|
||||||
*/
|
|
||||||
$data_estate = $crawler->filter('[data-estate]');
|
|
||||||
if ($data_estate->count() > 0) {
|
|
||||||
return $this->parseJSON($parsedHome, $crawler);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->parseHTML($parsedHome, $crawler);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param int $score
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
private function calculateDPE($score)
|
|
||||||
{
|
|
||||||
if (empty($score)) {
|
|
||||||
return 'Inconnu';
|
|
||||||
}
|
|
||||||
if ($score <= 50) {
|
|
||||||
return 'A';
|
|
||||||
}
|
|
||||||
if ($score >= 51 && $score <= 90) {
|
|
||||||
return 'B';
|
|
||||||
}
|
|
||||||
if ($score >= 91 && $score <= 150) {
|
|
||||||
return 'C';
|
|
||||||
}
|
|
||||||
if ($score >= 151 && $score <= 230) {
|
|
||||||
return 'D';
|
|
||||||
}
|
|
||||||
if ($score >= 231 && $score <= 330) {
|
|
||||||
return 'E';
|
|
||||||
}
|
|
||||||
if ($score >= 331 && $score <= 450) {
|
|
||||||
return 'F';
|
|
||||||
}
|
|
||||||
if ($score > 450) {
|
|
||||||
return 'G';
|
|
||||||
}
|
|
||||||
|
|
||||||
return 'Inconnu';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $score
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
private function calculateGES($score)
|
|
||||||
{
|
|
||||||
if (empty($score)) {
|
|
||||||
return 'Inconnu';
|
|
||||||
}
|
|
||||||
if ($score <= 5) {
|
|
||||||
return 'A';
|
|
||||||
}
|
|
||||||
if ($score >= 6 && $score <= 10) {
|
|
||||||
return 'B';
|
|
||||||
}
|
|
||||||
if ($score >= 11 && $score <= 20) {
|
|
||||||
return 'C';
|
|
||||||
}
|
|
||||||
if ($score >= 21 && $score <= 35) {
|
|
||||||
return 'D';
|
|
||||||
}
|
|
||||||
if ($score >= 36 && $score <= 55) {
|
|
||||||
return 'E';
|
|
||||||
}
|
|
||||||
if ($score >= 56 && $score <= 80) {
|
|
||||||
return 'F';
|
|
||||||
}
|
|
||||||
if ($score > 80) {
|
|
||||||
return 'G';
|
|
||||||
}
|
|
||||||
|
|
||||||
return 'Inconnu';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param \App\ParsedHome $parsed_home
|
|
||||||
* @param \Symfony\Component\DomCrawler\Crawler $crawler
|
|
||||||
*
|
|
||||||
* @return \App\ParsedHome
|
|
||||||
*/
|
|
||||||
private function parseJSON(ParsedHome $parsed_home, Crawler $crawler)
|
|
||||||
{
|
|
||||||
$data_estate = $crawler->filter('[data-estate]');
|
|
||||||
try {
|
|
||||||
$json_data = json_decode($data_estate->attr('data-estate'), true);
|
|
||||||
$parsed_home->price = $json_data['price'];
|
|
||||||
$parsed_home->city = $json_data['city']['name'];
|
|
||||||
$parsed_home->surface = $json_data['surface'];
|
|
||||||
$parsed_home->garden_surface = $json_data['lotSurface'];
|
|
||||||
$parsed_home->rooms = $json_data['nbRooms'];
|
|
||||||
$parsed_home->description = $json_data['longAd'];
|
|
||||||
$parsed_home->title = $json_data['seo']['metaTitle'];
|
|
||||||
$parsed_home->map = ['lat' => $json_data['latitude'], 'lng' => $json_data['longitude']];
|
|
||||||
$parsed_home->pictures = $json_data['imagesFull'];
|
|
||||||
$parsed_home->energy = $this->calculateDPE($json_data['consumptionValue']);
|
|
||||||
$parsed_home->ges = $this->calculateGES($json_data['emissionValue']);
|
|
||||||
|
|
||||||
return $parsed_home;
|
|
||||||
} catch (InvalidArgumentException $e) {
|
|
||||||
return $this->parseHTML($parsed_home, $crawler);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param \App\ParsedHome $parsed_home
|
|
||||||
* @param \Symfony\Component\DomCrawler\Crawler $crawler
|
|
||||||
*
|
|
||||||
* @return \App\ParsedHome
|
|
||||||
*/
|
|
||||||
private function parseHTML(ParsedHome $parsed_home, Crawler $crawler)
|
|
||||||
{
|
|
||||||
$ad = $crawler->filter('article');
|
|
||||||
$first_section = $ad->children()->first();
|
|
||||||
$second_section = $ad->children()->eq(1);
|
|
||||||
$third_section = $ad->children()->eq(2);
|
|
||||||
$parsed_home->description = $second_section->filter('.o-container')->children()->eq(1)->text();
|
|
||||||
$second_section->filter('.c-badge__text')->each(static function (Crawler $detail, $i) use (&$parsed_home) {
|
|
||||||
$detail_text = $detail->text();
|
|
||||||
if (mb_strpos($detail_text, 'Terrain') === 0) {
|
|
||||||
$parsed_home->garden_surface = mb_substr($detail_text, 8, -2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mb_strpos($detail_text, 'pièces') !== false) {
|
|
||||||
$parsed_home->rooms = (int)$detail_text;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
$h1 = $first_section->filter('h1');
|
|
||||||
$parsed_home->title = $h1->children()->first()->text();
|
|
||||||
$parsed_home->surface = (int)$h1->children()->eq(2)->text();
|
|
||||||
$parsed_home->city = $h1->children()->eq(4)->text();
|
|
||||||
$parsed_home->price = (int)str_replace(' ', '', $first_section->filter('.u-h1')->text());
|
|
||||||
$third_section->filter('.c-dpe')->each(static function (Crawler $detail, $i) use (&$parsed_home) {
|
|
||||||
$abbr = $detail->filter('abbr');
|
|
||||||
if ($abbr->count() > 0) {
|
|
||||||
if ($detail->attr('c-dpe--ges') !== null) {
|
|
||||||
$parsed_home->ges = $abbr->text();
|
|
||||||
} elseif ($detail) {
|
|
||||||
$parsed_home->energy = $abbr->text();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$request = $this->client->get($this->url.'/photos/');
|
|
||||||
$body = $request->getBody()->getContents();
|
|
||||||
$crawler = new Crawler($body);
|
|
||||||
$parsed_home->pictures = $crawler
|
|
||||||
->filter('.u-cover')
|
|
||||||
->each(static function (Crawler $node, $i) {
|
|
||||||
if (strtolower($node->nodeName()) === 'img') {
|
|
||||||
return $node->attr('src');
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
|
|
||||||
return $parsed_home;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Providers;
|
namespace App\Providers;
|
||||||
|
|
||||||
|
use Illuminate\Pagination\Paginator;
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
@@ -34,5 +35,6 @@ class AppServiceProvider extends ServiceProvider
|
|||||||
}
|
}
|
||||||
return sprintf('%s m²', number_format($surface, 0, ',', ' '));
|
return sprintf('%s m²', number_format($surface, 0, ',', ' '));
|
||||||
});
|
});
|
||||||
|
Paginator::useBootstrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -8,27 +8,27 @@
|
|||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^7.2.5",
|
"php": "^7.3.0",
|
||||||
"ext-json": "*",
|
"ext-json": "*",
|
||||||
"absmoca/leboncoin": "dev-master",
|
"absmoca/leboncoin": "dev-master",
|
||||||
"artesaos/seotools": "^0.18.0",
|
"artesaos/seotools": "^0",
|
||||||
"emanueleminotto/simple-html-dom": "^1.5",
|
"emanueleminotto/simple-html-dom": "^1.5",
|
||||||
"fabpot/goutte": "^3.1",
|
"fabpot/goutte": "^4.0",
|
||||||
"fideloper/proxy": "^4.2",
|
"fideloper/proxy": "^4.2",
|
||||||
"fruitcake/laravel-cors": "^2.0",
|
"fruitcake/laravel-cors": "^2.0",
|
||||||
"guzzlehttp/guzzle": "^6.3",
|
"guzzlehttp/guzzle": "^7.0.1",
|
||||||
"laravel/framework": "^7.0",
|
"laravel/framework": "^8.0",
|
||||||
"laravel/tinker": "^2.0",
|
"laravel/tinker": "^2.0",
|
||||||
"laravel/ui": "^2.1",
|
"laravel/ui": "^3.0",
|
||||||
"spatie/laravel-feed": "^2.7",
|
"spatie/laravel-feed": "^2.7",
|
||||||
"spatie/laravel-query-builder": "^2.8"
|
"spatie/laravel-query-builder": "^2.8"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"facade/ignition": "^2.0",
|
"facade/ignition": "^2.3.6",
|
||||||
"fzaninotto/faker": "^1.9.1",
|
"fzaninotto/faker": "^1.9.1",
|
||||||
"mockery/mockery": "^1.3.1",
|
"mockery/mockery": "^1.3.1",
|
||||||
"nunomaduro/collision": "^4.1",
|
"nunomaduro/collision": "^5.0",
|
||||||
"phpunit/phpunit": "^8.5"
|
"phpunit/phpunit": "^9.0"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"optimize-autoloader": true,
|
"optimize-autoloader": true,
|
||||||
@@ -42,7 +42,9 @@
|
|||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
"App\\": "app/"
|
"App\\": "app/",
|
||||||
|
"Database\\Factories\\": "database/factories/",
|
||||||
|
"Database\\Seeders\\": "database/seeders/"
|
||||||
},
|
},
|
||||||
"classmap": [
|
"classmap": [
|
||||||
"database/seeds",
|
"database/seeds",
|
||||||
|
2137
composer.lock
generated
2137
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,6 @@
|
|||||||
use App\Parser\ImmobilierNotaires;
|
use App\Parser\ImmobilierNotaires;
|
||||||
use App\Parser\LannionImmo;
|
use App\Parser\LannionImmo;
|
||||||
use App\Parser\LBC;
|
use App\Parser\LBC;
|
||||||
use App\Parser\Orpi;
|
|
||||||
use App\Parser\OuestFrance;
|
use App\Parser\OuestFrance;
|
||||||
use App\Parser\Pap;
|
use App\Parser\Pap;
|
||||||
use App\Parser\SeLoger;
|
use App\Parser\SeLoger;
|
||||||
@@ -15,7 +14,6 @@ return [
|
|||||||
'pap.fr' => Pap::class,
|
'pap.fr' => Pap::class,
|
||||||
'ouestfrance-immo.com' => OuestFrance::class,
|
'ouestfrance-immo.com' => OuestFrance::class,
|
||||||
'lannion.immo' => LannionImmo::class,
|
'lannion.immo' => LannionImmo::class,
|
||||||
'immobilier.notaires.fr'=> ImmobilierNotaires::class,
|
'immobilier.notaires.fr'=> ImmobilierNotaires::class
|
||||||
'orpi.com' => Orpi::class
|
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
@@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Factories;
|
||||||
|
|
||||||
/** @var \Illuminate\Database\Eloquent\Factory $factory */
|
/** @var \Illuminate\Database\Eloquent\Factory $factory */
|
||||||
|
|
||||||
use App\User;
|
use App\User;
|
||||||
|
@@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class UpdateFailedJobsLaravel8 extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('failed_jobs', function (Blueprint $table) {
|
||||||
|
$table->string('uuid')->after('id')->nullable()->unique();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('failed_jobs', static function (Blueprint $table) {
|
||||||
|
$table->dropColumn('uuid');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Seeders;
|
||||||
|
|
||||||
use Illuminate\Database\Seeder;
|
use Illuminate\Database\Seeder;
|
||||||
|
|
||||||
class DatabaseSeeder extends Seeder
|
class DatabaseSeeder extends Seeder
|
@@ -9,6 +9,10 @@
|
|||||||
|
|
||||||
define('LARAVEL_START', microtime(true));
|
define('LARAVEL_START', microtime(true));
|
||||||
|
|
||||||
|
if (file_exists(__DIR__.'/../storage/framework/maintenance.php')) {
|
||||||
|
require __DIR__.'/../storage/framework/maintenance.php';
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Register The Auto Loader
|
| Register The Auto Loader
|
||||||
|
Reference in New Issue
Block a user