massive update, probably broken
[dotfiles/.git] / .config / awesome / lain / widget / contrib / moc.lua
1 --[[
2
3      Licensed under GNU General Public License v2
4       * (c) 2014, anticlockwise <http://github.com/anticlockwise>
5
6 --]]
7
8 local helpers      = require("lain.helpers")
9 local shell        = require("awful.util").shell
10 local focused      = require("awful.screen").focused
11 local escape_f     = require("awful.util").escape
12 local naughty      = require("naughty")
13 local wibox        = require("wibox")
14 local os           = os
15 local string       = string
16
17 -- MOC audio player
18 -- lain.widget.contrib.moc
19
20 local function factory(args)
21     local moc           = { widget = wibox.widget.textbox() }
22     local args          = args or {}
23     local timeout       = args.timeout or 2
24     local music_dir     = args.music_dir or os.getenv("HOME") .. "/Music"
25     local cover_pattern = args.cover_pattern or "*\\.(jpg|jpeg|png|gif)$"
26     local cover_size    = args.cover_size or 100
27     local default_art   = args.default_art or ""
28     local followtag     = args.followtag or false
29     local settings      = args.settings or function() end
30
31     moc_notification_preset = { title = "Now playing", timeout = 6 }
32
33     helpers.set_map("current moc track", nil)
34
35     function moc.update()
36         helpers.async("mocp -i", function(f)
37             moc_now = {
38                 state   = "N/A",
39                 file    = "N/A",
40                 artist  = "N/A",
41                 title   = "N/A",
42                 album   = "N/A",
43                 elapsed = "N/A",
44                 total   = "N/A"
45             }
46
47             for line in string.gmatch(f, "[^\n]+") do
48                 for k, v in string.gmatch(line, "([%w]+):[%s](.*)$") do
49                     if     k == "State"       then moc_now.state   = v
50                     elseif k == "File"        then moc_now.file    = v
51                     elseif k == "Artist"      then moc_now.artist  = escape_f(v)
52                     elseif k == "SongTitle"   then moc_now.title   = escape_f(v)
53                     elseif k == "Album"       then moc_now.album   = escape_f(v)
54                     elseif k == "CurrentTime" then moc_now.elapsed = escape_f(v)
55                     elseif k == "TotalTime"   then moc_now.total   = escape_f(v)
56                     end
57                 end
58             end
59
60             moc_notification_preset.text = string.format("%s (%s) - %s\n%s", moc_now.artist,
61                                            moc_now.album, moc_now.total, moc_now.title)
62             widget = moc.widget
63             settings()
64
65             if moc_now.state == "PLAY" then
66                 if moc_now.title ~= helpers.get_map("current moc track") then
67                     helpers.set_map("current moc track", moc_now.title)
68
69                     if followtag then moc_notification_preset.screen = focused() end
70
71                     local common =  {
72                         preset      = moc_notification_preset,
73                         icon        = default_art,
74                         icon_size   = cover_size,
75                         replaces_id = moc.id,
76                     }
77
78                     local path   = string.format("%s/%s", music_dir, string.match(moc_now.file, ".*/"))
79                     local cover  = string.format("find '%s' -maxdepth 1 -type f | egrep -i -m1 '%s'", path, cover_pattern)
80                     helpers.async({ shell, "-c", cover }, function(current_icon)
81                         common.icon = current_icon:gsub("\n", "")
82                         moc.id = naughty.notify(common).id
83                     end)
84                 end
85             elseif  moc_now.state ~= "PAUSE" then
86                 helpers.set_map("current moc track", nil)
87             end
88         end)
89     end
90
91     moc.timer = helpers.newtimer("moc", timeout, moc.update, true, true)
92
93     return moc
94 end
95
96 return factory