ruby-mpd-client 0.2.0 → 1.0.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 +5 -5
- data/.travis.yml +10 -0
- data/README.md +13 -5
- data/lib/mpd/commands.rb +61 -0
- data/lib/mpd/commands/abstract.rb +61 -0
- data/lib/mpd/commands/all_files.rb +17 -0
- data/lib/mpd/commands/change_volume.rb +14 -0
- data/lib/mpd/commands/current_playlist_add.rb +19 -0
- data/lib/mpd/commands/current_playlist_info.rb +18 -0
- data/lib/mpd/commands/current_playlist_remove.rb +20 -0
- data/lib/mpd/commands/current_song.rb +14 -0
- data/lib/mpd/commands/ping.rb +23 -0
- data/lib/mpd/commands/play.rb +23 -0
- data/lib/mpd/commands/set_volume.rb +14 -0
- data/lib/mpd/commands/status.rb +14 -0
- data/lib/mpd/connection.rb +41 -0
- data/lib/mpd/server_response.rb +50 -0
- data/lib/mpd/version.rb +1 -1
- data/lib/ruby-mpd-client.rb +1 -1
- data/ruby-mpd-client.gemspec +1 -0
- metadata +32 -10
- data/lib/mpd/client.rb +0 -51
- data/lib/mpd/client/commands.rb +0 -10
- data/lib/mpd/client/commands/current_playlist.rb +0 -17
- data/lib/mpd/client/commands/playback_control.rb +0 -36
- data/lib/mpd/client/commands/playback_options.rb +0 -36
- data/lib/mpd/client/connection.rb +0 -39
- data/lib/mpd/client/server_response.rb +0 -52
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 | 
            -
             | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 2 | 
            +
            SHA256:
         | 
| 3 | 
            +
              metadata.gz: 8ca78849c735d15541f0f0e04e83ac1af66d71c3c3202739a0718f7cfc7860e4
         | 
| 4 | 
            +
              data.tar.gz: db532da5093220f87880cd0d47137866b089be98ba8d03a7aa89334869b6da9d
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 0d23063c2519c020bcf16009a1f6f1874b2d4f53ad41879fc023b5b460e9a531f13a5a665574399cef5836bd9fadbfd4213d2a64f8cef966fa2b8c2dd79194e4
         | 
| 7 | 
            +
              data.tar.gz: 0423b775979eb61f9eff55fcfd05d29e6375a17df5e1caf2bb6b9828d7b2d3c32e84e10c792ade9ab004f0462a91292d225e0851f9164a417c6f55c1b698504d
         | 
    
        data/.travis.yml
    ADDED
    
    | @@ -0,0 +1,10 @@ | |
| 1 | 
            +
            language: ruby
         | 
| 2 | 
            +
            rvm:
         | 
| 3 | 
            +
            - 2.3.0
         | 
| 4 | 
            +
            script: rake spec
         | 
| 5 | 
            +
            deploy:
         | 
| 6 | 
            +
              provider: rubygems
         | 
| 7 | 
            +
              api_key:
         | 
| 8 | 
            +
                secure: CCtmgUnWoiG4tKRalp9kfEcaeDUfipES0mcWPV4K0D/K651nxZ0kHe+VV+3rpvV1KDs4i5W+TosVvpH5lDL7+oALLFTsYgo3iam+kzMLfoskkZUuizUDxYjXrWI0T+SM0gL3Ax1J9oJ0cd7j1sUGi5TZ/IHXrKknm1yqFIx83mgKCFxYKJUAwQuwpo924ukqyQ0IsJtYX7AJ31hQwFBZSscJbriaxsz3dN+ptmvYVt9/+oIowHrvZCFnlgejel/eZ9iKCMR8buxx1RF3Q3y7LZkpMb20UBfjMwUkz/XBXGFCFVUaCLEcdFnAuoRePJ8a+q3Qkd0wZp+5g2offguVycTWsPTGgSjSAXcPUK0fOnE6bsBZ9XnkAiwkPtxO3MeG7iBcGBX2XY/Tzl+8EW2FgGeIICBh5sg+UqmrGAuqzmtgrJJwOaBeyLEbAKemAdPRfN7M0Hq1DgbOHchttmiCAY1Ja/RBiYwbEkZsPn9VI2tH3CUvdqc0B4jPV05OKU1sv06hHKJTWoCjsmvd52Tr0Kbr5ofBvLMj+uHnyCx78SwfReVCPEb2PzK5GUBG6+Ufu8UOTFdlS8gDmSO09R/qd/kSILvxCLntNVQAn/aUlnZ0aBJURxhoTQkKRSBGcGrOUXhMKnj3jnwZw1othJ5xxiSXy6fM/8JrsxyPH7TalT8=
         | 
| 9 | 
            +
              on:
         | 
| 10 | 
            +
                branch: master
         | 
    
        data/README.md
    CHANGED
    
    | @@ -18,13 +18,21 @@ It does not do much | |
