[Breaking Change] Another overhaul of the code
This was made possible by the previous overhaul and cleanup * Code now uses strings.Builder instead of slices * Fixed --add-frame flag to only work for PNG * Moved --format to only work as ?format= * Added --free-style to replace previous --format functionality * Added explicit --download flag to download instead of print * Added explicit --file-name flag to specify a file name to use * Renamed --extra-information to --export-mode * Updated the --export-mode with more useful information
This commit is contained in:
parent
d43443f885
commit
826d262d42
1 changed files with 118 additions and 55 deletions
173
main.go
173
main.go
|
@ -79,12 +79,17 @@ func (w weather) print(resp *http.Response) {
|
|||
|
||||
// `weather` method to download the weather
|
||||
func (w weather) download(resp *http.Response) {
|
||||
splitURL := strings.Split(w.url, "/")
|
||||
filename := splitURL[len(splitURL)-1]
|
||||
var fName string
|
||||
if *fileName != "" {
|
||||
fName = *fileName
|
||||
} else {
|
||||
splitURL := strings.Split(w.url, "/")
|
||||
fName = splitURL[len(splitURL)-1]
|
||||
}
|
||||
|
||||
f, err := os.Create(filename)
|
||||
f, err := os.Create(fName)
|
||||
if err != nil {
|
||||
return
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
|
@ -104,76 +109,116 @@ func getWheather(url string, headers map[string]string, download bool) {
|
|||
// This will figure out if we need to download the PNG image
|
||||
// as well.
|
||||
func generateParamFormat() (string, bool, error) {
|
||||
var params []string
|
||||
var prefix []string
|
||||
var download bool
|
||||
var params strings.Builder
|
||||
var prefix = "?"
|
||||
var downloadMode = *download
|
||||
|
||||
prefix = append(prefix, "?")
|
||||
|
||||
// If --format is specified, let's not bother and simply return it
|
||||
if *format != "" {
|
||||
return *format, false, nil
|
||||
// If --free-syle is specified, let's not bother and simply return it
|
||||
if *freeStyle != "" {
|
||||
return *freeStyle, downloadMode, nil
|
||||
}
|
||||
|
||||
// If --format is specified, let's return the format the user wants
|
||||
if *format != "" {
|
||||
var str strings.Builder
|
||||
str.WriteString("?format=\"")
|
||||
str.WriteString(*format)
|
||||
str.WriteString("\"")
|
||||
return str.String(), downloadMode, nil
|
||||
}
|
||||
// If --one-liner is specified, we know the format is set so let's return it
|
||||
if *oneLiner {
|
||||
return "?format=3", false, nil
|
||||
return "?format=3", downloadMode, nil
|
||||
}
|
||||
|
||||
for i := range switches {
|
||||
if *switches[i] {
|
||||
params = append(params, switchesFlags[i])
|
||||
params.WriteString(switchesFlags[i])
|
||||
}
|
||||
}
|
||||
|
||||
if *png {
|
||||
prefix[0] = "_"
|
||||
prefix = "_"
|
||||
|
||||
if *transparency >= 0 && *transparency <= 100 {
|
||||
params = append(params, strings.Join([]string{"_transparency=", string(*transparency)}, ""))
|
||||
if *addFrame {
|
||||
params.WriteString(switchesFlags[12])
|
||||
}
|
||||
|
||||
params = append(params, ".png")
|
||||
download = true
|
||||
if *transparency >= 0 && *transparency <= 255 {
|
||||
params.WriteString("_transparency=")
|
||||
params.WriteString(string(*transparency))
|
||||
}
|
||||
|
||||
params.WriteString(".png")
|
||||
downloadMode = true
|
||||
}
|
||||
|
||||
params = append(prefix, strings.Join(params, ""))
|
||||
var affix strings.Builder
|
||||
affix.WriteString(prefix)
|
||||
affix.WriteString(params.String())
|
||||
|
||||
return strings.Join(params, ""), download, nil
|
||||
return affix.String(), downloadMode, nil
|
||||
}
|
||||
|
||||
// Defining the command-line interface
|
||||
var (
|
||||
app = kingpin.New("go-cmw", "A small terminal wrapper around the wttr.in weather endpoint.")
|
||||
location = app.Flag("location", "Specify explicite location").Short('L').OverrideDefaultFromEnvar("GO_CMW_LOCATION").String()
|
||||
language = app.Flag("language", "Specify explicite language").Short('l').OverrideDefaultFromEnvar("GO_CMW_LANGUAGE").String()
|
||||
v2 = app.Flag("v2", "Display Data-Rich output").Default("false").Bool()
|
||||
switches = [13]*bool{
|
||||
app.Flag("metric", "Display weather in metric").Short('m').Default("false").Bool(),
|
||||
app.Flag("uscs", "Display weather in imperial").Short('u').Default("false").Bool(),
|
||||
app.Flag("meter-second", "Display wind in m/s").Short('M').Default("false").Bool(),
|
||||
app.Flag("zero", "Show the weather now").Short('z').Default("false").Bool(),
|
||||
app.Flag("one", "Show the weather for one day").Short('o').Default("false").Bool(),
|
||||
app.Flag("two", "Show the weather for two days").Short('w').Default("false").Bool(),
|
||||
app.Flag("ignore-user-agent", "Request ignoring the user agent").Short('A').Default("false").Bool(),
|
||||
app.Flag("follow-link", "Follow link redirect").Short('F').Default("true").Bool(),
|
||||
app.Flag("narrow", "Display weather in narrow view").Short('n').Default("false").Bool(),
|
||||
app.Flag("quiet", "Add the quiet flag").Short('q').Default("false").Bool(),
|
||||
app.Flag("super-quiet", "Add the super quiet flag").Short('Q').Default("false").Bool(),
|
||||
app.Flag("no-colors", "Disable displaying colors (always enabled on windows").Short('N').Default("false").Bool(),
|
||||
app.Flag("add-frame", "Add a frame to the output").Short('p').Default("false").Bool()}
|
||||
png = app.Flag("png", "Download a weather PNG image").Short('P').Default("false").Bool()
|
||||
v2 = app.Flag("v2", "Use the v2 endpoint").Default("false").Bool()
|
||||
transparency = app.Flag("transparency", "Set transparency level (0-100) (PNG only)").Short('t').Default("0").Int()
|
||||
format = app.Flag("format", "Query format (overrides everything else)").Short('f').OverrideDefaultFromEnvar("GO_CMW_FORMAT").String()
|
||||
location = app.Flag("location", "Specify explicite location").Short('L').OverrideDefaultFromEnvar("GO_CMW_LOCATION").String()
|
||||
language = app.Flag("language", "Specify explicite language").Short('l').OverrideDefaultFromEnvar("GO_CMW_LANGUAGE").String()
|
||||
oneLiner = app.Flag("one-liner", "One liner outpet (for the terminal multiplexer lovers out there)").Short('O').Default("false").Bool()
|
||||
extraInformation = app.Flag("extra-information", "Print extra information").Default("false").Bool()
|
||||
app.Flag("zero", "Display current weather").Short('z').Default("false").Bool(),
|
||||
app.Flag("one", "Display current weather + 1 day").Short('o').Default("false").Bool(),
|
||||
app.Flag("two", "Display current weather + 2 days").Short('w').Default("false").Bool(),
|
||||
app.Flag("ignore-user-agent", "Ignore User-Agent and force ANSI output").Short('A').Default("false").Bool(),
|
||||
app.Flag("follow-link", "Do not display the 'Follow' line").Short('F').Default("true").Bool(),
|
||||
app.Flag("narrow", "Display narrow view (only day/night)").Short('n').Default("false").Bool(),
|
||||
app.Flag("quiet", "Display quiet version (no weather report)").Short('q').Default("false").Bool(),
|
||||
app.Flag("super-quiet", "Display super quiet version (no weather report and no city)").Short('Q').Default("false").Bool(),
|
||||
app.Flag("no-colors", "Display no colors (always enabled on windows").Short('N').Default("false").Bool()}
|
||||
|
||||
png = app.Flag("png", "Download a weather PNG image").Short('P').Default("false").Bool()
|
||||
addFrame = app.Flag("add-frame", "Add a frame to the output (PNG only)").Short('p').Default("false").Bool()
|
||||
transparency = app.Flag("transparency", "Set transparency level (0-255) (PNG only)").OverrideDefaultFromEnvar("GO_CMW_TRANSPARENCY").Short('t').Default("0").Int()
|
||||
download = app.Flag("download", "Enables download mode").Short('d').Default("false").Bool()
|
||||
fileName = app.Flag("file-name", "Name download file").OverrideDefaultFromEnvar("GO_CMW_FILE_NAME").Default("").String()
|
||||
oneLiner = app.Flag("one-liner", "One liner outpet (for the terminal multiplexer lovers out there)").Short('O').Default("false").Bool()
|
||||
format = app.Flag("format", "Specify a format query (e.g. \"%l:+%c+%t\") (--expert-mode)").OverrideDefaultFromEnvar("GO_CMW_FORMAT").String()
|
||||
freeStyle = app.Flag("free-style", "Specify a free-style API call (--expert-mode)").OverrideDefaultFromEnvar("GO_CMW_FREE_STYLE").String()
|
||||
expertMode = app.Flag("expert-mode", "Print expert mode information").Default("false").Bool()
|
||||
)
|
||||
|
||||
// Special help menu
|
||||
func printExtraInformation() {
|
||||
func printExpertMode() {
|
||||
eInfo := `
|
||||
Expert Mode
|
||||
-----------
|
||||
|
||||
All commands flagged with --expert-mode override
|
||||
values/flags added by go-cmw.
|
||||
|
||||
This gives the user full control over
|
||||
the queries requested.
|
||||
|
||||
Environment Variables
|
||||
---------------------
|
||||
|
||||
go-cmw makes use of the following environment
|
||||
variables:
|
||||
|
||||
* GO_CMW_LOCATION for --location
|
||||
* GO_CMW_LANGUAGE for --language
|
||||
* GO_CMW_FORMAT for --format
|
||||
* GO_CMW_FREE_STYLE for --free-style
|
||||
* GO_CMW_FILE_NAME for --file-name
|
||||
* GO_CMW_TRANSPARENCY for --transparency
|
||||
|
||||
Supported Location Types
|
||||
------------------------
|
||||
|
||||
City name: Paris
|
||||
Unicode name: Москва
|
||||
Airport code (3 letters): muc
|
||||
|
@ -183,16 +228,33 @@ GPS coordinates: -78.46,106.79
|
|||
|
||||
Special Location
|
||||
----------------
|
||||
|
||||
Moon phase (add ,+US or
|
||||
,+France for these cities): moon
|
||||
Moon phase for a date: moon@2016-10-25
|
||||
|
||||
Format Flags (--format)
|
||||
------------
|
||||
|
||||
c Weather condition
|
||||
C Weather condition textual name
|
||||
h Humidity
|
||||
t Temperature
|
||||
w Wind
|
||||
l Location
|
||||
m Moonphase
|
||||
M Moonday
|
||||
p precipitation (mm)
|
||||
o Probability of Precipitation
|
||||
P pressure (hPa)
|
||||
|
||||
Supported languages
|
||||
-------------------
|
||||
|
||||
Supported: af da de el et fr fa hu id it nb nl
|
||||
pl pt-br ro ru tr uk vi
|
||||
`
|
||||
Supported: af be ca da de el et fr fa hu id it
|
||||
nb nl pl pt-br ro ru tr th uk vi
|
||||
zh-cn zh-tw
|
||||
`
|
||||
|
||||
println(eInfo)
|
||||
}
|
||||
|
@ -206,8 +268,8 @@ func flagParser() {
|
|||
|
||||
kingpin.MustParse(app.Parse(os.Args[1:]))
|
||||
|
||||
if *extraInformation {
|
||||
printExtraInformation()
|
||||
if *expertMode {
|
||||
printExpertMode()
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
|
@ -219,38 +281,39 @@ func flagParser() {
|
|||
}
|
||||
|
||||
// Create a function to generate the url that we'll be calling shortly.
|
||||
func generateURL(domain string, v2 bool, location string, lang string, affix string) ([]string, map[string]string) {
|
||||
var link []string
|
||||
func generateURL(domain string, v2 bool, location string, lang string, affix string) (string, map[string]string) {
|
||||
var link strings.Builder
|
||||
var headers = make(map[string]string)
|
||||
|
||||
link = append(link, "https://")
|
||||
link.WriteString("https://")
|
||||
|
||||
if v2 {
|
||||
link = append(link, "v2.")
|
||||
link.WriteString("v2.")
|
||||
}
|
||||
|
||||
link = append(link, domain, "/")
|
||||
link.WriteString(domain)
|
||||
link.WriteString("/")
|
||||
|
||||
if location != "" {
|
||||
link = append(link, location)
|
||||
link.WriteString(location)
|
||||
}
|
||||
|
||||
if affix != "" {
|
||||
link = append(link, affix)
|
||||
link.WriteString(affix)
|
||||
}
|
||||
|
||||
if lang != "" {
|
||||
headers["Accept-Language"] = lang
|
||||
}
|
||||
|
||||
return link, headers
|
||||
return link.String(), headers
|
||||
}
|
||||
|
||||
// This is the main function that glues everything together.
|
||||
func main() {
|
||||
var domain string = "wttr.in"
|
||||
flagParser()
|
||||
affix, download, _ := generateParamFormat()
|
||||
affix, downloadFile, _ := generateParamFormat()
|
||||
link, headers := generateURL(domain, *v2, *location, *language, affix)
|
||||
getWheather(strings.Join(link, ""), headers, download)
|
||||
getWheather(link, headers, downloadFile)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue