Version 5.1 - All the GraphQL #32

Closed
timw4mail wants to merge 1160 commits from develop into master
7 changed files with 252 additions and 97 deletions
Showing only changes of commit fa27abb954 - Show all commits

View File

@ -183,10 +183,13 @@ return [
] ]
], ],
'user_info' => [ 'user_info' => [
'path' => '/me', 'path' => '/about/{user}',
'action' => 'me', 'action' => 'about',
'controller' => 'me', 'controller' => DEFAULT_CONTROLLER,
'verb' => 'get', 'verb' => 'get',
'tokens' => [
'user' => '.*?'
]
], ],
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
// Default / Shared routes // Default / Shared routes

View File

@ -88,6 +88,12 @@
</article> </article>
</section> </section>
<?php /* if(count($characters) > 0 && count($staff) > 0): ?>
<div class="tabs">
<?php $i = 0; ?>
</div>
<?php endif */ ?>
<?php if (count($characters) > 0): ?> <?php if (count($characters) > 0): ?>
<br /> <br />
<hr /> <hr />

View File

@ -31,11 +31,12 @@ use Aviat\AnimeClient\API\Kitsu;
<?php if (array_key_exists('anime', $data['included']) || array_key_exists('manga', $data['included'])): ?> <?php if (array_key_exists('anime', $data['included']) || array_key_exists('manga', $data['included'])): ?>
<h3>Media</h3> <h3>Media</h3>
<section class="flex flex-no-wrap"> <div class="tabs">
<?php if (array_key_exists('anime', $data['included'])): ?> <?php if (array_key_exists('anime', $data['included'])): ?>
<div> <input checked="checked" type="radio" id="media-anime" name="media-tabs" />
<h4>Anime</h4> <label for="media-anime"><h4> Anime </h4></label>
<section class="align_left media-wrap">
<section class="align_left media-wrap content">
<?php foreach($data['included']['anime'] as $id => $anime): ?> <?php foreach($data['included']['anime'] as $id => $anime): ?>
<article class="media"> <article class="media">
<?php <?php
@ -69,14 +70,13 @@ use Aviat\AnimeClient\API\Kitsu;
</article> </article>
<?php endforeach ?> <?php endforeach ?>
</section> </section>
</div>
<?php endif ?> <?php endif ?>
</section>
<section class="flex flex-no-wrap">
<?php if (array_key_exists('manga', $data['included'])): ?> <?php if (array_key_exists('manga', $data['included'])): ?>
<div> <input type="radio" id="media-manga" name="media-tabs" />
<h4>Manga</h4> <label for="media-manga"><h4>Manga</h4></label>
<section class="align_left media-wrap">
<section class="align_left media-wrap content">
<?php foreach($data['included']['manga'] as $id => $manga): ?> <?php foreach($data['included']['manga'] as $id => $manga): ?>
<article class="media"> <article class="media">
@ -97,16 +97,92 @@ use Aviat\AnimeClient\API\Kitsu;
</div> </div>
</article> </article>
<?php endforeach ?> <?php endforeach ?>
</section> </section>
</div>
<?php endif ?> <?php endif ?>
</section> </div>
<?php endif ?> <?php endif ?>
<section> <section>
<?php if ($castCount > 0): ?> <?php if ($castCount > 0): ?>
<h3>Castings</h3> <h3>Castings</h3>
<?php
$vas = $castings['Voice Actor'];
unset($castings['Voice Actor']);
ksort($vas)
?>
<?php if ( ! empty($vas)): ?>
<h4>Voice Actors</h4>
<div class="tabs">
<?php $i = 0; ?>
<?php foreach($vas as $language => $casting): ?>
<input <?= $i === 0 ? 'checked="checked"' : '' ?> type="radio" id="character-va<?= $i ?>"
name="character-vas"
/>
<label for="character-va<?= $i ?>"><h5><?= $language ?></h5></label>
<section class="content">
<table style='width:100%'>
<tr>
<th>Cast Member</th>
<th>Series</th>
</tr>
<?php foreach($casting as $cid => $c): ?>
<tr>
<td style="width:229px">
<article class="character">
<?php
$link = $url->generate('person', ['id' => $c['person']['id']]);
?>
<a href="<?= $link ?>">
<img
src="<?= $urlGenerator->assetUrl(getLocalImg($c['person']['image'])) ?>"
alt=""
/>
<div class="name">
<?= $c['person']['name'] ?>
</div>
</a>
</article>
</td>
<td>
<section class="align_left media-wrap">
<?php foreach ($c['series'] as $series): ?>
<article class="media">
<?php
$link = $url->generate('anime.details', ['id' => $series['attributes']['slug']]);
$titles = Kitsu::filterTitles($series['attributes']);
?>
<a href="<?= $link ?>">
<img
src="<?= $urlGenerator->assetUrl(getLocalImg($series['attributes']['posterImage']['small'])) ?>"
width="220" alt=""
/>
</a>
<div class="name">
<a href="<?= $link ?>">
<?= array_shift($titles) ?>
<?php foreach ($titles as $title): ?>
<br />
<small><?= $title ?></small>
<?php endforeach ?>
</a>
</div>
</article>
<?php endforeach ?>
</section>
</td>
</tr>
<?php endforeach ?>
</table>
</section>
<?php $i++ ?>
<?php endforeach ?>
</div>
<?php endif ?>
<?php foreach($castings as $role => $entries): ?> <?php foreach($castings as $role => $entries): ?>
<h4><?= $role ?></h4> <h4><?= $role ?></h4>
<?php foreach($entries as $language => $casting): ?> <?php foreach($entries as $language => $casting): ?>

