diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index a8c5158..d8746fd 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -2,6 +2,7 @@ namespace App\Console; +use App\Jobs\UpdateConstellations; use Illuminate\Console\Scheduling\Schedule; use Illuminate\Foundation\Console\Kernel as ConsoleKernel; @@ -24,8 +25,9 @@ class Kernel extends ConsoleKernel */ protected function schedule(Schedule $schedule) { - // $schedule->command('inspire') - // ->hourly(); + $schedule->call(function(){ + dispatch(app(UpdateConstellations::class))->onQueue('updateConstellations'); + })->hourly(); } /** diff --git a/app/Constellation.php b/app/Constellation.php new file mode 100644 index 0000000..9a43477 --- /dev/null +++ b/app/Constellation.php @@ -0,0 +1,20 @@ +orderBy('date', 'DESC') + ->get([ + DB::raw('Date(created_at) as date') + ])->pluck('date'); + + $queriedDate = $request->get('date'); + if(!$queriedDate) { + $queriedDate = $dates->first(); + } + + $constellations = Constellation::whereDate('created_at', $queriedDate)->get(); + + return view('constellations')->with([ + 'dates' => $dates, + 'queriedDate' => $queriedDate, + 'constellations' => $constellations + ]); + } } diff --git a/app/Jobs/UpdateConstellations.php b/app/Jobs/UpdateConstellations.php new file mode 100644 index 0000000..e2b67a4 --- /dev/null +++ b/app/Jobs/UpdateConstellations.php @@ -0,0 +1,55 @@ +getConstellations() as $name => $constellation) { + $existedConstellation = Constellation::where('name', $name)->whereDate('created_at', Carbon::today())->first(); + if(!$existedConstellation) { + $constellation = Constellation::create([ + 'name' => $name, + 'all' => $constellation['all'], + 'all_desc' => $constellation['all_desc'], + 'love' => $constellation['love'], + 'love_desc' => $constellation['love_desc'], + 'career' => $constellation['career'], + 'career_desc' => $constellation['career_desc'], + 'income' => $constellation['income'], + 'income_desc' => $constellation['income_desc'], + ]); + Log::info("{$constellation->name} updated"); + } + } + } +} diff --git a/app/Services/ConstellationCrawler.php b/app/Services/ConstellationCrawler.php new file mode 100644 index 0000000..c1d2f6e --- /dev/null +++ b/app/Services/ConstellationCrawler.php @@ -0,0 +1,157 @@ + 0, + 'Taurus' => 1, + 'Gemini' => 2, + 'Cancer' => 3, + 'Leo' => 4, + 'Virgo' => 5, + 'Libra' => 6, + 'Scorpio' => 7, + 'Sagittarius' => 8, + 'Capricorn' => 9, + 'Aquarius' => 10, + 'Pisces' => 11, + ]; + + private function getHtml($pageId = 0) + { + $httpClient = new Client; + $resp = $httpClient->request('GET', $this->baseUrl . '?' . http_build_query([ + 'iAstro' => $pageId, + 'iAcDay' => Carbon::now()->format('Y-m-d') + ])); + if($resp->getStatusCode() == 200) { + return $resp->getBody()->getContents(); + } else { + return ''; + } + } + + private function removeEscapeSign($str) + { + return str_replace('\\', '', $str); + } + + private function parseHtml($html) + { + $matches = []; + $entryPattern = '
'; + + $htmlPatterns = [ + [ + 'pattern' => '

', + ], + [ + 'pattern' => '<\/span><\/p>', + 'name' => 'all', + 'type' => 'level' + ], + [ + 'pattern' => '

' + ], + [ + 'pattern' => '<\/p>', + 'name' => 'all_desc', + 'type' => 'text' + ], + [ + 'pattern' => '

', + ], + [ + 'pattern' => '<\/span><\/p>', + 'name' => 'love', + 'type' => 'level' + ], + [ + 'pattern' => '

' + ], + [ + 'pattern' => '<\/p>', + 'name' => 'love_desc', + 'type' => 'text' + ], + [ + 'pattern' => '

', + ], + [ + 'pattern' => '<\/span><\/p>', + 'name' => 'career', + 'type' => 'level' + ], + [ + 'pattern' => '

' + ], + [ + 'pattern' => '<\/p>', + 'name' => 'career_desc', + 'type' => 'text' + ], + [ + 'pattern' => '

', + ], + [ + 'pattern' => '<\/span><\/p>', + 'name' => 'income', + 'type' => 'level' + ], + [ + 'pattern' => '

' + ], + [ + 'pattern' => '<\/p>', + 'name' => 'income_desc', + 'type' => 'text' + ], + ]; + + preg_match("/$entryPattern/", $html, $matches, PREG_OFFSET_CAPTURE); + + if(!empty($matches[0])) { + $offset = $matches[0][1]; + $html = trim(substr($html, $offset + strlen($entryPattern))); + $data = []; + + foreach ($htmlPatterns as $htmlPattern) { + preg_match("/{$htmlPattern['pattern']}/", $html, $matches, PREG_OFFSET_CAPTURE); + $offset = $matches[0][1]; + if(!empty($htmlPattern['type'])) { + if($htmlPattern['type'] == 'level') { + $rateText = substr($html, 0, $offset); + $starMatches = []; + preg_match('/★+/u', $rateText, $starMatches); + $rate = empty($starMatches[0]) ? 0 : mb_strlen($starMatches[0]); + $data[$htmlPattern['name']] = $rate; + } else if($htmlPattern['type'] == 'text') { + $data[$htmlPattern['name']] = substr($html, 0, $offset); + } + } + $html = trim(substr($html, $offset + strlen($this->removeEscapeSign($htmlPattern['pattern'])))); + } + return $data; + } else { + return null; + } + } + + public function getConstellations() + { + $data = []; + foreach ($this->constellationPageIds as $name => $constellationPageId) { + $html = $this->getHtml($constellationPageId); + $data[$name] = $this->parseHtml($html); + } + + return $data; + } +} diff --git a/composer.json b/composer.json index bc951b7..e0a463e 100644 --- a/composer.json +++ b/composer.json @@ -11,8 +11,10 @@ "php": "^7.2", "fideloper/proxy": "^4.0", "google/apiclient": "^2.4", + "guzzlehttp/guzzle": "^6.5", "laravel/framework": "^6.2", - "laravel/tinker": "^2.0" + "laravel/tinker": "^2.0", + "predis/predis": "^1.1" }, "require-dev": { "facade/ignition": "^1.4", diff --git a/composer.lock b/composer.lock index de9ab8d..037cdd3 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "f8c1c5bbfc814eceb05f09efe571e699", + "content-hash": "4d733788f8dc0c1f6d18ade50ac5fc42", "packages": [ { "name": "dnoegel/php-xdg-base-dir", @@ -1631,6 +1631,56 @@ ], "time": "2020-02-25T04:16:50+00:00" }, + { + "name": "predis/predis", + "version": "v1.1.1", + "source": { + "type": "git", + "url": "https://github.com/nrk/predis.git", + "reference": "f0210e38881631afeafb56ab43405a92cafd9fd1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nrk/predis/zipball/f0210e38881631afeafb56ab43405a92cafd9fd1", + "reference": "f0210e38881631afeafb56ab43405a92cafd9fd1", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "phpunit/phpunit": "~4.8" + }, + "suggest": { + "ext-curl": "Allows access to Webdis when paired with phpiredis", + "ext-phpiredis": "Allows faster serialization and deserialization of the Redis protocol" + }, + "type": "library", + "autoload": { + "psr-4": { + "Predis\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniele Alessandri", + "email": "suppakilla@gmail.com", + "homepage": "http://clorophilla.net" + } + ], + "description": "Flexible and feature-complete Redis client for PHP and HHVM", + "homepage": "http://github.com/nrk/predis", + "keywords": [ + "nosql", + "predis", + "redis" + ], + "time": "2016-06-16T16:22:20+00:00" + }, { "name": "psr/cache", "version": "1.0.1", diff --git a/database/migrations/2020_03_04_002130_create_constellations_table.php b/database/migrations/2020_03_04_002130_create_constellations_table.php new file mode 100644 index 0000000..dfe241b --- /dev/null +++ b/database/migrations/2020_03_04_002130_create_constellations_table.php @@ -0,0 +1,40 @@ +bigIncrements('id'); + $table->string('name', 11); + $table->unsignedTinyInteger('all'); + $table->text('all_desc'); + $table->unsignedTinyInteger('love'); + $table->text('love_desc'); + $table->unsignedTinyInteger('career'); + $table->text('career_desc'); + $table->unsignedTinyInteger('income'); + $table->text('income_desc'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('constellations'); + } +} diff --git a/public/fonts/vendor/font-awesome/fontawesome-webfont.eot b/public/fonts/vendor/font-awesome/fontawesome-webfont.eot new file mode 100644 index 0000000..e9f60ca Binary files /dev/null and b/public/fonts/vendor/font-awesome/fontawesome-webfont.eot differ diff --git a/public/fonts/vendor/font-awesome/fontawesome-webfont.svg b/public/fonts/vendor/font-awesome/fontawesome-webfont.svg new file mode 100644 index 0000000..855c845 --- /dev/null +++ b/public/fonts/vendor/font-awesome/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/fonts/vendor/font-awesome/fontawesome-webfont.ttf b/public/fonts/vendor/font-awesome/fontawesome-webfont.ttf new file mode 100644 index 0000000..35acda2 Binary files /dev/null and b/public/fonts/vendor/font-awesome/fontawesome-webfont.ttf differ diff --git a/public/fonts/vendor/font-awesome/fontawesome-webfont.woff b/public/fonts/vendor/font-awesome/fontawesome-webfont.woff new file mode 100644 index 0000000..400014a Binary files /dev/null and b/public/fonts/vendor/font-awesome/fontawesome-webfont.woff differ diff --git a/public/fonts/vendor/font-awesome/fontawesome-webfont.woff2 b/public/fonts/vendor/font-awesome/fontawesome-webfont.woff2 new file mode 100644 index 0000000..4d13fc6 Binary files /dev/null and b/public/fonts/vendor/font-awesome/fontawesome-webfont.woff2 differ diff --git a/resources/views/constellations.blade.php b/resources/views/constellations.blade.php new file mode 100644 index 0000000..6c81ed1 --- /dev/null +++ b/resources/views/constellations.blade.php @@ -0,0 +1,55 @@ +@extends('layouts.app') + +@section('content') +

+
+
+
+
+ + +
+
+
+
+
+
+ + + + + + + + + + + + + + + + @foreach($constellations as $constellation) + + + + + + + + + + + + @endforeach + +
名稱整體運勢整理運勢說明愛情運勢愛情運勢說明事業運勢事業運勢說明財運運勢財運運勢說明
{{ $constellation->name }}{{ $constellation->all }}{{ $constellation->all_desc }}{{ $constellation->love }}{{ $constellation->love_desc }}{{ $constellation->career }}{{ $constellation->career_desc }}{{ $constellation->income }}{{ $constellation->income_desc }}
+
+
+
+ +@endsection diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php index 94737c6..5c62f90 100644 --- a/resources/views/layouts/app.blade.php +++ b/resources/views/layouts/app.blade.php @@ -37,7 +37,9 @@