Better id mapping error handling for Anilist
timw4mail/HummingBirdAnimeClient/develop This commit looks good Details

This commit is contained in:
Timothy Warren 2020-01-15 12:35:37 -05:00
parent 7a4cda5bf0
commit 580dbb5993
7 changed files with 141 additions and 44 deletions

View File

@ -22,7 +22,7 @@ use Aviat\AnimeClient\Types\FormItemData;
/**
* Common interface for anime and manga list item CRUD
*/
interface ListItemInterface {
abstract class AbstractListItem {
/**
* Create a list item
@ -30,7 +30,7 @@ interface ListItemInterface {
* @param array $data -
* @return Request
*/
public function create(array $data): Request;
abstract public function create(array $data): Request;
/**
* Retrieve a list item
@ -38,7 +38,7 @@ interface ListItemInterface {
* @param string $id - The id of the list item
* @return array
*/
public function get(string $id): array;
abstract public function get(string $id): array;
/**
* Increase progress on a list item
@ -47,7 +47,7 @@ interface ListItemInterface {
* @param FormItemData $data
* @return Request
*/
public function increment(string $id, FormItemData $data): Request;
abstract public function increment(string $id, FormItemData $data): Request;
/**
* Update a list item
@ -56,7 +56,7 @@ interface ListItemInterface {
* @param FormItemData $data - The data with which to update the list item
* @return Request
*/
public function update(string $id, FormItemData $data): Request;
abstract public function update(string $id, FormItemData $data): Request;
/**
* Delete a list item
@ -64,5 +64,5 @@ interface ListItemInterface {
* @param string $id - The id of the list item to delete
* @return Request
*/
public function delete(string $id): Request;
abstract public function delete(string $id):?Request;
}

View File

@ -18,7 +18,7 @@ namespace Aviat\AnimeClient\API\Anilist;
use Amp\Artax\Request;
use Aviat\AnimeClient\API\ListItemInterface;
use Aviat\AnimeClient\API\AbstractListItem;
use Aviat\AnimeClient\API\Enum\AnimeWatchingStatus\Anilist as AnilistStatus;
use Aviat\AnimeClient\API\Mapping\AnimeWatchingStatus;
use Aviat\AnimeClient\Types\FormItemData;
@ -26,7 +26,7 @@ use Aviat\AnimeClient\Types\FormItemData;
/**
* CRUD operations for MAL list items
*/
final class ListItem implements ListItemInterface{
final class ListItem extends AbstractListItem {
use AnilistTrait;
/**
@ -37,7 +37,8 @@ final class ListItem implements ListItemInterface{
*/
public function create(array $data): Request
{
return $this->mutateRequest('CreateMediaListEntry', $data);
$checkedData = (new Types\MediaListEntry($data))->toArray();
return $this->mutateRequest('CreateMediaListEntry', $checkedData);
}
/**
@ -48,7 +49,8 @@ final class ListItem implements ListItemInterface{
*/
public function createFull(array $data): Request
{
return $this->mutateRequest('CreateFullMediaListEntry', $data);
$checkedData = (new Types\MediaListEntry($data))->toArray();
return $this->mutateRequest('CreateFullMediaListEntry', $checkedData);
}
/**
@ -83,10 +85,12 @@ final class ListItem implements ListItemInterface{
*/
public function increment(string $id, FormItemData $data): Request
{
return $this->mutateRequest('IncrementMediaListEntry', [
$checkedData = (new Types\MediaListEntry([
'id' => $id,
'progress' => $data['progress'],
]);
'progress' => $data->progress,
]))->toArray();
return $this->mutateRequest('IncrementMediaListEntry', $checkedData);
}
/**
@ -98,15 +102,15 @@ final class ListItem implements ListItemInterface{
*/
public function update(string $id, FormItemData $data): Request
{
$array = $data->toArray();
$notes = $data->notes ?? '';
$progress = (int)$data->progress;
$private = (bool)$data->private;
$rating = $data->ratingTwenty;
$status = ($data->reconsuming === TRUE)
? AnilistStatus::REPEATING
: AnimeWatchingStatus::KITSU_TO_ANILIST[$data->status];
$notes = $data['notes'] ?? '';
$progress = array_key_exists('progress', $array) ? $data['progress'] : 0;
$private = array_key_exists('private', $array) ? (bool)$data['private'] : false;
$rating = array_key_exists('ratingTwenty', $array) ? $data['ratingTwenty'] : NULL;
$status = ($data['reconsuming'] === true) ? AnilistStatus::REPEATING : AnimeWatchingStatus::KITSU_TO_ANILIST[$data['status']];
$updateData = [
$updateData = (new Types\MediaListEntry([
'id' => (int)$id,
'status' => $status,
'score' => $rating * 5,
@ -114,7 +118,7 @@ final class ListItem implements ListItemInterface{
'repeat' => (int)$data['reconsumeCount'],
'private' => $private,
'notes' => $notes,
];
]))->toArray();
return $this->mutateRequest('UpdateMediaListEntry', $updateData);
}

View File

@ -123,16 +123,16 @@ final class Model
* @param string $type
* @return Request
*/
public function createListItem(array $data, string $type = 'anime'): Request
public function createListItem(array $data, string $type = 'anime'): ?Request
{
$createData = [];
$mediaId = $this->getMediaIdFromMalId($data['mal_id'], mb_strtoupper($type));
/* if (empty($mediaId))
if ($mediaId === NULL)
{
throw new InvalidArgumentException('Media id missing');
} */
return NULL;
}
if ($type === 'ANIME')
{
@ -200,9 +200,13 @@ final class Model
* @param string $type - Them media type (anime/manga)
* @return Request
*/
public function incrementListItem(FormItem $data, string $type): Request
public function incrementListItem(FormItem $data, string $type): ?Request
{
$id = $this->getListIdFromMalId($data['mal_id'], $type);
if ($id === NULL)
{
return NULL;
}
return $this->listItem->increment($id, $data['data']);
}
@ -214,10 +218,15 @@ final class Model
* @param string $type - Them media type (anime/manga)
* @return Request
*/
public function updateListItem(FormItem $data, string $type): Request
public function updateListItem(FormItem $data, string $type): ?Request
{
$id = $this->getListIdFromMalId($data['mal_id'], mb_strtoupper($type));
if ($id === NULL)
{
return NULL;
}
return $this->listItem->update($id, $data['data']);
}
@ -228,11 +237,15 @@ final class Model
* @param string $type - Them media type (anime/manga)
* @return Request
*/
public function deleteListItem(string $malId, string $type): Request
public function deleteListItem(string $malId, string $type): ?Request
{
$item_id = $this->getListIdFromMalId($malId, $type);
$id = $this->getListIdFromMalId($malId, $type);
if ($id === NULL)
{
return NULL;
}
return $this->listItem->delete($item_id);
return $this->listItem->delete($id);
}
/**
@ -245,6 +258,11 @@ final class Model
public function getListIdFromMalId(string $malId, string $type): ?string
{
$mediaId = $this->getMediaIdFromMalId($malId, $type);
if ($mediaId === NULL)
{
return NULL;
}
return $this->getListIdFromMediaId($mediaId);
}

View File

@ -0,0 +1,56 @@
<?php declare(strict_types=1);
/**
* Hummingbird Anime List Client
*
* An API client for Kitsu to manage anime and manga watch lists
*
* PHP version 7.2
*
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2020 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 4.2
* @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient
*/
namespace Aviat\AnimeClient\API\Anilist\Types;
use Aviat\AnimeClient\Types\AbstractType;
class MediaListEntry extends AbstractType {
/**
* @var int
*/
public $id;
/**
* @var string
*/
public $notes;
/**
* @var bool
*/
public $private;
/**
* @var int
*/
public $progress;
/**
* @var int
*/
public $repeat;
/**
* @var string
*/
public $status;
/**
* @var int
*/
public $score;
}

View File

@ -24,7 +24,7 @@ use function Amp\Promise\wait;
use function Aviat\AnimeClient\getResponse;
use Amp\Artax\Request;
use Aviat\AnimeClient\API\ListItemInterface;
use Aviat\AnimeClient\API\AbstractListItem;
use Aviat\AnimeClient\Types\FormItemData;
use Aviat\Ion\Di\ContainerAware;
use Aviat\Ion\Json;
@ -34,7 +34,7 @@ use Throwable;
/**
* CRUD operations for Kitsu list items
*/
final class ListItem implements ListItemInterface {
final class ListItem extends AbstractListItem {
use ContainerAware;
use KitsuTrait;

View File

@ -173,7 +173,12 @@ class Anime extends API {
if ($this->anilistEnabled && $data['mal_id'] !== null)
{
$requester->addRequest($this->anilistModel->createListItem($data, 'ANIME'), 'anilist');
// If can't map MAL id, this will be null
$maybeRequest = $this->anilistModel->createListItem($data, 'ANIME');
if ($maybeRequest !== NULL)
{
$requester->addRequest($maybeRequest, 'anilist');
}
}
$results = $requester->makeRequests();
@ -195,7 +200,12 @@ class Anime extends API {
if (( ! empty($data['mal_id'])) && $this->anilistEnabled)
{
$requester->addRequest($this->anilistModel->incrementListItem($data, 'ANIME'), 'anilist');
// If can't map MAL id, this will be null
$maybeRequest = $this->anilistModel->incrementListItem($data, 'ANIME');
if ($maybeRequest !== NULL)
{
$requester->addRequest($maybeRequest, 'anilist');
}
}
$results = $requester->makeRequests();
@ -223,7 +233,12 @@ class Anime extends API {
if (( ! empty($data['mal_id'])) && $this->anilistEnabled)
{
$requester->addRequest($this->anilistModel->updateListItem($data, 'ANIME'), 'anilist');
// If can't map MAL id, this will be null
$maybeRequest = $this->anilistModel->updateListItem($data, 'ANIME');
if ($maybeRequest !== NULL)
{
$requester->addRequest($maybeRequest, 'anilist');
}
}
$results = $requester->makeRequests();
@ -252,7 +267,12 @@ class Anime extends API {
if ($this->anilistEnabled && $malId !== null)
{
$requester->addRequest($this->anilistModel->deleteListItem($malId, 'ANIME'), 'anilist');
// If can't map MAL id, this will be null
$maybeRequest = $this->anilistModel->deleteListItem($malId, 'ANIME');
if ($maybeRequest !== NULL)
{
$requester->addRequest($maybeRequest, 'anilist');
}
}
$results = $requester->makeRequests();

View File

@ -63,6 +63,8 @@ abstract class AbstractType implements ArrayAccess, Countable {
*/
public function __isset($name): bool
{
// This returns the expected results because unset
// properties no longer exist on the class
return property_exists($this, $name);
}
@ -101,12 +103,9 @@ abstract class AbstractType implements ArrayAccess, Countable {
*/
public function __get($name)
{
if (property_exists($this, $name))
{
return $this->$name;
}
throw new UndefinedPropertyException("Trying to get undefined property: '$name'");
// Be a bit more lenient here, so that you can easily typecast missing
// values to reasonable defaults, and not have to resort to array indexes
return ($this->__isset($name)) ? $this->$name : NULL;
}
/**
@ -210,7 +209,7 @@ abstract class AbstractType implements ArrayAccess, Countable {
*/
public function isEmpty(): bool
{
foreach ($this as $key => $value)
foreach ($this as $value)
{
if ( ! empty($value))
{