| 18 18 | 
             
            ```ruby
         | 
| 19 19 | 
             
            require 'ruby-mpd-client'
         | 
| 20 20 |  | 
| 21 | 
            -
             | 
| 22 | 
            -
             | 
| 23 | 
            -
             | 
| 24 | 
            -
             | 
| 25 | 
            -
            # | 
| 21 | 
            +
            MPD::Commands::SetVolume.new(host: 'localhost') # :host can be ommited
         | 
| 22 | 
            +
                                    .execute(75)
         | 
| 23 | 
            +
            MPD::Commands::Next.new.execute
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            #
         | 
| 26 | 
            +
            # to use one connection
         | 
| 27 | 
            +
            #
         | 
| 28 | 
            +
            conn = MPD::Connection.new(host: 'localhost', port: 6600)
         | 
| 29 | 
            +
            conn.connect
         | 
| 30 | 
            +
            MPD::Commands::Next.new(connection: conn).execute
         | 
| 31 | 
            +
            MPD::Commands::Pause.new(connection: conn).execute
         | 
| 26 32 | 
             
            ```
         | 
| 27 33 |  | 
| 34 | 
            +
            For available commands see [lib/mpd/commands](lib/mpd/commands).
         | 
| 35 | 
            +
             | 
| 28 36 | 
             
            ## Contributing
         | 
| 29 37 |  | 
| 30 38 | 
             
            Bug reports and pull requests are welcome on GitHub at https://github.com/Nondv/ruby-mpd-client.
         | 
    
        data/lib/mpd/commands.rb
    ADDED
    
    | @@ -0,0 +1,61 @@ | |
| 1 | 
            +
            Dir[File.join(__dir__, 'commands', '*.rb')].each { |f| require f }
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module MPD
         | 
| 4 | 
            +
              #
         | 
| 5 | 
            +
              # Contains classes representing MPD commands
         | 
| 6 | 
            +
              #
         | 
| 7 | 
            +
              module Commands
         | 
| 8 | 
            +
                #
         | 
| 9 | 
            +
                # To decrease code amount
         | 
| 10 | 
            +
                #
         | 
| 11 | 
            +
                def self.define_trivial_command(class_name, command)
         | 
| 12 | 
            +
                  klass = Class.new(::MPD::Commands::Abstract) do
         | 
| 13 | 
            +
                    define_method :execute do
         | 
| 14 | 
            +
                      super(command)
         | 
| 15 | 
            +
                    end
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                  const_set(class_name, klass)
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                #
         | 
| 22 | 
            +
                # To define commands like 'save "whatever this is"'
         | 
| 23 | 
            +
                #
         | 
| 24 | 
            +
                def self.define_text_argument_command(class_name, command)
         | 
| 25 | 
            +
                  klass = Class.new(::MPD::Commands::Abstract) do
         | 
| 26 | 
            +
                    define_method :execute do |arg|
         | 
| 27 | 
            +
                      super("#{command} \"#{arg}\"")
         | 
| 28 | 
            +
                    end
         | 
| 29 | 
            +
                  end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                  const_set(class_name, klass)
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                #
         | 
| 35 | 
            +
                # To define commands like "random <1/0>"
         | 
| 36 | 
            +
                #
         | 
| 37 | 
            +
                def self.define_option_command(class_name, command)
         | 
| 38 | 
            +
                  klass = Class.new(::MPD::Commands::Abstract) do
         | 
| 39 | 
            +
                    define_method :execute do |state|
         | 
| 40 | 
            +
                      super(command + state ? ' 1' : ' 0')
         | 
| 41 | 
            +
                    end
         | 
| 42 | 
            +
                  end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                  const_set(class_name, klass)
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                define_trivial_command(:Pause, 'pause 1')
         | 
| 48 | 
            +
                define_trivial_command(:Stop, 'stop')
         | 
| 49 | 
            +
                define_trivial_command(:Previous, 'previous')
         | 
| 50 | 
            +
                define_trivial_command(:Next, 'next')
         | 
| 51 | 
            +
                define_trivial_command(:CurrentPlaylistClear, 'clear')
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                define_text_argument_command :PlaylistDelete, :rm
         | 
| 54 | 
            +
                define_text_argument_command :PlaylistSave, :save
         | 
| 55 | 
            +
                define_text_argument_command :PlaylistLoad, :load
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                %w[Consume Crossfade Random Repeat Single].each do |class_name|
         | 
| 58 | 
            +
                  define_option_command(class_name, class_name.downcase)
         | 
| 59 | 
            +
                end
         | 
| 60 | 
            +
              end
         | 
| 61 | 
            +
            end
         | 
| @@ -0,0 +1,61 @@ | |
| 1 | 
            +
            require 'mpd/connection'
         | 
| 2 | 
            +
            require 'mpd/server_response'
         | 
| 3 | 
            +
            require 'mpd/playlist'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module MPD
         | 
| 6 | 
            +
              module Commands
         | 
