Your one-stop-cake-shop for everything Freshly Baked has to offer

feat(pm/umber): init grocy

Grocy is a stock tracking application for groceries. I'd like to use it
to keep track of some of my stuff, so let's host it on umber!

authored by a.starrysky.fyi and committed by tangled.org f655e938 3e26528f

+61
+34
packetmix/systems/umber/grocy.nix
··· 1 + # SPDX-FileCopyrightText: 2025 FreshlyBakedCake 2 + # 3 + # SPDX-License-Identifier: MIT 4 + 5 + { pkgs, lib, ... }: 6 + { 7 + services.grocy = { 8 + enable = true; 9 + package = pkgs.stdenv.mkDerivation { 10 + name = "grocy-custom-js"; 11 + src = pkgs.grocy; 12 + 13 + dontBuild = true; 14 + installPhase = '' 15 + mkdir -p $out/ 16 + cp -r * $out/ 17 + 18 + mkdir -p $out/data/ 19 + cp ${./grocy/custom_js.html} $out/data/custom_js.html # we need to specify the filename explicitly, as otherwise this'll have a hash 20 + ''; 21 + }; 22 + hostName = "grocy.starrysky.fyi"; 23 + 24 + settings.currency = "GBP"; 25 + }; 26 + 27 + services.nginx.virtualHosts."grocy.starrysky.fyi" = { 28 + acmeRoot = null; 29 + forceSSL = lib.mkForce false; 30 + onlySSL = true; 31 + }; 32 + 33 + clicks.storage.impermanence.persist.directories = [ "/var/lib/grocy" ]; 34 + }
+27
packetmix/systems/umber/grocy/custom_js.html
··· 1 + <!-- 2 + SPDX-FileCopyrightText: 2026 Freshly Baked Cake 3 + 4 + SPDX-License-Identifier: MIT 5 + --> 6 + 7 + <script> 8 + { 9 + const locationFilter = document.getElementById("location-filter"); 10 + let desiredLocation = GetUriParam("location"); 11 + if (locationFilter !== null && desiredLocation !== null) 12 + { 13 + if (locationFilter.selectedOptions.length === 0 || locationFilter.selectedOptions[0].value === "all") { 14 + // Don't trigger if we select a different option and refresh the page 15 + desiredLocation = desiredLocation.replaceAll("_", " ") // WikiText needs underscores to be spaces 16 + const option = locationFilter.querySelector(`option[value="${desiredLocation}"]`) 17 + ?? locationFilter.querySelector(`option[value^="${desiredLocation}"]`) 18 + ?? locationFilter.querySelector(`option[value*="${desiredLocation}"]`); 19 + // Search first for an exact match, then a match which starts with, then a match which contains 20 + if (option) { 21 + locationFilter.value = option.value; 22 + locationFilter.dispatchEvent(new Event('change')); 23 + } 24 + } 25 + } 26 + } 27 + </script>