summaryrefslogtreecommitdiff
path: root/docker-widget/docker.lua
diff options
context:
space:
mode:
authorstreetturtle <streetturtle@gmail.com>2020-08-14 21:35:54 -0400
committerstreetturtle <streetturtle@gmail.com>2020-08-14 21:35:54 -0400
commit1310031b3a95f991cb7832b239d42e4b2225facf (patch)
tree77e8e8a4c119ca7b2dc16ea364e672c57e06d652 /docker-widget/docker.lua
parentaed5e8a2bfb9b16bbb7b6199817eada030362762 (diff)
[docker] new widget init commit
Diffstat (limited to 'docker-widget/docker.lua')
-rw-r--r--docker-widget/docker.lua229
1 files changed, 229 insertions, 0 deletions
diff --git a/docker-widget/docker.lua b/docker-widget/docker.lua
new file mode 100644
index 0000000..2f3aadb
--- /dev/null
+++ b/docker-widget/docker.lua
@@ -0,0 +1,229 @@
+-------------------------------------------------
+-- Docker Widget for Awesome Window Manager
+-- Lists containers and allows to manage them
+-- More details could be found here:
+-- https://github.com/streetturtle/awesome-wm-widgets/tree/master/docker-widget
+
+-- @author Pavel Makhov
+-- @copyright 2020 Pavel Makhov
+-------------------------------------------------
+
+local awful = require("awful")
+local wibox = require("wibox")
+local watch = require("awful.widget.watch")
+local spawn = require("awful.spawn")
+local naughty = require("naughty")
+local gears = require("gears")
+local beautiful = require("beautiful")
+local gfs = require("gears.filesystem")
+
+local HOME_DIR = os.getenv("HOME")
+local WIDGET_DIR = HOME_DIR .. '/.config/awesome/awesome-wm-widgets/docker-widget'
+local ICONS_DIR = WIDGET_DIR .. '/icons/'
+
+--- Utility function to show warning messages
+local function show_warning(message)
+ naughty.notify{
+ preset = naughty.config.presets.critical,
+ title = 'Docker Widget',
+ text = message}
+end
+
+local popup = awful.popup{
+ ontop = true,
+ visible = false,
+ shape = gears.shape.rounded_rect,
+ border_width = 1,
+ border_color = beautiful.bg_focus,
+ maximum_width = 400,
+ offset = { y = 5 },
+ widget = {}
+}
+
+local docker_widget = wibox.widget {
+ {
+ {
+ id = 'icon',
+ widget = wibox.widget.imagebox
+ },
+ id = "m",
+ margins = 4,
+ layout = wibox.container.margin
+ },
+ {
+ id = "txt",
+ widget = wibox.widget.textbox
+ },
+ layout = wibox.layout.fixed.horizontal,
+ set_icon = function(self, new_icon)
+ self.m.icon.image = new_icon
+ end,
+ set_text = function(self, new_value)
+ self.txt.text = new_value
+ end
+}
+
+local parse_container = function(line)
+ local name, id, image, status, how_long = line:match('(.*)::(.*)::(.*)::(%w*) (.*)')
+ local actual_status
+ if status == 'Up' and how_long:find('Paused') then actual_status = 'Paused'
+ else actual_status = status
+ end
+
+ local container = {
+ name = name,
+ id = id,
+ image = image,
+ status = actual_status,
+ how_long = how_long:gsub('%s?%(.*%)%s?', ''),
+ is_up = function() return status == 'Up' end,
+ is_paused = function() return how_long:find('Paused') end
+ }
+ return container
+end
+
+local status_to_icon_name = {
+ Up = '/usr/share/icons/Arc/actions/16/media-playback-start.png',
+ Exited = '/usr/share/icons/Arc/actions/16/media-playback-stop.png',
+ Paused = '/usr/share/icons/Arc/actions/16/media-playback-pause.png'
+}
+
+local function worker(args)
+
+ local args = args or {}
+
+ local icon = args.icon or ICONS_DIR .. 'docker.svg'
+
+ docker_widget:set_icon(icon)
+
+ local rows = {
+ { widget = wibox.widget.textbox },
+ layout = wibox.layout.fixed.vertical,
+ }
+
+ local function rebuild_widget(stdout, stderr, _, _)
+ if stderr ~= '' then
+ show_warning(stderr)
+ return
+ end
+
+ for i = 0, #rows do rows[i]=nil end
+
+ for line in stdout:gmatch("[^\r\n]+") do
+
+ local container = parse_container(line)
+ print(container:is_up())
+ local name, container_id, image, status, how_long = line:match('(.*)::(.*)::(.*)::(%w*) (.*)')
+
+ local is_visible
+ if status == 'Up' or 'Exited' then is_visible = true else is_visible = false end
+
+ local start_stop_button = wibox.widget {
+ image = container:is_up() and '/usr/share/icons/Arc/actions/16/media-playback-stop.png' or '/usr/share/icons/Arc/actions/16/media-playback-start.png',
+ visible = is_visible,
+ resize = false,
+ widget = wibox.widget.imagebox
+ }
+
+ local pause_unpause_button = wibox.widget {
+ image = container:is_up() and '/usr/share/icons/Arc/actions/16/media-playback-pause.png' or '/usr/share/icons/Arc/actions/16/media-skip-forward.png',
+ visible = container.is_up(),
+ resize = false,
+ widget = wibox.widget.imagebox
+ }
+
+ start_stop_button:buttons(
+ awful.util.table.join( awful.button({}, 1, function()
+ local command
+ if container:is_up() then command = 'stop' else command = 'start' end
+
+ awful.spawn.easy_async('docker ' .. command .. ' ' .. container['name'], function(stdout, stderr)
+ if stderr ~= '' then show_warning(stderr) return end
+ spawn.easy_async([[bash -c "docker container ls -a --format '{{.Names}}::{{.ID}}::{{.Image}}::{{.Status}}'"]], function(stdout, stderr)
+ rebuild_widget(stdout, stderr) end)
+ end)
+ end) ) )
+
+ pause_unpause_button:buttons(
+ awful.util.table.join( awful.button({}, 1, function()
+ local command
+ if container:is_paused() then command = 'unpause' else command = 'pause' end
+
+ awful.spawn.easy_async('docker ' .. command .. ' ' .. container['name'], function(stdout, stderr)
+ if stderr ~= '' then show_warning(stderr) return end
+ spawn.easy_async([[bash -c "docker container ls -a --format '{{.Names}}::{{.ID}}::{{.Image}}::{{.Status}}'"]], function(stdout, stderr)
+ rebuild_widget(stdout, stderr) end)
+ end)
+ end) ) )
+
+ local row = wibox.widget {
+ {
+ {
+ {
+ {
+ image = status_to_icon_name[container['status']],
+ resize = false,
+ widget = wibox.widget.imagebox
+ },
+ margins = 8,
+ layout = wibox.container.margin
+ },
+ {
+ {
+ text = container['name'],
+ widget = wibox.widget.textbox
+ },
+ {
+ text = container['how_long'],
+ widget = wibox.widget.textbox
+ },
+ forced_width = 160,
+ layout = wibox.layout.fixed.vertical
+ },
+ {
+ {
+ start_stop_button,
+ pause_unpause_button,
+ layout = wibox.layout.align.horizontal
+ },
+ forced_width = 40,
+ valign = 'center',
+ haligh = 'center',
+ layout = wibox.container.place,
+ },
+ spacing = 8,
+ layout = wibox.layout.align.horizontal
+ },
+ margins = 8,
+ layout = wibox.container.margin
+ },
+ bg = beautiful.bg_normal,
+ widget = wibox.container.background
+ }
+
+ row:connect_signal("mouse::enter", function(c) c:set_bg(beautiful.bg_focus) end)
+ row:connect_signal("mouse::leave", function(c) c:set_bg(beautiful.bg_normal) end)
+
+ table.insert(rows, row)
+ end
+
+ popup:setup(rows)
+ end
+
+ docker_widget:buttons(
+ awful.util.table.join(
+ awful.button({}, 1, function()
+ if popup.visible then
+ popup.visible = not popup.visible
+ else
+ spawn.easy_async([[bash -c "docker container ls -a --format '{{.Names}}::{{.ID}}::{{.Image}}::{{.Status}}'"]], function(stdout, stderr) rebuild_widget(stdout, stderr) end)
+ popup:move_next_to(mouse.current_widget_geometry)
+ end
+ end)
+ )
+ )
+
+ return docker_widget
+end
+
+return setmetatable(docker_widget, { __call = function(_, ...) return worker(...) end })