| 7 | 
            +
                #
         | 
| 8 | 
            +
                # Base class for MPD commands.
         | 
| 9 | 
            +
                #
         | 
| 10 | 
            +
                class Abstract
         | 
| 11 | 
            +
                  attr_reader :connection
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  #
         | 
| 14 | 
            +
                  # You can provide you own connection. It should have same
         | 
| 15 | 
            +
                  #
         | 
| 16 | 
            +
                  def initialize(connection: nil, host: 'localhost', port: 6600)
         | 
| 17 | 
            +
                    @connection = connection || Connection.new(host: host, port: port).tap(&:connect).tap(&:gets)
         | 
| 18 | 
            +
                  end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                  #
         | 
| 21 | 
            +
                  # This method should be overriden.
         | 
| 22 | 
            +
                  # Example:
         | 
| 23 | 
            +
                  #
         | 
| 24 | 
            +
                  #     def execute
         | 
| 25 | 
            +
                  #       super('ping')
         | 
| 26 | 
            +
                  #     end
         | 
| 27 | 
            +
                  #
         | 
| 28 | 
            +
                  def execute(command)
         | 
| 29 | 
            +
                    exec_command(command)
         | 
| 30 | 
            +
                  end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                  private
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                  def exec_command(command)
         | 
| 35 | 
            +
                    connection.puts(command)
         | 
| 36 | 
            +
                    response = ServerResponse.from_connection(connection)
         | 
| 37 | 
            +
                    raise(MpdError, response.status) if response.error?
         | 
| 38 | 
            +
                    response
         | 
| 39 | 
            +
                  end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                  def exec_command_list(commands)
         | 
| 42 | 
            +
                    connection.puts('command_list_begin')
         | 
| 43 | 
            +
                    commands.each { |c| connection.puts(c) }
         | 
| 44 | 
            +
                    connection.puts('command_list_end')
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                    response = ServerResponse.from_connection(connection)
         | 
| 47 | 
            +
                    raise(MpdError, response.status) if response.error?
         | 
| 48 | 
            +
                    response
         | 
| 49 | 
            +
                  end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                  def resolve_range(arg)
         | 
| 52 | 
            +
                    if arg.is_a?(Range)
         | 
| 53 | 
            +
                      last = arg.exclude_end? ? arg.end : arg.end + 1
         | 
| 54 | 
            +
                      "#{arg.begin}:#{last}"
         | 
| 55 | 
            +
                    else
         | 
| 56 | 
            +
                      arg
         | 
| 57 | 
            +
                    end
         | 
| 58 | 
            +
                  end
         | 
| 59 | 
            +
                end
         | 
| 60 | 
            +
              end
         | 
| 61 | 
            +
            end
         | 
| @@ -0,0 +1,17 @@ | |
| 1 | 
            +
            require 'mpd/commands/abstract'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module MPD
         | 
| 4 | 
            +
              module Commands
         | 
| 5 | 
            +
                #
         | 
| 6 | 
            +
                # Uses "listall" command to get
         | 
| 7 | 
            +
                # all files (directories are filtered out) from db.
         | 
| 8 | 
            +
                #
         | 
| 9 | 
            +
                class AllFiles < Abstract
         | 
| 10 | 
            +
                  def execute
         | 
| 11 | 
            +
                    super('listall').key_value_pairs
         | 
| 12 | 
            +
                                    .select { |e| e[0] == 'file' }
         | 
| 13 | 
            +
                                    .map(&:last)
         | 
| 14 | 
            +
                  end
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
            end
         | 
| @@ -0,0 +1,19 @@ | |
| 1 | 
            +
            require 'mpd/commands/abstract'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module MPD
         | 
| 4 | 
            +
              module Commands
         | 
| 5 | 
            +
                #
         | 
| 6 | 
            +
                # Adds song(s) to current playlist
         | 
| 7 | 
            +
                # `songs` is an array of URIs.
         | 
| 8 | 
            +
                #
         | 
| 9 | 
            +
                class CurrentPlaylistAdd < Abstract
         | 
| 10 | 
            +
                  #
         | 
| 11 | 
            +
                  # `songs` is position (as int) or range
         | 
| 12 | 
            +
                  #
         | 
| 13 | 
            +
                  def execute(songs)
         | 
| 14 | 
            +
                    return exec_command("add \"#{songs}\"") unless songs.is_a?(Array)
         | 
| 15 | 
            +
                    exec_command_list(songs.map { |s| "add \"#{s}\"" })
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
            end
         | 
| @@ -0,0 +1,18 @@ | |
| 1 | 
            +
            require 'mpd/commands/abstract'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module MPD
         | 
| 4 | 
            +
              module Commands
         | 
| 5 | 
            +
                #
         | 
| 6 | 
            +
                # Info about songs in current playlist
         | 
| 7 | 
            +
                #
         | 
| 8 | 
            +
                class CurrentPlaylistInfo < Abstract
         | 
