Version 5.1 - All the GraphQL #32
@ -25,9 +25,9 @@
|
|||||||
<td><label for="status">Reading Status</label></td>
|
<td><label for="status">Reading Status</label></td>
|
||||||
<td>
|
<td>
|
||||||
<select name="status" id="status">
|
<select name="status" id="status">
|
||||||
<?php foreach($status_list as $status): ?>
|
<?php foreach($status_list as $val => $status): ?>
|
||||||
<option <?php if($item['reading_status'] === $status): ?>selected="selected"<?php endif ?>
|
<option <?php if($item['reading_status'] === $val): ?>selected="selected"<?php endif ?>
|
||||||
value="<?= $status ?>"><?= $status ?></option>
|
value="<?= $val ?>"><?= $status ?></option>
|
||||||
<?php endforeach ?>
|
<?php endforeach ?>
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
|
@ -1174,8 +1174,8 @@ a:hover, a:active {
|
|||||||
position:absolute;
|
position:absolute;
|
||||||
top: 86px;
|
top: 86px;
|
||||||
top: calc(50% - 58.5px);
|
top: calc(50% - 58.5px);
|
||||||
left: 5px;
|
left: 43.5px;
|
||||||
left: calc(50% - 95px);
|
left: calc(50% - 66.5px);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
@ -1222,11 +1222,16 @@ a:hover, a:active {
|
|||||||
position:absolute;
|
position:absolute;
|
||||||
display:block;
|
display:block;
|
||||||
top:0;
|
top:0;
|
||||||
|
left:0;
|
||||||
height:100%;
|
height:100%;
|
||||||
width:100%;
|
width:100%;
|
||||||
vertical-align:middle;
|
vertical-align:middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#series_list .name small {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
Details page styles
|
Details page styles
|
||||||
-----------------------------------------------------------------------------*/
|
-----------------------------------------------------------------------------*/
|
||||||
|
@ -439,8 +439,8 @@ a:hover, a:active {
|
|||||||
position:absolute;
|
position:absolute;
|
||||||
top: 86px;
|
top: 86px;
|
||||||
top: calc(50% - 58.5px);
|
top: calc(50% - 58.5px);
|
||||||
left: 5px;
|
left: 43.5px;
|
||||||
left: calc(50% - 95px);
|
left: calc(50% - 66.5px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -484,10 +484,14 @@ a:hover, a:active {
|
|||||||
position:absolute;
|
position:absolute;
|
||||||
display:block;
|
display:block;
|
||||||
top:0;
|
top:0;
|
||||||
|
left:0;
|
||||||
height:100%;
|
height:100%;
|
||||||
width:100%;
|
width:100%;
|
||||||
vertical-align:middle;
|
vertical-align:middle;
|
||||||
}
|
}
|
||||||
|
#series_list .name small {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
Details page styles
|
Details page styles
|
||||||
|
8
public/js/manga_edit.js
Executable file → Normal file
8
public/js/manga_edit.js
Executable file → Normal file
@ -18,12 +18,16 @@
|
|||||||
completed = 0;
|
completed = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Setup the update data
|
||||||
let data = {
|
let data = {
|
||||||
id: manga_id
|
id: manga_id,
|
||||||
|
data: {
|
||||||
|
progress: completed
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Update the total count
|
// Update the total count
|
||||||
data[type + "s_read"] = ++completed;
|
data['data']['progress'] = ++completed;
|
||||||
|
|
||||||
_.ajax(_.url('/manga/update'), {
|
_.ajax(_.url('/manga/update'), {
|
||||||
data: data,
|
data: data,
|
||||||
|
@ -4,10 +4,13 @@
|
|||||||
<input type="radio" class="big-check" id="{{attributes.slug}}" name="id" value="{{id}}" />
|
<input type="radio" class="big-check" id="{{attributes.slug}}" name="id" value="{{id}}" />
|
||||||
<label for="{{attributes.slug}}">
|
<label for="{{attributes.slug}}">
|
||||||
<span class="name">
|
<span class="name">
|
||||||
{{attributes.canonicalTitle}}<br />
|
{{attributes.canonicalTitle}}
|
||||||
{{attributes.titles.en}}<br />
|
<br />
|
||||||
{{attributes.titles.en_jp}}<br />
|
<small>
|
||||||
{{attributes.titles.ja_jp}}
|
{{#attributes.titles}}
|
||||||
|
{{.}}<br />
|
||||||
|
{{/attributes.titles}}
|
||||||
|
</small>
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,10 +1,18 @@
|
|||||||
{{#search}}
|
{{#data}}
|
||||||
<article class="media search">
|
<article class="media search">
|
||||||
<div class="name" style="background-image:url({{image}})">
|
<div class="name" style="background-image:url({{attributes.posterImage.small}})">
|
||||||
<input type="radio" class="big-check" id="{{link}}" name="id" value="{{link}}" />
|
<input type="radio" class="big-check" id="{{attributes.slug}}" name="id" value="{{id}}" />
|
||||||
<label for="{{link}}">
|
<label for="{{attributes.slug}}">
|
||||||
<span>{{title}}</span>
|
<span class="name">
|
||||||
|
{{attributes.canonicalTitle}}
|
||||||
|
<br />
|
||||||
|
<small>
|
||||||
|
{{#attributes.titles}}
|
||||||
|
{{.}}<br />
|
||||||
|
{{/attributes.titles}}
|
||||||
|
</small>
|
||||||
|
</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
{{/search}}
|
{{/data}}
|
@ -16,7 +16,11 @@
|
|||||||
|
|
||||||
namespace Aviat\AnimeClient\API;
|
namespace Aviat\AnimeClient\API;
|
||||||
|
|
||||||
use Aviat\AnimeClient\API\Kitsu\Enum\{AnimeAiringStatus, AnimeWatchingStatus};
|
use Aviat\AnimeClient\API\Kitsu\Enum\{
|
||||||
|
AnimeAiringStatus,
|
||||||
|
AnimeWatchingStatus,
|
||||||
|
MangaReadingStatus
|
||||||
|
};
|
||||||
use DateTimeImmutable;
|
use DateTimeImmutable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -41,6 +45,17 @@ class Kitsu {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function getStatusToMangaSelectMap()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
MangaReadingStatus::READING => 'Currently Reading',
|
||||||
|
MangaReadingStatus::PLAN_TO_READ => 'Plan to Read',
|
||||||
|
MangaReadingStatus::COMPLETED => 'Completed',
|
||||||
|
MangaReadingStatus::ON_HOLD => 'On Hold',
|
||||||
|
MangaReadingStatus::DROPPED => 'Dropped'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine whether an anime is airing, finished airing, or has not yet aired
|
* Determine whether an anime is airing, finished airing, or has not yet aired
|
||||||
*
|
*
|
||||||
|
@ -22,10 +22,10 @@ use Aviat\Ion\Enum as BaseEnum;
|
|||||||
* Possible values for current reading status of manga
|
* Possible values for current reading status of manga
|
||||||
*/
|
*/
|
||||||
class MangaReadingStatus extends BaseEnum {
|
class MangaReadingStatus extends BaseEnum {
|
||||||
const READING = 1;
|
const READING = 'current';
|
||||||
const PLAN_TO_READ = 2;
|
const PLAN_TO_READ = 'planned';
|
||||||
const DROPPED = 5;
|
const DROPPED = 'dropped';
|
||||||
const ON_HOLD = 4;
|
const ON_HOLD = 'on_hold';
|
||||||
const COMPLETED = 3;
|
const COMPLETED = 'completed';
|
||||||
}
|
}
|
||||||
// End of MangaReadingStatus.php
|
// End of MangaReadingStatus.php
|
@ -24,6 +24,7 @@ use Aviat\AnimeClient\API\Kitsu\Transformer\{
|
|||||||
use Aviat\Ion\Di\ContainerAware;
|
use Aviat\Ion\Di\ContainerAware;
|
||||||
use Aviat\Ion\Json;
|
use Aviat\Ion\Json;
|
||||||
use GuzzleHttp\Exception\ClientException;
|
use GuzzleHttp\Exception\ClientException;
|
||||||
|
use PHP_CodeSniffer\Tokenizers\JS;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Kitsu API Model
|
* Kitsu API Model
|
||||||
@ -32,9 +33,6 @@ class KitsuModel {
|
|||||||
use ContainerAware;
|
use ContainerAware;
|
||||||
use KitsuTrait;
|
use KitsuTrait;
|
||||||
|
|
||||||
const CLIENT_ID = 'dd031b32d2f56c990b1425efe6c42ad847e7fe3ab46bf1299f05ecd856bdb7dd';
|
|
||||||
const CLIENT_SECRET = '54d7307928f63414defd96399fc31ba847961ceaecef3a5fd93144e960c0e151';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class to map anime list items
|
* Class to map anime list items
|
||||||
* to a common format used by
|
* to a common format used by
|
||||||
@ -101,7 +99,8 @@ class KitsuModel {
|
|||||||
*/
|
*/
|
||||||
public function authenticate(string $username, string $password)
|
public function authenticate(string $username, string $password)
|
||||||
{
|
{
|
||||||
$data = $this->postRequest(K::AUTH_URL, [
|
$response = $this->getResponse('POST', K::AUTH_URL, [
|
||||||
|
'headers' => [],
|
||||||
'form_params' => [
|
'form_params' => [
|
||||||
'grant_type' => 'password',
|
'grant_type' => 'password',
|
||||||
'username' => $username,
|
'username' => $username,
|
||||||
@ -109,6 +108,8 @@ class KitsuModel {
|
|||||||
]
|
]
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$data = Json::decode((string)$response->getBody());
|
||||||
|
|
||||||
if (array_key_exists('access_token', $data))
|
if (array_key_exists('access_token', $data))
|
||||||
{
|
{
|
||||||
return $data['access_token'];
|
return $data['access_token'];
|
||||||
@ -161,7 +162,6 @@ class KitsuModel {
|
|||||||
|
|
||||||
$data = $this->getRequest('library-entries', $options);
|
$data = $this->getRequest('library-entries', $options);
|
||||||
$included = K::organizeIncludes($data['included']);
|
$included = K::organizeIncludes($data['included']);
|
||||||
/*?><pre><?= print_r($included, TRUE) ?></pre><?php*/
|
|
||||||
|
|
||||||
foreach($data['data'] as $i => &$item)
|
foreach($data['data'] as $i => &$item)
|
||||||
{
|
{
|
||||||
@ -173,8 +173,6 @@ class KitsuModel {
|
|||||||
{
|
{
|
||||||
$item['genres'][] = $included['genres'][$id]['name'];
|
$item['genres'][] = $included['genres'][$id]['name'];
|
||||||
}
|
}
|
||||||
|
|
||||||
// $item['genres'] = array_pluck($genres, 'name');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$transformed = $this->animeListTransformer->transformCollection($data['data']);
|
$transformed = $this->animeListTransformer->transformCollection($data['data']);
|
||||||
@ -223,7 +221,15 @@ class KitsuModel {
|
|||||||
'include' => 'media'
|
'include' => 'media'
|
||||||
];
|
];
|
||||||
|
|
||||||
return $this->getRequest($type, $options);
|
$raw = $this->getRequest($type, $options);
|
||||||
|
|
||||||
|
foreach ($raw['data'] as &$item)
|
||||||
|
{
|
||||||
|
$item['attributes']['titles'] = K::filterTitles($item['attributes']);
|
||||||
|
array_shift($item['attributes']['titles']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $raw;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getListItem(string $listId): array
|
public function getListItem(string $listId): array
|
||||||
@ -264,6 +270,11 @@ class KitsuModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function deleteListItem(string $id): bool
|
||||||
|
{
|
||||||
|
return $this->listItem->delete($id);
|
||||||
|
}
|
||||||
|
|
||||||
private function getUsername(): string
|
private function getUsername(): string
|
||||||
{
|
{
|
||||||
return $this->getContainer()
|
return $this->getContainer()
|
||||||
|
@ -18,12 +18,12 @@ namespace Aviat\AnimeClient\API\Kitsu;
|
|||||||
|
|
||||||
use Aviat\AnimeClient\AnimeClient;
|
use Aviat\AnimeClient\AnimeClient;
|
||||||
use Aviat\AnimeClient\API\GuzzleTrait;
|
use Aviat\AnimeClient\API\GuzzleTrait;
|
||||||
|
use Aviat\AnimeClient\API\Kitsu as K;
|
||||||
use Aviat\Ion\Json;
|
use Aviat\Ion\Json;
|
||||||
use GuzzleHttp\Client;
|
use GuzzleHttp\Client;
|
||||||
use GuzzleHttp\Cookie\CookieJar;
|
use GuzzleHttp\Cookie\CookieJar;
|
||||||
use GuzzleHttp\Psr7\Response;
|
use GuzzleHttp\Psr7\Response;
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
use PHP_CodeSniffer\Tokenizers\JS;
|
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
|
|
||||||
trait KitsuTrait {
|
trait KitsuTrait {
|
||||||
@ -43,7 +43,7 @@ trait KitsuTrait {
|
|||||||
protected $defaultHeaders = [
|
protected $defaultHeaders = [
|
||||||
'User-Agent' => "Tim's Anime Client/4.0",
|
'User-Agent' => "Tim's Anime Client/4.0",
|
||||||
'Accept-Encoding' => 'application/vnd.api+json',
|
'Accept-Encoding' => 'application/vnd.api+json',
|
||||||
'Content-Type' => 'application/vnd.api+json; charset=utf-8',
|
'Content-Type' => 'application/vnd.api+json',
|
||||||
'client_id' => 'dd031b32d2f56c990b1425efe6c42ad847e7fe3ab46bf1299f05ecd856bdb7dd',
|
'client_id' => 'dd031b32d2f56c990b1425efe6c42ad847e7fe3ab46bf1299f05ecd856bdb7dd',
|
||||||
'client_secret' => '54d7307928f63414defd96399fc31ba847961ceaecef3a5fd93144e960c0e151',
|
'client_secret' => '54d7307928f63414defd96399fc31ba847961ceaecef3a5fd93144e960c0e151',
|
||||||
];
|
];
|
||||||
@ -93,23 +93,22 @@ trait KitsuTrait {
|
|||||||
'headers' => $this->defaultHeaders
|
'headers' => $this->defaultHeaders
|
||||||
];
|
];
|
||||||
|
|
||||||
if ($this->getContainer());
|
$logger = $this->container->getLogger('request');
|
||||||
{
|
$sessionSegment = $this->getContainer()
|
||||||
$logger = $this->container->getLogger('request');
|
->get('session')
|
||||||
$sessionSegment = $this->getContainer()
|
->getSegment(AnimeClient::SESSION_SEGMENT);
|
||||||
->get('session')
|
|
||||||
->getSegment(AnimeClient::SESSION_SEGMENT);
|
|
||||||
|
|
||||||
if ($sessionSegment->get('auth_token') !== null)
|
if ($sessionSegment->get('auth_token') !== null && $url !== K::AUTH_URL)
|
||||||
{
|
{
|
||||||
$token = $sessionSegment->get('auth_token');
|
$token = $sessionSegment->get('auth_token');
|
||||||
$defaultOptions['headers']['Authorization'] = "bearer {$token}";
|
$defaultOptions['headers']['Authorization'] = "bearer {$token}";
|
||||||
}
|
|
||||||
$logger->debug(Json::encode(func_get_args()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$options = array_merge($defaultOptions, $options);
|
$options = array_merge($defaultOptions, $options);
|
||||||
|
|
||||||
|
$logger->debug(Json::encode([$type, $url]));
|
||||||
|
$logger->debug(Json::encode($options));
|
||||||
|
|
||||||
return $this->client->request($type, $url, $options);
|
return $this->client->request($type, $url, $options);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,7 +130,7 @@ trait KitsuTrait {
|
|||||||
|
|
||||||
$response = $this->getResponse($type, $url, $options);
|
$response = $this->getResponse($type, $url, $options);
|
||||||
|
|
||||||
if ((int) $response->getStatusCode() !== 200)
|
if ((int) $response->getStatusCode() > 299 || (int) $response->getStatusCode() < 200)
|
||||||
{
|
{
|
||||||
if ($logger)
|
if ($logger)
|
||||||
{
|
{
|
||||||
@ -192,7 +191,7 @@ trait KitsuTrait {
|
|||||||
$logger->warning($response->getBody());
|
$logger->warning($response->getBody());
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new RuntimeException($response->getBody());
|
// throw new RuntimeException($response->getBody());
|
||||||
}
|
}
|
||||||
|
|
||||||
return JSON::decode($response->getBody(), TRUE);
|
return JSON::decode($response->getBody(), TRUE);
|
||||||
|
@ -37,14 +37,33 @@ class ListItem extends AbstractListItem {
|
|||||||
|
|
||||||
public function create(array $data): bool
|
public function create(array $data): bool
|
||||||
{
|
{
|
||||||
// TODO: Implement create() method.
|
$response = $this->getResponse('post', 'library-entries', [
|
||||||
return false;
|
'body' => [
|
||||||
|
'type' => 'libraryEntries',
|
||||||
|
'attributes' => [
|
||||||
|
'status' => $data['status'],
|
||||||
|
'progress' => $data['progress'] ?? 0
|
||||||
|
],
|
||||||
|
'relationships' => [
|
||||||
|
'user' => [
|
||||||
|
'id' => $data['user_id'],
|
||||||
|
'type' => 'users'
|
||||||
|
],
|
||||||
|
'media' => [
|
||||||
|
'id' => $data['id'],
|
||||||
|
'type' => $data['type']
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
return ($response->getStatusCode() === 201);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function delete(string $id): bool
|
public function delete(string $id): bool
|
||||||
{
|
{
|
||||||
// TODO: Implement delete() method.
|
$response = $this->getResponse('DELETE', "library-entries/{$id}");
|
||||||
return false;
|
return ($response->getStatusCode() === 204);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function get(string $id): array
|
public function get(string $id): array
|
||||||
|
@ -91,18 +91,18 @@ class MangaListTransformer extends AbstractTransformer {
|
|||||||
|
|
||||||
$map = [
|
$map = [
|
||||||
'id' => $item['id'],
|
'id' => $item['id'],
|
||||||
'manga_id' => $item['manga_id'],
|
'data' => [
|
||||||
'status' => $item['status'],
|
'status' => $item['status'],
|
||||||
'chapters_read' => (int)$item['chapters_read'],
|
'progress' => (int)$item['chapters_read'],
|
||||||
'volumes_read' => (int)$item['volumes_read'],
|
'reconsuming' => $rereading,
|
||||||
'rereading' => $rereading,
|
'reconsumeCount' => (int)$item['reread_count'],
|
||||||
'reread_count' => (int)$item['reread_count'],
|
'notes' => $item['notes'],
|
||||||
'notes' => $item['notes'],
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
if ($item['new_rating'] !== $item['old_rating'] && $item['new_rating'] !== "")
|
if ($item['new_rating'] !== $item['old_rating'] && $item['new_rating'] !== "")
|
||||||
{
|
{
|
||||||
$map['rating'] = ($item['new_rating'] > 0)
|
$map['data']['rating'] = ($item['new_rating'] > 0)
|
||||||
? $item['new_rating'] / 2
|
? $item['new_rating'] / 2
|
||||||
: $item['old_rating'] / 2;
|
: $item['old_rating'] / 2;
|
||||||
}
|
}
|
||||||
|
@ -260,8 +260,6 @@ class Anime extends BaseController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$response = $this->model->updateLibraryItem($data);
|
$response = $this->model->updateLibraryItem($data);
|
||||||
//echo JSON::encode($response);
|
|
||||||
//die();
|
|
||||||
|
|
||||||
// $this->cache->purge();
|
// $this->cache->purge();
|
||||||
$this->outputJSON($response['body'], $response['statusCode']);
|
$this->outputJSON($response['body'], $response['statusCode']);
|
||||||
@ -274,12 +272,13 @@ class Anime extends BaseController {
|
|||||||
*/
|
*/
|
||||||
public function delete()
|
public function delete()
|
||||||
{
|
{
|
||||||
$response = $this->model->delete($this->request->getParsedBody());
|
$body = $this->request->getParsedBody();
|
||||||
|
$response = $this->model->deleteLibraryItem($body['id']);
|
||||||
|
|
||||||
if ((bool)$response['body'] === TRUE)
|
if ((bool)$response === TRUE)
|
||||||
{
|
{
|
||||||
$this->set_flash_message("Successfully deleted anime.", 'success');
|
$this->set_flash_message("Successfully deleted anime.", 'success');
|
||||||
$this->cache->purge();
|
// $this->cache->purge();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
namespace Aviat\AnimeClient\Controller;
|
namespace Aviat\AnimeClient\Controller;
|
||||||
|
|
||||||
use Aviat\AnimeClient\Controller;
|
use Aviat\AnimeClient\Controller;
|
||||||
|
use Aviat\AnimeClient\API\Kitsu;
|
||||||
use Aviat\AnimeClient\API\Kitsu\Enum\MangaReadingStatus;
|
use Aviat\AnimeClient\API\Kitsu\Enum\MangaReadingStatus;
|
||||||
use Aviat\AnimeClient\API\Kitsu\Transformer\MangaListTransformer;
|
use Aviat\AnimeClient\API\Kitsu\Transformer\MangaListTransformer;
|
||||||
use Aviat\AnimeClient\Model\Manga as MangaModel;
|
use Aviat\AnimeClient\Model\Manga as MangaModel;
|
||||||
@ -166,7 +167,7 @@ class Manga extends Controller {
|
|||||||
|
|
||||||
$this->outputHTML('manga/edit', [
|
$this->outputHTML('manga/edit', [
|
||||||
'title' => $title,
|
'title' => $title,
|
||||||
'status_list' => MangaReadingStatus::getConstList(),
|
'status_list' => Kitsu::getStatusToMangaSelectMap(),
|
||||||
'item' => $item,
|
'item' => $item,
|
||||||
'action' => $this->container->get('url-generator')
|
'action' => $this->container->get('url-generator')
|
||||||
->url('/manga/update_form'),
|
->url('/manga/update_form'),
|
||||||
@ -185,50 +186,54 @@ class Manga extends Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update an anime item via a form submission
|
* Update an manga item via a form submission
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function form_update()
|
public function form_update()
|
||||||
{
|
{
|
||||||
$post_data = $this->request->getParsedBody();
|
$data = $this->request->getParsedBody();
|
||||||
|
|
||||||
// Do some minor data manipulation for
|
// Do some minor data manipulation for
|
||||||
// large form-based updates
|
// large form-based updates
|
||||||
$transformer = new MangaListTransformer();
|
$transformer = new MangaListTransformer();
|
||||||
$post_data = $transformer->untransform($post_data);
|
$post_data = $transformer->untransform($data);
|
||||||
$full_result = $this->model->update($post_data);
|
$full_result = $this->model->updateLibraryItem($post_data);
|
||||||
|
|
||||||
$result = Json::decode((string)$full_result['body']);
|
if ($full_result['statusCode'] === 200)
|
||||||
|
|
||||||
if ((int)$full_result['statusCode'] === 200)
|
|
||||||
{
|
{
|
||||||
$m =& $result['manga'][0];
|
$this->set_flash_message("Successfully updated manga.", 'success');
|
||||||
$title = ( ! empty($m['english_title']))
|
// $this->cache->purge();
|
||||||
? "{$m['romaji_title']} ({$m['english_title']})"
|
|
||||||
: "{$m['romaji_title']}";
|
|
||||||
|
|
||||||
$this->set_flash_message("Successfully updated {$title}.", 'success');
|
|
||||||
$this->cache->purge();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$this->set_flash_message('Failed to update manga.', 'error');
|
$this->set_flash_message('Failed to update manga.', 'error');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->session_redirect();
|
$this->session_redirect();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update an anime item
|
* Update a manga item
|
||||||
*
|
*
|
||||||
* @return boolean|null
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function update()
|
public function update()
|
||||||
{
|
{
|
||||||
$result = $this->model->update($this->request->getParsedBody());
|
if ($this->request->getHeader('content-type')[0] === 'application/json')
|
||||||
$this->cache->purge();
|
{
|
||||||
$this->outputJSON($result['body'], $result['statusCode']);
|
$data = JSON::decode((string)$this->request->getBody());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$data = $this->request->getParsedBody();
|
||||||
|
}
|
||||||
|
|
||||||
|
$response = $this->model->updateLibraryItem($data);
|
||||||
|
|
||||||
|
// $this->cache->purge();
|
||||||
|
$this->outputJSON($response['body'], $response['statusCode']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,10 +38,10 @@ class API extends Model {
|
|||||||
*/
|
*/
|
||||||
protected $cache;
|
protected $cache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default settings for Guzzle
|
* Default settings for Guzzle
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $connectionDefaults = [];
|
protected $connectionDefaults = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -75,4 +75,4 @@ class API extends Model {
|
|||||||
array_multisort($sort, SORT_ASC, $array);
|
array_multisort($sort, SORT_ASC, $array);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// End of BaseApiModel.php
|
// End of BaseApiModel.php
|
||||||
|
@ -115,5 +115,10 @@ class Anime extends API {
|
|||||||
{
|
{
|
||||||
return $this->kitsuModel->updateListItem($data);
|
return $this->kitsuModel->updateListItem($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function deleteLibraryItem($id): bool
|
||||||
|
{
|
||||||
|
return $this->kitsuModel->deleteListItem($id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// End of AnimeModel.php
|
// End of AnimeModel.php
|
@ -18,6 +18,7 @@ namespace Aviat\AnimeClient\Model;
|
|||||||
|
|
||||||
use Aviat\Ion\Di\ContainerInterface;
|
use Aviat\Ion\Di\ContainerInterface;
|
||||||
use Aviat\Ion\Model\DB;
|
use Aviat\Ion\Model\DB;
|
||||||
|
use PDO;
|
||||||
use PDOException;
|
use PDOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -95,6 +95,28 @@ class Manga extends API
|
|||||||
return $this->kitsuModel->getListItem($itemId);
|
return $this->kitsuModel->getListItem($itemId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a list entry
|
||||||
|
*
|
||||||
|
* @param array $data
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function updateLibraryItem(array $data): array
|
||||||
|
{
|
||||||
|
return $this->kitsuModel->updateListItem($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search for anime by name
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function search($name)
|
||||||
|
{
|
||||||
|
return $this->kitsuModel->search('manga', $name);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map transformed anime data to be organized by reading status
|
* Map transformed anime data to be organized by reading status
|
||||||
*
|
*
|
||||||
|
94
src/Util.php
94
src/Util.php
@ -109,97 +109,5 @@ class Util {
|
|||||||
{
|
{
|
||||||
return ! $this->is_view_page();
|
return ! $this->is_view_page();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the path of the cached version of the image. Create the cached image
|
|
||||||
* if the file does not already exist
|
|
||||||
*
|
|
||||||
* @codeCoverageIgnore
|
|
||||||
* @param string $api_path - The original image url
|
|
||||||
* @param string $series_slug - The part of the url with the series name, becomes the image name
|
|
||||||
* @param string $type - Anime or Manga, controls cache path
|
|
||||||
* @return string - the frontend path for the cached image
|
|
||||||
* @throws \DomainException
|
|
||||||
*/
|
|
||||||
public function get_cached_image($api_path, $series_slug, $type = "anime")
|
|
||||||
{
|
|
||||||
$path_parts = explode('?', basename($api_path));
|
|
||||||
$path = current($path_parts);
|
|
||||||
$ext_parts = explode('.', $path);
|
|
||||||
$ext = end($ext_parts);
|
|
||||||
|
|
||||||
// Workaround for some broken file extensions
|
|
||||||
if ($ext === "jjpg")
|
|
||||||
{
|
|
||||||
$ext = "jpg";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Failsafe for weird urls
|
|
||||||
if (strlen($ext) > 3)
|
|
||||||
{
|
|
||||||
return $api_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
$img_cache_path = $this->config->get('img_cache_path');
|
|
||||||
$cached_image = "{$series_slug}.{$ext}";
|
|
||||||
$cached_path = "{$img_cache_path}/{$type}/{$cached_image}";
|
|
||||||
|
|
||||||
// Cache the file if it doesn't already exist
|
|
||||||
if ( ! file_exists($cached_path))
|
|
||||||
{
|
|
||||||
if (function_exists('curl_init'))
|
|
||||||
{
|
|
||||||
$ch = curl_init($api_path);
|
|
||||||
$fp = fopen($cached_path, 'wb');
|
|
||||||
curl_setopt_array($ch, [
|
|
||||||
CURLOPT_FILE => $fp,
|
|
||||||
CURLOPT_HEADER => 0
|
|
||||||
]);
|
|
||||||
curl_exec($ch);
|
|
||||||
curl_close($ch);
|
|
||||||
fclose($fp);
|
|
||||||
}
|
|
||||||
else if (ini_get('allow_url_fopen'))
|
|
||||||
{
|
|
||||||
copy($api_path, $cached_path);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new DomainException("Couldn't cache images because they couldn't be downloaded.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resize the image
|
|
||||||
if ($type === 'anime')
|
|
||||||
{
|
|
||||||
$resize_width = 220;
|
|
||||||
$resize_height = 319;
|
|
||||||
$this->_resize($cached_path, $resize_width, $resize_height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return "/public/images/{$type}/{$cached_image}";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resize an image
|
|
||||||
*
|
|
||||||
* @codeCoverageIgnore
|
|
||||||
* @param string $path
|
|
||||||
* @param string $width
|
|
||||||
* @param string $height
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
private function _resize($path, $width, $height)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
$img = new SimpleImage($path);
|
|
||||||
$img->resize($width, $height)->save();
|
|
||||||
}
|
|
||||||
catch (Exception $e)
|
|
||||||
{
|
|
||||||
// Catch image errors, since they don't otherwise affect
|
|
||||||
// functionality
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user