in_our_time 0.3.4 → 0.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2cf2c996c094b425c9b23dfdc1d333be877ad11b
4
- data.tar.gz: 27014f8d06c891f07bcb92db25325718d08affc6
3
+ metadata.gz: fba0bd53285d9df8789fb1d0464650ed0c769a41
4
+ data.tar.gz: e190622c306d519d8d0a568d629c3f06dc1a5a79
5
5
  SHA512:
6
- metadata.gz: c124de122df9bc9ac02db4c35461e48ca010a3d99a806e222ef5ec5108512e2a4ff9b931afc1b741c38a99f4a86dd24f1f4a9e97176792850bacb6bc74db8c67
7
- data.tar.gz: e6b1afc628991379da911fdcd8a4a6cd051859c05f396e085b765658779758d3e35f119d63d47721148caef008fd7c58c01f24f49661690d09ea945586d0e626
6
+ metadata.gz: 5293b5c48c8a45a2dc7efc464f0ce3c87fdffddd9546e7c4223d339335ef4cd400f8c989fd5c4d227ebd1afd1559a5e72abeea28dfce4287ce9036e8045e0e9a
7
+ data.tar.gz: 86738cce5846617abd0f2aac1d019c88eca1a59143792e59c6c7b5137ebcfeaf690fc151ef2334ec9b3d0ebace094170eb1aa381039cc99c96fca7738ce9a239
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
1
  /audio/
2
2
  /rss/
3
3
  /in_our_time.org
4
+ /.rubocop_todo.yml
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.4
1
+ 0.4.0
data/in_our_time.gemspec CHANGED
@@ -24,3 +24,4 @@ Gem::Specification.new do |spec|
24
24
  spec.add_runtime_dependency 'colorize', '>= 0.8.1'
25
25
  spec.add_development_dependency 'version', '>= 1.0.0'
26
26
  end
27
+
data/lib/iot/iot.rb CHANGED
@@ -8,9 +8,9 @@ require 'colorize'
8
8
  require 'oga'
9
9
  require 'pty'
10
10
  require 'io/console'
11
+ require_relative 'keyboard_events'
11
12
 
12
13
  class InOurTime
13
-
14
14
  ROOT = File.expand_path '~/'
15
15
  HERE = File.dirname(__FILE__)
16
16
  CONFIG_DIR = '.in_our_time'
@@ -22,102 +22,19 @@ class InOurTime
22
22
  UPDATE_INTERVAL = 604800
23
23
  AUDIO_DIRECTORY = 'audio'
24
24
  RSS_DIRECTORY = 'rss'
25
- PAGE_HEIGHT = 20
26
- PAGE_WIDTH = 80
27
-
28
- class KeyboardEvents
29
-
30
- def initialize
31
- @mode = :normal
32
- @event = :no_event
33
- end
34
-
35
- def reset
36
- STDIN.flush
37
- end
38
-
39
- def ke_events
40
- sleep 0.001
41
- end
42
-
43
- def read
44
- ret_val = @event
45
- # reset
46
- @event = :no_event
47
- ret_val
48
- end
49
-
50
- def run
51
- Thread.new do
52
- loop do
53
- str = ''
54
- loop do
55
- str = STDIN.getch
56
- if str == "\e"
57
- @mode = :escape
58
- else
59
- case @mode
60
- when :escape
61
- if str == "["
62
- @mode = :escape_2
63
- else
64
- @mode = :normal
65
- end
66
- when :escape_2
67
- @event = :previous if str == "A"
68
- @event = :next if str == "B"
69
- @event = :page_forward if str == "C"
70
- @event = :previous if str == "D"
71
- @mode = :normal
72
-
73
- else
74
- break if @event == :no_event
75
- end
76
- end
77
- ke_events
78
- end
79
-
80
- case str
81
- when "\e"
82
- @mode = :escape
83
- when "l",'L'
84
- @event = :list
85
- when "u",'U'
86
- @event = :update
87
- when ' '
88
- @event = :page_forward
89
- when "q",'Q', "\u0003", "\u0004"
90
- @event = :quit
91
- when 'p', 'P'
92
- @event = :pause
93
- when 'f', 'F'
94
- @event = :forward
95
- when 'r', 'R'
96
- @event = :rewind
97
- when 's', 'S'
98
- @event = :sort
99
- when 'x', 'X', "\r"
100
- @event = :play
101
- when 'i', 'I'
102
- @event = :info
103
- when '?', 'h'
104
- @event = :help
105
- else
106
- @event = :no_event
107
- end
108
- ke_events
109
- end
110
- end
111
- end
112
- end
113
25
 
114
26
  class Tic
115
27
  def initialize