View File

@ -51,7 +51,7 @@ $hasManga = stripos($_SERVER['REQUEST_URI'], 'manga') !== FALSE;
</span> </span>
<span class="flex-no-wrap small-font">[<?= $helper->a( <span class="flex-no-wrap small-font">[<?= $helper->a(
$url->generate('user_info'), $url->generate('user_info', ['user' => 'me']),
'About '. $config->get('whose_list') 'About '. $config->get('whose_list')
) ?>]</span> ) ?>]</span>

View File

@ -1,20 +1,15 @@
<?php use Aviat\AnimeClient\API\Kitsu; ?> <?php
use function Aviat\AnimeClient\getLocalImg;
use Aviat\AnimeClient\API\Kitsu;
?>
<main class="user-page details"> <main class="user-page details">
<section class="flex flex-no-wrap"> <section class="flex flex-no-wrap">
<div> <div>
<center> <center>
<h2>
<a title='View profile on Kisu'
href="https://kitsu.io/users/<?= $attributes['name'] ?>">
<?= $attributes['name'] ?>
</a>
</h2>
<?php <?php
$file = basename(parse_url($attributes['avatar']['original'], \PHP_URL_PATH)); $avatar = getLocalImg($attributes['avatar']['original']);
$parts = explode('.', $file);
$ext = end($parts);
?> ?>
<img src="<?= $urlGenerator->assetUrl('images/avatars', "{$data['id']}.{$ext}") ?>" alt="" /> <img src="<?= $urlGenerator->assetUrl($avatar) ?>" alt="" />
</center> </center>
<br /> <br />
<br /> <br />
@ -38,7 +33,7 @@
$character = $relationships['waifu']['attributes']; $character = $relationships['waifu']['attributes'];
echo $helper->a( echo $helper->a(
$url->generate('character', ['slug' => $character['slug']]), $url->generate('character', ['slug' => $character['slug']]),
$character['name'] $character['canonicalName']
); );
?> ?>
</td> </td>
@ -47,6 +42,10 @@
<tr> <tr>
<th colspan="2">User Stats</th> <th colspan="2">User Stats</th>
</tr> </tr>
<tr>
<td>Time spent watching anime:</td>
<td><?= $timeOnAnime ?></td>
</tr>
<tr> <tr>
<td># of Posts</td> <td># of Posts</td>
<td><?= $attributes['postsCount'] ?></td> <td><?= $attributes['postsCount'] ?></td>
@ -62,19 +61,30 @@
</table> </table>
</div> </div>
<div> <div>
<h2>
<a
title='View profile on Kisu'
href="https://kitsu.io/users/<?= $attributes['slug'] ?>"
>
<?= $attributes['name'] ?>
</a>
</h2>
<dl> <dl>
<dt>About:</dt> <dt><h3>About:</h3></dt>
<dd><?= $escape->html($attributes['about']) ?></dd> <dd><?= $escape->html($attributes['about']) ?></dd>
</dl> </dl>
<?php if ( ! empty($favorites)): ?> <?php if ( ! empty($favorites)): ?>
<h3>Favorites</h3>
<?php if ( ! empty($favorites['characters'])): ?> <?php if ( ! empty($favorites['characters'])): ?>
<h4>Favorite Characters</h4> <h4>Characters</h4>
<section class="media-wrap"> <section class="media-wrap">
<?php foreach($favorites['characters'] as $id => $char): ?> <?php foreach($favorites['characters'] as $id => $char): ?>
<?php if ( ! empty($char['image']['original'])): ?> <?php if ( ! empty($char['image']['original'])): ?>
<article class="small_character"> <article class="small_character">
<?php $link = $url->generate('character', ['slug' => $char['slug']]) ?> <?php $link = $url->generate('character', ['slug' => $char['slug']]) ?>
<div class="name"><?= $helper->a($link, $char['name']); ?></div> <div class="name"><?= $helper->a($link, $char['canonicalName']); ?></div>
<a href="<?= $link ?>"> <a href="<?= $link ?>">
<picture> <picture>
<source srcset="<?= $urlGenerator->assetUrl("images/characters/{$char['id']}.webp") ?>" type="image/webp"> <source srcset="<?= $urlGenerator->assetUrl("images/characters/{$char['id']}.webp") ?>" type="image/webp">
@ -88,7 +98,7 @@
</section> </section>
<?php endif ?> <?php endif ?>
<?php if ( ! empty($favorites['anime'])): ?> <?php if ( ! empty($favorites['anime'])): ?>
<h4>Favorite Anime</h4> <h4>Anime</h4>
<section class="media-wrap"> <section class="media-wrap">
<?php foreach($favorites['anime'] as $anime): ?> <?php foreach($favorites['anime'] as $anime): ?>
<article class="media"> <article class="media">
@ -116,7 +126,7 @@
</section> </section>
<?php endif ?> <?php endif ?>
<?php if ( ! empty($favorites['manga'])): ?> <?php if ( ! empty($favorites['manga'])): ?>
<h4>Favorite Manga</h4> <h4>Manga</h4>
<section class="media-wrap"> <section class="media-wrap">
<?php foreach($favorites['manga'] as $manga): ?> <?php foreach($favorites['manga'] as $manga): ?>
<article class="media"> <article class="media">

