diff --git a/endpoints/coffee/GET.php b/endpoints/coffee/GET.php new file mode 100644 index 0000000..e925438 --- /dev/null +++ b/endpoints/coffee/GET.php @@ -0,0 +1,38 @@ +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 + ]); + } + } \ No newline at end of file diff --git a/endpoints/coffee/POST.php b/endpoints/coffee/POST.php new file mode 100644 index 0000000..58e3964 --- /dev/null +++ b/endpoints/coffee/POST.php @@ -0,0 +1,38 @@ +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); + } + } \ No newline at end of file diff --git a/endpoints/coffee/stats/GET.php b/endpoints/coffee/stats/GET.php new file mode 100644 index 0000000..0514a0a --- /dev/null +++ b/endpoints/coffee/stats/GET.php @@ -0,0 +1,42 @@ +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()); + } + } \ No newline at end of file diff --git a/endpoints/coffee/stats/POST.php b/endpoints/coffee/stats/POST.php new file mode 100644 index 0000000..43ca84f --- /dev/null +++ b/endpoints/coffee/stats/POST.php @@ -0,0 +1,35 @@ +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); + } + } \ No newline at end of file diff --git a/public/about.php b/public/about.php index b95d41f..be1fa43 100644 --- a/public/about.php +++ b/public/about.php @@ -1,5 +1,6 @@ week() - $this->week_average(); + + return match (true) { + $diff < 1 => "less than", + $diff === 1 => "the same as", + $diff > 1 => "more than" + }; + } + }; ?> @@ -44,8 +58,8 @@

I​'m a full-stack web developer from Sweden, and welcome to my little personal corner of the Internet!

-

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 mirrors and sources on Forgejo.

-

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.

+

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 Forgejo.

+

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.

@@ -87,7 +101,7 @@

Personal

-

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 too much of a coffee snob! As long as it's dark roast and warm, I'm probably happy to have it.

+

One thing is true.. Coffee, lots of coffee. In fact, I've had week() ?> cupweek() === 1 ? "" : "s" ?> of coffee in the last 7 days! That's week_average_string() ?> my average of week_average() ?> per week, impressive! Even though you just read that.. I don't consider myself too much of a coffee snob! As long as it's dark roast and warm, I'm probably happy to have it.

At times, I become a true, amateur, armchair detective for a variety of your typical-nerdy topics that I find interesting and you can bet I spend way more time reading about those things than I will ever have use for in life.

My coding happens almost exclusivly in code-server, 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 dotfiles ready to get things set up the way I like it.

Another silent passion of mine that comes out every few years is building computers and fiddling with weird networking stuff.

diff --git a/src/API/Endpoints.php b/src/API/Endpoints.php index 2fb97e2..efd1012 100644 --- a/src/API/Endpoints.php +++ b/src/API/Endpoints.php @@ -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"; } \ No newline at end of file diff --git a/src/Consts.php b/src/Consts.php index f4700f1..f954031 100644 --- a/src/Consts.php +++ b/src/Consts.php @@ -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 diff --git a/src/Database/Models/Coffee/Coffee.php b/src/Database/Models/Coffee/Coffee.php new file mode 100644 index 0000000..e1adb6a --- /dev/null +++ b/src/Database/Models/Coffee/Coffee.php @@ -0,0 +1,35 @@ +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()); + } + } \ No newline at end of file diff --git a/src/Database/Models/Coffee/Stats.php b/src/Database/Models/Coffee/Stats.php new file mode 100644 index 0000000..7756eb3 --- /dev/null +++ b/src/Database/Models/Coffee/Stats.php @@ -0,0 +1,32 @@ +get(StatsTable::COUNT_WEEK->value); + } + + public function week_average(): int { + return $this->get(StatsTable::COUNT_WEEK_AVERAGE->value); + } + } \ No newline at end of file diff --git a/src/Database/Tables/Coffee/Coffee.php b/src/Database/Tables/Coffee/Coffee.php new file mode 100644 index 0000000..a4abc6b --- /dev/null +++ b/src/Database/Tables/Coffee/Coffee.php @@ -0,0 +1,13 @@ +