Bit of a style update

This commit is contained in:
Timothy Warren 2015-06-17 08:50:01 -04:00
parent 38a2b470c5
commit 401c21e98f
13 changed files with 195 additions and 74 deletions

View File

@ -44,17 +44,5 @@ class BaseApiModel extends BaseModel {
]
]);
}
/**
* Get the full url path, since the base_url in Guzzle doesn't work correctly
*
* @param string $path
* @return string
*/
protected function _url($path)
{
return "{$this->base_url}{$path}";
}
}
// End of BaseApiModel.php

View File

@ -97,5 +97,16 @@ class BaseController {
header("Location: {$url}");
die();
}
/**
* Clear the api session
*
* @return void
*/
public function logout()
{
session_destroy();
$this->redirect('');
}
}
// End of BaseController.php

View File

@ -90,8 +90,7 @@ class Router {
}
else
{
$controller_name = $route->params['controller'];
$action_method = $route->params['action'];
list($controller_name, $action_method) = $route->params['action'];
$params = (isset($route->params['params'])) ? $route->params['params'] : [];
if ( ! empty($route->tokens))
@ -133,7 +132,7 @@ class Router {
$routes = $this->config->routes;
// Add routes by the configuration file
// Add routes for the current controller
foreach($routes[$route_type] as $name => $route)
{
$path = $route['path'];
@ -153,6 +152,21 @@ class Router {
->addTokens($tokens);
}
}
// Add routes by required http verb
foreach(['get', 'post'] as $verb)
{
$add = "add" . ucfirst($verb);
foreach($routes[$verb] as $name => $route)
{
$path = $route['path'];
unset($route['path']);
$this->router->$add($name, $path)
->addValues($route);
}
}
}
}
// End of Router.php

View File

