Css tweaks, and start caching kitsu images

This commit is contained in:
Timothy Warren 2017-04-13 11:15:16 -04:00
parent 33099df6ea
commit 2d9c5b3093
15 changed files with 189 additions and 25 deletions

5
.gitignore vendored
View File

@ -25,4 +25,7 @@ app/config/*.toml
phinx.yml phinx.yml
.idea/ .idea/
Caddyfile Caddyfile
build/humbuglog.txt build/humbuglog.txt
public/images/anime/**
public/images/manga/**
public/images/characters/**

View File

@ -147,6 +147,16 @@ return [
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
// Default / Shared routes // Default / Shared routes
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
'image_proxy' => [
'path' => '/public/images/{type}/{file}',
'action' => 'images',
'controller' => DEFAULT_CONTROLLER,
'verb' => 'get',
'tokens' => [
'type' => '[a-z0-9\-]+',
'file' => '[a-z0-9\-]+\.[a-z]{3}'
]
],
'cache_purge' => [ 'cache_purge' => [
'path' => '/cache_purge', 'path' => '/cache_purge',
'action' => 'clearCache', 'action' => 'clearCache',

View File

@ -1,7 +1,7 @@
<main class="details fixed"> <main class="details fixed">
<section class="flex flex-no-wrap"> <section class="flex flex-no-wrap">
<div> <div>
<img class="cover" width="402" height="284" src="<?= $data['cover_image'] ?>" alt="" /> <img class="cover" width="402" height="284" src="<?= $urlGenerator->assetUrl("images/anime/{$data['id']}.jpg") ?>" alt="" />
<br /> <br />
<br /> <br />
<table class="media_details"> <table class="media_details">
@ -80,7 +80,7 @@
<?php if (count($characters) > 0): ?> <?php if (count($characters) > 0): ?>
<h2>Characters</h2> <h2>Characters</h2>
<section class="align_left media-wrap"> <section class="align_left media-wrap">
<?php foreach($characters as $char): ?> <?php foreach($characters as $id => $char): ?>
<?php if ( ! empty($char['image']['original'])): ?> <?php if ( ! empty($char['image']['original'])): ?>
<article class="character"> <article class="character">
<?php $link = $url->generate('character', ['slug' => $char['slug']]) ?> <?php $link = $url->generate('character', ['slug' => $char['slug']]) ?>
@ -88,7 +88,7 @@
<?= $helper->a($link, $char['name']); ?> <?= $helper->a($link, $char['name']); ?>
</div> </div>
<a href="<?= $link ?>"> <a href="<?= $link ?>">
<?= $helper->img($char['image']['original'], [ <?= $helper->img($urlGenerator->assetUrl("images/characters/{$id}.jpg"), [
'width' => '225' 'width' => '225'
]) ?> ]) ?>
</a> </a>

View File

@ -2,7 +2,7 @@
<main class="details"> <main class="details">
<section class="flex flex-no-wrap"> <section class="flex flex-no-wrap">
<div> <div>
<img class="cover" width="284" src="<?= $data[0]['attributes']['image']['original'] ?>" alt="" /> <img class="cover" width="284" src="<?= $urlGenerator->assetUrl("images/characters/{$data[0]['id']}.jpg") ?>" alt="" />
</div> </div>
<div> <div>
<h2><?= $data[0]['attributes']['name'] ?></h2> <h2><?= $data[0]['attributes']['name'] ?></h2>
@ -18,14 +18,14 @@
<div> <div>
<h4>Anime</h4> <h4>Anime</h4>
<section class="align_left media-wrap"> <section class="align_left media-wrap">
<?php foreach($data['included']['anime'] as $anime): ?> <?php foreach($data['included']['anime'] as $id => $anime): ?>
<article class="media"> <article class="media">
<?php <?php
$link = $url->generate('anime.details', ['id' => $anime['attributes']['slug']]); $link = $url->generate('anime.details', ['id' => $anime['attributes']['slug']]);
$titles = Kitsu::filterTitles($anime['attributes']); $titles = Kitsu::filterTitles($anime['attributes']);
?> ?>
<a href="<?= $link ?>"> <a href="<?= $link ?>">
<img src="<?= $anime['attributes']['posterImage']['small'] ?>" width="220" alt="" /> <img src="<?= $urlGenerator->assetUrl("images/anime/{$id}.jpg") ?>" width="220" alt="" />
</a> </a>
<div class="name"> <div class="name">
<a href="<?= $link ?>"> <a href="<?= $link ?>">
@ -45,14 +45,14 @@
<h4>Manga</h4> <h4>Manga</h4>
<section class="align_left media-wrap"> <section class="align_left media-wrap">
<?php foreach($data['included']['manga'] as $manga): ?> <?php foreach($data['included']['manga'] as $id => $manga): ?>
<article class="media"> <article class="media">
<?php <?php
$link = $url->generate('manga.details', ['id' => $manga['attributes']['slug']]); $link = $url->generate('manga.details', ['id' => $manga['attributes']['slug']]);
$titles = Kitsu::filterTitles($manga['attributes']); $titles = Kitsu::filterTitles($manga['attributes']);
?> ?>
<a href="<?= $link ?>"> <a href="<?= $link ?>">
<img src="<?= $manga['attributes']['posterImage']['small'] ?>" width="220" alt="" /> <img src="<?= $urlGenerator->assetUrl("images/manga/{$id}.jpg") ?>" width="220" alt="" />
</a> </a>
<div class="name"> <div class="name">
<a href="<?= $link ?>"> <a href="<?= $link ?>">

View File

@ -11,7 +11,7 @@
<section class="media-wrap"> <section class="media-wrap">
<?php foreach($items as $item): ?> <?php foreach($items as $item): ?>
<article class="media" id="a-<?= $item['hummingbird_id'] ?>"> <article class="media" id="a-<?= $item['hummingbird_id'] ?>">
<img src="https://media.kitsu.io/anime/poster_images/<?= $item['hummingbird_id'] ?>/small.jpg" <img src="<?= $urlGenerator->assetUrl("images/anime/{$item['hummingbird_id']}.jpg") ?>"
alt="<?= $item['title'] ?> cover image" /> alt="<?= $item['title'] ?> cover image" />
<div class="name"> <div class="name">
<a href="<?= $url->generate('anime.details', ['id' => $item['slug']]) ?>"> <a href="<?= $url->generate('anime.details', ['id' => $item['slug']]) ?>">

View File

@ -11,10 +11,11 @@ const css = fs.readFileSync('css/base.css', 'utf8');
postcss() postcss()
.use(atImport()) .use(atImport())
.use(cssNext({ .use(cssNext())
warnForDuplicates: false
}))
.use(cssNano({ .use(cssNano({
autoprefixer: false,
colormin: false,
minifyFontValues: false,
options: { options: {
sourcemap: false sourcemap: false
} }

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
:root { :root {
--default-font-list:system-ui,sans-serif; --default-font-list: system-ui,sans-serif;
--monospace-font-list:'Anonymous Pro','Fira Code',Menlo,Monaco,Consolas,'Courier New',monospace; --monospace-font-list:'Anonymous Pro','Fira Code',Menlo,Monaco,Consolas,'Courier New',monospace;
--serif-font-list:Georgia,Times,'Times New Roman',serif; --serif-font-list:Georgia,Times,'Times New Roman',serif;
-ms-text-size-adjust:100%; -ms-text-size-adjust:100%;

View File

View File

@ -829,6 +829,7 @@ class Model {
} }
$baseData = $data['data']['attributes']; $baseData = $data['data']['attributes'];
$baseData['id'] = $data['id'];
$baseData['included'] = $data['included']; $baseData['included'] = $data['included'];
return $baseData; return $baseData;
} }
@ -864,6 +865,7 @@ class Model {
} }
$baseData = $data['data'][0]['attributes']; $baseData = $data['data'][0]['attributes'];
$baseData['id'] = $data['data'][0]['id'];
$baseData['included'] = $data['included']; $baseData['included'] = $data['included'];
return $baseData; return $baseData;
} }

View File

@ -36,10 +36,11 @@ class AnimeTransformer extends AbstractTransformer {
$item['included'] = JsonAPI::organizeIncludes($item['included']); $item['included'] = JsonAPI::organizeIncludes($item['included']);
$item['genres'] = array_column($item['included']['genres'], 'name') ?? []; $item['genres'] = array_column($item['included']['genres'], 'name') ?? [];
sort($item['genres']); sort($item['genres']);
$titles = Kitsu::filterTitles($item); $titles = Kitsu::filterTitles($item);
return [ return [
'id' => $item['id'],
'slug' => $item['slug'], 'slug' => $item['slug'],
'title' => $titles[0], 'title' => $titles[0],
'titles' => $titles, 'titles' => $titles,

View File

@ -16,10 +16,16 @@
namespace Aviat\AnimeClient\Controller; namespace Aviat\AnimeClient\Controller;
use function Amp\wait;
use Amp\Artax\Client;
use Aviat\AnimeClient\Controller as BaseController; use Aviat\AnimeClient\Controller as BaseController;
use Aviat\AnimeClient\API\JsonAPI; use Aviat\AnimeClient\API\JsonAPI;
use Aviat\Ion\View\HtmlView; use Aviat\Ion\View\HtmlView;
/**
* Controller for handling routes that don't fit elsewhere
*/
class Index extends BaseController { class Index extends BaseController {
/** /**
@ -113,6 +119,44 @@ class Index extends BaseController {
]); ]);
} }
/**
* Get image covers from kitsu
*
* @return void
*/
public function images($type, $file)
{
$kitsuUrl = 'https://media.kitsu.io/';
list($id, $ext) = explode('.', basename($file));
switch ($type)
{
case 'anime':
$kitsuUrl .= "anime/poster_images/{$id}/small.{$ext}";
break;
case 'manga':
$kitsuUrl .= "manga/poster_images/{$id}/small.{$ext}";
break;
case 'characters':
$kitsuUrl .= "characters/images/{$id}/original.{$ext}";
break;
default:
$this->notFound();
return;
}
$promise = (new Client)->request($kitsuUrl);
$response = wait($promise);
$data = (string) $response->getBody();
$baseSavePath = $this->config->get('img_cache_path');
file_put_contents("{$baseSavePath}/{$type}/{$id}.{$ext}", $data);
header('Content-type: ' . $response->getHeader('content-type')[0]);
echo (string) $response->getBody();
}
private function organizeFavorites(array $rawfavorites): array private function organizeFavorites(array $rawfavorites): array
{ {
// return $rawfavorites; // return $rawfavorites;

View File

@ -22,29 +22,27 @@ use Aviat\Ion\Friend;
use Aviat\Ion\Json; use Aviat\Ion\Json;
class AnimeTransformerTest extends AnimeClientTestCase { class AnimeTransformerTest extends AnimeClientTestCase {
protected $dir; protected $dir;
protected $beforeTransform; protected $beforeTransform;
protected $afterTransform; protected $afterTransform;
protected $transformer; protected $transformer;
public function setUp() public function setUp()
{ {
parent::setUp(); parent::setUp();
$this->dir = AnimeClientTestCase::TEST_DATA_DIR . '/Kitsu'; $this->dir = AnimeClientTestCase::TEST_DATA_DIR . '/Kitsu';
$this->beforeTransform = Json::decodeFile("{$this->dir}/animeBeforeTransform.json"); $this->beforeTransform = Json::decodeFile("{$this->dir}/animeBeforeTransform.json");
$this->afterTransform = Json::decodeFile("{$this->dir}/animeAfterTransform.json");
$this->transformer = new AnimeTransformer(); $this->transformer = new AnimeTransformer();
} }
public function testTransform() public function testTransform()
{ {
$expected = $this->afterTransform; $expected = $this->afterTransform;
$actual = $this->transformer->transform($this->beforeTransform); $actual = $this->transformer->transform($this->beforeTransform);
// Json::encodeFile("{$this->dir}/animeAfterTransform.json", $actual);
$this->assertMatchesSnapshot($actual);
$this->assertEquals($expected, $actual);
} }
} }

View File

@ -0,0 +1,104 @@
<?php return array (
'id' => 32344,
'slug' => 'attack-on-titan',
'title' => 'Attack on Titan',
'titles' =>
array (
0 => 'Attack on Titan',
1 => 'Shingeki no Kyojin',
2 => '進撃の巨人',
),
'status' => 'Finished Airing',
'cover_image' => 'https://media.kitsu.io/anime/poster_images/7442/small.jpg?1418580054',
'show_type' => 'TV',
'episode_count' => 25,
'episode_length' => 24,
'synopsis' => 'Several hundred years ago, humans were nearly exterminated by titans. Titans are typically several stories tall, seem to have no intelligence, devour human beings and, worst of all, seem to do it for the pleasure rather than as a food source. A small percentage of humanity survived by enclosing themselves in a city protected by extremely high walls, even taller than the biggest of titans. Flash forward to the present and the city has not seen a titan in over 100 years. Teenage boy Eren and his foster sister Mikasa witness something horrific as the city walls are destroyed by a colossal titan that appears out of thin air. As the smaller titans flood the city, the two kids watch in horror as their mother is eaten alive. Eren vows that he will murder every single titan and take revenge for all of mankind.
(Source: ANN)',
'age_rating' => 'R',
'age_rating_guide' => 'Violence, Profanity',
'url' => 'https://kitsu.io/anime/attack-on-titan',
'genres' =>
array (
0 => 'Action',
1 => 'Drama',
2 => 'Fantasy',
3 => 'Super Power',
),
'streaming_links' =>
array (
0 =>
array (
'meta' =>
array (
'name' => 'Crunchyroll',
'link' => true,
'image' => 'streaming-logos/crunchyroll.svg',
),
'link' => 'http://www.crunchyroll.com/attack-on-titan',
'subs' =>
array (
0 => 'en',
),
'dubs' =>
array (
0 => 'ja',
),
),
1 =>
array (
'meta' =>
array (
'name' => 'Hulu',
'link' => true,
'image' => 'streaming-logos/hulu.svg',
),
'link' => 'http://www.hulu.com/attack-on-titan',
'subs' =>
array (
0 => 'en',
),
'dubs' =>
array (
0 => 'ja',
),
),
2 =>
array (
'meta' =>
array (
'name' => 'Funimation',
'link' => true,
'image' => 'streaming-logos/funimation.svg',
),
'link' => 'http://www.funimation.com/shows/attack-on-titan/videos/episodes',
'subs' =>
array (
0 => 'en',
),
'dubs' =>
array (
0 => 'ja',
),
),
3 =>
array (
'meta' =>
array (
'name' => 'Netflix',
'link' => false,
'image' => 'streaming-logos/netflix.svg',
),
'link' => 't',
'subs' =>
array (
0 => 'en',
),
'dubs' =>
array (
0 => 'ja',
),
),
),
);

View File

@ -1,4 +1,5 @@
{ {
"id": 32344,
"slug": "attack-on-titan", "slug": "attack-on-titan",
"synopsis": "Several hundred years ago, humans were nearly exterminated by titans. Titans are typically several stories tall, seem to have no intelligence, devour human beings and, worst of all, seem to do it for the pleasure rather than as a food source. A small percentage of humanity survived by enclosing themselves in a city protected by extremely high walls, even taller than the biggest of titans. Flash forward to the present and the city has not seen a titan in over 100 years. Teenage boy Eren and his foster sister Mikasa witness something horrific as the city walls are destroyed by a colossal titan that appears out of thin air. As the smaller titans flood the city, the two kids watch in horror as their mother is eaten alive. Eren vows that he will murder every single titan and take revenge for all of mankind.\n\n(Source: ANN)", "synopsis": "Several hundred years ago, humans were nearly exterminated by titans. Titans are typically several stories tall, seem to have no intelligence, devour human beings and, worst of all, seem to do it for the pleasure rather than as a food source. A small percentage of humanity survived by enclosing themselves in a city protected by extremely high walls, even taller than the biggest of titans. Flash forward to the present and the city has not seen a titan in over 100 years. Teenage boy Eren and his foster sister Mikasa witness something horrific as the city walls are destroyed by a colossal titan that appears out of thin air. As the smaller titans flood the city, the two kids watch in horror as their mother is eaten alive. Eren vows that he will murder every single titan and take revenge for all of mankind.\n\n(Source: ANN)",
"coverImageTopOffset": 263, "coverImageTopOffset": 263,