From 57e567a9436af6fc4b38a4d9d9c4e33d235e7f08 Mon Sep 17 00:00:00 2001 From: Nathan Lowe Date: Thu, 12 Dec 2019 22:02:59 -0500 Subject: [PATCH] Update problem generator to fetch input --- gen/problem.go | 121 ++++++++++++++++++++++++++++++++++++------------- go.mod | 5 ++ go.sum | 14 ++++++ 3 files changed, 109 insertions(+), 31 deletions(-) diff --git a/gen/problem.go b/gen/problem.go index 7d24bee..b6aaa32 100644 --- a/gen/problem.go +++ b/gen/problem.go @@ -3,6 +3,8 @@ package main import ( "fmt" "io" + "io/ioutil" + "net/http" "os" "os/exec" "path/filepath" @@ -10,6 +12,9 @@ import ( "strconv" "strings" "text/template" + "time" + + "github.com/zellyn/kooky" ) const ( @@ -80,47 +85,111 @@ func main() { } m := metadata{N: n, AB: ab} - funcs := template.FuncMap{ "toLower": strings.ToLower, } - challengeTemplate := template.Must(template.New("challenge").Funcs(funcs).Parse(problemTemplate)) - cf, err := os.Create(filepath.Join(p, fmt.Sprintf("%s.go", strings.ToLower(ab)))) - if err != nil { + genFile(filepath.Join(p, fmt.Sprintf("%s.go", strings.ToLower(ab))), problemTemplate, funcs, m) + genFile(filepath.Join(p, fmt.Sprintf("%s_test.go", strings.ToLower(ab))), testTemplate, funcs, m) + + goimports := exec.Command("goimports", "-w", p) + if err := goimports.Run(); err != nil { abort(err) } - defer mustClose(cf) - if err := challengeTemplate.Execute(cf, m); err != nil { - abort(err) + if _, stat := os.Stat(filepath.Join(p, "input.txt")); os.IsNotExist(stat) { + fmt.Println("fetching input for day", n) + problemInput, err := getInput(n) + if err != nil { + panic(err) + } + + if err := ioutil.WriteFile(filepath.Join(p, "input.txt"), problemInput, 0644); err != nil { + panic(err) + } + } else { + fmt.Println("input already downloaded, skipping...") } - testTemplate := template.Must(template.New("test").Funcs(funcs).Parse(testTemplate)) - tf, err := os.Create(filepath.Join(p, fmt.Sprintf("%s_test.go", strings.ToLower(ab)))) + fmt.Printf("Generated problem %s for day %d. Be sure to add it to main.go\n", ab, n) + + // TODO: Can we modify main.go easily? +} + +func genFile(path, t string, funcs template.FuncMap, m metadata) { + if _, stat := os.Stat(path); os.IsNotExist(stat) { + fmt.Println("creating", path) + t := template.Must(template.New(path).Funcs(funcs).Parse(t)) + cf, err := os.Create(path) + if err != nil { + abort(err) + } + + defer mustClose(cf) + if err := t.Execute(cf, m); err != nil { + abort(err) + } + } else { + fmt.Println(path, "already exists, skipping...") + } +} + +func chromeCookiePath() (string, error) { + if p, set := os.LookupEnv("CHROME_PROFILE_PATH"); set { + return filepath.Join(p, "Cookies"), nil + } + + if runtime.GOOS == "windows" { + localAppData, err := os.UserCacheDir() + return filepath.Join(localAppData, "Google", "Chrome", "User Data", "Default", "Cookies"), err + } + + return "", fmt.Errorf("chrome cookie path for GOOS %s not implemented, set CHROME_PROFILE_PATH instead", runtime.GOOS) +} + +func getInput(day int) ([]byte, error) { + cookiePath, err := chromeCookiePath() if err != nil { - abort(err) + return nil, err } - defer mustClose(tf) - if err := testTemplate.Execute(tf, m); err != nil { - abort(err) + _, _ = os.UserConfigDir() + _, _ = os.UserCacheDir() + cookies, err := kooky.ReadChromeCookies(cookiePath, ".adventofcode.com", "session", time.Time{}) + if err != nil { + return nil, err } - goimports := exec.Command("goimports", "-w", p) - if err := goimports.Run(); err != nil { - abort(err) + if len(cookies) == 0 { + return nil, fmt.Errorf("session cookie not found, ensure that you are logged in") } - input, err := os.OpenFile(filepath.Join(p, "input.txt"), os.O_CREATE|os.O_APPEND, 0644) + req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("https://adventofcode.com/2019/day/%d/input", day), nil) if err != nil { - abort(err) + return nil, err } - defer mustClose(input) - fmt.Printf("Generated problem %s for day %d. Be sure to add it to main.go\n", ab, n) + sessionToken := cookies[0].HttpCookie() + req.AddCookie(&sessionToken) - // TODO: Can we modify main.go easily? + resp, err := http.DefaultClient.Do(req) + if err != nil { + return nil, err + } + defer mustClose(resp.Body) + + body, err := ioutil.ReadAll(resp.Body) + return body, err +} + +func mustClose(c io.Closer) { + if c == nil { + return + } + + if err := c.Close(); err != nil { + panic(fmt.Errorf("error closing io.Closer: %w", err)) + } } func pkgPath(day int) string { @@ -136,13 +205,3 @@ func abort(err error) { fmt.Printf("%s\n\nsyntax: go run gen/problem.go \n", err.Error()) os.Exit(1) } - -func mustClose(c io.Closer) { - if c == nil { - return - } - - if err := c.Close(); err != nil { - panic(fmt.Errorf("error closing io.Closer: %w", err)) - } -} diff --git a/go.mod b/go.mod index a6d39e5..cdba4ae 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,9 @@ module github.com/nlowe/aoc2019 go 1.13 require ( + github.com/go-sqlite/sqlite3 v0.0.0-20180313105335-53dd8e640ee7 // indirect + github.com/gonuts/binary v0.2.0 // indirect + github.com/keybase/go-keychain v0.0.0-20191114153608-ccd67945d59e // indirect github.com/magiconair/properties v1.8.1 github.com/pelletier/go-toml v1.6.0 // indirect github.com/pkg/profile v1.4.0 @@ -12,6 +15,8 @@ require ( github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/viper v1.5.0 github.com/stretchr/testify v1.4.0 + github.com/zalando/go-keyring v0.0.0-20191212171435-ac5f1d08068b // indirect + github.com/zellyn/kooky v0.0.0-20190514172626-f2bb24889ec7 golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9 // indirect golang.org/x/text v0.3.2 // indirect gopkg.in/yaml.v2 v2.2.7 // indirect diff --git a/go.sum b/go.sum index e86916e..fec76f3 100644 --- a/go.sum +++ b/go.sum @@ -18,6 +18,7 @@ github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/danieljoos/wincred v1.0.2/go.mod h1:SnuYRW9lp1oJrZX/dXJqr0cPK5gYXqx3EJbmjhLdK9U= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -29,7 +30,11 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-sqlite/sqlite3 v0.0.0-20180313105335-53dd8e640ee7 h1:ow5vK9Q/DSKkxbEIJHBST6g+buBDwdaDIyk1dGGwpQo= +github.com/go-sqlite/sqlite3 v0.0.0-20180313105335-53dd8e640ee7/go.mod h1:JxSQ+SvsjFb+p8Y+bn+GhTkiMfKVGBD0fq43ms2xw04= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/godbus/dbus v4.1.0+incompatible h1:WqqLRTsQic3apZUK9qC5sGNfXthmPXzUZ7nQPrNITa4= +github.com/godbus/dbus v4.1.0+incompatible/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -37,6 +42,8 @@ github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4er github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/gonuts/binary v0.2.0 h1:caITwMWAoQWlL0RNvv2lTU/AHqAJlVuu6nZmNgfbKW4= +github.com/gonuts/binary v0.2.0/go.mod h1:kM+CtBrCGDSKdv8WXTuCUsw+loiy8f/QEI8YCCC0M/E= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= @@ -49,6 +56,8 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/keybase/go-keychain v0.0.0-20191114153608-ccd67945d59e h1:M88A1cGUWZRErgbiGFZ6OFOXCCeCKdVRFoSa+t+vgfY= +github.com/keybase/go-keychain v0.0.0-20191114153608-ccd67945d59e/go.mod h1:JJNrCn9otv/2QP4D7SMJBgaleKpOf66PnW6F5WGNRIc= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -124,12 +133,17 @@ github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8 h1:3SVOIvH7Ae1KRYy github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/zalando/go-keyring v0.0.0-20191212171435-ac5f1d08068b h1:1qTomCI2pk/vHuNDwNoIE9/sFZCmASzjKYy7AkbjKA4= +github.com/zalando/go-keyring v0.0.0-20191212171435-ac5f1d08068b/go.mod h1:RaxNwUITJaHVdQ0VC7pELPZ3tOWn13nr0gZMZEhpVU0= +github.com/zellyn/kooky v0.0.0-20190514172626-f2bb24889ec7 h1:wgs0+Ml8DOQbCBLlIPPjPdBUMQxRlhE6H4OmXRW6irY= +github.com/zellyn/kooky v0.0.0-20190514172626-f2bb24889ec7/go.mod h1:45MAFn3o6erpJrzlrSmsJBaUNWhz5YyM9lxj/nyXDjM= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=