Archived
1
0
Fork 0

WIP parsing

This commit is contained in:
Alexander Yakovlev 2019-09-13 00:03:56 +07:00
parent 0d859b6e8f
commit f73d5bb412
Signed by: oreolek
GPG key ID: 1CDC4B7820C93BD3
33 changed files with 2897 additions and 171 deletions

View file

@ -1 +1,21 @@
CONSUMER_KEY=
DRY_RUN=false
DEBUG=false
MASTODON_ACCESS_TOKEN=
MASTODON_SERVER=https://botsin.space
MASTODON_USER=ifnews_eng
TELEGRAM_API_KEY=somekey
TELEGRAM_BOT_NAME=somekey
TELEGRAM_CHAT_ID=someid
BITLY_TOKEN=
WIKI=https://ifwiki.ru/api.php
WIKIUSER=maibot
WIKIPASSWORD=
DB_CONNECTION=mysql
DB_HOST=localhost
DB_USERNAME=
DB_PASSWORD=
DB_PORT=3306
DB_DATABASE=ifgames

77
app/Commands/Collect.php Normal file
View file

@ -0,0 +1,77 @@
<?php
namespace App\Commands;
use Illuminate\Console\Scheduling\Schedule;
use LaravelZero\Framework\Commands\Command;
use Log;
class Collect extends Command
{
/**
* The signature of the command.
*
* @var string
*/
protected $signature = 'collect';
/**
* The description of the command.
*
* @var string
*/
protected $description = 'Collect info about new games';
/**
* List of parsers to run.
*
* @var array
*/
protected $parsers = [
'Urq',
'Anivisual',
'Kvester',
//'vndb',
'Apero',
'Instory',
// 'instead',
'Hyperbook',
'HyperbookEn',
'Questbook',
'Textadventures',
'IFDB',
'Dashingdon',
'Itch',
'Gamejolt',
'Steam',
];
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
foreach ($this->parsers as $parser) {
$cname = 'App\\Sources\\'.$parser;
try {
(new $cname())->parse();
} catch (\Exception $e) {
Log::error($e->getMessage());
Log::debug($e->getTraceAsString());
}
}
}
/**
* Define the command's schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
public function schedule(Schedule $schedule): void
{
$schedule->command(static::class)->daily();
}
}

View file

@ -1,44 +0,0 @@
<?php
namespace App\Commands;
use Illuminate\Console\Scheduling\Schedule;
use LaravelZero\Framework\Commands\Command;
class InspiringCommand extends Command
{
/**
* The signature of the command.
*
* @var string
*/
protected $signature = 'inspiring {name=Artisan}';
/**
* The description of the command.
*
* @var string
*/
protected $description = 'Display an inspiring quote';
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$this->info('Simplicity is the ultimate sophistication.');
}
/**
* Define the command's schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
public function schedule(Schedule $schedule)
{
// $schedule->command(static::class)->everyMinute();
}
}

45
app/Downloader.php Normal file
View file

@ -0,0 +1,45 @@
<?php
/*
A set of utilities for tracking text-based game releases
Copyright (C) 2017 Alexander Yakovlev
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace App;
class Downloader {
public static function get_text($url) {
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $url,
));
$resp = curl_exec($curl);
curl_close($curl);
return $resp;
}
public static function download($url, $outFile) {
$options = array(
CURLOPT_FILE => fopen($outFile, 'w'),
CURLOPT_TIMEOUT => 28800, // set this to 8 hours so we dont timeout on big files
CURLOPT_URL => $url
);
$ch = curl_init();
curl_setopt_array($ch, $options);
curl_exec($ch);
curl_close($ch);
}
}

15
app/Models/Author.php Normal file
View file

@ -0,0 +1,15 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use App\Models\Game;
class Author extends Model
{
protected $table = 'authors';
public function games() {
return $this->belongsToMany(Game::class, 'authors_games');
}
}

30
app/Models/Game.php Normal file
View file

@ -0,0 +1,30 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use App\Models\Author;
use App\Models\Language;
use App\Models\Tag;
use App\Models\Platform;
class Game extends Model
{
protected $table = 'games';
public function authors() {
return $this->belongsToMany(Author::class, 'authors_games');
}
public function languages() {
return $this->belongsToMany(Language::class, 'languages_games');
}
public function tags() {
return $this->belongsToMany(Tag::class, 'tags_games');
}
public function platform() {
return $this->hasOne(Platform::class);
}
}

20
app/Models/Language.php Normal file
View file

@ -0,0 +1,20 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use App\Models\Game;
use App\Models\Tag;
class Language extends Model
{
protected $table = 'languages';
public function games() {
return $this->belongsToMany(Game::class, 'languages_games');
}
public function tags() {
return $this->hasMany(Tag::class);
}
}

13
app/Models/Platform.php Normal file
View file

@ -0,0 +1,13 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use App\Models\Game;
class Platform extends Model
{
public function games() {
return $this->hasMany(Game::class);
}
}

18
app/Models/Tag.php Normal file
View file

@ -0,0 +1,18 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use App\Models\Language;
use App\Models\Game;
class Tag extends Model
{
public function language() {
return $this->belongsTo(Language::class);
}
public function games() {
return $this->belongsToMany(Game::class, 'tags_games');
}
}

View file

@ -6,23 +6,23 @@ use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
//
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
//
}
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
}

96
app/Source.php Normal file
View file

@ -0,0 +1,96 @@
<?php
/*
A set of utilities for tracking text-based game releases
Copyright (C) 2017-2018 Alexander Yakovlev
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace App;
use \Symfony\Component\DomCrawler\Crawler;
use \GuzzleHttp\Client as GuzzleClient;
use App\Models\Game;
abstract class Source {
// Title
public $title;
// Optional warning or note
public $warning = FALSE;
protected $dom;
protected $cookies = '';
/**
* Should be load the page before the parsing or during
*
* @var boolean
*/
public $delayedLoad = false;
public function loadStr($html) {
$this->dom = new Crawler($html);
}
abstract protected function parse();
/**
* System function to download page HTML.
*
* @return string
*/
public function get_text($url, $post = []) {
$client = new GuzzleClient([
'timeout' => 30,
]);
if ($post === []) {
$response = $client->request('GET', $url, [
'cookies' => $this->cookies,
]);
} else {
$response = $client->request('POST', $url, [
'form_params' => $post,
'cookies' => $this->cookies,
]);
}
return (string) $response->getBody();
}
/**
* GET JSON data.
*/
public function get_json($url) {
$client = new GuzzleClient([
'timeout' => 30,
]);
$response = $client->request('GET', $url, [
'cookies' => $this->cookies,
]);
$text = (string) $response->getBody();
return json_decode($text);
}
/**
* Check if URL corresponds to this source.
*
* @return boolean
*/
public function checkPage($url) {
return false;
}
/**
* Save the game if not a duplicate.
*/
protected function saveGame(Game $game) {
$game->save();
}
}

113
app/Sources/Anivisual.php Normal file
View file

