mirror of
https://github.com/chubin/wttr.in
synced 2025-01-25 18:24:59 +00:00
Add support for geoip cache db writing
This commit is contained in:
parent
a27541a25b
commit
4855adeaf6
2 changed files with 41 additions and 9 deletions
|
@ -59,6 +59,9 @@ func NewCache(config *config.Config) (*Cache, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// Needed for "upsert" implementation in Put()
|
||||
db.UseErrorParser()
|
||||
|
||||
return &Cache{
|
||||
config: config,
|
||||
db: db,
|
||||
|
@ -89,7 +92,7 @@ func (c *Cache) readFromCacheFile(addr string) (*Location, error) {
|
|||
if err != nil {
|
||||
return nil, ErrNotFound
|
||||
}
|
||||
return parseCacheEntry(addr, string(bytes))
|
||||
return NewLocationFromString(addr, string(bytes))
|
||||
}
|
||||
|
||||
func (c *Cache) readFromCacheDB(addr string) (*Location, error) {
|
||||
|
@ -103,14 +106,42 @@ func (c *Cache) readFromCacheDB(addr string) (*Location, error) {
|
|||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *Cache) Put(addr string, loc *Location) error {
|
||||
if c.config.Geo.CacheType == types.CacheTypeDB {
|
||||
return c.putToCacheDB(addr, loc)
|
||||
}
|
||||
return c.putToCacheFile(addr, loc)
|
||||
}
|
||||
|
||||
func (c *Cache) putToCacheDB(addr string, loc *Location) error {
|
||||
err := c.db.Insert(loc).Do()
|
||||
// it should work like this:
|
||||
//
|
||||
// target := dberror.UniqueConstraint{}
|
||||
// if errors.As(err, &target) {
|
||||
//
|
||||
// See: https://github.com/samonzeweb/godb/pull/23
|
||||
//
|
||||
// But for some reason it does not work,
|
||||
// so the dirty hack is used:
|
||||
if strings.Contains(fmt.Sprint(err), "UNIQUE constraint failed") {
|
||||
return c.db.Update(loc).Do()
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *Cache) putToCacheFile(addr string, loc *Location) error {
|
||||
return os.WriteFile(c.cacheFile(addr), []byte(loc.String()), 0644)
|
||||
}
|
||||
|
||||
// cacheFile retuns path to the cache entry for addr.
|
||||
func (c *Cache) cacheFile(addr string) string {
|
||||
return path.Join(c.config.Geo.IPCache, addr)
|
||||
}
|
||||
|
||||
// parseCacheEntry parses the location cache entry s,
|
||||
// NewLocationFromString parses the location cache entry s,
|
||||
// and return location, or error, if the cache entry is invalid.
|
||||
func parseCacheEntry(addr, s string) (*Location, error) {
|
||||
func NewLocationFromString(addr, s string) (*Location, error) {
|
||||
var (
|
||||
lat float64 = -1000
|
||||
long float64 = -1000
|
||||
|
@ -172,7 +203,12 @@ func (c *Cache) Response(r *http.Request) *routing.Cadre {
|
|||
return respERR
|
||||
}
|
||||
|
||||
err := c.putRaw(ip, value)
|
||||
location, err := NewLocationFromString(ip, value)
|
||||
if err != nil {
|
||||
return respERR
|
||||
}
|
||||
|
||||
err = c.Put(ip, location)
|
||||
if err != nil {
|
||||
return respERR
|
||||
}
|
||||
|
@ -193,10 +229,6 @@ func (c *Cache) Response(r *http.Request) *routing.Cadre {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (c *Cache) putRaw(addr, value string) error {
|
||||
return os.WriteFile(c.cacheFile(addr), []byte(value), 0644)
|
||||
}
|
||||
|
||||
func validIP4(ipAddress string) bool {
|
||||
re, _ := regexp.Compile(`^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$`)
|
||||
return re.MatchString(strings.Trim(ipAddress, " "))
|
||||
|
|
|
@ -68,7 +68,7 @@ func TestParseCacheEntry(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
result, err := parseCacheEntry(tt.addr, tt.input)
|
||||
result, err := NewLocationFromString(tt.addr, tt.input)
|
||||
if tt.err == nil {
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, *result, tt.expected)
|
||||
|
|
Loading…
Reference in a new issue