about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFranck Cuny <franck@fcuny.net>2024-04-28 19:15:51 -0700
committerFranck Cuny <franck@fcuny.net>2024-04-28 19:17:12 -0700
commit58d0a9cb616e35daf115b8e1aa9f5b79e4a21a70 (patch)
tree87f0cb04b860048f70c2f90cf9ba9d7d5e7f2634
parentchore: update flake (diff)
downloadworld-58d0a9cb616e35daf115b8e1aa9f5b79e4a21a70.tar.gz
add a script to fetch cheeseboard's menu
Delete the version in go.
-rw-r--r--cmd/cbpt/main.go57
-rw-r--r--go.mod20
-rw-r--r--go.sum86
-rw-r--r--nix/flake/packages.nix1
-rw-r--r--nix/profiles/home-manager/dev.nix12
-rw-r--r--nix/profiles/home-manager/shell.nix1
-rw-r--r--packages/pizza/default.nix31
-rwxr-xr-xpackages/pizza/pizza.py58
8 files changed, 99 insertions, 167 deletions
diff --git a/cmd/cbpt/main.go b/cmd/cbpt/main.go
deleted file mode 100644
index 075f084..0000000
--- a/cmd/cbpt/main.go
+++ /dev/null
@@ -1,57 +0,0 @@
-package main
-
-import (
-	"fmt"
-	"regexp"
-	"strings"
-
-	"github.com/gocolly/colly"
-)
-
-const (
-	cheeseboardURL = "https://cheeseboardcollective.coop/pizza/"
-)
-
-var (
-	boilerPlateParBake      = regexp.MustCompile(`Parbake pizza is available in the bakery from \d a.m. to \d p.m., while supplies last.`)
-	boilerPlateParBakeLunch = regexp.MustCompile(`Parbake pizza is available in the bakery from \d a.m. to \d p.m..Lunch from 1\d:30-\d:30 and dinner from \d-\d.`)
-	boilerPlateNoHotPizza   = regexp.MustCompile(`No hot pizza today.`)
-	cheeseboardIsClosed     = regexp.MustCompile(`The Pizzeria is closed today`)
-)
-
-type Pizza struct {
-	Date     string
-	Toppings string
-}
-
-func main() {
-	c := colly.NewCollector()
-
-	c.OnRequest(func(r *colly.Request) {
-		fmt.Println("Visiting", r.URL)
-	})
-
-	var pizzas []Pizza
-
-	c.OnHTML("div.pizza-list", func(e *colly.HTMLElement) {
-		e.ForEach("article", func(c int, el *colly.HTMLElement) {
-			var pizza Pizza
-			pizza.Date = el.ChildText("div.date")
-			toppings := el.ChildText("div.menu > p:nth-child(2)")
-			if cheeseboardIsClosed.MatchString(toppings) {
-				return
-			}
-			toppings = boilerPlateParBake.ReplaceAllString(toppings, "")
-			toppings = boilerPlateParBakeLunch.ReplaceAllString(toppings, "")
-			toppings = boilerPlateNoHotPizza.ReplaceAllString(toppings, "")
-			toppings = strings.TrimLeft(toppings, " ")
-			pizza.Toppings = toppings
-			pizzas = append(pizzas, pizza)
-		})
-	})
-
-	c.Visit(cheeseboardURL)
-	for _, pizza := range pizzas {
-		fmt.Printf("%s: %s\n", pizza.Date, pizza.Toppings)
-	}
-}
diff --git a/go.mod b/go.mod
index d5ff1f1..c28fd3c 100644
--- a/go.mod
+++ b/go.mod
@@ -1,23 +1,3 @@
 module github.com/fcuny/world
 
 go 1.21.4
