mirror of https://github.com/chubin/wttr.in
parent
08794675a7
commit
c398d9204d
@ -0,0 +1,41 @@
|
|||||||
|
package location
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/chubin/wttr.in/internal/routing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Response provides routing interface to the geo cache.
|
||||||
|
func (c *Cache) Response(r *http.Request) *routing.Cadre {
|
||||||
|
var (
|
||||||
|
locationName = r.URL.Query().Get("location")
|
||||||
|
loc *Location
|
||||||
|
bytes []byte
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
if locationName == "" {
|
||||||
|
return errorResponse("location is not specified")
|
||||||
|
}
|
||||||
|
|
||||||
|
loc, err = c.Resolve(locationName)
|
||||||
|
if err != nil {
|
||||||
|
return errorResponse(fmt.Sprint(err))
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes, err = json.Marshal(loc)
|
||||||
|
if err != nil {
|
||||||
|
return errorResponse(fmt.Sprint(err))
|
||||||
|
}
|
||||||
|
|
||||||
|
return &routing.Cadre{Body: bytes}
|
||||||
|
}
|
||||||
|
|
||||||
|
func errorResponse(s string) *routing.Cadre {
|
||||||
|
return &routing.Cadre{Body: []byte(
|
||||||
|
fmt.Sprintf(`{"error": %q}`, s),
|
||||||
|
)}
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
package location
|
||||||
|
|
||||||
|
import "github.com/chubin/wttr.in/internal/config"
|
||||||
|
|
||||||
|
type Provider interface {
|
||||||
|
Query(location string) (*Location, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Searcher struct {
|
||||||
|
providers []Provider
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewSearcher returns a new Searcher for the specified config.
|
||||||
|
func NewSearcher(config *config.Config) *Searcher {
|
||||||
|
providers := []Provider{}
|
||||||
|
for _, p := range config.Geo.Nominatim {
|
||||||
|
providers = append(providers, NewNominatim(p.Name, p.URL, p.Token))
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Searcher{
|
||||||
|
providers: providers,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search makes queries through all known providers,
|
||||||
|
// and returns response, as soon as it is not nil.
|
||||||
|
// If all responses were nil, the last response is returned.
|
||||||
|
func (s *Searcher) Search(location string) (*Location, error) {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
result *Location
|
||||||
|
)
|
||||||
|
|
||||||
|
for _, p := range s.providers {
|
||||||
|
result, err = p.Query(location)
|
||||||
|
if result != nil && err == nil {
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, err
|
||||||
|
}
|
Loading…
Reference in new issue