View File

@ -266,10 +266,11 @@ final class Model {
'name' => $username, 'name' => $username,
], ],
'fields' => [ 'fields' => [
// 'anime' => 'slug,name,canonicalTitle', 'anime' => 'slug,canonicalTitle,posterImage',
'characters' => 'slug,name,image' 'manga' => 'slug,canonicalTitle,posterImage',
'characters' => 'slug,canonicalName,image'
], ],
'include' => 'waifu,pinnedPost,blocks,linkedAccounts,profileLinks,profileLinks.profileLinkSite,userRoles,favorites.item' 'include' => 'waifu,favorites.item,stats'
] ]
]); ]);

View File

@ -186,22 +186,32 @@ final class Index extends BaseController {
* *
* @return void * @return void
*/ */
public function me() public function about($username = 'me')
{ {
$username = $this->config->get(['kitsu_username']); $isMainUser = $username === 'me';
$username = $isMainUser
? $this->config->get(['kitsu_username'])
: $username;
$model = $this->container->get('kitsu-model'); $model = $this->container->get('kitsu-model');
$data = $model->getUserData($username); $data = $model->getUserData($username);
$orgData = JsonAPI::organizeData($data)[0]; $orgData = JsonAPI::organizeData($data)[0];
$rels = $orgData['relationships'] ?? []; $rels = $orgData['relationships'] ?? [];
$favorites = array_key_exists('favorites', $rels) ? $rels['favorites'] : []; $favorites = array_key_exists('favorites', $rels) ? $rels['favorites'] : [];
$timeOnAnime = $this->formatAnimeTime($orgData['attributes']['lifeSpentOnAnime']);
$whom = $isMainUser
? $this->config->get('whose_list')
: $username;
$this->outputHTML('me', [ $this->outputHTML('me', [
'title' => 'About ' . $this->config->get('whose_list'), 'title' => 'About ' . $whom,
'data' => $orgData, 'data' => $orgData,
'attributes' => $orgData['attributes'], 'attributes' => $orgData['attributes'],
'relationships' => $rels, 'relationships' => $rels,
'favorites' => $this->organizeFavorites($favorites), 'favorites' => $this->organizeFavorites($favorites),
'timeOnAnime' => $timeOnAnime,
]); ]);
} }
@ -330,6 +340,12 @@ final class Index extends BaseController {
$gdImg = imagecreatefromstring($data); $gdImg = imagecreatefromstring($data);
$resizedImg = imagescale($gdImg, $width ?? $origWidth); $resizedImg = imagescale($gdImg, $width ?? $origWidth);
if ($ext === 'gif')
{
file_put_contents("{$filePrefix}.gif", $data);
}
else
{
// save the webp versions // save the webp versions
imagewebp($gdImg, "{$filePrefix}-original.webp"); imagewebp($gdImg, "{$filePrefix}-original.webp");
imagewebp($resizedImg, "{$filePrefix}.webp"); imagewebp($resizedImg, "{$filePrefix}.webp");
@ -337,11 +353,12 @@ final class Index extends BaseController {
// save the scaled jpeg file // save the scaled jpeg file
imagejpeg($resizedImg, "{$filePrefix}.jpg"); imagejpeg($resizedImg, "{$filePrefix}.jpg");
imagedestroy($gdImg);
imagedestroy($resizedImg);
// And the original // And the original
file_put_contents("{$filePrefix}-original.jpg", $data); file_put_contents("{$filePrefix}-original.jpg", $data);
}
imagedestroy($gdImg);
imagedestroy($resizedImg);
if ($display) if ($display)
{ {
@ -388,6 +405,13 @@ final class Index extends BaseController {
return $output; return $output;
} }
/**
* Get a placeholder for a missing image
*
* @param string $path
* @param int|null $width
* @param int|null $height
*/
private function getPlaceholder (string $path, ?int $width = 200, ?int $height = NULL): void private function getPlaceholder (string $path, ?int $width = 200, ?int $height = NULL): void
{ {
$height = $height ?? $width; $height = $height ?? $width;
@ -402,4 +426,39 @@ final class Index extends BaseController {
header('Content-Type: image/png'); header('Content-Type: image/png');
echo file_get_contents($filename); echo file_get_contents($filename);
} }
/**
* Format the time spent on anime in a more readable format
*
* @param int $minutes
* @return string
*/
private function formatAnimeTime (int $minutes): string
{
$minutesPerDay = 1440;
$minutesPerYear = $minutesPerDay * 365;
// Minutes short of a year
$years = (int)floor($minutes / $minutesPerYear);
$minutes %= $minutesPerYear;
// Minutes short of a day
$extraMinutes = $minutes % $minutesPerDay;
$days = ($minutes - $extraMinutes) / $minutesPerDay;
// Minutes short of an hour
$remMinutes = $extraMinutes % 60;
$hours = ($extraMinutes - $remMinutes) / 60;
$output = "{$days} days, {$hours} hours, and {$remMinutes} minutes.";
if ($years > 0)
{
$output = "{$years} year(s),{$output}";
}
return $output;
}
} }