@ -0,0 +1,113 @@
<?php
/*
A set of utilities for tracking text-based game releases
Copyright (C) 2017-2018 Alexander Yakovlev
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace App\Sources;
use \App\Models\Game;
use \App\Source;
class Anivisual extends Source {
public $title = "Anivisual";
protected $months = [
'Января' => 'January',
'Февраля' => 'February',
'Марта' => 'March',
'Апреля' => 'April',
'Мая' => 'May',
'Июня' => 'June',
'Июля' => 'July',
'Августа' => 'August',
'Сентября' => 'September',
'Октября' => 'October',
'Ноября' => 'November',
'Декабря' => 'December',
];
protected function parse() {
$text = $this->get_text('http://anivisual.net/stuff/1');
$this->loadStr($text);
unset($text);
$this->dom->filter('.entryBlock')->each(function($gameBlock) {
$date = trim($gameBlock->filter('.icon-calendar')->text());
foreach ($this->months as $ruM => $enM) {
$date = str_replace($ruM, $enM, $date);
}
$date = \DateTime::createFromFormat('d F Y', $date);
$game->date = $date;
$link = $gameBlock->filter('.novel-ttl a')->first();
$link = 'http://anivisual.net'.$link->attr('href');
$game = $this->page($link);
//$game = new Game;
//$game->title = htmlspecialchars_decode($link->html());
//$game->url = 'http://anivisual.net'.$link->attr('href');
//$game->description = $gameBlock->filter('span')->first()->text();
$this->saveGame($game);
});
}
public function checkPage($url) {
return (strpos($url,'://anivisual.net/stuff/') !== FALSE);
}
public function page($url) {
$text = $this->get_text($url);
$this->loadStr($text);
unset($text);
$game = new Game;
$game->url = $url;
$gameBlock = $this->dom->filter('#casing-box');
$dateBlock = $this->dom->filter('.icon-calendar');
$date = '';
if ($dateBlock->count() > 0) {
$date = trim($dateBlock->first()->text());
}
if (!empty($date)) {
foreach ($this->months as $ruM => $enM) {
$date = str_replace($ruM, $enM, $date);
}
$game->date = \DateTime::createFromFormat('d F Y', $date);
unset($date);
}
$title = $this->dom->filter('h1.logo')->first();
if ($title->count() > 0) {
$game->title = trim(htmlspecialchars_decode($title->text()));
}
$game->description = $this->dom->filter('#content > section > span')->first()->text();
$game->description = str_replace('(adsbygoogle = window.adsbygoogle || []).push({});', '', $game->description);
$game->description = str_replace('Доп. ссылки: Доступно только для пользователей', '', $game->description);
$game->description = trim($game->description);
$sidebar = $gameBlock->filter('#sidebar')->first()->html();
$pos_start = mb_strpos($sidebar, '<b>Автор:');
$sidebar_search = trim(mb_substr($sidebar, $pos_start));
$pos_end = mb_strpos($sidebar_search, '<br>');
$sidebar_search = trim(mb_substr($sidebar_search, 0, $pos_end));
$sidebar_search = str_replace('<b>Автор:</b>', '', $sidebar_search);
$game->author = trim(strip_tags($sidebar_search));
$pos_start = mb_strpos($sidebar, '<b>Перевод:');
$sidebar_search = trim(mb_substr($sidebar, $pos_start));
$pos_end = mb_strpos($sidebar_search, '<br>');
$sidebar_search = trim(mb_substr($sidebar_search, 0, $pos_end));
$sidebar_search = trim(strip_tags(str_replace('<b>Перевод:</b>', '', $sidebar_search)));
if ($sidebar_search !== '') {
$game->author .= ', пер. '.$sidebar_search;
}
return $game;
}
}

97
app/Sources/Apero.php Normal file
View file

@ -0,0 +1,97 @@
<?php
/*
A set of utilities for tracking text-based game releases
Copyright (C) 2017-2018 Alexander Yakovlev
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace App\Sources;
use \App\Models\Game;
use \App\Source;
/**
* Парсер для Apero.ru
* Проблема парсера в том, что на Аперо часто поломана кодировка UTF-8.
*/
class Apero extends Source {
public $title = "Apero";
protected function parse() {
$text = $this->get_text('http://apero.ru/Текстовые-игры/Песочница', [
'order_by' => 'by_public',
]);
$text = mb_convert_encoding($text, 'UTF-8', 'auto');
$this->loadStr($text);
$this->parseIndex();
$text = $this->get_text('http://apero.ru/Текстовые-игры', [
'order_by' => 'by_public',
]);
$text = mb_convert_encoding($text, 'UTF-8', 'auto');
$this->loadStr($text);
$this->parseIndex();
}
protected function parseIndex()
{
$this->dom->filter('.tabled-game-block')->each(function($gameBlock){
$formatter = new \IntlDateFormatter( 'ru', \IntlDateFormatter::LONG, \IntlDateFormatter::NONE );
$date = trim($gameBlock->filter('.game-updated-block')->text(), "() \t\n\r\0\x0B");
$date = str_replace('вчера', date('d.m.Y', strtotime('-1 day')), $date);
$date = $formatter->parse($date);
// TODO last date from last game from apero
$game = new Game;
$game->author = trim($gameBlock->filter('.game-author-block:first-child a')->text());
$game->title = trim($gameBlock->filter('h2 a')->first()->text());
$game->url = trim($gameBlock->filter('h2 a')->first()->attr('href'));
$game->description = trim($gameBlock->filter('.game-desc-block')->first()->text());
$this->saveGame($game);
});
}
public function checkPage($url) {
return (strpos($url,'http://apero.ru/') !== FALSE);
}
public function page($url) {
$game = new Game;
$game->url = $url;
$game->platform = 'Аперо';
$game->title = $this->dom->filter('dd')->reduce(function($block) {
if ($block->attr('itemprop') === 'name') {
return true;
}
return false;
})->text();
$game->author = [];
$this->dom->filter('dd a')->reduce(function($block){
if ($block->attr('itemprop') === 'author') {
return true;
}
return false;
})->each(function($block) use($game){
$game->author[] = $block->text();
});
$date = $this->dom->filter('meta')->reduce(function($block){
if ($block->attr('itemprop') === 'datePublished') {
return true;
}
return false;
})->first();
if ($date->count() > 0) {
$date = $date->attr('content');
} else {
$date = NULL;
}
$game->date = \DateTime::createFromFormat('Y-M-d', $date);
// TODO description
return $game;
}
}

45
app/Sources/Axma.php Normal file
View file

@ -0,0 +1,45 @@
<?php
/*
A set of utilities for tracking text-based game releases
Copyright (C) 2017-2018 Alexander Yakovlev
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace App\Sources;
use \App\Models\Game;
use \App\Source;
class Axma extends Source {
public $title = "Библиотека AXMA (самая новая)";
protected $games = array();
protected $rootUrl = 'https://axma.info/library/';
protected function parse() {
$i = 0;
$text = $this->get_text('https://axma.info/library/?sort=last&from='.$i);
$this->loadStr($text);
unset($text);
$this->dom->filter("#listPubs h3 a")->each(function($link) {
$game = new Game;
$game->title = $link->text();
$game->url = $link->attr('href');
$game->url = str_replace('file', $this->rootUrl.'/comments.php?id=', $game->url);
$this->saveGame($game);
});
$i += 5;
}
public function checkPage($url) {
return (strpos($url,$this->rootUrl) !== FALSE);
}
}

View file

@ -0,0 +1,34 @@
<?php
/*
A set of utilities for tracking text-based game releases
Copyright (C) 2017-2018 Alexander Yakovlev
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace App\Sources;
use \App\Models\Game;
use \App\Source;
/**
* And here's the problem: there are no publication dates.
*/
class Dashingdon extends Source {
public $title = "DashingDon";
protected function parse() {
$text = $this->get_text("https://dashingdon.com/screenreader/");
$this->loadStr($text);
unset($text);
}
}

55
app/Sources/Gamejolt.php Normal file
View file

