Skip to content

Instantly share code, notes, and snippets.

@bnortman
Last active May 1, 2018 16:58
Show Gist options
  • Save bnortman/8ba51efc0ae9ac50c92b67a7cad2ebe3 to your computer and use it in GitHub Desktop.
Save bnortman/8ba51efc0ae9ac50c92b67a7cad2ebe3 to your computer and use it in GitHub Desktop.
Weather API Call
package main
import (
"encoding/json"
"io/ioutil"
"log"
"net/http"
"strconv"
"sync"
"time"
"github.com/gin-gonic/gin"
)
var waitGrp sync.WaitGroup
type Weather struct {
Latitude float64 `json:"latitude"`
Longitude float64 `json:"longitude"`
Timezone string `json:"timezone"`
Daily struct {
Data []struct {
Time int `json:"time"`
Summary string `json:"summary"`
Icon string `json:"icon"`
SunriseTime int `json:"sunriseTime"`
SunsetTime int `json:"sunsetTime"`
MoonPhase float64 `json:"moonPhase"`
PrecipIntensity float64 `json:"precipIntensity"`
PrecipIntensityMax float64 `json:"precipIntensityMax"`
PrecipIntensityMaxTime int `json:"precipIntensityMaxTime"`
PrecipProbability float64 `json:"precipProbability"`
PrecipAccumulation float64 `json:"precipAccumulation"`
PrecipType string `json:"precipType"`
TemperatureHigh float64 `json:"temperatureHigh"`
TemperatureHighTime int `json:"temperatureHighTime"`
TemperatureLow float64 `json:"temperatureLow"`
TemperatureLowTime int `json:"temperatureLowTime"`
ApparentTemperatureHigh float64 `json:"apparentTemperatureHigh"`
ApparentTemperatureHighTime int `json:"apparentTemperatureHighTime"`
ApparentTemperatureLow float64 `json:"apparentTemperatureLow"`
ApparentTemperatureLowTime int `json:"apparentTemperatureLowTime"`
DewPoint float64 `json:"dewPoint"`
Humidity float64 `json:"humidity"`
Pressure float64 `json:"pressure"`
WindSpeed float64 `json:"windSpeed"`
WindGust float64 `json:"windGust"`
WindGustTime int `json:"windGustTime"`
WindBearing int `json:"windBearing"`
CloudCover float64 `json:"cloudCover"`
UvIndex int `json:"uvIndex"`
UvIndexTime int `json:"uvIndexTime"`
Visibility float64 `json:"visibility"`
Ozone float64 `json:"ozone"`
TemperatureMin float64 `json:"temperatureMin"`
TemperatureMinTime int `json:"temperatureMinTime"`
TemperatureMax float64 `json:"temperatureMax"`
TemperatureMaxTime int `json:"temperatureMaxTime"`
ApparentTemperatureMin float64 `json:"apparentTemperatureMin"`
ApparentTemperatureMinTime int `json:"apparentTemperatureMinTime"`
ApparentTemperatureMax float64 `json:"apparentTemperatureMax"`
ApparentTemperatureMaxTime int `json:"apparentTemperatureMaxTime"`
} `json:"data"`
} `json:"daily"`
Flags struct {
Sources []string `json:"sources"`
IsdStations []string `json:"isd-stations"`
Units string `json:"units"`
} `json:"flags"`
Offset int `json:"offset"`
}
func getWeatherAtTime(waitGrp *sync.WaitGroup, workQueue chan Weather, lat string, long string, daysBack int) {
log.Println("Working for time")
urlDarkSky := "https://api.darksky.net/forecast/"
secretKey := "8639c348aac30cef51ba318d5e8783e1"
tailUrl := "?exclude=hourly,currently,minutely,alerts,flag"
timePoint := time.Now().Unix() - (int64(daysBack) * 60 * 60 * int64(24))
timeStr := strconv.FormatInt(timePoint, 10)
log.Println(timeStr)
requestUrl := urlDarkSky + secretKey + "/" + lat + "," + long + "," + timeStr + tailUrl
log.Printf("Lat=%s, Long=%s Weather Requested.", lat, long)
log.Println(requestUrl)
weatherData, err := http.Get(requestUrl)
if err != nil {
log.Println(err)
return
}
data, _ := ioutil.ReadAll(weatherData.Body)
weatherData.Body.Close()
var weatherObject Weather
err = json.Unmarshal(data, &weatherObject)
if err != nil {
log.Fatal(err)
}
workQueue <- weatherObject
waitGrp.Done()
}
func getWeather(cntx *gin.Context) {
lat := cntx.Params.ByName("lat")
long := cntx.Params.ByName("long")
//weatherTimeMap := make(map[string]string)
log.Printf("Lat=%s, Long=%s Weather Requested.", lat, long)
weatherWorkQueue := make(chan Weather, 10)
log.Println("Starting Loop")
for i := 6; i >= 0; i-- {
log.Printf("Request %d days ago", i)
waitGrp.Add(1)
go getWeatherAtTime(&waitGrp, weatherWorkQueue, lat, long, i)
}
log.Println("After Loop - Waiting")
waitGrp.Wait()
log.Println("Done Waiting")
close(weatherWorkQueue)
var weatherDays = make([]Weather, 0)
cnt := 0
for weatherDay := range weatherWorkQueue {
cnt++
log.Printf("Working on another WeatherDay %d", cnt)
weatherDays = append(weatherDays, weatherDay)
log.Printf("Finished %d", cnt)
}
//TODO Handle Sort Order from Async Callsw
log.Println("Weather Array")
returnWeather, _ := json.Marshal(&weatherDays)
log.Println(string(returnWeather))
cntx.JSON(http.StatusOK, string(returnWeather))
}
func main() {
log.Println("Starting GoLang Weather API Service.")
routes := gin.Default()
versionRoutes := routes.Group("/api/v1")
{
weatherRoutes := versionRoutes.Group("/weather")
{
weatherRoutes.GET("/:lat/:long", getWeather)
}
}
routes.Run(":3001")
log.Println("Ending GoLang Weather API Services.")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment