Making API requests to Anilist, see #5
This commit is contained in:
parent
b5f8413ceb
commit
b3a3e19146
@ -41,11 +41,27 @@ final class Anilist {
|
||||
];
|
||||
|
||||
const ANILIST_KITSU_WATCHING_STATUS_MAP = [
|
||||
'CURRENT' => KAWS::WATCHING,
|
||||
'COMPLETED' => KAWS::COMPLETED,
|
||||
'PAUSED' => KAWS::ON_HOLD,
|
||||
'DROPPED' => KAWS::DROPPED,
|
||||
'PLANNING' => KAWS::PLAN_TO_WATCH,
|
||||
AnimeWatchingStatus::WATCHING => KAWS::WATCHING,
|
||||
AnimeWatchingStatus::COMPLETED => KAWS::COMPLETED,
|
||||
AnimeWatchingStatus::ON_HOLD => KAWS::ON_HOLD,
|
||||
AnimeWatchingStatus::DROPPED => KAWS::DROPPED,
|
||||
AnimeWatchingStatus::PLAN_TO_WATCH => KAWS::PLAN_TO_WATCH,
|
||||
];
|
||||
|
||||
const KITSU_ANILIST_READING_STATUS_MAP = [
|
||||
KMRS::READING => MangaReadingStatus::READING,
|
||||
KMRS::COMPLETED => MangaReadingStatus::COMPLETED,
|
||||
KMRS::ON_HOLD => MangaReadingStatus::ON_HOLD,
|
||||
KMRS::DROPPED => MangaReadingStatus::DROPPED,
|
||||
KMRS::PLAN_TO_READ => MangaReadingStatus::PLAN_TO_READ,
|
||||
];
|
||||
|
||||
const ANILIST_KITSU_READING_STATUS_MAP = [
|
||||
MangaReadingStatus::READING => KMRS::READING,
|
||||
MangaReadingStatus::COMPLETED => KMRS::COMPLETED,
|
||||
MangaReadingStatus::ON_HOLD => KMRS::ON_HOLD,
|
||||
MangaReadingStatus::DROPPED => KMRS::DROPPED,
|
||||
MangaReadingStatus::PLAN_TO_READ => KMRS::PLAN_TO_READ,
|
||||
];
|
||||
|
||||
public static function getIdToWatchingStatusMap()
|
||||
@ -67,7 +83,8 @@ final class Anilist {
|
||||
'COMPLETED' => MangaReadingStatus::COMPLETED,
|
||||
'PAUSED' => MangaReadingStatus::ON_HOLD,
|
||||
'DROPPED' => MangaReadingStatus::DROPPED,
|
||||
'PLANNING' => MangaReadingStatus::PLAN_TO_READ
|
||||
'PLANNING' => MangaReadingStatus::PLAN_TO_READ,
|
||||
'REPEATING' => MangaReadingStatus::READING,
|
||||
];
|
||||
}
|
||||
}
|
@ -16,14 +16,20 @@
|
||||
|
||||
namespace Aviat\AnimeClient\API\Anilist;
|
||||
|
||||
use Amp\Artax\Request;
|
||||
use Amp\Artax\Response;
|
||||
use function Amp\Promise\wait;
|
||||
|
||||
use Aviat\AnimeClient\API\{
|
||||
Anilist,
|
||||
HummingbirdClient
|
||||
};
|
||||
use const Aviat\AnimeClient\SESSION_SEGMENT;
|
||||
use Aviat\Ion\Json;
|
||||
use Aviat\Ion\Di\ContainerAware;
|
||||
|
||||
trait AnilistTrait {
|
||||
use ContainerAware;
|
||||
|
||||
/**
|
||||
* The request builder for the MAL API
|
||||
@ -66,27 +72,92 @@ trait AnilistTrait {
|
||||
|
||||
* @param string $url
|
||||
* @param array $options
|
||||
* @return \Amp\Artax\Response
|
||||
* @return Request
|
||||
*/
|
||||
public function setUpRequest(string $url, array $options = [])
|
||||
public function setUpRequest(string $url, array $options = []): Request
|
||||
{
|
||||
// @TODO Implement
|
||||
$config = $this->getContainer()->get('config');
|
||||
$anilistConfig = $config->get('anilist');
|
||||
|
||||
$request = $this->requestBuilder->newRequest('POST', $url);
|
||||
$sessionSegment = $this->getContainer()
|
||||
->get('session')
|
||||
->getSegment(SESSION_SEGMENT);
|
||||
|
||||
$authenticated = $sessionSegment->get('auth_token') !== NULL;
|
||||
|
||||
if ($authenticated)
|
||||
{
|
||||
$request = $request->setAuth('bearer', $anilistConfig['access_token']);
|
||||
}
|
||||
|
||||
if (array_key_exists('form_params', $options)) {
|
||||
$request = $request->setFormFields($options['form_params']);
|
||||
}
|
||||
|
||||
if (array_key_exists('query', $options)) {
|
||||
$request = $request->setQuery($options['query']);
|
||||
}
|
||||
|
||||
if (array_key_exists('body', $options)) {
|
||||
$request = $request->setJsonBody($options['body']);
|
||||
}
|
||||
|
||||
if (array_key_exists('headers', $options)) {
|
||||
$request = $request->setHeaders($options['headers']);
|
||||
}
|
||||
|
||||
return $request->getFullRequest();
|
||||
}
|
||||
|
||||
/**
|
||||
* Run a GraphQL API query
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $variables
|
||||
* @return array
|
||||
*/
|
||||
public function runQuery(string $name, array $variables = []): array
|
||||
{
|
||||
$file = realpath(__DIR__ . "/GraphQL/Queries/{$name}.graphql");
|
||||
if ( ! file_exists($file))
|
||||
{
|
||||
throw new \LogicException('GraphQL query file does not exist.');
|
||||
}
|
||||
|
||||
// $query = str_replace(["\t", "\n"], ' ', file_get_contents($file));
|
||||
$query = file_get_contents($file);
|
||||
$body = [
|
||||
'query' => $query
|
||||
];
|
||||
|
||||
if ( ! empty($variables))
|
||||
{
|
||||
$body['variables'] = [];
|
||||
foreach($variables as $key => $val)
|
||||
{
|
||||
$body['variables'][$key] = $val;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->postRequest([
|
||||
'body' => $body
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a request
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $url
|
||||
* @param array $options
|
||||
* @return \Amp\Artax\Response
|
||||
* @return Response
|
||||
*/
|
||||
private function getResponse(string $type, string $url, array $options = [])
|
||||
private function getResponse(string $url, array $options = []): Response
|
||||
{
|
||||
$logger = NULL;
|
||||
if ($this->getContainer())
|
||||
{
|
||||
$logger = $this->container->getLogger('mal-request');
|
||||
$logger = $this->container->getLogger('anilist-request');
|
||||
}
|
||||
|
||||
$request = $this->setUpRequest($url, $options);
|
||||
@ -104,14 +175,12 @@ trait AnilistTrait {
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a request
|
||||
* Remove some boilerplate for post requests
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $url
|
||||
* @param array $options
|
||||
* @return array
|
||||
*/
|
||||
private function request(string $type, string $url, array $options = []): array
|
||||
protected function postRequest(array $options = []): array
|
||||
{
|
||||
$logger = NULL;
|
||||
if ($this->getContainer())
|
||||
@ -119,44 +188,19 @@ trait AnilistTrait {
|
||||
$logger = $this->container->getLogger('anilist-request');
|
||||
}
|
||||
|
||||
$response = $this->getResponse($type, $url, $options);
|
||||
|
||||
if ((int) $response->getStatus() > 299 OR (int) $response->getStatus() < 200)
|
||||
{
|
||||
if ($logger)
|
||||
{
|
||||
$logger->warning('Non 200 response for api call', (array)$response->getBody());
|
||||
}
|
||||
}
|
||||
|
||||
return XML::toArray(wait($response->getBody()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove some boilerplate for post requests
|
||||
*
|
||||
* @param mixed ...$args
|
||||
* @return array
|
||||
*/
|
||||
protected function postRequest(...$args): array
|
||||
{
|
||||
$logger = NULL;
|
||||
if ($this->getContainer())
|
||||
{
|
||||
$logger = $this->container->getLogger('anilist-request');
|
||||
}
|
||||
|
||||
$response = $this->getResponse('POST', ...$args);
|
||||
$response = $this->getResponse(Anilist::BASE_URL, $options);
|
||||
$validResponseCodes = [200, 201];
|
||||
|
||||
if ( ! \in_array((int) $response->getStatus(), $validResponseCodes, TRUE))
|
||||
if ( ! \in_array($response->getStatus(), $validResponseCodes, TRUE))
|
||||
{
|
||||
if ($logger)
|
||||
{
|
||||
$logger->warning('Non 201 response for POST api call', (array)$response->getBody());
|
||||
$logger->warning('Non 200 response for POST api call', (array)$response->getBody());
|
||||
}
|
||||
}
|
||||
|
||||
return XML::toArray($response->getBody());
|
||||
// dump(wait($response->getBody()));
|
||||
|
||||
return Json::decode(wait($response->getBody()));
|
||||
}
|
||||
}
|
56
src/API/Anilist/GraphQL/Queries/UserAnimeList.graphql
Normal file
56
src/API/Anilist/GraphQL/Queries/UserAnimeList.graphql
Normal file
@ -0,0 +1,56 @@
|
||||
query ($name: String) {
|
||||
MediaListCollection(userName: $name, type: ANIME) {
|
||||
lists {
|
||||
entries {
|
||||
id
|
||||
mediaId
|
||||
score
|
||||
progress
|
||||
repeat
|
||||
private
|
||||
notes
|
||||
status
|
||||
media {
|
||||
id
|
||||
idMal
|
||||
title {
|
||||
romaji
|
||||
english
|
||||
native
|
||||
userPreferred
|
||||
}
|
||||
type
|
||||
format
|
||||
status
|
||||
episodes
|
||||
season
|
||||
genres
|
||||
synonyms
|
||||
countryOfOrigin
|
||||
source
|
||||
trailer {
|
||||
id
|
||||
}
|
||||
coverImage {
|
||||
large
|
||||
medium
|
||||
}
|
||||
bannerImage
|
||||
tags {
|
||||
id
|
||||
}
|
||||
externalLinks {
|
||||
id
|
||||
}
|
||||
mediaListEntry {
|
||||
id
|
||||
}
|
||||
}
|
||||
user {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
56
src/API/Anilist/GraphQL/Queries/UserMangaList.graphql
Normal file
56
src/API/Anilist/GraphQL/Queries/UserMangaList.graphql
Normal file
@ -0,0 +1,56 @@
|
||||
{query ($name: String) {
|
||||
MediaListCollection(userName: $name, type: MANGA) {
|
||||
lists {
|
||||
entries {
|
||||
id
|
||||
mediaId
|
||||
score
|
||||
progress
|
||||
progressVolumes
|
||||
repeat
|
||||
private
|
||||
notes
|
||||
status
|
||||
media {
|
||||
id
|
||||
idMal
|
||||
title {
|
||||
romaji
|
||||
english
|
||||
native
|
||||
userPreferred
|
||||
}
|
||||
type
|
||||
format
|
||||
status
|
||||
chapters
|
||||
volumes
|
||||
genres
|
||||
synonyms
|
||||
countryOfOrigin
|
||||
source
|
||||
trailer {
|
||||
id
|
||||
}
|
||||
coverImage {
|
||||
large
|
||||
medium
|
||||
}
|
||||
bannerImage
|
||||
tags {
|
||||
id
|
||||
}
|
||||
externalLinks {
|
||||
id
|
||||
}
|
||||
mediaListEntry {
|
||||
id
|
||||
}
|
||||
}
|
||||
user {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -39,127 +39,17 @@ final class Model
|
||||
public function __construct(ListItem $listItem)
|
||||
{
|
||||
$this->listItem = $listItem;
|
||||
|
||||
}
|
||||
|
||||
public function getAnimeList()
|
||||
public function getAnimeList(): array
|
||||
{
|
||||
$graphQL = <<<GQL
|
||||
{
|
||||
MediaListCollection(userId: 103470, type: ANIME) {
|
||||
lists {
|
||||
entries {
|
||||
id
|
||||
mediaId
|
||||
score
|
||||
progress
|
||||
status
|
||||
media {
|
||||
id
|
||||
idMal
|
||||
title {
|
||||
romaji
|
||||
english
|
||||
native
|
||||
userPreferred
|
||||
}
|
||||
type
|
||||
format
|
||||
status
|
||||
episodes
|
||||
season
|
||||
genres
|
||||
synonyms
|
||||
countryOfOrigin
|
||||
source
|
||||
trailer {
|
||||
id
|
||||
}
|
||||
coverImage {
|
||||
large
|
||||
medium
|
||||
}
|
||||
bannerImage
|
||||
tags {
|
||||
id
|
||||
}
|
||||
externalLinks {
|
||||
id
|
||||
}
|
||||
mediaListEntry {
|
||||
id
|
||||
}
|
||||
}
|
||||
user {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
GQL;
|
||||
return $this->runQuery('UserAnimeList', ['name' => 'timw4mail']);
|
||||
}
|
||||
|
||||
public function getMangaList()
|
||||
public function getMangaList(): array
|
||||
{
|
||||
$graphQL = <<<GQL
|
||||
{
|
||||
MediaListCollection(userId: 103470, type: MANGA) {
|
||||
lists {
|
||||
entries {
|
||||
id
|
||||
mediaId
|
||||
score
|
||||
progress
|
||||
progressVolumes
|
||||
repeat
|
||||
private
|
||||
notes
|
||||
status
|
||||
media {
|
||||
id
|
||||
idMal
|
||||
title {
|
||||
romaji
|
||||
english
|
||||
native
|
||||
userPreferred
|
||||
}
|
||||
type
|
||||
format
|
||||
status
|
||||
chapters
|
||||
volumes
|
||||
genres
|
||||
synonyms
|
||||
countryOfOrigin
|
||||
source
|
||||
trailer {
|
||||
id
|
||||
}
|
||||
coverImage {
|
||||
large
|
||||
medium
|
||||
}
|
||||
bannerImage
|
||||
tags {
|
||||
id
|
||||
}
|
||||
externalLinks {
|
||||
id
|
||||
}
|
||||
mediaListEntry {
|
||||
id
|
||||
}
|
||||
}
|
||||
user {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
GQL;
|
||||
|
||||
return $this->runQuery('UserMangaList', ['name' => 'timw4mail']);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
27
src/API/Anilist/Transformer/AnimeListTransformer.php
Normal file
27
src/API/Anilist/Transformer/AnimeListTransformer.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php declare(strict_types=1);
|
||||
/**
|
||||
* Hummingbird Anime List Client
|
||||
*
|
||||
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
|
||||
*
|
||||
* PHP version 7
|
||||
*
|
||||
* @package HummingbirdAnimeClient
|
||||
* @author Timothy J. Warren <tim@timshomepage.net>
|
||||
* @copyright 2015 - 2018 Timothy J. Warren
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @version 4.0
|
||||
* @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient
|
||||
*/
|
||||
|
||||
namespace Aviat\AnimeClient\API\Anilist\Transformer;
|
||||
|
||||
use Aviat\Ion\Transformer\AbstractTransformer;
|
||||
|
||||
class AnimeListTransformer extends AbstractTransformer {
|
||||
|
||||
public function transform($item)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
28
src/API/Anilist/Transformer/MangaListTransformer.php
Normal file
28
src/API/Anilist/Transformer/MangaListTransformer.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php declare(strict_types=1);
|
||||
/**
|
||||
* Hummingbird Anime List Client
|
||||
*
|
||||
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
|
||||
*
|
||||
* PHP version 7
|
||||
*
|
||||
* @package HummingbirdAnimeClient
|
||||
* @author Timothy J. Warren <tim@timshomepage.net>
|
||||
* @copyright 2015 - 2018 Timothy J. Warren
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @version 4.0
|
||||
* @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient
|
||||
*/
|
||||
|
||||
namespace Aviat\AnimeClient\API\Anilist\Transformer;
|
||||
|
||||
use Aviat\Ion\Transformer\AbstractTransformer;
|
||||
|
||||
class MangaListTransformer extends AbstractTransformer
|
||||
{
|
||||
|
||||
public function transform($item)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@ -22,10 +22,10 @@ use Aviat\Ion\Enum;
|
||||
* Possible values for watching status for the current anime
|
||||
*/
|
||||
final class Anilist extends Enum {
|
||||
const WATCHING = 'CURRENT';
|
||||
const READING = 'CURRENT';
|
||||
const COMPLETED = 'COMPLETED';
|
||||
const ON_HOLD = 'PAUSED';
|
||||
const DROPPED = 'DROPPED';
|
||||
const PLAN_TO_WATCH = 'PLANNING';
|
||||
const PLAN_TO_READ = 'PLANNING';
|
||||
const REPEATING = 'REPEATING';
|
||||
}
|
Loading…
Reference in New Issue
Block a user