massive update, probably broken
[dotfiles/.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