116
28
  @flag = false
29
+ run
30
+ end
31
+
32
+ def kill
33
+ Thread.kill(@th_tic) if @th_tic
117
34
  end
118
35
 
119
36
  def run
120
- Thread.new do
37
+ @th_tic = Thread.new do
121
38
  loop do
122
39
  sleep 1
123
40
  @flag = true
@@ -126,41 +43,56 @@ class InOurTime
126
43
  end
127
44
 
128
45
  def toc
129
- ret_val, @flag = @flag, false
46
+ ret_val = @flag
47
+ @flag = false
130
48
  ret_val
131
49
  end
132
50
  end
133
51
 
134
52
  def initialize
135
- @programs, @selected = [], 0
53
+ @content = ''
54
+ @programs = []
55
+ @selected = 0
56
+ clear
57
+ print "\e[?25h"
136
58
  setup
137
59
  load_config
138
60
  load_version
139
61
  load_help_maybe
140
- display_version
62
+ opening_title
141
63
  check_remote
142
64
  parse_rss
143
65
  sort_titles
144
66
  version_display_wait
67
+ STDIN.echo = false
68
+ STDIN.raw!
145
69
  run
146
70
  end
147
71
 
148
72
  def do_events
149
73
  sleep 0.003
74
+ sleep 0.1
150
75
  end
151
76
 
152
77
  def quit code = 0
153
- system("stty -raw echo")
78
+ STDIN.echo = true
79
+ STDIN.cooked!
80
+ clear
81
+ puts 'Quitting...'
82
+ clear
83
+ @key.kill
84
+ @tic.kill
154
85
  exit code
155
86
  end
156
87
 
157
88
  def version_display_wait
158
- do_events while Time.now - @start_time < 1
89
+ return if dev_mode?
90
+ do_events while Time.now - @start_time < 1.5
159
91
  end
160
92
 
161
93
  def iot_print x, col = @text_colour
162
- STDOUT.print x.colorize col if @config[:colour]
163
- STDOUT.print x unless @config[:colour]
94
+ @content << x.colorize(col) if @config[:colour]
95
+ @content << x unless @config[:colour]
164
96
  end
165
97
 
166
98
  def iot_puts x = '', col = @text_colour
@@ -168,6 +100,15 @@ class InOurTime
168
100
  iot_print "\n\r"
169
101
  end
170
102
 
103
+ def clear_content
104
+ @content.clear
105
+ end
106
+
107
+ def render
108
+ clear
109
+ $stdout << @content
110
+ end
111
+
171
112
  def now
172
113
  Time.now.to_i
173
114
  end
@@ -179,16 +120,44 @@ class InOurTime
179
120
  pages = File.join iot, RSS_DIRECTORY
180
121
  Dir.mkdir iot unless Dir.exist? iot
181
122
  Dir.mkdir audio unless Dir.exist? audio
182
- unless Dir.exist? pages
183
- Dir.mkdir pages
184
- local_rss.map{|f| FileUtils.touch(File.join pages, f)}
185
- end
123
+ return if Dir.exist?(pages)
124
+ Dir.mkdir pages
125
+ local_rss.map{|f| FileUtils.touch(File.join pages, f)}
126
+ end
127
+
128
+ def dev_mode?
129
+ ENV['IN_OUR_TIME'] == 'development'
130
+ end
131
+
132
+ def puts_title colour
133
+ title =
134
+ %q{ _____ ____ _______ _
135
+ |_ _| / __ \ |__ __(_)
136
+ | | _ __ | | | |_ _ _ __ | | _ _ __ ___ ___
137
+ | | | '_ \ | | | | | | | '__| | | | | '_ ` _ \ / _ \
138
+ _| |_| | | | | |__| | |_| | | | | | | | | | | | __/
139
+ |_____|_| |_| \____/ \__,_|_| |_| |_|_| |_| |_|\___|
140
+ }
141
+
142
+ title.split("\n").map{|l| iot_print(l + "\r\n", colour)} if(window_width > 61)
143
+ iot_puts("In Our Time\r", colour) unless(window_width > 61)
144
+ iot_puts
145
+ end
146
+
147
+ def opening_title
148
+ return if dev_mode?
149
+ puts_title :light_green
150
+ render
151
+ sleep 0.5
152
+ clear_content
153
+ puts_title @system_colour
154
+ display_version
155
+ render
186
156
  end
187
157
 
188
158
  def display_version
189
- clear
190
- iot_print("Loading ", @system_colour) unless ARGV[0] == '-v' || ARGV[0] == '--version'
191
- iot_puts "In Our Time Player (#{@version})", @system_colour
159
+ iot_print("Loading ", :light_green) unless ARGV[0] == '-v' || ARGV[0] == '--version'
160
+ iot_puts "In Our Time Player (#{@version})", :light_green
192
161
  quit if ARGV[0] == '-v' || ARGV[0] == '--version'
193
162
  end
194
163
 
@@ -201,31 +170,71 @@ class InOurTime
201
170
  end
202
171
 
203
172
  def create_config
204
- @config = YAML::load_file(DEFAULT_CONFIG)
173
+ @config = YAML.load_file(DEFAULT_CONFIG)
205
174
  save_config
206
175
  end
207
176
 
208
- def do_configs
177
+ def init_theme
209
178
  theme = @config[:colour_theme]
210
179
  @selection_colour = @config[theme][:selection_colour]
211
180
  @count_sel_colour = @config[theme][:count_sel_colour]
212
181
  @count_colour = @config[theme][:count_colour]
213
182
  @text_colour = @config[theme][:text_colour]
214
183
  @system_colour = @config[theme][:system_colour]
215
- rows, cols = $stdout.winsize
216
- while(rows % 10 != 0) ; rows -=1 ; end
217
- while(cols % 10 != 0) ; cols -=1 ; end
218
- rows = 10 if rows < 10
219
- cols = 20 if cols < 20
220
- @config[:page_height] = rows if(@config[:page_height] == :auto)
221
- @config[:page_width] = cols if(@config[:page_width] == :auto)
222
- @line_count = @config[:page_height]
184
+ end
185
+
186
+ def theme_toggle
187
+ theme = @config[:colour_theme]
188
+ @config[:colour_theme] = theme == :light_theme ?
189
+ :dark_theme : :light_theme
190
+ save_config
191
+ init_theme
192
+ redraw
193
+ end
194
+
195
+ def set_height
196
+ height = window_height
197
+ while(height -2 % 10 != 0) ; height -=1 ; end
198
+ height = 10 if height < 10
199
+ @page_height = height if(@config[:page_height] == :auto)
200
+ @page_height = @config[:page_height] unless(@config[:page_height] == :auto)
201
+ end
202
+
203
+ def set_width
204
+ width = window_width
205
+ while(width % 10 != 0) ; width -=1 ; end
206
+ width = 20 if width < 20
207
+ @page_width = width - 1 if(@config[:page_width] == :auto)
208
+ @page_width = @config[:page_width] unless(@config[:page_width] == :auto)
209
+ end
210
+
211
+ def window_height
212
+ $stdout.winsize.first
213
+ end
214
+
215
+ def window_width
216
+ $stdout.winsize[1]
217
+ end
218
+
219
+ def set_dimensions
220
+ set_height
221
+ set_width
222
+ end
223
+
224
+ def init_line_count
225
+ @line_count = @page_height
226
+ end
227
+
228
+ def do_configs
229
+ init_theme
230
+ set_dimensions
231
+ init_line_count
223
232
  @sort = @config[:sort]
224
233
  end
225
234
 
226
235
  def load_config
227
236
  create_config unless File.exist? CONFIG
228
- @config = YAML::load_file(CONFIG)
237
+ @config = YAML.load_file(CONFIG)
229
238
  do_configs
230
239
  end
231
240
 
@@ -264,28 +273,32 @@ class InOurTime
264
273
  end
265
274
 
266
275
  def filename_from_title title
267
- temp = title.gsub(/[^0-9a-z ]/i, '').gsub(' ', '_').strip + '.mp3'
276
+ temp = title.gsub(/[^0-9a-z ]/i, '').tr(' ', '_').strip + '.mp3'
268
277
  File.join IN_OUR_TIME, AUDIO_DIRECTORY, temp.downcase
269
278
  end
270
279
 
271
- def download_audio program, addr
280
+ def download_audio(program, addr)
272
281
  res = Net::HTTP.get_response(URI.parse(addr))
273
282
  case res
274
283
  when Net::HTTPOK
275
284
  File.open(filename_from_title(program[:title]) , 'wb') do |f|
276
285
  iot_print "writing #{filename_from_title(program[:title])}...", @system_colour
286
+ render
277
287
  f.print(res.body)
278
288
  iot_puts " written.", @system_colour
289
+ render
279
290
  end
280
291
  program[:have_locally] = true
281
292
  else
282
293
  iot_puts 'Download failed. Retrying...', @system_colour
294
+ render
295
+ nil
283
296
  end
284
297
  end
285
298
 
286
299
  def have_locally? title
287
300
  filename = filename_from_title(title)
288
- File.exists?(filename) ? true : false
301
+ File.exist?(filename) ? true : false
289
302
  end
290
303
 
291
304
  def rss_files
@@ -293,13 +306,14 @@ class InOurTime
293
306
  end
294
307
 
295
308
  def update
296
- clear
309
+ clear_content
297
310
  iot_print "Checking rss feeds ", @system_colour
298
311
  local_rss.length.times do |count|
299
312
  iot_print '.', @system_colour
313
+ render
300
314
  fetch_uri rss_addresses[count], rss_files[count]
301
315
  end
302
- iot_puts
316
+ # iot_puts
303
317
  @config[:last_update] = now
304
318
  save_config
305
319
  end
@@ -310,10 +324,9 @@ class InOurTime
310
324
 
311
325
  def uniquify_programs
312
326
  @programs = @programs.uniq{|pr| pr[:title]}
313
- unless @programs.uniq.length == @programs.length
314
- print_error_and_delay "Error ensuring Programs unique!"
315
- quit 1
316
- end
327
+ return if @programs.uniq.length == @programs.length
328
+ print_error_and_delay "Error ensuring Programs unique!"
329
+ quit 1
317
330
  end
318
331
 
319
332
  def parse_rss
@@ -326,7 +339,7 @@ class InOurTime
326
339
  dates = @doc.xpath('rss/channel/item/pubDate')
327
340
  links = @doc.xpath('rss/channel/item/link')
328
341
 
329
- 0.upto (titles.length - 1) do |idx|
342
+ 0.upto(titles.length - 1) do |idx|
330
343
  program = {}
331
344
  program[:title] = titles[idx].text
332
345
  program[:subtitle] = subtitles[idx].text
@@ -357,7 +370,7 @@ class InOurTime
357
370
  if st == title
358
371
  selected = idx
359
372
  idx += 1
360
- while idx % @config[:page_height] != 0
373
+ while idx % @page_height != 0
361
374
  idx += 1
362
375
  end
363
376
  return selected, idx
@@ -365,12 +378,55 @@ class InOurTime
365
378
  end
366
379
  end
367
380
 
368
- def sort
381
+ def list_selected title
382
+ @selected, @line_count = sort_selected(title)
383
+ redraw
384
+ end
385
+
386
+ def list_playing
387
+ title = @sorted_titles[@selected]
388
+ if title == @playing
389
+ list_top
390
+ else
391
+ list_selected @playing
392
+ end
393
+ end
394
+
395
+ def list_stopped
396
+ if @selected == 0
397
+ title = @sorted_titles[@last_selected || 0]
398
+ list_selected title
399
+ else
400
+ list_top
401
+ end
402
+ end
403
+
404
+ def list_key
405
+ if @playing
406
+ list_playing
407
+ else
408
+ list_stopped
409
+ end
410
+ end
411
+
412
+ def list_top
413
+ @last_selected = @selected
414
+ @line_count = 0
415
+ @selected = 0
416
+ display_list :next_page
417
+ end
418
+
419
+ def sort_key
369
420
  title = @sorted_titles[@selected]
421
+ toggle_sort
422
+ list_selected title
423
+ end
424
+
425
+ def toggle_sort
370
426
  @sort = @sort == :age ? :alphabet : :age
427
+ @config[:sort] = @sort
428
+ save_config
371
429
  sort_titles
372
- @selected, @line_count = sort_selected(title)
373
- redraw
374
430
  end
375
431
 
376
432
  def redraw
@@ -402,43 +458,47 @@ class InOurTime
402
458
  end
403
459
 
404
460
  def clear
405
- system 'clear' or system 'cls'
461
+ system('clear') || system('cls')
406
462
  end
407
463
 
408
- def print_error_and_delay message
464
+ def print_error_and_delay message, delay = 2
409
465
  iot_puts message, :red
410
- sleep 2
466
+ sleep delay
411
467
  end
412
468
 
413
469
  def run_program prg
414
470
  unless prg[:have_locally]
415
471
  retries = 0
416
- clear
472
+ clear_content
417
473
  iot_puts "Fetching #{prg[:title]}", @system_colour
474
+ render
418
475
  10.times do
419
476
  begin
420
477
  res = Net::HTTP.get_response(URI.parse(prg[:link]))
421
478
  rescue SocketError => e
422
479
  print_error_and_delay "Error: Failed to connect to Internet! (#{e.class})"
480
+ render
423
481
  @no_play = true
424
482
  break
425
483
  end
426
484
  case res
427
485
  when Net::HTTPFound
428
486
  iot_puts 'redirecting...', @system_colour
487
+ render
429
488
  @doc = Oga.parse_xml(res.body)
430
489
  redirect = @doc.css("body p a").text
431
490
  break if download_audio(prg, redirect)
432
491
  sleep 2
433
492
  else
434
493
  print_error_and_delay 'Error! Failed to be redirected!'
494
+ render
435
495
  @no_play = true
436
- break
437
496
  end
438
497
  retries += 1
439
498
  end
440
499
  if retries >= 10
441
500
  print_error_and_delay "Max retries downloading #{prg[:title]}"
501
+ render
442
502
  @no_play = true
443
503
  end
444
504
  end
@@ -457,7 +517,9 @@ class InOurTime
457
517
  end
458
518
 
459
519
  def reset
460
- @pid, @playing, @paused = nil, nil, nil
520
+ @pid = nil
521
+ @playing = nil
522
+ @paused = nil
461
523
  window_title
462
524
  redraw
463
525
  end
@@ -471,11 +533,10 @@ class InOurTime
471
533
  end
472
534
 
473
535
  def pause
474
- if control_play?
475
- @paused = @paused ? false : true
476
- write_player " "
477
- redraw
478
- end
536
+ return unless control_play?
537
+ @paused = @paused ? false : true
538
+ write_player " "
539
+ redraw
479
540
  end
480
541
 
481
542
  def control_play?
@@ -492,30 +553,22 @@ class InOurTime
492
553
 
493
554
  def print_playing_maybe
494
555
  if @playing
495
- iot_print("\nPlaying: ", @count_colour) unless @paused
496
- iot_print("\nPaused: ", @count_colour) if @paused
556
+ iot_print("Playing: ", @count_colour) unless @paused
557
+ iot_print("Paused: ", @count_colour) if @paused
497
558
  iot_puts @playing, @selection_colour
498
559
  elsif @started.nil?
499
560
  @started = true
500
- iot_puts "\n? or h for instructions", @text_colour
501
- else
502
- iot_puts "\n"
561
+ iot_print "? or h for instructions", @text_colour
503
562
  end
504
563
  end
505
564
 
506
- def kill_cmd
507
- "killall " +
508
- @config[:mpg_player].to_s
509
- end
510
-
511
565
  def kill_audio
512
- if @playing
513
- if @pid.is_a? Fixnum
514
- Process.kill('QUIT', @pid)
515
- sleep 0.2
516
- reset
517
- end
518
- end
566
+ return unless @playing
567
+ @playing = nil
568
+ return unless @pid.is_a?(Integer)
569
+ Process.kill('QUIT', @pid)
570
+ sleep 0.2
571
+ reset
519
572
  end
520
573
 
521
574
  def idx_format idx
@@ -524,7 +577,7 @@ class InOurTime
524
577
 
525
578
  def show_count_maybe idx
526
579
  if have_locally?(@sorted_titles[idx])
527
- iot_print idx_format(idx), @count_sel_colour if @config[:show_count]
580
+ iot_print idx_format(idx), @count_sel_colour if @config[:show_count]
528
581
  else
529
582
  iot_print idx_format(idx), @count_colour if @config[:show_count]
530
583
  end
@@ -532,8 +585,9 @@ class InOurTime
532
585
  end
533
586
 
534
587
  def draw_page
588
+ clear_content
535
589
  if @line_count <= @sorted_titles.length
536
- @line_count.upto(@line_count + @config[:page_height] - 1) do |idx|
590
+ @line_count.upto(@line_count + @page_height - 1) do |idx|
537
591
  if idx < @sorted_titles.length
538
592
  iot_print "> " if(idx == @selected) unless @config[:colour]
539
593
  show_count_maybe idx
@@ -543,65 +597,79 @@ class InOurTime
543
597
  end
544
598
  else
545
599
  @line_count = 0
546
- 0.upto(@config[:page_height] - 1) do |idx|
600
+ 0.upto(@page_height - 1) do |idx|
547
601
  iot_print "> ", @selection_colour if(idx == @selected)
548
602
  show_count_maybe(idx) unless @sorted_titles[idx].nil?
549
603
  iot_puts @sorted_titles[idx], @text_colour unless @sorted_titles[idx].nil?
550
604
  end
551
605
  end
552
- @line_count += @config[:page_height]
606
+ @line_count += @page_height
553
607
  print_playing_maybe
608
+ render
554
609
  end
555
610
 
556
611
  def display_list action
557
- clear
558
612
  case action
559
613
  when :next_page
560
614
  draw_page
561
615
  when :previous_page
562
616
  if @line_count > 0
563
- @line_count -= (@config[:page_height] * 2)
617
+ @line_count -= (@page_height * 2)
564
618
  else
565
619
  @line_count = @sorted_titles.length
566
620
  @selected = @line_count
567
621
  end
568
622
  draw_page
569
623
  when :same_page
570
- @line_count -= @config[:page_height]
624
+ @line_count -= @page_height
571
625
  draw_page
572
626
  end
573
627
  end
574
628
 
629
+ def help_option?
630
+ ARGV[0] == '-h' || ARGV[0] == '--help' || ARGV[0] == '-?'
631
+ end
632
+
575
633
  def load_help_maybe
576
- if ARGV[0] == '-h' || ARGV[0] == '--help' || ARGV[0] == '-?'
577
- help
578
- quit
579
- end
634
+ return unless help_option?
635
+ help
636
+ quit
637
+ end
638
+
639
+ def help_screen
640
+ [] <<
641
+ " In Our Time Player (#{@version})" <<
642
+ " " <<
643
+ " Play/Stop - X or Enter " <<
644
+ " Previous/Next - Down / Up " <<
645
+ " Next Page - SPACE " <<
646
+ " Sort - S " <<
647
+ " Theme Toggle - T " <<
648
+ " List Top - L " <<
649
+ " Update - U " <<
650
+ " Info - I " <<
651
+ " Help - H " <<
652
+ " Quit - Q " <<
653
+ " " <<
654
+ " mpg123 Controls: " <<
655
+ " Pause/Resume - P " <<
656
+ " Forward Skip - F " <<
657
+ " Reverse Skip - R " <<
658
+ " " <<
659
+ "Config: #{CONFIG} "
660
+ end
661
+
662
+ def print_help
663
+ iot_puts help_screen.map{|x|x.rstrip}.join("\n\r"), @system_colour
580
664
  end
581
665
 
582
666
  def help
583
667
  unless @help
584
- clear
585
- iot_puts " In Our Time Player (#{@version})"
586
- iot_puts " Next - N or Down Key ", @system_colour
587
- iot_puts " Previous - P or Up Key ", @system_colour
588
- iot_puts " Next Page - SPACE ", @system_colour
589
- iot_puts " Play/Stop - X or Enter ", @system_colour
590
- iot_puts " Sort - S ", @system_colour
591
- iot_puts " List Top - L ", @system_colour
592
- iot_puts " Update - U ", @system_colour
593
- iot_puts " Info - I ", @system_colour
594
- iot_puts " Help - H ", @system_colour
595
- iot_puts " Quit - Q ", @system_colour
596
- iot_puts
597
- iot_puts " mpg123 Controls: ", @system_colour
598
- iot_puts " Pause/Resume - P ", @system_colour
599
- iot_puts " Forward Skip - F ", @system_colour
600
- iot_puts " Reverse Skip - R ", @system_colour
601
- iot_puts
602
- iot_puts "Config: #{CONFIG}", @system_colour
668
+ clear_content
669
+ print_help
603
670
  print_playing_maybe
604
671
  @help = true
672
+ render
605
673
  else
606
674
  redraw
607
675
  @help = nil
@@ -609,8 +677,7 @@ class InOurTime
609
677
  end
610
678
 
611
679
  def reformat info
612
- ['With','Guests',
613
- 'Producer','Contributors'].map do | x|
680
+ ['With','Guests','Producer','Contributors'].map do | x|
614
681
  [' ', ':'].map do |y|
615
682
  [x, x.upcase].map do |z|
616
683
  info.gsub!(z + y, "\n" + z + y)
@@ -629,19 +696,25 @@ class InOurTime
629
696
  end
630
697
 
631
698
  def last_line? info, top
632
- info[top..-1].length < @config[:page_width]
699
+ info[top..-1].length < @page_width
633
700
  end
634
701
 
635
702
  def justify info
636
703
  pages = [[],[]]
637
- page, top, bottom = 0, 0, @config[:page_width]
704
+ page = 0
705
+ top = 0
706
+ bottom = @page_width
638
707
  loop do
639
708
  shift = top_space info[top..bottom]
640
- top, bottom = top + shift, bottom + shift
709
+ top = top + shift
710
+ bottom = bottom + shift
641
711
  loop do
642
- if idx = info[top..bottom].index("\n")
712
+ idx = info[top..bottom].index("\n")
713
+ if idx
643
714
  pages[page] << info[top..top + idx]
644
- page,bottom,top = 1,top + idx + @config[:page_width] + 1, top + idx + 1
715
+ page = 1
716
+ bottom = top + idx + @page_width + 1
717
+ top = top + idx + 1
645
718
  else
646
719
  break if bottom_space? info[bottom]
647
720
  bottom -= 1
@@ -652,13 +725,15 @@ class InOurTime
652
725
  break
653
726
  end
654
727
  pages[page] << info[top..bottom]
655
- bottom, top = bottom + @config[:page_width], bottom
728
+ top = bottom
729
+ bottom = bottom + @page_width
656
730
  end
657
731
  pages
658
732
  end
659
733
 
660
734
  def print_subtitle prg
661
735
  clear
736
+ puts_title @system_colour
662
737
  justify(prg[:subtitle].gsub(/\s+/, ' '))[0].map{|x| iot_puts x}
663
738
  print_program_details prg
664
739
  @info = 1
@@ -674,16 +749,15 @@ class InOurTime
674
749
 
675
750
  def print_info prg
676
751
  info = prg[:summary].gsub(/\s+/, ' ')
677
- clear
678
752
  count = 1
679
753
  justify(reformat(info))[0].each do |x|
680
- if (count > (@page_count - 1) * @config[:page_height]) &&
681
- (count <= @page_count * @config[:page_height])
754
+ if (count > (@page_count - 1) * @page_height) &&
755
+ (count <= @page_count * @page_height)
682
756
  iot_puts x
683
757
  end
684
758
  count += 1
685
759
  end
686
- if count <= @page_count * @config[:page_height] + 1
760
+ if count <= @page_count * @page_height + 1
687
761
  @info = justify(reformat(info))[1] == [] ? -1 : 2
688
762
  else
689
763
  @page_count += 1
@@ -698,6 +772,7 @@ class InOurTime
698
772
  end
699
773
 
700
774
  def info
775
+ clear_content
701
776
  case @info
702
777
  when nil
703
778
  prg = select_program @sorted_titles[@selected]
@@ -711,14 +786,16 @@ class InOurTime
711
786
  else
712
787
  redraw
713
788
  @info = nil
789
+ return
714
790
  end
791
+ render
715
792
  end
716
793
 
717
794
  def check_process
718
- if(@playing && @pid.is_a?(Fixnum))
795
+ if(@playing && @pid.is_a?(Integer))
719
796
  begin
720
797
  write_player( "\e")
721
- if @pid.is_a? Fixnum
798
+ if @pid.is_a? Integer
722
799
  Process.kill 0, @pid
723
800
  end
724
801
  rescue Errno::ESRCH
@@ -729,83 +806,86 @@ class InOurTime
729
806
  end
730
807
  end
731
808
 
732
- def run
733
- ip, action = '', :unknown
734
- @tic, @key = Tic.new, KeyboardEvents.new
735
- @tic.run
736
- @key.run
809
+ def page_forward
810
+ @selected = @line_count
811
+ display_list :next_page
812
+ end
737
813
 
738
- redraw
739
- loop do
814
+ def previous
815
+ @selected -= 1 if @selected > 0
816
+ if @selected >= @line_count -
817
+ @page_height
818
+ redraw
819
+ else
820
+ display_list :previous_page
821
+ end
822
+ end
740
823
 
741
- unless action == :unknown
742
- @key.reset
743
- end
824
+ def next
825
+ @selected += 1
826
+ if @selected <= @line_count - 1
827
+ redraw
828
+ else
829
+ display_list :next_page
830
+ end
831
+ end
744
832
 
833
+ def play
834
+ if @playing
835
+ kill_audio
836
+ else
837
+ kill_audio
838
+ title = @sorted_titles[@selected]
839
+ pr = select_program title
840
+ run_program pr
841
+ redraw
842
+ end
843
+ end
844
+
845
+ def update_key
846
+ update
847
+ parse_rss
848
+ sort_titles
849
+ @line_count = 0
850
+ @selected = 0
851
+ display_list :next_page
852
+ end
853
+
854
+ def quit_key
855
+ kill_audio
856
+ quit
857
+ end
858
+
859
+ def do_action ip
860
+ case ip
861
+ when :pause, :forward, :rewind,
862
+ :list_key, :page_forward, :previous,
863
+ :next, :play, :sort_key, :theme_toggle,
864
+ :update_key, :info, :help, :quit_key
865
+ self.send ip
866
+ end
867
+ end
868
+
869
+ def reset_info_maybe ip
870
+ @info = nil unless ip == :info
871
+ @help = nil unless ip == :help
872
+ end
873
+
874
+ def run
875
+ ip = ''
876
+ @tic = Tic.new
877
+ @key = KeyboardEvents.new
878
+ redraw
879
+
880
+ loop do
745
881
  loop do
746
882
  ip = @key.read
747
883
  break unless ip == :no_event
748
884
  check_process if @tic.toc
749
885
  do_events
750
886
  end
