4.1 Beta...ish #12
@ -49,6 +49,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<?php endif ?>
|
<?php endif ?>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
<div><?= $item['manga']['type'] ?></div>
|
||||||
<div class="user_rating">Rating: <?= $item['user_rating'] ?> / 10</div>
|
<div class="user_rating">Rating: <?= $item['user_rating'] ?> / 10</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -1,12 +1,61 @@
|
|||||||
<?php
|
<?php
|
||||||
use function Aviat\AnimeClient\arrayToToml;
|
use function Aviat\AnimeClient\loadTomlByFile;
|
||||||
|
|
||||||
|
$settings = loadTomlByFile($config->get('config_dir'));
|
||||||
|
|
||||||
if ( ! $auth->isAuthenticated())
|
if ( ! $auth->isAuthenticated())
|
||||||
{
|
{
|
||||||
echo '<h1>Not Authorized</h1>';
|
echo '<h1>Not Authorized</h1>';
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function render_settings_form ($data, $file)
|
||||||
|
{
|
||||||
|
ob_start();
|
||||||
|
foreach ($data as $key => $value)
|
||||||
|
{
|
||||||
|
?>
|
||||||
|
<tr>
|
||||||
|
<td><label for="<?= $key ?>"><?= $key ?></label></td>
|
||||||
|
<td>
|
||||||
|
<?php if (is_scalar($value)): ?>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="<?= $key ?>"
|
||||||
|
name="config[<?= $file ?>][<?= $key ?>]"
|
||||||
|
value="<?= $value ?>"
|
||||||
|
/>
|
||||||
|
<?php else: ?>
|
||||||
|
<table><?= render_settings_form($value, $file); ?></table>
|
||||||
|
<?php endif ?>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
|
||||||
|
$buffer = ob_get_contents();
|
||||||
|
ob_end_clean();
|
||||||
|
|
||||||
|
return $buffer;
|
||||||
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
||||||
|
<pre><?= print_r($_POST, TRUE) ?></pre>
|
||||||
|
|
||||||
|
<?php foreach($settings as $file => $properties): ?>
|
||||||
|
<form action="<?= $_SERVER['REQUEST_URI'] ?>" method="POST">
|
||||||
|
<table class="form">
|
||||||
|
<caption><?= $file ?></caption>
|
||||||
|
<tbody>
|
||||||
|
<?= render_settings_form($properties, $file); ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<button type="submit">Save Changes</button>
|
||||||
|
</form>
|
||||||
|
<?php endforeach ?>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
"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-json": "*",
|
||||||
"ext-gd":"*",
|
"ext-gd":"*",
|
||||||
"ext-pdo": "*",
|
"ext-pdo": "*",
|
||||||
"maximebf/consolekit": "^1.0",
|
"maximebf/consolekit": "^1.0",
|
||||||
|
3
console
3
console
@ -17,7 +17,8 @@ try
|
|||||||
(new Console([
|
(new Console([
|
||||||
'cache:clear' => Command\CacheClear::class,
|
'cache:clear' => Command\CacheClear::class,
|
||||||
'cache:refresh' => Command\CachePrime::class,
|
'cache:refresh' => Command\CachePrime::class,
|
||||||
// 'lists:sync' => Command\SyncLists::class,
|
'lists:sync' => Command\SyncLists::class,
|
||||||
|
'mal_id:check' => Command\MALIDCheck::class,
|
||||||
]))->run();
|
]))->run();
|
||||||
}
|
}
|
||||||
catch (\Exception $e)
|
catch (\Exception $e)
|
||||||
|
12
public/js/scripts-authed.min.js
vendored
12
public/js/scripts-authed.min.js
vendored
@ -365,12 +365,10 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wire up mal checkbox
|
// Click on hidden MAL checkbox so
|
||||||
|
// that MAL id is passed
|
||||||
AnimeClient.on('main', 'change', '.big-check', (e) => {
|
AnimeClient.on('main', 'change', '.big-check', (e) => {
|
||||||
const id = e.target.id;
|
const id = e.target.id;
|
||||||
AnimeClient.$('.mal-check').forEach(el => {
|
|
||||||
el.checked = false;
|
|
||||||
});
|
|
||||||
document.getElementById(`mal_${id}`).checked = true;
|
document.getElementById(`mal_${id}`).checked = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -386,7 +384,7 @@
|
|||||||
results.push(`
|
results.push(`
|
||||||
<article class="media search">
|
<article class="media search">
|
||||||
<div class="name">
|
<div class="name">
|
||||||
<input type="checkbox" class="mal-check" id="mal_${item.slug}" name="mal_id" value="${x.mal_id}" />
|
<input type="radio" class="mal-check" id="mal_${item.slug}" name="mal_id" value="${x.mal_id}" />
|
||||||
<input type="radio" class="big-check" id="${item.slug}" name="id" value="${x.id}" />
|
<input type="radio" class="big-check" id="${item.slug}" name="id" value="${x.id}" />
|
||||||
<label for="${item.slug}">
|
<label for="${item.slug}">
|
||||||
<img src="/public/images/anime/${x.id}.jpg" alt="" width="220" />
|
<img src="/public/images/anime/${x.id}.jpg" alt="" width="220" />
|
||||||
@ -422,7 +420,7 @@
|
|||||||
results.push(`
|
results.push(`
|
||||||
<article class="media search">
|
<article class="media search">
|
||||||
<div class="name">
|
<div class="name">
|
||||||
<input type="checkbox" id="mal_${item.slug}" name="mal_id" value="${x.mal_id}" />
|
<input type="radio" id="mal_${item.slug}" name="mal_id" value="${x.mal_id}" />
|
||||||
<input type="radio" class="big-check" id="${item.slug}" name="id" value="${x.id}" />
|
<input type="radio" class="big-check" id="${item.slug}" name="id" value="${x.id}" />
|
||||||
<label for="${item.slug}">
|
<label for="${item.slug}">
|
||||||
<img src="/public/images/manga/${x.id}.jpg" alt="" width="220" />
|
<img src="/public/images/manga/${x.id}.jpg" alt="" width="220" />
|
||||||
@ -595,7 +593,7 @@
|
|||||||
|
|
||||||
AnimeClient.show(AnimeClient.$('#loading-shadow')[ 0 ]);
|
AnimeClient.show(AnimeClient.$('#loading-shadow')[ 0 ]);
|
||||||
|
|
||||||
AnimeClient.ajax(AnimeClient.url('/manga/update'), {
|
AnimeClient.ajax(AnimeClient.url('/manga/increment'), {
|
||||||
data,
|
data,
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
|
File diff suppressed because one or more lines are too long
@ -61,7 +61,7 @@ _.on('.manga.list', 'click', '.edit_buttons button', (e) => {
|
|||||||
|
|
||||||
_.show(_.$('#loading-shadow')[ 0 ]);
|
_.show(_.$('#loading-shadow')[ 0 ]);
|
||||||
|
|
||||||
_.ajax(_.url('/manga/update'), {
|
_.ajax(_.url('/manga/increment'), {
|
||||||
data,
|
data,
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
import _ from './base/AnimeClient.js';
|
import _ from './base/AnimeClient.js';
|
||||||
|
|
||||||
// Wire up mal checkbox
|
// Click on hidden MAL checkbox so
|
||||||
|
// that MAL id is passed
|
||||||
_.on('main', 'change', '.big-check', (e) => {
|
_.on('main', 'change', '.big-check', (e) => {
|
||||||
const id = e.target.id;
|
const id = e.target.id;
|
||||||
_.$('.mal-check').forEach(el => {
|
|
||||||
el.checked = false;
|
|
||||||
})
|
|
||||||
document.getElementById(`mal_${id}`).checked = true;
|
document.getElementById(`mal_${id}`).checked = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -21,7 +19,7 @@ export function renderAnimeSearchResults (data) {
|
|||||||
results.push(`
|
results.push(`
|
||||||
<article class="media search">
|
<article class="media search">
|
||||||
<div class="name">
|
<div class="name">
|
||||||
<input type="checkbox" class="mal-check" id="mal_${item.slug}" name="mal_id" value="${x.mal_id}" />
|
<input type="radio" class="mal-check" id="mal_${item.slug}" name="mal_id" value="${x.mal_id}" />
|
||||||
<input type="radio" class="big-check" id="${item.slug}" name="id" value="${x.id}" />
|
<input type="radio" class="big-check" id="${item.slug}" name="id" value="${x.id}" />
|
||||||
<label for="${item.slug}">
|
<label for="${item.slug}">
|
||||||
<img src="/public/images/anime/${x.id}.jpg" alt="" width="220" />
|
<img src="/public/images/anime/${x.id}.jpg" alt="" width="220" />
|
||||||
@ -57,7 +55,7 @@ export function renderMangaSearchResults (data) {
|
|||||||
results.push(`
|
results.push(`
|
||||||
<article class="media search">
|
<article class="media search">
|
||||||
<div class="name">
|
<div class="name">
|
||||||
<input type="checkbox" id="mal_${item.slug}" name="mal_id" value="${x.mal_id}" />
|
<input type="radio" id="mal_${item.slug}" name="mal_id" value="${x.mal_id}" />
|
||||||
<input type="radio" class="big-check" id="${item.slug}" name="id" value="${x.id}" />
|
<input type="radio" class="big-check" id="${item.slug}" name="id" value="${x.id}" />
|
||||||
<label for="${item.slug}">
|
<label for="${item.slug}">
|
||||||
<img src="/public/images/manga/${x.id}.jpg" alt="" width="220" />
|
<img src="/public/images/manga/${x.id}.jpg" alt="" width="220" />
|
||||||
|
@ -11,6 +11,7 @@ query ($name: String, $type: MediaType) {
|
|||||||
private
|
private
|
||||||
notes
|
notes
|
||||||
status
|
status
|
||||||
|
updatedAt
|
||||||
media {
|
media {
|
||||||
id
|
id
|
||||||
idMal
|
idMal
|
||||||
|
@ -18,10 +18,12 @@ namespace Aviat\AnimeClient\API\Anilist\Transformer;
|
|||||||
|
|
||||||
use Aviat\AnimeClient\API\Enum\AnimeWatchingStatus\Anilist as AnilistStatus;
|
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\{Anime, AnimeListItem, AnimeFormItem};
|
use Aviat\AnimeClient\Types\{AnimeListItem, FormItem};
|
||||||
|
|
||||||
use Aviat\Ion\Transformer\AbstractTransformer;
|
use Aviat\Ion\Transformer\AbstractTransformer;
|
||||||
|
|
||||||
|
use DateTime;
|
||||||
|
|
||||||
class AnimeListTransformer extends AbstractTransformer {
|
class AnimeListTransformer extends AbstractTransformer {
|
||||||
|
|
||||||
public function transform($item): AnimeListItem
|
public function transform($item): AnimeListItem
|
||||||
@ -33,11 +35,11 @@ class AnimeListTransformer extends AbstractTransformer {
|
|||||||
* Transform Anilist list item to Kitsu form update format
|
* Transform Anilist list item to Kitsu form update format
|
||||||
*
|
*
|
||||||
* @param array $item
|
* @param array $item
|
||||||
* @return AnimeFormItem
|
* @return FormItem
|
||||||
*/
|
*/
|
||||||
public function untransform(array $item): AnimeFormItem
|
public function untransform(array $item): FormItem
|
||||||
{
|
{
|
||||||
return new AnimeFormItem([
|
return new FormItem([
|
||||||
'id' => $item['id'],
|
'id' => $item['id'],
|
||||||
'mal_id' => $item['media']['idMal'],
|
'mal_id' => $item['media']['idMal'],
|
||||||
'data' => [
|
'data' => [
|
||||||
@ -48,7 +50,10 @@ class AnimeListTransformer extends AbstractTransformer {
|
|||||||
'reconsumeCount' => $item['repeat'],
|
'reconsumeCount' => $item['repeat'],
|
||||||
'reconsuming' => $item['status'] === AnilistStatus::REPEATING,
|
'reconsuming' => $item['status'] === AnilistStatus::REPEATING,
|
||||||
'status' => AnimeWatchingStatus::ANILIST_TO_KITSU[$item['status']],
|
'status' => AnimeWatchingStatus::ANILIST_TO_KITSU[$item['status']],
|
||||||
]
|
'updatedAt' => (new DateTime())
|
||||||
|
->setTimestamp($item['updatedAt'])
|
||||||
|
->format(DateTime::W3C)
|
||||||
|
],
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,10 +18,12 @@ namespace Aviat\AnimeClient\API\Anilist\Transformer;
|
|||||||
|
|
||||||
use Aviat\AnimeClient\API\Enum\MangaReadingStatus\Anilist as AnilistStatus;
|
use Aviat\AnimeClient\API\Enum\MangaReadingStatus\Anilist as AnilistStatus;
|
||||||
use Aviat\AnimeClient\API\Mapping\MangaReadingStatus;
|
use Aviat\AnimeClient\API\Mapping\MangaReadingStatus;
|
||||||
use Aviat\AnimeClient\Types\MangaFormItem;
|
use Aviat\AnimeClient\Types\FormItem;
|
||||||
|
|
||||||
use Aviat\Ion\Transformer\AbstractTransformer;
|
use Aviat\Ion\Transformer\AbstractTransformer;
|
||||||
|
|
||||||
|
use DateTime;
|
||||||
|
|
||||||
class MangaListTransformer extends AbstractTransformer {
|
class MangaListTransformer extends AbstractTransformer {
|
||||||
|
|
||||||
public function transform($item)
|
public function transform($item)
|
||||||
@ -33,11 +35,11 @@ class MangaListTransformer extends AbstractTransformer {
|
|||||||
* Transform Anilist list item to Kitsu form update format
|
* Transform Anilist list item to Kitsu form update format
|
||||||
*
|
*
|
||||||
* @param array $item
|
* @param array $item
|
||||||
* @return MangaFormItem
|
* @return FormItem
|
||||||
*/
|
*/
|
||||||
public function untransform(array $item): MangaFormItem
|
public function untransform(array $item): FormItem
|
||||||
{
|
{
|
||||||
return new MangaFormItem([
|
return new FormItem([
|
||||||
'id' => $item['id'],
|
'id' => $item['id'],
|
||||||
'mal_id' => $item['media']['idMal'],
|
'mal_id' => $item['media']['idMal'],
|
||||||
'data' => [
|
'data' => [
|
||||||
@ -48,6 +50,9 @@ class MangaListTransformer extends AbstractTransformer {
|
|||||||
'reconsumeCount' => $item['repeat'],
|
'reconsumeCount' => $item['repeat'],
|
||||||
'reconsuming' => $item['status'] === AnilistStatus::REPEATING,
|
'reconsuming' => $item['status'] === AnilistStatus::REPEATING,
|
||||||
'status' => MangaReadingStatus::ANILIST_TO_KITSU[$item['status']],
|
'status' => MangaReadingStatus::ANILIST_TO_KITSU[$item['status']],
|
||||||
|
'updatedAt' => (new DateTime())
|
||||||
|
->setTimestamp($item['updatedAt'])
|
||||||
|
->format(DateTime::W3C),
|
||||||
]
|
]
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ final class Auth {
|
|||||||
* @param string $password
|
* @param string $password
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function authenticate($password)
|
public function authenticate(string $password): bool
|
||||||
{
|
{
|
||||||
$config = $this->container->get('config');
|
$config = $this->container->get('config');
|
||||||
$username = $config->get(['kitsu_username']);
|
$username = $config->get(['kitsu_username']);
|
||||||
@ -117,7 +117,7 @@ final class Auth {
|
|||||||
* @param string $token
|
* @param string $token
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function reAuthenticate(string $token)
|
public function reAuthenticate(string $token): bool
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -162,7 +162,7 @@ final class Auth {
|
|||||||
*
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function isAuthenticated()
|
public function isAuthenticated(): bool
|
||||||
{
|
{
|
||||||
return ($this->get_auth_token() !== FALSE);
|
return ($this->get_auth_token() !== FALSE);
|
||||||
}
|
}
|
||||||
@ -172,7 +172,7 @@ final class Auth {
|
|||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function logout()
|
public function logout(): void
|
||||||
{
|
{
|
||||||
$this->segment->clear();
|
$this->segment->clear();
|
||||||
}
|
}
|
||||||
@ -185,14 +185,18 @@ final class Auth {
|
|||||||
public function get_auth_token()
|
public function get_auth_token()
|
||||||
{
|
{
|
||||||
$token = $this->segment->get('auth_token', FALSE);
|
$token = $this->segment->get('auth_token', FALSE);
|
||||||
$refresh_token = $this->segment->get('refresh_token', FALSE);
|
$refreshToken = $this->segment->get('refresh_token', FALSE);
|
||||||
$isExpired = time() > $this->segment->get('auth_token_expires', 0);
|
$isExpired = time() > $this->segment->get('auth_token_expires', 0);
|
||||||
|
|
||||||
// Attempt to re-authenticate with refresh token
|
// Attempt to re-authenticate with refresh token
|
||||||
if ($isExpired && $refresh_token)
|
if ($isExpired && $refreshToken)
|
||||||
{
|
{
|
||||||
$reauthenticated = $this->reAuthenticate($refresh_token);
|
if ($this->reAuthenticate($refreshToken))
|
||||||
return $this->segment->get('auth_token', FALSE);
|
{
|
||||||
|
return $this->segment->get('auth_token', FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $token;
|
return $token;
|
||||||
|
@ -19,7 +19,7 @@ namespace Aviat\AnimeClient\API\Kitsu\Transformer;
|
|||||||
use Aviat\AnimeClient\API\Kitsu;
|
use Aviat\AnimeClient\API\Kitsu;
|
||||||
use Aviat\AnimeClient\Types\{
|
use Aviat\AnimeClient\Types\{
|
||||||
Anime,
|
Anime,
|
||||||
AnimeFormItem,
|
FormItem,
|
||||||
AnimeListItem
|
AnimeListItem
|
||||||
};
|
};
|
||||||
use Aviat\Ion\Transformer\AbstractTransformer;
|
use Aviat\Ion\Transformer\AbstractTransformer;
|
||||||
@ -95,7 +95,7 @@ final class AnimeListTransformer extends AbstractTransformer {
|
|||||||
'title' => $title,
|
'title' => $title,
|
||||||
'titles' => $titles,
|
'titles' => $titles,
|
||||||
'slug' => $anime['slug'],
|
'slug' => $anime['slug'],
|
||||||
'show_type' => $this->string($anime['showType'])->upperCaseFirst()->__toString(),
|
'show_type' => $this->string($anime['subtype'])->upperCaseFirst()->__toString(),
|
||||||
'cover_image' => $anime['posterImage']['small'],
|
'cover_image' => $anime['posterImage']['small'],
|
||||||
'genres' => $genres,
|
'genres' => $genres,
|
||||||
'streaming_links' => $streamingLinks,
|
'streaming_links' => $streamingLinks,
|
||||||
@ -114,14 +114,14 @@ final class AnimeListTransformer extends AbstractTransformer {
|
|||||||
* api response format
|
* api response format
|
||||||
*
|
*
|
||||||
* @param array $item Transformed library item
|
* @param array $item Transformed library item
|
||||||
* @return AnimeFormItem API library item
|
* @return FormItem API library item
|
||||||
*/
|
*/
|
||||||
public function untransform($item): AnimeFormItem
|
public function untransform($item): FormItem
|
||||||
{
|
{
|
||||||
$privacy = (array_key_exists('private', $item) && $item['private']);
|
$privacy = (array_key_exists('private', $item) && $item['private']);
|
||||||
$rewatching = (array_key_exists('rewatching', $item) && $item['rewatching']);
|
$rewatching = (array_key_exists('rewatching', $item) && $item['rewatching']);
|
||||||
|
|
||||||
$untransformed = new AnimeFormItem([
|
$untransformed = new FormItem([
|
||||||
'id' => $item['id'],
|
'id' => $item['id'],
|
||||||
'anilist_item_id' => $item['anilist_item_id'] ?? NULL,
|
'anilist_item_id' => $item['anilist_item_id'] ?? NULL,
|
||||||
'mal_id' => $item['mal_id'] ?? NULL,
|
'mal_id' => $item['mal_id'] ?? NULL,
|
||||||
|
@ -18,7 +18,7 @@ namespace Aviat\AnimeClient\API\Kitsu\Transformer;
|
|||||||
|
|
||||||
use Aviat\AnimeClient\API\Kitsu;
|
use Aviat\AnimeClient\API\Kitsu;
|
||||||
use Aviat\AnimeClient\Types\{
|
use Aviat\AnimeClient\Types\{
|
||||||
MangaFormItem, MangaFormItemData,
|
FormItem, FormItemData,
|
||||||
MangaListItem, MangaListItemDetail
|
MangaListItem, MangaListItemDetail
|
||||||
};
|
};
|
||||||
use Aviat\Ion\StringWrapper;
|
use Aviat\Ion\StringWrapper;
|
||||||
@ -97,7 +97,7 @@ final class MangaListTransformer extends AbstractTransformer {
|
|||||||
'slug' => $manga['slug'],
|
'slug' => $manga['slug'],
|
||||||
'title' => $title,
|
'title' => $title,
|
||||||
'titles' => $titles,
|
'titles' => $titles,
|
||||||
'type' => $manga['mangaType'],
|
'type' => $this->string($manga['subtype'])->upperCaseFirst()->__toString(),
|
||||||
'url' => 'https://kitsu.io/manga/' . $manga['slug'],
|
'url' => 'https://kitsu.io/manga/' . $manga['slug'],
|
||||||
]),
|
]),
|
||||||
'reading_status' => $item['attributes']['status'],
|
'reading_status' => $item['attributes']['status'],
|
||||||
@ -114,16 +114,16 @@ final class MangaListTransformer extends AbstractTransformer {
|
|||||||
* Untransform data to update the api
|
* Untransform data to update the api
|
||||||
*
|
*
|
||||||
* @param array $item
|
* @param array $item
|
||||||
* @return MangaFormItem
|
* @return FormItem
|
||||||
*/
|
*/
|
||||||
public function untransform($item): MangaFormItem
|
public function untransform($item): FormItem
|
||||||
{
|
{
|
||||||
$rereading = array_key_exists('rereading', $item) && (bool)$item['rereading'];
|
$rereading = array_key_exists('rereading', $item) && (bool)$item['rereading'];
|
||||||
|
|
||||||
$map = new MangaFormItem([
|
$map = new FormItem([
|
||||||
'id' => $item['id'],
|
'id' => $item['id'],
|
||||||
'mal_id' => $item['mal_id'],
|
'mal_id' => $item['mal_id'],
|
||||||
'data' => new MangaFormItemData([
|
'data' => new FormItemData([
|
||||||
'status' => $item['status'],
|
'status' => $item['status'],
|
||||||
'reconsuming' => $rereading,
|
'reconsuming' => $rereading,
|
||||||
'reconsumeCount' => (int)$item['reread_count'],
|
'reconsumeCount' => (int)$item['reread_count'],
|
||||||
|
@ -51,6 +51,26 @@ function loadToml(string $path): array
|
|||||||
return $output;
|
return $output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load configuration from toml files, keyed by the original file
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
function loadTomlByFile(string $path): array
|
||||||
|
{
|
||||||
|
$output = [];
|
||||||
|
$files = glob("{$path}/*.toml");
|
||||||
|
|
||||||
|
foreach ($files as $file)
|
||||||
|
{
|
||||||
|
$config = Toml::parseFile($file);
|
||||||
|
$output[basename($file)] = $config;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is the array sequential, not associative?
|
* Is the array sequential, not associative?
|
||||||
*
|
*
|
||||||
|
192
src/Command/MALIDCheck.php
Normal file
192
src/Command/MALIDCheck.php
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
<?php declare(strict_types=1);
|
||||||
|
/**
|
||||||
|
* Hummingbird Anime List Client
|
||||||
|
*
|
||||||
|
* An API client for Kitsu 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\Command;
|
||||||
|
|
||||||
|
|
||||||
|
use Aviat\AnimeClient\API\{
|
||||||
|
APIRequestBuilder,
|
||||||
|
JsonAPI,
|
||||||
|
FailedResponseException,
|
||||||
|
ParallelAPIRequest
|
||||||
|
};
|
||||||
|
|
||||||
|
use Aviat\Ion\Json;
|
||||||
|
|
||||||
|
|
||||||
|
final class MALIDCheck extends BaseCommand {
|
||||||
|
|
||||||
|
private $kitsuModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check MAL mapping validity
|
||||||
|
*
|
||||||
|
* @param array $args
|
||||||
|
* @param array $options
|
||||||
|
* @throws \Aviat\Ion\Di\Exception\ContainerException
|
||||||
|
* @throws \Aviat\Ion\Di\Exception\NotFoundException
|
||||||
|
*/
|
||||||
|
public function execute(array $args, array $options = []): void
|
||||||
|
{
|
||||||
|
$this->setContainer($this->setupContainer());
|
||||||
|
$this->setCache($this->container->get('cache'));
|
||||||
|
$this->kitsuModel = $this->container->get('kitsu-model');
|
||||||
|
|
||||||
|
// @TODO: Stuff!
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getListIds()
|
||||||
|
{
|
||||||
|
$this->getListCounts('anime');
|
||||||
|
$this->getListCounts('manga');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getListCounts($type): void
|
||||||
|
{
|
||||||
|
$uType = ucfirst($type);
|
||||||
|
|
||||||
|
$kitsuCount = 0;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$kitsuCount = $this->kitsuModel->{"get{$uType}ListCount"}();
|
||||||
|
} catch (FailedResponseException $e)
|
||||||
|
{
|
||||||
|
dump($e);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->echoBox("Number of Kitsu {$type} list items: {$kitsuCount}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format a kitsu list for the sake of comparision
|
||||||
|
*
|
||||||
|
* @param string $type
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function formatKitsuList(string $type = 'anime'): array
|
||||||
|
{
|
||||||
|
$data = $this->kitsuModel->{'getFull' . ucfirst($type) . 'List'}();
|
||||||
|
|
||||||
|
if (empty($data))
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$includes = JsonAPI::organizeIncludes($data['included']);
|
||||||
|
$includes['mappings'] = $this->filterMappings($includes['mappings'], $type);
|
||||||
|
|
||||||
|
$output = [];
|
||||||
|
|
||||||
|
foreach ($data['data'] as $listItem)
|
||||||
|
{
|
||||||
|
$id = $listItem['relationships'][$type]['data']['id'];
|
||||||
|
|
||||||
|
$potentialMappings = $includes[$type][$id]['relationships']['mappings'];
|
||||||
|
$malId = NULL;
|
||||||
|
|
||||||
|
foreach ($potentialMappings as $mappingId)
|
||||||
|
{
|
||||||
|
if (array_key_exists($mappingId, $includes['mappings']))
|
||||||
|
{
|
||||||
|
$malId = $includes['mappings'][$mappingId]['externalId'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip to the next item if there isn't a MAL ID
|
||||||
|
if ($malId === NULL)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$output[$listItem['id']] = [
|
||||||
|
'id' => $listItem['id'],
|
||||||
|
'malId' => $malId,
|
||||||
|
'data' => $listItem['attributes'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter Kitsu mappings for the specified type
|
||||||
|
*
|
||||||
|
* @param array $includes
|
||||||
|
* @param string $type
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function filterMappings(array $includes, string $type = 'anime'): array
|
||||||
|
{
|
||||||
|
$output = [];
|
||||||
|
|
||||||
|
foreach ($includes as $id => $mapping)
|
||||||
|
{
|
||||||
|
if ($mapping['externalSite'] === "myanimelist/{$type}")
|
||||||
|
{
|
||||||
|
$output[$id] = $mapping;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function checkMALIds(array $kitsuList, string $type)
|
||||||
|
{
|
||||||
|
$requester = new ParallelAPIRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create/Update list items on Kitsu
|
||||||
|
*
|
||||||
|
* @param array $itemsToUpdate
|
||||||
|
* @param string $action
|
||||||
|
* @param string $type
|
||||||
|
*/
|
||||||
|
protected function updateKitsuListItems(array $itemsToUpdate, string $action = 'update', string $type = 'anime'): void
|
||||||
|
{
|
||||||
|
$requester = new ParallelAPIRequest();
|
||||||
|
foreach ($itemsToUpdate as $item)
|
||||||
|
{
|
||||||
|
if ($action === 'update')
|
||||||
|
{
|
||||||
|
$requester->addRequest($this->kitsuModel->updateListItem($item));
|
||||||
|
} else if ($action === 'create')
|
||||||
|
{
|
||||||
|
$requester->addRequest($this->kitsuModel->createListItem($item));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$responses = $requester->makeRequests();
|
||||||
|
|
||||||
|
foreach ($responses as $key => $response)
|
||||||
|
{
|
||||||
|
$responseData = Json::decode($response);
|
||||||
|
|
||||||
|
$id = $itemsToUpdate[$key]['id'];
|
||||||
|
if ( ! array_key_exists('errors', $responseData))
|
||||||
|
{
|
||||||
|
$verb = ($action === 'update') ? 'updated' : 'created';
|
||||||
|
$this->echoBox("Successfully {$verb} Kitsu {$type} list item with id: {$id}");
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
dump($responseData);
|
||||||
|
$verb = ($action === 'update') ? 'update' : 'create';
|
||||||
|
$this->echoBox("Failed to {$verb} Kitsu {$type} list item with id: {$id}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -16,14 +16,18 @@
|
|||||||
|
|
||||||
namespace Aviat\AnimeClient\Command;
|
namespace Aviat\AnimeClient\Command;
|
||||||
|
|
||||||
use Aviat\AnimeClient\API\
|
use Aviat\AnimeClient\API\{
|
||||||
{FailedResponseException, JsonAPI, Kitsu\Transformer\MangaListTransformer, ParallelAPIRequest};
|
FailedResponseException,
|
||||||
|
JsonAPI,
|
||||||
|
Kitsu\Transformer\MangaListTransformer,
|
||||||
|
ParallelAPIRequest
|
||||||
|
};
|
||||||
use Aviat\AnimeClient\API\Anilist\Transformer\{
|
use Aviat\AnimeClient\API\Anilist\Transformer\{
|
||||||
AnimeListTransformer as AALT,
|
AnimeListTransformer as AALT,
|
||||||
MangaListTransformer as AMLT,
|
MangaListTransformer as AMLT
|
||||||
};
|
};
|
||||||
use Aviat\AnimeClient\API\Mapping\{AnimeWatchingStatus, MangaReadingStatus};
|
use Aviat\AnimeClient\API\Mapping\{AnimeWatchingStatus, MangaReadingStatus};
|
||||||
use Aviat\AnimeClient\Types\{AnimeFormItem, MangaFormItem};
|
use Aviat\AnimeClient\Types\FormItem;
|
||||||
use Aviat\Ion\Json;
|
use Aviat\Ion\Json;
|
||||||
use DateTime;
|
use DateTime;
|
||||||
|
|
||||||
@ -49,9 +53,9 @@ final class SyncLists extends BaseCommand {
|
|||||||
*
|
*
|
||||||
* @param array $args
|
* @param array $args
|
||||||
* @param array $options
|
* @param array $options
|
||||||
* @throws \Aviat\Ion\Di\ContainerException
|
* @throws \Aviat\Ion\Di\Exception\ContainerException
|
||||||
* @throws \Aviat\Ion\Di\NotFoundException
|
* @throws \Aviat\Ion\Di\Exception\NotFoundException
|
||||||
* @return void
|
* @throws \Throwable
|
||||||
*/
|
*/
|
||||||
public function execute(array $args, array $options = []): void
|
public function execute(array $args, array $options = []): void
|
||||||
{
|
{
|
||||||
@ -65,10 +69,10 @@ final class SyncLists extends BaseCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempt to synchronize external apis
|
* Attempt to synchronize external APIs
|
||||||
*
|
*
|
||||||
* @param string $type anime|manga
|
* @param string $type
|
||||||
* @return void
|
* @throws \Throwable
|
||||||
*/
|
*/
|
||||||
protected function sync(string $type): void
|
protected function sync(string $type): void
|
||||||
{
|
{
|
||||||
@ -157,6 +161,8 @@ final class SyncLists extends BaseCommand {
|
|||||||
* Format an Anilist anime list for comparison
|
* Format an Anilist anime list for comparison
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
|
* @throws \Aviat\Ion\Di\Exception\ContainerException
|
||||||
|
* @throws \Aviat\Ion\Di\Exception\NotFoundException
|
||||||
*/
|
*/
|
||||||
protected function formatAnilistAnimeList(): array
|
protected function formatAnilistAnimeList(): array
|
||||||
{
|
{
|
||||||
@ -188,6 +194,8 @@ final class SyncLists extends BaseCommand {
|
|||||||
* Format an Anilist manga list for comparison
|
* Format an Anilist manga list for comparison
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
|
* @throws \Aviat\Ion\Di\Exception\ContainerException
|
||||||
|
* @throws \Aviat\Ion\Di\Exception\NotFoundException
|
||||||
*/
|
*/
|
||||||
protected function formatAnilistMangaList(): array
|
protected function formatAnilistMangaList(): array
|
||||||
{
|
{
|
||||||
@ -223,7 +231,8 @@ final class SyncLists extends BaseCommand {
|
|||||||
*/
|
*/
|
||||||
protected function formatKitsuList(string $type = 'anime'): array
|
protected function formatKitsuList(string $type = 'anime'): array
|
||||||
{
|
{
|
||||||
$data = $this->kitsuModel->{'getFullRaw' . ucfirst($type) . 'List'}();
|
$method = 'getFullRaw' . ucfirst($type) . 'List';
|
||||||
|
$data = $this->kitsuModel->$method();
|
||||||
|
|
||||||
if (empty($data))
|
if (empty($data))
|
||||||
{
|
{
|
||||||
@ -294,14 +303,14 @@ final class SyncLists extends BaseCommand {
|
|||||||
] : [
|
] : [
|
||||||
114638, // Cells at Work: Black
|
114638, // Cells at Work: Black
|
||||||
];
|
];
|
||||||
|
|
||||||
$malIds = array_keys($anilistList);
|
$malIds = array_keys($anilistList);
|
||||||
$kitsuMalIds = array_map('intval', array_column($kitsuList, 'malId'));
|
$kitsuMalIds = array_map('intval', array_column($kitsuList, 'malId'));
|
||||||
$missingMalIds = array_diff($malIds, $kitsuMalIds);
|
$missingMalIds = array_diff($malIds, $kitsuMalIds);
|
||||||
$missingMalIds = array_diff($missingMalIds, $malBlackList);
|
$missingMalIds = array_diff($missingMalIds, $malBlackList);
|
||||||
|
|
||||||
foreach($missingMalIds as $mid)
|
foreach($missingMalIds as $mid)
|
||||||
{
|
{
|
||||||
$itemsToAddToKitsu[] = array_merge($anilistList[$mid]['data'], [
|
$itemsToAddToKitsu[] = array_merge($anilistList[$mid]['data'], [
|
||||||
'id' => $this->kitsuModel->getKitsuIdFromMALId((string)$mid, $type),
|
'id' => $this->kitsuModel->getKitsuIdFromMALId((string)$mid, $type),
|
||||||
'type' => $type
|
'type' => $type
|
||||||
@ -311,8 +320,8 @@ final class SyncLists extends BaseCommand {
|
|||||||
foreach($kitsuList as $kitsuItem)
|
foreach($kitsuList as $kitsuItem)
|
||||||
{
|
{
|
||||||
$malId = $kitsuItem['malId'];
|
$malId = $kitsuItem['malId'];
|
||||||
|
|
||||||
if (in_array($malId, $malBlackList))
|
if (\in_array((int)$malId, $malBlackList, TRUE))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -341,7 +350,7 @@ final class SyncLists extends BaseCommand {
|
|||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$statusMap = ($type === 'anime') ? AnimeWatchingStatus::class : MangaReadingStatus::class;
|
$statusMap = ($type === 'anime') ? AnimeWatchingStatus::class : MangaReadingStatus::class;
|
||||||
|
|
||||||
// Looks like this item only exists on Kitsu
|
// Looks like this item only exists on Kitsu
|
||||||
@ -356,13 +365,9 @@ final class SyncLists extends BaseCommand {
|
|||||||
'repeat' => $kItem['reconsumeCount'],
|
'repeat' => $kItem['reconsumeCount'],
|
||||||
'score' => $kItem['ratingTwenty'] / 2,
|
'score' => $kItem['ratingTwenty'] / 2,
|
||||||
'status' => $newItemStatus,
|
'status' => $newItemStatus,
|
||||||
], // $kitsuItem['data']
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//dump($itemsToAddToAnilist);
|
|
||||||
//die();
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'addToAnilist' => $itemsToAddToAnilist,
|
'addToAnilist' => $itemsToAddToAnilist,
|
||||||
@ -390,6 +395,7 @@ final class SyncLists extends BaseCommand {
|
|||||||
'status',
|
'status',
|
||||||
];
|
];
|
||||||
$diff = [];
|
$diff = [];
|
||||||
|
$dateDiff = new DateTime($kitsuItem['data']['updatedAt']) <=> new DateTime((string)$anilistItem['data']['updatedAt']);
|
||||||
|
|
||||||
// Correct differences in notation
|
// Correct differences in notation
|
||||||
$kitsuItem['data']['rating'] = $kitsuItem['data']['ratingTwenty'] / 2;
|
$kitsuItem['data']['rating'] = $kitsuItem['data']['ratingTwenty'] / 2;
|
||||||
@ -429,7 +435,6 @@ final class SyncLists extends BaseCommand {
|
|||||||
$return['updateType'][] = 'kitsu';
|
$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
|
||||||
if ($sameStatus && ( ! $sameProgress))
|
if ($sameStatus && ( ! $sameProgress))
|
||||||
{
|
{
|
||||||
@ -444,17 +449,24 @@ final class SyncLists extends BaseCommand {
|
|||||||
$return['updateType'][] = 'kitsu';
|
$return['updateType'][] = 'kitsu';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If status is different, go with Kitsu
|
// If status is different, use the status of the more recently updated item
|
||||||
if ( ! $sameStatus)
|
if ( ! $sameStatus)
|
||||||
{
|
{
|
||||||
$update['data']['status'] = $kitsuItem['data']['status'];
|
if ($dateDiff === 1)
|
||||||
$return['updateType'][] = 'anilist';
|
{
|
||||||
|
$update['data']['status'] = $kitsuItem['data']['status'];
|
||||||
|
$return['updateType'][] = 'anilist';
|
||||||
|
} else if ($dateDiff === -1)
|
||||||
|
{
|
||||||
|
$update['data']['status'] = $anilistItem['data']['status'];
|
||||||
|
$return['updateType'][] = 'kitsu';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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)
|
||||||
{
|
{
|
||||||
@ -478,18 +490,17 @@ final class SyncLists extends BaseCommand {
|
|||||||
|
|
||||||
$return['updateType'][] = 'kitsu';
|
$return['updateType'][] = 'kitsu';
|
||||||
}
|
}
|
||||||
}*/
|
}
|
||||||
|
|
||||||
// If rating is different, use the kitsu rating, unless the other rating
|
// Use the first set rating, otherwise use the newer rating
|
||||||
// is set, and the kitsu rating is not set
|
|
||||||
if ( ! $sameRating)
|
if ( ! $sameRating)
|
||||||
{
|
{
|
||||||
if ($kitsuItem['data']['rating'] !== 0)
|
if ($kitsuItem['data']['rating'] !== 0 && $dateDiff === 1)
|
||||||
{
|
{
|
||||||
$update['data']['rating'] = $kitsuItem['data']['rating'];
|
$update['data']['rating'] = $kitsuItem['data']['rating'];
|
||||||
$return['updateType'][] = 'anilist';
|
$return['updateType'][] = 'anilist';
|
||||||
}
|
}
|
||||||
else
|
else if($dateDiff === -1)
|
||||||
{
|
{
|
||||||
$update['data']['rating'] = $anilistItem['data']['rating'];
|
$update['data']['rating'] = $anilistItem['data']['rating'];
|
||||||
$return['updateType'][] = 'kitsu';
|
$return['updateType'][] = 'kitsu';
|
||||||
@ -526,30 +537,17 @@ final class SyncLists extends BaseCommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If status is different, use the status of the more recently updated item
|
|
||||||
/* if ( ! $sameStatus)
|
|
||||||
{
|
|
||||||
if ($dateDiff === 1)
|
|
||||||
{
|
|
||||||
$update['data']['status'] = $kitsuItem['data']['status'];
|
|
||||||
$return['updateType'][] = 'anilist';
|
|
||||||
}
|
|
||||||
else if ($dateDiff === -1)
|
|
||||||
{
|
|
||||||
$update['data']['status'] = $anilistItem['data']['status'];
|
|
||||||
$return['updateType'][] = 'kitsu';
|
|
||||||
}
|
|
||||||
} */
|
|
||||||
|
|
||||||
$return['meta'] = [
|
$return['meta'] = [
|
||||||
'kitsu' => $kitsuItem['data'],
|
'kitsu' => $kitsuItem['data'],
|
||||||
'anilist' => $anilistItem['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
|
// Fill in missing data values for update on Anlist
|
||||||
// so I don't have to create a really complex graphql query
|
// so I don't have to create a really complex graphql query
|
||||||
// to handle each combination of fields
|
// to handle each combination of fields
|
||||||
@ -564,11 +562,11 @@ final class SyncLists extends BaseCommand {
|
|||||||
'reconsuming' => $kitsuItem['data']['reconsuming'],
|
'reconsuming' => $kitsuItem['data']['reconsuming'],
|
||||||
'status' => $kitsuItem['data']['status'],
|
'status' => $kitsuItem['data']['status'],
|
||||||
];
|
];
|
||||||
|
|
||||||
$return['data']['data'] = array_merge($prevData, $return['data']['data']);
|
$return['data']['data'] = array_merge($prevData, $return['data']['data']);
|
||||||
}
|
}
|
||||||
|
|
||||||
// dump($return);
|
dump($return);
|
||||||
|
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
@ -579,18 +577,17 @@ final class SyncLists extends BaseCommand {
|
|||||||
* @param array $itemsToUpdate
|
* @param array $itemsToUpdate
|
||||||
* @param string $action
|
* @param string $action
|
||||||
* @param string $type
|
* @param string $type
|
||||||
|
* @throws \Throwable
|
||||||
*/
|
*/
|
||||||
protected function updateKitsuListItems(array $itemsToUpdate, string $action = 'update', string $type = 'anime'): void
|
protected function updateKitsuListItems(array $itemsToUpdate, string $action = 'update', string $type = 'anime'): void
|
||||||
{
|
{
|
||||||
$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(
|
$requester->addRequest(
|
||||||
$this->kitsuModel->updateListItem(new $typeClass($item))
|
$this->kitsuModel->updateListItem(new FormItem($item))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else if ($action === 'create')
|
else if ($action === 'create')
|
||||||
@ -626,19 +623,18 @@ final class SyncLists extends BaseCommand {
|
|||||||
* @param array $itemsToUpdate
|
* @param array $itemsToUpdate
|
||||||
* @param string $action
|
* @param string $action
|
||||||
* @param string $type
|
* @param string $type
|
||||||
|
* @throws \Throwable
|
||||||
*/
|
*/
|
||||||
protected function updateAnilistListItems(array$itemsToUpdate, string $action = 'update', string $type = 'anime'): void
|
protected function updateAnilistListItems(array $itemsToUpdate, string $action = 'update', string $type = 'anime'): void
|
||||||
{
|
{
|
||||||
$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(
|
$requester->addRequest(
|
||||||
$this->anilistModel->updateListItem(new $typeClass($item), $type)
|
$this->anilistModel->updateListItem(new FormItem($item), $type)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else if ($action === 'create')
|
else if ($action === 'create')
|
||||||
|
@ -20,7 +20,7 @@ use Aviat\AnimeClient\Controller as BaseController;
|
|||||||
use Aviat\AnimeClient\API\Kitsu\Transformer\AnimeListTransformer;
|
use Aviat\AnimeClient\API\Kitsu\Transformer\AnimeListTransformer;
|
||||||
use Aviat\AnimeClient\API\Enum\AnimeWatchingStatus\Kitsu as KitsuWatchingStatus;
|
use Aviat\AnimeClient\API\Enum\AnimeWatchingStatus\Kitsu as KitsuWatchingStatus;
|
||||||
use Aviat\AnimeClient\API\Mapping\AnimeWatchingStatus;
|
use Aviat\AnimeClient\API\Mapping\AnimeWatchingStatus;
|
||||||
use Aviat\AnimeClient\Types\AnimeFormItem;
|
use Aviat\AnimeClient\Types\FormItem;
|
||||||
use Aviat\Ion\Di\ContainerInterface;
|
use Aviat\Ion\Di\ContainerInterface;
|
||||||
use Aviat\Ion\Json;
|
use Aviat\Ion\Json;
|
||||||
use Aviat\Ion\StringWrapper;
|
use Aviat\Ion\StringWrapper;
|
||||||
@ -204,7 +204,7 @@ final class Anime extends BaseController {
|
|||||||
// large form-based updates
|
// large form-based updates
|
||||||
$transformer = new AnimeListTransformer();
|
$transformer = new AnimeListTransformer();
|
||||||
$postData = $transformer->untransform($data);
|
$postData = $transformer->untransform($data);
|
||||||
$fullResult = $this->model->updateLibraryItem(new AnimeFormItem($postData));
|
$fullResult = $this->model->updateLibraryItem(new FormItem($postData));
|
||||||
|
|
||||||
if ($fullResult['statusCode'] === 200)
|
if ($fullResult['statusCode'] === 200)
|
||||||
{
|
{
|
||||||
@ -235,7 +235,7 @@ final class Anime extends BaseController {
|
|||||||
$data = $this->request->getParsedBody();
|
$data = $this->request->getParsedBody();
|
||||||
}
|
}
|
||||||
|
|
||||||
$response = $this->model->incrementLibraryItem(new AnimeFormItem($data));
|
$response = $this->model->incrementLibraryItem(new FormItem($data));
|
||||||
|
|
||||||
$this->cache->clear();
|
$this->cache->clear();
|
||||||
$this->outputJSON($response['body'], $response['statusCode']);
|
$this->outputJSON($response['body'], $response['statusCode']);
|
||||||
|
@ -175,6 +175,16 @@ final class Index extends BaseController {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function settings_post()
|
||||||
|
{
|
||||||
|
$auth = $this->container->get('auth');
|
||||||
|
$this->outputHTML('settings', [
|
||||||
|
'auth' => $auth,
|
||||||
|
'config' => $this->config,
|
||||||
|
'title' => $this->config->get('whose_list') . "'s Settings",
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get image covers from kitsu
|
* Get image covers from kitsu
|
||||||
*
|
*
|
||||||
|
@ -20,7 +20,7 @@ use Aviat\AnimeClient\Controller;
|
|||||||
use Aviat\AnimeClient\API\Kitsu\Transformer\MangaListTransformer;
|
use Aviat\AnimeClient\API\Kitsu\Transformer\MangaListTransformer;
|
||||||
use Aviat\AnimeClient\API\Mapping\MangaReadingStatus;
|
use Aviat\AnimeClient\API\Mapping\MangaReadingStatus;
|
||||||
use Aviat\AnimeClient\Model\Manga as MangaModel;
|
use Aviat\AnimeClient\Model\Manga as MangaModel;
|
||||||
use Aviat\AnimeClient\Types\MangaFormItem;
|
use Aviat\AnimeClient\Types\FormItem;
|
||||||
use Aviat\Ion\Di\ContainerInterface;
|
use Aviat\Ion\Di\ContainerInterface;
|
||||||
use Aviat\Ion\{Json, StringWrapper};
|
use Aviat\Ion\{Json, StringWrapper};
|
||||||
|
|
||||||
@ -207,7 +207,7 @@ final class Manga extends Controller {
|
|||||||
// large form-based updates
|
// large form-based updates
|
||||||
$transformer = new MangaListTransformer();
|
$transformer = new MangaListTransformer();
|
||||||
$post_data = $transformer->untransform($data);
|
$post_data = $transformer->untransform($data);
|
||||||
$full_result = $this->model->updateLibraryItem(new MangaFormItem($post_data));
|
$full_result = $this->model->updateLibraryItem(new FormItem($post_data));
|
||||||
|
|
||||||
if ($full_result['statusCode'] === 200)
|
if ($full_result['statusCode'] === 200)
|
||||||
{
|
{
|
||||||
@ -237,7 +237,7 @@ final class Manga extends Controller {
|
|||||||
$data = $this->request->getParsedBody();
|
$data = $this->request->getParsedBody();
|
||||||
}
|
}
|
||||||
|
|
||||||
$response = $this->model->incrementLibraryItem(new MangaFormItem($data));
|
$response = $this->model->incrementLibraryItem(new FormItem($data));
|
||||||
|
|
||||||
$this->cache->clear();
|
$this->cache->clear();
|
||||||
$this->outputJSON($response['body'], $response['statusCode']);
|
$this->outputJSON($response['body'], $response['statusCode']);
|
||||||
|
@ -20,7 +20,7 @@ use Aviat\AnimeClient\API\ParallelAPIRequest;
|
|||||||
use Aviat\AnimeClient\API\Mapping\AnimeWatchingStatus;
|
use Aviat\AnimeClient\API\Mapping\AnimeWatchingStatus;
|
||||||
use Aviat\AnimeClient\Types\{
|
use Aviat\AnimeClient\Types\{
|
||||||
Anime as AnimeType,
|
Anime as AnimeType,
|
||||||
AnimeFormItem,
|
FormItem,
|
||||||
AnimeListItem
|
AnimeListItem
|
||||||
};
|
};
|
||||||
use Aviat\Ion\Di\ContainerInterface;
|
use Aviat\Ion\Di\ContainerInterface;
|
||||||
@ -187,10 +187,10 @@ class Anime extends API {
|
|||||||
/**
|
/**
|
||||||
* Increment progress for the specified anime
|
* Increment progress for the specified anime
|
||||||
*
|
*
|
||||||
* @param AnimeFormItem $data
|
* @param FormItem $data
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function incrementLibraryItem(AnimeFormItem $data): array
|
public function incrementLibraryItem(FormItem $data): array
|
||||||
{
|
{
|
||||||
$requester = new ParallelAPIRequest();
|
$requester = new ParallelAPIRequest();
|
||||||
$requester->addRequest($this->kitsuModel->incrementListItem($data), 'kitsu');
|
$requester->addRequest($this->kitsuModel->incrementListItem($data), 'kitsu');
|
||||||
@ -216,10 +216,10 @@ class Anime extends API {
|
|||||||
/**
|
/**
|
||||||
* Update a list entry
|
* Update a list entry
|
||||||
*
|
*
|
||||||
* @param AnimeFormItem $data
|
* @param FormItem $data
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function updateLibraryItem(AnimeFormItem $data): array
|
public function updateLibraryItem(FormItem $data): array
|
||||||
{
|
{
|
||||||
$requester = new ParallelAPIRequest();
|
$requester = new ParallelAPIRequest();
|
||||||
$requester->addRequest($this->kitsuModel->updateListItem($data), 'kitsu');
|
$requester->addRequest($this->kitsuModel->updateListItem($data), 'kitsu');
|
||||||
|
@ -22,7 +22,7 @@ use Aviat\AnimeClient\API\{
|
|||||||
ParallelAPIRequest
|
ParallelAPIRequest
|
||||||
};
|
};
|
||||||
use Aviat\AnimeClient\Types\{
|
use Aviat\AnimeClient\Types\{
|
||||||
MangaFormItem,
|
FormItem,
|
||||||
MangaListItem,
|
MangaListItem,
|
||||||
MangaPage
|
MangaPage
|
||||||
};
|
};
|
||||||
@ -149,10 +149,10 @@ class Manga extends API {
|
|||||||
/**
|
/**
|
||||||
* Update a list entry
|
* Update a list entry
|
||||||
*
|
*
|
||||||
* @param MangaFormItem $data
|
* @param FormItem $data
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function updateLibraryItem(MangaFormItem $data): array
|
public function updateLibraryItem(FormItem $data): array
|
||||||
{
|
{
|
||||||
$requester = new ParallelAPIRequest();
|
$requester = new ParallelAPIRequest();
|
||||||
$requester->addRequest($this->kitsuModel->updateListItem($data), 'kitsu');
|
$requester->addRequest($this->kitsuModel->updateListItem($data), 'kitsu');
|
||||||
@ -177,10 +177,10 @@ class Manga extends API {
|
|||||||
/**
|
/**
|
||||||
* Increase the progress of a list entry
|
* Increase the progress of a list entry
|
||||||
*
|
*
|
||||||
* @param MangaFormItem $data
|
* @param FormItem $data
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function incrementLibraryItem(MangaFormItem $data): array
|
public function incrementLibraryItem(FormItem $data): array
|
||||||
{
|
{
|
||||||
$requester = new ParallelAPIRequest();
|
$requester = new ParallelAPIRequest();
|
||||||
$requester->addRequest($this->kitsuModel->incrementListItem($data), 'kitsu');
|
$requester->addRequest($this->kitsuModel->incrementListItem($data), 'kitsu');
|
||||||
|
@ -26,7 +26,7 @@ abstract class AbstractType implements ArrayAccess {
|
|||||||
* @param $properties
|
* @param $properties
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public static function __set_state($properties)
|
public static function __set_state($properties): self
|
||||||
{
|
{
|
||||||
return new static($properties);
|
return new static($properties);
|
||||||
}
|
}
|
||||||
@ -165,7 +165,7 @@ abstract class AbstractType implements ArrayAccess {
|
|||||||
{
|
{
|
||||||
$object = $parent ?? $this;
|
$object = $parent ?? $this;
|
||||||
|
|
||||||
if (is_scalar($object))
|
if (is_scalar($object) || empty($object))
|
||||||
{
|
{
|
||||||
return $object;
|
return $object;
|
||||||
}
|
}
|
||||||
@ -174,7 +174,7 @@ abstract class AbstractType implements ArrayAccess {
|
|||||||
|
|
||||||
foreach ($object as $key => $value)
|
foreach ($object as $key => $value)
|
||||||
{
|
{
|
||||||
$output[$key] = is_scalar($value)
|
$output[$key] = (is_scalar($value) || empty($value))
|
||||||
? $value
|
? $value
|
||||||
: $this->toArray((array) $value);
|
: $this->toArray((array) $value);
|
||||||
}
|
}
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
<?php declare(strict_types=1);
|
|
||||||
/**
|
|
||||||
* Hummingbird Anime List Client
|
|
||||||
*
|
|
||||||
* An API client for Kitsu 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\Types;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Type representing an Anime object for display
|
|
||||||
*/
|
|
||||||
final class AnimeFormItem extends FormItem {
|
|
||||||
public function setData($value): void
|
|
||||||
{
|
|
||||||
$this->data = new AnimeFormItemData($value);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
<?php declare(strict_types=1);
|
|
||||||
/**
|
|
||||||
* Hummingbird Anime List Client
|
|
||||||
*
|
|
||||||
* An API client for Kitsu 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\Types;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Type representing an Anime object for display
|
|
||||||
*/
|
|
||||||
final class AnimeFormItemData extends FormItemData {}
|
|
@ -19,12 +19,15 @@ namespace Aviat\AnimeClient\Types;
|
|||||||
/**
|
/**
|
||||||
* Type representing an Anime object for display
|
* Type representing an Anime object for display
|
||||||
*/
|
*/
|
||||||
abstract class FormItem extends AbstractType {
|
class FormItem extends AbstractType {
|
||||||
public $id;
|
public $id;
|
||||||
public $anilist_item_id;
|
public $anilist_item_id;
|
||||||
public $mal_id;
|
public $mal_id;
|
||||||
public $data;
|
public $data;
|
||||||
|
|
||||||
abstract public function setData($value): void;
|
public function setData($value): void
|
||||||
|
{
|
||||||
|
$this->data = new FormItemData($value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,9 +17,9 @@
|
|||||||
namespace Aviat\AnimeClient\Types;
|
namespace Aviat\AnimeClient\Types;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Type representing an Anime object for display
|
* Type representing a Media object for editing/syncing
|
||||||
*/
|
*/
|
||||||
abstract class FormItemData extends AbstractType {
|
class FormItemData extends AbstractType {
|
||||||
public $notes;
|
public $notes;
|
||||||
public $private;
|
public $private;
|
||||||
public $progress;
|
public $progress;
|
||||||
@ -28,4 +28,5 @@ abstract class FormItemData extends AbstractType {
|
|||||||
public $reconsumeCount;
|
public $reconsumeCount;
|
||||||
public $reconsuming;
|
public $reconsuming;
|
||||||
public $status;
|
public $status;
|
||||||
|
public $updatedAt;
|
||||||
}
|
}
|
||||||
|
@ -1,28 +0,0 @@
|
|||||||
<?php declare(strict_types=1);
|
|
||||||
/**
|
|
||||||
* Hummingbird Anime List Client
|
|
||||||
*
|
|
||||||
* An API client for Kitsu 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\Types;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Form data for updating a Manga List item
|
|
||||||
*/
|
|
||||||
final class MangaFormItem extends FormItem {
|
|
||||||
public function setData($value): void
|
|
||||||
{
|
|
||||||
$this->data = new MangaFormItemData($value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
|||||||
<?php declare(strict_types=1);
|
|
||||||
/**
|
|
||||||
* Hummingbird Anime List Client
|
|
||||||
*
|
|
||||||
* An API client for Kitsu 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\Types;
|
|
||||||
|
|
||||||
final class MangaFormItemData extends FormItemData {}
|
|
Loading…
Reference in New Issue
Block a user