Skip to content

Commit b5e406b

Browse files
committed
Feature: cleaning avatars over CLI
1 parent 9db3773 commit b5e406b

File tree

7 files changed

+206
-16
lines changed

7 files changed

+206
-16
lines changed

app/config/app/model.neon

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,4 @@ services:
3535
- App\Model\Tasks\Addons\UpdateComposerTask
3636
- App\Model\Tasks\Addons\UpdateBowerTask
3737
- App\Model\Tasks\Addons\StatsComposerTask
38+
- App\Model\Tasks\Avatars\UpdateAvatarTask
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
namespace App\Model\Tasks\Avatars;
4+
5+
use App\Model\ORM\Addon\AddonRepository;
6+
use App\Model\Tasks\BaseTask;
7+
8+
abstract class BaseAvatarTask extends BaseTask
9+
{
10+
11+
/** @var AddonRepository */
12+
protected $addonRepository;
13+
14+
/**
15+
* @param AddonRepository $addonRepository
16+
*/
17+
public function __construct(AddonRepository $addonRepository)
18+
{
19+
$this->addonRepository = $addonRepository;
20+
}
21+
22+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
3+
namespace App\Model\Tasks\Avatars;
4+
5+
use App\Model\ORM\Addon\Addon;
6+
use App\Model\ORM\Addon\AddonRepository;
7+
use App\Model\WebImages\GithubImages;
8+
use App\Model\WebServices\Github\Service;
9+
use Nette\Utils\DateTime;
10+
use Nextras\Orm\Collection\ICollection;
11+
12+
final class UpdateAvatarTask extends BaseAvatarTask
13+
{
14+
15+
/** @var Service */
16+
private $github;
17+
18+
/** @var GithubImages */
19+
private $githubImages;
20+
21+
/**
22+
* @param AddonRepository $addonRepository
23+
* @param Service $github
24+
* @param GithubImages $githubImages
25+
*/
26+
public function __construct(AddonRepository $addonRepository, Service $github, GithubImages $githubImages)
27+
{
28+
parent::__construct($addonRepository);
29+
$this->github = $github;
30+
$this->githubImages = $githubImages;
31+
}
32+
33+
/**
34+
* @param array $args
35+
* @return int
36+
*/
37+
public function run(array $args = [])
38+
{
39+
/** @var ICollection|Addon[] $addons */
40+
$addons = $this->addonRepository->findActive();
41+
42+
$counter = 0;
43+
foreach ($addons as $addon) {
44+
45+
// User avatar
46+
$response = $this->github->avatar($addon->owner);
47+
list ($info, $avatar) = $response;
48+
49+
// If avatar was update before less then a week, remove it from filesystem
50+
if (DateTime::from($info['filetime']) > DateTime::from('- 1 week')) {
51+
$this->githubImages->remove(['type' => 'avatar', 'owner' => $addon->owner]);
52+
53+
// Increase counting
54+
$counter++;
55+
}
56+
}
57+
58+
return $counter;
59+
}
60+
61+
}

app/model/webimages/GithubImages.php

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public function __construct($imageDir)
2525
}
2626

2727
/**
28-
* FACTORIES ***************************************************************
28+
* AVATAR ******************************************************************
2929
*/
3030

3131
/**
@@ -48,6 +48,14 @@ protected function createAvatar($owner)
4848
}
4949
}
5050

51+
/**
52+
* @param string $owner
53+
*/
54+
protected function removeAvatar($owner)
55+
{
56+
FileSystem::delete($this->imageDir . '/avatar/' . $owner);
57+
}
58+
5159
/**
5260
* API *********************************************************************
5361
*/
@@ -71,6 +79,25 @@ public function create(array $args)
7179
}
7280
}
7381

82+
/**
83+
* @param array $args
84+
*/
85+
public function remove(array $args)
86+
{
87+
if (!isset($args['type'])) {
88+
throw new InvalidArgumentException('No type given');
89+
}
90+
91+
switch ($args['type']) {
92+
case 'avatar':
93+
$this->removeAvatar($this->normalize($args['owner']));
94+
break;
95+
96+
default:
97+
throw new InvalidArgumentException('Unknown type "' . $args['type'] . '"given');
98+
}
99+
}
100+
74101
/**
75102
* HELPERS *****************************************************************
76103
* *************************************************************************

app/model/webservices/github/Client.php

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ final class Client
88
{
99

1010
const VERSION = 'v3';
11-
const URL = 'https://api.github.com';
11+
const URL_API = 'https://api.github.com';
12+
const URL_AVATAR = 'https://avatars.githubusercontent.com';
1213

1314
/** @var string */
1415
private $token;
@@ -23,10 +24,29 @@ public function __construct($token = NULL)
2324

