diff --git a/app/Commands/Collect.php b/app/Commands/Collect.php index 9ccffe6..f43452c 100644 --- a/app/Commands/Collect.php +++ b/app/Commands/Collect.php @@ -40,8 +40,8 @@ class Collect extends Command 'Steam', 'Kvester', 'Urq', - /* 'Instory', + /* 'Textadventures', 'vndb', 'Dashingdon', diff --git a/app/Downloader.php b/app/Downloader.php index e18df5d..3be8ed8 100644 --- a/app/Downloader.php +++ b/app/Downloader.php @@ -87,4 +87,54 @@ class Downloader { $text = (string) $response->getBody(); return json_decode($text); } + + /** + * @param string $dateString + * @return \DateTime|false + */ + public function convertDate($dateString) { + $months = [ + 'янв.' => 'Jan', + 'янв' => 'Jan', + 'февр.' => 'Feb', + 'февр' => 'Feb', + 'фев' => 'Feb', + 'мар.' => 'Mar', + 'мар' => 'Mar', + 'апр.' => 'Apr', + 'апр' => 'Apr', + 'мая' => 'May', + 'май' => 'May', + 'июн.' => 'Jun', + 'июн' => 'Jun', + 'июня' => 'Jun', + 'июнь' => 'Jun', + 'июль' => 'Jul', + 'июл.' => 'Jul', + 'июля' => 'Jul', + 'июл' => 'Jul', + 'авг.' => 'Aug', + 'авг' => 'Aug', + 'сент.' => 'Sep', + 'сент' => 'Sep', + 'сен.' => 'Sep', + 'сен' => 'Sep', + 'окт.' => 'Oct', + 'окт' => 'Oct', + 'ноябр.' => 'Nov', + 'нояб.' => 'Nov', + 'нояб' => 'Nov', + 'ноя.' => 'Nov', + 'ноя' => 'Nov', + 'нов.' => 'Nov', + 'нов' => 'Nov', + 'дек.' => 'Dec', + 'дек' => 'Dec', + ]; + foreach ($months as $ru => $en) { + $dateString = str_replace($ru, $en, $dateString); + } + $retval = new \DateTime($dateString); + return $retval; + } } diff --git a/app/Sources/Instory.php b/app/Sources/Instory.php index 6cd906c..1c6da7c 100644 --- a/app/Sources/Instory.php +++ b/app/Sources/Instory.php @@ -19,67 +19,82 @@ namespace App\Sources; use \App\Models\Game; +use \App\Models\Language; +use \App\Models\Tag; +use \App\Models\Author; +use \App\Models\Platform; use \App\Source; class Instory extends Source { public $title = "Instory"; + public $keyword = 'instory'; + public $platform = 'Instory'; public function parse() { - $this->parseFeed('http://instory.su/feed/'); + $this->parseIndex('https://instory.su/catalog/sandbox'); + $this->parseIndex('https://instory.su/catalog'); } - public function parseFeed($feedUrl) { + public function parseIndex($feedUrl) { $string = $this->get_text($feedUrl); $string = mb_convert_encoding($string, 'UTF-8', 'auto'); - $service = new \Sabre\Xml\Service(); - $service->elementMap = [ - '{}item' => function(\Sabre\Xml\Reader $reader) { - return \Sabre\Xml\Deserializer\keyValue($reader, ''); - }, - '{}channel' => function(\Sabre\Xml\Reader $reader) { - return \Sabre\Xml\Deserializer\repeatingElements($reader, '{}item'); - }, - ]; - try { - $games = $service->parse($string)[0]['value']; - } catch (\Sabre\Xml\LibXMLException $e) { - echo $e->getMessage(); - echo $e->getTraceAsString(); - return ""; - } + $this->loadStr($string); unset($string); - foreach ($games as $gameBlock) { - $date = strtotime($gameBlock['pubDate']); - // TODO abort if pubdate equals to last parsed game + + $this->dom->filter('.container .at-card')->each(functioN($gameBlock) { $game = new Game; - $game->title = trim($gameBlock['title']); - $game->url = trim($gameBlock['link']); - $game->description = trim($gameBlock['description']); - $game->author = trim($gameBlock['{http://purl.org/dc/elements/1.1/}creator']); - $this->saveGame($game); - } + $game->title = trim($gameBlock->filter('h5')->text()); + $game->url = 'https://instory.su'.trim($gameBlock->filter('h5 a')->attr('href')); + $game->description = trim($gameBlock->filter('.post-card__excerpt')->html()); + $game->release_date = $this->downloader->convertDate($gameBlock->filter('.at-author__extend span')->text()); + $game = $this->findGame($game); + $author = trim($gameBlock->filter('.at-author__name a')->text()); + $game->save(); + + $tags = []; + $gameBlock->filter('.at-badge--cats .at-badge__content')->each(function($tag) use(&$tags){ + $tags[] = trim($tag->text()); + }); + + $language = Language::findByCode('ru'); + if (!$game->languages()->where('code', 'ru')->exists()) { + $game->languages()->attach($language); + } + + foreach ($tags as $tag) { + $model = Tag::where('language_id', $language->id) + ->where('title', $tag) + ->first(); + if (!$model) { + $model = new Tag(); + $model->language_id = $language->id; + $model->title = $tag; + $model->save(); + } + $game->tags()->attach($model); + } + + $model = Platform::where('title', $this->platform)->first(); + if (!$model) { + $model = new Platform(); + $model->title = $this->platform; + $model->save(); + } + $game->platforms()->attach($model); + + if (!empty($author)) { + $author_model = Author::findByName($author); + if (empty($author_model)) { + $author_model = new Author(); + $author_model->name = $author; + $author_model->save(); + } + if (!$game->authors()->where('name', $author)->exists()) { + $game->authors()->attach($author_model); + } + } + + }); } public function checkPage($url) { - return (strpos($url,'http://instory.top/') !== FALSE); + return (strpos($url,'//instory.su/') !== FALSE); } - public function page($url) { - $text = $this->get_text($url); - $this->loadStr($text); - unset($text); - $game = new Game; - $game->url = $url; - $author = trim($this->dom->filter('.elementor-author-box__name')->first()->text()); - $date = $this->dom->filter('.elementor-icon-list-text.elementor-post-info__item.elementor-post-info__item--type-date')->first()->text(); - $date = str_replace('Дата:', '', $date); - $date = str_replace(' в', '', $date); - $date = new \DateTime($date); - $title = $this->dom->filter('.elementor-heading-title.elementor-size-medium')->first(); - if ($title->count() > 0) { - $game->title = htmlspecialchars_decode($title->text()); - } - $game->image = $this->dom->filter('.elementor-image > a')->first()->getAttribute('href'); - $game->description = $this->dom->filter('.elementor-widget.elementor-widget-theme-post-content > div')->first()->text(); - $game->description = str_replace($this->dom->filter('.elementor-widget.elementor-widget-theme-post-content .rcl-rating-box')->first()->text(), '', $game->description); - $game->description = trim($game->description); - return $game; - } - }