More caching, and start of anime collection view
This commit is contained in:
parent
86663d2179
commit
7c913986d4
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
vendor
|
||||||
|
app/cache/*
|
||||||
|
public/images/*
|
||||||
|
composer.lock
|
BIN
anime_collection.sqlite
Executable file
BIN
anime_collection.sqlite
Executable file
Binary file not shown.
@ -2,29 +2,12 @@
|
|||||||
|
|
||||||
class BaseController {
|
class BaseController {
|
||||||
|
|
||||||
|
protected $config;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
|
global $config;
|
||||||
}
|
$this->config = $config;
|
||||||
|
|
||||||
public function __destruct()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public function login()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public function logout()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public function search()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -6,10 +6,14 @@ use \GuzzleHttp\Cookie\CookieJar;
|
|||||||
class BaseModel {
|
class BaseModel {
|
||||||
|
|
||||||
protected $client;
|
protected $client;
|
||||||
|
protected $config;
|
||||||
protected $cookieJar;
|
protected $cookieJar;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
|
global $config;
|
||||||
|
|
||||||
|
$this->config = $config;
|
||||||
$this->cookieJar = new CookieJar();
|
$this->cookieJar = new CookieJar();
|
||||||
$this->client = new Client([
|
$this->client = new Client([
|
||||||
'base_url' => $this->base_url,
|
'base_url' => $this->base_url,
|
||||||
@ -53,7 +57,7 @@ class BaseModel {
|
|||||||
$ext = end($ext_parts);
|
$ext = end($ext_parts);
|
||||||
|
|
||||||
$cached_image = "{$series_slug}.{$ext}";
|
$cached_image = "{$series_slug}.{$ext}";
|
||||||
$cached_path = __DIR__ . "/../../public/cache/{$type}/{$cached_image}";
|
$cached_path = "{$this->config->img_cache_path}/{$type}/{$cached_image}";
|
||||||
|
|
||||||
// Cache the file if it doesn't already exist
|
// Cache the file if it doesn't already exist
|
||||||
if ( ! file_exists($cached_path))
|
if ( ! file_exists($cached_path))
|
||||||
@ -80,7 +84,7 @@ class BaseModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return "/public/cache/{$type}/{$cached_image}";
|
return "/public/images/{$type}/{$cached_image}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// End of BaseModel.php
|
// End of BaseModel.php
|
9
app/config/config.php
Normal file
9
app/config/config.php
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
return (object)[
|
||||||
|
// Username for feeds
|
||||||
|
'hummingbird_username' => 'timw4mail',
|
||||||
|
|
||||||
|
// Cache paths
|
||||||
|
'data_cache_path' => __DIR__ . '/../cache',
|
||||||
|
'img_cache_path' => __DIR__ .'/../../public/images'
|
||||||
|
];
|
13
app/config/database.php
Normal file
13
app/config/database.php
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
return [
|
||||||
|
'collection' => [
|
||||||
|
'type' => 'sqlite',
|
||||||
|
'host' => '',
|
||||||
|
'user' => '',
|
||||||
|
'pass' => '',
|
||||||
|
'port' => '',
|
||||||
|
'name' => 'default',
|
||||||
|
'database' => '',
|
||||||
|
'file' => __DIR__ . '/../../anime_collection.sqlite',
|
||||||
|
]
|
||||||
|
];
|
@ -43,6 +43,12 @@ return [
|
|||||||
'type' => 'completed'
|
'type' => 'completed'
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
'collection' => [
|
||||||
|
'path' => '/collection',
|
||||||
|
'controller' => 'AnimeController',
|
||||||
|
'action' => 'collection',
|
||||||
|
'params' => []
|
||||||
|
],
|
||||||
'anime_login' => [
|
'anime_login' => [
|
||||||
'path' => '/login',
|
'path' => '/login',
|
||||||
'controller' => 'AnimeController',
|
'controller' => 'AnimeController',
|
||||||
|
@ -3,16 +3,13 @@
|
|||||||
class AnimeController extends BaseController {
|
class AnimeController extends BaseController {
|
||||||
|
|
||||||
private $model;
|
private $model;
|
||||||
|
private $collection_model;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
$this->model = new AnimeModel();
|
$this->model = new AnimeModel();
|
||||||
}
|
$this->collection_model = new AnimeCollectionModel();
|
||||||
|
|
||||||
public function __destruct()
|
|
||||||
{
|
|
||||||
parent::__destruct();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function index()
|
public function index()
|
||||||
@ -38,6 +35,16 @@ class AnimeController extends BaseController {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function collection()
|
||||||
|
{
|
||||||
|
$this->collection_model->get_collection_seed();
|
||||||
|
|
||||||
|
$this->outputHTML('anime_list', [
|
||||||
|
'title' => "Tim's Anime Collection",
|
||||||
|
'sections' => []
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
public function login()
|
public function login()
|
||||||
{
|
{
|
||||||
$data = $this->model->authenticate();
|
$data = $this->model->authenticate();
|
||||||
|
@ -10,11 +10,6 @@ class MangaController extends BaseController {
|
|||||||
$this->model = new MangaModel();
|
$this->model = new MangaModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __destruct()
|
|
||||||
{
|
|
||||||
parent::__destruct();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
$this->manga_list('Reading');
|
$this->manga_list('Reading');
|
||||||
|
28
app/models/AnimeCollectionModel.php
Normal file
28
app/models/AnimeCollectionModel.php
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model for getting anime collection data
|
||||||
|
*/
|
||||||
|
class AnimeCollectionModel extends BaseModel {
|
||||||
|
|
||||||
|
private $db;
|
||||||
|
private $anime_model;
|
||||||
|
private $db_config;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->db_config = require_once(__DIR__ . '/../config/database.php');
|
||||||
|
$this->db = Query($this->db_config['collection']);
|
||||||
|
|
||||||
|
$this->anime_model = new AnimeModel();
|
||||||
|
|
||||||
|
//parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_collection()
|
||||||
|
{
|
||||||
|
// TODO: show collection from database
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
// End of AnimeCollectionModel.php
|
@ -4,7 +4,6 @@
|
|||||||
* Model for handling requests dealing with the anime list
|
* Model for handling requests dealing with the anime list
|
||||||
*/
|
*/
|
||||||
class AnimeModel extends BaseModel {
|
class AnimeModel extends BaseModel {
|
||||||
|
|
||||||
protected $client;
|
protected $client;
|
||||||
protected $cookieJar;
|
protected $cookieJar;
|
||||||
protected $base_url = "https://hummingbird.me/api/v1";
|
protected $base_url = "https://hummingbird.me/api/v1";
|
||||||
@ -69,10 +68,10 @@ class AnimeModel extends BaseModel {
|
|||||||
/**
|
/**
|
||||||
* Get a category out of the full list
|
* Get a category out of the full list
|
||||||
*
|
*
|
||||||
* @param string $type
|
* @param string $status
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function get_list($type)
|
public function get_list($status)
|
||||||
{
|
{
|
||||||
$map = [
|
$map = [
|
||||||
'currently-watching' => 'Watching',
|
'currently-watching' => 'Watching',
|
||||||
@ -82,41 +81,65 @@ class AnimeModel extends BaseModel {
|
|||||||
'completed' => 'Completed',
|
'completed' => 'Completed',
|
||||||
];
|
];
|
||||||
|
|
||||||
$data = $this->_get_list($type);
|
$data = $this->_get_list($status);
|
||||||
$this->sort_by_name($data);
|
$this->sort_by_name($data);
|
||||||
|
|
||||||
$output = [];
|
$output = [];
|
||||||
$output[$map[$type]] = $data;
|
$output[$map[$status]] = $data;
|
||||||
|
|
||||||
return $output;
|
return $output;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function _get_list($type="all")
|
/**
|
||||||
|
* Actually retreive the data from the api
|
||||||
|
*
|
||||||
|
* @param string $status - Status to filter by
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function _get_list($status="all")
|
||||||
{
|
{
|
||||||
global $defaultHandler;
|
global $defaultHandler;
|
||||||
|
|
||||||
|
$cache_file = "{$this->config->data_cache_path}/anime-{$status}.json";
|
||||||
|
|
||||||
$config = [
|
$config = [
|
||||||
'query' => [
|
'query' => [
|
||||||
'username' => 'timw4mail',
|
'username' => $this->config->hummingbird_username,
|
||||||
],
|
],
|
||||||
'allow_redirects' => false
|
'allow_redirects' => false
|
||||||
];
|
];
|
||||||
|
|
||||||
if ($type != "all")
|
if ($status != "all")
|
||||||
{
|
{
|
||||||
$config['query']['status'] = $type;
|
$config['query']['status'] = $status;
|
||||||
}
|
}
|
||||||
|
|
||||||
$response = $this->client->get($this->_url('/users/timw4mail/library'), $config);
|
$response = $this->client->get($this->_url('/users/' . $this->config->hummingbird_username . '/library'), $config);
|
||||||
|
|
||||||
$defaultHandler->addDataTable('response', (array)$response);
|
$defaultHandler->addDataTable('anime_list_response', (array)$response);
|
||||||
|
|
||||||
if ($response->getStatusCode() != 200)
|
if ($response->getStatusCode() != 200)
|
||||||
|
{
|
||||||
|
if ( ! file_exists($cache_file))
|
||||||
{
|
{
|
||||||
throw new Exception($response->getEffectiveUrl());
|
throw new Exception($response->getEffectiveUrl());
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$output = json_decode(file_get_contents($cache_file), TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$output = $response->json();
|
$output = $response->json();
|
||||||
|
$output_json = json_encode($output);
|
||||||
|
|
||||||
|
if (file_get_contents($cache_file) !== $output_json)
|
||||||
|
{
|
||||||
|
// Cache the call in case of downtime
|
||||||
|
file_put_contents($cache_file, json_encode($output));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
foreach($output as &$row)
|
foreach($output as &$row)
|
||||||
{
|
{
|
||||||
@ -126,6 +149,39 @@ class AnimeModel extends BaseModel {
|
|||||||
return $output;
|
return $output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search for anime by name
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function search($name)
|
||||||
|
{
|
||||||
|
global $defaultHandler;
|
||||||
|
|
||||||
|
$config = [
|
||||||
|
'query' => [
|
||||||
|
'query' => $name
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = $this->client->get($this->_url('/search/anime'), $config);
|
||||||
|
$defaultHandler->addDataTable('anime_search_response', (array)$response);
|
||||||
|
|
||||||
|
if ($response->getStatusCode() != 200)
|
||||||
|
{
|
||||||
|
throw new Exception($response->getEffectiveUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
return $response->json();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort the list by title
|
||||||
|
*
|
||||||
|
* @param array &$array
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
private function sort_by_name(&$array)
|
private function sort_by_name(&$array)
|
||||||
{
|
{
|
||||||
$sort = array();
|
$sort = array();
|
||||||
|
@ -34,25 +34,33 @@ class MangaModel extends BaseModel {
|
|||||||
/**
|
/**
|
||||||
* Get a category out of the full list
|
* Get a category out of the full list
|
||||||
*
|
*
|
||||||
* @param string $type
|
* @param string $status
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function get_list($type)
|
public function get_list($status)
|
||||||
{
|
{
|
||||||
$data = $this->_get_list($type);
|
$data = $this->_get_list($status);
|
||||||
|
|
||||||
$this->sort_by_name($data);
|
$this->sort_by_name($data);
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function _get_list($type="all")
|
/**
|
||||||
|
* Massage the list of manga entries into something more usable
|
||||||
|
*
|
||||||
|
* @param string $status
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function _get_list($status="all")
|
||||||
{
|
{
|
||||||
global $defaultHandler;
|
global $defaultHandler;
|
||||||
|
|
||||||
|
$cache_file = __DIR__ . "/../cache/manga.json";
|
||||||
|
|
||||||
$config = [
|
$config = [
|
||||||
'query' => [
|
'query' => [
|
||||||
'user_id' => 'timw4mail',
|
'user_id' => $this->config->hummingbird_username
|
||||||
],
|
],
|
||||||
'allow_redirects' => false
|
'allow_redirects' => false
|
||||||
];
|
];
|
||||||
@ -62,13 +70,25 @@ class MangaModel extends BaseModel {
|
|||||||
$defaultHandler->addDataTable('response', (array)$response);
|
$defaultHandler->addDataTable('response', (array)$response);
|
||||||
|
|
||||||
if ($response->getStatusCode() != 200)
|
if ($response->getStatusCode() != 200)
|
||||||
|
{
|
||||||
|
if ( ! file_exists($cache_file))
|
||||||
{
|
{
|
||||||
throw new Exception($response->getEffectiveUrl());
|
throw new Exception($response->getEffectiveUrl());
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$raw_data = json_decode(file_get_contents($cache_file), TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// Reorganize data to be more usable
|
// Reorganize data to be more usable
|
||||||
$raw_data = $response->json();
|
$raw_data = $response->json();
|
||||||
|
|
||||||
|
// Cache data in case of downtime
|
||||||
|
file_put_contents($cache_file, json_encode($raw_data));
|
||||||
|
}
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'Reading' => [],
|
'Reading' => [],
|
||||||
'Plan to Read' => [],
|
'Plan to Read' => [],
|
||||||
@ -78,11 +98,13 @@ class MangaModel extends BaseModel {
|
|||||||
];
|
];
|
||||||
$manga_data = [];
|
$manga_data = [];
|
||||||
|
|
||||||
|
// Massage the two lists into one
|
||||||
foreach($raw_data['manga'] as $manga)
|
foreach($raw_data['manga'] as $manga)
|
||||||
{
|
{
|
||||||
$manga_data[$manga['id']] = $manga;
|
$manga_data[$manga['id']] = $manga;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Filter data by status
|
||||||
foreach($raw_data['manga_library_entries'] as &$entry)
|
foreach($raw_data['manga_library_entries'] as &$entry)
|
||||||
{
|
{
|
||||||
$entry['manga'] = $manga_data[$entry['manga_id']];
|
$entry['manga'] = $manga_data[$entry['manga_id']];
|
||||||
@ -115,9 +137,15 @@ class MangaModel extends BaseModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (array_key_exists($type, $data)) ? $data[$type] : $data;
|
return (array_key_exists($status, $data)) ? $data[$status] : $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort the manga entries by their title
|
||||||
|
*
|
||||||
|
* @param array $array
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
private function sort_by_name(&$array)
|
private function sort_by_name(&$array)
|
||||||
{
|
{
|
||||||
$sort = array();
|
$sort = array();
|
||||||
|
0
app/views/anime_collection.php
Normal file
0
app/views/anime_collection.php
Normal file
@ -5,6 +5,7 @@
|
|||||||
<li class="<?= is_selected('/on_hold', $route_path) ?>"><a href="/on_hold">On Hold</a></li>
|
<li class="<?= is_selected('/on_hold', $route_path) ?>"><a href="/on_hold">On Hold</a></li>
|
||||||
<li class="<?= is_selected('/dropped', $route_path) ?>"><a href="/dropped">Dropped</a></li>
|
<li class="<?= is_selected('/dropped', $route_path) ?>"><a href="/dropped">Dropped</a></li>
|
||||||
<li class="<?= is_selected('/completed', $route_path) ?>"><a href="/completed">Completed</a></li>
|
<li class="<?= is_selected('/completed', $route_path) ?>"><a href="/completed">Completed</a></li>
|
||||||
|
<?php /*<li class="<?= is_selected('/collection', $route_path) ?>"><a href="/collection">Collection</a></li> */ ?>
|
||||||
<li class="<?= is_selected('/all', $route_path) ?>"><a href="/all">All</a></li>
|
<li class="<?= is_selected('/all', $route_path) ?>"><a href="/all">All</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
@ -2,6 +2,7 @@
|
|||||||
"require": {
|
"require": {
|
||||||
"guzzlehttp/guzzle": "5.3.*",
|
"guzzlehttp/guzzle": "5.3.*",
|
||||||
"filp/whoops": "1.1.*",
|
"filp/whoops": "1.1.*",
|
||||||
"aura/router": "2.2.*"
|
"aura/router": "2.2.*",
|
||||||
|
"aviat4ion/query": "2.0.*"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -13,6 +13,8 @@ function is_selected($a, $b)
|
|||||||
return ($a === $b) ? 'selected' : '';
|
return ($a === $b) ? 'selected' : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$config = require_once(__DIR__ . '/app/config/config.php');
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Setup error handling
|
// Setup error handling
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
@ -34,7 +36,7 @@ $whoops->register();
|
|||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
$router = new Router();
|
$router = new Router();
|
||||||
$defaultHandler->addDataTable('route', (array)$router->get_route());
|
//$defaultHandler->addDataTable('route', (array)$router->get_route());
|
||||||
$router->dispatch();
|
$router->dispatch();
|
||||||
|
|
||||||
// End of index.php
|
// End of index.php
|
Loading…
Reference in New Issue
Block a user