Giter VIP home page Giter VIP logo

ruby-mpd's Issues

callback stops firing after a few hours

not sure if this is ruby-mpd related, but i didnt find a clue yet, maybe you can enlighten me

basically i have this code for handling the connection

def self.connect_mpd
    @mpd = MPD.new 'localhost', 6600, {callbacks: true} if @mpd == nil
    unless @mpd.connected?
      Rails.logger.info "Connecting to MPD . . ."
      @mpd.connect
      sleep 0.3
      @mpd.on :song do |song|
        Rails.logger.info "!!!!!!!!!!!!!! #{Time.now.to_s} MPD_SONG change: #{song.title} - #{song.artist} !!!"
      end
    end

  end

this block gets fired about every minute(or even more) and works fine basically

After a few hours(about 6-8) the callback just stops firing, but the connection to mpd is still there, application continuing to work normally. No clues about dropped connection in mpd.log

connection_timeout is set to 3600 in mpd.conf

using ruby-mpd 0.31, MPD 0.18, local only

any tips what could be wrong?

Insert at position

mpc has a feature to insert a song at a specific position, is this available here as well?

Error adding song with backslash in name

Given the (ugly) situation of a file with a backslash in the name, MPD requires the backslash to be escaped. Right now only double-quotes are backslash-escaped inside the double quoted param.

Song callback event doesn't happen correctly when using radio streams.

When using a song callback as such:

@mpd.on :song do |current|
  puts current.inspect
end

it only works when a new file starts to play, which is a problem with radio streams, for two reasons.

  • It takes a second or two to get the metadata from the stream, and so when you first add the stream the callback happens, but it generates something like this:
#<MPD::Song:0x00000002a30c58 @data={:pos=>0, :id=>703}, @time=nil, @file="http://streamer.strobe.fm/", @title=nil, @artist=nil, @album=nil, @albumartist=nil>

But, it would generate something like this if the callback detected the metadata changing:

#<MPD::Song:0x000000019a9628 @data={:name=>"Strobe.FM", :pos=>0, :id=>703}, @time=nil, @file="http://streamer.strobe.fm/", @title="Goo Goo Dolls - Caught In The Storm", @artist=nil, @album=nil, @albumartist=nil>
  • Whenever the song changes in the stream, it doesn't go through the code again, and so the metadata that was generated when the stream was first added stays that way until it's changed to a different file.

