in_our_time 0.7.0 → 0.7.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/in_our_time.gemspec +2 -1
- data/lib/iot/iot.rb +441 -135
- data/lib/iot/keyboard_events.rb +10 -3
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f7366e48fb9235107463e7af22d3b04b30ea7368
|
4
|
+
data.tar.gz: 3ef1be69c2de15068ad48ac13ae7bec99f6498bc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 30258e410871e24e8f7e8f93d95fd8e8a4464b11d321b5659a8b5f80e79e10091a8c269973d794f084b289f62dda29690d0be8ce8cc8a5d4f1ddaf06d1a85f1d
|
7
|
+
data.tar.gz: 3928c59f30aff170246a1480fbc1e0965c0386c115e43f7fc387d9876ed78b9cca85d9e1fae810766a9eef5441a2c9df8dc8b7c54a1370bb8486bdeb219c0fe4
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.7.
|
1
|
+
0.7.3
|
data/in_our_time.gemspec
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# coding: utf-8
|
2
|
+
require "time"
|
2
3
|
lib = File.expand_path('../lib', __FILE__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
5
|
|
@@ -20,7 +21,7 @@ Gem::Specification.new do |spec|
|
|
20
21
|
|
21
22
|
spec.require_paths = ["lib"]
|
22
23
|
spec.required_ruby_version = '>= 2.0.0'
|
23
|
-
spec.add_runtime_dependency 'oga', '
|
24
|
+
spec.add_runtime_dependency 'oga', '>= 2.1.4'
|
24
25
|
spec.add_runtime_dependency 'colorize', '>= 0.8.1'
|
25
26
|
spec.add_development_dependency 'version', '>= 1.0.0'
|
26
27
|
end
|
data/lib/iot/iot.rb
CHANGED
@@ -13,30 +13,74 @@ require_relative 'keyboard_events'
|
|
13
13
|
class InOurTime
|
14
14
|
ROOT = File.expand_path '~/'
|
15
15
|
HERE = File.dirname(__FILE__)
|
16
|
-
CONFIG_DIR = '.in_our_time'
|
17
|
-
CONFIG_NAME = 'config.yml'
|
16
|
+
CONFIG_DIR = '.in_our_time'.freeze
|
17
|
+
CONFIG_NAME = 'config.yml'.freeze
|
18
18
|
IN_OUR_TIME = File.join ROOT, CONFIG_DIR
|
19
19
|
VERSION = File.join HERE, '..','..','VERSION'
|
20
20
|
DEFAULT_CONFIG = File.join HERE, '..','..',CONFIG_NAME
|
21
21
|
CONFIG = File.join IN_OUR_TIME,CONFIG_NAME
|
22
22
|
UPDATE_INTERVAL = 604800
|
23
|
-
AUDIO_DIRECTORY = 'audio'
|
24
|
-
|
23
|
+
AUDIO_DIRECTORY = '../../../../Volumes/UNTITLED/.in_our_time/audio'.freeze
|
24
|
+
# AUDIO_DIRECTORY = 'audio'.freeze
|
25
|
+
RSS_DIRECTORY = 'rss'.freeze
|
25
26
|
|
26
27
|
class Tic
|
27
28
|
def initialize
|
29
|
+
Thread.abort_on_exception = true
|
28
30
|
@flag = false
|
31
|
+
init_processes
|
29
32
|
run
|
30
33
|
end
|
31
34
|
|
35
|
+
def init_processes
|
36
|
+
@processes =
|
37
|
+
{ process: {
|
38
|
+
timeout: 5,
|
39
|
+
value: 0 },
|
40
|
+
playing_time: {
|
41
|
+
timeout: 1,
|
42
|
+
value: 0 },
|
43
|
+
ended: {
|
44
|
+
timeout: 1,
|
45
|
+
value: 0 }
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
def inc_processes
|
50
|
+
@processes.each { |process| process[:value] += 1 }
|
51
|
+
end
|
52
|
+
|
32
53
|
def kill
|
33
54
|
Thread.kill(@th_tic) if @th_tic
|
34
55
|
end
|
35
56
|
|
57
|
+
def timeout? type
|
58
|
+
@processes[type]
|
59
|
+
return unless @processes[type][:value] > @processes[type][:timeout]
|
60
|
+
@processes[type][:value] = 0
|
61
|
+
true
|
62
|
+
end
|
63
|
+
|
64
|
+
def process
|
65
|
+
timeout? :process
|
66
|
+
end
|
67
|
+
|
68
|
+
def playing_time
|
69
|
+
timeout? :playing_time
|
70
|
+
end
|
71
|
+
|
72
|
+
def ended
|
73
|
+
timeout? :ended
|
74
|
+
end
|
75
|
+
|
36
76
|
def run
|
77
|
+
Thread.abort_on_exception = true
|
37
78
|
@th_tic = Thread.new do
|
38
79
|
loop do
|
39
|
-
sleep
|
80
|
+
sleep 0.2
|
81
|
+
@processes[:process][:value] += 1
|
82
|
+
@processes[:playing_time][:value] += 1
|
83
|
+
@processes[:ended][:value] += 1
|
40
84
|
@flag = true
|
41
85
|
end
|
42
86
|
end
|
@@ -49,8 +93,102 @@ class InOurTime
|
|
49
93
|
end
|
50
94
|
end
|
51
95
|
|
96
|
+
class PlayTime
|
97
|
+
def initialize(dur)
|
98
|
+
@duration = dur
|
99
|
+
@start_time = Time.now
|
100
|
+
update
|
101
|
+
end
|
102
|
+
|
103
|
+
def changed?
|
104
|
+
! unchanged?
|
105
|
+
end
|
106
|
+
|
107
|
+
def read
|
108
|
+
store
|
109
|
+
format_time
|
110
|
+
end
|
111
|
+
|
112
|
+
def ended?
|
113
|
+
(@duration + 20) < @seconds
|
114
|
+
end
|
115
|
+
|
116
|
+
def unchanged?
|
117
|
+
(update == stored) || paused?
|
118
|
+
end
|
119
|
+
|
120
|
+
def store
|
121
|
+
@stored = @seconds
|
122
|
+
end
|
123
|
+
|
124
|
+
def stored
|
125
|
+
@stored
|
126
|
+
end
|
127
|
+
|
128
|
+
def plural x
|
129
|
+
x == 1 ? '' : 's'
|
130
|
+
end
|
131
|
+
|
132
|
+
def mins
|
133
|
+
@seconds / 60
|
134
|
+
end
|
135
|
+
|
136
|
+
def secs
|
137
|
+
@seconds % 60
|
138
|
+
end
|
139
|
+
|
140
|
+
def format x
|
141
|
+
x < 10 ? '0' + x.to_s : x.to_s
|
142
|
+
end
|
143
|
+
|
144
|
+
def format_minutes
|
145
|
+
format mins
|
146
|
+
end
|
147
|
+
|
148
|
+
def format_secs
|
149
|
+
format secs
|
150
|
+
end
|
151
|
+
|
152
|
+
def format_remaining_time
|
153
|
+
secs = @duration - @seconds
|
154
|
+
format(secs/60) + ':' + format(secs%60)
|
155
|
+
end
|
156
|
+
|
157
|
+
def format_time
|
158
|
+
' (' + format_minutes + ':' + format_secs +
|
159
|
+
' / ' + format_remaining_time + ')'
|
160
|
+
end
|
161
|
+
|
162
|
+
def update
|
163
|
+
@seconds = (Time.now - @start_time).to_i
|
164
|
+
end
|
165
|
+
|
166
|
+
def pause
|
167
|
+
@paused = Time.now
|
168
|
+
end
|
169
|
+
|
170
|
+
def paused?
|
171
|
+
@paused
|
172
|
+
end
|
173
|
+
|
174
|
+
def unpause
|
175
|
+
@start_time = @start_time + (Time.now - @paused)
|
176
|
+
@paused = false
|
177
|
+
end
|
178
|
+
|
179
|
+
def forward
|
180
|
+
@start_time -= 1.5
|
181
|
+
end
|
182
|
+
|
183
|
+
def rewind
|
184
|
+
@start_time += 1.5
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
52
188
|
def initialize
|
53
|
-
|
189
|
+
Thread.abort_on_exception = true
|
190
|
+
@queued = Array.new
|
191
|
+
@content = String.new
|
54
192
|
@selected = 0
|
55
193
|
clear
|
56
194
|
print "\e[?25h"
|
@@ -80,7 +218,7 @@ class InOurTime
|
|
80
218
|
STDIN.echo = true
|
81
219
|
STDIN.cooked!
|
82
220
|
puts "\n\n#{@error_msg}" if @error_msg
|
83
|
-
puts 'Quitting...'
|
221
|
+
puts 'Quitting...'.freeze
|
84
222
|
sleep 0.5
|
85
223
|
exit code
|
86
224
|
end
|
@@ -91,7 +229,7 @@ class InOurTime
|
|
91
229
|
end
|
92
230
|
|
93
231
|
def iot_print x, col = @text_colour, now = false
|
94
|
-
content =
|
232
|
+
content = String.new
|
95
233
|
content << x.colorize(col) if @config[:colour]
|
96
234
|
content << x unless @config[:colour]
|
97
235
|
unless now
|
@@ -101,9 +239,9 @@ class InOurTime
|
|
101
239
|
end
|
102
240
|
end
|
103
241
|
|
104
|
-
def iot_puts x = '', col = @text_colour
|
105
|
-
iot_print x, col
|
106
|
-
iot_print "\n\r"
|
242
|
+
def iot_puts x = '', col = @text_colour, now = false
|
243
|
+
iot_print x, col, now
|
244
|
+
iot_print "\n\r", now
|
107
245
|
end
|
108
246
|
|
109
247
|
def clear_content
|
@@ -132,18 +270,18 @@ class InOurTime
|
|
132
270
|
end
|
133
271
|
|
134
272
|
def dev_mode?
|
135
|
-
ENV['IN_OUR_TIME'] == 'development'
|
273
|
+
ENV['IN_OUR_TIME'] == 'development'.freeze
|
136
274
|
end
|
137
275
|
|
138
276
|
def puts_title colour
|
139
277
|
title =
|
140
|
-
|
278
|
+
%q{ _____ ____ _______ _
|
141
279
|
|_ _| / __ \ |__ __(_)
|
142
280
|
| | _ __ | | | |_ _ _ __ | | _ _ __ ___ ___
|
143
281
|
| | | '_ \ | | | | | | | '__| | | | | '_ ` _ \ / _ \
|
144
282
|
_| |_| | | | | |__| | |_| | | | | | | | | | | | __/
|
145
283
|
|_____|_| |_| \____/ \__,_|_| |_| |_|_| |_| |_|\___|
|
146
|
-
}
|
284
|
+
}.freeze
|
147
285
|
|
148
286
|
title.split("\n").map{|l| iot_print(l + "\r\n", colour)} if(window_width > 61)
|
149
287
|
iot_puts("In Our Time\r", colour) unless(window_width > 61)
|
@@ -200,7 +338,7 @@ class InOurTime
|
|
200
338
|
|
201
339
|
def set_height
|
202
340
|
height = window_height
|
203
|
-
while(height -2 % 10 != 0) ; height -=1 ; end
|
341
|
+
while(((height - 2) % 10) != 0) ; height -= 1 ; end
|
204
342
|
height = 10 if height < 10
|
205
343
|
@page_height = height if(@config[:page_height] == :auto)
|
206
344
|
@page_height = @config[:page_height] unless(@config[:page_height] == :auto)
|
@@ -210,8 +348,8 @@ class InOurTime
|
|
210
348
|
width = window_width
|
211
349
|
while(width % 10 != 0) ; width -=1 ; end
|
212
350
|
width = 20 if width < 20
|
213
|
-
@page_width = width - 1 if(@config[:page_width]
|
214
|
-
@page_width = @config[:page_width] unless(@config[:page_width]
|
351
|
+
@page_width = width - 1 if(@config[:page_width] == :auto)
|
352
|
+
@page_width = @config[:page_width] unless(@config[:page_width] == :auto)
|
215
353
|
end
|
216
354
|
|
217
355
|
def window_height
|
@@ -249,25 +387,16 @@ class InOurTime
|
|
249
387
|
end
|
250
388
|
|
251
389
|
def rss_addresses
|
390
|
+
filename = "/episodes/downloads.rss"
|
252
391
|
host = 'http://www.bbc.co.uk/programmes'
|
253
|
-
[ "/b006qykl/
|
254
|
-
"/
|
255
|
-
|
256
|
-
"/p01f0vzr/episodes/downloads.rss",
|
257
|
-
"/p01gvqlg/episodes/downloads.rss",
|
258
|
-
"/p01gyd7j/episodes/downloads.rss"
|
259
|
-
].collect{|page| host + page}
|
392
|
+
[ "/b006qykl", "/p01drwny", "/p01dh5yg",
|
393
|
+
"/p01f0vzr", "/p01gvqlg", "/p01gyd7j"
|
394
|
+
].collect{|page| host + page + filename}
|
260
395
|
end
|
261
396
|
|
262
397
|
def local_rss
|
263
|
-
[
|
264
|
-
"
|
265
|
-
"history.rss",
|
266
|
-
"in_our_time.rss",
|
267
|
-
"philosophy.rss",
|
268
|
-
"religion.rss",
|
269
|
-
"science.rss"
|
270
|
-
]
|
398
|
+
[ "culture.rss", "history.rss", "in_our_time.rss",
|
399
|
+
"philosophy.rss", "religion.rss", "science.rss"]
|
271
400
|
end
|
272
401
|
|
273
402
|
def fetch_uri uri, file
|
@@ -342,13 +471,14 @@ class InOurTime
|
|
342
471
|
end
|
343
472
|
|
344
473
|
def build_program(bin)
|
345
|
-
title = bin[
|
474
|
+
title = bin['title'].shift.text
|
346
475
|
{ title: title,
|
347
|
-
subtitle: bin[
|
348
|
-
summary: bin[
|
349
|
-
duration: bin[
|
350
|
-
date: bin[
|
351
|
-
link: bin[
|
476
|
+
subtitle: bin['itunes:subtitle'].shift.text,
|
477
|
+
summary: bin['itunes:summary'].shift.text,
|
478
|
+
duration: bin['itunes:duration'].shift.text,
|
479
|
+
date: bin['pubDate'].shift.text[0..15],
|
480
|
+
link: bin['link'].shift.text,
|
481
|
+
url: bin['url'].shift,
|
352
482
|
have_locally: have_locally?(title)
|
353
483
|
}
|
354
484
|
end
|
@@ -376,6 +506,10 @@ class InOurTime
|
|
376
506
|
bin[tag] = [] if bin[tag].nil?
|
377
507
|
bin[tag] = @doc.xpath(item_path(tag))
|
378
508
|
end
|
509
|
+
bin['url'] = []
|
510
|
+
@doc.xpath(item_path('enclosure')).each do |x|
|
511
|
+
bin['url'] << x.get('url')
|
512
|
+
end
|
379
513
|
build_programs(bin)
|
380
514
|
end
|
381
515
|
uniquify_programs
|
@@ -418,12 +552,51 @@ class InOurTime
|
|
418
552
|
redraw
|
419
553
|
end
|
420
554
|
|
421
|
-
def
|
422
|
-
|
555
|
+
def title_focus
|
556
|
+
@playing ? @playing : (@sorted_titles[@last_selected || 0])
|
557
|
+
end
|
558
|
+
|
559
|
+
def top_selected
|
560
|
+
@selected == 0
|
561
|
+
end
|
562
|
+
|
563
|
+
def end_selected
|
564
|
+
@selected == @titles_count - 1
|
565
|
+
end
|
566
|
+
|
567
|
+
def top_title_focus
|
568
|
+
title_focus == @sorted_titles.first
|
569
|
+
end
|
570
|
+
|
571
|
+
def end_title_focus
|
572
|
+
title_focus == @sorted_titles.last
|
573
|
+
end
|
574
|
+
|
575
|
+
def top_or_end?
|
576
|
+
top_selected || end_selected
|
577
|
+
end
|
578
|
+
|
579
|
+
def store_selected
|
580
|
+
@last_selected = @selected
|
581
|
+
end
|
582
|
+
|
583
|
+
def top_or_end_title_focus
|
584
|
+
top_title_focus || end_title_focus
|
585
|
+
end
|
586
|
+
|
587
|
+
def jump_key
|
423
588
|
if top_or_end?
|
424
|
-
|
589
|
+
if top_or_end_title_focus
|
590
|
+
if top_selected
|
591
|
+
list_end
|
592
|
+
else
|
593
|
+
list_top
|
594
|
+
end
|
595
|
+
else
|
596
|
+
draw_by_title title_focus
|
597
|
+
end
|
425
598
|
else
|
426
|
-
|
599
|
+
store_selected
|
427
600
|
list_top_or_end
|
428
601
|
end
|
429
602
|
end
|
@@ -437,18 +610,12 @@ class InOurTime
|
|
437
610
|
end
|
438
611
|
end
|
439
612
|
|
440
|
-
def top_or_end?
|
441
|
-
@selected == 0 || @selected == @titles_count - 1
|
442
|
-
end
|
443
|
-
|
444
613
|
def list_top
|
445
|
-
@last_selected = @selected
|
446
614
|
@selected = 0
|
447
615
|
draw_selected
|
448
616
|
end
|
449
617
|
|
450
618
|
def list_end
|
451
|
-
@last_selected = @selected
|
452
619
|
@selected = @titles_count - 1
|
453
620
|
draw_selected
|
454
621
|
end
|
@@ -497,7 +664,7 @@ class InOurTime
|
|
497
664
|
|
498
665
|
def player_cmd
|
499
666
|
if use_mpg123?
|
500
|
-
"mpg123
|
667
|
+
"mpg123 -Cvk#{pre_delay}"
|
501
668
|
else
|
502
669
|
get_player
|
503
670
|
end
|
@@ -517,12 +684,12 @@ class InOurTime
|
|
517
684
|
@sorted_titles.each do |title|
|
518
685
|
title.split(' ').each do |word|
|
519
686
|
if distances[title].nil?
|
520
|
-
distances[title] = Levenshtein
|
687
|
+
distances[title] = Levenshtein.distance(search_term, word)
|
521
688
|
else
|
522
689
|
distances[title] =
|
523
690
|
distances[title] >
|
524
|
-
Levenshtein
|
525
|
-
Levenshtein
|
691
|
+
Levenshtein.distance(search_term, word.downcase) ?
|
692
|
+
Levenshtein.distance(search_term, word.downcase) :
|
526
693
|
distances[title]
|
527
694
|
end
|
528
695
|
end
|
@@ -534,11 +701,14 @@ class InOurTime
|
|
534
701
|
|
535
702
|
def print_search_results results
|
536
703
|
puts
|
537
|
-
|
704
|
+
iot_print "0:", @count_sel_colour, :now
|
705
|
+
iot_puts " Search Again!", @system_colour, :now
|
706
|
+
puts
|
538
707
|
puts
|
539
708
|
5.times do |count|
|
540
|
-
|
541
|
-
|
709
|
+
iot_print "#{count + 1}:", @count_sel_colour, :now
|
710
|
+
iot_print " #{results[count][0]}", @system_colour, :now
|
711
|
+
puts
|
542
712
|
end
|
543
713
|
puts
|
544
714
|
end
|
@@ -555,7 +725,8 @@ class InOurTime
|
|
555
725
|
end
|
556
726
|
|
557
727
|
def get_search_term
|
558
|
-
|
728
|
+
iot_puts "Enter Search Term or just Return for Random:", @system_colour, :now
|
729
|
+
puts
|
559
730
|
puts
|
560
731
|
print "Search Term: "
|
561
732
|
gets.chomp
|
@@ -563,7 +734,7 @@ class InOurTime
|
|
563
734
|
|
564
735
|
def get_search_choice
|
565
736
|
print "Enter Choice: "
|
566
|
-
temp =
|
737
|
+
temp = $stdin.getch.chomp
|
567
738
|
temp == '0' ? :search_again : temp
|
568
739
|
end
|
569
740
|
|
@@ -598,7 +769,7 @@ class InOurTime
|
|
598
769
|
render
|
599
770
|
10.times do
|
600
771
|
begin
|
601
|
-
res = Net::HTTP.get_response(URI.parse(prg[:
|
772
|
+
res = Net::HTTP.get_response(URI.parse(prg[:url]))
|
602
773
|
rescue SocketError => e
|
603
774
|
print_error_and_delay "Error: Failed to connect to Internet! (#{e.class})"
|
604
775
|
render
|
@@ -620,11 +791,10 @@ class InOurTime
|
|
620
791
|
end
|
621
792
|
retries += 1
|
622
793
|
end
|
623
|
-
if retries
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
end
|
794
|
+
return if retries < 10
|
795
|
+
print_error_and_delay "Max retries downloading #{prg[:title]}"
|
796
|
+
render
|
797
|
+
@no_play = true
|
628
798
|
end
|
629
799
|
|
630
800
|
# Cross-platform way of finding an executable in the $PATH.
|
@@ -647,16 +817,58 @@ class InOurTime
|
|
647
817
|
quit 1
|
648
818
|
end
|
649
819
|
|
820
|
+
def init_countdown(duration)
|
821
|
+
@play_time = PlayTime.new(duration) unless use_mpg123?
|
822
|
+
end
|
823
|
+
|
650
824
|
def run_program prg
|
651
|
-
download prg
|
652
825
|
unless @no_play
|
653
826
|
@playing = prg[:title]
|
654
827
|
player = player_cmd.split(' ').first
|
655
|
-
unknown_player(player) unless which(player)
|
828
|
+
unknown_player(player) unless which(File.basename player)
|
656
829
|
window_title prg[:title]
|
657
830
|
cmd = player_cmd + ' ' + filename_from_title(@playing)
|
658
831
|
@messages = []
|
659
|
-
|
832
|
+
init_countdown prg[:duration].to_i
|
833
|
+
@player_th = Thread.new do
|
834
|
+
buf = ''
|
835
|
+
p_out, @p_in, @pid = PTY.spawn(cmd)
|
836
|
+
sleep 1
|
837
|
+
count = 0
|
838
|
+
loop do
|
839
|
+
unless use_mpg123?
|
840
|
+
sleep 1
|
841
|
+
else
|
842
|
+
x = p_out.getc unless p_out.eof?
|
843
|
+
if(((count >= 6) && (count <= 10)) ||
|
844
|
+
((count > 15) && (count < 21)) )
|
845
|
+
buf << x
|
846
|
+
count += 1
|
847
|
+
elsif(((count == 0) && (x == 'T')) ||
|
848
|
+
((count == 1) && (x == 'i')) ||
|
849
|
+
((count == 2) && (x == 'm')) ||
|
850
|
+
((count == 3) && (x == 'e')) ||
|
851
|
+
((count == 4) && (x == ':')) ||
|
852
|
+
((count == 5) && (x == ' ')) ||
|
853
|
+
((count >= 12) && (count <= 15)))
|
854
|
+
count += 1
|
855
|
+
elsif count == 11
|
856
|
+
@running_time = buf
|
857
|
+
buf = ''
|
858
|
+
count += 1
|
859
|
+
elsif count == 21
|
860
|
+
@remaining_time = buf
|
861
|
+
buf = ''
|
862
|
+
count = 0
|
863
|
+
sleep 0.3
|
864
|
+
p_out.flush
|
865
|
+
else
|
866
|
+
count = 0
|
867
|
+
sleep 0.001
|
868
|
+
end
|
869
|
+
end
|
870
|
+
end
|
871
|
+
end
|
660
872
|
end
|
661
873
|
@no_play = nil
|
662
874
|
end
|
@@ -677,6 +889,7 @@ class InOurTime
|
|
677
889
|
begin
|
678
890
|
@p_in.puts str
|
679
891
|
rescue Errno::EIO
|
892
|
+
kill_audio
|
680
893
|
reset
|
681
894
|
end
|
682
895
|
end
|
@@ -684,6 +897,8 @@ class InOurTime
|
|
684
897
|
def pause
|
685
898
|
return unless control_play?
|
686
899
|
@paused = @paused ? false : true
|
900
|
+
@play_time.pause if @paused unless use_mpg123?
|
901
|
+
@play_time.unpause unless @paused unless use_mpg123?
|
687
902
|
write_player " "
|
688
903
|
redraw
|
689
904
|
end
|
@@ -693,11 +908,15 @@ class InOurTime
|
|
693
908
|
end
|
694
909
|
|
695
910
|
def forward
|
696
|
-
|
911
|
+
return unless control_play?
|
912
|
+
write_player ":"
|
913
|
+
@play_time.forward unless use_mpg123?
|
697
914
|
end
|
698
915
|
|
699
916
|
def rewind
|
700
|
-
|
917
|
+
return unless control_play?
|
918
|
+
write_player ";"
|
919
|
+
@play_time.rewind unless use_mpg123?
|
701
920
|
end
|
702
921
|
|
703
922
|
def instructions
|
@@ -706,11 +925,30 @@ class InOurTime
|
|
706
925
|
iot_print "for instructions", @system_colour
|
707
926
|
end
|
708
927
|
|
928
|
+
def print_playing
|
929
|
+
iot_print("Playing: ", @count_colour)
|
930
|
+
end
|
931
|
+
|
932
|
+
def print_paused
|
933
|
+
iot_print("Paused: ", @count_colour)
|
934
|
+
end
|
935
|
+
|
936
|
+
def print_play_time
|
937
|
+
if use_mpg123?
|
938
|
+
iot_print(@playing, @selection_colour)
|
939
|
+
iot_print(' (' + @running_time, @selection_colour) unless @running_time.nil?
|
940
|
+
iot_print(' / ' + @remaining_time, @selection_colour) unless @remaining_time.nil?
|
941
|
+
iot_puts(')', @selection_colour) unless @running_time.nil?
|
942
|
+
else
|
943
|
+
iot_puts(@playing + @play_time.read, @selection_colour)
|
944
|
+
end
|
945
|
+
end
|
946
|
+
|
709
947
|
def print_playing_maybe
|
710
948
|
if @playing
|
711
|
-
|
712
|
-
|
713
|
-
|
949
|
+
print_playing unless @paused
|
950
|
+
print_paused if @paused
|
951
|
+
print_play_time
|
714
952
|
elsif @started.nil?
|
715
953
|
@started = true
|
716
954
|
instructions
|
@@ -718,11 +956,19 @@ class InOurTime
|
|
718
956
|
end
|
719
957
|
|
720
958
|
def kill_audio
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
959
|
+
loop do
|
960
|
+
Thread.kill(@player_th) if @player_th
|
961
|
+
return unless @playing
|
962
|
+
begin
|
963
|
+
break unless @pid.is_a?(Integer)
|
964
|
+
Process.kill('QUIT', @pid)
|
965
|
+
_, status = Process.wait2 @pid
|
966
|
+
break if status.exited?
|
967
|
+
rescue Errno::ESRCH
|
968
|
+
break
|
969
|
+
end
|
970
|
+
sleep 0.2
|
971
|
+
end
|
726
972
|
reset
|
727
973
|
end
|
728
974
|
|
@@ -769,6 +1015,7 @@ class InOurTime
|
|
769
1015
|
|
770
1016
|
def load_help_maybe
|
771
1017
|
return unless help_option?
|
1018
|
+
@config[:colour] = false
|
772
1019
|
help
|
773
1020
|
puts
|
774
1021
|
exit 0
|
@@ -776,37 +1023,43 @@ class InOurTime
|
|
776
1023
|
|
777
1024
|
def help_screen
|
778
1025
|
[] <<
|
779
|
-
" In Our Time
|
780
|
-
" " <<
|
781
|
-
" Play/Stop - X / Enter " <<
|
782
|
-
" Next/Prev - Up / Down " <<
|
783
|
-
" Next/Prev Page - Right / Left " <<
|
784
|
-
" Sort - S " <<
|
785
|
-
" Search - ? " <<
|
786
|
-
" Theme Toggle - T " <<
|
787
|
-
" List Top/End - L " <<
|
788
|
-
" Update - U " <<
|
789
|
-
" Download - D " <<
|
790
|
-
" Info - I " <<
|
791
|
-
" Help - H " <<
|
792
|
-
" Quit - Q " <<
|
793
|
-
" mpg123 Control - " <<
|
794
|
-
" Pause/Resume - P / Spacebar " <<
|
795
|
-
" Forward Skip - F " <<
|
796
|
-
" Reverse Skip - R " <<
|
1026
|
+
" In Our Time Payer (#{@version}) " <<
|
797
1027
|
" " <<
|
1028
|
+
" Play/Stop - Enter/X " <<
|
1029
|
+
" Next/Prev - Up/Down " <<
|
1030
|
+
" Next/Prev Page - Right/Left " <<
|
1031
|
+
" Arrange - A " <<
|
1032
|
+
" Search - ? " <<
|
1033
|
+
" Theme Toggle - T " <<
|
1034
|
+
" Jump Around List - J " <<
|
1035
|
+
" Update - U " <<
|
1036
|
+
" Download - D " <<
|
1037
|
+
" Enqueue - E " <<
|
1038
|
+
" Shuffle Play - S " <<
|
1039
|
+
" Shuffle Next - N " <<
|
1040
|
+
" Info - I " <<
|
1041
|
+
" Help - H " <<
|
1042
|
+
" Quit - Q " <<
|
1043
|
+
" mpg123 Control - " <<
|
1044
|
+
" Pause/Resume - P/Spacebar " <<
|
1045
|
+
" Forward Skip - F " <<
|
1046
|
+
" Reverse Skip - R " <<
|
798
1047
|
"Config: #{CONFIG} "
|
799
1048
|
end
|
800
1049
|
|
801
|
-
def
|
802
|
-
def
|
803
|
-
def
|
804
|
-
def
|
1050
|
+
def title_xy; [0,0] end
|
1051
|
+
def main_xy; [1, help_screen.size - 7] end
|
1052
|
+
def mpg_xy; [help_screen.size - 6, -2] end
|
1053
|
+
def cfg_xy; [help_screen.size - 1, -1] end
|
1054
|
+
def help_partial(x); help_screen[x[0]..x[1]] end
|
1055
|
+
def help_title; help_partial(title_xy) end
|
1056
|
+
def help_main; help_partial(main_xy) end
|
1057
|
+
def help_cfg; help_partial(cfg_xy) end
|
805
1058
|
|
806
1059
|
def help_mpg
|
807
|
-
scr = help_partial(
|
808
|
-
scr[0].rstrip! << ' (enabled)
|
809
|
-
scr[0].rstrip! << ' (disabled)
|
1060
|
+
scr = help_partial(mpg_xy)
|
1061
|
+
scr[0].rstrip! << ' (enabled) ' if use_mpg123?
|
1062
|
+
scr[0].rstrip! << ' (disabled) ' unless use_mpg123?
|
810
1063
|
scr
|
811
1064
|
end
|
812
1065
|
|
@@ -817,6 +1070,8 @@ class InOurTime
|
|
817
1070
|
@count_colour if use_mpg123?
|
818
1071
|
when :cfg
|
819
1072
|
@system_colour
|
1073
|
+
when :title
|
1074
|
+
@system_colour
|
820
1075
|
else
|
821
1076
|
@text_colour
|
822
1077
|
end
|
@@ -835,14 +1090,13 @@ class InOurTime
|
|
835
1090
|
help_render :title
|
836
1091
|
help_render :main
|
837
1092
|
help_render :mpg
|
838
|
-
help_render :cfg
|
1093
|
+
# help_render :cfg
|
839
1094
|
end
|
840
1095
|
|
841
1096
|
def help
|
842
1097
|
unless @help
|
843
1098
|
clear_content
|
844
1099
|
print_help
|
845
|
-
print_playing_maybe unless help_option?
|
846
1100
|
@help = true
|
847
1101
|
render
|
848
1102
|
else
|
@@ -966,21 +1220,6 @@ class InOurTime
|
|
966
1220
|
render
|
967
1221
|
end
|
968
1222
|
|
969
|
-
def check_process
|
970
|
-
if(@playing && @pid.is_a?(Integer))
|
971
|
-
begin
|
972
|
-
write_player( "\e")
|
973
|
-
if @pid.is_a? Integer
|
974
|
-
Process.kill 0, @pid
|
975
|
-
end
|
976
|
-
rescue Errno::ESRCH
|
977
|
-
reset
|
978
|
-
end
|
979
|
-
else
|
980
|
-
@pid = nil
|
981
|
-
end
|
982
|
-
end
|
983
|
-
|
984
1223
|
def page_forward
|
985
1224
|
return unless @line_count < @titles_count
|
986
1225
|
@selected = @line_count
|
@@ -1006,23 +1245,23 @@ class InOurTime
|
|
1006
1245
|
end
|
1007
1246
|
|
1008
1247
|
def play
|
1009
|
-
|
1010
|
-
|
1011
|
-
|
1012
|
-
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
1016
|
-
|
1017
|
-
|
1248
|
+
title = @sorted_titles[@selected]
|
1249
|
+
playing = @playing
|
1250
|
+
prg = select_program(title)
|
1251
|
+
download prg unless playing
|
1252
|
+
download prg if playing && (playing != title)
|
1253
|
+
kill_audio
|
1254
|
+
return unless (! playing) || (playing != title)
|
1255
|
+
run_program prg
|
1256
|
+
redraw
|
1018
1257
|
end
|
1019
1258
|
|
1020
1259
|
def update_key
|
1021
|
-
|
1022
|
-
|
1023
|
-
|
1024
|
-
|
1025
|
-
|
1260
|
+
update
|
1261
|
+
parse_rss
|
1262
|
+
sort_titles
|
1263
|
+
@selected = 0
|
1264
|
+
draw_selected
|
1026
1265
|
end
|
1027
1266
|
|
1028
1267
|
def download_key
|
@@ -1032,6 +1271,18 @@ class InOurTime
|
|
1032
1271
|
draw_selected
|
1033
1272
|
end
|
1034
1273
|
|
1274
|
+
def enqueue
|
1275
|
+
@queued << @sorted_titles[@selected]
|
1276
|
+
end
|
1277
|
+
|
1278
|
+
def next_program
|
1279
|
+
kill_audio
|
1280
|
+
end
|
1281
|
+
|
1282
|
+
def shuffle_key
|
1283
|
+
@queued = @sorted_titles.shuffle
|
1284
|
+
end
|
1285
|
+
|
1035
1286
|
def quit_key
|
1036
1287
|
kill_audio
|
1037
1288
|
quit
|
@@ -1039,9 +1290,10 @@ class InOurTime
|
|
1039
1290
|
|
1040
1291
|
def do_action ip
|
1041
1292
|
case ip
|
1042
|
-
when :pause, :forward, :rewind, :
|
1293
|
+
when :pause, :forward, :rewind, :jump_key, :page_forward, :page_back,
|
1043
1294
|
:previous, :next, :play, :sort_key, :theme_toggle, :update_key,
|
1044
|
-
:info, :help, :quit_key, :search, :download_key
|
1295
|
+
:info, :help, :quit_key, :search, :download_key, :enqueue,
|
1296
|
+
:next_program, :shuffle_key
|
1045
1297
|
self.send ip
|
1046
1298
|
end
|
1047
1299
|
end
|
@@ -1051,6 +1303,60 @@ class InOurTime
|
|
1051
1303
|
@help = nil unless ip == :help
|
1052
1304
|
end
|
1053
1305
|
|
1306
|
+
def ping_player
|
1307
|
+
write_player("\e")
|
1308
|
+
end
|
1309
|
+
|
1310
|
+
def check_player_process
|
1311
|
+
Process.kill 0, @pid
|
1312
|
+
end
|
1313
|
+
|
1314
|
+
def check_process
|
1315
|
+
return unless @playing
|
1316
|
+
if @pid.is_a?(Integer)
|
1317
|
+
begin
|
1318
|
+
write_player("\e")
|
1319
|
+
sleep 0.1
|
1320
|
+
if @pid.is_a? Integer
|
1321
|
+
check_player_process
|
1322
|
+
end
|
1323
|
+
rescue Errno::ESRCH
|
1324
|
+
kill_audio
|
1325
|
+
end
|
1326
|
+
else
|
1327
|
+
kill_audio
|
1328
|
+
unless @queued.empty?
|
1329
|
+
title = @queued.shift
|
1330
|
+
prg = select_program(title)
|
1331
|
+
download prg
|
1332
|
+
run_program(prg)
|
1333
|
+
draw_by_title title
|
1334
|
+
end
|
1335
|
+
end
|
1336
|
+
end
|
1337
|
+
|
1338
|
+
def check_finished
|
1339
|
+
return if use_mpg123?
|
1340
|
+
return unless @playing
|
1341
|
+
return unless @play_time.ended?
|
1342
|
+
kill_audio
|
1343
|
+
end
|
1344
|
+
|
1345
|
+
def check_tic
|
1346
|
+
return unless @tic.toc
|
1347
|
+
# check_process if @tic.process
|
1348
|
+
# check_finished if @tic.ended
|
1349
|
+
return unless @info.nil?
|
1350
|
+
return unless @help.nil?
|
1351
|
+
check_playing_time if @tic.playing_time
|
1352
|
+
end
|
1353
|
+
|
1354
|
+
def check_playing_time
|
1355
|
+
return unless @playing
|
1356
|
+
return unless @play_time.changed? unless use_mpg123?
|
1357
|
+
redraw
|
1358
|
+
end
|
1359
|
+
|
1054
1360
|
def run
|
1055
1361
|
ip = ''
|
1056
1362
|
@tic = Tic.new
|
@@ -1061,7 +1367,7 @@ class InOurTime
|
|
1061
1367
|
loop do
|
1062
1368
|
ip = @key.read
|
1063
1369
|
break unless ip == :no_event
|
1064
|
-
|
1370
|
+
check_tic
|
1065
1371
|
do_events
|
1066
1372
|
end
|
1067
1373
|
reset_info_maybe ip
|
data/lib/iot/keyboard_events.rb
CHANGED
@@ -36,6 +36,7 @@ class KeyboardEvents
|
|
36
36
|
end
|
37
37
|
|
38
38
|
def run
|
39
|
+
Thread.abort_on_exception = true
|
39
40
|
@key = Thread.new do
|
40
41
|
while @event != :quit_key
|
41
42
|
str = ''
|
@@ -72,6 +73,8 @@ class KeyboardEvents
|
|
72
73
|
when "\e"
|
73
74
|
@mode = :escape
|
74
75
|
:no_event
|
76
|
+
when 'a', 'A'
|
77
|
+
:sort_key
|
75
78
|
when 'd', 'D'
|
76
79
|
:download_key
|
77
80
|
when 'f', 'F'
|
@@ -80,8 +83,10 @@ class KeyboardEvents
|
|
80
83
|
:help
|
81
84
|
when 'i', 'I'
|
82
85
|
:info
|
83
|
-
when '
|
84
|
-
:
|
86
|
+
when 'j', 'J'
|
87
|
+
:jump_key
|
88
|
+
when 'e', 'E'
|
89
|
+
:enqueue
|
85
90
|
when 'p', 'P', ' '
|
86
91
|
:pause
|
87
92
|
when 'q', 'Q', "\u0003", "\u0004"
|
@@ -89,7 +94,9 @@ class KeyboardEvents
|
|
89
94
|
when 'r', 'R'
|
90
95
|
:rewind
|
91
96
|
when 's', 'S'
|
92
|
-
:
|
97
|
+
:shuffle_key
|
98
|
+
when 'n', 'N'
|
99
|
+
:next_program
|
93
100
|
when 't', 'T'
|
94
101
|
:theme_toggle
|
95
102
|
when 'u', 'U'
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: in_our_time
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Martyn Jago
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-02-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: oga
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 2.1.4
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 2.1.4
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: colorize
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -94,7 +94,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
94
94
|
version: '0'
|
95
95
|
requirements: []
|
96
96
|
rubyforge_project:
|
97
|
-
rubygems_version: 2.
|
97
|
+
rubygems_version: 2.6.13
|
98
98
|
signing_key:
|
99
99
|
specification_version: 4
|
100
100
|
summary: Select, play, and download BBC 'In Our Time' podcasts - all from the command
|