Add dashboard

This commit is contained in:
2022-09-20 00:27:25 +01:00
parent bdfe02f776
commit e689c852e7
96 changed files with 16313 additions and 1 deletions

68
jobs/daily_xkcd.rb Normal file
View File

@@ -0,0 +1,68 @@
require 'net/http'
require 'json'
require 'date'
XKCD_URI = 'https://xkcd.com'
DATE_FORMAT_STR = '%B %-d, %Y'
$displayed_xkcd = nil
$prev_displayed_xkcd = nil
# Get's the nth xkcd entry, unless
# nil is passed, in which case current
def get_nth_xkcd(n)
uri = URI.join(XKCD_URI, n.to_s + '/', 'info.0.json')
response = Net::HTTP.get(uri)
JSON.parse(response)
end
# Get's the current, featured xkcd entry
def get_current_xkcd
get_nth_xkcd(nil)
end
# Get's a random xkcd
def get_random_xkcd
curr_id = get_current_xkcd['num']
random_id = nil
# 404 is reserved for Not found
while true do
random_id = rand(curr_id)
break if random_id != 404
end
get_nth_xkcd(random_id)
end
# Check if provided xkcd was published yesterday
def published_yesterday_and_unseen(xkcd_date, xkcd)
xkcd_date == Date.today.prev_day and ($prev_displayed_xkcd.nil? or not $prev_displayed_xkcd['num'] == xkcd['num'])
end
# Basic logic:
# - if an xkcd was published today, display it.
# - if an xkcd was published yesterday, and we didn't
# show it yesterday, display it.
# - otherwise, display a random xkcd.
SCHEDULER.every '1d', :first_in => 0 do |job|
$prev_displayed_xkcd = $displayed_xkcd
xkcd = get_current_xkcd
xkcd_date = Date.new(
xkcd['year'].to_i,
xkcd['month'].to_i,
xkcd['day'].to_i
)
if xkcd_date == Date.today or published_yesterday_and_unseen(xkcd_date, xkcd)
$displayed_xkcd = xkcd
else
$displayed_xkcd = get_random_xkcd
xkcd_date = Date.new(
$displayed_xkcd['year'].to_i,
$displayed_xkcd['month'].to_i,
$displayed_xkcd['day'].to_i
)
end
$displayed_xkcd['datestr'] = xkcd_date.strftime(DATE_FORMAT_STR)
send_event('xkcd-of-the-day', $displayed_xkcd)
end

94
jobs/national_rail.rb Normal file
View File

@@ -0,0 +1,94 @@
require 'uri'
require 'net/http'
require 'openssl'
require 'nokogiri'
require "json"
require 'active_support/all'
token = "05fcc54b-f553-47e9-b532-57b890134b24"
crss = ["station_code_1", "station_code_2"]
numRows = "8"
SCHEDULER.every "3m", :first_in => 0 do |job|
crss.each do |crs|
url = URI("https://lite.realtime.nationalrail.co.uk/OpenLDBWS/ldb6.asmx")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
# http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Post.new(url)
request["content-type"] = 'text/xml'
request["cache-control"] = 'no-cache'
request.body = "<?xml version=\"1.0\"?>\r\n<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ns1=\"http://thalesgroup.com/RTTI/2014-02-20/ldb/\" xmlns:ns2=\"http://thalesgroup.com/RTTI/2010-11-01/ldb/commontypes\">\r\n <SOAP-ENV:Header>\r\n <ns2:AccessToken>\r\n <ns2:TokenValue>#{token}</ns2:TokenValue>\r\n </ns2:AccessToken>\r\n </SOAP-ENV:Header>\r\n <SOAP-ENV:Body>\r\n <ns1:GetDepartureBoardRequest>\r\n <ns1:numRows>#{numRows}</ns1:numRows>\r\n <ns1:crs>#{crs}</ns1:crs>\r\n </ns1:GetDepartureBoardRequest>\r\n </SOAP-ENV:Body>\r\n</SOAP-ENV:Envelope>"
response = http.request(request)
parsed_json = Hash.from_xml(response.read_body).to_json
data = JSON.parse(parsed_json)
stationMessage = data.dig("Envelope", "Body", "GetDepartureBoardResponse", "GetStationBoardResult", "nrccMessages")
trains = []
digResult = data.dig("Envelope", "Body", "GetDepartureBoardResponse", "GetStationBoardResult", "trainServices","service")
if(digResult != nil)
services = data['Envelope']['Body']['GetDepartureBoardResponse']['GetStationBoardResult']['trainServices']['service']
if(services.kind_of?(Array))
data['Envelope']['Body']['GetDepartureBoardResponse']['GetStationBoardResult']['trainServices']['service'].each do |child|
isValidTime = Time.parse(child['etd']) rescue nil
if isValidTime
timeDiff = "- #{time_diff(child['std'].to_time.to_i , child['etd'].to_time.to_i )} min"
end
item = {
label: "#{child['destination']['location']['locationName']}",
value: "#{child['std']} (#{child['etd']}) #{timeDiff}",
}
trains.push(item)
end
if(stationMessage == nil)
send_event "NationalRail_#{crs}", { items: trains, message: ""}
else
message = stationMessage['message']
indexOf = stationMessage['message'].index "<A"
message.insert (indexOf.to_i + 2), " target='_blank'"
message = "Notice: #{message}"
send_event "NationalRail_#{crs}", { items: trains, message: message}
end
else
send_event "NationalRail_#{crs}", { items: [{label: "No more trains today", value: ":("}] }
end
else
send_event "NationalRail_#{crs}", { items: [{label: "No more trains today", value: ":("}] }
end
end
end
def time_diff(start_time, end_time)
seconds_diff = (start_time - end_time).to_i.abs
hours = seconds_diff / 3600
seconds_diff -= hours * 3600
minutes = seconds_diff / 60
end

