diff --git a/default.nix b/default.nix index e6bc0e2..c1bcdec 100644 --- a/default.nix +++ b/default.nix @@ -1,8 +1,14 @@ { pkgs, lib, config, ... }: { options = { - scripts.output = lib.mkOption { - type = lib.types.package; + scripts = { + output = lib.mkOption { + type = lib.types.package; + }; + + geocode = lib.mkOption { + type = lib.types.package; + }; }; map = { @@ -10,6 +16,11 @@ type = lib.types.nullOr lib.types.int; default = 2; }; + + center = lib.mkOption { + type = lib.types.nullOr lib.types.str; + default = "Switzerland"; + }; }; requestParams = lib.mkOption { @@ -18,17 +29,30 @@ }; config = { - scripts.output = pkgs.writeShellApplication { - name = "map"; + scripts = { + output = pkgs.writeShellApplication { + name = "map"; - runtimeInputs = with pkgs; [ - curl - imagemagick - ]; + runtimeInputs = with pkgs; [ + curl + imagemagick + ]; - text = '' - convert <(${./map} ${lib.concatStringsSep " " config.requestParams}) sixel:- - ''; + text = '' + convert <(${./map} ${lib.concatStringsSep " " config.requestParams}) sixel:- + ''; + }; + + geocode = pkgs.writeShellApplication { + name = "geocode"; + + runtimeInputs = with pkgs; [ + curl + jq + ]; + + text = ''exec ${./geocode} "$@"''; + }; }; requestParams = [ @@ -36,6 +60,10 @@ "scale=2" (lib.mkIf (config.map.zoom != null) "zoom=${toString config.map.zoom}") + (lib.mkIf (config.map.center != null) + "center=\"${config.scripts.geocode}/bin/geocode ${ + lib.escapeShellArg config.map.center + }\"") ]; }; } diff --git a/geocode b/geocode new file mode 100755 index 0000000..2da35ab --- /dev/null +++ b/geocode @@ -0,0 +1,53 @@ +#!/usr/bin/env bash +set -euo pipefail + +cachedir=~/.cache/google-api/geocode +mkdir -p "$cachedir" +hash=$(echo "$1" | sha256sum - | cut -d' ' -f1) +cachefile="$cachedir/$hash" + +if [[ ! -f "$cachefile" ]]; then + + keyFile=${XDG_DATA_HOME:-~/.local/share}/google-api/key + + if [[ ! -f "$keyFile" ]]; then + mkdir -p "$(basename "$keyFile")" + echo "No Google API key found in $keyFile" >&2 + echo "For getting one, see https://developers.google.com/maps/documentation/geocoding/overview#before-you-begin" >&2 + exit 1 + fi + + key=$(cat "$keyFile") + + + tmp=$(mktemp -d) + trap 'rm -rf "$tmp"' exit + + output=$tmp/output + + curlArgs=( + https://maps.googleapis.com/maps/api/geocode/json + --silent --show-error --get --output "$output" --write-out '%{http_code}' + --data-urlencode address="$1" + ) + + #echo curl ''${curlArgs[@]@Q} >&2 + + curlArgs+=(--data-urlencode key="$key") + + if status=$(curl "${curlArgs[@]}"); then + if [[ "$status" == 200 ]]; then + jq -r '.results[0].geometry.location as $loc | "\($loc | .lat),\($loc | .lng)"' "$output" > "$cachefile" + else + echo "API returned non-200 HTTP status code $status, output is" >&2 + cat "$output" >&2 + exit 1 + fi + else + code=$? + echo "curl exited with code $code" >&2 + exit 1 + fi +fi + +cat "$cachefile"