The only thing I can think of is that the callback checks if the id changed, (notice the id is 703 in both of those arrays, because it's still the same stream) but it doesn't change when using radio streams. I guess the best way to check this would be to check if anything in the array changed.

Obviously my diagnosis could be entirely wrong, I'm not that good with ruby, but that's my theory.

Detect invalid songs

  1. Create a playlist and add a song to it.
  2. Remove that song from the MPD library.
  3. Load the playlist.

The playlist now has a song with a file but no other data. How can I detect if this is a valid song with no metadata, or an invalid song?

I'm currently using the heuristic of checking to see if song.time.nil?. It would be nice to have something like MPD::Song#valid? to see if the song instance is grounded in reality and able to be used.

Limit search results

I have a DB that's currently at 17k songs (and growing). Some search terms can produce a lot of results, like:

@mpd.where file:'.'
@mpd.where any:'e'

Calls like this take 1.3 seconds on the server before they return. In my interface I then go on to truncate the results to the first 500. I'd like to be able to:

@mpd.where {file:'.'}, {limit:500}

and have the results limited for me.

I realize that this requires MPD support. I've posted a feature request on the MPD forum.

(FWIW, I also tried modifying build_songs_list in parser.rb to accept an optional limit, to reduce the number of songs created in the map. Reducing the map set from 16883 songs to 500 songs only reduced the time from 1.27s to 1.23s, a negligible savings.)

song_with_id( nil ) causes error

A silly edge case, but:

begin; @mpd.song_with_id(1); rescue MPD::Error=>e; puts e; end
#=> [playlistid] No such song

begin; @mpd.song_with_id(-1); rescue MPD::Error=>e; puts e; end
#=> [playlistid] Number too large: -1

begin; @mpd.song_with_id('cat'); rescue MPD::Error=>e; puts e; end
#=> [playlistid] Integer expected: cat

begin; @mpd.song_with_id(nil); rescue MPD::Error=>e; puts e; end
NoMethodError: undefined method `delete' for true:TrueClass
        from /var/lib/gems/2.1.0/gems/ruby-mpd-0.3.3/lib/ruby-mpd/song.rb:13:in `initialize'
        from /var/lib/gems/2.1.0/gems/ruby-mpd-0.3.3/lib/ruby-mpd/plugins/queue.rb:81:in `new'
        from /var/lib/gems/2.1.0/gems/ruby-mpd-0.3.3/lib/ruby-mpd/plugins/queue.rb:81:in `song_with_id'
        ...

No event generated when 'updating_db' disappears from 'status'

Ideally, if I

@mpd.on :updating_db do |job_id|
  puts "Updating DB #{job_id.inspect}"
end
@mpd.update

I should get something like

Updating DB 1
Updating DB nil

so that I can tell when the update has ended, but that doesn't happen at all. Instead the callback is only executed when updating_db appears.

Here's the relevant status change:

{:volume=>96, :repeat=>false, :random=>false, :single=>false, :consume=>false, :playlist=>5002, :playlistlength=>4999, :mixrampdb=>0.0, :state=>:play, :song=>0, :songid=>5000, :time=>[5, 244], :elapsed=>4.574, :bitrate=>1202, :audio=>[44100, 16, 2], :updating_db=>1, :nextsong=>1, :nextsongid=>5001}
{:volume=>96, :repeat=>false, :random=>false, :single=>false, :consume=>false, :playlist=>5002, :playlistlength=>4999, :mixrampdb=>0.0, :state=>:play, :song=>0, :songid=>5000, :time=>[6, 244], :elapsed=>5.619, :bitrate=>1224, :audio=>[44100, 16, 2], :nextsong=>1, :nextsongid=>5001}

As you can see, updating_db simply disappears when the update has completed, which is fine, but I should also get an event.

A bug in SoundCloud playing?

mpd 0.17.0 added some new-ish support for SoundCloud URLs.

In a Ruby script, I can execute

`mpc load soundcloud://track/121108619`

To queue a new URL. With this library, the following does not work:

mpd.load "soundcloud://track/121108619"

The error is:

MPD::ConnectionError (Broken pipe (got disconnected)):

Note that this should be load, not add, because MPD considers these to be playlists.

Adding songs to the queue is slow

On my live music server:

@mpd.add( song )         # takes about 40ms
`mpc add "#{song.file}"` # takes about  5ms

This may seem trivial, but when dynamically generating the queue with 100 songs this is the difference between waiting 4 seconds versus half a second.

I wonder if this is the @mutex.synchronize slowing me down; I'll be looking at ways to speed up the batch adding of many songs.

Error in make_chunks in parser.rb

I tried using your gem today, and I get the following error when I try to run any commands. Seems that the regex in the make_chunks command returns Nil, and that's causing an error in the match command that exits the entire program.

/home/pi/.rvm/gems/ruby-2.2.1/gems/ruby-mpd-0.3.3/lib/ruby-mpd/parser.rb:129:in `make_chunks': undefined method `[]' for nil:NilClass (NoMethodError)
    from /home/pi/.rvm/gems/ruby-2.2.1/gems/ruby-mpd-0.3.3/lib/ruby-mpd/parser.rb:155:in `build_response'
    from /home/pi/.rvm/gems/ruby-2.2.1/gems/ruby-mpd-0.3.3/lib/ruby-mpd/parser.rb:147:in `parse_response'
    from /home/pi/.rvm/gems/ruby-2.2.1/gems/ruby-mpd-0.3.3/lib/ruby-mpd.rb:195:in `block in send_command'
    from /home/pi/.rvm/gems/ruby-2.2.1/gems/ruby-mpd-0.3.3/lib/ruby-mpd.rb:191:in `synchronize'
    from /home/pi/.rvm/gems/ruby-2.2.1/gems/ruby-mpd-0.3.3/lib/ruby-mpd.rb:191:in `send_command'
    from /home/pi/.rvm/gems/ruby-2.2.1/gems/ruby-mpd-0.3.3/lib/ruby-mpd/plugins/controls.rb:29:in `play'
    from radio.rb:10:in `block in <main>'
    from radio.rb:5:in `loop'
    from radio.rb:5:in `<main>'

Protocol updates in mpd v.18

There are a few new commands and features in .18 that aren't implemented:

  • protocol:
    • new command "readcomments" lists arbitrary file tags
    • new command "toggleoutput"
    • "find"/"search" with "any" does not match file name
    • "search" and "find" with base URI (keyword "base")
    • search for album artist falls back to the artist tag
    • re-add the "volume" command

http://git.musicpd.org/cgit/master/mpd.git/plain/NEWS?h=release-0.18

:toggleoutput is pretty straightforward but :readcomments is not. :readcomments returns a hash of additional arbitrary tags on the song file. I'd like to implement it but I wanted to see if you had any comment on how it should be done.

The last 4 items already work.

Correct way of handling timeouts?

As the README.md states, version 0.3.0 should introduce some kind of 'reconnect mechanism'. As far as is can see, there is no such mechanism. If the server decides to time out the connection of a ruby-mpd client object, #connected? doesn't report the timed out connection as well as #ping and any call that requires a working connection returns true or throws different exceptions as calls to the sockets #gets function return nil. The only way to detect, that the server closed the connection due to a timeout would be to check #eof? on the socket.
At the moment i'm working on an implementation of the #callback_thread that uses a blocking #gets version of the mpd idle command and as a result of my implementation, not even having callbacks enabled prevents the connection from timing out as there are no frequent polling any more. That is why i stumbled about it.
Am i missing something or is this the intended way the ruby-mpd gem should work?

Add toggle command (mpc like)

mpc like toggle command seems to be unsupported, would be a good addition.
"mpc toggle Toggles Play/Pause, plays if stopped"

Add a function to temporarily disable callbacks

When I'm adding a lot of songs one by one (which as far as I can see can't be done any other way), the :playlist callback gets fired multiple times, which is correct. But it would be nice to be able to temporarily disable callbacks for potentially long operations, like this:

class MPD
  def no_callbacks(&block)
    # pause callback thread (or stop it)
    yield
    # resume callback thread (or restart it)
  end
end

mpd.no_callbacks do
  # add many songs here
end
# :playlist callback gets fired here

This way, my client would get the updated playlist when it's finished and wouldn't have to process multiple incomplete updates. At the end of the provided block, the callback thread would resume as usual and emit all changed keys. This requires that the callback cannot only be stopped, but also resumed (or stopped and then restarted).

Any feedback would be appreciated!

License missing from gemspec

RubyGems.org doesn't report a license for your gem. This is because it is not specified in the gemspec of your last release.

via e.g.

spec.license = 'MIT'
# or
spec.licenses = ['MIT', 'GPL-2']

Including a license in your gemspec is an easy way for rubygems.org and other tools to check how your gem is licensed. As you can imagine, scanning your repository for a LICENSE file or parsing the README, and then attempting to identify the license or licenses is much more difficult and more error prone. So, even for projects that already specify a license, including a license in your gemspec is a good practice. See, for example, how rubygems.org uses the gemspec to display the rails gem license.

There is even a License Finder gem to help companies/individuals ensure all gems they use meet their licensing needs. This tool depends on license information being available in the gemspec. This is an important enough issue that even Bundler now generates gems with a default 'MIT' license.

I hope you'll consider specifying a license in your gemspec. If not, please just close the issue with a nice message. In either case, I'll follow up. Thanks for your time!

Appendix:

If you need help choosing a license (sorry, I haven't checked your readme or looked for a license file), GitHub has created a license picker tool. Code without a license specified defaults to 'All rights reserved'-- denying others all rights to use of the code.
Here's a list of the license names I've found and their frequencies

p.s. In case you're wondering how I found you and why I made this issue, it's because I'm collecting stats on gems (I was originally looking for download data) and decided to collect license metadata,too, and make issues for gemspecs not specifying a license as a public service :). See the previous link or my blog post about this project for more information.

First command causes error

Using MPD 0.19.1 on Debian 8, Ruby 2.1.5p273

require 'ruby-mpd'
mpd = MPD.new
mpd.status # NoMethodError: undefined method `[]' for nil:NilClass from /var/lib/gems/2.1.0/gems/ruby-mpd-0.3.3/lib/ruby-mpd/parser.rb:129:in `make_chunks'
mpd.status # works

.songs returns empty array despite reporting 200k songs

Any idea why I would always get an empty string when using mpd.songs. When using ympd it shows a database, and mpd stats even report back that it has songs. I can do mpd.albums and mpd.artists and it gives the exepcted output but songs is empty. Is it that I have too many songs?

mpd.stats
 => {:uptime=>2930, :playtime=>0, :artists=>2169, :albums=>1772, :songs=>201361, :db_playtime=>29261847, :db_update=>2016-02-01 23:44:27 +0100}

New release?

First of all, thanks for this library. It's been terrific for scripting with.

I just came across the bug in #62, but the last release was back in 2015 (and the fix was in 2016). Is it possible to get a new release pushed to RubyGems so that I (and others) don't have to vendor/monkeypatch this in?

Thanks!

mpd.playlists[index].songs breaks when playlist contains non-existent file

If a playlist has an internet radio or an erroneous file the .songs method throws the exception:

TypeError: no implicit conversion of Symbol into String

I would expect the the method to return a list of song objects as stated in the playlist. Perhaps some checks could be made for interet radio. Or perhaps return nil for those songs which do not exist. Or worst case provide an error indicating which playlist and file produce the error. In my case, the playlist has two good files and just one bad, and it took me a while to track down the problem.

To confirm just echo some erronous fileames or an internet radio url into an .m3u file in mpd's playlist directory and parse it with ruby-mpd. Heres the trace:

from ...gem/ruby/2.0.0/gems/ruby-mpd-0.2.2/lib/ruby-mpd/song.rb:12:in `initialize'
from ...gem/ruby/2.0.0/gems/ruby-mpd-0.2.2/lib/ruby-mpd/playlist.rb:25:in `new'
from ...gem/ruby/2.0.0/gems/ruby-mpd-0.2.2/lib/ruby-mpd/playlist.rb:25:in `block in songs'
from ...gem/ruby/2.0.0/gems/ruby-mpd-0.2.2/lib/ruby-mpd/playlist.rb:25:in `map'
from ...gem/ruby/2.0.0/gems/ruby-mpd-0.2.2/lib/ruby-mpd/playlist.rb:25:in `songs'

Time not correctly updating

I recently into strange behavior regarding the time field and streams. If I add a youtube stream to mpd, mpd seems to first have no idea of the time (mpc reports it as 0:00/0:00) and then as it parses it mpd starts correctly reporting the time. ruby-mpd always reports the time as nil, even when mpc is correctly reporting the time. I am thinking the ruby-mpd might not be getting the latest information? But I'm a bit lost as to where the issue lies. Here is an example of what I am talking about:

Youtube video I have been using for testing (happens to all videos): https://www.youtube.com/watch?v=Q1JxHz_9LBI

I have been obtaining the stream using youtube-dl --prefer-insecure -i -f140 -q --no-warnings -ge https://www.youtube.com/watch?v=Q1JxHz_9LBI via my mumble bot.

Immediately after adding the stream, nothing is playing yet

brick@treef ~/mumblecop (hg)-[default] % mpc
Stanchinsky - Piano Sonata in E-flat minor 
[playing] #1/1   0:00/0:00 (0%)
volume: n/a   repeat: off   random: off   single: off   consume: on \

Stream starts playing through mpd

brick@treef ~/mumblecop (hg)-[default] % mpc
Stanchinsky - Piano Sonata in E-flat minor 
[playing] #1/1   0:17/9:46 (2%)
volume: n/a   repeat: off   random: off   single: off   consume: on 
brick@treef ~/mumblecop (hg)-[default] % irb
irb(main):001:0> require 'ruby-mpd'
=> true
irb(main):002:0> a = MPD.new
=> #<MPD:0x00000002593268 @hostname="localhost", @port=6600, @options={:callbacks=>false}, @password=nil, @socket=nil, @version=nil, @tags=nil, @mutex=#<Mutex:0x00000002593150>, @callbacks={}>
irb(main):003:0> a.connect
=> true
irb(main):004:0> a.current_song
=> #<MPD::Song:0x000000025767f8 @mpd=#<MPD:0x00000002593268 @hostname="localhost", @port=6600, @options={:callbacks=>false}, @password=nil, @socket=#<TCPSocket:fd 9>, @version="0.19.0", @tags=nil, @mutex=#<Mutex:0x00000002593150>, @callbacks={}>, @data={:pos=>0, :id=>35}, @time=nil, @file="http://r9---sn-ab5e6m7e.googlevideo.com/videoplayback?id=4352711f3ffd2c12&itag=140&source=youtube&pl=17&mm=31&mn=sn-ab5e6m7e&mv=m&ms=au&nh=EAI&ratebypass=yes&mime=audio/mp4&gir=yes&clen=9300109&lmt=1390341494585760&dur=585.514&mt=1438116453&sver=3&signature=81FD1414A77EFE2FDCE2CDB9F2E7B6215AE56704.19EB9387CC5F4D701538CEA4779088190B7E8797&key=dg_yt0&upn=5RvJtqAhGo0&fexp=901816,9407150,9407813,9408710,9415365,9415387,9415430,9415485,9416126,9416217,9416324,9417279,9417878&ip=96.252.105.91&ipbits=0&expire=1438138113&sparams=ip,ipbits,expire,id,itag,source,pl,mm,mn,mv,ms,nh,ratebypass,mime,gir,clen,lmt,dur", @title="Stanchinsky - Piano Sonata in E-flat minor ", @artist=nil, @album=nil, @albumartist=nil>

ruby-mpd returns time as nil.

Any thoughts? I will try digging more into the source. I'm guessing that when the song object is initialized the time is nil but when mpd updates it ruby-mpd doesn't read the updated value, but I'm not sure how it works behind the scenes. But on second thought I guess I must be wrong because I have been adding the title after adding the stream and ruby-mpd is correctly reading the song. So... I'll keep looking :)

extraneous data leading to inconsistencies in MPD#songs

I'm working on Dockerizing an application that uses ruby-mpd. I include a small set of Creative Commons mp3s as a kind of "database seed". I noticed that @mpd.songs.count was always 1 greater than the actual count of my library.

using some Dirty Ruby Tricks(tm), I've traced it as follows:

[1] pry(main)> @mpd = MPD.new ENV['MPD_HOST'], ENV['MPD_PORT']    
=> #<MPD:0x0000000584e6d0
 @callbacks={},
 @hostname="127.0.0.1",
 @mutex=#<Mutex:0x0000000584e590>,
 @options={:callbacks=>false},
 @password=nil,
 @port="6600",
 @socket=nil,
 @tags=nil,
 @version=nil>
[2] pry(main)> @mpd.connect    
=> true
[3] pry(main)> unless ENV['MPD_PASS'].nil?    
[3] pry(main)*   @mpd.password ENV['MPD_PASS']      
[3] pry(main)* end      
=> nil
[4] pry(main)> 
[5] pry(main)> 
[6] pry(main)> 
[7] pry(main)> 
[8] pry(main)> @mpd.send('socket').puts 'listallinfo'
=> nil
[9] pry(main)> response = @mpd.send('handle_server_response')
=> "directory: test_library\nLast-Modified: 2015-08-04T20:01:23Z\nfile: test_library/Indian_Summer-212174.mp3\nLast-Modified: 2009-04-04T13:04:47Z\nTime: 286\nArtist: canton\nTitle: Indian Summer\nAlbum: http://www.cantonbecker.com\nfile: test_library/Map_of_the_Cosmos-184608.mp3\nLast-Modified: 2009-03-16T01:37:52Z\nTime: 395\nArtist: canton\nTitle: Map of the Cosmos\nAlbum: http://www.cantonbecker.com\n"
[10] pry(main)> 
[11] pry(main)> response.lines
=> ["directory: test_library\n",
 "Last-Modified: 2015-08-04T20:01:23Z\n",
 "file: test_library/Indian_Summer-212174.mp3\n",
 "Last-Modified: 2009-04-04T13:04:47Z\n",
 "Time: 286\n",
 "Artist: canton\n",
 "Title: Indian Summer\n",
 "Album: http://www.cantonbecker.com\n",
 "file: test_library/Map_of_the_Cosmos-184608.mp3\n",
 "Last-Modified: 2009-03-16T01:37:52Z\n",
 "Time: 395\n",
 "Artist: canton\n",
 "Title: Map of the Cosmos\n",
 "Album: http://www.cantonbecker.com\n"]
[12] pry(main)> response.lines.reject {|line| line =~ /(#{[:directory, :playlist].join('|')}):/i}
=> ["Last-Modified: 2015-08-04T20:01:23Z\n",
 "file: test_library/Indian_Summer-212174.mp3\n",
 "Last-Modified: 2009-04-04T13:04:47Z\n",
 "Time: 286\n",
 "Artist: canton\n",
 "Title: Indian Summer\n",
 "Album: http://www.cantonbecker.com\n",
 "file: test_library/Map_of_the_Cosmos-184608.mp3\n",
 "Last-Modified: 2009-03-16T01:37:52Z\n",
 "Time: 395\n",
 "Artist: canton\n",
 "Title: Map of the Cosmos\n",
 "Album: http://www.cantonbecker.com\n"]

note statements 11 and 12. MPD::Parser#filter_lines removes the "directory" line, but leaves behind the "Last-Modified" line associated with the directory. this later on manifests as a bizarre, inconsistent song list:

[13] pry(main)> @mpd.songs
=> [#<MPD::Song:0x000000049a5930
  @album=nil,
  @albumartist=nil,
  @artist=nil,
  @data={:"last-modified"=>2015-08-04 20:01:23 UTC},
  @file="test_library/Indian_Summer-212174.mp3",
  @mpd=
   #<MPD:0x0000000584e6d0
    @callbacks={},
    @hostname="127.0.0.1",
    @mutex=#<Mutex:0x0000000584e590>,
    @options={:callbacks=>false},
    @password=nil,
    @port="6600",
    @socket=#<TCPSocket:fd 10>,
    @tags=nil,
    @version="0.19.0">,
  @time=nil,
  @title=nil>,
 #<MPD::Song:0x000000049a58b8
  @album="http://www.cantonbecker.com",
  @albumartist=nil,
  @artist="canton",
  @data={:"last-modified"=>2009-04-04 13:04:47 UTC},
  @file="test_library/Map_of_the_Cosmos-184608.mp3",
  @mpd=
   #<MPD:0x0000000584e6d0
    @callbacks={},
    @hostname="127.0.0.1",
    @mutex=#<Mutex:0x0000000584e590>,
    @options={:callbacks=>false},
    @password=nil,
    @port="6600",
    @socket=#<TCPSocket:fd 10>,
    @tags=nil,
    @version="0.19.0">,
  @time=[nil, 286],
  @title="Indian Summer">,
 #<MPD::Song:0x000000049a5868
  @album="http://www.cantonbecker.com",
  @albumartist=nil,
  @artist="canton",
  @data={:"last-modified"=>2009-03-16 01:37:52 UTC},
  @file=nil,
  @mpd=
   #<MPD:0x0000000584e6d0
    @callbacks={},
    @hostname="127.0.0.1",
    @mutex=#<Mutex:0x0000000584e590>,
    @options={:callbacks=>false},
    @password=nil,
    @port="6600",
    @socket=#<TCPSocket:fd 10>,
    @tags=nil,
    @version="0.19.0">,
  @time=[nil, 395],
  @title="Map of the Cosmos">]

3 songs where there should be 2, one with a nil @file variable, another with a nil @time variable.

I have no idea what a fix would/should look like. I think I've spent all of today's brain juices tracing the issue this far.

as an additional exhibit, here's a data structure that has obviously weird behavior in :"last-modified" and :time. I didn't trace it fully, but I assume this data structure will eventually become an array of MPD::Song objects. the mis-matched columns likely causes malformed objects to be created.

[15] pry(main)> @mpd.send('parse_response', 'listallinfo', response)
=> {:directory=>"test_library",
 :"last-modified"=>[23, 1, 20, 4, 8, 2015, 2, 216, false, "UTC", 2009-04-04 13:04:47 UTC, 2009-03-16 01:37:52 UTC],
 :file=>["test_library/Indian_Summer-212174.mp3", "test_library/Map_of_the_Cosmos-184608.mp3"],
 :time=>[nil, 286, [nil, 395]],
 :artist=>["canton", "canton"],
 :title=>["Indian Summer", "Map of the Cosmos"],
 :album=>["http://www.cantonbecker.com", "http://www.cantonbecker.com"]}

Tag releases

Hey Blaz @archseer,

I’ve seen that you’ve incremented the version number in ruby-mpd but and released on Rubygems but in fact the code has not been tagged. Given that I’ve migrated the codebase onto Bundler, I thought I’d share with you what I do, it may be useful:

I use rake release after changing version.rb, this rake task comes from Bundler and it properly tags the codebase, pushes it up and then releases the gem onto Rubygems. So all release stuff can be done using a single command in the terminal.

Hopefully this will help.

— Attila

track_length errors when a song has no time

A Song may have @time==nil if the song is not valid. This may occur if a playlist has songs added to it that have then been removed from the queue (or if a playlist file is hand-edited to add broken entries).

When this is the case, asking for song.track_length errors, because the implementation is just @time.last.

Song filename with double-quotes causes errors

Though rarely a good idea, it's possible for filenames to have double-quotes in them. In this case, the MPD protocol expects the name to be double-quoted, with double-quotes inside escaped with backslashes. For example, given a song test/"Suddenly".mp3:

# telnet to MPD
add test/"Suddenly".mp3
ACK [2@0] {add} Invalid unquoted character
add "test/"Suddenly".mp3"
ACK [2@0] {add} Space expected after closing '"'
add "test/\"Suddenly\".mp3"
OK

Several spots in the codebase just wrap a uri in quotes without escaping embedded quotes.

Cannot fetch songs for playlist (TypeError)

Code

require "pp"
require "ruby-mpd"

mpd = MPD.new
mpd.connect

begin
  playlist = MPD::Playlist.new(mpd, "Example")
  playlist.add("http://uk1.internet-radio.com:8106/listen.pls")
  pp playlist.songs
ensure
  mpd.disconnect
end

Output

Files inside Playlist 'Example' do not exist!
[]

I've checked the code and found this implementation of MPD::Playlist#songs:

    # Lists the songs in the playlist. Playlist plugins are supported.
    # @return [Array<MPD::Song>] songs in the playlist.
    def songs
      result = @mpd.send_command(:listplaylistinfo, @name)
      result.map do |hash|
        if hash[:file] && !hash[:file].match(/^(https?:\/\/)?/)[0].empty?
          Song.new(@mpd, {:file => hash[:file], :time => [0]})
        else
          Song.new(@mpd, hash)
        end
      end
    rescue TypeError
      puts "Files inside Playlist '#{@name}' do not exist!"
      return []
    rescue NotFound
      return [] # we rescue in the case the playlist doesn't exist.
    end

The problem is, that result looks like this:

[ "http://uk1.internet-radio.com:8106/listen.pls" ]

But the code requires result to look like this:

[ { :file => "http://uk1.internet-radio.com:8106/listen.pls" } ]

Edit: I am using MPD 0.18.0

Crash everytime #where is called with add: true

Whenever I call #where with the add flag true, it crashes with the following error:

/usr/lib/ruby/gems/1.9.1/gems/ruby-mpd-0.3.1/lib/ruby-mpd/parser.rb:112:in `build_songs_list': undefined method `map' for true:TrueClass (NoMethodError)
        from /usr/lib/ruby/gems/1.9.1/gems/ruby-mpd-0.3.1/lib/ruby-mpd/plugins/database.rb:95:in `where'
        from MusicBot.rb:117:in `search'
        from MusicBot.rb:191:in `parse_input'
        from MusicBot.rb:55:in `block in <main>'
        from /usr/lib/ruby/gems/1.9.1/gems/mumble-ruby-1.0.2/lib/mumble-ruby/client.rb:145:in `call'
        from /usr/lib/ruby/gems/1.9.1/gems/mumble-ruby-1.0.2/lib/mumble-ruby/client.rb:145:in `block in run_callbacks'
        from /usr/lib/ruby/gems/1.9.1/gems/mumble-ruby-1.0.2/lib/mumble-ruby/client.rb:145:in `each'
        from /usr/lib/ruby/gems/1.9.1/gems/mumble-ruby-1.0.2/lib/mumble-ruby/client.rb:145:in `run_callbacks'
        from /usr/lib/ruby/gems/1.9.1/gems/mumble-ruby-1.0.2/lib/mumble-ruby/client.rb:136:in `read'
        from /usr/lib/ruby/gems/1.9.1/gems/mumble-ruby-1.0.2/lib/mumble-ruby/client.rb:130:in `block (2 levels) in spawn_thread'
        from /usr/lib/ruby/gems/1.9.1/gems/mumble-ruby-1.0.2/lib/mumble-ruby/client.rb:130:in `loop'
        from /usr/lib/ruby/gems/1.9.1/gems/mumble-ruby-1.0.2/lib/mumble-ruby/client.rb:130:in `block in spawn_thread'

This also happens when I am calling #where from irb, and regardless of the value of the strict option. Also, it should be noted that mpd does indeed add the query into the queue, but ruby-mpd crashes.

By looking at the source, you say that #where should return true whenever the add option is true and it seems like #build_song_list can't handle the return from #send_command.

I think that this is unintentional behavior, as half of the examples that are given on how to use #where use the add option.

I have tested and reproduced the bug on debian squeeze with mpd 0.17.6 and ruby 1.9.3 and on arch with mpd 0.18.9 with ruby 2.1.1

Problem adding 1st song to the queue.

Hey,

I wasn't sure if this was a bug or I'm not using the library correctly. I noticed that the first song I add doesn't show up in the queue until I add a 2nd song. I took a screenshot of the irb session so you could see what I'm talking about. Let me know if it's a bug, I wouldn't mind putting in a fix for it if you wanted some help. Also thank you very much for putting this gem together. It's been great fun working with it.

ruby-mpd-irb

Getting stickers does not parse the values

mpd.set_sticker 'song', song, 'added-by', 'phrogz'
#=> true

mpd.list_stickers 'song', song
#=> "added-by=phrogz"

mpd.get_sticker 'song', song, 'added-by'
#=> "added-by=phrogz"

I would expect list_stickers to return a Hash, e.g. { 'added-by' => 'phrogz' }
I would expect get_sticker to return a String, e.g. "phrogz"

Some genres have cryptic ids instead of text

s = M.where(genre:'(123)').first
s.genre         #=> "(123)"
s.file          #=> "Beelzebubs/Foster Street/08 Comfortably Numb.mp3"
phrogz$ eyeD3 "Beelzebubs/Foster Street/08 Comfortably Numb.mp3" | grep genre
track: 8        genre: A Cappella (id 123)

I'd like to get the genre name, not the id, in my Song instances. Is this possible?

Error when attempting to play stream

When using the add command (in a queue) with a valid stream URL (both m3u or mp3), this error is shown : [] No database .
How can I fix that ?

Songs with nil file

Just imported my song library. There are many Songs returned with no file.

[ M.stats[:songs], M.songs.length, M.songs.reject(&:file).length ]
#=> [17103, 22892, 5789]

Some of them are real zombies:

M.songs.reject(&:file).first
#=> #<MPD::Song:0x000000028e18e8 @mpd=…, @data={:"last-modified"=>2015-11-08 07:57:01 UTC}, @time=nil, @file=nil, @title=nil, @artist=nil, @album=nil, @albumartist=nil>

Some of them are files that exist on disk (perhaps the Unicode characters in the path are tricky?):

M.songs.reject(&:file).last
#=> #<MPD::Song:0x00000003704178 @mpd=…, @data={:"last-modified"=>2008-06-01 03:16:00 UTC, :track=>1, :date=>2003, :genre=>"Soundtrack"}, @time=[nil, 160], @file=nil, @title="Bang Bang (My Baby Shot Me Down)", @artist="Nancy Sinatra", @album="Kill Bill: Vol.1", @albumartist="群星">

Dir['**/*'].grep /Bang Bang/
#=> ["群星/Kill Bill_ Vol.1/01 Bang Bang (My Baby Shot Me Down).mp3"]

puts `ls -l "群星/Kill Bill_ Vol.1/"`
#=> total 3744
#=> -rw-r--r-- 1 gkistner gkistner 3833856 May 31  2008 01 Bang Bang (My Baby Shot Me Down).mp3

How do I fix it so that all songs have a file?

error in playlist.rb method move

hi, thank you for this gem
i got error when try to move song in playlist
there are not enough params (songid and songpos) in @mpd.send_command

def move(songid, songpos)
- @mpd.send_command :playlistmove, @name
+ @mpd.send_command :playlistmove, @name, songid, songpos
end

Discussion: how to best test complex interactions?

I've put a question on Stack Exchange Code Review:
http://codereview.stackexchange.com/q/120345/3060

In short, I am writing tests for the command_lists functionality and expected results for ugly edge cases. I welcome any opinions on a better way to simulate MPD getting and sending information.

The two changes I plan to make beyond what I put there are:

  1. Instead of one monolithic recording of requests and responses, I'd prefer a more modular approach of smaller recordings that are easier to handle. Maybe one recording file per 'feature', or maybe even (!) one recording file per streak of commands sent. (Where the filename is the SHA-1 hash of the commands sent?)
  2. Instead of impenetrable Marshal files for the recordings, which can't be hand-edited, I want some sort of plain-text syntax. If I have one file per response, the contents of the file can BE the response, one on each line. I like that.

Song with multiple genres causes runtime error

Some of my songs come back from the server with multiple genres applied:

$ telnet 0 6600
Trying 0.0.0.0...
Connected to 0.
Escape character is '^]'.
OK MPD 0.19.0
search file "pull me under"
file: doza/Dream Theater/Images and Words/01 Pull Me Under.mp3
Last-Modified: 2012-11-11T16:44:44Z
Time: 493
Artist: Dream Theater
AlbumArtist: Dream Theater
Title: Pull Me Under
Album: Images and Words
Track: 1
Date: 1992
Genre: Rock
Genre: Rock
Composer: Dream Theater; Kevin Moore

This results in an array in the genre metadata:

song = @mpd.where(file:'pull me under').first
p song.instance_variable_get(:@data)[:genre]
#=> ["Rock", "Rock"]

This causes some code in the new genre resolver to fail when asking for song.genre.

/var/lib/gems/2.1.0/gems/ruby-mpd-0.3.3/lib/ruby-mpd/song.rb:264:in `[]': no implicit conversion of Regexp into Integer (TypeError)

Support `idle`

The information.rb plugin has an idle command, but it is currently commented out.

I'd like to be able to watch for changes. As it is I'll have to use background threads shelling out to mpc idle to implement the same functionality.

Instantiate a playlist by name

My UI uses the name of a playlist as the unique identifier. When I want to fetch a playlist with this name I must currently use one of the following:

playlist = @mpd.playlists.find{ |pl| pl.name==playlistname }
playlist = MPD::Playlist.new( @mpd, playlist:playlistname )

Using find feels gross because it instantiates all the playlists (maybe a great many) when I only need one. Using new feels gross because if I mistakenly ask for a playlist that does not exist it will be created.

I'd prefer to be able to do something like:

playlist = @mpd.playlist( playlistname )

Does that seem reasonable?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.