-
-require github.com/gocolly/colly v1.2.0
-
-require (
-	github.com/PuerkitoBio/goquery v1.9.1 // indirect
-	github.com/andybalholm/cascadia v1.3.2 // indirect
-	github.com/antchfx/htmlquery v1.3.0 // indirect
-	github.com/antchfx/xmlquery v1.3.18 // indirect
-	github.com/antchfx/xpath v1.2.4 // indirect
-	github.com/gobwas/glob v0.2.3 // indirect
-	github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
-	github.com/golang/protobuf v1.5.2 // indirect
-	github.com/kennygrant/sanitize v1.2.4 // indirect
-	github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d // indirect
-	github.com/temoto/robotstxt v1.1.2 // indirect
-	golang.org/x/net v0.22.0 // indirect
-	golang.org/x/text v0.14.0 // indirect
-	google.golang.org/appengine v1.6.8 // indirect
-	google.golang.org/protobuf v1.26.0 // indirect
-)
diff --git a/go.sum b/go.sum
index 34c69a4..e69de29 100644
--- a/go.sum
+++ b/go.sum
@@ -1,86 +0,0 @@
-github.com/PuerkitoBio/goquery v1.9.1 h1:mTL6XjbJTZdpfL+Gwl5U2h1l9yEkJjhmlTeV9VPW7UI=
-github.com/PuerkitoBio/goquery v1.9.1/go.mod h1:cW1n6TmIMDoORQU5IU/P1T3tGFunOeXEpGP2WHRwkbY=
-github.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsViSLyss=
-github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU=
-github.com/antchfx/htmlquery v1.3.0 h1:5I5yNFOVI+egyia5F2s/5Do2nFWxJz41Tr3DyfKD25E=
-github.com/antchfx/htmlquery v1.3.0/go.mod h1:zKPDVTMhfOmcwxheXUsx4rKJy8KEY/PU6eXr/2SebQ8=
-github.com/antchfx/xmlquery v1.3.18 h1:FSQ3wMuphnPPGJOFhvc+cRQ2CT/rUj4cyQXkJcjOwz0=
-github.com/antchfx/xmlquery v1.3.18/go.mod h1:Afkq4JIeXut75taLSuI31ISJ/zeq+3jG7TunF7noreA=
-github.com/antchfx/xpath v1.2.3/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs=
-github.com/antchfx/xpath v1.2.4 h1:dW1HB/JxKvGtJ9WyVGJ0sIoEcqftV3SqIstujI+B9XY=
-github.com/antchfx/xpath v1.2.4/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs=
-github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
-github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
-github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
-github.com/gocolly/colly v1.2.0 h1:qRz9YAn8FIH0qzgNUw+HT9UN7wm1oF9OBAilwEWpyrI=
-github.com/gocolly/colly v1.2.0/go.mod h1:Hof5T3ZswNVsOHYmba1u03W65HDWgpV5HifSuueE0EA=
-github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
-github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
-github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
-github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
-github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
-github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
-github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/kennygrant/sanitize v1.2.4 h1:gN25/otpP5vAsO2djbMhF/LQX6R7+O1TB4yv8NzpJ3o=
-github.com/kennygrant/sanitize v1.2.4/go.mod h1:LGsjYYtgxbetdg5owWB2mpgUL6e2nfw2eObZ0u0qvak=
-github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
-github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d h1:hrujxIzL1woJ7AwssoOcM/tq5JjjG2yYOc8odClEiXA=
-github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU=
-github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
-github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
-github.com/temoto/robotstxt v1.1.2 h1:W2pOjSJ6SWvldyEuiFXNxz3xZ8aiWX5LbfDiOFd7Fxg=
-github.com/temoto/robotstxt v1.1.2/go.mod h1:+1AmkuG3IYkh1kv0d2qEB9Le88ehNO0zwOr3ujewlOo=
-github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
-golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
-golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
-golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
-golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
-golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
-golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
-golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
-golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
-golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
-golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
-golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
-golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=
-golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
-golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
-golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
-golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
-golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
-golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
-golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
-golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
-golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
-golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
-golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
-google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
-google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
-google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
-google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
diff --git a/nix/flake/packages.nix b/nix/flake/packages.nix
index 71b9dc5..dddf4b5 100644
--- a/nix/flake/packages.nix
+++ b/nix/flake/packages.nix
@@ -15,6 +15,7 @@
       git-blame-stats = pkgs.callPackage "${self}/packages/git-blame-stats" { };
       git-broom = pkgs.callPackage "${self}/packages/git-broom" { };
       ipconverter = pkgs.callPackage "${self}/packages/ipconverter" { };
+      pizza = pkgs.callPackage "${self}/packages/pizza" { };
       slocalc = pkgs.callPackage "${self}/packages/slocalc" { };
     };
   };
diff --git a/nix/profiles/home-manager/dev.nix b/nix/profiles/home-manager/dev.nix
index a7b1df7..9a8db09 100644
--- a/nix/profiles/home-manager/dev.nix
+++ b/nix/profiles/home-manager/dev.nix
@@ -5,17 +5,21 @@
 let
   pythonEnv = pkgs.python3.withPackages (p:
     with p; [
+      beautifulsoup4
       black
       click
+      ipython
       isort
-      python-lsp-server
+      pip
+      prettytable
       pylsp-mypy
       python-lsp-ruff
-      ruff-lsp
+      python-lsp-server
       requests
+      ruff-lsp
+      termcolor
+      types-beautifulsoup4
       types-requests
-      pip
-      ipython
       virtualenv
     ]);
 in
diff --git a/nix/profiles/home-manager/shell.nix b/nix/profiles/home-manager/shell.nix
index 83be24d..bf63775 100644
--- a/nix/profiles/home-manager/shell.nix
+++ b/nix/profiles/home-manager/shell.nix
@@ -32,6 +32,7 @@
     self.packages.${pkgs.system}.ipconverter
     self.packages.${pkgs.system}.seqstat
     self.packages.${pkgs.system}.slocalc
+    self.packages.${pkgs.system}.pizza
   ];
 
   xdg = {
diff --git a/packages/pizza/default.nix b/packages/pizza/default.nix
new file mode 100644
index 0000000..cf5e836
--- /dev/null
+++ b/packages/pizza/default.nix
@@ -0,0 +1,31 @@
+{ lib, python3 }:
+
+python3.pkgs.buildPythonApplication rec {
+  pname = "pizza";
+  src = ./pizza.py;
+  version = "0.1.0";
+  format = "other";
+
+  buildInputs = [ python3 ];
+  propagatedBuildInputs = with python3.pkgs; [
+    beautifulsoup4
+    prettytable
+    requests
+    termcolor
+  ];
+
+  dontUnpack = true;
+  dontBuild = true;
+
+  installPhase = ''
+    mkdir -p $out/bin
+    cp $src $out/bin/${pname}
+  '';
+
+  meta = with lib; {
+    description = "Get the pizza for the week for CheeseBoard.";
+    license = with licenses; [ mit ];
+    platforms = platforms.unix;
+    maintainers = with maintainers; [ fcuny ];
+  };
+}
diff --git a/packages/pizza/pizza.py b/packages/pizza/pizza.py
new file mode 100755
index 0000000..727d2af
--- /dev/null
+++ b/packages/pizza/pizza.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python3
+
+from bs4 import BeautifulSoup
+import requests
+from prettytable import PrettyTable
+from textwrap import fill
+from termcolor import colored
+
+
+url = "https://cheeseboardcollective.coop/pizza/"
+
+content = requests.get(url)
+soup = BeautifulSoup(content.text, "html.parser")
+
+magic_ingredients = ["corn"]
+
+table = PrettyTable()
+table.field_names = ["date", "pizza"]
+table.align = "l"
+
+pizzas = soup.select(".pizza-list > article")
+for pizza in pizzas:
+    date_color = "white"
+    menu_color = "white"
+
+    date = pizza.find(class_="date").text
+
+    # the pizza is the 1st element, the 2nd is the salad, and i don't
+    # care about the salad :)
+    menu = (
+        pizza.select(".menu > p:nth-of-type(1)")[0]
+        .get_text(strip=True, separator="\n")
+        .split("\n")
+    )
+
+    if "closed" in menu[0]:
+        date_color = "red"
+
+    if "Parbake pizza is available" in menu[0]:
+        menu.pop(0)
+
+    if "Lunch from" in menu[0]:
+        menu.pop(0)
+
+    if "No hot pizza today" in menu[0]:
+        menu.pop(0)
+
+    final_menu = "".join(menu)
+
+    for ingredient in magic_ingredients:
+        if ingredient in final_menu:
+            menu_color = "yellow"
+
+    table.add_row(
+        [colored(date, date_color), fill(colored(final_menu, menu_color), width=80)]
+    )
+
+print(table)