21
jobs/quote.rb Normal file
View File

@@ -0,0 +1,21 @@
require 'net/http'
require 'uri'
require 'json'
server = "http://api.forismatic.com"
SCHEDULER.every '3h', :first_in => 0 do |job|
url = URI.parse("#{server}/api/1.0/?method=getQuote&key=&format=json&lang=en")
req = Net::HTTP::Get.new(url.to_s)
res = Net::HTTP.start(url.host, url.port) {|http|
http.request(req)
}
# Convert to JSON
j = JSON[res.body]
# Update the dashboard
send_event("quote", { text: j['quoteText'], moreinfo: j['quoteAuthor'] })
end

23
jobs/random_aww.rb Normal file
View File

@@ -0,0 +1,23 @@
require 'net/http'
require 'json'
require 'open-uri'
placeholder = '/assets/nyantocat.gif'
SCHEDULER.every '1h', first_in: 0 do |job|
# uri = URI('https://www.reddit.com/r/aww.json')
# response = Net::HTTP.get(uri)
response = URI.parse("https://www.reddit.com/r/aww.json").read
# puts(response)
json = JSON.parse(response)
if json['data']['children'].count <= 0
send_event('aww', image: placeholder)
else
urls = json['data']['children'].map{|child| child['data']['url'] }
# Ensure we're linking directly to an image, not a gallery etc.
valid_urls = urls.select{|url| url.downcase.end_with?('png', 'gif', 'jpg', 'jpeg')}
send_event('aww', image: "background-image:url(#{valid_urls.sample(1).first})")
end
end

66
jobs/server_status.rb Normal file
View File

@@ -0,0 +1,66 @@
#!/usr/bin/env ruby
require 'net/http'
require 'uri'
# Check whether a server is responding
# you can set a server to check via http request or ping
#
# server options:
# name: how it will show up on the dashboard
# url: either a website url or an IP address (do not include https:// when usnig ping method)
# method: either 'http' or 'ping'
# if the server you're checking redirects (from http to https for example) the check will
# return false
servers = [{name: 'name', url: 'url', method: 'http'},
{name: 'name', url: 'url', method: 'http'},
{name: 'name', url: 'url', method: 'http'}]
SCHEDULER.every '5m', :first_in => 0 do |job|
statuses = Array.new
# check status for each server
servers.each do |server|
if server[:method] == 'http'
uri = URI.parse(server[:url])
http = Net::HTTP.new(uri.host, uri.port)
if uri.scheme == "https"
http.use_ssl=true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
request = Net::HTTP::Get.new(uri.request_uri)
begin
response = http.request(request)
if response.code == "200"
result = 1
else
result = 0
end
rescue
result = 0
end
elsif server[:method] == 'ping'
ping_count = 10
result = `ping -q -c #{ping_count} #{server[:url]}`
if ($?.exitstatus == 0)
result = 1
else
result = 0
end
end
if result == 1
arrow = "fa fa-check-circle"
color = "green"
else
arrow = "fa fa-exclamation-triangle"
color = "red"
end
statuses.push({label: server[:name], value: result, arrow: arrow, color: color})
end
# print statuses to dashboard
send_event('server_status', {items: statuses})
end

46
jobs/timeline.rb Normal file
View File

@@ -0,0 +1,46 @@
require 'yaml'
MAX_DAYS_OVERDUE = -20
MAX_DAYS_AWAY = 90
config_file = '/home/me/dashboard/timeline.yml'
SCHEDULER.every '6h', :first_in => 0 do |job|
config = YAML.load_file(config_file)
unless config["events"].nil?
events = Array.new
today = Date.today
no_event_today = true
config["events"].each do |event|
days_away = (event["date"] - today).to_i
if (days_away >= 0) && (days_away <= MAX_DAYS_AWAY)
events << {
name: event["name"],
date: event["date"],
background: event["background"]
}
elsif (days_away < 0) && (days_away >= MAX_DAYS_OVERDUE)
events << {
name: event["name"],
date: event["date"],
background: event["background"],
opacity: 0.5
}
end
no_event_today = false if days_away == 0
end
if no_event_today
events << {
name: "TODAY",
date: today.strftime('%a %d %b %Y'),
background: "gold"
}
end
File.write("/home/me/dashboard/timeline.log", "events sorted...\n" + events.to_s)
send_event("a_timeline", {events: events})
else
puts "No events found :("
end
end

28
jobs/twitter.rb.disabled Normal file
View File

@@ -0,0 +1,28 @@
require 'twitter'
#### Get your twitter keys & secrets:
#### https://dev.twitter.com/docs/auth/tokens-devtwittercom
twitter = Twitter::REST::Client.new do |config|
config.consumer_key = 'YOUR_CONSUMER_KEY'
config.consumer_secret = 'YOUR_CONSUMER_SECRET'
config.access_token = 'YOUR_OAUTH_TOKEN'
config.access_token_secret = 'YOUR_OAUTH_SECRET'
end
search_term = URI::encode('#todayilearned')
SCHEDULER.every '10m', :first_in => 0 do |job|
begin
tweets = twitter.search("#{search_term}")
if tweets
tweets = tweets.map do |tweet|
{ name: tweet.user.name, body: tweet.text, avatar: tweet.user.profile_image_url_https }
end
send_event('twitter_mentions', comments: tweets)
end
rescue Twitter::Error
puts "\e[33mFor the twitter widget to work, you need to put in your twitter API keys in the jobs/twitter.rb file.\e[0m"
end
end