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 +4 -4
- data/.gitignore +1 -0
- data/VERSION +1 -1
- data/in_our_time.gemspec +1 -0
- data/lib/iot/iot.rb +349 -269
- data/lib/iot/keyboard_events.rb +102 -0
- metadata +4 -3
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: fba0bd53285d9df8789fb1d0464650ed0c769a41
         | 
| 4 | 
            +
              data.tar.gz: e190622c306d519d8d0a568d629c3f06dc1a5a79
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 5293b5c48c8a45a2dc7efc464f0ce3c87fdffddd9546e7c4223d339335ef4cd400f8c989fd5c4d227ebd1afd1559a5e72abeea28dfce4287ce9036e8045e0e9a
         | 
| 7 | 
            +
              data.tar.gz: 86738cce5846617abd0f2aac1d019c88eca1a59143792e59c6c7b5137ebcfeaf690fc151ef2334ec9b3d0ebace094170eb1aa381039cc99c96fca7738ce9a239
         | 
    
        data/.gitignore
    CHANGED
    
    
    
        data/VERSION
    CHANGED
    
    | @@ -1 +1 @@ | |
| 1 | 
            -
            0. | 
| 1 | 
            +
            0.4.0
         | 
    
        data/in_our_time.gemspec
    CHANGED
    
    
    
        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 | 
| 46 | 
            +
                  ret_val = @flag
         | 
| 47 | 
            +
                  @flag = false
         | 
| 130 48 | 
             
                  ret_val
         | 
| 131 49 | 
             
                end
         | 
| 132 50 | 
             
              end
         | 
| 133 51 |  | 
| 134 52 | 
             
              def initialize
         | 
| 135 | 
            -
                @ | 
| 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 | 
            -
                 | 
| 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 | 
            -
                 | 
| 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 | 
            -
                 | 
| 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 | 
            -
                 | 
| 163 | 
            -
                 | 
| 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 | 
            -
                 | 
| 183 | 
            -
             | 
| 184 | 
            -
             | 
| 185 | 
            -
             | 
| 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 | 
            -
                 | 
| 190 | 
            -
                 | 
| 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 | 
| 173 | 
            +
                @config = YAML.load_file(DEFAULT_CONFIG)
         | 
| 205 174 | 
             
                save_config
         | 
| 206 175 | 
             
              end
         | 
| 207 176 |  | 
| 208 | 
            -
              def  | 
| 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 | 
            -
             | 
| 216 | 
            -
             | 
| 217 | 
            -
             | 
| 218 | 
            -
                 | 
| 219 | 
            -
                 | 
| 220 | 
            -
             | 
| 221 | 
            -
                 | 
| 222 | 
            -
                 | 
| 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 | 
| 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, ''). | 
| 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 | 
| 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. | 
| 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 | 
            -
                 | 
| 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 | 
            -
                 | 
| 314 | 
            -
             | 
| 315 | 
            -
             | 
| 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 | 
| 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 % @ | 
| 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  | 
| 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 | 
| 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  | 
| 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 | 
            -
                   | 
| 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 | 
| 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 | 
            -
                 | 
| 475 | 
            -
             | 
| 476 | 
            -
             | 
| 477 | 
            -
             | 
| 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(" | 
| 496 | 
            -
                  iot_print(" | 
| 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 | 
            -
                   | 
| 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 | 
            -
                 | 
| 513 | 
            -
             | 
| 514 | 
            -
             | 
| 515 | 
            -
             | 
| 516 | 
            -
             | 
| 517 | 
            -
             | 
| 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 | 
| 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 + @ | 
| 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(@ | 
| 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 += @ | 
| 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 -= (@ | 
| 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 -= @ | 
| 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 | 
            -
                 | 
| 577 | 
            -
             | 
| 578 | 
            -
             | 
| 579 | 
            -
             | 
| 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 | 
            -
                   | 
| 585 | 
            -
                   | 
| 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 < @ | 
| 699 | 
            +
                info[top..-1].length < @page_width
         | 
| 633 700 | 
             
              end
         | 
| 634 701 |  | 
| 635 702 | 
             
              def justify info
         | 
| 636 703 | 
             
                pages = [[],[]]
         | 
| 637 | 
            -
                page | 
| 704 | 
            +
                page = 0
         | 
| 705 | 
            +
                top = 0
         | 
| 706 | 
            +
                bottom = @page_width
         | 
| 638 707 | 
             
                loop do
         | 
| 639 708 | 
             
                  shift = top_space info[top..bottom]
         | 
| 640 | 
            -
                  top | 
| 709 | 
            +
                  top = top + shift
         | 
| 710 | 
            +
                  bottom = bottom + shift
         | 
| 641 711 | 
             
                  loop do
         | 
| 642 | 
            -
                     | 
| 712 | 
            +
                    idx = info[top..bottom].index("\n")
         | 
| 713 | 
            +
                    if idx
         | 
| 643 714 | 
             
                      pages[page] << info[top..top + idx]
         | 
| 644 | 
            -
                      page | 
| 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 | 
            -
                   | 
| 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) * @ | 
| 681 | 
            -
                     (count <= @page_count * @ | 
| 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 * @ | 
| 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?( | 
| 795 | 
            +
                if(@playing && @pid.is_a?(Integer))
         | 
| 719 796 | 
             
                  begin
         | 
| 720 797 | 
             
                    write_player( "\e")
         | 
| 721 | 
            -
                    if @pid.is_a?  | 
| 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  | 
| 733 | 
            -
                 | 
| 734 | 
            -
                 | 
| 735 | 
            -
             | 
| 736 | 
            -
                @key.run
         | 
| 809 | 
            +
              def page_forward
         | 
| 810 | 
            +
                @selected = @line_count
         | 
| 811 | 
            +
                display_list :next_page
         | 
| 812 | 
            +
              end
         | 
| 737 813 |  | 
| 738 | 
            -
             | 
| 739 | 
            -
                 | 
| 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 | 
            -
             | 
| 742 | 
            -
             | 
| 743 | 
            -
             | 
| 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 | 
            -
                   | 
| 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. | 
| 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- | 
| 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. | 
| 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
         |