| 9 | 
            +
                  # `songs` can be range
         | 
| 10 | 
            +
                  # or integer (to show info about one song)
         | 
| 11 | 
            +
                  # or completely ommited (to show info about all songs)
         | 
| 12 | 
            +
                  def execute(songs = nil)
         | 
| 13 | 
            +
                    response = super("playlistinfo #{resolve_range(songs)}")
         | 
| 14 | 
            +
                    Playlist.from_response(response)
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
            end
         | 
| @@ -0,0 +1,20 @@ | |
| 1 | 
            +
            require 'mpd/commands/abstract'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module MPD
         | 
| 4 | 
            +
              module Commands
         | 
| 5 | 
            +
                #
         | 
| 6 | 
            +
                # Removes songs from current playlist
         | 
| 7 | 
            +
                # by id or position/range
         | 
| 8 | 
            +
                #
         | 
| 9 | 
            +
                class CurrentPlaylistRemove < Abstract
         | 
| 10 | 
            +
                  #
         | 
| 11 | 
            +
                  # `position` is int or range
         | 
| 12 | 
            +
                  # `id` is int song id
         | 
| 13 | 
            +
                  #
         | 
| 14 | 
            +
                  def execute(position: nil, id: nil)
         | 
| 15 | 
            +
                    raise(ArgumentError) if position && id || !position && !id
         | 
| 16 | 
            +
                    exec_command(id ? "deleteid #{id}" : "delete #{resolve_range(position)}")
         | 
| 17 | 
            +
                  end
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
            end
         | 
| @@ -0,0 +1,23 @@ | |
| 1 | 
            +
            require 'mpd/commands/abstract'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module MPD
         | 
| 4 | 
            +
              module Commands
         | 
| 5 | 
            +
                #
         | 
| 6 | 
            +
                # Tries to execute "ping" command.
         | 
| 7 | 
            +
                # Returns `true` if succedeed,
         | 
| 8 | 
            +
                # raises error if `MpdError` occurred,
         | 
| 9 | 
            +
                # `false` otherwise
         | 
| 10 | 
            +
                #
         | 
| 11 | 
            +
                class Ping < Abstract
         | 
| 12 | 
            +
                  # rubocop:disable Lint/RescueWithoutErrorClass
         | 
| 13 | 
            +
                  def execute
         | 
| 14 | 
            +
                    super('ping')
         | 
| 15 | 
            +
                    true
         | 
| 16 | 
            +
                  rescue => e
         | 
| 17 | 
            +
                    raise e if e.is_a?(MpdError)
         | 
| 18 | 
            +
                    false
         | 
| 19 | 
            +
                  end
         | 
| 20 | 
            +
                  # rubocop:enable Lint/RescueWithoutErrorClass
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
            end
         | 
| @@ -0,0 +1,23 @@ | |
| 1 | 
            +
            require 'mpd/commands/abstract'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module MPD
         | 
| 4 | 
            +
              module Commands
         | 
| 5 | 
            +
                #
         | 
| 6 | 
            +
                # Play specific song (by id or cur. playlist position).
         | 
| 7 | 
            +
                #
         | 
| 8 | 
            +
                #
         | 
| 9 | 
            +
                class Play < Abstract
         | 
| 10 | 
            +
                  def execute(position: nil, id: nil)
         | 
| 11 | 
            +
                    raise(ArgumentError, 'too many arguments') if position && id
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                    if position
         | 
| 14 | 
            +
                      super("play #{position}")
         | 
| 15 | 
            +
                    elsif id
         | 
| 16 | 
            +
                      super("playid #{id}")
         | 
| 17 | 
            +
                    else
         | 
| 18 | 
            +
                      super('play')
         | 
| 19 | 
            +
                    end
         | 
| 20 | 
            +
                  end
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
            end
         | 
| @@ -0,0 +1,41 @@ | |
| 1 | 
            +
            require 'socket'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module MPD
         | 
| 4 | 
            +
              #
         | 
| 5 | 
            +
              # Simple wrapper over Socket
         | 
| 6 | 
            +
              #
         | 
| 7 | 
            +
              class Connection
         | 
| 8 | 
            +
                def initialize(host:, port:)
         | 
| 9 | 
            +
                  @host = host
         | 
| 10 | 
            +
                  @port = port
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                def connect
         | 
| 14 | 
            +
                  disconnect if socket
         | 
| 15 | 
            +
                  @socket = TCPSocket.open(host, port)
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                def disconnect
         | 
| 19 | 
            +
                  socket && socket.close
         | 
| 20 | 
            +
                  @socket = nil
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                def puts(text)
         | 
| 24 | 
            +
                  raise ConnectionError unless socket
         | 
| 25 | 
            +
                  socket.puts(text)
         | 
| 26 | 
            +
                rescue Errno::ECONNRESET
         | 
| 27 | 
            +
                  raise ConnectionError
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                def gets
         | 
| 31 | 
            +
                  raise ConnectionError unless socket
         | 
