Skip to content

Commit

Permalink
Feature: implement caching Github avatar's [closes #39]
Browse files Browse the repository at this point in the history
  • Loading branch information
f3l1x committed Feb 14, 2016
1 parent f1be068 commit 36a5de5
Show file tree
Hide file tree
Showing 11 changed files with 163 additions and 4 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
/www/assets/css/*.css
/www/dist

# Front-end
/www/imgs

# Composer
/vendor/*
/composer.lock
Expand Down
3 changes: 3 additions & 0 deletions app/config/app/model.neon
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ services:
# [back-end]
- App\Model\Facade\Admin\AddonFacade

# Images ===============================================
- App\Model\WebImages\GithubImages(%wwwDir%/imgs)

# Tasks ================================================
- App\Model\Tasks\Addons\GenerateContentTask
- App\Model\Tasks\Addons\UpdateGithubTask
Expand Down
9 changes: 9 additions & 0 deletions app/model/exceptions/logic/InvalidArgumentException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

namespace App\Model\Exceptions\Runtime;

use App\Model\Exceptions\LogicException;

class InvalidArgumentException extends LogicException
{
}
16 changes: 16 additions & 0 deletions app/model/routing/RouterFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,22 @@ protected function createWeb()
$front[] = new Route('search/', 'List:search');
$front[] = new Route('search/<tag>', 'List:tag');
$front[] = new Route('status/', 'Status:default');

// FRONT.IMAGES ====================================
$front[] = new Route('imgs/<action>/<owner [\w\-\/]+>.[!<ext=png>]', [
'presenter' => 'WebImage',
'action' => 'default',
'owner' => [
Route::FILTER_OUT => function ($owner) {
return strtolower($owner);
},
Route::FILTER_IN => function ($owner) {
return strtolower($owner);
}
]
]);

// COMMON SCHEME
$front[] = new Route('<presenter>/<action>', 'Home:default');

return $router;
Expand Down
87 changes: 87 additions & 0 deletions app/model/webimages/GithubImages.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<?php

namespace App\Model\WebImages;

use App\Model\Exceptions\Runtime\InvalidArgumentException;
use Nette\Utils\FileSystem;
use Nette\Utils\Image;

final class GithubImages implements ImageProvider
{

// Github URL's
const URL_AVATAR = 'https://github.com/%s';

/** @var string */
private $imageDir;

/**
* @param string $imageDir
*/
public function __construct($imageDir)
{
$this->imageDir = $imageDir;
FileSystem::createDir($imageDir);
}

/**
* FACTORIES ***************************************************************
*/

/**
* @param string $owner
*/
protected function createAvatar($owner)
{
$image = @file_get_contents(sprintf(self::URL_AVATAR, $owner));
if ($image) {
// Save Github avatar to our FS
$filename = $this->imageDir . '/avatar/' . $owner;
FileSystem::write($filename, $image);

// Send image for first request
$image = Image::fromFile($filename);
$image->send(Image::PNG);
exit;
}

}

/**
* API *********************************************************************
*/

/**
* @param array $args
*/
public function create(array $args)
{
if (!isset($args['type'])) {
throw new InvalidArgumentException('No type given');
}

switch ($args['type']) {
case 'avatar':
$this->createAvatar($this->normalize($args['owner']));
break;

default:
throw new InvalidArgumentException('Unknown type "' . $args['type'] . '"given');
}
}

/**
* HELPERS *****************************************************************
* *************************************************************************
*/

/**
* @param string $image
* @return string
*/
private function normalize($image)
{
return strtolower(htmlspecialchars($image));
}

}
13 changes: 13 additions & 0 deletions app/model/webimages/ImageProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace App\Model\WebImages;

interface ImageProvider
{

/**
* @param array $args
*/
public function create(array $args);

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

<div class="title-owner">
<a data-ga="1" data-event="click" data-category="sidebar" data-action="owner-title" data-toggle="tooltip" data-placement="left" title="Show all addons by {$owner}" href="{plink List:owner, slug => $owner}">
<img alt="" title="{$owner}" src="{$addon->github->linker->getOwnerAvatarUrl(40)}"> {$owner}
<img alt="" title="{$owner}" src="{plink WebImage:avatar, $addon->owner}"> {$owner}
</a>
</div>

Expand Down
2 changes: 1 addition & 1 deletion app/modules/front/controls/AddonList/templates/list.latte
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<article class="b-addon__article">
<section class="b-addon__image">
<a href="{plink :Front:Addon:detail, slug => $addon->id}">
<img alt="" title="{$addon->owner}" src="{$addon->github->linker->getOwnerAvatarUrl(60)}">
<img alt="" title="{$addon->owner}" src="{plink WebImage:avatar, $addon->owner}">
</a>
</section>
<section class="b-addon__body">
Expand Down
2 changes: 1 addition & 1 deletion app/modules/front/controls/AddonMeta/templates/full.latte
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<section class="meta">
<a href="{$addon->github->linker->getOwnerUrl()}"><img alt="" title="{$addon->owner}" src="{$addon->github->linker->getOwnerAvatarUrl(20)}"></a>
<a href="{$addon->github->linker->getOwnerUrl()}"><img alt="" title="{$addon->owner}" src="{plink WebImage:avatar, $addon->owner}"></a>
<a class="link-author" href="{plink List:owner, slug => $addon->github->owner}">{$addon->github->owner}</a>

<div class="meta-right">
Expand Down
28 changes: 28 additions & 0 deletions app/modules/front/presenters/WebImagePresenter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace App\Modules\Front;

use App\Model\WebImages\GithubImages;
use Nette\Utils\Strings;

final class WebImagePresenter extends BasePresenter
{

/** @var GithubImages @inject */
public $githubImages;

/**
* Create and send user avatar from Github
*
* @param string $owner
* @param string $ext
*/
public function actionAvatar($owner, $ext)
{
$this->githubImages->create([
'type' => 'avatar',
'owner' => "$owner.$ext",
]);
}

}
2 changes: 1 addition & 1 deletion www/.htaccess
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
# front controller
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule !\.(pdf|js|ico|gif|jpg|png|css|rar|zip|tar\.gz|map)$ index.php [L]
RewriteRule !\.(pdf|js|ico|css|rar|zip|tar\.gz|map)$ index.php [L]
</IfModule>

# enable gzip compression
Expand Down

0 comments on commit 36a5de5

Please sign in to comment.