code: remove `protected` from top-level methods (now in sys)
[nit.git] / lib / mpd.nit
index 43e6eae..e814b56 100644 (file)
@@ -21,25 +21,33 @@ import socket
 
 # Connection to a MPD server
 class MPDConnection
-       var socket: nullable Socket = null
 
+       # Socket connection to server.
+       var socket: nullable TCPStream = null
+
+       # Server hostname.
        var host: String
+
+       # Server port.
        var port: Int
+
+       # Server password.
        var password: nullable String
 
+       # Last occured error.
        var error: nullable String = null
 
        # Connect to the MPD server
        fun connect
        do
-               var p: nullable Socket = null
+               var p: nullable TCPStream = null
 
-               p = new Socket.stream_with_host(host, port)
-               p.connect
+               p = new TCPStream.connect(host, port)
+               assert p.connected
 
                sys.nanosleep(0,5000)
 
-               var rep = p.read
+               var rep = p.read(1024)
                assert not rep.is_empty
                if not rep.has_prefix("OK") then
                        print "MPD responded {rep}"
@@ -61,8 +69,12 @@ class MPDConnection
 
                socket.write(msg)
                sys.nanosleep(0,5000)
-               var rep = socket.read
-               assert rep.has_prefix("OK") else print "MPD responded {rep}"
+               var rep = socket.read(1024)
+               if not rep.has_prefix("OK") then
+                       print "Error: MPD responded {rep}"
+                       socket.close
+                       socket = null
+               end
        end
 
        # Get MPD server status
@@ -72,27 +84,37 @@ class MPDConnection
 
                var volume: nullable Int = null
                var state: nullable String = null
+               var elapsed: nullable Int = null
+               var time_at: nullable Int = null
+               var time_total: nullable Int = null
 
                # get current status
                socket.write("status\n")
-               var rep = socket.read
+               var rep = socket.read(1024)
                for l in rep.split_with("\n") do
                        var words = l.split_with(" ")
                        if words.length > 1 then
                                var key = words[0].to_lower
-                               var first_space = l.index_of(' ')
+                               var first_space = l.chars.index_of(' ')
                                var rest = l.substring_from(first_space+1)
                                if  key == "volume:" then
                                        volume = rest.to_i
                                        if volume == -1 then volume = null
-                               else if  key == "volume:" then
+                               else if  key == "state:" then
                                        state = rest
+                               else if  key == "elapsed:" then
+                                       elapsed = rest.to_i
+                               else if  key == "time:" then
+                                       var times = rest.split(":")
+                                       time_at = times[0].to_i
+                                       time_total = times[1].to_i
                                end
                        end
                end
 
                if state != null then
-                       return new ServerStatus(volume, state)
+                       var status = new ServerStatus(volume, state, elapsed, time_at, time_total)
+                       return status
                else
                        return null
                end
@@ -117,6 +139,7 @@ class MPDConnection
                error = "Cannot get volume"
        end
 
+       # Set MPD server volume.
        fun volume=(vol: Int) do write_and_check("setvol {vol}\n")
 
        # Pause music playing on the MPD server
@@ -136,14 +159,15 @@ class MPDConnection
                var album: nullable String = null
                var artist: nullable String = null
                var title: nullable String = null
+               var time: nullable Int = null
 
                socket.write("currentsong\n")
-               var rep = socket.read
+               var rep = socket.read(1024)
                for l in rep.split_with("\n") do
                        var words = l.split_with(" ")
                        if words.length > 1 then
                                var key = words[0].to_lower
-                               var first_space = l.index_of(' ')
+                               var first_space = l.chars.index_of(' ')
                                var rest = l.substring_from(first_space+1)
                                if key == "album:" then
                                        album = rest
@@ -151,27 +175,83 @@ class MPDConnection
                                        artist = rest
                                else if key == "title:" then
                                        title = rest
+                               else if key == "time:" then
+                                       time = rest.to_i
                                end
                        end
                end
 
-               if album != null and artist != null and title != null then
-                       return new SongInfo(album, artist, title)
+               if album != null and artist != null and
+                       title != null and time != null then
+                       return new SongInfo(album, artist, title, time)
                else
                        return null
                end
        end
+
+       # Load playlist named `name`.
+       fun load_playlist(name: String)
+       do
+               write_and_check "load \"{name}\""
+       end
 end
 
 # MPD song info
 class SongInfo
+       # Song album.
        var album: String
+
+       # Song artist.
        var artist: String
+
+       # Song title.
        var title: String
+
+       # Song total duration.
+       var time: Int
 end
 
 # MPD server status
 class ServerStatus
+
+       # MPD server volume.
        var volume: nullable Int
+
+       # Playback state (play/stop/pause).
        var state: String
+
+       # Is MPD server playing?
+       fun playing: Bool do return state == "play"
+
+       # Is MPD server stopped?
+       fun stopped: Bool do return state == "stop"
+
+       # Time elapsed within the current song.
+       var elapsed: nullable Int
+
+       # TODO comment
+       var time_at: nullable Int
+
+       # Total time of the current song.
+       var time_total: nullable Int
+
+       # Get the cursor position on the song duration.
+       fun time_ratio: nullable Float do
+               if time_at == null or time_total == null then return null
+               return time_at.to_f / time_total.to_f
+       end
+
+       redef fun to_s do
+               var vol = "unknown"
+               if volume != null then vol = volume.to_s
+
+               var time_at = time_at
+               var time_total = time_total
+               var elapsed = elapsed
+               if time_at != null and time_total != null and elapsed != null then
+                       return "volume: {vol}\nstate: {state}\nelapsed: {elapsed}\ntime_[at|total]: {time_at}:{time_total}\ntime_ratio: {time_ratio.as(not null)}"
+               else
+                       return "volume: {vol}\nstate: {state}"
+               end
+       end
 end