]> git.madduck.net Git - etc/awesome.git/blob - .config/awesome/lain/widget/mpd.lua

madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

All patches and comments are welcome. Please squash your changes to logical commits before using git-format-patch and git-send-email to patches@git.madduck.net. If you'd read over the Git project's submission guidelines and adhered to them, I'd be especially grateful.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

Sound and music player handling
[etc/awesome.git] / .config / awesome / lain / widget / mpd.lua
1 --[[
2
3      Licensed under GNU General Public License v2
4       * (c) 2013, Luca CPZ
5       * (c) 2010, Adrian C. <anrxc@sysphere.org>
6
7 --]]
8
9 local helpers  = require("lain.helpers")
10 local shell    = require("awful.util").shell
11 local escape_f = require("awful.util").escape
12 local focused  = require("awful.screen").focused
13 local naughty  = require("naughty")
14 local wibox    = require("wibox")
15 local os       = os
16 local string   = string
17
18 -- MPD infos
19 -- lain.widget.mpd
20
21 local function factory(args)
22     local mpd           = { widget = wibox.widget.textbox() }
23     local args          = args or {}
24     local timeout       = args.timeout or 2
25     local password      = (args.password and #args.password > 0 and string.format("password %s\\n", args.password)) or ""
26     local host          = args.host or os.getenv("MPD_HOST") or "127.0.0.1"
27     local port          = args.port or os.getenv("MPD_PORT") or "6600"
28     local music_dir     = args.music_dir or os.getenv("HOME") .. "/Music"
29     local cover_pattern = args.cover_pattern or "*\\.(jpg|jpeg|png|gif)$"
30     local cover_size    = args.cover_size or 100
31     local default_art   = args.default_art
32     local notify        = args.notify or "on"
33     local followtag     = args.followtag or false
34     local settings      = args.settings or function() end
35
36     local mpdh = string.format("telnet://%s:%s", host, port)
37     local echo = string.format("printf \"%sstatus\\ncurrentsong\\nclose\\n\"", password)
38     local cmd  = string.format("%s | curl --connect-timeout 1 -fsm 3 %s", echo, mpdh)
39
40     mpd_notification_preset = { title = "Now playing", timeout = 6 }
41
42     helpers.set_map("current mpd track", nil)
43
44     function mpd.update()
45         helpers.async({ shell, "-c", cmd }, function(f)
46             mpd_now = {
47                 random_mode  = false,
48                 single_mode  = false,
49                 repeat_mode  = false,
50                 consume_mode = false,
51                 pls_pos      = "N/A",
52                 pls_len      = "N/A",
53                 state        = "N/A",
54                 file         = "N/A",
55                 name         = "N/A",
56                 artist       = "N/A",
57                 title        = "N/A",
58                 album        = "N/A",
59                 genre        = "N/A",
60                 track        = "N/A",
61                 date         = "N/A",
62                 time         = "N/A",
63                 elapsed      = "N/A"
64             }
65
66             for line in string.gmatch(f, "[^\n]+") do
67                 for k, v in string.gmatch(line, "([%w]+):[%s](.*)$") do
68                     if     k == "state"          then mpd_now.state        = v
69                     elseif k == "file"           then mpd_now.file         = v
70                     elseif k == "Name"           then mpd_now.name         = escape_f(v)
71                     elseif k == "Artist"         then mpd_now.artist       = escape_f(v)
72                     elseif k == "Title"          then mpd_now.title        = escape_f(v)
73                     elseif k == "Album"          then mpd_now.album        = escape_f(v)
74                     elseif k == "Genre"          then mpd_now.genre        = escape_f(v)
75                     elseif k == "Track"          then mpd_now.track        = escape_f(v)
76                     elseif k == "Date"           then mpd_now.date         = escape_f(v)
77                     elseif k == "Time"           then mpd_now.time         = v
78                     elseif k == "elapsed"        then mpd_now.elapsed      = string.match(v, "%d+")
79                     elseif k == "song"           then mpd_now.pls_pos      = v
80                     elseif k == "playlistlength" then mpd_now.pls_len      = v
81                     elseif k == "repeat"         then mpd_now.repeat_mode  = v ~= "0"
82                     elseif k == "single"         then mpd_now.single_mode  = v ~= "0"
83                     elseif k == "random"         then mpd_now.random_mode  = v ~= "0"
84                     elseif k == "consume"        then mpd_now.consume_mode = v ~= "0"
85                     end
86                 end
87             end
88
89             mpd_notification_preset.text = string.format("%s (%s) - %s\n%s", mpd_now.artist,
90                                            mpd_now.album, mpd_now.date, mpd_now.title)
91             widget = mpd.widget
92             settings()
93
94             if mpd_now.state == "play" then
95                 if notify == "on" and mpd_now.title ~= helpers.get_map("current mpd track") then
96                     helpers.set_map("current mpd track", mpd_now.title)
97
98                     if followtag then mpd_notification_preset.screen = focused() end
99
100                     local common =  {
101                         preset      = mpd_notification_preset,
102                         icon        = default_art,
103                         icon_size   = cover_size,
104                         replaces_id = mpd.id
105                     }
106
107                     if not string.match(mpd_now.file, "http.*://") then -- local file instead of http stream
108                         local path   = string.format("%s/%s", music_dir, string.match(mpd_now.file, ".*/"))
109                         local cover  = string.format("find '%s' -maxdepth 1 -type f | egrep -i -m1 '%s'",
110                                        path:gsub("'", "'\\''"), cover_pattern)
111                         helpers.async({ shell, "-c", cover }, function(current_icon)
112                             common.icon = current_icon:gsub("\n", "")
113                             if #common.icon == 0 then common.icon = nil end
114                             mpd.id = naughty.notify(common).id
115                         end)
116                     else
117                         mpd.id = naughty.notify(common).id
118                     end
119
120                 end
121             elseif mpd_now.state ~= "pause" then
122                 helpers.set_map("current mpd track", nil)
123             end
124         end)
125     end
126
127     mpd.timer = helpers.newtimer("mpd", timeout, mpd.update, true, true)
128
129     return mpd
130 end
131
132 return factory