Initial commit
This commit is contained in:
302
vendor/github.com/briandowns/openweathermap/openweathermap.go
generated
vendored
Normal file
302
vendor/github.com/briandowns/openweathermap/openweathermap.go
generated
vendored
Normal file
@@ -0,0 +1,302 @@
|
||||
// Copyright 2022 Brian J. Downs
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package openweathermap
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
errUnitUnavailable = errors.New("unit unavailable")
|
||||
errLangUnavailable = errors.New("language unavailable")
|
||||
errInvalidKey = errors.New("invalid api key")
|
||||
errInvalidOption = errors.New("invalid option")
|
||||
errInvalidHttpClient = errors.New("invalid http client")
|
||||
errForecastUnavailable = errors.New("forecast unavailable")
|
||||
errExcludesUnavailable = errors.New("onecall excludes unavailable")
|
||||
errCountOfCityIDs = errors.New("count of ids should not be more than 20 per request")
|
||||
)
|
||||
|
||||
// DataUnits represents the character chosen to represent the temperature notation
|
||||
var DataUnits = map[string]string{"C": "metric", "F": "imperial", "K": "internal"}
|
||||
var (
|
||||
baseURL = "https://api.openweathermap.org/data/2.5/weather?%s"
|
||||
onecallURL = "https://api.openweathermap.org/data/3.0/onecall?%s"
|
||||
iconURL = "https://openweathermap.org/img/w/%s"
|
||||
groupURL = "http://api.openweathermap.org/data/2.5/group?%s"
|
||||
stationURL = "https://api.openweathermap.org/data/2.5/station?id=%d"
|
||||
forecast5Base = "https://api.openweathermap.org/data/2.5/forecast?appid=%s&%s&mode=json&units=%s&lang=%s&cnt=%d"
|
||||
forecast16Base = "https://api.openweathermap.org/data/2.5/forecast/daily?appid=%s&%s&mode=json&units=%s&lang=%s&cnt=%d"
|
||||
historyURL = "https://api.openweathermap.org/data/2.5/history/%s"
|
||||
pollutionURL = "https://api.openweathermap.org/data/2.5/air_pollution?appid=%s&lat=%s&lon=%s"
|
||||
uvURL = "https://api.openweathermap.org/data/2.5/"
|
||||
dataPostURL = "https://openweathermap.org/data/post"
|
||||
)
|
||||
|
||||
// LangCodes holds all supported languages to be used
|
||||
// inspried and sourced from @bambocher (github.com/bambocher)
|
||||
var LangCodes = map[string]string{
|
||||
"AF": "Afrikaans",
|
||||
"AL": "Albanian",
|
||||
"AR": "Arabic",
|
||||
"AZ": "Azerbaijani",
|
||||
"BG": "Bulgarian",
|
||||
"CA": "Catalan",
|
||||
"CZ": "Czech",
|
||||
"DA": "Danish",
|
||||
"DE": "German",
|
||||
"EL": "Greek",
|
||||
"EN": "English",
|
||||
"ES": "Spanish",
|
||||
"EU": "Basque",
|
||||
"FA": "Persian (Farsi)",
|
||||
"FI": "Finnish",
|
||||
"FR": "French",
|
||||
"GL": "Galician",
|
||||
"HE": "Hebrew",
|
||||
"HI": "Hindi",
|
||||
"HR": "Croatian",
|
||||
"HU": "Hungarian",
|
||||
"ID": "Indonesian",
|
||||
"IT": "Italian",
|
||||
"JA": "Japanese",
|
||||
"KR": "Korean",
|
||||
"LA": "Latvian",
|
||||
"LT": "Lithuanian",
|
||||
"MK": "Macedonian",
|
||||
"NL": "Dutch",
|
||||
"NO": "Norwegian",
|
||||
"PL": "Polish",
|
||||
"PT": "Portuguese",
|
||||
"PT_BR": "Português Brasil",
|
||||
"RO": "Romanian",
|
||||
"RU": "Russian",
|
||||
"SE": "Swedish",
|
||||
"SK": "Slovak",
|
||||
"SL": "Slovenian",
|
||||
"SP": "Spanish",
|
||||
"SR": "Serbian",
|
||||
"SV": "Swedish",
|
||||
"TH": "Thai",
|
||||
"TR": "Turkish",
|
||||
"UA": "Ukrainian",
|
||||
"UK": "Ukrainian",
|
||||
"VI": "Vietnamese",
|
||||
"ZH_CN": "Chinese Simplified",
|
||||
"ZH_TW": "Chinese Traditional",
|
||||
"ZU": "Zulu",
|
||||
}
|
||||
|
||||
// Exclude holds all supported excludes option to be used
|
||||
const (
|
||||
ExcludeCurrent = "current"
|
||||
ExcludeMinutely = "minutely"
|
||||
ExcludeHourly = "hourly"
|
||||
ExcludeDaily = "daily"
|
||||
ExcludeAlerts = "alerts"
|
||||
)
|
||||
|
||||
var Excludes []string = []string{
|
||||
ExcludeCurrent,
|
||||
ExcludeMinutely,
|
||||
ExcludeHourly,
|
||||
ExcludeDaily,
|
||||
ExcludeAlerts,
|
||||
}
|
||||
|
||||
// Config will hold default settings to be passed into the
|
||||
// "NewCurrent, NewForecast, etc}" functions.
|
||||
type Config struct {
|
||||
Mode string // user choice of JSON or XML
|
||||
Unit string // measurement for results to be displayed. F, C, or K
|
||||
Lang string // should reference a key in the LangCodes map
|
||||
APIKey string // API Key for connecting to the OWM
|
||||
Username string // Username for posting data
|
||||
Password string // Pasword for posting data
|
||||
}
|
||||
|
||||
// APIError returned on failed API calls.
|
||||
type APIError struct {
|
||||
Message string `json:"message"`
|
||||
COD string `json:"cod"`
|
||||
}
|
||||
|
||||
// Coordinates struct holds longitude and latitude data in returned
|
||||
// JSON or as parameter data for requests using longitude and latitude.
|
||||
type Coordinates struct {
|
||||
Longitude float64 `json:"lon"`
|
||||
Latitude float64 `json:"lat"`
|
||||
}
|
||||
|
||||
// Sys struct contains general information about the request
|
||||
// and the surrounding area for where the request was made.
|
||||
type Sys struct {
|
||||
Type int `json:"type"`
|
||||
ID int `json:"id"`
|
||||
Message float64 `json:"message"`
|
||||
Country string `json:"country"`
|
||||
Sunrise int `json:"sunrise"`
|
||||
Sunset int `json:"sunset"`
|
||||
}
|
||||
|
||||
// Wind struct contains the speed and degree of the wind.
|
||||
type Wind struct {
|
||||
Speed float64 `json:"speed"`
|
||||
Deg float64 `json:"deg"`
|
||||
}
|
||||
|
||||
// Weather struct holds high-level, basic info on the returned
|
||||
// data.
|
||||
type Weather struct {
|
||||
ID int `json:"id"`
|
||||
Main string `json:"main"`
|
||||
Description string `json:"description"`
|
||||
Icon string `json:"icon"`
|
||||
}
|
||||
|
||||
// Main struct contains the temperates, humidity, pressure for the request.
|
||||
type Main struct {
|
||||
Temp float64 `json:"temp"`
|
||||
TempMin float64 `json:"temp_min"`
|
||||
TempMax float64 `json:"temp_max"`
|
||||
FeelsLike float64 `json:"feels_like"`
|
||||
Pressure float64 `json:"pressure"`
|
||||
SeaLevel float64 `json:"sea_level"`
|
||||
GrndLevel float64 `json:"grnd_level"`
|
||||
Humidity int `json:"humidity"`
|
||||
}
|
||||
|
||||
// Clouds struct holds data regarding cloud cover.
|
||||
type Clouds struct {
|
||||
All int `json:"all"`
|
||||
}
|
||||
|
||||
// return key
|
||||
// }
|
||||
func setKey(key string) (string, error) {
|
||||
if err := ValidAPIKey(key); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return key, nil
|
||||
}
|
||||
|
||||
// ValidDataUnit makes sure the string passed in is an accepted
|
||||
// unit of measure to be used for the return data.
|
||||
func ValidDataUnit(u string) bool {
|
||||
for d := range DataUnits {
|
||||
if u == d {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ValidLangCode makes sure the string passed in is an
|
||||
// acceptable lang code.
|
||||
func ValidLangCode(c string) bool {
|
||||
for d := range LangCodes {
|
||||
if c == d {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ValidDataUnitSymbol makes sure the string passed in is an
|
||||
// acceptable data unit symbol.
|
||||
func ValidDataUnitSymbol(u string) bool {
|
||||
for _, d := range DataUnits {
|
||||
if u == d {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ValidExcludes makes sure the string passed in is an
|
||||
// acceptable excludes options.
|
||||
func ValidExcludes(e []string) (string, error) {
|
||||
list := make([]string, 0)
|
||||
for _, v := range e {
|
||||
vl := strings.ToLower(v)
|
||||
notFound := true
|
||||
|
||||
for _, d := range Excludes {
|
||||
if d == vl {
|
||||
list = append(list, v)
|
||||
notFound = false
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if notFound {
|
||||
return "", errExcludesUnavailable
|
||||
}
|
||||
}
|
||||
return strings.Join(list, ","), nil
|
||||
}
|
||||
|
||||
// ValidAPIKey makes sure that the key given is a valid one
|
||||
func ValidAPIKey(key string) error {
|
||||
if len(key) > 64 {
|
||||
return errInvalidKey
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CheckAPIKeyExists will see if an API key has been set.
|
||||
func (c *Config) CheckAPIKeyExists() bool { return len(c.APIKey) > 1 }
|
||||
|
||||
// Settings holds the client settings
|
||||
type Settings struct {
|
||||
client *http.Client
|
||||
}
|
||||
|
||||
// NewSettings returns a new Setting pointer with default http client.
|
||||
func NewSettings() *Settings {
|
||||
return &Settings{
|
||||
client: http.DefaultClient,
|
||||
}
|
||||
}
|
||||
|
||||
// Optional client settings
|
||||
type Option func(s *Settings) error
|
||||
|
||||
// WithHttpClient sets custom http client when creating a new Client.
|
||||
func WithHttpClient(c *http.Client) Option {
|
||||
return func(s *Settings) error {
|
||||
if c == nil {
|
||||
return errInvalidHttpClient
|
||||
}
|
||||
s.client = c
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// setOptions sets Optional client settings to the Settings pointer
|
||||
func setOptions(settings *Settings, options []Option) error {
|
||||
for _, option := range options {
|
||||
if option == nil {
|
||||
return errInvalidOption
|
||||
}
|
||||
err := option(settings)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user