2425
/**
2526
* @param string $uri
27+
* @return string
28+
*/
29+
public function getApiUrl($uri)
30+
{
31+
return self::URL_API . '/' . trim($uri, '/');
32+
}
33+
34+
/**
35+
* @param string $username
36+
* @return string
37+
*/
38+
public function getAvatarUrl($username)
39+
{
40+
return self::URL_AVATAR . '/' . trim($username, '/');
41+
}
42+
43+
/**
44+
* @param string $url
2645
* @param array $headers
27-
* @return mixed (array|NULL)
46+
* @param array $opts
47+
* @return array
2848
*/
29-
public function makeRequest($uri, array $headers = [])
49+
public function makeRequest($url, array $headers = [], array $opts = [])
3050
{
3151
$ch = curl_init();
3252

@@ -39,35 +59,34 @@ public function makeRequest($uri, array $headers = [])
3959
$_headers[] = 'Authorization: token ' . $this->token;
4060
}
4161

42-
$url = self::URL . '/' . trim($uri, '/');
43-
44-
curl_setopt_array($ch, [
62+
$_opts = [
4563
CURLOPT_RETURNTRANSFER => 1,
4664
CURLOPT_URL => $url,
4765
CURLOPT_USERAGENT => 'ComponetteClient-v1',
4866
CURLOPT_HTTPHEADER => $_headers,
4967
CURLOPT_FOLLOWLOCATION => 1,
5068
CURLOPT_SSL_VERIFYPEER => FALSE,
51-
]);
69+
];
70+
curl_setopt_array($ch, $opts + $_opts);
5271

5372
$result = curl_exec($ch);
5473
$info = curl_getinfo($ch);
5574
curl_close($ch);
5675

5776
if ($info['http_code'] > 300) {
58-
throw new GithubException($uri, $headers, [], $info, $result);
77+
throw new GithubException($url, $headers, [], $info, $result);
5978
}
6079

6180
// Pure result
6281
if (strpos($info['content_type'], 'application/json') === FALSE) {
63-
return $result;
82+
return [$info, $result];
6483
}
6584

6685
// Parse result from json
6786
if ($result) {
68-
return @json_decode($result, TRUE);
87+
return [$info, @json_decode($result, TRUE)];
6988
} else {
70-
return NULL;
89+
return [$info, NULL];
7190
}
7291
}
7392

app/model/webservices/github/Service.php

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,15 @@ public function __construct(Client $client)
2222
}
2323

2424
/**
25-
* @param string $uri
25+
* @param string $url
2626
* @param array $headers
27-
* @return mixed
27+
* @param array $opts
28+
* @return array
2829
*/
29-
protected function call($uri, array $headers = [])
30+
protected function makeRequest($url, array $headers = [], array $opts = [])
3031
{
3132
try {
32-
return $this->client->makeRequest($uri, $headers);
33+
return $this->client->makeRequest($url, $headers, $opts);
3334
} catch (GithubException $e) {
3435
// Trigger events
3536
foreach ($this->onException as $cb) {
@@ -41,6 +42,18 @@ protected function call($uri, array $headers = [])
4142
}
4243
}
4344

45+
/**
46+
* @param string $uri
47+
* @param array $headers
48+
* @param array $opts
49+
* @return mixed
50+
*/
51+
protected function call($uri, array $headers = [], array $opts = [])
52+
{
53+
list($info, $result) = $this->makeRequest($this->client->getApiUrl($uri), $headers, $opts);
54+
return $result;
55+
}
56+
4457
/**
4558
* @param string $owner
4659
* @param string $repo
@@ -146,6 +159,28 @@ public function stargazers($owner, $repo)
146159
return $this->call("/repos/$owner/$repo/stargazers");
147160
}
148161

162+
/**
163+
* @param string $owner
164+
* @return mixed
165+
*/
166+
public function user($owner)
167+
{
168+
return $this->call("/users/$owner");
169+
}
170+
171+
/**
172+
* @param string $username
173+
* @return array
174+
*/
175+
public function avatar($username)
176+
{
177+
return $this->makeRequest(
178+
$this->client->getAvatarUrl($username),
179+
[],
180+
[CURLOPT_FILETIME => TRUE, CURLOPT_NOBODY => TRUE]
181+
);
182+
}
183+
149184
/**
150185
* @return mixed
151186
*/
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
namespace App\Modules\Cli;
4+
5+
use App\Model\Tasks\Avatars\UpdateAvatarTask;
6+
7+
final class AvatarsPresenter extends BasePresenter
8+
{
9+
10+
/** @var UpdateAvatarTask @inject */
11+
public $updateAvatarTask;
12+
13+
public function actionUpdate()
14+
{
15+
$this->output->outln('Avatars:update');
16+
17+
$this->output->outln('* running [UpdateAvatar]');
18+
$res = $this->updateAvatarTask->run($this->getParameters());
19+
$this->output->outln('* result [UpdateAvatar](' . $res . ')');
20+
21+
$this->finish();
22+
}
23+
24+
25+
}

0 commit comments

Comments
 (0)