in_our_time 0.7.0 → 0.7.3
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 +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
|