Simultaneously update kitsu and MAL manga list item

This commit is contained in:
Timothy Warren 2017-03-29 13:29:03 -04:00
parent 377e102650
commit 15b26d8e39
7 changed files with 131 additions and 41 deletions

View File

@ -10,7 +10,7 @@
<h2><?= $escape->html($name) ?></h2> <h2><?= $escape->html($name) ?></h2>
<section class="media-wrap"> <section class="media-wrap">
<?php foreach($items as $item): ?> <?php foreach($items as $item): ?>
<article class="media" id="manga-<?= $item['id'] ?>"> <article class="media" data-kitsu-id="<?= $item['id'] ?>" data-mal-id="<?= $item['mal_id'] ?>">
<?php if ($auth->isAuthenticated()): ?> <?php if ($auth->isAuthenticated()): ?>
<div class="edit_buttons" hidden> <div class="edit_buttons" hidden>
<button class="plus_one_chapter">+1 Chapter</button> <button class="plus_one_chapter">+1 Chapter</button>

View File

@ -74,6 +74,7 @@
<td>&nbsp;</td> <td>&nbsp;</td>
<td> <td>
<input type="hidden" value="<?= $item['id'] ?>" name="id" /> <input type="hidden" value="<?= $item['id'] ?>" name="id" />
<input type="hidden" value="<?= $item['mal_id'] ?>" name="mal_id" />
<input type="hidden" value="<?= $item['manga']['slug'] ?>" name="manga_id" /> <input type="hidden" value="<?= $item['manga']['slug'] ?>" name="manga_id" />
<input type="hidden" value="<?= $item['user_rating'] ?>" name="old_rating" /> <input type="hidden" value="<?= $item['user_rating'] ?>" name="old_rating" />
<input type="hidden" value="true" name="edit" /> <input type="hidden" value="true" name="edit" />
@ -92,6 +93,7 @@
<td>&nbsp;</td> <td>&nbsp;</td>
<td> <td>
<input type="hidden" value="<?= $item['id'] ?>" name="id" /> <input type="hidden" value="<?= $item['id'] ?>" name="id" />
<input type="hidden" value="<?= $item['mal_id'] ?>" name="mal_id" />
<button type="submit" class="danger">Delete Entry</button> <button type="submit" class="danger">Delete Entry</button>
</td> </td>
</tr> </tr>

View File

@ -18,6 +18,7 @@
<th>Completed Chapters</th> <th>Completed Chapters</th>
<th># of Volumes</th> <th># of Volumes</th>
<th>Type</th> <th>Type</th>
<th>Genres</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -40,6 +41,9 @@
<td><?= $item['chapters']['read'] ?> / <?= $item['chapters']['total'] ?></td> <td><?= $item['chapters']['read'] ?> / <?= $item['chapters']['total'] ?></td>
<td><?= $item['volumes']['total'] ?></td> <td><?= $item['volumes']['total'] ?></td>
<td><?= $item['manga']['type'] ?></td> <td><?= $item['manga']['type'] ?></td>
<td class="align_left">
<?= implode(', ', $item['manga']['genres']) ?>
</td>
</tr> </tr>
<?php endforeach ?> <?php endforeach ?>
</tbody> </tbody>

View File

