-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

The subject says it all. :P

Reasons why this is better:
- - It times out after 1 sec if mpd is unreachable, old code could freeze 
awesome
- - It works with passworded mpd servers (untested, but saw a bug in the old 
code)
- - It can do xcb-style async requests
- - The code doesn't have a 200 lines license header ;)
- - It doesn't error out badly if lua-socket is missing
- - No API breakage, old code will continue to work
- - I wrote it!

Uli


The following changes since commit e64d4f92f1f1a6430a000c5051e157218ccfe7b7:
  Gregor Best (1):
        Merge branch 'for-farhaven' of git://git.znc.in/psychon/obvious

are available in the git repository at:

  git://git.znc.in/psychon/obvious.git mpd

Uli Schlachter (1):
      Replace lib.mpd with a waaay better version :P

 lib/mpd.lua      |  212 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/mpd/init.lua |  160 ----------------------------------------
 2 files changed, 212 insertions(+), 160 deletions(-)
 create mode 100644 lib/mpd.lua
 delete mode 100644 lib/mpd/init.lua
- --
"Do you know that books smell like nutmeg or some spice from a foreign land?"
                                                  -- Faber in Fahrenheit 451
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)

iQEcBAEBCAAGBQJKjZNtAAoJECLkKOvLj8sGukcH/jvk0Qfbg2uy9LgKGSQhWF8n
FM5BevTe9+pv3HhAXwMJVwlbmMBQo+oV6rnwZdGSOy/YRwN1OxdO14r+MQNr/SGR
Sgze4jd+zYRpYniac2hEm3Zmswj6BCSntioe+0I7Kf+BHwUZVOFfPY0849opa1iJ
GLghCa27ntwxP/r45hUi2V0S9G1LOp6Hxfohd1kT3Bl8nswfKdpGF9HXLh5rN3yP
+N52ju8zz3+MVeFJnc4YE4981xtGg5dj4pfCf0/7KelYVPhbGqc/dV7QnyHzxyPA
sWmLkrUZ+t3kJ3YFMYTFTr7oE+C73HLPt3f+F9Tq2s0IZOFN7mQFegonUN4rU9c=
=Hp64
-----END PGP SIGNATURE-----
>From 2055732a68008b7010c8034139afd3c0c6b2762c Mon Sep 17 00:00:00 2001
From: Uli Schlachter <psyc...@znc.in>
Date: Thu, 20 Aug 2009 20:10:38 +0200
Subject: [PATCH] Replace lib.mpd with a waaay better version :P

The api stays the same, no breakage here.

Signed-off-by: Uli Schlachter <psyc...@znc.in>
---
 lib/mpd.lua      |  212 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/mpd/init.lua |  160 ----------------------------------------
 2 files changed, 212 insertions(+), 160 deletions(-)
 create mode 100644 lib/mpd.lua
 delete mode 100644 lib/mpd/init.lua

