summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--main.go65
-rw-r--r--templates/search.tmpl50
2 files changed, 115 insertions, 0 deletions
diff --git a/main.go b/main.go
index 11cde3b..503938a 100644
--- a/main.go
+++ b/main.go
@@ -16,6 +16,7 @@ import (
"time"
"ricketyspace.net/peach/nws"
+ "ricketyspace.net/peach/photon"
)
// peach port. defaults to 8151
@@ -61,6 +62,13 @@ type WeatherTimeline struct {
Periods []WeatherPeriod
}
+type Search struct {
+ Title string
+ Location string
+ Message string
+ MatchingCoords []photon.Coordinates
+}
+
func init() {
flag.Parse()
if *peachPort < 80 {
@@ -73,6 +81,9 @@ func main() {
// static files handler.
http.Handle("/static/", http.FileServer(http.FS(peachFS)))
+ // search handler.
+ http.HandleFunc("/search", showSearch)
+
// default handler.
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/" {
@@ -95,6 +106,8 @@ func main() {
}
showWeather(w, float32(lat), float32(lng))
})
+
+ // start server
log.Fatal(http.ListenAndServe(peachAddr, nil))
}
@@ -127,9 +140,28 @@ func showWeather(w http.ResponseWriter, lat, lng float32) {
// render.
err = peachTemplates.ExecuteTemplate(w, "weather.tmpl", weather)
if err != nil {
+ log.Printf("weather: template: %v", err)
+ return
+ }
+}
+
+func showSearch(w http.ResponseWriter, r *http.Request) {
+ // Search is disabled if photon is not enabled.
+ if !photon.Enabled() {
+ http.NotFound(w, r)
+ return
+ }
+
+ search, err := NewSearch(r)
+ if err != nil {
http.Error(w, err.Error(), 500)
return
}
+ err = peachTemplates.ExecuteTemplate(w, "search.tmpl", search)
+ if err != nil {
+ log.Printf("search: template: %v", err)
+ return
+ }
}
func NewWeather(point *nws.NWSPoint, f, fh *nws.NWSForecast) (*Weather, error) {
@@ -178,3 +210,36 @@ func NewWeather(point *nws.NWSPoint, f, fh *nws.NWSForecast) (*Weather, error) {
return w, nil
}
+
+func NewSearch(r *http.Request) (*Search, error) {
+ s := new(Search)
+ s.Title = "search"
+
+ if r.Method == "GET" {
+ return s, nil
+ }
+
+ // get location.
+ err := r.ParseForm()
+ if err != nil {
+ return s, fmt.Errorf("form: %v", err)
+ }
+ location := strings.TrimSpace(r.PostForm.Get("location"))
+ s.Location = location
+ if len(location) < 2 {
+ s.Message = "location invalid"
+ }
+
+ // try to fetch matching coordinates.
+ s.MatchingCoords, err = photon.Geocode(location)
+ if err != nil {
+ log.Printf("search: geocode: %v", err)
+ s.Message = "unable to lookup location"
+ return s, nil
+ }
+ if len(s.MatchingCoords) < 1 {
+ s.Message = "location not found"
+ return s, nil
+ }
+ return s, nil
+}
diff --git a/templates/search.tmpl b/templates/search.tmpl
new file mode 100644
index 0000000..a6d7cff
--- /dev/null
+++ b/templates/search.tmpl
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="UTF-8">
+ <title>peach - {{.Title}}</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <meta name="author" content="siddharth ravikumar">
+ <link rel="preload" href="/static/peach.css" as="style" />
+ <style>@import url("/static/peach.css");</style>
+ </head>
+ <body>
+ <div class="peach">
+ <div class="root-container">
+
+ <div class="search-container">
+ <form method="post">
+ <div class="search-box">
+ <input type="text" class="location" placeholder="us city"
+ value="{{ .Location }}" name="location" required>
+ </div>
+ <div class="search-btn">
+ <input type="submit" value="search">
+ </div>
+ </form>
+ </div>
+
+ {{ if .Message }}
+ <div class="message-container">
+ <div class="message-block">
+ <p>{{ .Message }}</p>
+ </div>
+ </div>
+ {{ end }}
+
+ {{ if .MatchingCoords }}
+ <div class="search-result-container">
+ {{ range .MatchingCoords }}
+ <div class="item">
+ <div class="location-name">
+ <a href="/{{ printf "%.4f,%.4f" .Lat .Lng }}">{{ .Name }}</a>
+ </div>
+ </div>
+ {{ end }}
+ </div>
+ {{ end }}
+
+ </div> <!-- root-container end -->
+ </div> <!-- peach end -->
+ </body>
+</html>