awesome-wm-widgets/spotify-widget/spotify.lua

162 lines
5.7 KiB
Lua
Raw Normal View History

2018-01-07 01:06:30 +01:00
-------------------------------------------------
-- Spotify Widget for Awesome Window Manager
-- Shows currently playing song on Spotify for Linux client
-- More details could be found here:
-- https://github.com/streetturtle/awesome-wm-widgets/tree/master/spotify-widget
-- @author Pavel Makhov
-- @copyright 2020 Pavel Makhov
2018-01-07 01:06:30 +01:00
-------------------------------------------------
2017-01-23 17:01:16 +01:00
local awful = require("awful")
2017-10-11 20:22:51 +02:00
local wibox = require("wibox")
2017-01-26 04:47:50 +01:00
local watch = require("awful.widget.watch")
2017-01-23 17:01:16 +01:00
local GET_SPOTIFY_STATUS_CMD = 'sp status'
local GET_CURRENT_SONG_CMD = 'sp current'
local function ellipsize(text, length)
-- utf8 only available in Lua 5.3+
if utf8 == nil then
return text:sub(0, length)
end
2021-10-08 16:21:35 +02:00
return (utf8.len(text) > length and length > 0)
and text:sub(0, utf8.offset(text, length - 2) - 1) .. '...'
or text
end
2017-01-23 17:01:16 +01:00
2019-05-04 02:28:50 +02:00
local spotify_widget = {}
2020-12-02 15:24:05 +01:00
local function worker(user_args)
2020-12-02 15:24:05 +01:00
local args = user_args or {}
2019-05-04 02:28:50 +02:00
local play_icon = args.play_icon or '/usr/share/icons/Arc/actions/24/player_play.png'
local pause_icon = args.pause_icon or '/usr/share/icons/Arc/actions/24/player_pause.png'
local font = args.font or 'Play 9'
local dim_when_paused = args.dim_when_paused == nil and false or args.dim_when_paused
local dim_opacity = args.dim_opacity or 0.2
local max_length = args.max_length or 15
2020-11-14 18:59:43 +01:00
local show_tooltip = args.show_tooltip == nil and true or args.show_tooltip
2020-09-19 10:08:15 +02:00
local timeout = args.timeout or 1
local cur_artist = ''
local cur_title = ''
local cur_album = ''
2019-05-04 02:28:50 +02:00
spotify_widget = wibox.widget {
{
id = 'artistw',
font = font,
widget = wibox.widget.textbox,
},
2019-05-04 02:28:50 +02:00
{
id = "icon",
widget = wibox.widget.imagebox,
},
{
2020-11-14 18:59:43 +01:00
layout = wibox.container.scroll.horizontal,
max_size = 100,
step_function = wibox.container.scroll.step_functions.waiting_nonlinear_back_and_forth,
speed = 40,
{
id = 'titlew',
font = font,
widget = wibox.widget.textbox
}
2019-05-04 02:28:50 +02:00
},
layout = wibox.layout.align.horizontal,
set_status = function(self, is_playing)
self.icon.image = (is_playing and play_icon or pause_icon)
if dim_when_paused then
2020-11-14 18:59:43 +01:00
self:get_children_by_id('icon')[1]:set_opacity(is_playing and 1 or dim_opacity)
2020-11-14 18:59:43 +01:00
self:get_children_by_id('titlew')[1]:set_opacity(is_playing and 1 or dim_opacity)
self:get_children_by_id('titlew')[1]:emit_signal('widget::redraw_needed')
2020-11-14 18:59:43 +01:00
self:get_children_by_id('artistw')[1]:set_opacity(is_playing and 1 or dim_opacity)
self:get_children_by_id('artistw')[1]:emit_signal('widget::redraw_needed')
end
2019-05-04 02:28:50 +02:00
end,
set_text = function(self, artist, song)
local artist_to_display = ellipsize(artist, max_length)
2020-11-14 18:59:43 +01:00
if self:get_children_by_id('artistw')[1]:get_markup() ~= artist_to_display then
self:get_children_by_id('artistw')[1]:set_markup(artist_to_display)
end
local title_to_display = ellipsize(song, max_length)
2020-11-14 18:59:43 +01:00
if self:get_children_by_id('titlew')[1]:get_markup() ~= title_to_display then
self:get_children_by_id('titlew')[1]:set_markup(title_to_display)
end
end
2019-05-04 02:28:50 +02:00
}
local update_widget_icon = function(widget, stdout, _, _, _)
stdout = string.gsub(stdout, "\n", "")
widget:set_status(stdout == 'Playing' and true or false)
end
2019-05-04 02:28:50 +02:00
local update_widget_text = function(widget, stdout, _, _, _)
if string.find(stdout, 'Error: Spotify is not running.') ~= nil then
widget:set_text('','')
2019-05-04 02:28:50 +02:00
widget:set_visible(false)
return
end
local escaped = string.gsub(stdout, "&", '&')
2020-12-02 15:24:05 +01:00
local album, _, artist, title =
string.match(escaped, 'Album%s*(.*)\nAlbumArtist%s*(.*)\nArtist%s*(.*)\nTitle%s*(.*)\n')
if album ~= nil and title ~=nil and artist ~= nil then
cur_artist = artist
cur_title = title
cur_album = album
widget:set_text(artist, title)
2019-05-04 02:28:50 +02:00
widget:set_visible(true)
end
end
2019-05-04 02:28:50 +02:00
2020-09-19 10:08:15 +02:00
watch(GET_SPOTIFY_STATUS_CMD, timeout, update_widget_icon, spotify_widget)
watch(GET_CURRENT_SONG_CMD, timeout, update_widget_text, spotify_widget)
2019-05-04 02:28:50 +02:00
--- Adds mouse controls to the widget:
-- - left click - play/pause
-- - scroll up - play next song
-- - scroll down - play previous song
spotify_widget:connect_signal("button::press", function(_, _, _, button)
if (button == 1) then
awful.spawn("sp play", false) -- left click
elseif (button == 4) then
awful.spawn("sp next", false) -- scroll up
elseif (button == 5) then
awful.spawn("sp prev", false) -- scroll down
end
awful.spawn.easy_async(GET_SPOTIFY_STATUS_CMD, function(stdout, stderr, exitreason, exitcode)
update_widget_icon(spotify_widget, stdout, stderr, exitreason, exitcode)
end)
end)
2018-01-07 01:06:30 +01:00
if show_tooltip then
local spotify_tooltip = awful.tooltip {
mode = 'outside',
preferred_positions = {'bottom'},
}
spotify_tooltip:add_to_object(spotify_widget)
spotify_widget:connect_signal('mouse::enter', function()
spotify_tooltip.markup = '<b>Album</b>: ' .. cur_album
.. '\n<b>Artist</b>: ' .. cur_artist
.. '\n<b>Song</b>: ' .. cur_title
end)
end
2019-05-04 02:28:50 +02:00
return spotify_widget
end
return setmetatable(spotify_widget, { __call = function(_, ...)
return worker(...)
end })