@ -4,8 +4,7 @@ return [
'anime' => [
'index' => [
'path' => '/',
'controller' => 'AnimeController',
'action' => 'redirect',
'action' => ['AnimeController', 'redirect'],
'params' => [
'url' => '', // Determined by config
'code' => '301'
@ -13,8 +12,7 @@ return [
],
'all' => [
'path' => '/all{/view}',
'controller' => 'AnimeController',
'action' => 'anime_list',
'action' => ['AnimeController', 'anime_list'],
'params' => [
'type' => 'all',
'title' => WHOSE . " Anime List · All"
@ -25,8 +23,7 @@ return [
],
'watching' => [
'path' => '/watching{/view}',
'controller' => 'AnimeController',
'action' => 'anime_list',
'action' => ['AnimeController', 'anime_list'],
'params' => [
'type' => 'currently-watching',
'title' => WHOSE . " Anime List · Watching"
@ -37,8 +34,7 @@ return [
],
'plan_to_watch' => [
'path' => '/plan_to_watch{/view}',
'controller' => 'AnimeController',
'action' => 'anime_list',
'action' => ['AnimeController', 'anime_list'],
'params' => [
'type' => 'plan-to-watch',
'title' => WHOSE . " Anime List · Plan to Watch"
@ -49,8 +45,7 @@ return [
],
'on_hold' => [
'path' => '/on_hold{/view}',
'controller' => 'AnimeController',
'action' => 'anime_list',
'action' => ['AnimeController', 'anime_list'],
'params' => [
'type' => 'on-hold',
'title' => WHOSE . " Anime List · On Hold"
@ -61,8 +56,7 @@ return [
],
'dropped' => [
'path' => '/dropped{/view}',
'controller' => 'AnimeController',
'action' => 'anime_list',
'action' => ['AnimeController', 'anime_list'],
'params' => [
'type' => 'dropped',
'title' => WHOSE . " Anime List · Dropped"
@ -73,8 +67,7 @@ return [
],
'completed' => [
'path' => '/completed{/view}',
'controller' => 'AnimeController',
'action' => 'anime_list',
'action' => ['AnimeController', 'anime_list'],
'params' => [
'type' => 'completed',
'title' => WHOSE . " Anime List · Completed"
@ -85,8 +78,7 @@ return [
],
'collection' => [
'path' => '/collection{/view}',
'controller' => 'AnimeController',
'action' => 'collection',
'action' => ['AnimeController', 'collection'],
'params' => [],
'tokens' => [
'view' => '[a-z_]+'
@ -96,8 +88,7 @@ return [
'manga' => [
'index' => [
'path' => '/',
'controller' => 'MangaController',
'action' => 'redirect',
'action' => ['MangaController', 'redirect'],
'params' => [
'url' => '', // Determined by config
'code' => '301',
@ -106,8 +97,7 @@ return [
],
'all' => [
'path' => '/all{/view}',
'controller' => 'MangaController',
'action' => 'manga_list',
'action' => ['MangaController', 'manga_list'],
'params' => [
'type' => 'all',
'title' => WHOSE . " Manga List · All"
@ -118,8 +108,7 @@ return [
],
'reading' => [
'path' => '/reading{/view}',
'controller' => 'MangaController',
'action' => 'manga_list',
'action' => ['MangaController', 'manga_list'],
'params' => [
'type' => 'Reading',
'title' => WHOSE . " Manga List · Reading"
@ -130,8 +119,7 @@ return [
],
'plan_to_read' => [
'path' => '/plan_to_read{/view}',
'controller' => 'MangaController',
'action' => 'manga_list',
'action' => ['MangaController', 'manga_list'],
'params' => [
'type' => 'Plan to Read',
'title' => WHOSE . " Manga List · Plan to Read"
@ -142,8 +130,7 @@ return [
],
'on_hold' => [
'path' => '/on_hold{/view}',
'controller' => 'MangaController',
'action' => 'manga_list',
'action' => ['MangaController', 'manga_list'],
'params' => [
'type' => 'On Hold',
'title' => WHOSE . " Manga List · On Hold"
@ -154,8 +141,7 @@ return [
],
'dropped' => [
'path' => '/dropped{/view}',
'controller' => 'MangaController',
'action' => 'manga_list',
'action' => ['MangaController', 'manga_list'],
'params' => [
'type' => 'Dropped',
'title' => WHOSE . " Manga List · Dropped"
@ -166,8 +152,7 @@ return [
],
'completed' => [
'path' => '/completed{/view}',
'controller' => 'MangaController',
'action' => 'manga_list',
'action' => ['MangaController', 'manga_list'],
'params' => [
'type' => 'Completed',
'title' => WHOSE . " Manga List · Completed"
@ -176,5 +161,22 @@ return [
'view' => '[a-z_]+'
]
],
],
// These routes are limited to a specific HTTP verb
'get' => [
'login_form' => [
'path' => '/login',
'action' => ['AnimeController', 'login'],
],
'logout' => [
'path' => '/logout',
'action' => ['BaseController', 'logout']
]
],
'post' => [
'login_action' => [
'path' => '/login',
'action' => ['AnimeController', 'login_action'],
]
]
];

View File

@ -104,5 +104,30 @@ class AnimeController extends BaseController {
'sections' => $data
]));
}
/**
* Show the login form
*
* @return void
*/
public function login()
{
$this->outputHTML('login', array_merge($this->base_data, [
'title' => 'Api login'
]));
}
/**
* Attempt to log in with the api
*
* @return void
*/
public function login_action()
{
if ($this->model->authenticate($this->config->hummingbird_username, $_POST['password']))
{
$this->redirect('');
}
}
}
// End of AnimeController.php

View File

@ -11,7 +11,7 @@ class AnimeModel extends BaseApiModel {
* The base url for api requests
* @var string $base_url
*/
protected $base_url = "https://hummingbird.me/api/v1";
protected $base_url = "https://hummingbird.me/api/v1/";
/**
* Constructor
@ -21,6 +21,31 @@ class AnimeModel extends BaseApiModel {
parent::__construct();
}
/**
* Attempt login via the api
*
* @param string $username
* @param string $password
* @return bool
*/
public function authenticate($username, $password)
{
$result = $this->client->post('users/authenticate', [
'form_params' => [
'username' => $this->config->hummingbird_username,
'password' => $password
]
]);
if ($response->getStatusCode() === 201)
{
$_SESSION['hummingbird_anime_token'] = $response->json();
return TRUE;
}
return FALSE;
}
/**
* Get the full set of anime lists
*
@ -111,9 +136,9 @@ class AnimeModel extends BaseApiModel {
$cache_file = "{$this->config->data_cache_path}/anime-{$status}.json";
$config = [
'query' => [
/*'query' => [
'username' => $this->config->hummingbird_username,
],
],*/
'allow_redirects' => false
];
@ -122,7 +147,7 @@ class AnimeModel extends BaseApiModel {
$config['query']['status'] = $status;
}
$response = $this->client->get($this->_url('/users/' . $this->config->hummingbird_username . '/library'), $config);
$response = $this->client->get("users/{$this->config->hummingbird_username}/library", $config);
$defaultHandler->addDataTable('anime_list_response', (array)$response);
@ -171,7 +196,7 @@ class AnimeModel extends BaseApiModel {
]
];
$response = $this->client->get($this->_url("/anime/{$anime_id}"), $config);
$response = $this->client->get("anime/{$anime_id}", $config);
return $response->json();
}
@ -192,7 +217,7 @@ class AnimeModel extends BaseApiModel {
]
];
$response = $this->client->get($this->_url('/search/anime'), $config);
$response = $this->client->get('search/anime', $config);
$defaultHandler->addDataTable('anime_search_response', (array)$response);
if ($response->getStatusCode() != 200)

View File

@ -11,7 +11,7 @@ class MangaModel extends BaseApiModel {
/**
* @var string $base_url - The base url for api requests
*/
protected $base_url = "https://hummingbird.me";
protected $base_url = "https://hummingbird.me/";
/**
* Constructor
@ -72,7 +72,7 @@ class MangaModel extends BaseApiModel {
'allow_redirects' => false
];
$response = $this->client->get($this->_url('/manga_library_entries'), $config);
$response = $this->client->get('manga_library_entries', $config);
$defaultHandler->addDataTable('response', (array)$response);

View File

@ -11,13 +11,14 @@
<?= $item['title'] ?>
<?= ($item['alternate_title'] != "") ? "<br />({$item['alternate_title']})" : ""; ?>
</div>
<div class="media_metadata">
<div class="completion">Episodes: <?= $item['episode_count'] ?></div>
</div>
<div class="medium_metadata">
<div class="media_type"><?= $item['show_type'] ?></div>
<div class="age_rating"><?= $item['age_rating'] ?></div>
<div class="table">
<div class="row">
<div class="completion">Episodes: <?= $item['episode_count'] ?></div>
<div class="media_type"><?= $item['show_type'] ?></div>
<div class="age_rating"><?= $item['age_rating'] ?></div>
</div>
</div>
</article>
</a>
<?php endforeach ?>

View File

View File

@ -6,19 +6,21 @@
<?php foreach($items as $item): ?>
<a href="<?= $item['anime']['url'] ?>">
<article class="media" id="a-<?= $item['anime']['id'] ?>">
<img class="round_all" src="<?= $item['anime']['cover_image'] ?>" />
<div class="round_all name">
<img src="<?= $item['anime']['cover_image'] ?>" />
<div class="name">
<?= $item['anime']['title'] ?>
<?= ($item['anime']['alternate_title'] != "") ? "<br />({$item['anime']['alternate_title']})" : ""; ?>
</div>
<div class="media_metadata">
<div class="round_top airing_status"><?= $item['anime']['status'] ?></div>
<div class="user_rating"><?= (int)($item['rating']['value'] * 2) ?> / 10</div>
<div class="round_bottom completion">Episodes: <?= $item['episodes_watched'] ?> / <?= $item['anime']['episode_count'] ?></div>
</div>
<div class="medium_metadata">
<div class="round_top media_type"><?= $item['anime']['show_type'] ?></div>
<div class="round_bottom age_rating"><?= $item['anime']['age_rating'] ?></div>
<div class="table">
<div class="row">
<div class="user_rating">Rating: <?= (int)($item['rating']['value'] * 2) ?> / 10</div>
<div class="completion">Episodes: <?= $item['episodes_watched'] ?>&nbsp;/&nbsp;<?= ($item['anime']['episode_count'] != 0) ? $item['anime']['episode_count'] : "-" ?></div>
</div>
<div class="row">
<div class="media_type"><?= $item['anime']['show_type'] ?></div>
<div class="airing_status"><?= $item['anime']['status'] ?></div>
<div class="age_rating"><?= $item['anime']['age_rating'] ?></div>
</div>
</div>
</article>
</a>

View File

@ -0,0 +1,16 @@
<main>
<aside>
<form method="post" action="<?= full_url('/login', $url_type) ?>">
<dl>
<dt><label for="username">Username: </label></dt>
<dd><input type="text" id="username" name="username" required="required" /></dd>
<dt><label for="password">Password: </label></dt>
<dd><input type="password" id="password" name="password" required="required" /></dd>
<dt>&nbsp;</dt>
<dd><input type="submit" value="Login" /></dd>
</dl>
</form>
</aside>
</main>

View File

@ -12,7 +12,7 @@
<?= (isset($item['manga']['english_title'])) ? "<br />({$item['manga']['english_title']})" : ""; ?>
</div>
<div class="media_metadata">
<div class="user_rating"><?= ($item['rating'] > 0) ? (int)($item['rating'] * 2) : '-' ?> / 10</div>
<div class="user_rating">Rating: <?= ($item['rating'] > 0) ? (int)($item['rating'] * 2) : '-' ?> / 10</div>
<div class="completion">
Chapters: <?= $item['chapters_read'] ?> / <?= ($item['manga']['chapter_count'] > 0) ? $item['manga']['chapter_count'] : "-" ?><?php /*<br />
Volumes: <?= $item['volumes_read'] ?> / <?= ($item['manga']['volume_count'] > 0) ? $item['manga']['volume_count'] : "-" ?>*/ ?>

View File

@ -50,6 +50,8 @@ tbody > tr:nth-child(odd) {
margin:0.25em;
}
.name, .media_type, .airing_status, .user_rating, .completion, .age_rating {
text-shadow: 1px 2px 1px rgba(0, 0, 0, 0.85);
background: rgba(0, 0, 0, 0.45);
@ -81,9 +83,10 @@ tbody > tr:nth-child(odd) {
.media:hover > .name,
.media:hover > .media_metadata > div,
.media:hover > .medium_metadata > div
.media:hover > .medium_metadata > div,
.media:hover > .table .row
{
background:rgba(0,0,0,0.9);
background:rgba(0,0,0,0.75);
}
.media > .name > a {
@ -93,8 +96,42 @@ tbody > tr:nth-child(odd) {
text-shadow: 1px 2px 1px rgba(0, 0, 0, 0.85);
}
.user_rating::before {
content: "Rating: ";
/* -----------------------------------------------------------------------------
Anime-list-specific styles
------------------------------------------------------------------------------*/
.anime .name {width:100%;}
.anime .media_type,
.anime .airing_status,
.anime .user_rating,
.anime .completion,
.anime .age_rating {
background: none;
text-align:center;
}
.anime .table {
position:absolute;
bottom:0;
left:0;
width:100%;
}
.anime .row {
width:100%;
background: rgba(0, 0, 0, 0.45);
display:table;
text-align:center;
padding:0 inherit;
}
.anime .row > div {
font-size:0.8em;
display:table-cell;
text-align:center;
vertical-align:middle;
}
/* -----------------------------------------------------------------------------