More caching, and start of anime collection view

This commit is contained in:
Timothy Warren 2015-06-09 18:18:53 -04:00
parent 86663d2179
commit 7c913986d4
16 changed files with 195 additions and 58 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
vendor
app/cache/*
public/images/*
composer.lock

BIN
anime_collection.sqlite Executable file

Binary file not shown.

View File

@ -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()
{
} }
/** /**

View File

@ -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
View 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
View File

@ -0,0 +1,13 @@
<?php
return [
'collection' => [
'type' => 'sqlite',
'host' => '',
'user' => '',
'pass' => '',
'port' => '',
'name' => 'default',
'database' => '',
'file' => __DIR__ . '/../../anime_collection.sqlite',
]
];

View File

@ -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',

View File

@ -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();

View File

@ -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');

View 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

View File

@ -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)
{ {
throw new Exception($response->getEffectiveUrl()); if ( ! file_exists($cache_file))
{
throw new Exception($response->getEffectiveUrl());
}
else
{
$output = json_decode(file_get_contents($cache_file), TRUE);
}
}
else
{
$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));
}
} }
$output = $response->json();
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();

View File

@ -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
]; ];
@ -63,11 +71,23 @@ class MangaModel extends BaseModel {
if ($response->getStatusCode() != 200) if ($response->getStatusCode() != 200)
{ {
throw new Exception($response->getEffectiveUrl()); if ( ! file_exists($cache_file))
{
throw new Exception($response->getEffectiveUrl());
}
else
{
$raw_data = json_decode(file_get_contents($cache_file), TRUE);
}
} }
else
{
// Reorganize data to be more usable
$raw_data = $response->json();
// Reorganize data to be more usable // Cache data in case of downtime
$raw_data = $response->json(); file_put_contents($cache_file, json_encode($raw_data));
}
$data = [ $data = [
'Reading' => [], 'Reading' => [],
@ -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();

View File

View 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>

View File

@ -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.*"
} }
} }

View File

@ -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