vlw.se/endpoints/about/languages/POST.php
Victor Westerlund 56cf142e0d refactor: major refactor, design overhaul and merge of Reflect API and Vegvisir sources into the same root (#23)
The PR is a huge refactor of all Reflect and Vegvisir code. I've merged the API and "Front-end" codebases together into the same root, this will allow for both Reflect and Vegvisir to use the same resources. Not only that, but I've also added proper database modeling with actual OOP inheritance for database tables.

Reviewed-on: https://codeberg.org/vlw/vlw.se/pulls/23
2025-02-05 04:49:23 +00:00

102 lines
No EOL
3 KiB
PHP

<?php
use ReflectRules\Ruleset;
use Reflect\{Response, Path, Call};
use VLW\API\Endpoints;
use VLW\Database\Database;
use VLW\Database\Tables\About\LanguagesTable;
use const VLW\{FORGEJO_ENDPOINT_USER, FORGEJO_ENDPOINT_SEARCH};
require_once Path::root("src/Consts.php");
require_once Path::root("src/API/Endpoints.php");
require_once Path::root("src/Database/Tables/About/Languages.php");
class POST_AboutLanguages extends Database {
protected readonly Ruleset $ruleset;
// Tally of all languages used in all configured repositories
private array $languages = [];
public function __construct() {
$this->ruleset = new Ruleset(strict: true);
$this->ruleset->validate_or_exit();
parent::__construct();
}
// Fetch JSON from URL
private static function fetch_json(string $url): array {
return json_decode(file_get_contents($url), true);
}
// Fetch JSON from a Forgejo endpoint
private static function fetch_endpoint(string $endpoint): array {
$url = $_ENV["server_forgejo"]["base_url"] . $endpoint;
return self::fetch_json($url);
}
// Write $this->languages to a JSON file
private function cache_languages(): void {
// Delete existing cache
(new Call(Endpoints::ABOUT_LANGUAGES->value))->delete();
$this->db->for(LanguagesTable::NAME);
foreach ($this->languages as $language => $bytes) {
$this->db->insert([
LanguagesTable::ID->value => $language,
LanguagesTable::BYTES->value => $bytes
]);
}
}
// Fetch and add languages to total from a fully-qualified Forgejo URL
private function add_repository_languages(string $url): void {
foreach(self::fetch_json($url) as $language => $bytes) {
// Create key for language if it doesn't exist
if (!array_key_exists($language, $this->languages)) {
$this->languages[$language] = 0;
}
// Add bytes to language in total
$this->languages[$language] += $bytes;
}
}
// Tally languages from public repositories for user id
private function add_public_repositores(int $uid): bool {
$resp = self::fetch_endpoint(sprintf(FORGEJO_ENDPOINT_SEARCH, $uid));
// Bail out if request failed or if response indicated a problem
if (!$resp or $resp["ok"] === false) {
return false;
}
// Add langauges for each public repository
foreach ($resp["data"] as $repo) {
$this->add_repository_languages($repo["languages_url"]);
}
return true;
}
// Add languages from all public repositories for profiles in config
private function add_repositories_from_config_profiles(): void {
foreach(explode(",", $_ENV["server_forgejo"]["scan_profiles"]) as $profile) {
// Resolve user data from username
$user = self::fetch_endpoint(sprintf(FORGEJO_ENDPOINT_USER, $profile));
$this->add_public_repositores($user["id"]);
}
}
public function main(): Response {
$this->add_repositories_from_config_profiles();
// Sort langauges bytes tally by largest in descending order
arsort($this->languages);
$this->cache_languages();
return new Response($this->languages);
}
}