| 32 | 
            +
                  socket.gets || raise(ConnectionError)
         | 
| 33 | 
            +
                rescue Errno::ECONNRESET
         | 
| 34 | 
            +
                  raise ConnectionError
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                private
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                attr_reader :socket, :host, :port
         | 
| 40 | 
            +
              end
         | 
| 41 | 
            +
            end
         | 
| @@ -0,0 +1,50 @@ | |
| 1 | 
            +
            module MPD
         | 
| 2 | 
            +
              #
         | 
| 3 | 
            +
              # Just a frozen string with some useful methods
         | 
| 4 | 
            +
              #
         | 
| 5 | 
            +
              class ServerResponse < String
         | 
| 6 | 
            +
                def self.from_connection(conn)
         | 
| 7 | 
            +
                  line = ''
         | 
| 8 | 
            +
                  buffer = ''
         | 
| 9 | 
            +
                  while line != "OK\n" && !line.start_with?('ACK')
         | 
| 10 | 
            +
                    line = conn.gets
         | 
| 11 | 
            +
                    raise(ConnectionError) if line.nil?
         | 
| 12 | 
            +
                    buffer << line
         | 
| 13 | 
            +
                  end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                  new(buffer.force_encoding('UTF-8'))
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                def initialize(response_text)
         | 
| 19 | 
            +
                  super
         | 
| 20 | 
            +
                  freeze
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                def to_h
         | 
| 24 | 
            +
                  key_value_pairs.to_h
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                def key_value_pairs
         | 
| 28 | 
            +
                  content.split("\n").map do |line|
         | 
| 29 | 
            +
                    index = line.index(':')
         | 
| 30 | 
            +
                    raise "can't create key-value pair" unless index
         | 
| 31 | 
            +
                    key = line[0...index]
         | 
| 32 | 
            +
                    value = line[(index + 1)..-1].strip
         | 
| 33 | 
            +
                    [key, value]
         | 
| 34 | 
            +
                  end
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                # text without status
         | 
| 38 | 
            +
                def content
         | 
| 39 | 
            +
                  lines[0..-2].join
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                def status
         | 
| 43 | 
            +
                  lines.last.chomp
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                def error?
         | 
| 47 | 
            +
                  status.start_with?('ACK')
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
              end
         | 
| 50 | 
            +
            end
         | 
    
        data/lib/mpd/version.rb
    CHANGED
    
    
    
        data/lib/ruby-mpd-client.rb
    CHANGED
    
    
    
        data/ruby-mpd-client.gemspec
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: ruby-mpd-client
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 1.0.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Dmitriy Non
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: exe
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2017- | 
| 11 | 
            +
            date: 2017-12-16 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: bundler
         | 
| @@ -38,6 +38,20 @@ dependencies: | |
| 38 38 | 
             
                - - "~>"
         | 
| 39 39 | 
             
                  - !ruby/object:Gem::Version
         | 
| 40 40 | 
             
                    version: '10.0'
         | 
| 41 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 42 | 
            +
              name: rspec-its
         | 
| 43 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 44 | 
            +
                requirements:
         | 
| 45 | 
            +
                - - ">="
         | 
| 46 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 47 | 
            +
                    version: '0'
         | 
| 48 | 
            +
              type: :development
         | 
| 49 | 
            +
              prerelease: false
         | 
| 50 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 51 | 
            +
                requirements:
         | 
| 52 | 
            +
                - - ">="
         | 
| 53 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 54 | 
            +
                    version: '0'
         | 
| 41 55 | 
             
            description: 
         | 
| 42 56 | 
             
            email:
         | 
| 43 57 | 
             
            - non.dmitriy@gmail.com
         | 
| @@ -46,21 +60,29 @@ extensions: [] | |
| 46 60 | 
             
            extra_rdoc_files: []
         | 
| 47 61 | 
             
            files:
         | 
| 48 62 | 
             
            - ".gitignore"
         | 
| 63 | 
            +
            - ".travis.yml"
         | 
| 49 64 | 
             
            - Gemfile
         | 
| 50 65 | 
             
            - LICENSE.txt
         | 
| 51 66 | 
             
            - README.md
         | 
| 52 67 | 
             
            - Rakefile
         | 
| 53 68 | 
             
            - bin/console
         | 
| 54 69 | 
             
            - bin/setup
         | 
| 55 | 
            -
            - lib/mpd/ | 
| 56 | 
            -
            - lib/mpd/ | 
| 57 | 
            -
            - lib/mpd/ | 
| 58 | 
            -
            - lib/mpd/ | 
| 59 | 
            -
            - lib/mpd/ | 
| 60 | 
            -
            - lib/mpd/ | 
| 61 | 
            -
            - lib/mpd/ | 
| 70 | 
            +
            - lib/mpd/commands.rb
         | 
| 71 | 
            +
            - lib/mpd/commands/abstract.rb
         | 
| 72 | 
            +
            - lib/mpd/commands/all_files.rb
         | 
