Remove cloudfn support
This commit is contained in:
parent
0ecc755b66
commit
34a78e6010
8 changed files with 2 additions and 2045 deletions
13
README.md
13
README.md
|
@ -6,16 +6,5 @@ Match patterns and solve anagrams - handy for crossword fanatics.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd standalone
|
cd standalone
|
||||||
go run main.go
|
go run main.go --listen :3000
|
||||||
```
|
|
||||||
|
|
||||||
## Cloud Function
|
|
||||||
|
|
||||||
To test using the Cloud Functions Framework:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
env FUNCTION_TARGET=WordSearch WORDLIST_BUCKET=word-search-1729-assets \
|
|
||||||
WORDLIST_PATH=data/wordlist.txt LOCAL_ONLY=true go run ./cmd/fn-framework-test/main.go
|
|
||||||
|
|
||||||
curl 'http://localhost:8080?mode=anagrams&pattern=idea'
|
|
||||||
```
|
```
|
||||||
|
|
137
cloudfn.go
137
cloudfn.go
|
@ -1,137 +0,0 @@
|
||||||
package wordsearch
|
|
||||||
|
|
||||||
import (
|
|
||||||
"embed"
|
|
||||||
"encoding/gob"
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
"sort"
|
|
||||||
"text/template"
|
|
||||||
|
|
||||||
"github.com/GoogleCloudPlatform/functions-framework-go/functions"
|
|
||||||
"github.com/ray1729/wordsearch/anagram"
|
|
||||||
"github.com/ray1729/wordsearch/match"
|
|
||||||
"github.com/rs/cors"
|
|
||||||
)
|
|
||||||
|
|
||||||
var anagramDB anagram.DB
|
|
||||||
var matchDB match.DB
|
|
||||||
|
|
||||||
func initializeDB() error {
|
|
||||||
anagrams, err := fs.Open("data/anagram.bin")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer anagrams.Close()
|
|
||||||
if err := gob.NewDecoder(anagrams).Decode(&anagramDB); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
matches, err := fs.Open("data/match.bin")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer matches.Close()
|
|
||||||
if err := gob.NewDecoder(matches).Decode(&matchDB); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
log.Println("Initializing databases")
|
|
||||||
if err := initializeDB(); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
corsHandler := cors.New(cors.Options{
|
|
||||||
AllowedOrigins: []string{"*"},
|
|
||||||
AllowedHeaders: []string{"*"},
|
|
||||||
AllowedMethods: []string{http.MethodPost},
|
|
||||||
AllowCredentials: false,
|
|
||||||
MaxAge: 3600,
|
|
||||||
})
|
|
||||||
log.Println("Registering HTTP function with the Functions Framework")
|
|
||||||
functions.HTTP("WordSearch", func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
corsHandler.ServeHTTP(w, r, handleFormSubmission)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func handleFormSubmission(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if err := r.ParseForm(); err != nil {
|
|
||||||
log.Printf("error parsing form: %v", err)
|
|
||||||
http.Error(w, "error parsing form", http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
mode := r.Form.Get("mode")
|
|
||||||
pattern := r.Form.Get("pattern")
|
|
||||||
if len(pattern) == 0 {
|
|
||||||
http.Error(w, "Missing pattern", http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
switch mode {
|
|
||||||
case "match":
|
|
||||||
results := matchResults(matchDB, pattern)
|
|
||||||
renderTemplate(w, resultsTmpl, results)
|
|
||||||
case "anagrams":
|
|
||||||
results := anagramResults(anagramDB, pattern)
|
|
||||||
renderTemplate(w, resultsTmpl, results)
|
|
||||||
default:
|
|
||||||
log.Printf("invalid mode: %s", mode)
|
|
||||||
http.Error(w, fmt.Sprintf("Invalid mode: %s", mode), http.StatusBadRequest)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func anagramResults(db anagram.DB, pattern string) ResultParams {
|
|
||||||
var params ResultParams
|
|
||||||
params.Results = db.FindAnagrams(pattern)
|
|
||||||
if len(params.Results) > 0 {
|
|
||||||
params.Preamble = fmt.Sprintf("Anagrams of %q:", pattern)
|
|
||||||
} else {
|
|
||||||
params.Preamble = fmt.Sprintf("Found no anagrams of %q", pattern)
|
|
||||||
}
|
|
||||||
sort.Slice(params.Results, func(i, j int) bool { return params.Results[i] < params.Results[j] })
|
|
||||||
return params
|
|
||||||
}
|
|
||||||
|
|
||||||
func matchResults(db match.DB, pattern string) ResultParams {
|
|
||||||
var params ResultParams
|
|
||||||
params.Results = db.FindMatches(pattern)
|
|
||||||
if len(params.Results) > 0 {
|
|
||||||
params.Preamble = fmt.Sprintf("Matches for %q:", pattern)
|
|
||||||
} else {
|
|
||||||
params.Preamble = fmt.Sprintf("Found no matches for %q", pattern)
|
|
||||||
}
|
|
||||||
sort.Slice(params.Results, func(i, j int) bool { return params.Results[i] < params.Results[j] })
|
|
||||||
return params
|
|
||||||
}
|
|
||||||
|
|
||||||
func renderTemplate(w http.ResponseWriter, t *template.Template, params any) {
|
|
||||||
err := t.Execute(w, params)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("Error rendering template %s: %v", t.Name(), err)
|
|
||||||
http.Error(w, "Internal server error", http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type ResultParams struct {
|
|
||||||
Preamble string
|
|
||||||
Results []string
|
|
||||||
}
|
|
||||||
|
|
||||||
var resultsTmpl = template.Must(template.New("results").Parse(`
|
|
||||||
{{ with .Preamble }}
|
|
||||||
<p>{{ . }}</p>
|
|
||||||
{{ end }}
|
|
||||||
<ul>
|
|
||||||
{{ range .Results }}
|
|
||||||
<li>
|
|
||||||
{{.}}
|
|
||||||
<a href="https://dicoweb.gnu.org.ua/?q={{.}}&db=gcide&define=1" target="defn"><span class="small">GCIDE</span></a>
|
|
||||||
<a href="https://dicoweb.gnu.org.ua/?q={{.}}&db=WordNet&define=1" target="defn"><span class="small">WordNet</span></a>
|
|
||||||
</li>
|
|
||||||
{{ end }}
|
|
||||||
</ul>
|
|
||||||
`))
|
|
||||||
|
|
||||||
//go:embed data/*
|
|
||||||
var fs embed.FS
|
|
|
@ -1,29 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
// Blank-import the function package so the init() runs
|
|
||||||
"github.com/GoogleCloudPlatform/functions-framework-go/funcframework"
|
|
||||||
_ "github.com/ray1729/wordsearch"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
// Use PORT environment variable, or default to 8080.
|
|
||||||
port := "8080"
|
|
||||||
if envPort := os.Getenv("PORT"); envPort != "" {
|
|
||||||
port = envPort
|
|
||||||
}
|
|
||||||
|
|
||||||
// By default, listen on all interfaces. If testing locally, run with
|
|
||||||
// LOCAL_ONLY=true to avoid triggering firewall warnings and
|
|
||||||
// exposing the server outside of your own machine.
|
|
||||||
hostname := ""
|
|
||||||
if localOnly := os.Getenv("LOCAL_ONLY"); localOnly == "true" {
|
|
||||||
hostname = "127.0.0.1"
|
|
||||||
}
|
|
||||||
if err := funcframework.StartHostPort(hostname, port); err != nil {
|
|
||||||
log.Fatalf("funcframework.StartHostPort: %v\n", err)
|
|
||||||
}
|
|
||||||
}
|
|
BIN
data/anagram.bin
BIN
data/anagram.bin
Binary file not shown.
BIN
data/match.bin
BIN
data/match.bin
Binary file not shown.
|
@ -1,9 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
V=$(git describe --tags)
|
|
||||||
|
|
||||||
zip function.zip go.mod go.sum cloudfn.go match/match.go anagram/anagram.go util/util.go data/*.bin
|
|
||||||
|
|
||||||
gsutil cp function.zip gs://word-search-1729-assets/cloudfn/${V}/
|
|
17
go.mod
17
go.mod
|
@ -2,19 +2,4 @@ module github.com/ray1729/wordsearch
|
||||||
|
|
||||||
go 1.21.1
|
go 1.21.1
|
||||||
|
|
||||||
require (
|
require golang.org/x/text v0.14.0
|
||||||
github.com/GoogleCloudPlatform/functions-framework-go v1.8.1
|
|
||||||
github.com/rs/cors v1.10.1
|
|
||||||
golang.org/x/text v0.14.0
|
|
||||||
)
|
|
||||||
|
|
||||||
require (
|
|
||||||
cloud.google.com/go/functions v1.16.1 // indirect
|
|
||||||
github.com/cloudevents/sdk-go/v2 v2.15.2 // indirect
|
|
||||||
github.com/google/uuid v1.6.0 // indirect
|
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
|
||||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
|
||||||
go.uber.org/multierr v1.11.0 // indirect
|
|
||||||
go.uber.org/zap v1.27.0 // indirect
|
|
||||||
)
|
|
||||||
|
|
Loading…
Reference in a new issue