diff --git a/lib/mpd.lua b/lib/mpd.lua
new file mode 100644
index 0000000..e29f6e8
--- /dev/null
+++ b/lib/mpd.lua
@@ -0,0 +1,212 @@
+-----------------------------------
+-- Author: Uli Schlachter        --
+-- Copyright 2009 Uli Schlachter --
+-----------------------------------
+
+-- pcall() catches errors if socket is not available
+local have_socket, socket = pcall(function() return require("socket") end)
+local setmetatable = setmetatable
+local print = print
+local pairs = pairs
+local string = string
+local tonumber = tonumber
+
+module("obvious.lib.mpd")
+
+local mpd_socket = nil
+local settings = {
+    hostname = "localhost",
+    port = 6600,
+    password = nil,
+    timeout = 1,
+}
+
+local function reconnect()
+    if not have_socket then
+        print('obvious.lib.mpd: require("socket") failed')
+        return
+    end
+
+    mpd_socket = socket.tcp()
+
+    -- First set the timeout so that :connect() honors it
+    mpd_socket:settimeout(settings.timeout, "t")
+    mpd_socket:setoption("keepalive", true)
+
+    local connected, err
+    connected, err = mpd_socket:connect(settings.hostname, settings.port)
+    if not connected then
+        -- Do something with err
+        mpd_socket:close()
+        mpd_socket = nil
+
+        return false
+    end
+
+    -- Skip the server's welcome message
+    mpd_socket:receive("*l")
+
+    if settings.password then
+        mpd_socket:send("password " ..  settings.password .. "\n")
+        -- Get rid of that "OK" or "ACK"
+        mpd_socket:receive("*l")
+    end
+
+    return true
+end
+
+-- Send a command to mpd
+function send_internal(command)
+    if not mpd_socket then
+        reconnect()
+    end
+
+    if mpd_socket then
+        local sent, err
+        sent, err = mpd_socket:send(command .. "\n")
+        if not sent and err then
+            -- Do something with err (can be "closed" or "timeout")
+        end
+    end
+end
+
+-- Collect the result of a previous send_internal() call
+-- *MUST* be called for each send_internal() call, not necessarily immediatly
+-- It returns a table with each server reply as key-value pairs
+-- (The special key _reply is used for the server's status code)
+function recv_internal()
+    local ret = { }
+
+    if mpd_socket then
+        local line, err
+        line, err = mpd_socket:receive("*l")
+        if not line then -- mpd died?
+            -- Do something with err (can be "closed" or "timeout")
+            mpd_socket:close()
+            mpd_socket = nil
+        else
+            while line do
+                if line:match("^OK ?") or line:match("^ACK ") then
+                    ret._reply = line
+                    break
+                end
+                local key = line:match("^([^:]+)")
+                local value = line:match(": ?(.*)$")
+                key = string.lower(key)
+
+                ret[key] = value
+
+                line = mpd_socket:receive("*l")
+            end
+        end
+    end
+
+    return ret
+end
+
+-- Send a command and return the reply
+function send(c)
+    send_internal(c)
+    return recv_internal()
+end
+
+local function get()
+    local ret = { }
+    local reply
+
+    send_internal("status")
+    send_internal("currentsong")
+
+    reply = recv_internal()
+    if reply then
+        ret.state = reply.state
+    end
+
+    reply = recv_internal()
+    if reply then
+        local title = reply.title
+        local artist = reply.artist
+        local file = reply.file
+
+        if title and artist then
+            ret.song = artist .. " - " .. title
+        elseif title then
+            ret.song = title
+        elseif artist then
+            ret.song = artist
+        elseif file then
+            ret.song = file
+        elseif #ret ~= 0 then
+            ret.song = "error"
+            local l = ""
+            for k, v in pairs(reply) do
+                l = l .. "\n" .. k .. ": " .. v
+            end
+            print("MPD: Could not parse:" .. l)
+        end
+    end
+
+    return ret
+end
+
+function toggle_play()
+    local reply = send("status")
+
+    if reply.state == "play" then
+        send("pause 1")
+    elseif reply.state == "pause" then
+        send("pause 0")
+    else
+        -- This should be the "stopped" case or MPD is down
+        send("play -1")
+    end
+end
+
+function toggle_random()
+    local reply = send("status")
+    if stats.random == "0" then
+        send("random 1")
+    else
+        send("random 0")
+    end
+end
+
+function toggle_repeat()
+    local reply = send("status")
+    if reply["repeat"] == "0" then
+        send("repeat 1")
+    else
+        send("repeat 0")
+    end
+end
+
+function next()
+    send("next")
+end
+
+function previous()
+    send("previous")
+end
+
+function pause()
+    send("pause")
+end
+
+function stop()
+    send("stop")
+end
+
+-- no need to check the new value, mpd will set the volume in [0,100]
+function volume_up(delta)
+    local stats = send("status")
+    local new_volume = tonumber(stats.volume) + delta
+    send(string.format("setvol %d", new_volume))
+end
+
+function volume_down(delta)
+    volume_up(-delta)
+end
+
+setmetatable(_M, { __call = get })
+
+-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
diff --git a/lib/mpd/init.lua b/lib/mpd/init.lua
deleted file mode 100644
index d1f0e35..0000000
--- a/lib/mpd/init.lua
+++ /dev/null
@@ -1,160 +0,0 @@
--- Small interface to MusicPD
--- based on a netcat version from Steve Jothen <sjothen at gmail dot com>
--- (see http://github.com/otkrove/ion3-config/tree/master/mpd.lua)
---
--- Copyright (c) 2008-2009, Alexandre Perrin <kaw...@kaworu.ch>
--- All rights reserved.
---
--- Redistribution and use in source and binary forms, with or without
--- modification, are permitted provided that the following conditions
--- are met:
---
--- 1. Redistributions of source code must retain the above copyright
---    notice, this list of conditions and the following disclaimer.
--- 2. Redistributions in binary form must reproduce the above copyright
---    notice, this list of conditions and the following disclaimer in the
---    documentation and/or other materials provided with the distribution.
--- 4. Neither the name of the author nor the names of its contributors
---    may be used to endorse or promote products derived from this software
---    without specific prior written permission.
---
--- THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
--- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
--- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
--- ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
--- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
--- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
--- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
--- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
--- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
--- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
--- SUCH DAMAGE.
-
-require("socket")
-
--- Grab env
-local socket = socket
-local string = string
-local tonumber = tonumber
-
--- Music Player Daemon Lua library.
-module("obvious.lib.mpd")
-
--- default settings values
-settings =
-{
-  hostname = "localhost",
-  port = 6600,
-  password = nil,
-}
-
--- our socket
-local sock = nil;
-
--- override default settings values
-function setup(hostname, port, password)
-  settings.hostname = hostname
-  settings.port = port
-  settings.password = password
-  -- Unset this so that next operation knows to
-  -- get a different server
-  sock = nil
-end
-
-
--- calls the action and returns the server's response.
---      Example: if the server's response to "status" action is:
---              volume: 20
---              repeat: 0
---              random: 0
---              playlist: 599
---              ...
---      then the returned table is:
---      { volume = 20, repeat = 0, random = 0, playlist = 599, ... }
-function send(action)
-  local command = string.format("%s\n", action)
-  local values = {}
-
-  -- connect to MPD server if not already done.
-  if not sock then
-    sock = socket.connect(settings.hostname, settings.port)
-    if sock and settings.password then
-      send(string.format("password %s", settings.password))
-    end
-  end
-
-  if sock then
-    sock:send(command)
-    local line = sock:receive("*l")
-
-    if not line then -- closed (mpd killed?): reset socket and retry
-      sock = nil
-      return send(action)
-    end
-
-    while not (line:match("^OK$") or line:match(string.format("unknow command \"%s\"", action))) do
-      local _, _, key, value = string.find(line, "(.+):%s(.+)")
-      if key then
-        values[string.lower(key)] = value
-      end
-      line = sock:receive("*l")
-    end
-  end
-
-  return values
-end
-
-function next()
-  send("next")
-end
-
-function previous()
-  send("previous")
-end
-
-function pause()
-  send("pause")
-end
-
-function stop()
-  send("stop")
-end
-
--- no need to check the new value, mpd will set the volume in [0,100]
-function volume_up(delta)
-  local stats = send("status")
-  local new_volume = tonumber(stats.volume) + delta
-  send(string.format("setvol %d", new_volume))
-end
-
-function volume_down(delta)
-  volume_up(-delta)
-end
-
-function toggle_random()
-  local stats = send("status")
-  if tonumber(stats.random) == 0 then
-    send("random 1")
-  else
-    send("random 0")
-  end
-end
-
-function toggle_repeat()
-  local stats = send("status")
-  if tonumber(stats["repeat"]) == 0 then
-    send("repeat 1")
-  else
-    send("repeat 0")
-  end
-end
-
-function toggle_play()
-  if send("status").state == "stop" then
-    send("play")
-  else
-    send("pause")
-  end
-end
-
--- vim:filetype=lua:tabstop=8:shiftwidth=2:fdm=marker:
-- 
1.6.3.3

Reply via email to