Last active
May 1, 2018 16:58
-
-
Save bnortman/8ba51efc0ae9ac50c92b67a7cad2ebe3 to your computer and use it in GitHub Desktop.
Weather API Call
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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