| 73 | 
            +
            - lib/mpd/commands/change_volume.rb
         | 
| 74 | 
            +
            - lib/mpd/commands/current_playlist_add.rb
         | 
| 75 | 
            +
            - lib/mpd/commands/current_playlist_info.rb
         | 
| 76 | 
            +
            - lib/mpd/commands/current_playlist_remove.rb
         | 
| 77 | 
            +
            - lib/mpd/commands/current_song.rb
         | 
| 78 | 
            +
            - lib/mpd/commands/ping.rb
         | 
| 79 | 
            +
            - lib/mpd/commands/play.rb
         | 
| 80 | 
            +
            - lib/mpd/commands/set_volume.rb
         | 
| 81 | 
            +
            - lib/mpd/commands/status.rb
         | 
| 82 | 
            +
            - lib/mpd/connection.rb
         | 
| 62 83 | 
             
            - lib/mpd/errors.rb
         | 
| 63 84 | 
             
            - lib/mpd/playlist.rb
         | 
| 85 | 
            +
            - lib/mpd/server_response.rb
         | 
| 64 86 | 
             
            - lib/mpd/song.rb
         | 
| 65 87 | 
             
            - lib/mpd/version.rb
         | 
| 66 88 | 
             
            - lib/ruby-mpd-client.rb
         | 
| @@ -85,7 +107,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 85 107 | 
             
                  version: '0'
         | 
| 86 108 | 
             
            requirements: []
         | 
| 87 109 | 
             
            rubyforge_project: 
         | 
| 88 | 
            -
            rubygems_version: 2. | 
| 110 | 
            +
            rubygems_version: 2.7.3
         | 
| 89 111 | 
             
            signing_key: 
         | 
| 90 112 | 
             
            specification_version: 4
         | 
| 91 113 | 
             
            summary: yet another MPD client on Ruby
         | 
    
        data/lib/mpd/client.rb
    DELETED
    
    | @@ -1,51 +0,0 @@ | |
| 1 | 
            -
            require 'mpd/client/connection'
         | 
| 2 | 
            -
            require 'mpd/client/server_response'
         | 
| 3 | 
            -
            require 'mpd/client/commands'
         | 
| 4 | 
            -
             | 
| 5 | 
            -
            module MPD
         | 
| 6 | 
            -
              class Client
         | 
| 7 | 
            -
                def self.connect(host: 'localhost', port: 6600)
         | 
| 8 | 
            -
                  new(host: host, port: port).tap(&:connect)
         | 
| 9 | 
            -
                end
         | 
| 10 | 
            -
             | 
| 11 | 
            -
                def initialize(host: 'localhost', port: 6600)
         | 
| 12 | 
            -
                  @connection = Connection.new(host: host, port: port)
         | 
| 13 | 
            -
                end
         | 
| 14 | 
            -
             | 
| 15 | 
            -
                def current_song
         | 
| 16 | 
            -
                  execute('currentsong').to_h
         | 
| 17 | 
            -
                end
         | 
| 18 | 
            -
             | 
| 19 | 
            -
                def status
         | 
| 20 | 
            -
                  response = execute('status')
         | 
| 21 | 
            -
                  response.to_h
         | 
| 22 | 
            -
                end
         | 
| 23 | 
            -
             | 
| 24 | 
            -
                def execute(command)
         | 
| 25 | 
            -
                  connection.puts(command)
         | 
| 26 | 
            -
                  response = ServerResponse.from_connection(connection)
         | 
| 27 | 
            -
                  raise(MpdError, response.status) if response.error?
         | 
| 28 | 
            -
                  response
         | 
| 29 | 
            -
                end
         | 
| 30 | 
            -
             | 
| 31 | 
            -
                def connected?
         | 
| 32 | 
            -
                  execute('ping')
         | 
| 33 | 
            -
                rescue => e
         | 
| 34 | 
            -
                  raise e if e.is_a?(MpdError)
         | 
| 35 | 
            -
                  false
         | 
| 36 | 
            -
                end
         | 
| 37 | 
            -
             | 
| 38 | 
            -
                def connect
         | 
| 39 | 
            -
                  connection.connect
         | 
| 40 | 
            -
                  raise(ConnectionError) unless connection.gets =~ /^OK/
         | 
| 41 | 
            -
                end
         | 
| 42 | 
            -
             | 
| 43 | 
            -
                def disconnect
         | 
| 44 | 
            -
                  connection.disconnect
         | 
| 45 | 
            -
                end
         | 
| 46 | 
            -
             | 
| 47 | 
            -
                private
         | 
| 48 | 
            -
             | 
| 49 | 
            -
                attr_reader :connection
         | 
| 50 | 
            -
              end
         | 
| 51 | 
            -
            end
         | 
    
        data/lib/mpd/client/commands.rb
    DELETED
    
    
| @@ -1,17 +0,0 @@ | |
| 1 | 
            -
            require 'mpd/playlist'
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            module MPD
         | 