@ -0,0 +1,55 @@
<?php
/*
A set of utilities for tracking text-based game releases
Copyright (C) 2017-2018 Alexander Yakovlev
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace App\Sources;
use \App\Models\Game;
use \App\Source;
class Gamejolt extends Source {
public $title = "GameJolt";
protected function parse_tag($url) {
$data = json_decode($this->get_text($url));
if (empty($data) or !isset($data->payload)) {
echo 'GameJolt data empty';
return;
}
$games = $data->payload->games;
if (count($games) > 0) {
foreach ($games as $gameData) {
$descUrl = 'https://gamejolt.com/site-api/web/discover/games/overview/'.$gameData->id;
$descData = json_decode($this->get_text($descUrl));
$game = new Game;
$game->title = $gameData->title;
$game->author = $gameData->developer->display_name;
$game->date = $gameData->published_on / 1000;
$game->description = $descData->payload->metaDescription;
$game->url = 'https://gamejolt.com/games/'.$gameData->slug.'/'.$gameData->id;
$this->saveGame($game);
}
}
}
protected function parse() {
try {
$this->parse_tag("https://gamejolt.com/site-api/web/library/games/tag/twine");
$this->parse_tag("https://gamejolt.com/site-api/web/library/games/tag/renpy");
$this->parse_tag("https://gamejolt.com/site-api/web/library/games/tag/text");
$this->parse_tag("https://gamejolt.com/site-api/web/library/games/tag/ascii");
} catch (\Exception $e) {}
}
}

92
app/Sources/Hyperbook.php Normal file
View file

@ -0,0 +1,92 @@
<?php
/*
A set of utilities for tracking text-based game releases
Copyright (C) 2017-2018 Alexander Yakovlev
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace App\Sources;
use \App\Models\Game;
use \App\Source;
class Hyperbook extends Source {
public $title = "Гиперкнига";
protected $games = array();
protected $rootUrl = 'http://hyperbook.ru';
protected function parse() {
$text = $this->get_text($this->rootUrl.'/lib.php?sort=time');
$this->loadStr($text);
unset($text);
$this->dom->filter("#listPubs h3 a")->each(function($link) {
$game = new Game;
$game->title = $link->text();
$game->url = $link->attr('href');
$game->url = str_replace('file', $this->rootUrl.'/comments.php?id=', $game->url);
$this->games[] = $game;
});
$this->dom->filter("#listPubs div")->reduce(function($node) {
if ($node->attr('style') === 'text-align:left;margin-bottom:4px;')
return true;
return false;
})->each(function($author, $i) {
$this->games[$i]->author = $author->text();
});
$this->dom->filter("#listPubs div")->reduce(function($node) {
if ($node->attr('style') === 'float: left; width: 20%; text-align:right;')
return true;
return false;
})->each(function($date, $i){
$this->games[$i]->date = $date->text();
});
$this->dom->filter("#listPubs div")->reduce(function($node) {
if ($node->attr('style') === NULL)
return true;
return false;
})->each(function($dsc, $i){
$this->games[$i]->description = $dsc->text();
});
foreach ($this->games as $game) {
$this->saveGame($game);
}
}
public function checkPage($url) {
return (strpos($url,$this->rootUrl.'/comments.php') !== FALSE);
}
public function page($url) {
$game = new Game;
$game->url = $url;
$game->platform = 'AXMA Story Maker';
$game->title = $this->dom->filter(".content h1")->first()->text();
$game->title = trim(str_replace($this->dom->filter("h1 span")->first()->text(), '', $game->title));
$game->author = $this->dom->filter(".content > div")->reduce(function($node) {
if ($node->attr('style') === 'float: left; width: 50%; margin-bottom:14px; text-align: left;') {
return true;
}
return false;
})->first()->text();
$game->date = $this->dom->filter(".content div.small")->reduce(function($node) {
if ($node->attr('style') === 'float: left; width: 20%; text-align:right;')
return true;
return false;
})->first()->text();
$game->description = $this->dom->filter(".content div.small")->reduce(function($node) {
if ($node->attr('style') === NULL)
return true;
return false;
})->first()->text();
$game->date = \DateTime::createFromFormat('d.m.y', $game->date);
return $game;
}
}

View file

@ -0,0 +1,28 @@
<?php
/*
A set of utilities for tracking text-based game releases
Copyright (C) 2017-2018 Alexander Yakovlev
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace App\Sources;
use \App\Models\Game;
use \App\Sources\Hyperbook;
use \App\Source;
class HyperbookEn extends Hyperbook {
public $title = "Гиперкнига";
protected $rootUrl = 'http://ifiction.net';
}

63
app/Sources/IFDB.php Normal file
View file

@ -0,0 +1,63 @@
<?php
/*
A set of utilities for tracking text-based game releases
Copyright (C) 2017-2018 Alexander Yakovlev
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace App\Sources;
use \App\Models\Game;
use \App\Source;
class IFDB extends Source {
public $title = "IFDB";
protected function parse() {
$service = new \Sabre\Xml\Service();
$xml = $this->get_text("http://ifdb.tads.org/allnew-rss");
$xml = tidy_repair_string($xml, [
'output-xml' => true,
'input-xml' => true
]);
$service->elementMap = [
'{}item' => function(\Sabre\Xml\Reader $reader) {
$game = new Game;
$keyValue = \Sabre\Xml\Deserializer\keyValue($reader, '{}item');
if (isset($keyValue['{}title'])) {
$title = $keyValue['{}title'];
if (strpos($title, 'A new listing') === FALSE)
return [];
$title = str_replace('A new listing for ', '', $title);
$title = explode(' by ', $title);
$game->title = $title[0];
if (isset($title[1])) {
$game->author = $title[1];
}
}
if (isset($keyValue['{}link'])) {
$game->url = $keyValue['{}link'];
}
if (isset($keyValue['{}description'])) {
$game->description = $keyValue['{}description'];
}
if (isset($keyValue['{}pubDate'])) {
$game->date = strtotime($keyValue['{}pubDate']);
}
$this->saveGame($game);
return $game;
},
];
$dom = $service->parse($xml);
}
}

81
app/Sources/Instead.php Normal file
View file

@ -0,0 +1,81 @@
<?php
/*
A set of utilities for tracking text-based game releases
Copyright (C) 2017-2018 Alexander Yakovlev
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace App\Sources;
use \App\Models\Game;
use \App\Source;
class Instead extends Source {
public $title = "INSTEAD репозиторий";
protected $baseUrl = 'http://instead-games.ru/';
protected function insteadfeed($url) {
$text = $this->get_text($url);
$this->loadStr($text);
unset($text);
$this->dom->filter('.game')->each(function($gameBlock) {
$date = trim($gameBlock->filter('.b .date b')->text());
$date = \DateTime::createFromFormat('Y.m.d', $date);
$date = $date->format('U');
$url = $this->baseUrl.trim($gameBlock->filter('h2:first-child a:first-child')->first()->attr('href'));
$game = $this->page($url);
$this->saveGame($game);
});
}
protected function parse() {
$this->insteadfeed("http://instead-games.ru/");
if (FORMAT === 'HTML') {
$this->output .= "<h5>Песочница</h5>\n";
} elseif (FORMAT === 'MARKDOWN') {
$this->output .= "##### Песочница\n";
}
$this->insteadfeed("http://instead-games.ru/index.php?approved=0");
}
public function checkPage($url) {
return (strpos($url,'http://instead-games.ru/game.php') !== FALSE);
}
public function page($url) {
$text = $this->get_text($url);
$this->loadStr($text);
unset($text);
$game = new Game;
$game->url = $url;
$game->platform = 'INSTEAD';
$text = trim($this->dom->filter('#panel')->text());
preg_match('/Дата: ([0-9]{4}\.[01][0-9]\.[0-3][0-9])Размер/', $text, $matches);
$game->date = \DateTime::createFromFormat('Y.m.d', $matches[1]);
preg_match('/Автор: (.+)Дата/', $text, $matches);
$game->author = trim($matches[1]);
$game->title = trim($this->dom->filter('h2')->first()->text());
$game->description = trim($this->dom->filter('.gamedsc')->first()->html());
if($this->dom->filter('#instead-em')->first()) {
$game->url_online = $this->baseUrl.$this->dom->filter('#instead-em')->attr('href');
$game->url_online_description = 'Играть онлайн';
}
$game->url_download = $this->baseUrl.ltrim($this->dom->selectLink('Скачать')->first()->attr('href'), '/');
$link = $this->dom->selectLink('Обсудить')->first();
if ($link->count() > 0) {
$game->url_discussion = $link->attr('href');
}
$image = $this->dom->filter('#screenshots a')->first();
if ($image->count() > 0) {
$game->image = $this->baseUrl.$image->attr('href');
}
return $game;
}
}

85
app/Sources/Instory.php Normal file
View file

@ -0,0 +1,85 @@
<?php
/*
A set of utilities for tracking text-based game releases
Copyright (C) 2017-2018 Alexander Yakovlev
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace App\Sources;
use \App\Models\Game;
use \App\Source;
class Instory extends Source {
public $title = "Instory";
protected function parse() {
$this->parseFeed('http://instory.su/feed/');
}
protected function parseFeed($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 "";
}
unset($string);
foreach ($games as $gameBlock) {
$date = strtotime($gameBlock['pubDate']);
if ($date < $this->period) continue;
$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->output .= $game->print();
}
}
public function checkPage($url) {
return (strpos($url,'http://instory.top/') !== 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;
}
}

124
app/Sources/Itch.php Normal file
View file

@ -0,0 +1,124 @@
<?php
/*
A set of utilities for tracking text-based game releases
Copyright (C) 2017-2018 Alexander Yakovlev
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace App\Sources;
use \App\Models\Game;
use \App\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 (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->saveGame($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;
}
}

76
app/Sources/Kvester.php Normal file
View file

@ -0,0 +1,76 @@
<?php
/*
A set of utilities for tracking text-based game releases
Copyright (C) 2017-2018 Alexander Yakovlev
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace App\Sources;
use \App\Models\Game;
use \App\Source;
class Kvester extends Source {
public $title = "Квестер";
protected $baseUrl = 'http://kvester.ru';
protected function parse() {
$text = $this->get_text($this->baseUrl."/catalog?sort=date");
$this->loadStr($text);
unset($text);
$this->dom->filter('.catalog-item')->each(function($gameBlock){
$date = trim($gameBlock->filter('.cell-2 .date')->text(), "() \t\n\r\0\x0B");
$date = \DateTime::createFromFormat("d.m.y", $date);
if ($date === false) return;
$date = $date->format('U');
if ($date < $this->period) return;
$game = new Game;
$game->author = trim(strip_tags($gameBlock->filter('.cell-2 .author')->text()));
$game->title = trim($gameBlock->filter('.cell-2 h3 a')->text());
$game->url = $this->baseUrl.trim($gameBlock->filter('.cell-2 h3 a')->attr('href'));
$game->description = "";
$this->loadStr($this->get_text($game->url));
$game->description = $this->dom->filter('.description')->first()->text();
$this->output .= $game->print();
});
}
public function checkPage($url) {
return (strpos($url, $this->baseUrl.'/game/') !== FALSE);
}
public function page($url) {
$game = new Game;
$game->url = $url;
$game_id = (int) str_replace($this->baseUrl.'/game/', '', $url);
$game->platform = 'Квестер';
$game->title = trim($this->dom->filter(".qt-in-1 h2")->first()->text());
$game->author = trim($this->dom->filter('.quest-info .author a')->text());
$game->date = \DateTime::createFromFormat(
'd.m.y',
trim($this->dom->filter('.quest-info .date')->first()->text())
);
$game->url_online = $this->baseUrl.trim($this->dom->filter(".play a")->first()->attr('href'));
$game->url_online_description = 'Играть онлайн на Квестер.ру';
$game->description = trim($this->dom->filter('.quest-profile .description')->first()->text());
$game->image = $this->baseUrl.trim($this->dom->filter('.quest-profile .cell-1 img')->first()->attr('src'));
if ($game->author === 'Совместный') {
$this->loadStr($this->get_text($this->baseUrl.'/game/quest/team/'.$game_id.'?ts_mode=public'));
$game->author = [];
$this->dom->filter('.team-item a .txt')->each(function($author) use($game){
$game->author[] = $author->text();
});
}
return $game;
}
}

68
app/Sources/Qsp.php Normal file
View file

@ -0,0 +1,68 @@
<?php
/*
A set of utilities for tracking text-based game releases
Copyright (C) 2017-2018 Alexander Yakovlev
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace App\Sources;
use \App\Models\Game;
use \App\Source;
class Qsp extends Source {
public $title = "Библиотека QSP";
protected function parse() {
$text = $this->get_text("http://qsp.su/index.php?option=com_sobi2&sobi2Task=rss&no_html=1&catid=1&Itemid=55");
$this->loadStr($text);
unset($text);
$this->dom->filter('channel item')->each(function($gameBlock){
$date = trim($gameBlock->filter('pubDate')->text(), "() \t\n\r\0\x0B");
$date = new \DateTime($date);
if ($date === false) return;
$date = $date->format('U');
if ($date < $this->period) return;
$game = new Game;
$game->author = trim($gameBlock->filter('category')->text());
$game->title = trim($gameBlock->filter('title')->text());
$game->url = trim($gameBlock->filter('link:first-child')->text());
$game->description = trim($gameBlock->filter('description')->text());
$this->output .= $game->print();
});
}
public function checkPage($url) {
return (strpos($url,'http://qsp.su') !== FALSE);
}
public function page($url) {
$game = new Game;
$game->url = $url;
try {
$game->author = trim($this->dom->filter('#sobi2Details_field_author')->text());
$game->author = trim(str_replace($this->dom->filter('#sobi2Listing_field_author_label')->text(), '', $game->author));
$game->title = trim($this->dom->filter('.sobi2Details h1')->first()->text());
$game->description = trim($this->dom->filter('#sobi2Details_field_description')->text());
$game->platform = 'QSP';
$game->url_download = trim($this->dom->filter('h2 a')->attr('href'));
$game->url_download_description = 'Архив для интерпретатора QSP';
$game->image = trim($this->dom->filter('.sobi2DetailsImage')->first()->attr('src'));
preg_match('/\d?\d\.\d?\d\.\d{4}/', $this->dom->filter('.sobi2DetailsFooter tr:first-child td')->text(), $matches);
$game->date = new \DateTime($matches[0]);
} catch (\Exception $e) {
echo 'Ошибка парсинга. Проверьте URL.'.PHP_EOL;
echo $e->getTraceAsString();
return $game;
}
return $game;
}
}

115
app/Sources/Questbook.php Normal file
View file

@ -0,0 +1,115 @@
<?php
/*
A set of utilities for tracking text-based game releases
Copyright (C) 2017-2018 Alexander Yakovlev
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace App\Sources;
use \App\Models\Game;
use \App\Source;
class Questbook extends Source {
public $title = "Сторигеймы";
protected function parse() {
global $argv;
if (isset($argv[2])) {
$game_page = $this->get_text($argv[2]);
$this->loadStr($game_page, []);
$this->output .= $this->page($argv[2])->print();
} else {
$this->parseFeed('https://quest-book.ru/directory/rss/');
$this->parseFeed('https://quest-book.ru/online/rss.xml');
}
}
protected function parseFeed($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 "";
}
unset($string);
foreach ($games as $gameBlock) {
$date = strtotime($gameBlock['pubDate']);
if ($date < $this->period) continue;
$game = new Game;
$game->title = trim($gameBlock['title'] ?? '');
$game->url = trim($gameBlock['link'] ?? '');
$game->url = str_replace('http://', 'https://', $game->url);
$game->description = trim($gameBlock['description'] ?? '');
$game->author = trim($gameBlock['author'] ?? '');
$this->output .= $game->print();
}
}
public function checkPage($url) {
return (strpos($url,'https://quest-book.ru/') !== FALSE);
}
public function page($url) {
$game = new Game;
$game->url = $url;
$title = $this->dom->filter('h2 a b');
if ($title->count() > 0) {
$title = $title->first()->text();
$game->title = $title;
} else {
$title = $this->dom->filter('h2.mt-1');
if ($title->count() > 0) {
$title = $title->first()->text();
$game->title = $title;
}
}
$game->platform = 'Книга-игра';
if (strpos($game->url, 'quest-book.ru/online/') !== FALSE) {
$game->platform = 'Атрил';
}
$description = $this->dom->filter('div.col-md-8.col-sm-12 > div > div')->reduce(function($node) {
if ($node->attr('style') === 'padding:5px;margin:2px;text-align:justify')
return true;
return false;
});
if ($description->count() > 0) {
$description = $description->text();
$game->description = $description;
}
$game->description = trim($game->description);
$author = $this->dom->filter('div.col-md-8.col-sm-12 em span')->reduce(function($node) {
if ($node->attr('itemprop') === 'author')
return true;
return false;
});
if ($author->count() > 0) {
$author = $author->text();
$game->author = $author;
}
return $game;
}
}

156
app/Sources/Steam.php Normal file
View file

@ -0,0 +1,156 @@
<?php
/*
A set of utilities for tracking text-based game releases
Copyright (C) 2017-2018 Alexander Yakovlev
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace App\Sources;
use \App\Models\Game;
use \App\Source;
use \Symfony\Component\DomCrawler\Crawler;
use \GuzzleHttp\Cookie\CookieJar;
use \GuzzleHttp\Cookie\SetCookie;
class Steam extends Source {
public $title = "Steam";
protected $games = [];
public $delayedLoad = true;
protected $months = [
'янв.' => 'January',
'фев.' => 'February',
'мар.' => 'March',
'апр.' => 'April',
'мая.' => 'May',
'июн.' => 'June',
'июл.' => 'July',
'авг.' => 'August',
'сен.' => 'September',
'окт.' => 'October',
'ноя.' => 'November',
'дек.' => 'December',
];
protected function parse_tag($tag) {
$url = 'https://store.steampowered.com/search/';
$url .= '?'.http_build_query([
'sort_by' => 'Released_DESC',
'term' => $tag,
'displayterm' => $tag,
'category1' => 998, // only games
]);
$text = $this->get_text($url);
$this->loadStr($text);
unset($text);
$this->dom->filter('#search_result_container a.search_result_row')->each(function($gameLink){
$url = $gameLink->attr('href');
$url = substr($url,0,strpos($url, '?')); // remove query string
$game = $this->page($url);
if ($game) {
if ($game->date) {
$date = $game->date->format('U');
if ($date < $this->period) return;
}
$this->games[] = $game->print();
}
});
}
protected function parse() {
global $argv;
if (isset($argv[2])) {
$game = $this->page($argv[2]);
$this->output .= $game->print();
} else {
$this->parse_tag("text-based");
$this->parse_tag("interactive fiction");
$this->parse_tag("visual novel");
$this->games = array_unique($this->games);
foreach ($this->games as $game) {
$this->output .= $game;
}
}
}
public function checkPage($url) {
return (strpos($url,'store.steampowered.com/') !== FALSE);
}
public function page($url) {
$this->cookies = new CookieJar(true);
$this->cookies->setCookie(new SetCookie([
'Domain' => 'store.steampowered.com',
'Name' => 'mature_content',
'Value' => 1
]));
$this->cookies->setCookie(new SetCookie([
'Domain' => 'store.steampowered.com',
'Name' => 'Steam_Language',
'Value' => 'russian'
]));
$this->cookies->setCookie(new SetCookie([
'Domain' => 'store.steampowered.com',
'Name' => 'timezoneOffset',
'Value' => '0,0'
]));
$this->loadStr($this->get_text($url));
$game = new Game;
$game->url = $url;
$comingsoon = $this->dom->filter('div.game_area_comingsoon')->first();
if ($comingsoon->count() > 0) {
// we are skipping preorders and coming soon games
return false;
}
$title = $this->dom->filter('div.apphub_AppName')->first();
if ($title->count() > 0) {
$game->title = trim($title->text());
}
$dsc = $this->dom->filter('div.game_description_snippet')->first();
if ($dsc->count() > 0) {
$game->description = trim($dsc->text());
}
$author = $this->dom->filter('div#developers_list')->first();
if ($author->count() > 0) {
$game->author = trim($author->text());
if (strpos($game->author, ',') !== FALSE) {
$game->author = explode(',', $game->author);
$game->author = array_map('trim', $game->author);
}
}
$image = $this->dom->filter('img.game_header_image_full')->first();
if ($image->count() > 0) {
$game->image = $image->attr('src');
}
$game->categories = 'Коммерческая ИЛ';
$languages = $this->dom->filter('.game_language_options tr td:first-child');
if ($languages->count() > 0) {
$game->language = [];
foreach ($languages as $language) {
$game->language[] = trim($language->nodeValue);
}
$game->language = implode(', ', $game->language);
}
$date = $this->dom->filter('div.date')->first();
if ($date->count() > 0) {
$date = $date->text();
$game->date = \DateTime::createFromFormat('d M, Y', $date);
if ($game->date === FALSE) { // если Steam отдал страницу на русском
foreach ($this->months as $ruM => $enM) {
$date = str_replace($ruM, $enM, $date);
}
$game->date = \DateTime::createFromFormat('d F Y', $date);
}
}
return $game;
}
}

View file

@ -0,0 +1,56 @@
<?php
/*
A set of utilities for tracking text-based game releases
Copyright (C) 2017-2018 Alexander Yakovlev
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace App\Sources;
use \App\Models\Game;
use \App\Source;
use \Symfony\Component\DomCrawler\Crawler;
class Textadventures extends Source {
public $title = "Textadventures.co.uk";
protected function parse() {
$text = $this->get_text('http://textadventures.co.uk/games/latest');
$this->loadStr($text);
unset($text);
$this->dom->filter('.games-item')->each(function($gameBlock){
$game = new Game;
$game->url = 'http://textadventures.co.uk'.$gameBlock->filter('.games-title a')->attr('href');
$game->title = $gameBlock->filter('.games-title a')->text();
$date = strtotime($gameBlock->filter('.games-date')->text());
if ($date < $this->period) return;
$text = $this->get_text($game->url);
$game_page = new Crawler($text);
unset($text);
$game->author = str_replace('by ', '', $game_page->filter('h1 small')->text());
$image = $game_page->filter('img.cover-image')->first();
if ($image->count()) {
$game->image = $image->attr('src');
}
$game_page = $game_page->filter('.col-md-12 .col-md-9 > .col-md-12')->first();
if (!$game_page->count()) {
$game_page = $game_page->filter('.col-md-12 .col-md-9 > .col-md-7')->first();
}
if ($game_page->count()) {
$game->desc = trim($game_page->children()->first()->text());
}
$this->output .= $game->print();
});
}
}

51
app/Sources/Urq.php Normal file
View file

@ -0,0 +1,51 @@
<?php
/*
A set of utilities for tracking text-based game releases
Copyright (C) 2017-2018 Alexander Yakovlev
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace App\Sources;
use \App\Models\Game;
use \App\Source;
class Urq extends Source {
public $title = "Библиотека URQ";
protected function parse() {
$text = $this->get_text('http://urq.plut.info/node/209');
$this->loadStr($text);
unset($text);
$games = $this->dom->filter('.view-NewGames tr')->each(function($gameBlock) {
$game = new Game;
$game->author = trim($gameBlock->filter('.views-field-taxonomy-vocabulary-2')->first()->text());
$game->title = trim($gameBlock->filter('.views-field-title')->text());
$game->url = 'http://urq.plut.info'.trim($gameBlock->filter('.views-field-title a')->attr('href'));
$this->output .= $game->print();
});
}
public function checkPage($url) {
return (strpos($url,'http://urq.plut.info/node/') !== FALSE);
}
public function page($url) {
$game = new Game;
$game->url = $url;
$gameBlock = $this->dom->filter('.content');
$game->author = trim($gameBlock->filter('.field-name-taxonomy-vocabulary-2 a')->first()->text());
$game->title = trim($this->dom->filter('h1.title')->first()->text());
$game->description = $gameBlock->filter('.field-type-text-with-summary .field-items span.field-item')->first()->text();
$game->platform = $gameBlock->filter('.field-name-taxonomy-vocabulary-5 .field-items span.field-item a')->first()->text();
return $game;
}
}

46
app/Sources/VNDB.php Normal file
View file

@ -0,0 +1,46 @@
<?php
/*
A set of utilities for tracking text-based game releases
Copyright (C) 2017-2018 Alexander Yakovlev
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace App\Sources;
use \App\Models\Game;
use \App\Source;
class VNDB extends Source {
public $title = "VNDB";
protected function parse() {
global $config;
$client = new Client();
$client->connect();
$client->login($config['VNDB_USER'], $config['VNDB_PASSWORD']);
$date = (new Date("1 week ago"))->format('Y-m-d');
echo $date;
return;
$list = $client->sendCommand('get vn basic (released > "'.$date.'")');
foreach ($list as $gameData) {
$game = new Game;
$game->title = $gameData->title;
$game->author = $gameData->developer->display_name;
$game->date = $gameData->published_on / 1000;
$game->description = $descData->payload->metaDescription;
$game->url = 'https://gamejolt.com/games/'.$gameData->slug.'/'.$gameData->id;
$this->output .= $game->print();
}
}
}

View file

@ -17,8 +17,16 @@
],
"require": {
"php": "^7.1.3",
"sabre/xml": "^2.0",
"addwiki/mediawiki-api": "^0.7.2",
"symfony/dom-crawler": "^4.0",
"symfony/css-selector": "^4.0",
"longman/telegram-bot": "dev-master",
"revolution/laravel-mastodon-api": "dev-master",
"cocur/slugify": "^3.2",
"illuminate/database": "5.8.*",
"laravel-zero/framework": "5.8.*"
"laravel-zero/framework": "5.8.*",
"ryakad/pandoc-php": "^1.0"
},
"require-dev": {
"mockery/mockery": "^1.0",

946
composer.lock generated
View file

@ -4,8 +4,222 @@
"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": "88cd99b646d7a43544960143c325731d",
"content-hash": "e1a249d24c801b7e1d16247486413b44",
"packages": [
{
"name": "addwiki/mediawiki-api",
"version": "0.7.2",
"source": {
"type": "git",
"url": "https://github.com/addwiki/mediawiki-api.git",
"reference": "f52fc3760d82774512d344e41c45c878a2c6659e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/addwiki/mediawiki-api/zipball/f52fc3760d82774512d344e41c45c878a2c6659e",
"reference": "f52fc3760d82774512d344e41c45c878a2c6659e",
"shasum": ""
},
"require": {
"addwiki/mediawiki-api-base": "~2.4",
"addwiki/mediawiki-datamodel": "~0.7.0"
},
"require-dev": {
"jakub-onderka/php-parallel-lint": "^0.9.2",
"mediawiki/mediawiki-codesniffer": "^13.0",
"monolog/monolog": "^1.23",
"phpunit/phpunit": "~4.8"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "0.7.x-dev"
}
},
"autoload": {
"psr-4": {
"Mediawiki\\Api\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"GPL-2.0+"
],
"authors": [
{
"name": "Addshore"
}
],
"description": "A MediaWiki API library",
"keywords": [
"mediawiki"
],
"time": "2017-11-20T03:08:06+00:00"
},
{
"name": "addwiki/mediawiki-api-base",
"version": "2.4.0",
"source": {
"type": "git",
"url": "https://github.com/addwiki/mediawiki-api-base.git",
"reference": "33c147e91d05a48e953839fb3ad9e6386cfd85c1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/addwiki/mediawiki-api-base/zipball/33c147e91d05a48e953839fb3ad9e6386cfd85c1",
"reference": "33c147e91d05a48e953839fb3ad9e6386cfd85c1",
"shasum": ""
},
"require": {
"guzzlehttp/guzzle": "~6.0",
"guzzlehttp/promises": "~1.0",
"php": ">=5.5",
"psr/log": "~1.0"
},
"require-dev": {
"jakub-onderka/php-parallel-lint": "0.9.2",
"mediawiki/mediawiki-codesniffer": "^13.0",
"phpunit/phpunit": "~4.8.0|~5.3.0"
},
"suggest": {
"etsy/phan": "Allows running static analysis on the package (requires PHP 7+)"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4.x-dev"
}
},
"autoload": {
"psr-4": {
"Mediawiki\\Api\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"GPL-2.0+"
],
"authors": [
{
"name": "Addshore"
}
],
"description": "A basic Mediawiki api base library",
"keywords": [
"mediawiki"
],
"time": "2017-11-02T10:53:36+00:00"
},
{
"name": "addwiki/mediawiki-datamodel",
"version": "0.7.1",
"source": {
"type": "git",
"url": "https://github.com/addwiki/mediawiki-datamodel.git",
"reference": "05dd783715a92ec5449bab4091c0482cf3fcface"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/addwiki/mediawiki-datamodel/zipball/05dd783715a92ec5449bab4091c0482cf3fcface",
"reference": "05dd783715a92ec5449bab4091c0482cf3fcface",
"shasum": ""
},
"require-dev": {
"jakub-onderka/php-parallel-lint": "0.9.2",
"mediawiki/mediawiki-codesniffer": "^13.0",
"phpunit/phpunit": "~4.8.0|~5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "0.7.x-dev"
}
},
"autoload": {
"psr-4": {
"Mediawiki\\DataModel\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"GPL-2.0+"
],
"authors": [
{
"name": "Addshore"
}
],
"description": "A Mediawiki datamodel",
"keywords": [
"mediawiki"
],
"time": "2018-01-10T19:14:13+00:00"
},
{
"name": "cocur/slugify",
"version": "v3.2",
"source": {
"type": "git",
"url": "https://github.com/cocur/slugify.git",
"reference": "d41701efe58ba2df9cae029c3d21e1518cc6780e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/cocur/slugify/zipball/d41701efe58ba2df9cae029c3d21e1518cc6780e",
"reference": "d41701efe58ba2df9cae029c3d21e1518cc6780e",
"shasum": ""
},
"require": {
"ext-mbstring": "*",
"php": ">=5.5.9"
},
"require-dev": {
"laravel/framework": "~5.1",
"latte/latte": "~2.2",
"league/container": "^2.2.0",
"mikey179/vfsstream": "~1.6",
"mockery/mockery": "~0.9",
"nette/di": "~2.2",
"phpunit/phpunit": "~4.8.36|~5.2",
"pimple/pimple": "~1.1",
"plumphp/plum": "~0.1",
"silex/silex": "~1.3",
"symfony/config": "~2.4|~3.0|~4.0",
"symfony/dependency-injection": "~2.4|~3.0|~4.0",
"symfony/http-kernel": "~2.4|~3.0|~4.0",
"twig/twig": "~1.26|~2.0",
"zendframework/zend-modulemanager": "~2.2",
"zendframework/zend-servicemanager": "~2.2",
"zendframework/zend-view": "~2.2"
},
"type": "library",
"autoload": {
"psr-4": {
"Cocur\\Slugify\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Ivo Bathke",
"email": "ivo.bathke@gmail.com"
},
{
"name": "Florian Eckerstorfer",
"email": "florian@eckerstorfer.co",
"homepage": "https://florian.ec"
}
],
"description": "Converts a string into a slug.",
"keywords": [
"slug",
"slugify"
],
"time": "2019-01-31T20:38:55+00:00"
},
{
"name": "doctrine/inflector",
"version": "v1.3.0",
@ -188,6 +402,193 @@
],
"time": "2019-08-07T09:00:00+00:00"
},
{
"name": "guzzlehttp/guzzle",
"version": "6.3.3",
"source": {
"type": "git",
"url": "https://github.com/guzzle/guzzle.git",
"reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/407b0cb880ace85c9b63c5f9551db498cb2d50ba",
"reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba",
"shasum": ""
},
"require": {
"guzzlehttp/promises": "^1.0",
"guzzlehttp/psr7": "^1.4",
"php": ">=5.5"
},
"require-dev": {
"ext-curl": "*",
"phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0",
"psr/log": "^1.0"
},
"suggest": {
"psr/log": "Required for using the Log middleware"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "6.3-dev"
}
},
"autoload": {
"files": [
"src/functions_include.php"
],
"psr-4": {
"GuzzleHttp\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
}
],
"description": "Guzzle is a PHP HTTP client library",
"homepage": "http://guzzlephp.org/",
"keywords": [
"client",
"curl",
"framework",
"http",
"http client",
"rest",
"web service"
],
"time": "2018-04-22T15:46:56+00:00"
},
{
"name": "guzzlehttp/promises",
"version": "v1.3.1",
"source": {
"type": "git",
"url": "https://github.com/guzzle/promises.git",
"reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646",
"reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646",
"shasum": ""
},
"require": {
"php": ">=5.5.0"
},
"require-dev": {
"phpunit/phpunit": "^4.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.4-dev"
}
},
"autoload": {
"psr-4": {
"GuzzleHttp\\Promise\\": "src/"
},
"files": [
"src/functions_include.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
}
],
"description": "Guzzle promises library",
"keywords": [
"promise"
],
"time": "2016-12-20T10:07:11+00:00"
},
{
"name": "guzzlehttp/psr7",
"version": "1.6.1",
"source": {
"type": "git",
"url": "https://github.com/guzzle/psr7.git",
"reference": "239400de7a173fe9901b9ac7c06497751f00727a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/239400de7a173fe9901b9ac7c06497751f00727a",
"reference": "239400de7a173fe9901b9ac7c06497751f00727a",
"shasum": ""
},
"require": {
"php": ">=5.4.0",
"psr/http-message": "~1.0",
"ralouphie/getallheaders": "^2.0.5 || ^3.0.0"
},
"provide": {
"psr/http-message-implementation": "1.0"
},
"require-dev": {
"ext-zlib": "*",
"phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8"
},
"suggest": {
"zendframework/zend-httphandlerrunner": "Emit PSR-7 responses"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.6-dev"
}
},
"autoload": {
"psr-4": {
"GuzzleHttp\\Psr7\\": "src/"
},
"files": [
"src/functions_include.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
},
{
"name": "Tobias Schultze",
"homepage": "https://github.com/Tobion"
}
],
"description": "PSR-7 message implementation that also provides common utility methods",
"keywords": [
"http",
"message",
"psr-7",
"request",
"response",
"stream",
"uri",
"url"
],
"time": "2019-07-01T23:21:34+00:00"
},
{
"name": "illuminate/cache",
"version": "v5.8.35",
@ -988,6 +1389,144 @@
],
"time": "2019-08-24T11:17:19+00:00"
},
{
"name": "longman/telegram-bot",
"version": "dev-master",
"source": {
"type": "git",
"url": "https://github.com/php-telegram-bot/core.git",
"reference": "46646884f5c05f1161f10605a0705aa24df3e583"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-telegram-bot/core/zipball/46646884f5c05f1161f10605a0705aa24df3e583",
"reference": "46646884f5c05f1161f10605a0705aa24df3e583",
"shasum": ""
},
"require": {
"ext-curl": "*",
"ext-json": "*",
"ext-mbstring": "*",
"ext-pdo": "*",
"guzzlehttp/guzzle": "^6.3",
"monolog/monolog": "^1.24",
"php": "^5.5|^7.0",
"psr/log": "^1.1"
},
"require-dev": {
"phpunit/phpunit": "^4.8|^5.7|^6.5|^7.5|^8.1",
"squizlabs/php_codesniffer": "^3.4"
},
"type": "library",
"autoload": {
"psr-4": {
"Longman\\TelegramBot\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Avtandil Kikabidze aka LONGMAN",
"role": "Developer",
"email": "akalongman@gmail.com",
"homepage": "http://longman.me"
},
{
"name": "PHP Telegram Bot Team",
"role": "Developer",
"homepage": "https://github.com/php-telegram-bot/core/graphs/contributors"
}
],
"description": "PHP Telegram bot",
"homepage": "https://github.com/php-telegram-bot/core",
"keywords": [
"api",
"bot",
"telegram"
],
"time": "2019-08-16T15:10:43+00:00"
},
{
"name": "monolog/monolog",
"version": "1.25.1",
"source": {
"type": "git",
"url": "https://github.com/Seldaek/monolog.git",
"reference": "70e65a5470a42cfec1a7da00d30edb6e617e8dcf"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/70e65a5470a42cfec1a7da00d30edb6e617e8dcf",
"reference": "70e65a5470a42cfec1a7da00d30edb6e617e8dcf",
"shasum": ""
},
"require": {
"php": ">=5.3.0",
"psr/log": "~1.0"
},
"provide": {
"psr/log-implementation": "1.0.0"
},
"require-dev": {
"aws/aws-sdk-php": "^2.4.9 || ^3.0",
"doctrine/couchdb": "~1.0@dev",
"graylog2/gelf-php": "~1.0",
"jakub-onderka/php-parallel-lint": "0.9",
"php-amqplib/php-amqplib": "~2.4",
"php-console/php-console": "^3.1.3",
"phpunit/phpunit": "~4.5",
"phpunit/phpunit-mock-objects": "2.3.0",
"ruflin/elastica": ">=0.90 <3.0",
"sentry/sentry": "^0.13",
"swiftmailer/swiftmailer": "^5.3|^6.0"
},
"suggest": {
"aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
"doctrine/couchdb": "Allow sending log messages to a CouchDB server",
"ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
"ext-mongo": "Allow sending log messages to a MongoDB server",
"graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server",
"mongodb/mongodb": "Allow sending log messages to a MongoDB server via PHP Driver",
"php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib",
"php-console/php-console": "Allow sending log messages to Google Chrome",
"rollbar/rollbar": "Allow sending log messages to Rollbar",
"ruflin/elastica": "Allow sending log messages to an Elastic Search server",
"sentry/sentry": "Allow sending log messages to a Sentry server"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Monolog\\": "src/Monolog"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jordi Boggiano",
"email": "j.boggiano@seld.be",
"homepage": "http://seld.be"
}
],
"description": "Sends your logs to files, sockets, inboxes, databases and various web services",
"homepage": "http://github.com/Seldaek/monolog",
"keywords": [
"log",
"logging",
"psr-3"
],
"time": "2019-09-06T13:49:17+00:00"
},
{
"name": "nesbot/carbon",
"version": "2.24.0",
@ -1397,6 +1936,56 @@
],
"time": "2017-02-14T16:28:37+00:00"
},
{
"name": "psr/http-message",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-message.git",
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Http\\Message\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interface for HTTP messages",
"homepage": "https://github.com/php-fig/http-message",
"keywords": [
"http",
"http-message",
"psr",
"psr-7",
"request",
"response"
],
"time": "2016-08-06T14:39:51+00:00"
},
{
"name": "psr/log",
"version": "1.1.0",
@ -1492,6 +2081,242 @@
],
"time": "2017-10-23T01:57:42+00:00"
},
{
"name": "ralouphie/getallheaders",
"version": "3.0.3",
"source": {
"type": "git",
"url": "https://github.com/ralouphie/getallheaders.git",
"reference": "120b605dfeb996808c31b6477290a714d356e822"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822",
"reference": "120b605dfeb996808c31b6477290a714d356e822",
"shasum": ""
},
"require": {
"php": ">=5.6"
},
"require-dev": {
"php-coveralls/php-coveralls": "^2.1",
"phpunit/phpunit": "^5 || ^6.5"
},
"type": "library",
"autoload": {
"files": [
"src/getallheaders.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Ralph Khattar",
"email": "ralph.khattar@gmail.com"
}
],
"description": "A polyfill for getallheaders.",
"time": "2019-03-08T08:55:37+00:00"
},
{
"name": "revolution/laravel-mastodon-api",
"version": "dev-master",
"source": {
"type": "git",
"url": "https://github.com/kawax/laravel-mastodon-api.git",
"reference": "35a02ea1b78c6dccbec628e2e1f39e1c9e666299"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/kawax/laravel-mastodon-api/zipball/35a02ea1b78c6dccbec628e2e1f39e1c9e666299",
"reference": "35a02ea1b78c6dccbec628e2e1f39e1c9e666299",
"shasum": ""
},
"require": {
"ext-json": "*",
"guzzlehttp/guzzle": "^6.2",
"illuminate/support": "*",
"php": ">=7.1.3"
},
"require-dev": {
"mockery/mockery": "^1.0",
"orchestra/testbench": "~3.8",
"phpunit/phpunit": "^7.5"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Revolution\\Mastodon\\Providers\\MastodonServiceProvider"
],
"aliases": {
"Mastodon": "Revolution\\Mastodon\\Facades\\Mastodon"
}
}
},
"autoload": {
"psr-4": {
"Revolution\\Mastodon\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "kawax",
"email": "kawaxbiz@gmail.com"
}
],
"description": "Mastodon API for Laravel",
"keywords": [
"laravel",
"mastodon"
],
"time": "2019-08-21T03:37:05+00:00"
},
{
"name": "ryakad/pandoc-php",
"version": "v1.0.0",
"source": {
"type": "git",
"url": "https://github.com/ryakad/pandoc-php.git",
"reference": "0cfdf959408e4c481db942b26785d94b9fe46672"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ryakad/pandoc-php/zipball/0cfdf959408e4c481db942b26785d94b9fe46672",
"reference": "0cfdf959408e4c481db942b26785d94b9fe46672",
"shasum": ""
},
"type": "library",
"autoload": {
"psr-0": {
"Pandoc": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"time": "2015-01-07T05:07:16+00:00"
},
{
"name": "sabre/uri",
"version": "2.1.3",
"source": {
"type": "git",
"url": "https://github.com/sabre-io/uri.git",
"reference": "18f454324f371cbcabdad3d0d3755b4b0182095d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sabre-io/uri/zipball/18f454324f371cbcabdad3d0d3755b4b0182095d",
"reference": "18f454324f371cbcabdad3d0d3755b4b0182095d",
"shasum": ""
},
"require": {
"php": ">=7"
},
"require-dev": {
"phpunit/phpunit": "^6"
},
"type": "library",
"autoload": {
"files": [
"lib/functions.php"
],
"psr-4": {
"Sabre\\Uri\\": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Evert Pot",
"email": "me@evertpot.com",
"homepage": "http://evertpot.com/",
"role": "Developer"
}
],
"description": "Functions for making sense out of URIs.",
"homepage": "http://sabre.io/uri/",
"keywords": [
"rfc3986",
"uri",
"url"
],
"time": "2019-09-09T23:00:25+00:00"
},
{
"name": "sabre/xml",
"version": "2.1.3",
"source": {
"type": "git",
"url": "https://github.com/sabre-io/xml.git",
"reference": "f08a58f57e2b0d7df769a432756aa371417ab9eb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sabre-io/xml/zipball/f08a58f57e2b0d7df769a432756aa371417ab9eb",
"reference": "f08a58f57e2b0d7df769a432756aa371417ab9eb",
"shasum": ""
},
"require": {
"ext-dom": "*",
"ext-xmlreader": "*",
"ext-xmlwriter": "*",
"lib-libxml": ">=2.6.20",
"php": ">=7.0",
"sabre/uri": ">=1.0,<3.0.0"
},
"require-dev": {
"phpunit/phpunit": "^6"
},
"type": "library",
"autoload": {
"psr-4": {
"Sabre\\Xml\\": "lib/"
},
"files": [
"lib/Deserializer/functions.php",
"lib/Serializer/functions.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Evert Pot",
"role": "Developer",
"email": "me@evertpot.com",
"homepage": "http://evertpot.com/"
},
{
"name": "Markus Staab",
"role": "Developer",
"email": "markus.staab@redaxo.de"
}
],
"description": "sabre/xml is an XML library that you may not hate.",
"homepage": "https://sabre.io/xml/",
"keywords": [
"XMLReader",
"XMLWriter",
"dom",
"xml"
],
"time": "2019-08-14T15:41:34+00:00"
},
{
"name": "symfony/console",
"version": "v4.3.4",
@ -1567,6 +2392,59 @@
"homepage": "https://symfony.com",
"time": "2019-08-26T08:26:39+00:00"
},
{
"name": "symfony/css-selector",
"version": "v4.3.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/css-selector.git",
"reference": "c6e5e2a00db768c92c3ae131532af4e1acc7bd03"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/css-selector/zipball/c6e5e2a00db768c92c3ae131532af4e1acc7bd03",
"reference": "c6e5e2a00db768c92c3ae131532af4e1acc7bd03",
"shasum": ""
},
"require": {
"php": "^7.1.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.3-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\CssSelector\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Jean-François Simon",
"email": "jeanfrancois.simon@sensiolabs.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony CssSelector Component",
"homepage": "https://symfony.com",
"time": "2019-08-20T14:07:54+00:00"
},
{
"name": "symfony/debug",
"version": "v4.3.4",
@ -1623,6 +2501,67 @@
"homepage": "https://symfony.com",
"time": "2019-08-20T14:27:59+00:00"
},
{
"name": "symfony/dom-crawler",
"version": "v4.3.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/dom-crawler.git",
"reference": "cc686552948d627528c0e2e759186dff67c2610e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/dom-crawler/zipball/cc686552948d627528c0e2e759186dff67c2610e",
"reference": "cc686552948d627528c0e2e759186dff67c2610e",
"shasum": ""
},
"require": {
"php": "^7.1.3",
"symfony/polyfill-ctype": "~1.8",
"symfony/polyfill-mbstring": "~1.0"
},
"conflict": {
"masterminds/html5": "<2.6"
},
"require-dev": {
"masterminds/html5": "^2.6",
"symfony/css-selector": "~3.4|~4.0"
},
"suggest": {
"symfony/css-selector": ""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.3-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\DomCrawler\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony DomCrawler Component",
"homepage": "https://symfony.com",
"time": "2019-08-26T08:26:39+00:00"
},
{
"name": "symfony/finder",
"version": "v4.3.4",
@ -5256,7 +6195,10 @@
],
"aliases": [],
"minimum-stability": "dev",
"stability-flags": [],
"stability-flags": {
"longman/telegram-bot": 20,
"revolution/laravel-mastodon-api": 20
},
"prefer-stable": true,
"prefer-lowest": false,
"platform": {

View file

@ -2,126 +2,126 @@
return [
/*
|--------------------------------------------------------------------------
| Default Database Connection Name
|--------------------------------------------------------------------------
|
| Here you may specify which of the database connections below you wish
| to use as your default connection for all database work. Of course
| you may use many connections at once using the Database library.
|
*/
/*
|--------------------------------------------------------------------------
| Default Database Connection Name
|--------------------------------------------------------------------------
|
| Here you may specify which of the database connections below you wish
| to use as your default connection for all database work. Of course
| you may use many connections at once using the Database library.
|
*/
'default' => env('DB_CONNECTION', 'sqlite'),
'default' => env('DB_CONNECTION', 'sqlite'),
/*
|--------------------------------------------------------------------------
| Database Connections
|--------------------------------------------------------------------------
|
| Here are each of the database connections setup for your application.
| Of course, examples of configuring each database platform that is
| supported by Laravel is shown below to make development simple.
|
|
| All database work in Laravel is done through the PHP PDO facilities
| so make sure you have the driver for your particular database of
| choice installed on your machine before you begin development.
|
*/
/*
|--------------------------------------------------------------------------
| Database Connections
|--------------------------------------------------------------------------
|
| Here are each of the database connections setup for your application.
| Of course, examples of configuring each database platform that is
| supported by Laravel is shown below to make development simple.
|
|
| All database work in Laravel is done through the PHP PDO facilities
| so make sure you have the driver for your particular database of
| choice installed on your machine before you begin development.
|
*/
'connections' => [
'connections' => [
'sqlite' => [
'driver' => 'sqlite',
'database' => env('DB_DATABASE', database_path('database.sqlite')),
'prefix' => '',
],
'sqlite' => [
'driver' => 'sqlite',
'database' => env('DB_DATABASE', database_path('database.sqlite')),
'prefix' => '',
],
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => true,
'engine' => null,
],
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => true,
'engine' => null,
],
'pgsql' => [
'driver' => 'pgsql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '5432'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
'schema' => 'public',
'sslmode' => 'prefer',
],
'pgsql' => [
'driver' => 'pgsql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '5432'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
'schema' => 'public',
'sslmode' => 'prefer',
],
'sqlsrv' => [
'driver' => 'sqlsrv',
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', '1433'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
],
'sqlsrv' => [
'driver' => 'sqlsrv',
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', '1433'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
],
],
],
/*
|--------------------------------------------------------------------------
| Migration Repository Table
|--------------------------------------------------------------------------
|
| This table keeps track of all the migrations that have already run for
| your application. Using this information, we can determine which of
| the migrations on disk haven't actually been run in the database.
|
*/
/*
|--------------------------------------------------------------------------
| Migration Repository Table
|--------------------------------------------------------------------------
|
| This table keeps track of all the migrations that have already run for
| your application. Using this information, we can determine which of
| the migrations on disk haven't actually been run in the database.
|
*/
'migrations' => 'migrations',
'migrations' => 'migrations',
/*
|--------------------------------------------------------------------------
| Redis Databases
|--------------------------------------------------------------------------
|
| Redis is an open source, fast, and advanced key-value store that also
| provides a richer set of commands than a typical key-value systems
| such as APC or Memcached. Laravel makes it easy to dig right in.
|
*/
/*
|--------------------------------------------------------------------------
| Redis Databases
|--------------------------------------------------------------------------
|
| Redis is an open source, fast, and advanced key-value store that also
| provides a richer set of commands than a typical key-value systems
| such as APC or Memcached. Laravel makes it easy to dig right in.
|
*/
'redis' => [
'redis' => [
'client' => 'predis',
'client' => 'predis',
'default' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_DB', 0),
],
'default' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_DB', 0),
],
'cache' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_CACHE_DB', 1),
],
'cache' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_CACHE_DB', 1),
],
],
],
];

