. */ namespace Oreolek\Source; use \Oreolek\Game; use \Oreolek\Source; use \Pandoc\Pandoc; class Itch extends Source { public $title = "Itch.io"; public $queue = []; public $games = []; public $print_description = FALSE; protected function parse_tag($url) { $max_pages = 4; // load 30*4 = 120 latest games for ($i = 1; $i <= $max_pages; $i++) { $cururl = $url.'?format=json&page='.$i; $text = $this->get_json($cururl); $this->loadStr($text->content); $this->dom->filter('.game_cell')->each(function($cell) { $game = new Game; $game->url = $cell->filter('a.game_link')->attr('href'); $game->title = $cell->filter('a.title')->text(); $game->author = $cell->filter('.game_author')->text(); $game->image = $cell->filter('.game_thumb')->attr('data-background_image'); $this->queue[] = $game; }); if ($text->num_items < 30) { // less than default number of games, probably last page break; } } } protected function parse() { global $argv; if (!$this->period instanceof \DateTime) { $this->period = new \DateTime('@'.$this->period); } if (isset($argv[2])) { $game_page = $this->get_text($argv[2]); $this->loadStr($game_page, []); $this->output .= $this->page($argv[2])->print(); } else { $this->parse_tag("https://itch.io/games/newest/tag-text-based"); $this->parse_tag("https://itch.io/games/newest/tag-twine"); $this->parse_tag("https://itch.io/games/newest/tag-interactive-fiction"); $this->queue = array_unique($this->queue); foreach ($this->queue as $game) { $game_page = $this->get_text($game->url); $this->loadStr($game_page, []); $game = $this->page($game->url); if ($game->date < $this->period) { continue; } $this->games[] = $game->print(); } $this->games = array_unique($this->games); foreach ($this->games as $game) { $this->output .= $game; } } } public function checkPage($url) { return (strpos($url,'.itch.io/') !== FALSE); } public function page($url) { $game = new Game; $game->url = $url; $title = trim($this->dom->filter("title")->first()->text()); [$game->title, $game->author] = explode(' by ', $title); unset($title); $this->dom->filter('script[type="application/ld+json"]')->each(function($script) use(&$game) { $data = json_decode($script->html()); if ($data === false) { return; } if ($data->{'@type'} === 'Product') { if (isset($data->description)) { $game->short_description = $data->description; } if (isset($data->name)) { $game->title = $data->name; } if (isset($data->offers) && isset($data->offers->seller)) { $game->author = $data->offers->seller->name; } } }); $date = $this->dom->filter('td abbr'); if ($date->count() > 0) { $date = $date->first()->attr('title'); $date = str_replace('@', '', $date); $game->date = new \DateTime($date); } if ($this->print_description) { $desc = $this->dom->filter('.formatted_description'); try { $game->description = trim($desc->first()->html()); } catch (\Throwable $e) { } if (empty($game->short_description)) { $converter = new Pandoc(); $description = $converter->convert($game->description, 'html', 'mediawiki'); $description = explode(' ',$description); // 50 first words $game->short_description = implode(' ', array_slice($description, 0, 50)); } } return $game; } }