#!/usr/bin/ruby -w # Simple web interface to music player daemon in Ruby. # More information on mpd can be found at http://www.musicpd.org/ # require 'librmpd' # librmpd is incomprehensibly bad. playlistinfo takes 30 damned seconds and isn't actually fucking named playlistinfo. require 'mpd' # Whereas here, playlistinfo takes one second and is fucking named playlistinfo. $VERBOSE = nil # mpd.rb is a bit noisy about versions, though. require 'cgi' cgi = CGI.new m = MPD.new def output_info(m) currentsong = m.currentsong status = m.status stats = m.stats playlistinfo = m.playlistinfo position = currentsong['pos'].to_i times = status['time'].split(':') listeners = 0 File.open('/proc/net/tcp', 'r').each do |line| if /^.{6}[0-9A-F]{8}:1F40 (?!00000000:0000)/ =~ line #255.255.255.255:4369 not LISTENing listeners += 1 end end print 'Content-type: text/html; charset=utf-8 Refresh: 30; URL=', ENV['REQUEST_URI'].sub(/\?.+/,''), ' Music Status

Music Status

Playing ' format_songinfo(currentsong) print ' for ', listeners, ' listeners.

This song is ', times[0].to_i*100/times[1].to_i, '% complete (', times[0], ' of ', times[1], ' seconds played).

This is song ', position+1, ' of ', status['playlistlength'], ' total in the library. Next!

', stats['playtime'].to_i/864/100.0, ' days into playlist length of ', stats['db_playtime'].to_i/864/100.0, ' days.

Here are the proximal songs:

'
  
  min = 0
  if position >= 10
    min = position-10
  end
  max = position+10
  if max > status['playlistlength'].to_i
    max = status['playlistlength'].to_i
  end
  playlistinfo[min,max].each do |songinfo|
    if songinfo['pos'] == position
      print ''
    end
    print 'Queue ' , songinfo['pos'], ' '

    format_songinfo(songinfo)

    if songinfo['pos'] == position
      print ''
    end
    print '
'
  end

  print '    

Full playlist management

' end def output_stopped() print 'Content-type: text/html; charset=utf-8 Music Status

Music Status

MPD is stopped.

Start?

' end def output_playlist(m) print 'Content-type: text/html; charset=utf-8 Playlist

Playlist

Return to main

Load pre-existing playlist: ' m.lsplaylists.each do |playlist| print '', playlist, ' '; end print'

'

  m.playlistinfo.each do |songinfo| # One giant object

      print '', songinfo['pos'], ' '

      format_songinfo(songinfo)

      print '
'
  end


  print'
    
' end def format_songinfo(songinfo) if songinfo['artist'] && songinfo['title'] print CGI.escapeHTML( songinfo['artist'] + ' - ' + songinfo['title'] ) elsif songinfo['title'] print CGI.escapeHTML( songinfo['title'] ) else print CGI.escapeHTML( songinfo['file'] ) end end def queue(m,songpos) curpos = m.currentsong['pos'].to_i if songpos <= curpos # mpd is a little screwy about how it handles playlist reordering m.move(songpos, curpos) elsif songpos > curpos m.move(songpos, curpos+1) end end if cgi.params['ajaxqueue'][0] =~ /^\d+$/ # ?ajaxqueue=55385 songinfo = m.playlistid(cgi.params['ajaxqueue'][0]) queue(m, songinfo['pos'].to_i) print 'Content-type: application/xhtml+xml; charset=utf-8 ' format_songinfo(songinfo) print ' has been requeued.' elsif cgi.params['queue'][0] =~ /^\d+$/ # ?queue=55385 queue(m, m.playlistid(cgi.params['queue'][0])['pos'].to_i) output_info(m) elsif cgi.params['playlist'][0] =~ /.+/ # ?playlist=something m.crop m.load(cgi.params['playlist'][0]) m.shuffle output_info(m) elsif cgi.params.has_key? 'playlist' # ?playlist output_playlist(m) elsif m.status['state'] == 'play' # mpd playing? if cgi.params.has_key? 'change' # ?change m.next end output_info(m) else # mpd not playing if cgi.params.has_key? 'start'# ?start m.play output_info(m) else # stopped display output_stopped() end end