View file

@ -0,0 +1,101 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class Initial extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('authors', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('url');
$table->boolean('is_company');
$table->boolean('is_person');
$table->text('description');
});
Schema::create('platforms', function (Blueprint $table) {
$table->increments('id');
$table->string('title')->unique();
});
Schema::create('languages', function (Blueprint $table) {
$table->increments('id');
$table->string('code')->unique();
$table->string('title_en')->unique();
$table->string('title_ru')->unique();
});
Schema::create('tags', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->unsignedInteger('language_id')->nullable();
});
Schema::create('games', function (Blueprint $table) {
$table->increments('id');
$table->string('url');
$table->string('url_play_online')->nullable();
$table->string('url_download')->nullable();
$table->string('url_discussion')->nullable();
$table->string('url_download_description')->nullable();
$table->string('url_online_description')->nullable();
$table->string('title')->nullable();
$table->text('description')->nullable();
$table->text('short_description')->nullable();
$table->text('version')->nullable();
$table->date('release_date')->nullable();
$table->string('image_url')->nullable();
$table->unsignedInteger('platform_id')->nullable();
$table->foreign('platform_id')->references('id')->on('platforms');
$table->nullableTimestamps();
$table->softDeletes();
});
Schema::create('authors_games', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('author_id');
$table->unsignedInteger('game_id');
$table->foreign('author_id')->references('id')->on('authors');
$table->foreign('game_id')->references('id')->on('games');
});
Schema::create('tags_games', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('tag_id');
$table->unsignedInteger('game_id');
$table->foreign('tag_id')->references('id')->on('tags');
$table->foreign('game_id')->references('id')->on('games');
});
Schema::create('languages_games', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('language_id');
$table->unsignedInteger('game_id');
$table->foreign('language_id')->references('id')->on('languages');
$table->foreign('game_id')->references('id')->on('games');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('authors_games');
Schema::drop('tags_games');
Schema::drop('languages_games');
Schema::drop('tags');
Schema::drop('games');
Schema::drop('platforms');
Schema::drop('authors');
Schema::drop('languages');
}
}