Skip to content

Commit 2c0b0df

Browse files
authored
feat: add command and schedule to save oldest and starred repositories (#17)
1 parent 2ec3d8f commit 2c0b0df

10 files changed

Lines changed: 214 additions & 22 deletions

File tree

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
3+
namespace App\Console\Commands;
4+
5+
use App\Models\FrozenRepository;
6+
use App\Models\GithubApi;
7+
use Illuminate\Console\Command;
8+
use Illuminate\Support\Carbon;
9+
10+
class FroozeRepositories extends Command {
11+
/**
12+
* The name and signature of the console command.
13+
*
14+
* @var string
15+
*/
16+
protected $signature = 'app:frooze-repositories';
17+
18+
/**
19+
* The console command description.
20+
*
21+
* @var string
22+
*/
23+
protected $description = 'Load and frooze oldest and starred repositories';
24+
25+
/**
26+
* Execute the console command.
27+
*/
28+
public function handle() {
29+
$client = new GithubApi();
30+
$repositories = $client->getOldestStarredRepositories();
31+
32+
FrozenRepository::truncate();
33+
34+
FrozenRepository::insert(
35+
array_map(
36+
function ($rep) {
37+
return array(
38+
'created_at' => Carbon::now(),
39+
'name' => $rep->name,
40+
'githubId' => $rep->id,
41+
'fullName' => $rep->fullName,
42+
'description' => $rep->description,
43+
'url' => $rep->url,
44+
'githubCreatedAt' => $rep->createdAt,
45+
'githubUpdatedAt' => $rep->updatedAt,
46+
'language' => $rep->language,
47+
'topics' => json_encode($rep->topics),
48+
'watchers' => $rep->watchers,
49+
'forks' => $rep->forks,
50+
'stars' => $rep->stars,
51+
'ownerIsOrganization' => $rep->ownerIsOrganization,
52+
'ownerLogin' => $rep->owner->login,
53+
'ownerGithubId' => $rep->owner->id,
54+
'ownerAvatarUrl' => $rep->owner->avatarUrl,
55+
'year' => $rep->createdAt->format('Y'),
56+
);
57+
}, $repositories)
58+
);
59+
}
60+
}

app/Console/Commands/LoadProLang.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@ private function getLanguages(int $page) {
121121
* Execute the console command.
122122
*/
123123
public function handle() {
124+
Log::info('action=load_prolang_command, status=started');
125+
124126
$this->getLanguages(1);
127+
128+
Log::info('action=load_prolang_command, status=finished');
125129
}
126130
}

app/Console/Commands/ProLangAssets.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use App\Models\ProLang;
77
use Illuminate\Console\Command;
88
use Illuminate\Support\Facades\Http;
9+
use Illuminate\Support\Facades\Log;
910

1011
class ProLangAssets extends Command {
1112
/**
@@ -42,6 +43,8 @@ private function getWikiImageSrc(string $authorLink) {
4243
* Execute the console command.
4344
*/
4445
public function handle() {
46+
Log::info('action=prolang_assets_command, status=started');
47+
4548
LangAuthor::whereNotNull('link')->each(
4649
function ($author) {
4750
$img = $this->getWikiImageSrc($author->link);
@@ -61,5 +64,7 @@ function ($lang) {
6164
);
6265
}
6366
);
67+
68+
Log::info('action=prolang_assets_command, status=finished');
6469
}
6570
}

app/Http/Controllers/MainController.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace App\Http\Controllers;
44

5+
use App\Models\FrozenRepository;
56
use App\Models\GithubApi;
67
use App\Models\ProLang;
78
use App\Models\YearGroup;
@@ -21,13 +22,16 @@ public function __construct() {
2122
* Homepage show oldest and starred repositories
2223
*/
2324
public function index(): \Inertia\Response {
24-
$repositories = $this->client->getOldestStarredRepositories();
25+
$repositories = FrozenRepository::orderBy('year')
26+
->orderBy('githubCreatedAt', 'asc')
27+
->get()
28+
->groupBy('year')
29+
->toArray();
30+
2531
$allLangs = ProLang::pluck('name')->toArray();
2632

2733
shuffle($allLangs);
2834

29-
Log::info('action=root_index');
30-
3135
return Inertia::render('HomePage', array(
3236
'oldestRepos' => $repositories,
3337
'allLangs' => $allLangs,

app/Models/FrozenRepository.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace App\Models;
4+
5+
use Illuminate\Database\Eloquent\Model;
6+
7+
class FrozenRepository extends Model {
8+
protected $guarded = array('id');
9+
10+
protected $casts = array('topics' => 'array');
11+
12+
protected $appends = array('owner');
13+
14+
protected $hidden = array('ownerLogin', 'ownerGithubId', 'ownerAvatarUrl');
15+
16+
public function getOwnerAttribute() {
17+
return array(
18+
'login' => $this->ownerLogin,
19+
'id' => $this->ownerGithubId,
20+
'avatarUrl' => $this->ownerAvatarUrl,
21+
);
22+
}
23+
}

app/Models/GithubApi.php

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,12 @@
1616

1717
class GithubApi extends ApiClient {
1818
/**
19-
* @return array<int, GithubRepository[]>
19+
* @return GithubRepository[]
2020
*/
2121
public function getOldestStarredRepositories(): array {
2222
$repositories = GithubRepositoryApi::get()->getOldestStarredRepositories();
23-
$years = array();
2423

25-
foreach ($repositories as $key => $item) {
26-
$year = $item->createdAt->format('Y');
27-
$needKey = array_key_exists($year, $years) === false;
28-
29-
if ($needKey) {
30-
$years[$year] = array();
31-
}
32-
33-
array_push($years[$year], $item);
34-
}
35-
36-
return $years;
24+
return $repositories;
3725
}
3826

3927
public function getOldestRepository(string $lang) {

app/Models/LangAuthor.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@
55
use Illuminate\Database\Eloquent\Model;
66
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
77

8+
/**
9+
* @property int $id
10+
* @property \Illuminate\Support\Carbon|null $created_at
11+
* @property \Illuminate\Support\Carbon|null $updated_at
12+
* @property string $name
13+
* @property string|null $pictureUrl
14+
* @property string|null $country
15+
* @property string|null $link
16+
*/
817
class LangAuthor extends Model {
918
protected $guarded = array('id');
1019

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Support\Facades\Schema;
6+
7+
return new class extends Migration {
8+
/**
9+
* Run the migrations.
10+
*/
11+
public function up(): void {
12+
Schema::create('frozen_repositories', function (Blueprint $table) {
13+
$table->id();
14+
$table->timestamps();
15+
$table->string('githubId');
16+
$table->string('name');
17+
$table->string('fullName');
18+
$table->longText('description')->nullable();
19+
$table->string('url');
20+
$table->dateTime('githubCreatedAt');
21+
$table->dateTime('githubUpdatedAt');
22+
$table->string('language')->nullable();
23+
$table->json('topics');
24+
$table->unsignedInteger('watchers');
25+
$table->unsignedInteger('forks');
26+
$table->unsignedInteger('stars');
27+
$table->boolean('ownerIsOrganization');
28+
$table->string('ownerLogin');
29+
$table->string('ownerGithubId');
30+
$table->string('ownerAvatarUrl');
31+
$table->string('year');
32+
});
33+
}
34+
35+
/**
36+
* Reverse the migrations.
37+
*/
38+
public function down(): void {
39+
Schema::dropIfExists('frozen_repositories');
40+
}
41+
};

routes/console.php

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
<?php
22

3-
// use Illuminate\Foundation\Inspiring;
4-
// use Illuminate\Support\Facades\Artisan;
3+
use App\Console\Commands\FroozeRepositories;
4+
use App\Console\Commands\LoadProLang;
5+
use App\Console\Commands\ProLangAssets;
6+
use Illuminate\Support\Facades\Schedule;
57

6-
// Artisan::command('inspire', function () {
7-
// $this->comment(Inspiring::quote());
8-
// })->purpose('Display an inspiring quote');
8+
Schedule::command(LoadProLang::class)->monthly();
9+
Schedule::command(ProLangAssets::class)->monthly();
10+
Schedule::command(FroozeRepositories::class)->monthly();
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
use App\Console\Commands\FroozeRepositories;
4+
use App\Models\FrozenRepository;
5+
use Illuminate\Support\Carbon;
6+
use Illuminate\Support\Facades\Http;
7+
8+
describe('FroozeRepositories', function () {
9+
it('should save repositories', function (array $repos) {
10+
Http::fake(array(
11+
'https://api.github.com/search/repositories*' => Http::response(
12+
array(
13+
'items' => $repos,
14+
),
15+
200,
16+
),
17+
));
18+
19+
FrozenRepository::insert(array(
20+
'created_at' => Carbon::now(),
21+
'name' => 'remove-me',
22+
'githubId' => '',
23+
'fullName' => 'remove-me',
24+
'description' => '',
25+
'url' => '',
26+
'githubCreatedAt' => Carbon::now(),
27+
'githubUpdatedAt' => Carbon::now(),
28+
'language' => '',
29+
'topics' => '[]',
30+
'watchers' => 1,
31+
'forks' => 2,
32+
'stars' => 69,
33+
'ownerIsOrganization' => false,
34+
'ownerLogin' => '',
35+
'ownerGithubId' => '',
36+
'ownerAvatarUrl' => '',
37+
'year' => '',
38+
));
39+
40+
(new FroozeRepositories())->handle();
41+
42+
expect(
43+
FrozenRepository::where('name', 'remove-me')->first()
44+
)->toBe(null);
45+
expect(
46+
FrozenRepository::all()->count()
47+
)->toBe(count($repos));
48+
expect(
49+
FrozenRepository::where('name', 'beat.time')->first()
50+
)->toMatchArray(array(
51+
'name' => 'beat.time',
52+
'year' => 2019,
53+
'ownerIsOrganization' => false,
54+
));
55+
})->with('github-repos');
56+
});

0 commit comments

Comments
 (0)