| 4 | 
            -
              class Client
         | 
| 5 | 
            -
                module Commands
         | 
| 6 | 
            -
                  # https://www.musicpd.org/doc/protocol/queue.html
         | 
| 7 | 
            -
                  module CurrentPlaylist
         | 
| 8 | 
            -
                    # songs - integer or range
         | 
| 9 | 
            -
                    def playlist_info(songs = nil)
         | 
| 10 | 
            -
                      argument = songs.is_a?(Range) ? "#{songs.begin}:#{songs.end}" : songs
         | 
| 11 | 
            -
                      response = execute "playlistinfo #{argument}"
         | 
| 12 | 
            -
                      Playlist.from_response(response)
         | 
| 13 | 
            -
                    end
         | 
| 14 | 
            -
                  end
         | 
| 15 | 
            -
                end
         | 
| 16 | 
            -
              end
         | 
| 17 | 
            -
            end
         | 
| @@ -1,36 +0,0 @@ | |
| 1 | 
            -
            module MPD
         | 
| 2 | 
            -
              class Client
         | 
| 3 | 
            -
                module Commands
         | 
| 4 | 
            -
                  # https://www.musicpd.org/doc/protocol/playback_commands.html
         | 
| 5 | 
            -
                  module PlaybackControl
         | 
| 6 | 
            -
                    def play(position: nil, id: nil)
         | 
| 7 | 
            -
                      raise(ArgumentError, 'too many arguments') if position && id
         | 
| 8 | 
            -
             | 
| 9 | 
            -
                      if position
         | 
| 10 | 
            -
                        execute "play #{position}"
         | 
| 11 | 
            -
                      elsif id
         | 
| 12 | 
            -
                        execute "playid #{id}"
         | 
| 13 | 
            -
                      else
         | 
| 14 | 
            -
                        execute 'pause 0'
         | 
| 15 | 
            -
                      end
         | 
| 16 | 
            -
                    end
         | 
| 17 | 
            -
             | 
| 18 | 
            -
                    def pause
         | 
| 19 | 
            -
                      execute 'pause 1'
         | 
| 20 | 
            -
                    end
         | 
| 21 | 
            -
             | 
| 22 | 
            -
                    def stop
         | 
| 23 | 
            -
                      execute 'stop'
         | 
| 24 | 
            -
                    end
         | 
| 25 | 
            -
             | 
| 26 | 
            -
                    def previous
         | 
| 27 | 
            -
                      execute 'previous'
         | 
| 28 | 
            -
                    end
         | 
| 29 | 
            -
             | 
| 30 | 
            -
                    def next
         | 
| 31 | 
            -
                      execute 'next'
         | 
| 32 | 
            -
                    end
         | 
| 33 | 
            -
                  end
         | 
| 34 | 
            -
                end
         | 
| 35 | 
            -
              end
         | 
| 36 | 
            -
            end
         | 
| @@ -1,36 +0,0 @@ | |
| 1 | 
            -
            module MPD
         | 
| 2 | 
            -
              class Client
         | 
| 3 | 
            -
                module Commands
         | 
| 4 | 
            -
                  # https://www.musicpd.org/doc/protocol/playback_option_commands.html
         | 
| 5 | 
            -
                  module PlaybackOptions
         | 
| 6 | 
            -
                    def consume(state)
         | 
| 7 | 
            -
                      execute "consume #{state ? 1 : 0}"
         | 
| 8 | 
            -
                    end
         | 
| 9 | 
            -
             | 
| 10 | 
            -
                    def crossfade(state)
         | 
| 11 | 
            -
                      execute "crossfade #{state ? 1 : 0}"
         | 
| 12 | 
            -
                    end
         | 
| 13 | 
            -
             | 
| 14 | 
            -
                    def random(state)
         | 
| 15 | 
            -
                      execute "random #{state ? 1 : 0}"
         | 
| 16 | 
            -
                    end
         | 
| 17 | 
            -
             | 
| 18 | 
            -
                    def repeat(state)
         | 
| 19 | 
            -
                      execute "repeat #{state ? 1 : 0}"
         | 
| 20 | 
            -
                    end
         | 
| 21 | 
            -
             | 
| 22 | 
            -
                    def single(state)
         | 
| 23 | 
            -
                      execute "single #{state ? 1 : 0}"
         | 
| 24 | 
            -
                    end
         | 
| 25 | 
            -
             | 
| 26 | 
            -
                    def volume(val)
         | 
| 27 | 
            -
                      execute "setvol #{val}"
         | 
| 28 | 
            -
                    end
         | 
| 29 | 
            -
             | 
| 30 | 
            -
                    def change_volume_by(val)
         | 
| 31 | 
            -
                      execute("volume #{val}")
         | 
| 32 | 
            -
                    end
         | 
| 33 | 
            -
                  end
         | 
| 34 | 
            -
                end
         | 
| 35 | 
            -
              end
         | 
