Browse Source

first commit

lotus 1 year ago
commit
d43a00501b
5 changed files with 276 additions and 0 deletions
  1. 11 0
      LICENSE.md
  2. 40 0
      README.md
  3. 17 0
      makefile
  4. 45 0
      simple-weather.1
  5. 163 0
      simple-weather.rb

File diff suppressed because it is too large
+ 11 - 0
LICENSE.md


+ 40 - 0
README.md

@@ -0,0 +1,40 @@
+# simple-weather
+
+### Installation
+
+> You need to have a Ruby interpreter installed to use this tool
+
+Simply run:
+```bash
+# as root
+make install
+# to uninstall
+make uninstall
+```
+
+The reasoning behind this tool is that it provides a way to get the bare minimum of information you need. All the CLI weather tools I've used, while nice, have not been very 'script-friendly'. This tool gives you only the bare minimum of what you ask for. Each item is separated by a new line. I've intentionally left out some items present in the OpenWeatherMap reponse simply because most of the time I never look at them.
+
+> Note: You will need to sign up for a free OpenWeatherMap [API key][https://openweathermap.org] in order to use this tool
+
+### Usage
+```bash
+sw -t -l seattle -k myapikeyhere           # get the temperature in seattle"
+sw -c -l seattle -k myapikeyhere           # get the 'condition' i.e. sunny, cloudy, etc."
+sw -w -l seattle -k myapikeyhere           # get the windspeed"
+sw -tcw -u m -l seattle -k myapikeyhere    # get all three, and use metric units"
+sw -h                                      # show this help message"
+sw -v                                      # show version"
+
+# note the order of arguments does not matter
+```
+
+### Limitations
+- No zip code support
+- English only
+- Metric and Imperial units only
+
+### License / Disclaimer
+This project is licensed under the 3-clause BSD license. (See LICENSE.md)
+I take no responsibility for you blowing stuff up.
+Artwork courtesy of BLANK (CC 3.0 BY)
+

+ 17 - 0
makefile

@@ -0,0 +1,17 @@
+PREFIX ?= /usr/local
+BINDIR ?= $(PREFIX)/bin
+MANDIR ?= $(PREFIX)/man/man1
+
+all: help
+
+help:
+	@echo "please run 'make install' as root"
+install:
+	cp ./simple-weather.rb $(BINDIR)/simple-weather
+	ln -s $(BINDIR)/simple-weather $(BINDIR)/sw
+	cp ./simple-weather.1 $(MANDIR)
+uninstall:
+	rm $(BINDIR)/simple-weather
+	rm $(BINDIR)/sw
+	rm $(MANDIR)/simple-weather.1
+

+ 45 - 0
simple-weather.1

@@ -0,0 +1,45 @@
+.TH SIMPLE-WEATHER 1
+.SH NAME
+simple-weather (sw) \- get plaintext weather information
+.SH SYNOPSIS
+.B simple-weather
+[\fB-l\fR \fIcity\fR]
+[\fB-k\fR \fIyourapikey\fR]
+[\fB-t\fR]
+[\fB-c\fR]
+[\fB-u\fR]
+[\fB-w\fR]
+[\fB-h\fR]
+[\fB-v\fR]
+.IR
+.SH DESCRIPTION
+.B simple-weather (sw)
+gets plaintext weather info, useful for piping into scripts. Each item is seperated by a newline. For this application you must sign up for a free API key from Open Weather Map.
+.SH OPTIONS
+.TP
+.BR -k " " \fI{32 character long API key}\fR
+Include your API key (aka appid) from OpenWeatherMap [REQUIRED]
+.TP
+.BR -u " " \fIm\fR
+Specify that you want Metric units (defaults to imperial)
+.TP
+.BR -t " "
+Specify that you want temperature returned
+.TP
+.BR -l " " \fIseattle\fR
+Use Seattle as your location [REQUIRED]
+.TP
+.BR -w "      "
+Specify that you want windspeed returned
+.TP
+.BR -c "      "
+Specify that you want 'condition' returned (i.e. showers, sunny, partly cloudy, etc.)
+.TP
+.BR -k " " \fIyourapikeyhere\fR
+Pass in your API key (aka appid) for Open Weather Map
+.TP
+.BR -h "      "
+Display help information.
+.TP
+.BR -v
+Display version information.

+ 163 - 0
simple-weather.rb

@@ -0,0 +1,163 @@
+#!/usr/bin/env ruby
+# coding: utf-8
+#
+# simple-weather - get plaintext weather information
+#
+# author: git.zerohack.xyz/lotus
+# license: BSD 3-clause
+
+
+require "optparse"
+require "json"
+require "net/http"
+
+
+# this class handles talking with OWM
+class SW
+  
+  API_VER = "2.5"
+  DEG_I = "°F"
+  DEG_M = "°C"
+  SPEED_I = "mph"
+  SPEED_M = "kph"
+  CONDS = {:sunny => "☀", :rain => "☔", :drizzle => "☔", :cloudy => "☁"}
+  @@base_api_url = "https://api.openweathermap.org/data/#{API_VER}/weather"
+  
+  def initialize(k, loc, u="imperial")
+    @api_key = k
+    @location = loc
+    if(u == "m")
+      @units = "metric"
+      @deg = DEG_M
+      @speed = SPEED_M
+    else
+      @units = u
+      @deg = DEG_I
+      @speed = SPEED_I
+    end
+  end
+
+  private def parse_resp(response, flags)
+    ret_hash = JSON.parse(response)
+    if(flags.key?(:condition))
+      puts ret_hash["weather"][0]["main"]
+    end
+    if(flags.key?(:temp))
+      puts "#{ret_hash["main"]["temp"]}#{@deg}"
+    end
+    if(flags.key?(:wind))
+      puts "#{ret_hash["wind"]["speed"]} #{@speed}"
+    end
+    return true
+  end
+  
+  private def get_request()
+    uri = URI(@@base_api_url)
+    params = { :q => @location, :units => @units, :appid => @api_key }
+    uri.query = URI.encode_www_form(params)
+    return Net::HTTP.get_response(uri)
+  end
+
+  # startup request/parse response action
+  def run(flags)
+    response = get_request()
+    if response.is_a?(Net::HTTPSuccess)
+      return parse_resp(response.body, flags)
+    else
+      puts "Error talking to OpenWeatherMap"
+      puts response
+      return false
+    end
+  end
+
+end #end SW class
+
+
+# parses through the args that were passed in
+class ParseArgs
+
+  VERSION = "0.1"
+
+  def initialize()
+    @args = {}
+    @flags = {}
+  end
+
+  def parse()
+    OptionParser.new do |parser|
+      parser.banner = "Usage: simple-weather [options]"
+      parser.on('-h', '--help', 'Show this help message') do |help|
+        puts parser.to_s
+        exit(0)
+      end
+      parser.on('-v', '--version', 'Show the version number') do |ver|
+        @flags[:version] = true
+        puts "simple-weather version: #{VERSION}"
+        exit(0)
+      end
+      parser.on('-k', '--key=KEY', 'Your Open Weather Map API key (aka appid)') do |key|
+        @args[:key] = key
+      end
+      parser.on('-l', '--key=LOCATION', 'Choose the location you wish to check') do |location|
+        @args[:location] = location
+      end
+      parser.on('-u', '--units=[UNITS]', 'Choose imperial or metric units (default: imperial)') do |units|
+        @args[:units] = units
+      end
+      parser.on('-t', '--temp', 'Return the current temperature') do |temp|
+        @flags[:temp] = true
+      end
+      parser.on('-w', '--wind', 'Return the windspeed') do |wind|
+        @flags[:wind] = true
+      end
+      parser.on('-c', '--condition', 'Return the "condition" i.e. clear, sunny, overcast, etc.') do |cond|
+        @flags[:condition] = true
+      end
+    end.parse!
+  end # end parse method
+
+  
+  private def check_args()
+    if(!@args.key?(:key))
+        return false
+    elsif(!@args.key?(:location))
+      return false
+    else
+      if(@args[:key].length != 32)
+        return false
+      elsif(@args.key?(:units) && (@args[:units] != 'i' || @args[:units] != 'm'))
+        return false
+      else
+        return true
+      end
+    end
+  end # end check_args
+
+
+  def run()
+    parse()
+    if(!check_args())
+      puts "Missing required argument(s)"
+      puts "type 'simple-weather -h' to view the help info"
+    else
+      if(@args.key?(:units))
+        sw_obj = SW.new(@args[:key], @args[:location], @args[:units])
+      else
+        sw_obj = SW.new(@args[:key], @args[:location])
+      end
+      return sw_obj.run(@flags)
+    end
+  end # end run
+
+  
+end # end class
+
+
+# -- ENTRY POINT --
+options = parse_obj = ParseArgs.new()
+ok = parse_obj.run()
+if(!ok)
+  exit(1)
+else
+  exit(0)
+end