Skip to content

Instantly share code, notes, and snippets.

@trekdemo
Created September 14, 2018 22:36
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save trekdemo/76a2b66bae455dd2348085012e07f3fa to your computer and use it in GitHub Desktop.
Save trekdemo/76a2b66bae455dd2348085012e07f3fa to your computer and use it in GitHub Desktop.
Show the 3 day forecast from Windfinder
#!/usr/bin/env ruby
# <bitbar.title>Windfinder </bitbar.title>
# <bitbar.version>v1.0</bitbar.version>
# <bitbar.author>Gergő Sulymosi</bitbar.author>
# <bitbar.author.github>trekdemo</bitbar.author.github>
# <bitbar.desc>Show the 3 day forecast from Windfinder</bitbar.desc>
# <bitbar.image></bitbar.image>
# <bitbar.dependencies>ruby</bitbar.dependencies>
# <bitbar.abouturl></bitbar.abouturl>
SPOTS = %w[
ijmuiden
muiderzand
markermeer_schellinkhout
]
require 'nokogiri'
require 'rainbow'
require "open-uri"
# ==============================================================================
# PARSING
# ==============================================================================
def fetch_spot(name)
url = "https://www.windfinder.com/widget/forecast/#{name}?show_pressure=0&unit_temperature=c&show_day=1&show_rain=1&unit_rain=mm&days=3&unit_wind=kts&show_clouds=0&version=2&show_wind=1&show_temperature=1&show_waves=0&columns=2&unit_wave=m"
html_string = open(url){ |f| f.read }
document = Nokogiri::HTML(html_string)
widget_title = document.at_css('.widget-title').text.strip
link = 'https://www.windfinder.com' + document.at_css('a#title-link').attr('href')
data = document.search('.weathertable').map do |node|
day_date = node.at('.weathertable__header').text.strip
daily_data = node.search('.weathertable__row').map do |node|
{
hour: node.at_css('.cell-timespan').text.strip,
direction: node.at_css('.directionarrow').attr('title').strip.to_i,
speed: node.at_css('.speed').text.strip.to_i,
gust: node.at_css('.data-gusts').text.gsub(/max[^\d+]/, '').strip.to_i,
rain: node.at_css('.data-rain').text.strip.to_i,
temp: node.at_css('.data-temp').text.strip.to_i,
}
end
[day_date, daily_data]
end
[widget_title, link, data]
end
# ==============================================================================
# FORMATTING
# ==============================================================================
ARROWS = '↓↙←↖↑↗→↘'.split('') # 0 -> 360
def colored_speed(speed)
string = Rainbow(format('%2d', speed))
case speed
when 0..6 then string.blue
when 7..15 then string.green
when 16..23 then string.yellow
else string.red
end
end
def colored_menu(speed)
case speed
when 0..6 then 'blue'
when 7..15 then 'lightblue'
when 16..23 then 'green'
else 'red'
end
end
def render_spot(name)
title, link, data = *fetch_spot(name)
puts format('%s | href=%s', title, link)
data.each do |day_date, hourly_data|
puts format('-- %s', Rainbow(day_date).bright)
hourly_data.each do |data|
puts format(
'-- %s (%s) %s / %s | color=%s',
Rainbow(data[:hour]).bright,
ARROWS[(data[:direction] / 45.0).round % 8],
colored_speed(data[:speed]),
colored_speed(data[:gust]),
colored_menu(data[:speed])
)
end
puts '--'
end
end
# ==============================================================================
# RENDERING
# ==============================================================================
# puts 'Windfinder'
puts ':surfer:'
puts '---'
SPOTS.each do |name|
render_spot(name)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment