From d43443f8853d23d8e263d8ca32fc17243bf95ab9 Mon Sep 17 00:00:00 2001 From: Elia el Lazkani Date: Sat, 29 Feb 2020 10:34:00 +0100 Subject: [PATCH] Massive rehauling of the code. * Moved the code away from all the if statements and switches * Built a better foundation to build upon for future expension * BUGFIX: Now if windows users want to download a PNG it can be in color --- main.go | 275 +++++++++----------------------------------------------- 1 file changed, 44 insertions(+), 231 deletions(-) diff --git a/main.go b/main.go index d0db4ee..1c4b0b7 100644 --- a/main.go +++ b/main.go @@ -18,49 +18,8 @@ const VERSION = "0.0.5" // AUTHOR The author name const AUTHOR = "Elia el Lazkani" -// Create a list of constants to figure out -// the command line flags and translate them -// into uri flags. -const ( - METRIC = 1 << iota - USCS - METERSECOND - ZERO - ONE - TWO - IGNOREUSERAGENT - FOLLOWLINK - NARROW - QUIET - SUPERQUIET - NOCOLORS - ADDFRAME - MIDTRANSPARENCY - FORMAT - ONELINER - LOCATION - LANGUAGE - PNG - VTWO -) - -// Create a list of constants to define -// uri switches by flag. -const ( - MetricSwitch = "m" - UscsSwitch = "u" - MeterSecondSwitch = "M" - ZeroSwitch = "0" - OneSwitch = "1" - TwoSwitch = "2" - IgnoreUserAgentSwitch = "A" - FollowLinkSwitch = "F" - NarrowSwitch = "n" - QuietSwitch = "q" - SuperQuietSwitch = "Q" - NoColorsSwitch = "T" - AddFrameSwitch = "p" - MidTransparencySwitch = "T" +var ( + switchesFlags = []string{"m", "u", "M", "0", "1", "2", "A", "F", "n", "q", "Q", "T", "p"} ) // We create a weather struct with the url @@ -140,122 +99,66 @@ func getWheather(url string, headers map[string]string, download bool) { w.get(req, download) } -// Define a command parameters struct. -// This will hold all the configurations -// set by the command line parameters provided. -type cmdParams struct { - Flags int - Transparency int - Format string - Location string - Language string -} - // Create a method to figure out the command parameters // provided and translate them into uri parameters. // This will figure out if we need to download the PNG image // as well. -func (cmdP *cmdParams) generateParamFormat() (string, bool, error) { +func generateParamFormat() (string, bool, error) { var params []string - var affix []string + var prefix []string var download bool - affix = append(affix, "?") + + prefix = append(prefix, "?") // If --format is specified, let's not bother and simply return it + if *format != "" { + return *format, false, nil + } + // If --one-liner is specified, we know the format is set so let's return it - if cmdP.Flags&FORMAT == FORMAT || cmdP.Flags&ONELINER == ONELINER { - return cmdP.Format, false, nil + if *oneLiner { + return "?format=3", false, nil } - if cmdP.Flags&METRIC == METRIC { - params = append(params, MetricSwitch) - } - - if cmdP.Flags&USCS == USCS { - params = append(params, UscsSwitch) - } - - if cmdP.Flags&METERSECOND == METERSECOND { - params = append(params, MeterSecondSwitch) - } - - if cmdP.Flags&ZERO == ZERO { - params = append(params, ZeroSwitch) - } - - if cmdP.Flags&ONE == ONE { - params = append(params, OneSwitch) - } - - if cmdP.Flags&TWO == TWO { - params = append(params, TwoSwitch) - } - - if cmdP.Flags&IGNOREUSERAGENT == IGNOREUSERAGENT { - params = append(params, IgnoreUserAgentSwitch) - } - - if cmdP.Flags&FOLLOWLINK == FOLLOWLINK { - params = append(params, FollowLinkSwitch) - } - - if cmdP.Flags&NARROW == NARROW { - params = append(params, NarrowSwitch) - } - - if cmdP.Flags&QUIET == QUIET { - params = append(params, QuietSwitch) - } - - if cmdP.Flags&SUPERQUIET == SUPERQUIET { - params = append(params, SuperQuietSwitch) - } - - if cmdP.Flags&NOCOLORS == NOCOLORS { - params = append(params, NoColorsSwitch) - } - - if cmdP.Flags&ADDFRAME == ADDFRAME { - params = append(params, AddFrameSwitch) - } - - if cmdP.Flags&PNG == PNG { - affix[0] = "_" - - if cmdP.Flags&MIDTRANSPARENCY == MIDTRANSPARENCY { - params = append(params, MidTransparencySwitch) + for i := range switches { + if *switches[i] { + params = append(params, switchesFlags[i]) } + } - if cmdP.Transparency >= 0 && cmdP.Transparency <= 100 { - params = append(params, strings.Join([]string{"_transparency=", string(cmdP.Transparency)}, "")) + if *png { + prefix[0] = "_" + + if *transparency >= 0 && *transparency <= 100 { + params = append(params, strings.Join([]string{"_transparency=", string(*transparency)}, "")) } params = append(params, ".png") download = true } - params = append(affix, strings.Join(params, "")) + params = append(prefix, strings.Join(params, "")) return strings.Join(params, ""), download, nil } // Defining the command-line interface var ( - app = kingpin.New("go-cmw", "A small terminal wrapper around the wttr.in weather endpoint.") - metric = app.Flag("metric", "Display weather in metric").Short('m').Default("false").Bool() - uscs = app.Flag("uscs", "Display weather in imperial").Short('u').Default("false").Bool() - meterSecond = app.Flag("meter-second", "Display wind in m/s").Short('M').Default("false").Bool() - zero = app.Flag("zero", "Show the weather now").Short('z').Default("false").Bool() - one = app.Flag("one", "Show the weather for one day").Short('o').Default("false").Bool() - two = app.Flag("two", "Show the weather for two days").Short('w').Default("false").Bool() - ignoreUserAgent = app.Flag("ignore-user-agent", "Request ignoring the user agent").Short('A').Default("false").Bool() - followLink = app.Flag("follow-link", "Follow link redirect").Short('F').Default("true").Bool() - narrow = app.Flag("narrow", "Display weather in narrow view").Short('n').Default("false").Bool() - quiet = app.Flag("quiet", "Add the quiet flag").Short('q').Default("false").Bool() - superQuiet = app.Flag("super-quiet", "Add the super quiet flag").Short('Q').Default("false").Bool() - noColors = app.Flag("no-colors", "Disable displaying colors (always enabled on windows").Short('N').Default("false").Bool() - addFrame = app.Flag("add-frame", "Add a frame to the output").Short('p').Default("false").Bool() - midTransparency = app.Flag("mid-transparency", "Enable mid-transparency (PNG only)").Short('T').Default("false").Bool() + app = kingpin.New("go-cmw", "A small terminal wrapper around the wttr.in weather endpoint.") + 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() @@ -296,7 +199,7 @@ Supported: af da de el et fr fa hu id it nb nl // Create a function to parse all the command line parameters // provided and save them in the parameter struct. -func flagParser(cmdP *cmdParams) { +func flagParser() { app.Version(VERSION) app.Author(AUTHOR) @@ -307,101 +210,12 @@ func flagParser(cmdP *cmdParams) { printExtraInformation() os.Exit(0) } + // Windows does not have color encoding // so let's make sure windows users are happy - term := os.Getenv("TERM") - if term == "" { - *noColors = true + if os.Getenv("TERM") == "" && !*png { + *switches[11] = true } - - if *metric { - cmdP.Flags += METRIC - } - - if *uscs { - cmdP.Flags += USCS - } - - if *meterSecond { - cmdP.Flags += METERSECOND - } - - if *zero { - cmdP.Flags += ZERO - } - - if *one { - cmdP.Flags += ONE - } - - if *two { - cmdP.Flags += TWO - } - - if *ignoreUserAgent { - cmdP.Flags += IGNOREUSERAGENT - } - - if *followLink { - cmdP.Flags += FOLLOWLINK - } - - if *narrow { - cmdP.Flags += NARROW - } - - if *quiet { - cmdP.Flags += QUIET - } - - if *superQuiet { - cmdP.Flags += SUPERQUIET - } - - if *noColors { - cmdP.Flags += NOCOLORS - } - - if *addFrame { - cmdP.Flags += ADDFRAME - } - - if *midTransparency { - cmdP.Flags += MIDTRANSPARENCY - } - - if *transparency >= 0 && *transparency <= 100 { - cmdP.Transparency = *transparency - } - - if *png { - cmdP.Flags += PNG - } - - if *v2 { - cmdP.Flags += VTWO - } - - if *format != "" { - cmdP.Flags += FORMAT - cmdP.Format = *format - } - - if *location != "" { - cmdP.Flags += LOCATION - cmdP.Location = *location - } - - if *language != "" { - cmdP.Flags += LANGUAGE - cmdP.Language = *language - } - - if *oneLiner { - cmdP.Flags += ONELINER - cmdP.Format = "?format=3" - } - } // Create a function to generate the url that we'll be calling shortly. @@ -434,10 +248,9 @@ func generateURL(domain string, v2 bool, location string, lang string, affix str // This is the main function that glues everything together. func main() { - var params cmdParams = cmdParams{} var domain string = "wttr.in" - flagParser(¶ms) - affix, download, _ := params.generateParamFormat() - link, headers := generateURL(domain, params.Flags&VTWO == VTWO, params.Location, params.Language, affix) + flagParser() + affix, download, _ := generateParamFormat() + link, headers := generateURL(domain, *v2, *location, *language, affix) getWheather(strings.Join(link, ""), headers, download) }