| 36 | 
            -
            end
         | 
| @@ -1,39 +0,0 @@ | |
| 1 | 
            -
            require 'socket'
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            module MPD
         | 
| 4 | 
            -
              class Client
         | 
| 5 | 
            -
                #
         | 
| 6 | 
            -
                # It's `Client`'s internal class. Don't use it outside `Client`
         | 
| 7 | 
            -
                #
         | 
| 8 | 
            -
                class Connection
         | 
| 9 | 
            -
                  def initialize(host:, port:)
         | 
| 10 | 
            -
                    @host = host
         | 
| 11 | 
            -
                    @port = port
         | 
| 12 | 
            -
                  end
         | 
| 13 | 
            -
             | 
| 14 | 
            -
                  def connect
         | 
| 15 | 
            -
                    disconnect if socket
         | 
| 16 | 
            -
                    @socket = TCPSocket.open(host, port)
         | 
| 17 | 
            -
                  end
         | 
| 18 | 
            -
             | 
| 19 | 
            -
                  def disconnect
         | 
| 20 | 
            -
                    socket && socket.close
         | 
| 21 | 
            -
                    @socket = nil
         | 
| 22 | 
            -
                  end
         | 
| 23 | 
            -
             | 
| 24 | 
            -
                  def puts(text)
         | 
| 25 | 
            -
                    raise ConnectionError unless socket
         | 
| 26 | 
            -
                    socket.puts(text)
         | 
| 27 | 
            -
                  end
         | 
| 28 | 
            -
             | 
| 29 | 
            -
                  def gets
         | 
| 30 | 
            -
                    raise ConnectionError unless socket
         | 
| 31 | 
            -
                    socket.gets
         | 
| 32 | 
            -
                  end
         | 
| 33 | 
            -
             | 
| 34 | 
            -
                  private
         | 
| 35 | 
            -
             | 
| 36 | 
            -
                  attr_reader :socket, :host, :port
         | 
| 37 | 
            -
                end
         | 
| 38 | 
            -
              end
         | 
| 39 | 
            -
            end
         | 
| @@ -1,52 +0,0 @@ | |
| 1 | 
            -
            module MPD
         | 
| 2 | 
            -
              class Client
         | 
| 3 | 
            -
                #
         | 
| 4 | 
            -
                # Just a frozen string with some useful methods
         | 
| 5 | 
            -
                #
         | 
| 6 | 
            -
                class ServerResponse < String
         | 
| 7 | 
            -
                  def self.from_connection(conn)
         | 
| 8 | 
            -
                    line = ''
         | 
| 9 | 
            -
                    buffer = ''
         | 
| 10 | 
            -
                    while line != "OK\n" && !line.start_with?('ACK')
         | 
| 11 | 
            -
                      line = conn.gets
         | 
| 12 | 
            -
                      raise(ConnectionError) if line.nil?
         | 
| 13 | 
            -
                      buffer << line
         | 
| 14 | 
            -
                    end
         | 
| 15 | 
            -
             | 
| 16 | 
            -
                    new(buffer.force_encoding('UTF-8'))
         | 
| 17 | 
            -
                  end
         | 
| 18 | 
            -
             | 
| 19 | 
            -
                  def initialize(response_text)
         | 
| 20 | 
            -
                    super
         | 
| 21 | 
            -
                    freeze
         | 
| 22 | 
            -
                  end
         | 
| 23 | 
            -
             | 
| 24 | 
            -
                  def to_h
         | 
| 25 | 
            -
                    key_value_pairs.to_h
         | 
| 26 | 
            -
                  end
         | 
| 27 | 
            -
             | 
| 28 | 
            -
                  def key_value_pairs
         | 
| 29 | 
            -
                    content.split("\n").map do |line|
         | 
| 30 | 
            -
                      index = line.index(':')
         | 
| 31 | 
            -
                      raise "can't create key-value pair" unless index
         | 
| 32 | 
            -
                      key = line[0...index]
         | 
| 33 | 
            -
                      value = line[(index + 1)..-1].strip
         | 
| 34 | 
            -
                      [key, value]
         | 
| 35 | 
            -
                    end
         | 
| 36 | 
            -
                  end
         | 
| 37 | 
            -
             | 
| 38 | 
            -
                  # text without status
         | 
| 39 | 
            -
                  def content
         | 
| 40 | 
            -
                    lines[0..-2].join
         | 
| 41 | 
            -
                  end
         | 
| 42 | 
            -
             | 
| 43 | 
            -
                  def status
         | 
| 44 | 
            -
                    lines.last.chomp
         | 
| 45 | 
            -
                  end
         | 
| 46 | 
            -
             | 
| 47 | 
            -
                  def error?
         | 
| 48 | 
            -
                    status.start_with?('ACK')
         | 
| 49 | 
            -
                  end
         | 
| 50 | 
            -
                end
         | 
| 51 | 
            -
              end
         | 
| 52 | 
            -
            end
         |