initial commit
This commit is contained in:
commit
885ff3b928
11 changed files with 367 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
/gomod2nix-template
|
||||
89
awl.go
Normal file
89
awl.go
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const AWL_URL string = "https://buergerportal.awl-neuss.de/api/v1/calendar"
|
||||
|
||||
func GetStreetNumbers() (map[string]int, error) {
|
||||
url := AWL_URL + "/townarea-streets"
|
||||
response, err := http.Get(url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer response.Body.Close()
|
||||
|
||||
content, err := io.ReadAll(response.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var streets []struct {
|
||||
Number int `json:"strasseNummer"`
|
||||
Name string `json:"strasseBezeichnung"`
|
||||
}
|
||||
err = json.Unmarshal(content, &streets)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nameToNumber := make(map[string]int, len(streets))
|
||||
for _, street := range streets {
|
||||
name := strings.ToLower(street.Name)
|
||||
name = strings.Replace(name, " ", "-", -1)
|
||||
name = strings.Replace(name, "--", "-", -1)
|
||||
nameToNumber[name] = street.Number
|
||||
}
|
||||
|
||||
return nameToNumber, nil
|
||||
}
|
||||
|
||||
func AwlTomorrow(street, home int) ([]string, error) {
|
||||
startDate := time.Now().AddDate(0, 0, 1)
|
||||
startDateFmt := startDate.Format("Jan 02 2006")
|
||||
|
||||
requestUrl := fmt.Sprintf(AWL_URL + "?startMonth=%s&streetNum=%d&homeNumber=%d", url.QueryEscape(startDateFmt), street, home)
|
||||
response, err := http.Get(requestUrl)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer response.Body.Close()
|
||||
|
||||
content, err := io.ReadAll(response.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var jsonBody map[string]map[string][]string
|
||||
err = json.Unmarshal(content, &jsonBody)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not parse json:\n%s\n%s", err.Error(), content)
|
||||
}
|
||||
|
||||
if len(jsonBody) != 1 {
|
||||
return nil, fmt.Errorf("unexpected awl response:\n%s", string(content))
|
||||
}
|
||||
|
||||
currentMonth := fmt.Sprintf("%d-%d", startDate.Month()-1, startDate.Year())
|
||||
currentDay := startDate.Format("2")
|
||||
|
||||
month, ok := jsonBody[currentMonth]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("could not access month (%s):\n%s", currentMonth, string(content))
|
||||
}
|
||||
|
||||
day, ok := month[currentDay]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("could not access day (%s):\n%s", currentDay, string(content))
|
||||
}
|
||||
|
||||
return day, nil
|
||||
}
|
||||
|
||||
21
default.nix
Normal file
21
default.nix
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
{ pkgs ? (
|
||||
let
|
||||
inherit (builtins) fetchTree fromJSON readFile;
|
||||
inherit ((fromJSON (readFile ./flake.lock)).nodes) nixpkgs gomod2nix;
|
||||
in
|
||||
import (fetchTree nixpkgs.locked) {
|
||||
overlays = [
|
||||
(import "${fetchTree gomod2nix.locked}/overlay.nix")
|
||||
];
|
||||
}
|
||||
)
|
||||
, buildGoApplication ? pkgs.buildGoApplication
|
||||
}:
|
||||
|
||||
buildGoApplication {
|
||||
pname = "awl-ntfy";
|
||||
version = "0.1";
|
||||
pwd = ./.;
|
||||
src = ./.;
|
||||
modules = ./gomod2nix.toml;
|
||||
}
|
||||
85
flake.lock
generated
Normal file
85
flake.lock
generated
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
{
|
||||
"nodes": {
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1731533236,
|
||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"gomod2nix": {
|
||||
"inputs": {
|
||||
"flake-utils": [
|
||||
"flake-utils"
|
||||
],
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1750314194,
|
||||
"narHash": "sha256-SjpXWEeB+UIMzuCAF94PuyAXpJdnBLF45JvI6o4wKIU=",
|
||||
"owner": "nix-community",
|
||||
"repo": "gomod2nix",
|
||||
"rev": "a5f75f563748599d448a4a076816041d7b0fc07e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "gomod2nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1751271578,
|
||||
"narHash": "sha256-P/SQmKDu06x8yv7i0s8bvnnuJYkxVGBWLWHaU+tt4YY=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "3016b4b15d13f3089db8a41ef937b13a9e33a8df",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"gomod2nix": "gomod2nix",
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
31
flake.nix
Normal file
31
flake.nix
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
description = "A basic gomod2nix flake";
|
||||
|
||||
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
inputs.flake-utils.url = "github:numtide/flake-utils";
|
||||
|
||||
inputs.gomod2nix = {
|
||||
url = "github:nix-community/gomod2nix";
|
||||
inputs = {
|
||||
nixpkgs.follows = "nixpkgs";
|
||||
flake-utils.follows = "flake-utils";
|
||||
};
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, flake-utils, gomod2nix }:
|
||||
(flake-utils.lib.eachDefaultSystem
|
||||
(system:
|
||||
let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
callPackage = pkgs.callPackage;
|
||||
in
|
||||
{
|
||||
packages.default = callPackage ./. {
|
||||
inherit (gomod2nix.legacyPackages.${system}) buildGoApplication;
|
||||
};
|
||||
devShells.default = callPackage ./shell.nix {
|
||||
inherit (gomod2nix.legacyPackages.${system}) mkGoEnv gomod2nix;
|
||||
};
|
||||
})
|
||||
);
|
||||
}
|
||||
8
go.mod
Normal file
8
go.mod
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
module catos.directory/tasks/awl-ntfy
|
||||
|
||||
go 1.24.2
|
||||
|
||||
require (
|
||||
github.com/alexflint/go-arg v1.5.1 // indirect
|
||||
github.com/alexflint/go-scalar v1.2.0 // indirect
|
||||
)
|
||||
7
go.sum
Normal file
7
go.sum
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
github.com/alexflint/go-arg v1.5.1 h1:nBuWUCpuRy0snAG+uIJ6N0UvYxpxA0/ghA/AaHxlT8Y=
|
||||
github.com/alexflint/go-arg v1.5.1/go.mod h1:A7vTJzvjoaSTypg4biM5uYNTkJ27SkNTArtYXnlqVO8=
|
||||
github.com/alexflint/go-scalar v1.2.0 h1:WR7JPKkeNpnYIOfHRa7ivM21aWAdHD0gEWHCx+WQBRw=
|
||||
github.com/alexflint/go-scalar v1.2.0/go.mod h1:LoFvNMqS1CPrMVltza4LvnGKhaSpc3oyLEBUZVhhS2o=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
3
gomod2nix.toml
Normal file
3
gomod2nix.toml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
schema = 1
|
||||
|
||||
[mod]
|
||||
52
main.go
Normal file
52
main.go
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
arg "github.com/alexflint/go-arg"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var args struct {
|
||||
Street string `arg:"positional,required"`
|
||||
Home int `arg:"positional,required"`
|
||||
}
|
||||
|
||||
parser, err := arg.NewParser(arg.Config{}, &args)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
parser.MustParse(os.Args[1:])
|
||||
|
||||
streetNumbers, err := GetStreetNumbers()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
_ = SendErr(args.Street, err)
|
||||
return
|
||||
}
|
||||
|
||||
streetNumber, ok := streetNumbers[args.Street]
|
||||
if !ok {
|
||||
fmt.Println("street could not be found:", args.Street)
|
||||
}
|
||||
|
||||
tomorrow, err := AwlTomorrow(streetNumber, args.Home)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
_ = SendErr(args.Street, err)
|
||||
return
|
||||
}
|
||||
|
||||
if len(tomorrow) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
err = SendAwlNotification(args.Street, tomorrow)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
_ = SendErr(args.Street, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
46
ntfy.go
Normal file
46
ntfy.go
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func SendAwlNotification(channel string, binColors []string) error {
|
||||
var bins = make([]string, 0, 5)
|
||||
for _, color := range binColors {
|
||||
switch color {
|
||||
case "pink":
|
||||
bins = append(bins, "🟣 Pink")
|
||||
case "gelb":
|
||||
bins = append(bins, "🟡 Gelb")
|
||||
case "blau":
|
||||
bins = append(bins, "🔵 Blau")
|
||||
case "grau":
|
||||
bins = append(bins, "⚫ Grau")
|
||||
case "braun":
|
||||
bins = append(bins, "🟤 Braun")
|
||||
}
|
||||
}
|
||||
|
||||
var message string
|
||||
if len(bins) == 1 {
|
||||
message = "Morgen wird folgende Tonne abgeholt: "
|
||||
} else {
|
||||
message = "Morgen werden folgende Tonnen abgeholt: "
|
||||
}
|
||||
message += strings.Join(bins, ", ")
|
||||
return SendNotification(channel, message)
|
||||
}
|
||||
|
||||
func SendNotification(channel, message string) error {
|
||||
topic := fmt.Sprintf("https://ntfy.sh/awl_neuss_%s_err", channel)
|
||||
_, err := http.Post(topic, "text/plain", strings.NewReader(message))
|
||||
return err
|
||||
}
|
||||
|
||||
func SendErr(channel string, err error) error {
|
||||
topic := fmt.Sprintf("https://ntfy.sh/awl_neuss_%s_err", channel)
|
||||
_, err = http.Post(topic, "text/plain", strings.NewReader(err.Error()))
|
||||
return err
|
||||
}
|
||||
24
shell.nix
Normal file
24
shell.nix
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
{ pkgs ? (
|
||||
let
|
||||
inherit (builtins) fetchTree fromJSON readFile;
|
||||
inherit ((fromJSON (readFile ./flake.lock)).nodes) nixpkgs gomod2nix;
|
||||
in
|
||||
import (fetchTree nixpkgs.locked) {
|
||||
overlays = [
|
||||
(import "${fetchTree gomod2nix.locked}/overlay.nix")
|
||||
];
|
||||
}
|
||||
)
|
||||
, mkGoEnv ? pkgs.mkGoEnv
|
||||
, gomod2nix ? pkgs.gomod2nix
|
||||
}:
|
||||
|
||||
let
|
||||
goEnv = mkGoEnv { pwd = ./.; };
|
||||
in
|
||||
pkgs.mkShell {
|
||||
packages = [
|
||||
goEnv
|
||||
gomod2nix
|
||||
];
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue