auntie 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +5 -0
- data/Gemfile.lock +22 -1
- data/README.md +7 -4
- data/bin/auntie +26 -0
- data/bin/news +1 -1
- data/bin/radio +15 -18
- data/bin/sport +1 -1
- data/bin/tv +13 -13
- data/bin/weather +7 -6
- data/features/step_definitions/location_steps.rb +2 -2
- data/features/step_definitions/weather_steps.rb +1 -1
- data/features/support/env.rb +1 -1
- data/lib/bbc/location.rb +14 -10
- data/lib/bbc/news.rb +9 -8
- data/lib/bbc/now_next.rb +24 -24
- data/lib/bbc/schedule.rb +12 -13
- data/lib/bbc/shell/characters.rb +32 -22
- data/lib/bbc/shell/colors.rb +39 -32
- data/lib/bbc/shell/describe_time.rb +23 -13
- data/lib/bbc/sport.rb +11 -9
- data/lib/bbc/version.rb +3 -1
- data/lib/bbc/weather.rb +29 -27
- data/spec/bbc/colors_spec.rb +18 -0
- data/spec/bbc/describe_time_spec.rb +69 -0
- data/spec/bbc/location_spec.rb +22 -22
- data/spec/bbc/news_spec.rb +8 -17
- data/spec/bbc/now_next_spec.rb +12 -4
- data/spec/bbc/schedule_spec.rb +10 -11
- data/spec/bbc/shell_symbols_spec.rb +49 -0
- data/spec/bbc/sport_spec.rb +7 -12
- data/spec/bbc/version_spec.rb +5 -5
- data/spec/bbc/weather_spec.rb +7 -13
- data/spec/spec_helper.rb +8 -2
- metadata +8 -3
data/lib/bbc/schedule.rb
CHANGED
@@ -1,16 +1,20 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
+
# Shows schedule information for BBC Television and Radio stations
|
4
|
+
#
|
3
5
|
# Helpful urls
|
4
6
|
#
|
5
7
|
# http://www.bbc.co.uk/programmes/developers
|
6
8
|
# http://www.bbc.co.uk/ontologies/programmes/2009-09-07.shtml
|
7
|
-
|
9
|
+
#
|
8
10
|
class Schedule
|
9
|
-
|
11
|
+
include ShellColors, Timings
|
12
|
+
|
13
|
+
def initialize(io = STDOUT)
|
10
14
|
@io = io
|
11
15
|
end
|
12
16
|
|
13
|
-
def load
|
17
|
+
def load(channel)
|
14
18
|
station = channel[:id]
|
15
19
|
region = channel[:region] ||= ''
|
16
20
|
period = channel[:period] ||= ''
|
@@ -22,7 +26,7 @@ class Schedule
|
|
22
26
|
list data, period
|
23
27
|
end
|
24
28
|
|
25
|
-
def list
|
29
|
+
def list(data, period)
|
26
30
|
now = time_now
|
27
31
|
|
28
32
|
data['schedule']['day']['broadcasts'].each do |e|
|
@@ -31,22 +35,17 @@ class Schedule
|
|
31
35
|
next if ends < now unless period == '/yesterday'
|
32
36
|
|
33
37
|
title = e['programme']['display_titles']['title']
|
34
|
-
#synopsis = e['programme']['short_synopsis']
|
38
|
+
# synopsis = e['programme']['short_synopsis']
|
35
39
|
|
36
40
|
starts = Time.parse(e['start'])
|
37
41
|
|
38
|
-
starts_at = starts.strftime(
|
42
|
+
starts_at = starts.strftime('%H:%M') # "%I:%M%P"
|
39
43
|
desc = "#{starts_at} #{title}"
|
40
44
|
|
41
|
-
|
42
|
-
|
43
|
-
end
|
45
|
+
on_now = (starts < now && ends > now)
|
46
|
+
desc = light_green desc if on_now
|
44
47
|
|
45
48
|
@io.puts desc
|
46
49
|
end
|
47
50
|
end
|
48
|
-
|
49
|
-
def time_now
|
50
|
-
Time.now
|
51
|
-
end
|
52
51
|
end
|
data/lib/bbc/shell/characters.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
#
|
4
|
-
|
3
|
+
# Easy output of characters in your terminal
|
4
|
+
#
|
5
|
+
# http://www.utf8-chartable.de/unicode-utf8-table.pl
|
6
|
+
#
|
5
7
|
module ShellCharacters
|
6
|
-
|
7
8
|
def west
|
8
9
|
"\xe2\x86\x90"
|
9
10
|
end
|
@@ -37,7 +38,11 @@ module ShellCharacters
|
|
37
38
|
end
|
38
39
|
|
39
40
|
def degrees_c
|
40
|
-
"\xC2\xB0C"
|
41
|
+
"\xC2\xB0C"
|
42
|
+
end
|
43
|
+
|
44
|
+
def degrees_f
|
45
|
+
"\xC2\xB0F"
|
41
46
|
end
|
42
47
|
|
43
48
|
def square_block
|
@@ -46,23 +51,28 @@ module ShellCharacters
|
|
46
51
|
|
47
52
|
def symbol_for_compass(direction)
|
48
53
|
case direction
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
54
|
+
when 'N' then north
|
55
|
+
when 'NNE' then north
|
56
|
+
when 'NE' then north_east
|
57
|
+
when 'ENE' then east
|
58
|
+
when 'E' then east
|
59
|
+
when 'ESE' then east
|
60
|
+
when 'SE' then south_east
|
61
|
+
when 'SSE' then south
|
62
|
+
when 'S' then south
|
63
|
+
when 'SSW' then south
|
64
|
+
when 'SW' then south_west
|
65
|
+
when 'WSW' then west
|
66
|
+
when 'W' then west
|
67
|
+
when 'WNW' then west
|
68
|
+
when 'NW' then north_west
|
69
|
+
when 'NNW' then north
|
70
|
+
else north
|
66
71
|
end
|
67
72
|
end
|
68
|
-
|
73
|
+
|
74
|
+
module_function :symbol_for_compass,
|
75
|
+
:north, :east, :south, :west,
|
76
|
+
:north_east, :south_east, :south_west, :north_west,
|
77
|
+
:degrees_c, :degrees_f, :square_block
|
78
|
+
end
|
data/lib/bbc/shell/colors.rb
CHANGED
@@ -1,39 +1,46 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
+
# Outputs the input in technicolour, for a happier terminal.
|
4
|
+
#
|
3
5
|
# Useful list of colour codes
|
4
6
|
# http://misc.flogisoft.com/bash/tip_colors_and_formatting
|
5
|
-
|
7
|
+
#
|
6
8
|
# And alternatives
|
7
9
|
# http://stackoverflow.com/questions/1108767/terminal-color-in-ruby
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
10
|
+
#
|
11
|
+
module ShellColors
|
12
|
+
def paint(txt, color)
|
13
|
+
"\033[#{color}m#{txt}\033[0m"
|
14
|
+
end
|
15
|
+
|
16
|
+
def red(txt)
|
17
|
+
paint(txt, 31)
|
18
|
+
end
|
19
|
+
|
20
|
+
def green(txt)
|
21
|
+
paint(txt, 32)
|
22
|
+
end
|
23
|
+
|
24
|
+
def yellow(txt)
|
25
|
+
paint(txt, 33)
|
26
|
+
end
|
27
|
+
|
28
|
+
def blue(txt)
|
29
|
+
paint(txt, 34)
|
30
|
+
end
|
31
|
+
|
32
|
+
def cyan(txt)
|
33
|
+
paint(txt, 36)
|
34
|
+
end
|
35
|
+
|
36
|
+
def white(txt)
|
37
|
+
paint(txt, 37)
|
38
|
+
end
|
39
|
+
|
40
|
+
def light_green(txt)
|
41
|
+
paint(txt, 92)
|
42
|
+
end
|
43
|
+
|
44
|
+
module_function :paint, :green, :red, :light_green,
|
45
|
+
:yellow, :cyan, :blue, :white
|
39
46
|
end
|
@@ -1,20 +1,30 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
# Collection of time related methods awaiting a relevantly named module.
|
4
|
+
#
|
5
|
+
module Timings
|
6
|
+
def how_long_between(past, future)
|
7
|
+
a = (future - past).to_i
|
5
8
|
|
6
|
-
|
7
|
-
when -
|
9
|
+
case a
|
10
|
+
when -10_000_000...0 then 'On now'
|
8
11
|
when 0 then 'Now!'
|
9
12
|
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..
|
13
|
-
when
|
14
|
-
when
|
15
|
-
when
|
16
|
-
when
|
17
|
-
when
|
18
|
-
else ((a+
|
13
|
+
when 2..59 then a.to_s + ' secs'
|
14
|
+
when 60..119 then 'A min' # 120 = 2 minutes
|
15
|
+
when 120..3_540 then (a / 60).to_i.to_s + ' mins'
|
16
|
+
when 3_541..7_100 then 'An hour' # 3600 = 1 hour
|
17
|
+
when 7_101..82_800 then ((a + 99) / 3600).to_i.to_s + ' hours'
|
18
|
+
when 82_801..172_000 then 'A day' # 86400 = 1 day
|
19
|
+
when 172_001..518_400 then ((a + 800) / (60 * 60 * 24)).to_i.to_s + ' days'
|
20
|
+
when 518_401..1_036_800 then 'A week'
|
21
|
+
else ((a + 180_000) / (60 * 60 * 24 * 7)).to_i.to_s + ' weeks'
|
22
|
+
end
|
19
23
|
end
|
24
|
+
|
25
|
+
def time_now
|
26
|
+
Time.now
|
27
|
+
end
|
28
|
+
|
29
|
+
module_function :how_long_between, :time_now
|
20
30
|
end
|
data/lib/bbc/sport.rb
CHANGED
@@ -1,17 +1,21 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
+
# Lists the latest BBC Sport headlines
|
4
|
+
#
|
3
5
|
class Sport
|
4
|
-
|
6
|
+
include ShellColors
|
7
|
+
|
8
|
+
def initialize(io = STDOUT)
|
5
9
|
@io = io
|
6
10
|
end
|
7
11
|
|
8
12
|
def headlines
|
9
|
-
data['entries'].each
|
13
|
+
data['entries'].each do |item|
|
10
14
|
prompt = yellow item['prompt'].capitalize.ljust(22)
|
11
15
|
|
12
16
|
headline = item['headline']
|
13
|
-
@io.puts prompt+headline
|
14
|
-
|
17
|
+
@io.puts prompt + headline
|
18
|
+
end
|
15
19
|
end
|
16
20
|
|
17
21
|
private
|
@@ -22,12 +26,10 @@ class Sport
|
|
22
26
|
|
23
27
|
def data
|
24
28
|
begin
|
25
|
-
|
26
|
-
|
29
|
+
raw = open(url, 'UserAgent' => AUNTIE::USER_AGENT).read
|
30
|
+
JSON.parse(raw)
|
27
31
|
rescue
|
28
|
-
|
29
|
-
exit
|
32
|
+
raise 'Unable to download sport data'
|
30
33
|
end
|
31
34
|
end
|
32
|
-
|
33
35
|
end
|
data/lib/bbc/version.rb
CHANGED
data/lib/bbc/weather.rb
CHANGED
@@ -1,11 +1,14 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
+
# Lists BBC weather for the requested location
|
4
|
+
#
|
5
|
+
#
|
3
6
|
class Weather
|
4
|
-
include ShellCharacters
|
7
|
+
include ShellCharacters, ShellColors
|
5
8
|
|
6
9
|
attr_reader :base_url
|
7
10
|
|
8
|
-
def initialize(location, io=STDOUT)
|
11
|
+
def initialize(location, io = STDOUT)
|
9
12
|
@io = io
|
10
13
|
@base_url = "http://open.live.bbc.co.uk/weather/feeds/en/#{location}"
|
11
14
|
end
|
@@ -18,7 +21,7 @@ class Weather
|
|
18
21
|
@io.puts "\nThe next 24 hours in #{location}\n\n"
|
19
22
|
@io.puts "Day Time Weather Max#{degrees_c} Wind"
|
20
23
|
|
21
|
-
feed['forecastContent']['forecasts'].each
|
24
|
+
feed['forecastContent']['forecasts'].each do |e|
|
22
25
|
|
23
26
|
day = e['dayName'].ljust(10)
|
24
27
|
time = e['timeSlot'].ljust(7)
|
@@ -28,17 +31,18 @@ class Weather
|
|
28
31
|
temp = "#{temp}#{degrees_c}".ljust(6)
|
29
32
|
|
30
33
|
wind = e['wind']['directionDesc']
|
31
|
-
wind_dir = e['wind']['direction']
|
34
|
+
# wind_dir = e['wind']['direction']
|
32
35
|
wind_spd = e['wind']['windspeed']['mph'] || '?'
|
33
36
|
wind_spd = "#{wind_spd}mph".ljust(5)
|
34
37
|
|
35
|
-
#visibility = e['visibility']
|
36
|
-
#millibars = e['pressureMillibars']
|
37
|
-
#humidity = e['humidityPercent']
|
38
|
-
#temp_colour = temp_to_color(temp.to_i)
|
38
|
+
# visibility = e['visibility']
|
39
|
+
# millibars = e['pressureMillibars']
|
40
|
+
# humidity = e['humidityPercent']
|
41
|
+
# temp_colour = temp_to_color(temp.to_i)
|
39
42
|
|
40
43
|
@io.puts "#{yellow day} #{time} #{desc} #{temp} #{wind_spd} #{wind}"
|
41
|
-
|
44
|
+
end
|
45
|
+
|
42
46
|
@io.puts "\n"
|
43
47
|
end
|
44
48
|
|
@@ -50,11 +54,11 @@ class Weather
|
|
50
54
|
@io.puts "\nThe next 3 days in #{location}\n\n"
|
51
55
|
@io.puts "Day Weather Max#{degrees_c} Wind"
|
52
56
|
|
53
|
-
feed['forecastContent']['forecasts'].each
|
54
|
-
day = sprintf
|
57
|
+
feed['forecastContent']['forecasts'].each do |e|
|
58
|
+
day = sprintf '%-10s', e['dayName']
|
55
59
|
|
56
60
|
d_weather = e['day']['weatherType']
|
57
|
-
d_weather = sprintf
|
61
|
+
d_weather = sprintf '%-12s', d_weather unless d_weather.nil?
|
58
62
|
|
59
63
|
d_temp = e['day']['maxTemperature']['centigrade']
|
60
64
|
d_temp = "#{d_temp}\xC2\xB0C" unless d_temp.nil?
|
@@ -63,36 +67,34 @@ class Weather
|
|
63
67
|
d_wind_spd = e['day']['wind']['windspeed']['mph']
|
64
68
|
d_wind_spd = "#{d_wind_spd}mph" unless d_wind_spd.nil?
|
65
69
|
|
66
|
-
day_desc = sprintf
|
70
|
+
day_desc = sprintf '%-17s %-6s %-5s %-20s', d_weather, d_temp, d_wind_spd, d_wind
|
67
71
|
|
68
72
|
n_weather = e['night']['weatherType']
|
69
73
|
n_temp = e['night']['minTemperature']['centigrade']
|
70
74
|
n_temp = "#{n_temp}\xC2\xB0C" unless n_temp.nil?
|
71
75
|
|
72
|
-
night_desc = sprintf
|
76
|
+
night_desc = sprintf '%-17s %-3s', n_weather, n_temp
|
73
77
|
|
74
78
|
@io.puts "#{yellow day} #{day_desc} #{cyan 'Night'} #{white night_desc}"
|
75
|
-
|
79
|
+
end
|
76
80
|
end
|
77
81
|
|
78
82
|
private
|
79
83
|
|
80
84
|
def load(url)
|
81
85
|
begin
|
82
|
-
|
83
|
-
|
86
|
+
raw = open(url, 'UserAgent' => AUNTIE::USER_AGENT).read
|
87
|
+
JSON.parse(raw)
|
84
88
|
rescue
|
85
|
-
|
86
|
-
exit
|
89
|
+
raise 'Unable to download the weather'
|
87
90
|
end
|
88
91
|
end
|
89
92
|
|
90
|
-
#def temp_to_color(temp)
|
91
|
-
#
|
92
|
-
#
|
93
|
-
#
|
94
|
-
#
|
95
|
-
#
|
96
|
-
#end
|
97
|
-
|
93
|
+
# def temp_to_color(temp)
|
94
|
+
# case temp
|
95
|
+
# when -100..0 then blue(square_block)
|
96
|
+
# when 0..10 then yellow(square_block)
|
97
|
+
# else red(square_block)
|
98
|
+
# end
|
99
|
+
# end
|
98
100
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require File.join(File.dirname(__FILE__), '/../spec_helper')
|
4
|
+
|
5
|
+
describe ShellColors, 'colours text for terminal' do
|
6
|
+
it 'colours red' do
|
7
|
+
expect(ShellColors.red 'red').to eq "\e[31mred\e[0m"
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'colours green, yellow, cyan, blue, light green' do
|
11
|
+
colours = %w(red green yellow blue cyan white)
|
12
|
+
codes = [31, 32, 33, 34, 36, 37]
|
13
|
+
|
14
|
+
colours.zip(codes) do |color, code|
|
15
|
+
expect(ShellColors.send(color, color)).to include("\e[#{code}m#{color}")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require File.join(File.dirname(__FILE__), '/../spec_helper')
|
4
|
+
|
5
|
+
describe Timings do
|
6
|
+
describe 'what the time is now' do
|
7
|
+
it 'is now' do
|
8
|
+
expect(Timings.time_now.class).to be Time
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe 'how long until a programme starts' do
|
13
|
+
it 'is on now' do
|
14
|
+
expect(Timings.how_long_between(1, 0)).to eq 'On now'
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'is now' do
|
18
|
+
expect(Timings.how_long_between(0, 0)).to eq 'Now!'
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'is in a second' do
|
22
|
+
expect(Timings.how_long_between(0, 1)).to eq 'A second'
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'in seconds' do
|
26
|
+
expect(Timings.how_long_between(0, 2)).to eq '2 secs'
|
27
|
+
expect(Timings.how_long_between(0, 59)).to eq '59 secs'
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'is a minute' do
|
31
|
+
expect(Timings.how_long_between(0, 60)).to eq 'A min'
|
32
|
+
expect(Timings.how_long_between(0, 119)).to eq 'A min' # round here?
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'is minutes' do
|
36
|
+
expect(Timings.how_long_between(0, 120)).to eq '2 mins'
|
37
|
+
expect(Timings.how_long_between(0, 3_540)).to eq '59 mins'
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'is an hour' do
|
41
|
+
expect(Timings.how_long_between(0, 3_541)).to eq 'An hour'
|
42
|
+
expect(Timings.how_long_between(0, 7_100)).to eq 'An hour' # round here?
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'is hours' do
|
46
|
+
expect(Timings.how_long_between(0, 7_101)).to eq '2 hours'
|
47
|
+
expect(Timings.how_long_between(0, 82_800)).to eq '23 hours'
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'is a day' do
|
51
|
+
expect(Timings.how_long_between(0, 82_801)).to eq 'A day'
|
52
|
+
expect(Timings.how_long_between(0, 172_000)).to eq 'A day'
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'is days' do
|
56
|
+
expect(Timings.how_long_between(0, 172_001)).to eq '2 days'
|
57
|
+
expect(Timings.how_long_between(0, 518_400)).to eq '6 days'
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'is a week' do
|
61
|
+
expect(Timings.how_long_between(0, 518_401)).to eq 'A week'
|
62
|
+
expect(Timings.how_long_between(0, 1_036_800)).to eq 'A week'
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'is weeks' do
|
66
|
+
expect(Timings.how_long_between(0, 1_036_801)).to eq '2 weeks'
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|