Version 5.1 - All the GraphQL #32
@ -24,6 +24,8 @@
|
|||||||
"aura/session": "^2.0",
|
"aura/session": "^2.0",
|
||||||
"aviat/banker": "^1.0.0",
|
"aviat/banker": "^1.0.0",
|
||||||
"aviat/ion": "^2.3.0",
|
"aviat/ion": "^2.3.0",
|
||||||
|
"ext-gd":"*",
|
||||||
|
"ext-pdo": "*",
|
||||||
"maximebf/consolekit": "^1.0",
|
"maximebf/consolekit": "^1.0",
|
||||||
"monolog/monolog": "^1.0",
|
"monolog/monolog": "^1.0",
|
||||||
"psr/http-message": "~1.0",
|
"psr/http-message": "~1.0",
|
||||||
|
@ -84,26 +84,30 @@ trait AnilistTrait {
|
|||||||
->get('session')
|
->get('session')
|
||||||
->getSegment(SESSION_SEGMENT);
|
->getSegment(SESSION_SEGMENT);
|
||||||
|
|
||||||
$authenticated = $sessionSegment->get('auth_token') !== NULL;
|
//$authenticated = $sessionSegment->get('auth_token') !== NULL;
|
||||||
|
|
||||||
if ($authenticated)
|
//if ($authenticated)
|
||||||
{
|
{
|
||||||
$request = $request->setAuth('bearer', $anilistConfig['access_token']);
|
$request = $request->setAuth('bearer', $anilistConfig['access_token']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array_key_exists('form_params', $options)) {
|
if (array_key_exists('form_params', $options))
|
||||||
|
{
|
||||||
$request = $request->setFormFields($options['form_params']);
|
$request = $request->setFormFields($options['form_params']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array_key_exists('query', $options)) {
|
if (array_key_exists('query', $options))
|
||||||
|
{
|
||||||
$request = $request->setQuery($options['query']);
|
$request = $request->setQuery($options['query']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array_key_exists('body', $options)) {
|
if (array_key_exists('body', $options))
|
||||||
|
{
|
||||||
$request = $request->setJsonBody($options['body']);
|
$request = $request->setJsonBody($options['body']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array_key_exists('headers', $options)) {
|
if (array_key_exists('headers', $options))
|
||||||
|
{
|
||||||
$request = $request->setHeaders($options['headers']);
|
$request = $request->setHeaders($options['headers']);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,7 +152,8 @@ trait AnilistTrait {
|
|||||||
public function mutateRequest (string $name, array $variables = []): Request
|
public function mutateRequest (string $name, array $variables = []): Request
|
||||||
{
|
{
|
||||||
$file = realpath(__DIR__ . "/GraphQL/Mutations/{$name}.graphql");
|
$file = realpath(__DIR__ . "/GraphQL/Mutations/{$name}.graphql");
|
||||||
if (!file_exists($file)) {
|
if (!file_exists($file))
|
||||||
|
{
|
||||||
throw new \LogicException('GraphQL mutation file does not exist.');
|
throw new \LogicException('GraphQL mutation file does not exist.');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,7 +166,8 @@ trait AnilistTrait {
|
|||||||
|
|
||||||
if (!empty($variables)) {
|
if (!empty($variables)) {
|
||||||
$body['variables'] = [];
|
$body['variables'] = [];
|
||||||
foreach ($variables as $key => $val) {
|
foreach ($variables as $key => $val)
|
||||||
|
{
|
||||||
$body['variables'][$key] = $val;
|
$body['variables'][$key] = $val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -211,7 +217,8 @@ trait AnilistTrait {
|
|||||||
private function getResponseFromRequest(Request $request): Response
|
private function getResponseFromRequest(Request $request): Response
|
||||||
{
|
{
|
||||||
$logger = NULL;
|
$logger = NULL;
|
||||||
if ($this->getContainer()) {
|
if ($this->getContainer())
|
||||||
|
{
|
||||||
$logger = $this->container->getLogger('anilist-request');
|
$logger = $this->container->getLogger('anilist-request');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,15 +243,22 @@ trait AnilistTrait {
|
|||||||
*/
|
*/
|
||||||
protected function postRequest(array $options = []): array
|
protected function postRequest(array $options = []): array
|
||||||
{
|
{
|
||||||
|
$response = $this->getResponse(Anilist::BASE_URL, $options);
|
||||||
|
$validResponseCodes = [200, 201];
|
||||||
|
|
||||||
$logger = NULL;
|
$logger = NULL;
|
||||||
if ($this->getContainer())
|
if ($this->getContainer())
|
||||||
{
|
{
|
||||||
$logger = $this->container->getLogger('anilist-request');
|
$logger = $this->container->getLogger('anilist-request');
|
||||||
|
$logger->debug('Anilist response', [
|
||||||
|
'status' => $response->getStatus(),
|
||||||
|
'reason' => $response->getReason(),
|
||||||
|
'body' => $response->getBody(),
|
||||||
|
'headers' => $response->getHeaders(),
|
||||||
|
//'requestHeaders' => $request->getHeaders(),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$response = $this->getResponse(Anilist::BASE_URL, $options);
|
|
||||||
$validResponseCodes = [200, 201];
|
|
||||||
|
|
||||||
if ( ! \in_array($response->getStatus(), $validResponseCodes, TRUE))
|
if ( ! \in_array($response->getStatus(), $validResponseCodes, TRUE))
|
||||||
{
|
{
|
||||||
if ($logger)
|
if ($logger)
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
mutation (
|
||||||
|
$id: Int,
|
||||||
|
$notes: String,
|
||||||
|
$private: Boolean,
|
||||||
|
$progress: Int,
|
||||||
|
$repeat: Int,
|
||||||
|
$status: MediaListStatus,
|
||||||
|
$score: Int,
|
||||||
|
) {
|
||||||
|
SaveMediaListEntry (
|
||||||
|
mediaId: $id,
|
||||||
|
notes: $notes,
|
||||||
|
private: $private,
|
||||||
|
progress: $progress,
|
||||||
|
repeat: $repeat,
|
||||||
|
scoreRaw: $score,
|
||||||
|
status: $status
|
||||||
|
) {
|
||||||
|
mediaId
|
||||||
|
notes
|
||||||
|
private
|
||||||
|
progress
|
||||||
|
repeat
|
||||||
|
score(format: POINT_10)
|
||||||
|
status
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
query ($id: Int) {
|
query ($id: Int, $type: MediaType) {
|
||||||
Media (idMal: $id) {
|
Media (idMal: $id, type: $type) {
|
||||||
mediaListEntry {
|
mediaListEntry {
|
||||||
id
|
id
|
||||||
userId
|
userId
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
query ($id: Int, $userName: String) {
|
||||||
|
MediaList (mediaId: $id, userName: $userName) {
|
||||||
|
id
|
||||||
|
userId
|
||||||
|
mediaId
|
||||||
|
}
|
||||||
|
}
|
27
src/API/Anilist/GraphQL/Queries/SyncUserList.graphql
Normal file
27
src/API/Anilist/GraphQL/Queries/SyncUserList.graphql
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
query ($name: String, $type: MediaType) {
|
||||||
|
MediaListCollection(userName: $name, type: $type) {
|
||||||
|
lists {
|
||||||
|
entries {
|
||||||
|
id
|
||||||
|
mediaId
|
||||||
|
score
|
||||||
|
progress
|
||||||
|
progressVolumes
|
||||||
|
repeat
|
||||||
|
private
|
||||||
|
notes
|
||||||
|
status
|
||||||
|
media {
|
||||||
|
id
|
||||||
|
idMal
|
||||||
|
title {
|
||||||
|
romaji
|
||||||
|
english
|
||||||
|
native
|
||||||
|
userPreferred
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -24,7 +24,6 @@ query ($name: String) {
|
|||||||
status
|
status
|
||||||
episodes
|
episodes
|
||||||
season
|
season
|
||||||
seasonYear
|
|
||||||
genres
|
genres
|
||||||
synonyms
|
synonyms
|
||||||
countryOfOrigin
|
countryOfOrigin
|
||||||
|
@ -19,6 +19,7 @@ namespace Aviat\AnimeClient\API\Anilist;
|
|||||||
use Amp\Artax\Request;
|
use Amp\Artax\Request;
|
||||||
|
|
||||||
use Aviat\AnimeClient\API\ListItemInterface;
|
use Aviat\AnimeClient\API\ListItemInterface;
|
||||||
|
use Aviat\AnimeClient\API\Enum\AnimeWatchingStatus\Anilist as AnilistStatus;
|
||||||
use Aviat\AnimeClient\API\Mapping\AnimeWatchingStatus;
|
use Aviat\AnimeClient\API\Mapping\AnimeWatchingStatus;
|
||||||
use Aviat\AnimeClient\Types\FormItemData;
|
use Aviat\AnimeClient\Types\FormItemData;
|
||||||
|
|
||||||
@ -29,7 +30,7 @@ final class ListItem implements ListItemInterface{
|
|||||||
use AnilistTrait;
|
use AnilistTrait;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a list item
|
* Create a minimal list item
|
||||||
*
|
*
|
||||||
* @param array $data
|
* @param array $data
|
||||||
* @return Request
|
* @return Request
|
||||||
@ -39,6 +40,17 @@ final class ListItem implements ListItemInterface{
|
|||||||
return $this->mutateRequest('CreateMediaListEntry', $data);
|
return $this->mutateRequest('CreateMediaListEntry', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a fleshed-out list item
|
||||||
|
*
|
||||||
|
* @param array $data
|
||||||
|
* @return Request
|
||||||
|
*/
|
||||||
|
public function createFull(array $data): Request
|
||||||
|
{
|
||||||
|
return $this->mutateRequest('CreateFullMediaListEntry', $data);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete a list item
|
* Delete a list item
|
||||||
*
|
*
|
||||||
@ -90,18 +102,20 @@ final class ListItem implements ListItemInterface{
|
|||||||
|
|
||||||
$notes = $data['notes'] ?? '';
|
$notes = $data['notes'] ?? '';
|
||||||
$progress = array_key_exists('progress', $array) ? $data['progress'] : 0;
|
$progress = array_key_exists('progress', $array) ? $data['progress'] : 0;
|
||||||
|
$private = array_key_exists('private', $array) ? (bool)$data['private'] : false;
|
||||||
$rating = array_key_exists('rating', $array) ? $data['rating'] : NULL;
|
$rating = array_key_exists('rating', $array) ? $data['rating'] : NULL;
|
||||||
$status = $data['status'];
|
$status = ($data['reconsuming'] === true) ? AnilistStatus::REPEATING : AnimeWatchingStatus::KITSU_TO_ANILIST[$data['status']];
|
||||||
|
|
||||||
// @TODO Handle weirdness with reWatching
|
$updateData = [
|
||||||
return $this->mutateRequest('UpdateMediaListEntry', [
|
'id' => (int)$id,
|
||||||
'id' => $id,
|
'status' => $status,
|
||||||
'status' => AnimeWatchingStatus::KITSU_TO_ANILIST[$status],
|
'score' => $rating * 10,
|
||||||
'score' => $rating * 20,
|
|
||||||
'progress' => $progress,
|
'progress' => $progress,
|
||||||
'repeat' => (int)$data['reconsumeCount'],
|
'repeat' => (int)$data['reconsumeCount'],
|
||||||
'private' => (bool)$data['private'],
|
'private' => $private,
|
||||||
'notes' => $notes,
|
'notes' => $notes,
|
||||||
]);
|
];
|
||||||
|
|
||||||
|
return $this->mutateRequest('UpdateMediaListEntry', $updateData);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
namespace Aviat\AnimeClient\API\Anilist;
|
namespace Aviat\AnimeClient\API\Anilist;
|
||||||
|
|
||||||
|
use InvalidArgumentException;
|
||||||
|
|
||||||
use Amp\Artax\Request;
|
use Amp\Artax\Request;
|
||||||
use Aviat\AnimeClient\API\Mapping\{AnimeWatchingStatus, MangaReadingStatus};
|
use Aviat\AnimeClient\API\Mapping\{AnimeWatchingStatus, MangaReadingStatus};
|
||||||
use Aviat\AnimeClient\Types\FormItem;
|
use Aviat\AnimeClient\Types\FormItem;
|
||||||
@ -45,6 +47,30 @@ final class Model
|
|||||||
// ! Generic API calls
|
// ! Generic API calls
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get user list data for syncing with Kitsu
|
||||||
|
*
|
||||||
|
* @param string $type
|
||||||
|
* @return array
|
||||||
|
* @throws \Aviat\Ion\Di\Exception\ContainerException
|
||||||
|
* @throws \Aviat\Ion\Di\Exception\NotFoundException
|
||||||
|
*/
|
||||||
|
public function getSyncList(string $type = 'anime'): array
|
||||||
|
{
|
||||||
|
$config = $this->container->get('config');
|
||||||
|
$anilistUser = $config->get(['anilist', 'username']);
|
||||||
|
|
||||||
|
if ( ! is_string($anilistUser))
|
||||||
|
{
|
||||||
|
throw new InvalidArgumentException('Anilist username is not defined in config');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->runQuery('SyncUserList', [
|
||||||
|
'name' => $anilistUser,
|
||||||
|
'type' => $type,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a list item
|
* Create a list item
|
||||||
*
|
*
|
||||||
@ -56,14 +82,22 @@ final class Model
|
|||||||
{
|
{
|
||||||
$createData = [];
|
$createData = [];
|
||||||
|
|
||||||
$mediaId = $this->getMediaIdFromMalId($data['mal_id'], strtoupper($type));
|
$mediaId = $this->getMediaIdFromMalId($data['mal_id'], mb_strtoupper($type));
|
||||||
|
|
||||||
if ($type === 'anime') {
|
if (empty($mediaId))
|
||||||
|
{
|
||||||
|
throw new InvalidArgumentException('Media id missing');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($type === 'anime')
|
||||||
|
{
|
||||||
$createData = [
|
$createData = [
|
||||||
'id' => $mediaId,
|
'id' => $mediaId,
|
||||||
'status' => AnimeWatchingStatus::KITSU_TO_ANILIST[$data['status']],
|
'status' => AnimeWatchingStatus::KITSU_TO_ANILIST[$data['status']],
|
||||||
];
|
];
|
||||||
} elseif ($type === 'manga') {
|
}
|
||||||
|
elseif ($type === 'manga')
|
||||||
|
{
|
||||||
$createData = [
|
$createData = [
|
||||||
'id' => $mediaId,
|
'id' => $mediaId,
|
||||||
'status' => MangaReadingStatus::KITSU_TO_ANILIST[$data['status']],
|
'status' => MangaReadingStatus::KITSU_TO_ANILIST[$data['status']],
|
||||||
@ -73,15 +107,32 @@ final class Model
|
|||||||
return $this->listItem->create($createData, $type);
|
return $this->listItem->create($createData, $type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a list item with all the relevant data
|
||||||
|
*
|
||||||
|
* @param array $data
|
||||||
|
* @param string $type
|
||||||
|
* @return Request
|
||||||
|
*/
|
||||||
|
public function createFullListItem(array $data, string $type = 'anime'): Request
|
||||||
|
{
|
||||||
|
$createData = $data['data'];
|
||||||
|
$mediaId = $this->getMediaIdFromMalId($data['mal_id']);
|
||||||
|
|
||||||
|
$createData['id'] = $mediaId;
|
||||||
|
|
||||||
|
return $this->listItem->createFull($createData);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the data for a specific list item, generally for editing
|
* Get the data for a specific list item, generally for editing
|
||||||
*
|
*
|
||||||
* @param string $malId - The unique identifier of that list item
|
* @param string $malId - The unique identifier of that list item
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function getListItem(string $malId): array
|
public function getListItem(string $malId, string $type): array
|
||||||
{
|
{
|
||||||
$id = $this->getListIdFromMalId($malId);
|
$id = $this->getListIdFromMalId($malId, $type);
|
||||||
|
|
||||||
$data = $this->listItem->get($id)['data'];
|
$data = $this->listItem->get($id)['data'];
|
||||||
|
|
||||||
@ -96,9 +147,9 @@ final class Model
|
|||||||
* @param FormItem $data
|
* @param FormItem $data
|
||||||
* @return Request
|
* @return Request
|
||||||
*/
|
*/
|
||||||
public function incrementListItem(FormItem $data): Request
|
public function incrementListItem(FormItem $data, string $type): Request
|
||||||
{
|
{
|
||||||
$id = $this->getListIdFromMalId($data['mal_id']);
|
$id = $this->getListIdFromMalId($data['mal_id'], $type);
|
||||||
|
|
||||||
return $this->listItem->increment($id, $data['data']);
|
return $this->listItem->increment($id, $data['data']);
|
||||||
}
|
}
|
||||||
@ -107,11 +158,12 @@ final class Model
|
|||||||
* Modify a list item
|
* Modify a list item
|
||||||
*
|
*
|
||||||
* @param FormItem $data
|
* @param FormItem $data
|
||||||
|
* @param int [$id]
|
||||||
* @return Request
|
* @return Request
|
||||||
*/
|
*/
|
||||||
public function updateListItem(FormItem $data): Request
|
public function updateListItem(FormItem $data, string $type): Request
|
||||||
{
|
{
|
||||||
$id = $this->getListIdFromMalId($data['mal_id']);
|
$id = $this->getListIdFromMalId($data['mal_id'], mb_strtoupper($type));
|
||||||
|
|
||||||
return $this->listItem->update($id, $data['data']);
|
return $this->listItem->update($id, $data['data']);
|
||||||
}
|
}
|
||||||
@ -122,9 +174,9 @@ final class Model
|
|||||||
* @param string $malId - The id of the list item to remove
|
* @param string $malId - The id of the list item to remove
|
||||||
* @return Request
|
* @return Request
|
||||||
*/
|
*/
|
||||||
public function deleteListItem(string $malId): Request
|
public function deleteListItem(string $malId, string $type): Request
|
||||||
{
|
{
|
||||||
$item_id = $this->getListIdFromMalId($malId);
|
$item_id = $this->getListIdFromMalId($malId, $type);
|
||||||
|
|
||||||
return $this->listItem->delete($item_id);
|
return $this->listItem->delete($item_id);
|
||||||
}
|
}
|
||||||
@ -135,10 +187,35 @@ final class Model
|
|||||||
* @param string $malId
|
* @param string $malId
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getListIdFromMalId(string $malId): ?string
|
public function getListIdFromMalId(string $malId, string $type): ?string
|
||||||
{
|
{
|
||||||
$info = $this->runQuery('ListItemIdByMalId', ['id' => $malId]);
|
$mediaId = $this->getMediaIdFromMalId($malId, $type);
|
||||||
return (string)$info['data']['Media']['mediaListEntry']['id'] ?? NULL;
|
return $this->getListIdFromMediaId($mediaId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Anilist media id from its MAL id
|
||||||
|
* this way is more accurate than getting the list item id
|
||||||
|
* directly from the MAL id
|
||||||
|
*/
|
||||||
|
private function getListIdFromMediaId(string $mediaId)
|
||||||
|
{
|
||||||
|
$config = $this->container->get('config');
|
||||||
|
$anilistUser = $config->get(['anilist', 'username']);
|
||||||
|
|
||||||
|
$info = $this->runQuery('ListItemIdByMediaId', [
|
||||||
|
'id' => $mediaId,
|
||||||
|
'userName' => $anilistUser,
|
||||||
|
]);
|
||||||
|
|
||||||
|
/* dump([
|
||||||
|
'media_id' => $mediaId,
|
||||||
|
'userName' => $anilistUser,
|
||||||
|
'response' => $info,
|
||||||
|
]);
|
||||||
|
die(); */
|
||||||
|
|
||||||
|
return (string)$info['data']['MediaList']['id'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -152,9 +229,15 @@ final class Model
|
|||||||
{
|
{
|
||||||
$info = $this->runQuery('MediaIdByMalId', [
|
$info = $this->runQuery('MediaIdByMalId', [
|
||||||
'id' => $malId,
|
'id' => $malId,
|
||||||
'type' => $type
|
'type' => mb_strtoupper($type),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
/* dump([
|
||||||
|
'mal_id' => $malId,
|
||||||
|
'response' => $info,
|
||||||
|
]);
|
||||||
|
die(); */
|
||||||
|
|
||||||
return (string)$info['data']['Media']['id'];
|
return (string)$info['data']['Media']['id'];
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -16,22 +16,51 @@
|
|||||||
|
|
||||||
namespace Aviat\AnimeClient\API\Anilist\Transformer;
|
namespace Aviat\AnimeClient\API\Anilist\Transformer;
|
||||||
|
|
||||||
use Aviat\AnimeClient\Types\{AnimeListItem, AnimeFormItem};
|
use Aviat\AnimeClient\API\Enum\AnimeWatchingStatus\Anilist as AnilistStatus;
|
||||||
|
use Aviat\AnimeClient\API\Mapping\AnimeWatchingStatus;
|
||||||
|
use Aviat\AnimeClient\Types\{Anime, AnimeListItem, AnimeFormItem};
|
||||||
|
|
||||||
use Aviat\Ion\Transformer\AbstractTransformer;
|
use Aviat\Ion\Transformer\AbstractTransformer;
|
||||||
|
|
||||||
class AnimeListTransformer extends AbstractTransformer {
|
class AnimeListTransformer extends AbstractTransformer {
|
||||||
|
|
||||||
public function transform($item): AnimeListItem
|
public function transform($item): AnimeListItem
|
||||||
{
|
{
|
||||||
dump($item); die();
|
return new AnimeListItem([]);
|
||||||
|
}
|
||||||
return new AnimeListItem([
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform Anilist list item to Kitsu form update format
|
||||||
|
*
|
||||||
|
* @param array $item
|
||||||
|
* @return AnimeFormItem
|
||||||
|
*/
|
||||||
|
public function untransform(array $item): AnimeFormItem
|
||||||
|
{
|
||||||
|
return new AnimeFormItem([
|
||||||
|
'id' => $item['id'],
|
||||||
|
'mal_id' => $item['media']['idMal'],
|
||||||
|
'data' => [
|
||||||
|
'notes' => $item['notes'] ?? '',
|
||||||
|
'private' => $item['private'],
|
||||||
|
'progress' => $item['progress'],
|
||||||
|
'rating' => $item['score'],
|
||||||
|
'reconsumeCount' => $item['repeat'],
|
||||||
|
'reconsuming' => $item['status'] === AnilistStatus::REPEATING,
|
||||||
|
'status' => AnimeWatchingStatus::ANILIST_TO_KITSU[$item['status']],
|
||||||
|
]
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function untransform(array $item): AnimeFormItem
|
/**
|
||||||
|
* Transform a set of structures
|
||||||
|
*
|
||||||
|
* @param array|object $collection
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function untransformCollection($collection): array
|
||||||
{
|
{
|
||||||
return new AnimeFormItem($item);
|
$list = (array)$collection;
|
||||||
|
return array_map([$this, 'untransform'], $list);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -16,7 +16,10 @@
|
|||||||
|
|
||||||
namespace Aviat\AnimeClient\API\Anilist\Transformer;
|
namespace Aviat\AnimeClient\API\Anilist\Transformer;
|
||||||
|
|
||||||
|
use Aviat\AnimeClient\API\Enum\MangaReadingStatus\Anilist as AnilistStatus;
|
||||||
|
use Aviat\AnimeClient\API\Mapping\MangaReadingStatus;
|
||||||
use Aviat\AnimeClient\Types\MangaFormItem;
|
use Aviat\AnimeClient\Types\MangaFormItem;
|
||||||
|
|
||||||
use Aviat\Ion\Transformer\AbstractTransformer;
|
use Aviat\Ion\Transformer\AbstractTransformer;
|
||||||
|
|
||||||
class MangaListTransformer extends AbstractTransformer {
|
class MangaListTransformer extends AbstractTransformer {
|
||||||
@ -26,8 +29,38 @@ class MangaListTransformer extends AbstractTransformer {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform Anilist list item to Kitsu form update format
|
||||||
|
*
|
||||||
|
* @param array $item
|
||||||
|
* @return MangaFormItem
|
||||||
|
*/
|
||||||
public function untransform(array $item): MangaFormItem
|
public function untransform(array $item): MangaFormItem
|
||||||
{
|
{
|
||||||
return new MangaFormItem($item);
|
return new MangaFormItem([
|
||||||
|
'id' => $item['id'],
|
||||||
|
'mal_id' => $item['media']['idMal'],
|
||||||
|
'data' => [
|
||||||
|
'notes' => $item['notes'] ?? '',
|
||||||
|
'private' => $item['private'],
|
||||||
|
'progress' => $item['progress'],
|
||||||
|
'rating' => $item['score'],
|
||||||
|
'reconsumeCount' => $item['repeat'],
|
||||||
|
'reconsuming' => $item['status'] === AnilistStatus::REPEATING,
|
||||||
|
'status' => MangaReadingStatus::ANILIST_TO_KITSU[$item['status']],
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform a set of structures
|
||||||
|
*
|
||||||
|
* @param array|object $collection
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function untransformCollection($collection): array
|
||||||
|
{
|
||||||
|
$list = (array)$collection;
|
||||||
|
return array_map([$this, 'untransform'], $list);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -62,6 +62,11 @@ final class ListItem implements ListItemInterface {
|
|||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
|
if (array_key_exists('notes', $data))
|
||||||
|
{
|
||||||
|
$body['data']['attributes']['notes'] = $data['notes'];
|
||||||
|
}
|
||||||
|
|
||||||
$authHeader = $this->getAuthHeader();
|
$authHeader = $this->getAuthHeader();
|
||||||
|
|
||||||
$request = $this->requestBuilder->newRequest('POST', 'library-entries');
|
$request = $this->requestBuilder->newRequest('POST', 'library-entries');
|
||||||
|
@ -37,11 +37,8 @@ use Aviat\AnimeClient\API\Kitsu\Transformer\{
|
|||||||
MangaListTransformer
|
MangaListTransformer
|
||||||
};
|
};
|
||||||
use Aviat\AnimeClient\Types\{
|
use Aviat\AnimeClient\Types\{
|
||||||
AbstractType,
|
|
||||||
Anime,
|
Anime,
|
||||||
FormItem,
|
FormItem,
|
||||||
FormItemData,
|
|
||||||
AnimeListItem,
|
|
||||||
MangaPage
|
MangaPage
|
||||||
};
|
};
|
||||||
use Aviat\Ion\{Di\ContainerAware, Json};
|
use Aviat\Ion\{Di\ContainerAware, Json};
|
||||||
|
@ -45,8 +45,8 @@ final class AnimeListTransformer extends AbstractTransformer {
|
|||||||
$genres = array_column($anime['relationships']['genres'], 'name') ?? [];
|
$genres = array_column($anime['relationships']['genres'], 'name') ?? [];
|
||||||
sort($genres);
|
sort($genres);
|
||||||
|
|
||||||
$rating = (int) $item['attributes']['rating'] !== 0
|
$rating = (int) $item['attributes']['ratingTwenty'] !== 0
|
||||||
? 2 * $item['attributes']['rating']
|
? $item['attributes']['ratingTwenty'] / 2
|
||||||
: '-';
|
: '-';
|
||||||
|
|
||||||
$total_episodes = array_key_exists('episodeCount', $anime) && (int) $anime['episodeCount'] !== 0
|
$total_episodes = array_key_exists('episodeCount', $anime) && (int) $anime['episodeCount'] !== 0
|
||||||
@ -141,7 +141,7 @@ final class AnimeListTransformer extends AbstractTransformer {
|
|||||||
|
|
||||||
if (is_numeric($item['user_rating']) && $item['user_rating'] > 0)
|
if (is_numeric($item['user_rating']) && $item['user_rating'] > 0)
|
||||||
{
|
{
|
||||||
$untransformed['data']['rating'] = $item['user_rating'] / 2;
|
$untransformed['data']['ratingTwenty'] = $item['user_rating'] * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $untransformed;
|
return $untransformed;
|
||||||
|
@ -46,8 +46,8 @@ final class MangaListTransformer extends AbstractTransformer {
|
|||||||
$genres = array_column($manga['relationships']['genres'], 'name') ?? [];
|
$genres = array_column($manga['relationships']['genres'], 'name') ?? [];
|
||||||
sort($genres);
|
sort($genres);
|
||||||
|
|
||||||
$rating = (int) $item['attributes']['rating'] !== 0
|
$rating = (int) $item['attributes']['ratingTwenty'] !== 0
|
||||||
? 2 * $item['attributes']['rating']
|
? $item['attributes']['ratingTwenty'] / 2
|
||||||
: '-';
|
: '-';
|
||||||
|
|
||||||
$totalChapters = ((int) $manga['chapterCount'] !== 0)
|
$totalChapters = ((int) $manga['chapterCount'] !== 0)
|
||||||
@ -138,7 +138,7 @@ final class MangaListTransformer extends AbstractTransformer {
|
|||||||
|
|
||||||
if (is_numeric($item['new_rating']) && $item['new_rating'] > 0)
|
if (is_numeric($item['new_rating']) && $item['new_rating'] > 0)
|
||||||
{
|
{
|
||||||
$map['data']['rating'] = $item['new_rating'] / 2;
|
$map['data']['ratingTwenty'] = $item['new_rating'] * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $map;
|
return $map;
|
||||||
|
@ -66,6 +66,7 @@ final class ParallelAPIRequest {
|
|||||||
* Actually make the requests
|
* Actually make the requests
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
|
* @throws \Throwable
|
||||||
*/
|
*/
|
||||||
public function makeRequests(): array
|
public function makeRequests(): array
|
||||||
{
|
{
|
||||||
|
@ -21,6 +21,7 @@ use function Aviat\AnimeClient\loadToml;
|
|||||||
use Aura\Session\SessionFactory;
|
use Aura\Session\SessionFactory;
|
||||||
use Aviat\AnimeClient\Util;
|
use Aviat\AnimeClient\Util;
|
||||||
use Aviat\AnimeClient\API\CacheTrait;
|
use Aviat\AnimeClient\API\CacheTrait;
|
||||||
|
use Aviat\AnimeClient\API\Anilist;
|
||||||
use Aviat\AnimeClient\API\Kitsu;
|
use Aviat\AnimeClient\API\Kitsu;
|
||||||
use Aviat\AnimeClient\API\Kitsu\KitsuRequestBuilder;
|
use Aviat\AnimeClient\API\Kitsu\KitsuRequestBuilder;
|
||||||
use Aviat\Banker\Pool;
|
use Aviat\Banker\Pool;
|
||||||
@ -85,7 +86,10 @@ class BaseCommand extends Command {
|
|||||||
$app_logger->pushHandler(new RotatingFileHandler($APP_DIR . '/logs/app-cli.log', Logger::NOTICE));
|
$app_logger->pushHandler(new RotatingFileHandler($APP_DIR . '/logs/app-cli.log', Logger::NOTICE));
|
||||||
$kitsu_request_logger = new Logger('kitsu-request');
|
$kitsu_request_logger = new Logger('kitsu-request');
|
||||||
$kitsu_request_logger->pushHandler(new RotatingFileHandler($APP_DIR . '/logs/kitsu_request-cli.log', Logger::NOTICE));
|
$kitsu_request_logger->pushHandler(new RotatingFileHandler($APP_DIR . '/logs/kitsu_request-cli.log', Logger::NOTICE));
|
||||||
|
$anilistRequestLogger = new Logger('anilist-request');
|
||||||
|
$anilistRequestLogger->pushHandler(new RotatingFileHandler($APP_DIR . '/logs/anilist_request-cli.log', Logger::NOTICE));
|
||||||
$container->setLogger($app_logger);
|
$container->setLogger($app_logger);
|
||||||
|
$container->setLogger($anilistRequestLogger, 'anilist-request');
|
||||||
$container->setLogger($kitsu_request_logger, 'kitsu-request');
|
$container->setLogger($kitsu_request_logger, 'kitsu-request');
|
||||||
|
|
||||||
// Create Config Object
|
// Create Config Object
|
||||||
@ -122,6 +126,20 @@ class BaseCommand extends Command {
|
|||||||
$model->setCache($cache);
|
$model->setCache($cache);
|
||||||
return $model;
|
return $model;
|
||||||
});
|
});
|
||||||
|
$container->set('anilist-model', function ($container) {
|
||||||
|
$requestBuilder = new Anilist\AnilistRequestBuilder();
|
||||||
|
$requestBuilder->setLogger($container->getLogger('anilist-request'));
|
||||||
|
|
||||||
|
$listItem = new Anilist\ListItem();
|
||||||
|
$listItem->setContainer($container);
|
||||||
|
$listItem->setRequestBuilder($requestBuilder);
|
||||||
|
|
||||||
|
$model = new Anilist\Model($listItem);
|
||||||
|
$model->setContainer($container);
|
||||||
|
$model->setRequestBuilder($requestBuilder);
|
||||||
|
|
||||||
|
return $model;
|
||||||
|
});
|
||||||
|
|
||||||
$container->set('util', function($container) {
|
$container->set('util', function($container) {
|
||||||
return new Util($container);
|
return new Util($container);
|
||||||
|
@ -16,19 +16,28 @@
|
|||||||
|
|
||||||
namespace Aviat\AnimeClient\Command;
|
namespace Aviat\AnimeClient\Command;
|
||||||
|
|
||||||
use Aviat\AnimeClient\API\{
|
use Aviat\AnimeClient\API\
|
||||||
FailedResponseException,
|
{FailedResponseException, JsonAPI, Kitsu\Transformer\MangaListTransformer, ParallelAPIRequest};
|
||||||
JsonAPI,
|
use Aviat\AnimeClient\API\Anilist\Transformer\{
|
||||||
ParallelAPIRequest
|
AnimeListTransformer as AALT,
|
||||||
|
MangaListTransformer as AMLT,
|
||||||
};
|
};
|
||||||
|
use Aviat\AnimeClient\API\Mapping\{AnimeWatchingStatus, MangaReadingStatus};
|
||||||
|
use Aviat\AnimeClient\Types\{AnimeFormItem, MangaFormItem};
|
||||||
use Aviat\Ion\Json;
|
use Aviat\Ion\Json;
|
||||||
use DateTime;
|
use DateTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears the API Cache
|
* Syncs list data between Anilist and Kitsu
|
||||||
*/
|
*/
|
||||||
final class SyncLists extends BaseCommand {
|
final class SyncLists extends BaseCommand {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model for making requests to Anilist API
|
||||||
|
* @var \Aviat\AnimeClient\API\Anilist\Model
|
||||||
|
*/
|
||||||
|
protected $anilistModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Model for making requests to Kitsu API
|
* Model for making requests to Kitsu API
|
||||||
* @var \Aviat\AnimeClient\API\Kitsu\Model
|
* @var \Aviat\AnimeClient\API\Kitsu\Model
|
||||||
@ -36,7 +45,7 @@ final class SyncLists extends BaseCommand {
|
|||||||
protected $kitsuModel;
|
protected $kitsuModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run the Kitsu <=> MAL sync script
|
* Run the Kitsu <=> Anilist sync script
|
||||||
*
|
*
|
||||||
* @param array $args
|
* @param array $args
|
||||||
* @param array $options
|
* @param array $options
|
||||||
@ -48,6 +57,7 @@ final class SyncLists extends BaseCommand {
|
|||||||
{
|
{
|
||||||
$this->setContainer($this->setupContainer());
|
$this->setContainer($this->setupContainer());
|
||||||
$this->setCache($this->container->get('cache'));
|
$this->setCache($this->container->get('cache'));
|
||||||
|
$this->anilistModel = $this->container->get('anilist-model');
|
||||||
$this->kitsuModel = $this->container->get('kitsu-model');
|
$this->kitsuModel = $this->container->get('kitsu-model');
|
||||||
|
|
||||||
$this->sync('anime');
|
$this->sync('anime');
|
||||||
@ -64,18 +74,6 @@ final class SyncLists extends BaseCommand {
|
|||||||
{
|
{
|
||||||
$uType = ucfirst($type);
|
$uType = ucfirst($type);
|
||||||
|
|
||||||
// Do a little check to make sure you don't have immediate issues
|
|
||||||
// if you have 0 or 1 items in a list on MAL.
|
|
||||||
/* $malList = $this->malModel->getList($type);
|
|
||||||
$malCount = 0;
|
|
||||||
if ( ! empty($malList))
|
|
||||||
{
|
|
||||||
$malCount = count(array_key_exists(0, $malList)
|
|
||||||
? $malList
|
|
||||||
: [$malList]
|
|
||||||
);
|
|
||||||
} */
|
|
||||||
|
|
||||||
$kitsuCount = 0;
|
$kitsuCount = 0;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -87,24 +85,23 @@ final class SyncLists extends BaseCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// $this->echoBox("Number of MAL {$type} list items: {$malCount}");
|
|
||||||
$this->echoBox("Number of Kitsu {$type} list items: {$kitsuCount}");
|
$this->echoBox("Number of Kitsu {$type} list items: {$kitsuCount}");
|
||||||
|
|
||||||
$data = $this->diffLists($type);
|
$data = $this->diffLists($type);
|
||||||
|
|
||||||
/* if ( ! empty($data['addToMAL']))
|
if ( ! empty($data['addToAnilist']))
|
||||||
{
|
{
|
||||||
$count = count($data['addToMAL']);
|
$count = count($data['addToAnilist']);
|
||||||
$this->echoBox("Adding {$count} missing {$type} list items to MAL");
|
$this->echoBox("Adding {$count} missing {$type} list items to Anilist");
|
||||||
$this->updateMALListItems($data['addToMAL'], 'create', $type);
|
$this->updateAnilistListItems($data['addToAnilist'], 'create', $type);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! empty($data['updateMAL']))
|
if ( ! empty($data['updateAnilist']))
|
||||||
{
|
{
|
||||||
$count = count($data['updateMAL']);
|
$count = count($data['updateAnilist']);
|
||||||
$this->echoBox("Updating {$count} outdated MAL {$type} list items");
|
$this->echoBox("Updating {$count} outdated Anilist {$type} list items");
|
||||||
$this->updateMALListItems($data['updateMAL'], 'update', $type);
|
$this->updateAnilistListItems($data['updateAnilist'], 'update', $type);
|
||||||
} */
|
}
|
||||||
|
|
||||||
if ( ! empty($data['addToKitsu']))
|
if ( ! empty($data['addToKitsu']))
|
||||||
{
|
{
|
||||||
@ -144,107 +141,79 @@ final class SyncLists extends BaseCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Format a MAL list for comparison
|
* Format an Anilist list for comparison
|
||||||
*
|
*
|
||||||
* @param string $type
|
* @param string $type
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
/* protected function formatMALList(string $type): array
|
protected function formatAnilistList(string $type): array
|
||||||
{
|
{
|
||||||
$type = ucfirst($type);
|
$type = ucfirst($type);
|
||||||
$method = "formatMAL{$type}List";
|
$method = "formatAnilist{$type}List";
|
||||||
return $this->$method();
|
return $this->$method();
|
||||||
} */
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Format a MAL anime list for comparison
|
* Format an Anilist anime list for comparison
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
/* protected function formatMALAnimeList(): array
|
protected function formatAnilistAnimeList(): array
|
||||||
{
|
{
|
||||||
$orig = $this->malModel->getList('anime');
|
$anilistList = $this->anilistModel->getSyncList('ANIME');
|
||||||
|
$anilistTransformer = new AALT();
|
||||||
|
|
||||||
|
$transformedAnilist = [];
|
||||||
|
|
||||||
|
foreach ($anilistList['data']['MediaListCollection']['lists'] as $list)
|
||||||
|
{
|
||||||
|
$newTransformed = $anilistTransformer->untransformCollection($list['entries']);
|
||||||
|
$transformedAnilist = array_merge($transformedAnilist, $newTransformed);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Key the array by the mal_id for easier reference in the next comparision step
|
||||||
$output = [];
|
$output = [];
|
||||||
|
foreach ($transformedAnilist as $item)
|
||||||
// Bail early on empty list
|
|
||||||
if (empty($orig))
|
|
||||||
{
|
{
|
||||||
return [];
|
$output[$item['mal_id']] = $item->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Due to xml parsing differences,
|
$count = count($output);
|
||||||
// 1 item has no wrapping array.
|
$this->echoBox("Number of Anilist anime list items: {$count}");
|
||||||
// In this case, just re-create the
|
|
||||||
// wrapper array
|
|
||||||
if ( ! array_key_exists(0, $orig))
|
|
||||||
{
|
|
||||||
$orig = [$orig];
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach($orig as $item)
|
|
||||||
{
|
|
||||||
$output[$item['series_animedb_id']] = [
|
|
||||||
'id' => $item['series_animedb_id'],
|
|
||||||
'data' => [
|
|
||||||
'status' => AnimeWatchingStatus::MAL_TO_KITSU[$item['my_status']],
|
|
||||||
'progress' => $item['my_watched_episodes'],
|
|
||||||
'reconsuming' => (bool) $item['my_rewatching'],
|
|
||||||
'rating' => $item['my_score'] / 2,
|
|
||||||
'updatedAt' => (new \DateTime())
|
|
||||||
->setTimestamp((int)$item['my_last_updated'])
|
|
||||||
->format(\DateTime::W3C),
|
|
||||||
]
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $output;
|
return $output;
|
||||||
} */
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Format a MAL manga list for comparison
|
* Format an Anilist manga list for comparison
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
/* protected function formatMALMangaList(): array
|
protected function formatAnilistMangaList(): array
|
||||||
{
|
{
|
||||||
$orig = $this->malModel->getList('manga');
|
$anilistList = $this->anilistModel->getSyncList('MANGA');
|
||||||
|
$anilistTransformer = new AMLT();
|
||||||
|
|
||||||
|
$transformedAnilist = [];
|
||||||
|
|
||||||
|
foreach ($anilistList['data']['MediaListCollection']['lists'] as $list)
|
||||||
|
{
|
||||||
|
$newTransformed = $anilistTransformer->untransformCollection($list['entries']);
|
||||||
|
$transformedAnilist = array_merge($transformedAnilist, $newTransformed);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Key the array by the mal_id for easier reference in the next comparision step
|
||||||
$output = [];
|
$output = [];
|
||||||
|
foreach ($transformedAnilist as $item)
|
||||||
// Bail early on empty list
|
|
||||||
if (empty($orig))
|
|
||||||
{
|
{
|
||||||
return [];
|
$output[$item['mal_id']] = $item->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Due to xml parsing differences,
|
$count = count($output);
|
||||||
// 1 item has no wrapping array.
|
$this->echoBox("Number of Anilist manga list items: {$count}");
|
||||||
// In this case, just re-create the
|
|
||||||
// wrapper array
|
|
||||||
if ( ! array_key_exists(0, $orig))
|
|
||||||
{
|
|
||||||
$orig = [$orig];
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach($orig as $item)
|
|
||||||
{
|
|
||||||
$output[$item['series_mangadb_id']] = [
|
|
||||||
'id' => $item['series_mangadb_id'],
|
|
||||||
'data' => [
|
|
||||||
'my_status' => $item['my_status'],
|
|
||||||
'status' => MangaReadingStatus::MAL_TO_KITSU[$item['my_status']],
|
|
||||||
'progress' => $item['my_read_chapters'],
|
|
||||||
'volumes' => $item['my_read_volumes'],
|
|
||||||
'reconsuming' => (bool) $item['my_rereadingg'],
|
|
||||||
'rating' => $item['my_score'] / 2,
|
|
||||||
'updatedAt' => (new \DateTime())
|
|
||||||
->setTimestamp((int)$item['my_last_updated'])
|
|
||||||
->format(\DateTime::W3C),
|
|
||||||
]
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $output;
|
return $output;
|
||||||
} */
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Format a kitsu list for the sake of comparision
|
* Format a kitsu list for the sake of comparision
|
||||||
@ -254,7 +223,7 @@ final class SyncLists extends BaseCommand {
|
|||||||
*/
|
*/
|
||||||
protected function formatKitsuList(string $type = 'anime'): array
|
protected function formatKitsuList(string $type = 'anime'): array
|
||||||
{
|
{
|
||||||
$data = $this->kitsuModel->{'getFull' . ucfirst($type) . 'List'}();
|
$data = $this->kitsuModel->{'getFullRaw' . ucfirst($type) . 'List'}();
|
||||||
|
|
||||||
if (empty($data))
|
if (empty($data))
|
||||||
{
|
{
|
||||||
@ -281,7 +250,7 @@ final class SyncLists extends BaseCommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip to the next item if there isn't a MAL ID
|
// Skip to the next item if there isn't a Anilist ID
|
||||||
if ($malId === NULL)
|
if ($malId === NULL)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
@ -309,31 +278,51 @@ final class SyncLists extends BaseCommand {
|
|||||||
// Organize mappings, and ignore entries without mappings
|
// Organize mappings, and ignore entries without mappings
|
||||||
$kitsuList = $this->formatKitsuList($type);
|
$kitsuList = $this->formatKitsuList($type);
|
||||||
|
|
||||||
// Get MAL list data
|
// Get Anilist list data
|
||||||
// $malList = $this->formatMALList($type);
|
$anilistList = $this->formatAnilistList($type);
|
||||||
|
|
||||||
$itemsToAddToMAL = [];
|
$itemsToAddToAnilist = [];
|
||||||
$itemsToAddToKitsu = [];
|
$itemsToAddToKitsu = [];
|
||||||
$malUpdateItems = [];
|
$anilistUpdateItems = [];
|
||||||
$kitsuUpdateItems = [];
|
$kitsuUpdateItems = [];
|
||||||
|
|
||||||
// $malIds = array_column($malList, 'id');
|
$malBlackList = ($type === 'anime')
|
||||||
// $kitsuMalIds = array_column($kitsuList, 'malId');
|
? [
|
||||||
// $missingMalIds = array_diff($malIds, $kitsuMalIds);
|
27821, // Fate/stay night: Unlimited Blade Works - Prologue
|
||||||
|
29317, // Saekano: How to Raise a Boring Girlfriend Prologue
|
||||||
|
30514, // Nisekoinogatari
|
||||||
|
] : [
|
||||||
|
114638, // Cells at Work: Black
|
||||||
|
];
|
||||||
|
|
||||||
/* foreach($missingMalIds as $mid)
|
$malIds = array_keys($anilistList);
|
||||||
|
$kitsuMalIds = array_map('intval', array_column($kitsuList, 'malId'));
|
||||||
|
$missingMalIds = array_diff($malIds, $kitsuMalIds);
|
||||||
|
$missingMalIds = array_diff($missingMalIds, $malBlackList);
|
||||||
|
|
||||||
|
foreach($missingMalIds as $mid)
|
||||||
{
|
{
|
||||||
$itemsToAddToKitsu[] = array_merge($malList[$mid]['data'], [
|
$itemsToAddToKitsu[] = array_merge($anilistList[$mid]['data'], [
|
||||||
'id' => $this->kitsuModel->getKitsuIdFromMALId($mid, $type),
|
'id' => $this->kitsuModel->getKitsuIdFromMALId((string)$mid, $type),
|
||||||
'type' => $type
|
'type' => $type
|
||||||
]);
|
]);
|
||||||
} */
|
}
|
||||||
|
|
||||||
/* foreach($kitsuList as $kitsuItem)
|
foreach($kitsuList as $kitsuItem)
|
||||||
{
|
{
|
||||||
if (\in_array($kitsuItem['malId'], $malIds, TRUE))
|
$malId = $kitsuItem['malId'];
|
||||||
|
|
||||||
|
if (in_array($malId, $malBlackList))
|
||||||
{
|
{
|
||||||
$item = $this->compareListItems($kitsuItem, $malList[$kitsuItem['malId']]);
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array_key_exists($malId, $anilistList))
|
||||||
|
{
|
||||||
|
$anilistItem = $anilistList[$malId];
|
||||||
|
// dump($anilistItem);
|
||||||
|
|
||||||
|
$item = $this->compareListItems($kitsuItem, $anilistItem);
|
||||||
|
|
||||||
if ($item === NULL)
|
if ($item === NULL)
|
||||||
{
|
{
|
||||||
@ -345,25 +334,39 @@ final class SyncLists extends BaseCommand {
|
|||||||
$kitsuUpdateItems[] = $item['data'];
|
$kitsuUpdateItems[] = $item['data'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (\in_array('mal', $item['updateType'], TRUE))
|
if (\in_array('anilist', $item['updateType'], TRUE))
|
||||||
{
|
{
|
||||||
$malUpdateItems[] = $item['data'];
|
$anilistUpdateItems[] = $item['data'];
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$statusMap = ($type === 'anime') ? AnimeWatchingStatus::class : MangaReadingStatus::class;
|
||||||
|
|
||||||
// Looks like this item only exists on Kitsu
|
// Looks like this item only exists on Kitsu
|
||||||
$itemsToAddToMAL[] = [
|
$kItem = $kitsuItem['data'];
|
||||||
'mal_id' => $kitsuItem['malId'],
|
$newItemStatus = ($kItem['reconsuming'] === true) ? 'REPEATING' : $statusMap::KITSU_TO_ANILIST[$kItem['status']];
|
||||||
'data' => $kitsuItem['data']
|
$itemsToAddToAnilist[] = [
|
||||||
|
'mal_id' => $malId,
|
||||||
|
'data' => [
|
||||||
|
'notes' => $kItem['notes'],
|
||||||
|
'private' => $kItem['private'],
|
||||||
|
'progress' => $kItem['progress'],
|
||||||
|
'repeat' => $kItem['reconsumeCount'],
|
||||||
|
'score' => $kItem['ratingTwenty'] / 2,
|
||||||
|
'status' => $newItemStatus,
|
||||||
|
], // $kitsuItem['data']
|
||||||
];
|
];
|
||||||
|
|
||||||
} */
|
}
|
||||||
|
|
||||||
|
//dump($itemsToAddToAnilist);
|
||||||
|
//die();
|
||||||
|
|
||||||
return [
|
return [
|
||||||
// 'addToMAL' => $itemsToAddToMAL,
|
'addToAnilist' => $itemsToAddToAnilist,
|
||||||
// 'updateMAL' => $malUpdateItems,
|
'updateAnilist' => $anilistUpdateItems,
|
||||||
'addToKitsu' => $itemsToAddToKitsu,
|
'addToKitsu' => $itemsToAddToKitsu,
|
||||||
'updateKitsu' => $kitsuUpdateItems
|
'updateKitsu' => $kitsuUpdateItems
|
||||||
];
|
];
|
||||||
@ -373,18 +376,27 @@ final class SyncLists extends BaseCommand {
|
|||||||
* Compare two list items, and return the out of date one, if one exists
|
* Compare two list items, and return the out of date one, if one exists
|
||||||
*
|
*
|
||||||
* @param array $kitsuItem
|
* @param array $kitsuItem
|
||||||
* @param array $malItem
|
* @param array $anilistItem
|
||||||
* @return array|null
|
* @return array|null
|
||||||
*/
|
*/
|
||||||
protected function compareListItems(array $kitsuItem, array $malItem): ?array
|
protected function compareListItems(array $kitsuItem, array $anilistItem): ?array
|
||||||
{
|
{
|
||||||
$compareKeys = ['status', 'progress', 'rating', 'reconsuming'];
|
$compareKeys = [
|
||||||
|
'notes',
|
||||||
|
'progress',
|
||||||
|
'rating',
|
||||||
|
'reconsumeCount',
|
||||||
|
'reconsuming',
|
||||||
|
'status',
|
||||||
|
];
|
||||||
$diff = [];
|
$diff = [];
|
||||||
$dateDiff = new DateTime($kitsuItem['data']['updatedAt']) <=> new DateTime($malItem['data']['updatedAt']);
|
|
||||||
|
// Correct differences in notation
|
||||||
|
$kitsuItem['data']['rating'] = $kitsuItem['data']['ratingTwenty'] / 2;
|
||||||
|
|
||||||
foreach($compareKeys as $key)
|
foreach($compareKeys as $key)
|
||||||
{
|
{
|
||||||
$diff[$key] = $kitsuItem['data'][$key] <=> $malItem['data'][$key];
|
$diff[$key] = $kitsuItem['data'][$key] <=> $anilistItem['data'][$key];
|
||||||
}
|
}
|
||||||
|
|
||||||
// No difference? Bail out early
|
// No difference? Bail out early
|
||||||
@ -404,9 +416,18 @@ final class SyncLists extends BaseCommand {
|
|||||||
'updateType' => []
|
'updateType' => []
|
||||||
];
|
];
|
||||||
|
|
||||||
|
$sameNotes = $diff['notes'] === 0;
|
||||||
$sameStatus = $diff['status'] === 0;
|
$sameStatus = $diff['status'] === 0;
|
||||||
$sameProgress = $diff['progress'] === 0;
|
$sameProgress = $diff['progress'] === 0;
|
||||||
$sameRating = $diff['rating'] === 0;
|
$sameRating = $diff['rating'] === 0;
|
||||||
|
$sameRewatchCount = $diff['reconsumeCount'] === 0;
|
||||||
|
|
||||||
|
// If an item is completed, make sure the 'reconsuming' flag is false
|
||||||
|
if ($kitsuItem['data']['status'] === 'completed' && $kitsuItem['data']['reconsuming'] === TRUE)
|
||||||
|
{
|
||||||
|
$update['data']['reconsuming'] = FALSE;
|
||||||
|
$return['updateType'][] = 'kitsu';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// If status is the same, and progress count is different, use greater progress
|
// If status is the same, and progress count is different, use greater progress
|
||||||
@ -415,18 +436,25 @@ final class SyncLists extends BaseCommand {
|
|||||||
if ($diff['progress'] === 1)
|
if ($diff['progress'] === 1)
|
||||||
{
|
{
|
||||||
$update['data']['progress'] = $kitsuItem['data']['progress'];
|
$update['data']['progress'] = $kitsuItem['data']['progress'];
|
||||||
$return['updateType'][] = 'mal';
|
$return['updateType'][] = 'anilist';
|
||||||
}
|
}
|
||||||
else if($diff['progress'] === -1)
|
else if($diff['progress'] === -1)
|
||||||
{
|
{
|
||||||
$update['data']['progress'] = $malItem['data']['progress'];
|
$update['data']['progress'] = $anilistItem['data']['progress'];
|
||||||
$return['updateType'][] = 'kitsu';
|
$return['updateType'][] = 'kitsu';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If status is different, go with Kitsu
|
||||||
|
if ( ! $sameStatus)
|
||||||
|
{
|
||||||
|
$update['data']['status'] = $kitsuItem['data']['status'];
|
||||||
|
$return['updateType'][] = 'anilist';
|
||||||
|
}
|
||||||
|
|
||||||
// If status and progress are different, it's a bit more complicated...
|
// If status and progress are different, it's a bit more complicated...
|
||||||
// But, at least for now, assume newer record is correct
|
// But, at least for now, assume newer record is correct
|
||||||
if ( ! ($sameStatus || $sameProgress))
|
/* if ( ! ($sameStatus || $sameProgress))
|
||||||
{
|
{
|
||||||
if ($dateDiff === 1)
|
if ($dateDiff === 1)
|
||||||
{
|
{
|
||||||
@ -437,59 +465,111 @@ final class SyncLists extends BaseCommand {
|
|||||||
$update['data']['progress'] = $kitsuItem['data']['progress'];
|
$update['data']['progress'] = $kitsuItem['data']['progress'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$return['updateType'][] = 'mal';
|
$return['updateType'][] = 'anilist';
|
||||||
}
|
}
|
||||||
else if($dateDiff === -1)
|
else if($dateDiff === -1)
|
||||||
{
|
{
|
||||||
$update['data']['status'] = $malItem['data']['status'];
|
$update['data']['status'] = $anilistItem['data']['status'];
|
||||||
|
|
||||||
if ((int)$malItem['data']['progress'] !== 0)
|
if ((int)$anilistItem['data']['progress'] !== 0)
|
||||||
{
|
{
|
||||||
$update['data']['progress'] = $kitsuItem['data']['progress'];
|
$update['data']['progress'] = $kitsuItem['data']['progress'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$return['updateType'][] = 'kitsu';
|
$return['updateType'][] = 'kitsu';
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// If rating is different, use the rating from the item most recently updated
|
// If rating is different, use the kitsu rating, unless the other rating
|
||||||
|
// is set, and the kitsu rating is not set
|
||||||
if ( ! $sameRating)
|
if ( ! $sameRating)
|
||||||
{
|
{
|
||||||
if ($dateDiff === 1)
|
if ($kitsuItem['data']['rating'] !== 0)
|
||||||
{
|
{
|
||||||
$update['data']['rating'] = $kitsuItem['data']['rating'];
|
$update['data']['rating'] = $kitsuItem['data']['rating'];
|
||||||
$return['updateType'][] = 'mal';
|
$return['updateType'][] = 'anilist';
|
||||||
}
|
}
|
||||||
else if ($dateDiff === -1)
|
else
|
||||||
{
|
{
|
||||||
$update['data']['rating'] = $malItem['data']['rating'];
|
$update['data']['rating'] = $anilistItem['data']['rating'];
|
||||||
|
$return['updateType'][] = 'kitsu';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If notes are set, use kitsu, otherwise, set kitsu from anilist
|
||||||
|
if ( ! $sameNotes)
|
||||||
|
{
|
||||||
|
if ($kitsuItem['data']['notes'] !== '')
|
||||||
|
{
|
||||||
|
$update['data']['notes'] = $kitsuItem['data']['notes'];
|
||||||
|
$return['updateType'][] = 'anilist';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$update['data']['notes'] = $anilistItem['data']['notes'];
|
||||||
|
$return['updateType'][] = 'kitsu';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assume the larger reconsumeCount is correct
|
||||||
|
if ( ! $sameRewatchCount)
|
||||||
|
{
|
||||||
|
if ($diff['reconsumeCount'] === 1)
|
||||||
|
{
|
||||||
|
$update['data']['reconsumeCount'] = $kitsuItem['data']['reconsumeCount'];
|
||||||
|
$return['updateType'][] = 'anilist';
|
||||||
|
}
|
||||||
|
else if ($diff['reconsumeCount'] === -1)
|
||||||
|
{
|
||||||
|
$update['data']['reconsumeCount'] = $anilistItem['data']['reconsumeCount'];
|
||||||
$return['updateType'][] = 'kitsu';
|
$return['updateType'][] = 'kitsu';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If status is different, use the status of the more recently updated item
|
// If status is different, use the status of the more recently updated item
|
||||||
if ( ! $sameStatus)
|
/* if ( ! $sameStatus)
|
||||||
{
|
{
|
||||||
if ($dateDiff === 1)
|
if ($dateDiff === 1)
|
||||||
{
|
{
|
||||||
$update['data']['status'] = $kitsuItem['data']['status'];
|
$update['data']['status'] = $kitsuItem['data']['status'];
|
||||||
$return['updateType'][] = 'mal';
|
$return['updateType'][] = 'anilist';
|
||||||
}
|
}
|
||||||
else if ($dateDiff === -1)
|
else if ($dateDiff === -1)
|
||||||
{
|
{
|
||||||
$update['data']['status'] = $malItem['data']['status'];
|
$update['data']['status'] = $anilistItem['data']['status'];
|
||||||
$return['updateType'][] = 'kitsu';
|
$return['updateType'][] = 'kitsu';
|
||||||
}
|
}
|
||||||
}
|
} */
|
||||||
|
|
||||||
$return['meta'] = [
|
$return['meta'] = [
|
||||||
'kitsu' => $kitsuItem['data'],
|
'kitsu' => $kitsuItem['data'],
|
||||||
'mal' => $malItem['data'],
|
'anilist' => $anilistItem['data'],
|
||||||
'dateDiff' => $dateDiff,
|
// 'dateDiff' => $dateDiff,
|
||||||
'diff' => $diff,
|
'diff' => $diff,
|
||||||
];
|
];
|
||||||
$return['data'] = $update;
|
$return['data'] = $update;
|
||||||
$return['updateType'] = array_unique($return['updateType']);
|
$return['updateType'] = array_unique($return['updateType']);
|
||||||
|
|
||||||
|
// Fill in missing data values for update on Anlist
|
||||||
|
// so I don't have to create a really complex graphql query
|
||||||
|
// to handle each combination of fields
|
||||||
|
if ($return['updateType'][0] === 'anilist')
|
||||||
|
{
|
||||||
|
$prevData = [
|
||||||
|
'notes' => $kitsuItem['data']['notes'],
|
||||||
|
'private' => $kitsuItem['data']['private'],
|
||||||
|
'progress' => $kitsuItem['data']['progress'],
|
||||||
|
'rating' => $kitsuItem['data']['rating'],
|
||||||
|
'reconsumeCount' => $kitsuItem['data']['reconsumeCount'],
|
||||||
|
'reconsuming' => $kitsuItem['data']['reconsuming'],
|
||||||
|
'status' => $kitsuItem['data']['status'],
|
||||||
|
];
|
||||||
|
|
||||||
|
$return['data']['data'] = array_merge($prevData, $return['data']['data']);
|
||||||
|
}
|
||||||
|
|
||||||
|
dump($return);
|
||||||
|
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -505,9 +585,13 @@ final class SyncLists extends BaseCommand {
|
|||||||
$requester = new ParallelAPIRequest();
|
$requester = new ParallelAPIRequest();
|
||||||
foreach($itemsToUpdate as $item)
|
foreach($itemsToUpdate as $item)
|
||||||
{
|
{
|
||||||
|
$typeClass = '\\Aviat\\AnimeClient\\Types\\' . ucFirst($type) . 'FormItem';
|
||||||
|
|
||||||
if ($action === 'update')
|
if ($action === 'update')
|
||||||
{
|
{
|
||||||
$requester->addRequest($this->kitsuModel->updateListItem($item));
|
$requester->addRequest(
|
||||||
|
$this->kitsuModel->updateListItem(new $typeClass($item))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
else if ($action === 'create')
|
else if ($action === 'create')
|
||||||
{
|
{
|
||||||
@ -537,27 +621,29 @@ final class SyncLists extends BaseCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create/Update list items on MAL
|
* Create/Update list items on Anilist
|
||||||
*
|
*
|
||||||
* @param array $itemsToUpdate
|
* @param array $itemsToUpdate
|
||||||
* @param string $action
|
* @param string $action
|
||||||
* @param string $type
|
* @param string $type
|
||||||
*/
|
*/
|
||||||
/* protected function updateMALListItems(array$itemsToUpdate, string $action = 'update', string $type = 'anime'): void
|
protected function updateAnilistListItems(array$itemsToUpdate, string $action = 'update', string $type = 'anime'): void
|
||||||
{
|
{
|
||||||
$transformer = new ALT();
|
|
||||||
$requester = new ParallelAPIRequest();
|
$requester = new ParallelAPIRequest();
|
||||||
|
|
||||||
|
$typeClass = '\\Aviat\\AnimeClient\\Types\\' . ucFirst($type) . 'FormItem';
|
||||||
|
|
||||||
foreach($itemsToUpdate as $item)
|
foreach($itemsToUpdate as $item)
|
||||||
{
|
{
|
||||||
if ($action === 'update')
|
if ($action === 'update')
|
||||||
{
|
{
|
||||||
$requester->addRequest($this->malModel->updateListItem($item, $type));
|
$requester->addRequest(
|
||||||
|
$this->anilistModel->updateListItem(new $typeClass($item), $type)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
else if ($action === 'create')
|
else if ($action === 'create')
|
||||||
{
|
{
|
||||||
$data = $transformer->untransform($item);
|
$requester->addRequest($this->anilistModel->createFullListItem($item, $type));
|
||||||
$requester->addRequest($this->malModel->createFullListItem($data, $type));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -566,20 +652,21 @@ final class SyncLists extends BaseCommand {
|
|||||||
foreach($responses as $key => $response)
|
foreach($responses as $key => $response)
|
||||||
{
|
{
|
||||||
$id = $itemsToUpdate[$key]['mal_id'];
|
$id = $itemsToUpdate[$key]['mal_id'];
|
||||||
$goodResponse = (
|
|
||||||
($action === 'update' && $response === 'Updated') ||
|
$responseData = Json::decode($response);
|
||||||
($action === 'create' && $response === 'Created')
|
|
||||||
);
|
// $id = $itemsToUpdate[$key]['id'];
|
||||||
if ($goodResponse)
|
if ( ! array_key_exists('errors', $responseData))
|
||||||
{
|
{
|
||||||
$verb = ($action === 'update') ? 'updated' : 'created';
|
$verb = ($action === 'update') ? 'updated' : 'created';
|
||||||
$this->echoBox("Successfully {$verb} MAL {$type} list item with id: {$id}");
|
$this->echoBox("Successfully {$verb} Anilist {$type} list item with id: {$id}");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
dump($responseData);
|
||||||
$verb = ($action === 'update') ? 'update' : 'create';
|
$verb = ($action === 'update') ? 'update' : 'create';
|
||||||
$this->echoBox("Failed to {$verb} MAL {$type} list item with id: {$id}");
|
$this->echoBox("Failed to {$verb} Anilist {$type} list item with id: {$id}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} */
|
}
|
||||||
}
|
}
|
||||||
|
@ -130,6 +130,11 @@ final class Manga extends Controller {
|
|||||||
$this->redirect('manga/add', 303);
|
$this->redirect('manga/add', 303);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (empty($data['mal_id']))
|
||||||
|
{
|
||||||
|
unset($data['mal_id']);
|
||||||
|
}
|
||||||
|
|
||||||
$result = $this->model->createLibraryItem($data);
|
$result = $this->model->createLibraryItem($data);
|
||||||
|
|
||||||
if ($result)
|
if ($result)
|
||||||
@ -182,8 +187,9 @@ final class Manga extends Controller {
|
|||||||
*/
|
*/
|
||||||
public function search(): void
|
public function search(): void
|
||||||
{
|
{
|
||||||
$query_data = $this->request->getQueryParams();
|
$queryParams = $this->request->getQueryParams();
|
||||||
$this->outputJSON($this->model->search($query_data['query']));
|
$query = $queryParams['query'];
|
||||||
|
$this->outputJSON($this->model->search($query));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -218,13 +224,9 @@ final class Manga extends Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update a manga item
|
* Increment the progress of a manga item
|
||||||
*
|
|
||||||
* @throws \Aviat\Ion\Di\ContainerException
|
|
||||||
* @throws \Aviat\Ion\Di\NotFoundException
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function update(): void
|
public function increment(): void
|
||||||
{
|
{
|
||||||
if (stripos($this->request->getHeader('content-type')[0], 'application/json') !== FALSE)
|
if (stripos($this->request->getHeader('content-type')[0], 'application/json') !== FALSE)
|
||||||
{
|
{
|
||||||
@ -235,7 +237,7 @@ final class Manga extends Controller {
|
|||||||
$data = $this->request->getParsedBody();
|
$data = $this->request->getParsedBody();
|
||||||
}
|
}
|
||||||
|
|
||||||
$response = $this->model->updateLibraryItem(new MangaFormItem($data));
|
$response = $this->model->incrementLibraryItem(new MangaFormItem($data));
|
||||||
|
|
||||||
$this->cache->clear();
|
$this->cache->clear();
|
||||||
$this->outputJSON($response['body'], $response['statusCode']);
|
$this->outputJSON($response['body'], $response['statusCode']);
|
||||||
@ -251,13 +253,11 @@ final class Manga extends Controller {
|
|||||||
public function delete(): void
|
public function delete(): void
|
||||||
{
|
{
|
||||||
$body = $this->request->getParsedBody();
|
$body = $this->request->getParsedBody();
|
||||||
$id = $body['id'];
|
$response = $this->model->deleteLibraryItem($body['id'], $body['mal_id']);
|
||||||
$malId = $body['mal_id'];
|
|
||||||
$response = $this->model->deleteLibraryItem($id, $malId);
|
|
||||||
|
|
||||||
if ($response)
|
if ($response)
|
||||||
{
|
{
|
||||||
$this->setFlashMessage("Successfully deleted manga.", 'success');
|
$this->setFlashMessage('Successfully deleted manga.', 'success');
|
||||||
$this->cache->clear();
|
$this->cache->clear();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -31,6 +31,13 @@ use Aviat\Ion\Json;
|
|||||||
*/
|
*/
|
||||||
class Anime extends API {
|
class Anime extends API {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the Anilist API enabled?
|
||||||
|
*
|
||||||
|
* @var boolean
|
||||||
|
*/
|
||||||
|
protected $anilistEnabled;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Model for making requests to Anilist API
|
* Model for making requests to Anilist API
|
||||||
*
|
*
|
||||||
@ -54,6 +61,9 @@ class Anime extends API {
|
|||||||
{
|
{
|
||||||
$this->anilistModel = $container->get('anilist-model');
|
$this->anilistModel = $container->get('anilist-model');
|
||||||
$this->kitsuModel = $container->get('kitsu-model');
|
$this->kitsuModel = $container->get('kitsu-model');
|
||||||
|
|
||||||
|
$config = $container->get('config');
|
||||||
|
$this->anilistEnabled = (bool) $config->get(['anilist', 'enabled']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -137,18 +147,6 @@ class Anime extends API {
|
|||||||
$item = $this->kitsuModel->getListItem($itemId);
|
$item = $this->kitsuModel->getListItem($itemId);
|
||||||
$array = $item->toArray();
|
$array = $item->toArray();
|
||||||
|
|
||||||
if ( ! empty($item->mal_id))
|
|
||||||
{
|
|
||||||
$anilistInfo = $this->anilistModel->getListItem($item['mal_id']);
|
|
||||||
|
|
||||||
if (empty($anilistInfo))
|
|
||||||
{
|
|
||||||
return $item;
|
|
||||||
}
|
|
||||||
|
|
||||||
$array['anilist_item_id'] = $anilistInfo['id'];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_array($array['notes']))
|
if (is_array($array['notes']))
|
||||||
{
|
{
|
||||||
$array['notes'] = '';
|
$array['notes'] = '';
|
||||||
@ -168,9 +166,9 @@ class Anime extends API {
|
|||||||
$requester = new ParallelAPIRequest();
|
$requester = new ParallelAPIRequest();
|
||||||
$requester->addRequest($this->kitsuModel->createListItem($data), 'kitsu');
|
$requester->addRequest($this->kitsuModel->createListItem($data), 'kitsu');
|
||||||
|
|
||||||
// @TODO Make sure Anilist integration is optional
|
if (array_key_exists('mal_id', $data) && $this->anilistEnabled)
|
||||||
if (array_key_exists('mal_id', $data)) {
|
{
|
||||||
$requester->addRequest($this->anilistModel->createListItem($data), 'anilist');
|
$requester->addRequest($this->anilistModel->createListItem($data, 'ANIME'), 'anilist');
|
||||||
}
|
}
|
||||||
|
|
||||||
$results = $requester->makeRequests();
|
$results = $requester->makeRequests();
|
||||||
@ -199,9 +197,9 @@ class Anime extends API {
|
|||||||
|
|
||||||
$array = $data->toArray();
|
$array = $data->toArray();
|
||||||
|
|
||||||
// @TODO Make sure Anilist integration is optional
|
if (array_key_exists('mal_id', $array) && $this->anilistEnabled)
|
||||||
if (array_key_exists('mal_id', $array)) {
|
{
|
||||||
$requester->addRequest($this->anilistModel->incrementListItem($data), 'anilist');
|
$requester->addRequest($this->anilistModel->incrementListItem($data, 'ANIME'), 'anilist');
|
||||||
}
|
}
|
||||||
|
|
||||||
$results = $requester->makeRequests();
|
$results = $requester->makeRequests();
|
||||||
@ -228,10 +226,9 @@ class Anime extends API {
|
|||||||
|
|
||||||
$array = $data->toArray();
|
$array = $data->toArray();
|
||||||
|
|
||||||
// @TODO Make sure Anilist integration is optional
|
if (array_key_exists('mal_id', $array) && $this->anilistEnabled)
|
||||||
if (array_key_exists('mal_id', $array))
|
|
||||||
{
|
{
|
||||||
$requester->addRequest($this->anilistModel->updateListItem($data), 'anilist');
|
$requester->addRequest($this->anilistModel->updateListItem($data, 'ANIME'), 'anilist');
|
||||||
}
|
}
|
||||||
|
|
||||||
$results = $requester->makeRequests();
|
$results = $requester->makeRequests();
|
||||||
@ -257,9 +254,9 @@ class Anime extends API {
|
|||||||
$requester = new ParallelAPIRequest();
|
$requester = new ParallelAPIRequest();
|
||||||
$requester->addRequest($this->kitsuModel->deleteListItem($id), 'kitsu');
|
$requester->addRequest($this->kitsuModel->deleteListItem($id), 'kitsu');
|
||||||
|
|
||||||
// @TODO Make sure Anilist integration is optional
|
if ($malId !== null && $this->anilistEnabled)
|
||||||
if ($malId !== null) {
|
{
|
||||||
$requester->addRequest($this->anilistModel->deleteListItem($malId), 'anilist');
|
$requester->addRequest($this->anilistModel->deleteListItem($malId, 'ANIME'), 'anilist');
|
||||||
}
|
}
|
||||||
|
|
||||||
$results = $requester->makeRequests();
|
$results = $requester->makeRequests();
|
||||||
|
@ -33,6 +33,19 @@ use Aviat\Ion\Json;
|
|||||||
* Model for handling requests dealing with the manga list
|
* Model for handling requests dealing with the manga list
|
||||||
*/
|
*/
|
||||||
class Manga extends API {
|
class Manga extends API {
|
||||||
|
/**
|
||||||
|
* Is the Anilist API enabled?
|
||||||
|
*
|
||||||
|
* @var boolean
|
||||||
|
*/
|
||||||
|
protected $anilistEnabled;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model for making requests to the Anilist API
|
||||||
|
* @var \Aviat\AnimeClient\API\Anilist\Model
|
||||||
|
*/
|
||||||
|
protected $anilistModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Model for making requests to Kitsu API
|
* Model for making requests to Kitsu API
|
||||||
* @var \Aviat\AnimeClient\API\Kitsu\Model
|
* @var \Aviat\AnimeClient\API\Kitsu\Model
|
||||||
@ -43,12 +56,14 @@ class Manga extends API {
|
|||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* @param ContainerInterface $container
|
* @param ContainerInterface $container
|
||||||
* @throws \Aviat\Ion\Di\ContainerException
|
|
||||||
* @throws \Aviat\Ion\Di\NotFoundException
|
|
||||||
*/
|
*/
|
||||||
public function __construct(ContainerInterface $container)
|
public function __construct(ContainerInterface $container)
|
||||||
{
|
{
|
||||||
|
$this->anilistModel = $container->get('anilist-model');
|
||||||
$this->kitsuModel = $container->get('kitsu-model');
|
$this->kitsuModel = $container->get('kitsu-model');
|
||||||
|
|
||||||
|
$config = $container->get('config');
|
||||||
|
$this->anilistEnabled = (bool)$config->get(['anilist', 'enabled']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -121,6 +136,11 @@ class Manga extends API {
|
|||||||
$requester = new ParallelAPIRequest();
|
$requester = new ParallelAPIRequest();
|
||||||
$requester->addRequest($this->kitsuModel->createListItem($data), 'kitsu');
|
$requester->addRequest($this->kitsuModel->createListItem($data), 'kitsu');
|
||||||
|
|
||||||
|
if (array_key_exists('mal_id', $data) && $this->anilistEnabled)
|
||||||
|
{
|
||||||
|
$requester->addRequest($this->anilistModel->createListItem($data, 'MANGA'), 'anilist');
|
||||||
|
}
|
||||||
|
|
||||||
$results = $requester->makeRequests();
|
$results = $requester->makeRequests();
|
||||||
|
|
||||||
return count($results) > 0;
|
return count($results) > 0;
|
||||||
@ -137,6 +157,13 @@ class Manga extends API {
|
|||||||
$requester = new ParallelAPIRequest();
|
$requester = new ParallelAPIRequest();
|
||||||
$requester->addRequest($this->kitsuModel->updateListItem($data), 'kitsu');
|
$requester->addRequest($this->kitsuModel->updateListItem($data), 'kitsu');
|
||||||
|
|
||||||
|
$array = $data->toArray();
|
||||||
|
|
||||||
|
if (array_key_exists('mal_id', $array) && $this->anilistEnabled)
|
||||||
|
{
|
||||||
|
$requester->addRequest($this->anilistModel->updateListItem($data, 'MANGA'), 'anilist');
|
||||||
|
}
|
||||||
|
|
||||||
$results = $requester->makeRequests();
|
$results = $requester->makeRequests();
|
||||||
$body = Json::decode($results['kitsu']);
|
$body = Json::decode($results['kitsu']);
|
||||||
$statusCode = array_key_exists('error', $body) ? 400: 200;
|
$statusCode = array_key_exists('error', $body) ? 400: 200;
|
||||||
@ -147,6 +174,34 @@ class Manga extends API {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increase the progress of a list entry
|
||||||
|
*
|
||||||
|
* @param MangaFormItem $data
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function incrementLibraryItem(MangaFormItem $data): array
|
||||||
|
{
|
||||||
|
$requester = new ParallelAPIRequest();
|
||||||
|
$requester->addRequest($this->kitsuModel->incrementListItem($data), 'kitsu');
|
||||||
|
|
||||||
|
$array = $data->toArray();
|
||||||
|
|
||||||
|
if (array_key_exists('mal_id', $array) && $this->anilistEnabled)
|
||||||
|
{
|
||||||
|
$requester->addRequest($this->anilistModel->incrementListItem($data, 'MANGA'), 'anilist');
|
||||||
|
}
|
||||||
|
|
||||||
|
$results = $requester->makeRequests();
|
||||||
|
$body = Json::decode($results['kitsu']);
|
||||||
|
$statusCode = array_key_exists('error', $body) ? 400 : 200;
|
||||||
|
|
||||||
|
return [
|
||||||
|
'body' => Json::decode($results['kitsu']),
|
||||||
|
'statusCode' => $statusCode
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete a list entry
|
* Delete a list entry
|
||||||
*
|
*
|
||||||
@ -159,6 +214,11 @@ class Manga extends API {
|
|||||||
$requester = new ParallelAPIRequest();
|
$requester = new ParallelAPIRequest();
|
||||||
$requester->addRequest($this->kitsuModel->deleteListItem($id), 'kitsu');
|
$requester->addRequest($this->kitsuModel->deleteListItem($id), 'kitsu');
|
||||||
|
|
||||||
|
if ($malId !== null && $this->anilistEnabled)
|
||||||
|
{
|
||||||
|
$requester->addRequest($this->anilistModel->deleteListItem($malId, 'MANGA'), 'anilist');
|
||||||
|
}
|
||||||
|
|
||||||
$results = $requester->makeRequests();
|
$results = $requester->makeRequests();
|
||||||
|
|
||||||
return count($results) > 0;
|
return count($results) > 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user