auntie 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +49 -0
- data/LICENSE +20 -0
- data/README.md +39 -0
- data/Rakefile +24 -0
- data/bin/news +4 -0
- data/bin/radio +51 -0
- data/bin/sport +4 -0
- data/bin/tv +45 -0
- data/bin/weather +23 -0
- data/features/location.feature +8 -0
- data/features/news.feature +8 -0
- data/features/radio.feature +8 -0
- data/features/sport.feature +8 -0
- data/features/step_definitions/location_steps.rb +7 -0
- data/features/step_definitions/radio_steps.rb +1 -0
- data/features/step_definitions/tv_steps.rb +1 -0
- data/features/step_definitions/weather_steps.rb +6 -0
- data/features/support/env.rb +15 -0
- data/features/tv.feature +8 -0
- data/features/weather.feature +8 -0
- data/lib/auntie.rb +16 -0
- data/lib/bbc/location.rb +44 -0
- data/lib/bbc/news.rb +28 -0
- data/lib/bbc/now_next.rb +93 -0
- data/lib/bbc/schedule.rb +53 -0
- data/lib/bbc/shell/characters.rb +68 -0
- data/lib/bbc/shell/colors.rb +39 -0
- data/lib/bbc/shell/describe_time.rb +20 -0
- data/lib/bbc/sport.rb +33 -0
- data/lib/bbc/version.rb +7 -0
- data/lib/bbc/weather.rb +98 -0
- data/scratch +9 -0
- data/spec/bbc/location_spec.rb +45 -0
- data/spec/bbc/news_spec.rb +43 -0
- data/spec/bbc/now_next_spec.rb +53 -0
- data/spec/bbc/schedule_spec.rb +56 -0
- data/spec/bbc/sport_spec.rb +35 -0
- data/spec/bbc/version_spec.rb +18 -0
- data/spec/bbc/weather_spec.rb +41 -0
- data/spec/fixtures/3dayforecast.json +149 -0
- data/spec/fixtures/3hourlyforecast.json +265 -0
- data/spec/fixtures/location.json +12 -0
- data/spec/fixtures/news.json +31 -0
- data/spec/fixtures/now_next_radio.json +7767 -0
- data/spec/fixtures/now_next_tv.json +3471 -0
- data/spec/fixtures/schedule_radio_today.json +939 -0
- data/spec/fixtures/schedule_radio_tomorrow.json +941 -0
- data/spec/fixtures/schedule_radio_yesterday.json +1118 -0
- data/spec/fixtures/schedule_tv.json +1695 -0
- data/spec/fixtures/sport.json +38 -0
- data/spec/spec_helper.rb +13 -0
- metadata +170 -0
data/lib/bbc/news.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
class News
|
4
|
+
def initialize(io=STDOUT)
|
5
|
+
@io = io
|
6
|
+
end
|
7
|
+
|
8
|
+
def load
|
9
|
+
cols = `stty size`.split(' ')[1].to_i
|
10
|
+
|
11
|
+
@io.puts 'BBC News Headlines'
|
12
|
+
data['entries'].each { |news_item|
|
13
|
+
@io.puts news_item['headline'][0..cols-1]
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def data
|
20
|
+
begin
|
21
|
+
raw = open('http://www.bbc.co.uk/news/10284448/ticker.sjson', 'UserAgent' => AUNTIE::USER_AGENT).read
|
22
|
+
JSON.parse(raw)
|
23
|
+
rescue
|
24
|
+
@io.puts "Unable to download news"
|
25
|
+
exit
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/bbc/now_next.rb
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
class NowNext
|
4
|
+
def initialize(io=STDIN)
|
5
|
+
@io = io
|
6
|
+
end
|
7
|
+
|
8
|
+
def tv_now
|
9
|
+
@fmt = "%-18s %s"
|
10
|
+
load 'tv'
|
11
|
+
|
12
|
+
on_now
|
13
|
+
end
|
14
|
+
|
15
|
+
def tv_next
|
16
|
+
@fmt = "%-18s %s"
|
17
|
+
load 'tv'
|
18
|
+
|
19
|
+
on_next
|
20
|
+
end
|
21
|
+
|
22
|
+
def radio_now
|
23
|
+
@fmt = "%-32s %s"
|
24
|
+
load 'radio'
|
25
|
+
|
26
|
+
on_now
|
27
|
+
end
|
28
|
+
|
29
|
+
def radio_next
|
30
|
+
@fmt = "%-32s %s"
|
31
|
+
load 'radio'
|
32
|
+
|
33
|
+
on_next
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
Programme = Struct.new(:channel, :title, :starts, :starts_in)
|
39
|
+
|
40
|
+
def load medium
|
41
|
+
begin
|
42
|
+
raw = open("http://www.bbc.co.uk/iplayer/ion/multinownext/service_type/#{medium}/simulcast_only/1/format/json", 'UserAgent' => AUNTIE::USER_AGENT).read
|
43
|
+
@data = JSON.parse(raw)
|
44
|
+
rescue
|
45
|
+
@io.puts "Unable to download #{medium} schedules"
|
46
|
+
exit
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def on_now
|
51
|
+
@data['blocklist'].each { |e|
|
52
|
+
channel = format_channel e['title']
|
53
|
+
programme = e['now'][0]['episode']['passionsite_title'] rescue next
|
54
|
+
|
55
|
+
@io.puts sprintf @fmt, channel, programme
|
56
|
+
}
|
57
|
+
end
|
58
|
+
|
59
|
+
def on_next
|
60
|
+
programmes = []
|
61
|
+
|
62
|
+
first = 9
|
63
|
+
second = 0
|
64
|
+
|
65
|
+
@data['blocklist'].each { |e|
|
66
|
+
p = Programme.new
|
67
|
+
p.channel = format_channel e['title']
|
68
|
+
|
69
|
+
p.title = e['next'][0]['episode']['passionsite_title'] rescue ''
|
70
|
+
p.starts = Time.parse(e['next'][0]['start_time_iso']) rescue ''
|
71
|
+
|
72
|
+
#next_start = starts.strftime("%H:%M")
|
73
|
+
p.starts_in = how_long_between(time_now, p.starts)
|
74
|
+
|
75
|
+
second = p.channel.length+3 if p.channel.length > second
|
76
|
+
|
77
|
+
programmes << p
|
78
|
+
}
|
79
|
+
|
80
|
+
programmes.sort_by! { |p| p.starts }
|
81
|
+
|
82
|
+
programmes.each { |p| @io.puts sprintf "%-#{first}s %-#{second}s %s", p.starts_in, p.channel, p.title }
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
def format_channel name
|
87
|
+
name.gsub(/^BBC | (London|England|Channel)/,'')
|
88
|
+
end
|
89
|
+
|
90
|
+
def time_now
|
91
|
+
Time.now
|
92
|
+
end
|
93
|
+
end
|
data/lib/bbc/schedule.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# Helpful urls
|
4
|
+
#
|
5
|
+
# http://www.bbc.co.uk/programmes/developers
|
6
|
+
# http://www.bbc.co.uk/ontologies/programmes/2009-09-07.shtml
|
7
|
+
|
8
|
+
class Schedule
|
9
|
+
def initialize(io=STDOUT)
|
10
|
+
@io = io
|
11
|
+
end
|
12
|
+
|
13
|
+
def load channel
|
14
|
+
station = channel[:id]
|
15
|
+
region = channel[:region] ||= ''
|
16
|
+
period = channel[:period] ||= ''
|
17
|
+
|
18
|
+
url = "http://www.bbc.co.uk/#{station}/programmes/schedules#{region}#{period}.json"
|
19
|
+
|
20
|
+
raw = open(url, 'UserAgent' => AUNTIE::USER_AGENT).read
|
21
|
+
data = JSON.parse(raw)
|
22
|
+
|
23
|
+
list data
|
24
|
+
end
|
25
|
+
|
26
|
+
def list data
|
27
|
+
now = time_now
|
28
|
+
|
29
|
+
data['schedule']['day']['broadcasts'].each do |e|
|
30
|
+
|
31
|
+
ends = Time.parse(e['end'])
|
32
|
+
|
33
|
+
title = e['programme']['display_titles']['title']
|
34
|
+
#synopsis = e['programme']['short_synopsis']
|
35
|
+
|
36
|
+
starts = Time.parse(e['start'])
|
37
|
+
|
38
|
+
starts_at = starts.strftime("%H:%M")
|
39
|
+
#starts_at = starts.strftime("%I:%M%P")
|
40
|
+
desc = "#{starts_at} #{title}"
|
41
|
+
|
42
|
+
if (starts < now) && (ends > now)
|
43
|
+
desc = light_green desc
|
44
|
+
end
|
45
|
+
|
46
|
+
@io.puts desc
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def time_now
|
51
|
+
Time.now
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
#http://www.utf8-chartable.de/unicode-utf8-table.pl
|
4
|
+
|
5
|
+
module ShellCharacters
|
6
|
+
|
7
|
+
def west
|
8
|
+
"\xe2\x86\x90"
|
9
|
+
end
|
10
|
+
|
11
|
+
def east
|
12
|
+
"\xe2\x86\x92"
|
13
|
+
end
|
14
|
+
|
15
|
+
def south
|
16
|
+
"\xe2\x86\x93"
|
17
|
+
end
|
18
|
+
|
19
|
+
def north
|
20
|
+
"\xe2\x86\x91"
|
21
|
+
end
|
22
|
+
|
23
|
+
def north_west
|
24
|
+
"\xe2\x86\x96"
|
25
|
+
end
|
26
|
+
|
27
|
+
def north_east
|
28
|
+
"\xe2\x86\x97"
|
29
|
+
end
|
30
|
+
|
31
|
+
def south_west
|
32
|
+
"\xe2\x86\x99"
|
33
|
+
end
|
34
|
+
|
35
|
+
def south_east
|
36
|
+
"\xe2\x86\x98"
|
37
|
+
end
|
38
|
+
|
39
|
+
def degrees_c
|
40
|
+
"\xC2\xB0C" #Shell escaped °C
|
41
|
+
end
|
42
|
+
|
43
|
+
def square_block
|
44
|
+
"\xe2\x96\x88"
|
45
|
+
end
|
46
|
+
|
47
|
+
def symbol_for_compass(direction)
|
48
|
+
case direction
|
49
|
+
when 'N' then north
|
50
|
+
when 'NNE' then north
|
51
|
+
when 'NE' then north_east
|
52
|
+
when 'ENE' then east
|
53
|
+
when 'E' then east
|
54
|
+
when 'ESE' then east
|
55
|
+
when 'SE' then south_east
|
56
|
+
when 'SSE' then south
|
57
|
+
when 'S' then south
|
58
|
+
when 'SSW' then south
|
59
|
+
when 'SW' then south_west
|
60
|
+
when 'WSW' then west
|
61
|
+
when 'W' then west
|
62
|
+
when 'WNW' then west
|
63
|
+
when 'NW' then north_west
|
64
|
+
when 'NNW' then north
|
65
|
+
else north
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# Useful list of colour codes
|
4
|
+
# http://misc.flogisoft.com/bash/tip_colors_and_formatting
|
5
|
+
|
6
|
+
# And alternatives
|
7
|
+
# http://stackoverflow.com/questions/1108767/terminal-color-in-ruby
|
8
|
+
|
9
|
+
def paint txt, color
|
10
|
+
"\033[#{color}m#{txt}\033[0m"
|
11
|
+
end
|
12
|
+
|
13
|
+
def green txt
|
14
|
+
paint txt, 32
|
15
|
+
end
|
16
|
+
|
17
|
+
def red txt
|
18
|
+
paint txt, 31
|
19
|
+
end
|
20
|
+
|
21
|
+
def light_green txt
|
22
|
+
paint txt, 92
|
23
|
+
end
|
24
|
+
|
25
|
+
def yellow txt
|
26
|
+
paint txt, 33
|
27
|
+
end
|
28
|
+
|
29
|
+
def cyan txt
|
30
|
+
paint txt, 36
|
31
|
+
end
|
32
|
+
|
33
|
+
def blue txt
|
34
|
+
paint txt, 34
|
35
|
+
end
|
36
|
+
|
37
|
+
def white txt
|
38
|
+
paint txt, 37
|
39
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
def how_long_between past, future
|
4
|
+
a = (future-past).to_i
|
5
|
+
|
6
|
+
case a
|
7
|
+
when -10000000..0 then "On now"
|
8
|
+
when 0 then 'Now!'
|
9
|
+
when 1 then 'A second'
|
10
|
+
when 2..59 then a.to_s+' secs'
|
11
|
+
when 60..119 then 'A min' #120 = 2 minutes
|
12
|
+
when 120..3540 then (a/60).to_i.to_s+' mins'
|
13
|
+
when 3541..7100 then 'An hour' # 3600 = 1 hour
|
14
|
+
when 7101..82800 then ((a+99)/3600).to_i.to_s+' hours'
|
15
|
+
when 82801..172000 then 'A day' # 86400 = 1 day
|
16
|
+
when 172001..518400 then ((a+800)/(60*60*24)).to_i.to_s+' days'
|
17
|
+
when 518400..1036800 then 'A week'
|
18
|
+
else ((a+180000)/(60*60*24*7)).to_i.to_s+' weeks'
|
19
|
+
end
|
20
|
+
end
|
data/lib/bbc/sport.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
class Sport
|
4
|
+
def initialize(io=STDOUT)
|
5
|
+
@io = io
|
6
|
+
end
|
7
|
+
|
8
|
+
def headlines
|
9
|
+
data['entries'].each { |item|
|
10
|
+
prompt = yellow item['prompt'].capitalize.ljust(22)
|
11
|
+
|
12
|
+
headline = item['headline']
|
13
|
+
@io.puts prompt+headline
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def url
|
20
|
+
'http://polling.bbc.co.uk/sport/0/16189337/ticker.sjson'
|
21
|
+
end
|
22
|
+
|
23
|
+
def data
|
24
|
+
begin
|
25
|
+
raw = open(url, 'UserAgent' => AUNTIE::USER_AGENT).read
|
26
|
+
JSON.parse(raw)
|
27
|
+
rescue
|
28
|
+
@io.puts "Unable to download sport"
|
29
|
+
exit
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
data/lib/bbc/version.rb
ADDED
data/lib/bbc/weather.rb
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
class Weather
|
4
|
+
include ShellCharacters
|
5
|
+
|
6
|
+
attr_reader :base_url
|
7
|
+
|
8
|
+
def initialize(location, io=STDOUT)
|
9
|
+
@io = io
|
10
|
+
@base_url = "http://open.live.bbc.co.uk/weather/feeds/en/#{location}"
|
11
|
+
end
|
12
|
+
|
13
|
+
def hourly
|
14
|
+
feed = load("#{base_url}/3hourlyforecast.json")
|
15
|
+
|
16
|
+
location = feed['forecastContent']['location']['locationName']
|
17
|
+
|
18
|
+
@io.puts "\nThe next 24 hours in #{location}\n\n"
|
19
|
+
@io.puts "Day Time Weather Max#{degrees_c} Wind"
|
20
|
+
|
21
|
+
feed['forecastContent']['forecasts'].each { |e|
|
22
|
+
|
23
|
+
day = e['dayName'].ljust(10)
|
24
|
+
time = e['timeSlot'].ljust(7)
|
25
|
+
desc = e['weatherType'].ljust(19)
|
26
|
+
|
27
|
+
temp = e['temperature']['centigrade'].to_s || '?'
|
28
|
+
temp = "#{temp}#{degrees_c}".ljust(6)
|
29
|
+
|
30
|
+
wind = e['wind']['directionDesc']
|
31
|
+
wind_dir = e['wind']['direction']
|
32
|
+
wind_spd = e['wind']['windspeed']['mph'] || '?'
|
33
|
+
wind_spd = "#{wind_spd}mph".ljust(5)
|
34
|
+
|
35
|
+
#visibility = e['visibility']
|
36
|
+
#millibars = e['pressureMillibars']
|
37
|
+
#humidity = e['humidityPercent']
|
38
|
+
#temp_colour = temp_to_color(temp.to_i)
|
39
|
+
|
40
|
+
@io.puts "#{yellow day} #{time} #{desc} #{temp} #{wind_spd} #{wind}"
|
41
|
+
}
|
42
|
+
@io.puts "\n"
|
43
|
+
end
|
44
|
+
|
45
|
+
def daily
|
46
|
+
feed = load("#{base_url}/3dayforecast.json")
|
47
|
+
|
48
|
+
location = feed['forecastContent']['location']['locationName']
|
49
|
+
|
50
|
+
@io.puts "\nThe next 3 days in #{location}\n\n"
|
51
|
+
@io.puts "Day Time Weather Max#{degrees_c} Wind"
|
52
|
+
|
53
|
+
feed['forecastContent']['forecasts'].each { |e|
|
54
|
+
day = sprintf "%-10s", e['dayName']
|
55
|
+
|
56
|
+
d_weather = e['day']['weatherType']
|
57
|
+
d_weather = sprintf "%-12s", d_weather unless d_weather.nil?
|
58
|
+
|
59
|
+
d_temp = e['day']['maxTemperature']['centigrade']
|
60
|
+
d_temp = "#{d_temp}\xC2\xB0C" unless d_temp.nil?
|
61
|
+
|
62
|
+
d_wind = e['day']['wind']['directionDesc']
|
63
|
+
d_wind_spd = e['day']['wind']['windspeed']['mph']
|
64
|
+
d_wind_spd = "#{d_wind_spd}mph" unless d_wind_spd.nil?
|
65
|
+
|
66
|
+
day_desc = sprintf "%-17s %-6s %-5s %-20s", d_weather, d_temp, d_wind_spd, d_wind
|
67
|
+
|
68
|
+
n_weather = e['night']['weatherType']
|
69
|
+
n_temp = e['night']['minTemperature']['centigrade']
|
70
|
+
n_temp = "#{n_temp}\xC2\xB0C" unless n_temp.nil?
|
71
|
+
|
72
|
+
night_desc = sprintf "%-12s %-3s", n_weather, n_temp
|
73
|
+
|
74
|
+
@io.puts "#{yellow day} #{day_desc} #{cyan 'night'} #{white night_desc}"
|
75
|
+
}
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def load(url)
|
81
|
+
begin
|
82
|
+
raw = open(url, 'UserAgent' => AUNTIE::USER_AGENT).read
|
83
|
+
JSON.parse(raw)
|
84
|
+
rescue
|
85
|
+
@io.puts "Unable to download the weather"
|
86
|
+
exit
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
#def temp_to_color(temp)
|
91
|
+
# case temp
|
92
|
+
# when -100..0 then blue(square_block)
|
93
|
+
# when 0..10 then yellow(square_block)
|
94
|
+
# else red(square_block)
|
95
|
+
# end
|
96
|
+
#end
|
97
|
+
|
98
|
+
end
|