commit f5caba6226de1e2faf5d273e1989c798635039bc
parent 8727a877b7f489ab5180d5536d9cb6794c7fdc9e
Author: Leah (ctucx) <leah@ctu.cx>
Date: Fri, 20 May 2022 18:17:40 +0200
parent 8727a877b7f489ab5180d5536d9cb6794c7fdc9e
Author: Leah (ctucx) <leah@ctu.cx>
Date: Fri, 20 May 2022 18:17:40 +0200
machines/osterei/websites/ctu.cx: add bikemap
5 files changed, 322 insertions(+), 1 deletion(-)
A
|
114
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A
|
137
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A
|
70
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
diff --git a/machines/osterei/websites/ctu.cx-bikemap/default-gpx2tiles.nix b/machines/osterei/websites/ctu.cx-bikemap/default-gpx2tiles.nix @@ -0,0 +1,114 @@ +{ pkgs, ... }: + +let + gpx2tiles = pkgs.stdenv.mkDerivation rec { + name = "gpx2tiles"; + + src = pkgs.fetchFromGitHub { + owner = "raalkml"; + repo = "gpx2tiles"; + rev = "bfe287bfdf21869212b5d095bba6979caee4a308"; + sha256 = "0x4cparlbxvjnwhwkdz157py1bmad2sap3wjjzaq988aymxnadym"; + }; + + buildInputs = with pkgs; [ + pkgconfig + libxml2 + gd + ]; + + makeFlags = [ "PREFIX=${placeholder "out"}" ]; + }; + + deployScript = pkgs.writeShellScript "deploy" '' + systemctl start deploy-bikemap + systemctl status deploy-bikemap + ''; + + deployHook = pkgs.writeShellScriptBin "post-receive" '' + [ -t 0 ] || cat >/dev/null + [ -z "$GL_REPO" ] && die GL_REPO not set + + #deploy bikemap + [ "$GL_REPO" == "bikemap" ] && sudo ${deployScript} + ''; + +in { + + users = { + users."bikemap" = { + home = "/var/lib/bikemap"; + group = "git"; + isSystemUser = true; + }; + }; + + security.sudo.extraRules = [{ + users = [ "git" ]; + commands = [ + { command = "${deployScript}"; options = [ "SETENV" "NOPASSWD" ]; } + ]; + }]; + + systemd = { + services.deploy-bikemap = { + script = '' + tmpdir=$(mktemp -d); + + ${pkgs.git}/bin/git clone /var/lib/gitolite/repositories/bikemap.git $tmpdir + + mkdir $tmpdir/tiles; + ${gpx2tiles}/bin/gpx2tiles -j 2 -t 7:2+ -t 13:4+ -z 6 -Z 16 -c ff8800 -C $tmpdir/tiles $tmpdir/tracks/*.gpx; + + rm -rf ~/*; + + cp -r $tmpdir/dist/* ~/.; + cp -r $tmpdir/tiles ~/.; + echo "{\"lastUpdated\":\"$(date +"%Y-%m-%d %H:%M")\"}" > ~/lastUpdated.json; + + rm -rf $tmpdir; + ''; + + serviceConfig = { + Type = "oneshot"; + + User = "bikemap"; + Group = "git"; + + WorkingDirectory = "~"; + StateDirectory = "bikemap"; + StateDirectoryMode = "755"; + + NoNewPrivileges = true; + PrivateTmp = true; + PrivateDevices = true; + + RestrictAddressFamilies = "none"; + RestrictNamespaces = true; + RestrictRealtime = true; + + ProtectSystem = "full"; + ProtectControlGroups = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + + DevicePolicy = "closed"; + LockPersonality = true; + }; + }; + }; + + services = { + gitolite.commonHooks = [ "${deployHook}/bin/post-receive" ]; + nginx = { + enable = true; + virtualHosts."ctu.cx" = { + enableACME = true; + forceSSL = true; + locations = { + "/bikemap/".alias = "/var/lib/bikemap/"; + }; + }; + }; + }; +}
diff --git a/machines/osterei/websites/ctu.cx-bikemap/default.nix b/machines/osterei/websites/ctu.cx-bikemap/default.nix @@ -0,0 +1,137 @@ +{ pkgs, ... }: + +let + parse-gpx = pkgs.stdenv.mkDerivation rec { + name = "parse-gpx"; + src = ./parse-gpx; + + nativeBuildInputs = [ pkgs.makeWrapper ]; + buildInputs = [ pkgs.perl ]; + + installPhase = ''mkdir -p $out/bin; cp parse-gpx $out/bin; chmod +x $out/bin/parse-gpx;''; + postFixup = ''wrapProgram $out/bin/parse-gpx --prefix PERL5LIB : "${with pkgs.perlPackages; makePerlPath [ XMLParser ]}"''; + }; + + datamaps = pkgs.stdenv.mkDerivation rec { + name = "datamaps"; + + src = pkgs.fetchFromGitHub { + owner = "e-n-f"; + repo = "datamaps"; + rev = "76e620adabbedabd6866b23b30c145b53bae751e"; + sha256 = "1rdqbyfmgidiv4aqy1s6llls304dxbg5226c7k622smd2rnda2jk"; + }; + + buildInputs = with pkgs; [ pkgconfig libpng ]; + + installPhase = '' + mkdir -p $out/bin; + cp {encode,render,merge,enumerate} $out/bin; + ''; + }; + + makeTile = pkgs.writeShellScript "makeTile" '' + mkdir -p tiles/$2/$3 + echo "rendering $1 $2 $3 $4 $5 $6" + + if [$2 -gt 13 ] + then + ${datamaps}/bin/render -g -t0 -L4 -c 'ff8800' -S 'ff8800' $1 $2 $3 $4 | ${pkgs.pngquant}/bin/pngquant 256 > tiles/$2/$3/$4.png + else + ${datamaps}/bin/render -g -t0 -L7 -c 'ff8800' -S 'ff8800' $1 $2 $3 $4 | ${pkgs.pngquant}/bin/pngquant 256 > tiles/$2/$3/$4.png + fi + ''; + + deployScript = pkgs.writeShellScript "deploy" '' + systemctl start deploy-bikemap; + systemctl status deploy-bikemap; + ''; + + deployHook = pkgs.writeShellScriptBin "post-receive" '' + [ -t 0 ] || cat >/dev/null + [ -z "$GL_REPO" ] && die GL_REPO not set + + #deploy bikemap + [ "$GL_REPO" == "bikemap" ] && sudo ${deployScript} + ''; + +in { + + users = { + users."bikemap" = { + home = "/var/lib/bikemap"; + group = "git"; + isSystemUser = true; + }; + }; + + security.sudo.extraRules = [{ + users = [ "git" ]; + commands = [ + { command = "${deployScript}"; options = [ "SETENV" "NOPASSWD" ]; } + ]; + }]; + + systemd = { + services.deploy-bikemap = { + script = '' + tmpdir=$(mktemp -d); + cd $tmpdir + + ${pkgs.git}/bin/git clone /var/lib/gitolite/repositories/bikemap.git $tmpdir + + find $tmpdir/tracks -name '*.gpx' -print0 | xargs -0 ${parse-gpx}/bin/parse-gpx | ${datamaps}/bin/encode -z16 -m8 -o $tmpdir/gpx.dm + ${datamaps}/bin/enumerate -s -Z6 -z16 ./gpx.dm | xargs -L1 -P3 ${makeTile} + + rm -rf ~/*; + + cp -r $tmpdir/dist/* ~/.; + cp -r $tmpdir/tiles ~/tiles; + echo "{\"lastUpdated\":\"$(date +"%Y-%m-%d %H:%M")\"}" > ~/lastUpdated.json; + + rm -rf $tmpdir; + ''; + + serviceConfig = { + Type = "oneshot"; + + User = "bikemap"; + Group = "git"; + + WorkingDirectory = "~"; + StateDirectory = "bikemap"; + StateDirectoryMode = "755"; + + NoNewPrivileges = true; + PrivateTmp = true; + PrivateDevices = true; + + RestrictAddressFamilies = "none"; + RestrictNamespaces = true; + RestrictRealtime = true; + + ProtectSystem = "full"; + ProtectControlGroups = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + + DevicePolicy = "closed"; + LockPersonality = true; + }; + }; + }; + + services = { + gitolite.commonHooks = [ "${deployHook}/bin/post-receive" ]; + nginx = { + enable = true; + virtualHosts."ctu.cx" = { + enableACME = true; + forceSSL = true; + locations = { + "/bikemap/".alias = "/var/lib/bikemap/"; + }; + }; + }; + }; +}
diff --git a/machines/osterei/websites/ctu.cx-bikemap/parse-gpx/parse-gpx b/machines/osterei/websites/ctu.cx-bikemap/parse-gpx/parse-gpx @@ -0,0 +1,70 @@ +#!/usr/bin/env perl +use POSIX; +use XML::Parser; + +$pi = 4 * atan2(1, 1); + +sub handle_start { + my ($expat, $element, @tags) = @_; + my %tags = @tags; + + if ($element eq "trkpt") { + $lat = $tags{'lat'}; + $lon = $tags{'lon'}; + } elsif ($element eq "ele") { + $state = "ele"; + } elsif ($element eq "time") { + $state = "time"; + } else { + $state = ""; + } +} + +sub handle_char { + my ($expat, $string) = @_; + + $text{$state} .= $string; +} + +sub handle_end { + my ($expat, $element) = @_; + + if ($element eq "trkseg" || $element eq "trk") { + $oldlat = $oldlon = ""; + } elsif ($element eq "trkpt") { + if ($lat ne "" && $lon ne "" && $oldlat ne "" && $oldlon ne "") { + if ($lat ne $oldlat || $lon ne $oldlon) { + print "$oldlat,$oldlon $lat,$lon "; + + $rat = cos(($lat + $oldlat) / 2 * $pi / 180); + $ang = atan2($lat - $oldlat, ($lon - $oldlon) * $rat); + + printf("8:%d\n", ($ang + $pi) * 256 / (2 * $pi)); + } + } + + $oldlat = $lat; + $oldlon = $lon; + %text = (); + } +} + +if ($#ARGV < 0) { + $parser = new XML::Parser(Handlers => { Start => \&handle_start, + End => \&handle_end, + Char => \&handle_char, + }); + + $parser->parse(*STDIN); +} else { + for $file (@ARGV) { + $oldwhen = 0; + + $parser = new XML::Parser(Handlers => { Start => \&handle_start, + End => \&handle_end, + Char => \&handle_char, + }); + + $parser->parsefile($file); + } +}
diff --git a/machines/osterei/websites/ctu.cx.nix b/machines/osterei/websites/ctu.cx.nix @@ -9,7 +9,6 @@ forceSSL = true; locations = { "/".root = ./ctu.cx; - "/bikemap/".alias = "/var/lib/websites/bikemap/"; "/vodafone-map" = { proxyPass = "https://netmap.vodafone.de/arcgis/rest/services/CoKart/netzabdeckung_mobilfunk_4x/MapServer";
diff --git a/machines/osterei/websites/default.nix b/machines/osterei/websites/default.nix @@ -4,6 +4,7 @@ imports = [ ./ctu.cx.nix + ./ctu.cx-bikemap ./photos.ctu.cx.nix ./flauschehorn.sexy.nix ];