751
-
752
- @info = nil unless ip == :info
753
- @help = nil unless ip == :help
754
-
755
- action =
756
- case ip
757
- when :pause, :forward, :rewind
758
- self.send ip
759
- when :list
760
- @line_count = 0
761
- @selected = 0
762
- display_list :next_page
763
- when :page_forward
764
- @selected = @line_count
765
- display_list :next_page
766
- when :previous
767
- @selected -= 1 if @selected > 0
768
- if @selected >= @line_count -
769
- @config[:page_height]
770
- redraw
771
- else
772
- display_list :previous_page
773
- end
774
- when :next
775
- @selected += 1
776
- if @selected <= @line_count - 1
777
- redraw
778
- else
779
- display_list :next_page
780
- end
781
- when :play
782
- if @playing
783
- kill_audio
784
- @playing = nil
785
- else
786
- kill_audio
787
- title = @sorted_titles[@selected]
788
- pr = select_program title
789
- run_program pr
790
- redraw
791
- end
792
- when :sort
793
- sort
794
- when :update
795
- update
796
- parse_rss
797
- sort_titles
798
- @line_count = 0
799
- @selected = 0
800
- display_list :next_page
801
- when :info
802
- info
803
- when :help
804
- help
805
- when :quit
806
- kill_audio
807
- quit
808
- end
887
+ reset_info_maybe ip
888
+ do_action ip
809
889
  do_events
810
890
  end
811
891
  end
@@ -0,0 +1,102 @@
1
+ class KeyboardEvents
2
+ def initialize
3
+ update_wait
4
+ @mode = :normal
5
+ @event = :no_event
6
+ @alive = true
7
+ run
8
+ end
9
+
10
+ def reset
11
+ STDIN.flush
12
+ end
13
+
14
+ def do_events
15
+ sleep 0.001
16
+ end
17
+
18
+ def kill
19
+ @alive = nil
20
+ Thread.kill(@key) if @key
21
+ end
22
+
23
+ def update_wait
24
+ @wait = Time.now + 0.02
25
+ end
26
+
27
+ def reset_event
28
+ @event = :no_event unless @event == :quit_key
29
+ end
30
+
31
+ def read
32
+ update_wait unless @event == :no_event
33
+ ret_val = @event
34
+ reset_event
35
+ ret_val
36
+ end
37
+
38
+ def run
39
+ @key = Thread.new do
40
+ while @event != :quit_key
41
+ str = ''
42
+ loop do
43
+ str = STDIN.getch
44
+ next if Time.now < @wait
45
+ if str == "\e"
46
+ @mode = :escape
47
+ else
48
+ case @mode
49
+ when :escape
50
+ @mode =
51
+ str == "[" ? :escape_2 : :normal
52
+ when :escape_2
53
+ @event = :previous if str == "A"
54
+ @event = :next if str == "B"
55
+ @event = :page_forward if str == "C"
56
+ @event = :previous if str == "D"
57
+ @mode = :normal
58
+ else
59
+ break if @event == :no_event
60
+ end
61
+ end
62
+ do_events
63
+ end
64
+ match_event str
65
+ end
66
+ end
67
+ end
68
+
69
+ def match_event str
70
+ case str
71
+ when "\e"
72
+ @mode = :escape
73
+ when "l",'L'
74
+ @event = :list_key
75
+ when "u",'U'
76
+ @event = :update_key
77
+ when ' '
78
+ @event = :page_forward
79
+ when "q",'Q', "\u0003", "\u0004"
80
+ @event = :quit_key
81
+ when 'p', 'P'
82
+ @event = :pause
83
+ when 'f', 'F'
84
+ @event = :forward
85
+ when 'r', 'R'
86
+ @event = :rewind
87
+ when 's', 'S'
88
+ @event = :sort_key
89
+ when 't', 'T'
90
+ @event = :theme_toggle
91
+ when 'x', 'X', "\r"
92
+ @event = :play
93
+ when 'i', 'I'
94
+ @event = :info
95
+ when '?', 'h', 'H'
96
+ @event = :help
97
+ else
98
+ return @event = :no_event
99
+ end
100
+ end
101
+ end
102
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: in_our_time
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.4
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martyn Jago
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-10-27 00:00:00.000000000 Z
11
+ date: 2016-11-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: oga
@@ -72,6 +72,7 @@ files:
72
72
  - in_our_time.gemspec
73
73
  - lib/in_our_time.rb
74
74
  - lib/iot/iot.rb
75
+ - lib/iot/keyboard_events.rb
75
76
  homepage: https://github.com/mjago/In_Our_Time
76
77
  licenses:
77
78
  - MIT
@@ -92,7 +93,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
92
93
  version: '0'
93
94
  requirements: []
94
95
  rubyforge_project:
95
- rubygems_version: 2.6.7
96
+ rubygems_version: 2.5.1
96
97
  signing_key:
97
98
  specification_version: 4
98
99
  summary: Select, play, and download BBC 'In Our Time' podcasts - all from the command