@ -530,7 +530,7 @@ class Model {
'media_type' => 'Manga', 'media_type' => 'Manga',
'status' => $status, 'status' => $status,
], ],
'include' => 'media', 'include' => 'media,media.genres,media.mappings',
'page' => [ 'page' => [
'offset' => $offset, 'offset' => $offset,
'limit' => $limit 'limit' => $limit
@ -544,9 +544,16 @@ class Model {
if ( ! $cacheItem->isHit()) if ( ! $cacheItem->isHit())
{ {
$data = $this->getRequest('library-entries', $options); $data = $this->getRequest('library-entries', $options);
$data = JsonAPI::inlineRawIncludes($data, 'manga');
$transformed = $this->mangaListTransformer->transformCollection($data); $included = JsonAPI::organizeIncludes($data['included']);
$included = JsonAPI::inlineIncludedRelationships($included, 'manga');
foreach($data['data'] as $i => &$item)
{
$item['included'] = $included;
}
$transformed = $this->mangaListTransformer->transformCollection($data['data']);
$cacheItem->set($transformed); $cacheItem->set($transformed);
$cacheItem->save(); $cacheItem->save();

View File

@ -35,22 +35,42 @@ class MangaListTransformer extends AbstractTransformer {
*/ */
public function transform($item) public function transform($item)
{ {
$manga =& $item['manga']; $included = $item['included'];
$mangaId = $item['relationships']['media']['data']['id'];
$manga = $included['manga'][$mangaId];
$genres = array_column($manga['relationships']['genres'], 'name') ?? [];
sort($genres);
$rating = (is_numeric($item['attributes']['rating'])) $rating = (is_numeric($item['attributes']['rating']))
? intval(2 * $item['attributes']['rating']) ? intval(2 * $item['attributes']['rating'])
: '-'; : '-';
$totalChapters = ($manga['attributes']['chapterCount'] > 0) $totalChapters = ($manga['chapterCount'] > 0)
? $manga['attributes']['chapterCount'] ? $manga['chapterCount']
: '-'; : '-';
$totalVolumes = ($manga['attributes']['volumeCount'] > 0) $totalVolumes = ($manga['volumeCount'] > 0)
? $manga['attributes']['volumeCount'] ? $manga['volumeCount']
: '-'; : '-';
$MALid = NULL;
if (array_key_exists('mappings', $manga['relationships']))
{
foreach ($manga['relationships']['mappings'] as $mapping)
{
if ($mapping['externalSite'] === 'myanimelist/manga')
{
$MALid = $mapping['externalId'];
break;
}
}
}
$map = [ $map = [
'id' => $item['id'], 'id' => $item['id'],
'mal_id' => $MALid,
'chapters' => [ 'chapters' => [
'read' => $item['attributes']['progress'], 'read' => $item['attributes']['progress'],
'total' => $totalChapters 'total' => $totalChapters
@ -60,13 +80,13 @@ class MangaListTransformer extends AbstractTransformer {
'total' => $totalVolumes 'total' => $totalVolumes
], ],
'manga' => [ 'manga' => [
'titles' => Kitsu::filterTitles($manga['attributes']), 'titles' => Kitsu::filterTitles($manga),
'alternate_title' => NULL, 'alternate_title' => NULL,
'slug' => $manga['attributes']['slug'], 'slug' => $manga['slug'],
'url' => 'https://kitsu.io/manga/' . $manga['attributes']['slug'], 'url' => 'https://kitsu.io/manga/' . $manga['slug'],
'type' => $manga['attributes']['mangaType'], 'type' => $manga['mangaType'],
'image' => $manga['attributes']['posterImage']['small'], 'image' => $manga['posterImage']['small'],
'genres' => [], //$manga['genres'], 'genres' => $genres,
], ],
'reading_status' => $item['attributes']['status'], 'reading_status' => $item['attributes']['status'],
'notes' => $item['attributes']['notes'], 'notes' => $item['attributes']['notes'],
@ -90,6 +110,7 @@ class MangaListTransformer extends AbstractTransformer {
$map = [ $map = [
'id' => $item['id'], 'id' => $item['id'],
'mal_id' => $item['mal_id'],
'data' => [ 'data' => [
'status' => $item['status'], 'status' => $item['status'],
'progress' => (int)$item['chapters_read'], 'progress' => (int)$item['chapters_read'],

View File

@ -17,7 +17,11 @@
namespace Aviat\AnimeClient\API\MAL; namespace Aviat\AnimeClient\API\MAL;
use Amp\Artax\Request; use Amp\Artax\Request;
use Aviat\AnimeClient\API\MAL\{ListItem, Transformer\AnimeListTransformer}; use Aviat\AnimeClient\API\MAL\{
ListItem,
Transformer\AnimeListTransformer,
Transformer\MangaListTransformer
};
use Aviat\AnimeClient\API\XML; use Aviat\AnimeClient\API\XML;
use Aviat\AnimeClient\API\Mapping\{AnimeWatchingStatus, MangaReadingStatus}; use Aviat\AnimeClient\API\Mapping\{AnimeWatchingStatus, MangaReadingStatus};
use Aviat\Ion\Di\ContainerAware; use Aviat\Ion\Di\ContainerAware;
@ -33,7 +37,7 @@ class Model {
* @var AnimeListTransformer * @var AnimeListTransformer
*/ */
protected $animeListTransformer; protected $animeListTransformer;
/** /**
* @var ListItem * @var ListItem
*/ */
@ -47,6 +51,7 @@ class Model {
public function __construct(ListItem $listItem) public function __construct(ListItem $listItem)
{ {
$this->animeListTransformer = new AnimeListTransformer(); $this->animeListTransformer = new AnimeListTransformer();
$this->mangaListTransformer = new MangaListTransformer();
$this->listItem = $listItem; $this->listItem = $listItem;
} }
@ -83,9 +88,7 @@ class Model {
]; ];
} }
return $this->listItem->create($createData, $type);
return $this->listItem->create($createData);
} }
public function getMangaList(): array public function getMangaList(): array
@ -103,15 +106,23 @@ class Model {
return []; return [];
} }
public function updateListItem(array $data): Request public function updateListItem(array $data, string $type = 'anime'): Request
{ {
$updateData = $this->animeListTransformer->untransform($data); if ($type === 'anime')
return $this->listItem->update($updateData['id'], $updateData['data']); {
$updateData = $this->animeListTransformer->untransform($data);
}
else if ($type === 'manga')
{
$updateData = $this->mangaListTransformer->untransform($data);
}
return $this->listItem->update($updateData['id'], $updateData['data'], $type);
} }
public function deleteListItem(string $id): Request public function deleteListItem(string $id, string $type = 'anime'): Request
{ {
return $this->listItem->delete($id); return $this->listItem->delete($id, $type);
} }
private function getList(string $type): array private function getList(string $type): array

View File

@ -22,6 +22,7 @@ use Aviat\AnimeClient\API\{
ParallelAPIRequest ParallelAPIRequest
}; };
use Aviat\Ion\Di\ContainerInterface; use Aviat\Ion\Di\ContainerInterface;
use Aviat\Ion\Json;
/** /**
* Model for handling requests dealing with the manga list * Model for handling requests dealing with the manga list
@ -83,17 +84,6 @@ class Manga extends API
return $this->kitsuModel->getManga($manga_id); return $this->kitsuModel->getManga($manga_id);
} }
/**
* Create a new manga list item
*
* @param array $data
* @return bool
*/
public function createLibraryItem(array $data): bool
{
return $this->kitsuModel->createListItem($data);
}
/** /**
* Get information about a specific list item * Get information about a specific list item
* for editing/updating that item * for editing/updating that item
@ -106,6 +96,35 @@ class Manga extends API
return $this->kitsuModel->getListItem($itemId); return $this->kitsuModel->getListItem($itemId);
} }
/**
* Create a new manga list item
*
* @param array $data
* @return bool
*/
public function createLibraryItem(array $data): bool
{
$requester = new ParallelAPIRequest();
if ($this->useMALAPI)
{
$malData = $data;
$malId = $this->kitsuModel->getMalIdForManga($malData['id']);
if ( ! is_null($malId))
{
$malData['id'] = $malId;
$requester->addRequest($this->malModel->createListItem($malData, 'manga'), 'mal');
}
}
$requester->addRequest($this->kitsuModel->createListItem($data), 'kitsu');
$results = $requester->makeRequests(TRUE);
return count($results[1]) > 0;
}
/** /**
* Update a list entry * Update a list entry
* *
@ -114,18 +133,44 @@ class Manga extends API
*/ */
public function updateLibraryItem(array $data): array public function updateLibraryItem(array $data): array
{ {
return $this->kitsuModel->updateListItem($data); $requester = new ParallelAPIRequest();
if ($this->useMALAPI)
{
$requester->addRequest($this->malModel->updateListItem($data, 'manga'), 'mal');
}
$requester->addRequest($this->kitsuModel->updateListItem($data), 'kitsu');
$results = $requester->makeRequests(TRUE);
return [
'body' => Json::decode($results[1]['kitsu']->getBody()),
'statusCode' => $results[1]['kitsu']->getStatus()
];
} }
/** /**
* Remove a list entry * Delete a list entry
* *
* @param string $itemId * @param string $id
* @param string|null $malId
* @return bool * @return bool
*/ */
public function deleteLibraryItem(string $itemId): bool public function deleteLibraryItem(string $id, string $malId = NULL): bool
{ {
return $this->kitsuModel->deleteListItem($itemId); $requester = new ParallelAPIRequest();
if ($this->useMALAPI && ! is_null($malId))
{
$requester->addRequest($this->malModel->deleteListItem($malId, 'manga'), 'MAL');
}
$requester->addRequest($this->kitsuModel->deleteListItem($id), 'kitsu');
$results = $requester->makeRequests(TRUE);
return count($results[1]) > 0;
} }
/** /**