mirror of
https://codeberg.org/vlw/vlw.se.git
synced 2025-09-13 21:13:40 +02:00
feat: add coffee stats to about page
This commit is contained in:
parent
c2596a0681
commit
ded2ea4f5f
11 changed files with 273 additions and 4 deletions
38
endpoints/coffee/GET.php
Normal file
38
endpoints/coffee/GET.php
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
use vlw\MySQL\Order;
|
||||
use Reflect\{Response, Path, Call};
|
||||
use ReflectRules\{Ruleset, Rules, Type};
|
||||
|
||||
use VLW\API\Endpoints;
|
||||
use VLW\Database\Database;
|
||||
use VLW\Database\Tables\Coffee\CoffeeTable;
|
||||
|
||||
require_once Path::root("src/API/Endpoints.php");
|
||||
require_once Path::root("src/Database/Database.php");
|
||||
require_once Path::root("src/Database/Tables/Coffee/Coffee.php");
|
||||
|
||||
class GET_Coffee extends Database {
|
||||
protected readonly Ruleset $ruleset;
|
||||
|
||||
public function __construct() {
|
||||
$this->ruleset = new Ruleset(strict: true);
|
||||
|
||||
$this->ruleset->GET([
|
||||
(new Rules(CoffeeTable::ID->value))
|
||||
->type(Type::NUMBER)
|
||||
->min(1)
|
||||
->max(parent::SIZE_UINT32)
|
||||
]);
|
||||
|
||||
$this->ruleset->validate_or_exit();
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function main(): Response {
|
||||
return $this->list(CoffeeTable::NAME, CoffeeTable::values(), [
|
||||
CoffeeTable::ID->value => Order::DESC
|
||||
]);
|
||||
}
|
||||
}
|
38
endpoints/coffee/POST.php
Normal file
38
endpoints/coffee/POST.php
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
use Reflect\{Response, Path, Call};
|
||||
use ReflectRules\{Ruleset, Rules, Type};
|
||||
|
||||
use VLW\API\Endpoints;
|
||||
use VLW\Database\Database;
|
||||
use VLW\Database\Tables\Coffee\CoffeeTable;
|
||||
|
||||
require_once Path::root("src/API/Endpoints.php");
|
||||
require_once Path::root("src/Database/Database.php");
|
||||
require_once Path::root("src/Database/Tables/Coffee/Coffee.php");
|
||||
|
||||
class POST_Coffee extends Database {
|
||||
protected Ruleset $ruleset;
|
||||
|
||||
public function __construct() {
|
||||
$this->ruleset = new Ruleset(strict: true);
|
||||
|
||||
$this->ruleset->POST([
|
||||
(new Rules(CoffeeTable::ID->value))
|
||||
->type(Type::NUMBER)
|
||||
->min(1)
|
||||
->max(parent::SIZE_UINT32)
|
||||
->default(time()),
|
||||
]);
|
||||
|
||||
$this->ruleset->validate_or_exit();
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function main(): Response {
|
||||
return $this->db->for(CoffeeTable::NAME)->insert($_POST) === true
|
||||
? new Response(null, 201)
|
||||
: new Response("Database error", 500);
|
||||
}
|
||||
}
|
42
endpoints/coffee/stats/GET.php
Normal file
42
endpoints/coffee/stats/GET.php
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
use vlw\MySQL\Order;
|
||||
use Reflect\{Response, Path, Call};
|
||||
use ReflectRules\{Ruleset, Rules, Type};
|
||||
|
||||
use VLW\API\Endpoints;
|
||||
use VLW\Database\Database;
|
||||
use const VLW\COFFEE_STATS_UPDATE_PARAM;
|
||||
use VLW\Database\Tables\Coffee\StatsTable;
|
||||
|
||||
require_once Path::root("src/Consts.php");
|
||||
require_once Path::root("src/API/Endpoints.php");
|
||||
require_once Path::root("src/Database/Database.php");
|
||||
require_once Path::root("src/Database/Tables/Coffee/Stats.php");
|
||||
|
||||
class GET_CoffeeStats extends Database {
|
||||
protected readonly Ruleset $ruleset;
|
||||
|
||||
public function __construct() {
|
||||
$this->ruleset = new Ruleset(strict: true);
|
||||
|
||||
$this->ruleset->GET([
|
||||
(new Rules(COFFEE_STATS_UPDATE_PARAM))
|
||||
->type(Type::BOOLEAN)
|
||||
->default(false)
|
||||
]);
|
||||
|
||||
$this->ruleset->validate_or_exit();
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function main(): Response {
|
||||
// Freshen cache if update flag is set
|
||||
if ($_GET[COFFEE_STATS_UPDATE_PARAM]) {
|
||||
(new Call(Endpoints::COFFEE_STATS->value))->post();
|
||||
}
|
||||
|
||||
return $this->list(StatsTable::NAME, StatsTable::values());
|
||||
}
|
||||
}
|
35
endpoints/coffee/stats/POST.php
Normal file
35
endpoints/coffee/stats/POST.php
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
use Reflect\{Response, Path, Call};
|
||||
use ReflectRules\{Ruleset, Rules, Type};
|
||||
|
||||
use VLW\API\Endpoints;
|
||||
use VLW\Database\Database;
|
||||
use VLW\Database\Tables\Coffee\{CoffeeTable, StatsTable};
|
||||
|
||||
require_once Path::root("src/API/Endpoints.php");
|
||||
require_once Path::root("src/Database/Database.php");
|
||||
require_once Path::root("src/Database/Tables/Coffee/Stats.php");
|
||||
require_once Path::root("src/Database/Tables/Coffee/Coffee.php");
|
||||
|
||||
class POST_CoffeeStats extends Database {
|
||||
protected Ruleset $ruleset;
|
||||
|
||||
public function __construct() {
|
||||
$this->ruleset = new Ruleset(strict: true);
|
||||
$this->ruleset->validate_or_exit();
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function main(): Response {
|
||||
$truncate = $this->db->execute_query("DELETE FROM `" . StatsTable::NAME . "`");
|
||||
|
||||
// Add a dummy row to run the MariaDB INSERT AFTER Trigger on the coffee database table
|
||||
$insert = $this->db->for(CoffeeTable::NAME)->insert([CoffeeTable::ID->value => 0]);
|
||||
// Remove the dummy row
|
||||
$remove = $this->db->for(CoffeeTable::NAME)->where([CoffeeTable::ID->value => 0])->delete();
|
||||
|
||||
return $truncate && $insert && $remove ? new Response() : new Response("Error", 500);
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
<?php
|
||||
|
||||
use VLW\Database\Models\Coffee\Stats;
|
||||
use VLW\Database\Models\About\Language;
|
||||
use const VLW\{
|
||||
FORGEJO_HREF,
|
||||
|
@ -8,6 +9,7 @@
|
|||
};
|
||||
|
||||
require_once VV::root("src/Consts.php");
|
||||
require_once VV::root("src/Database/Models/Coffee/Stats.php");
|
||||
require_once VV::root("src/Database/Models/About/Language.php");
|
||||
|
||||
$languages = new class extends Language {
|
||||
|
@ -33,7 +35,19 @@
|
|||
|
||||
return round($format) . " " . FORGEJO_SI_BYTE_MULTIPLE[$factor];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$coffee = new class extends Stats {
|
||||
public function week_average_string(): string {
|
||||
$diff = $this->week() - $this->week_average();
|
||||
|
||||
return match (true) {
|
||||
$diff < 1 => "less than",
|
||||
$diff === 1 => "the same as",
|
||||
$diff > 1 => "more than"
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
?>
|
||||
<style><?= VV::css("public/assets/css/pages/about") ?></style>
|
||||
|
@ -44,8 +58,8 @@
|
|||
<hr aria-hidden="true">
|
||||
<section class="about">
|
||||
<p>I​'m a full-stack web developer from Sweden, and welcome to my little personal corner of the Internet!</p>
|
||||
<p>I used to list the <programming/markup/command/whatever>-languages here that I use the most and order them by guesstimating how much I use each one. But then I thought it would be better to just show you instead using this chart that <a href="https://git.vlw.se/config/vlw.se">automatically pulls the total bytes</a> for each language from my public mirrors and sources on <a href="https://git.vlw.se/vlw">Forgejo</a>.</p>
|
||||
<p>Some other noteworthy techologies that I work a decent amount with are: Debian, MariaDB, SQLite, DNS, and probably a few others as well. Check out this page for a comprehensive list of all the tech that I use.</p>
|
||||
<p>I used to list the <programming/markup/command/whatever>-languages here that I use the most and order them by guesstimating how much I use each one. But then I thought it would be better to just show you instead using this chart that automatically pulls the total bytes for each language from my public repos on <a href="https://git.vlw.se/vlw">Forgejo</a>.</p>
|
||||
<p>Some other noteworthy techologies that I work a decent amount with are: Debian, MariaDB, SQLite, DNS, Redis, and probably a few others as well. Check out this page for a comprehensive list of all the tech that I use.</p>
|
||||
</section>
|
||||
<section class="languages">
|
||||
<stacked-bar-chart>
|
||||
|
@ -87,7 +101,7 @@
|
|||
</section>
|
||||
<section class="about">
|
||||
<h2>Personal</h2>
|
||||
<p>One thing is true.. Coffee, lots of coffee. In fact, I've had X cups of coffee in the last 7 days! That's less than my average of X per week, impressive! Even though you just read that.. I don't consider myself <i>too much</i> of a coffee snob! As long as it's dark roast and warm, I'm probably happy to have it.</p>
|
||||
<p>One thing is true.. Coffee, lots of coffee. In fact, I've had <?= $coffee->week() ?> cup<?= $coffee->week() === 1 ? "" : "s" ?> of coffee in the last 7 days! That's <?= $coffee->week_average_string() ?> my average of <?= $coffee->week_average() ?> per week, impressive! Even though you just read that.. I don't consider myself <i>too much</i> of a coffee snob! As long as it's dark roast and warm, I'm probably happy to have it.</p>
|
||||
<p>At times, I become a true, amateur, armchair detective for a <span class="interests">variety of your typical-nerdy topics that I find interesting</span> and you can bet I spend way more time reading about those things than I will ever have use for in life.</p>
|
||||
<p>My coding happens almost exclusivly in <a href="https://github.com/coder/code-server">code-server</a>, which is a fork of VSCode that runs entirely in the browser. I keep my development environment tucked away in a lightweight Debian VA that I can tote around to whatever host machine I happen to work on. If I can't do that for whatever reason, I have my <a href="https://codeberg.org/vlw/dotfiles">dotfiles</a> ready to get things set up the way I like it.</p>
|
||||
<p>Another silent passion of mine that comes out every few years is building computers and fiddling with weird networking stuff.</p>
|
||||
|
|
|
@ -10,9 +10,11 @@
|
|||
|
||||
case WORK = "/work";
|
||||
case SEARCH = "/search";
|
||||
case COFFEE = "/coffee";
|
||||
case MESSAGES = "/messages";
|
||||
case WORK_TAGS = "/work/tags";
|
||||
case WORK_ACTIONS = "/work/actions";
|
||||
case COFFEE_STATS = "/coffee/stats";
|
||||
case WORK_TIMELINE = "/work/timeline";
|
||||
case ABOUT_LANGUAGES = "/about/languages";
|
||||
}
|
|
@ -24,6 +24,12 @@
|
|||
const TIMELINE_PREVIEW_LIMIT_PARAM = "limit";
|
||||
const TIMELINE_PREVIEW_LIMIT_COUNT = 5;
|
||||
|
||||
/**
|
||||
* # Coffee
|
||||
* Constants related to the coffee endpoints
|
||||
*/
|
||||
const COFFEE_STATS_UPDATE_PARAM = "update";
|
||||
|
||||
/**
|
||||
* # Forgejo
|
||||
* Constants related to the fetching and caching of real-time prog. language use on Forgejo
|
||||
|
|
35
src/Database/Models/Coffee/Coffee.php
Normal file
35
src/Database/Models/Coffee/Coffee.php
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace VLW\Database\Models\Coffee;
|
||||
|
||||
use \VV;
|
||||
use \DateTimeImmutable;
|
||||
|
||||
use VLW\API\Endpoints;
|
||||
use VLW\Database\Models\Model;
|
||||
use VLW\Database\Tables\Coffee\CoffeeTable;
|
||||
|
||||
require_once VV::root("src/API/Endpoints.php");
|
||||
require_once VV::root("src/Database/Models/Model.php");
|
||||
require_once VV::root("src/Database/Tables/Coffee/Coffee.php");
|
||||
require_once VV::root("src/Database/Models/Coffee/Coffee.php");
|
||||
|
||||
class Coffee extends Model {
|
||||
public function __construct(public readonly string $id) {
|
||||
parent::__construct(Endpoints::COFFEE, [
|
||||
CoffeeTable::ID->value => $this->id
|
||||
]);
|
||||
}
|
||||
|
||||
public static function all(array $params = []): array {
|
||||
return array_map(fn(array $item): Coffee => new Coffee($item[CoffeeTable::ID->value]), parent::list(Endpoints::COFFEE, $params));
|
||||
}
|
||||
|
||||
public function timestamp(): int {
|
||||
return $this->get(CoffeeTable::ID->value);
|
||||
}
|
||||
|
||||
public function datetime(): DateTimeImmutable {
|
||||
return DateTimeImmutable::createFromFormat("U", $this->timestamp());
|
||||
}
|
||||
}
|
32
src/Database/Models/Coffee/Stats.php
Normal file
32
src/Database/Models/Coffee/Stats.php
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
namespace VLW\Database\Models\Coffee;
|
||||
|
||||
use \VV;
|
||||
|
||||
use VLW\API\Endpoints;
|
||||
use VLW\Database\Models\Model;
|
||||
use VLW\Database\Tables\Coffee\StatsTable;
|
||||
|
||||
require_once VV::root("src/API/Endpoints.php");
|
||||
require_once VV::root("src/Database/Models/Model.php");
|
||||
require_once VV::root("src/Database/Tables/Coffee/Stats.php");
|
||||
require_once VV::root("src/Database/Models/Coffee/Stats.php");
|
||||
|
||||
class Stats extends Model {
|
||||
public function __construct() {
|
||||
parent::__construct(Endpoints::COFFEE_STATS);
|
||||
}
|
||||
|
||||
public static function all(array $params = []): array {
|
||||
return [];
|
||||
}
|
||||
|
||||
public function week(): int {
|
||||
return $this->get(StatsTable::COUNT_WEEK->value);
|
||||
}
|
||||
|
||||
public function week_average(): int {
|
||||
return $this->get(StatsTable::COUNT_WEEK_AVERAGE->value);
|
||||
}
|
||||
}
|
13
src/Database/Tables/Coffee/Coffee.php
Normal file
13
src/Database/Tables/Coffee/Coffee.php
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace VLW\Database\Tables\Coffee;
|
||||
|
||||
use vlw\xEnum;
|
||||
|
||||
enum CoffeeTable: string {
|
||||
use xEnum;
|
||||
|
||||
const NAME = "coffee";
|
||||
|
||||
case ID = "id";
|
||||
}
|
14
src/Database/Tables/Coffee/Stats.php
Normal file
14
src/Database/Tables/Coffee/Stats.php
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace VLW\Database\Tables\Coffee;
|
||||
|
||||
use vlw\xEnum;
|
||||
|
||||
enum StatsTable: string {
|
||||
use xEnum;
|
||||
|
||||
const NAME = "coffee_stats";
|
||||
|
||||
case COUNT_WEEK = "count_week";
|
||||
case COUNT_WEEK_AVERAGE = "count_week_average";
|
||||
}
|
Loading…
Add table
Reference in a new issue