mirror of https://github.com/lcpz/lain.git
totally reworked widgets
This commit is contained in:
parent
04138e56b6
commit
eb8cec907a
|
@ -10,7 +10,7 @@ Layouts, widgets and utilities for Awesome WM
|
|||
:License: GNU-GPLv2_
|
||||
:Source: https://github.com/copycat-killer/lain
|
||||
|
||||
Based on a port of awesome-vain_, this costantly evolving module provides new layouts, a set of widgets and utility functions in order to improve Awesome usability and
|
||||
Successor of awesome-vain_, this costantly evolving module provides new layouts, a set of widgets and utility functions in order to improve Awesome usability and
|
||||
configurability.
|
||||
|
||||
Read the wiki_ for all the info.
|
||||
|
|
46
helpers.lua
46
helpers.lua
|
@ -4,14 +4,12 @@
|
|||
Licensed under GNU General Public License v2
|
||||
* (c) 2013, Luke Bonham
|
||||
* (c) 2010-2012, Peter Hofmann
|
||||
* (c) 2010, Adrian C. <anrxc@sysphere.org>
|
||||
|
||||
--]]
|
||||
|
||||
local awful = require("awful")
|
||||
local debug = require("debug")
|
||||
local pairs = pairs
|
||||
local rawget = rawget
|
||||
local io = { open = io.open }
|
||||
|
||||
-- Lain helper functions for internal use
|
||||
-- lain.helpers
|
||||
|
@ -30,33 +28,6 @@ end
|
|||
|
||||
-- }}}
|
||||
|
||||
-- {{{
|
||||
-- If lain.terminal is a string, e.g. "xterm", then "xterm -e " .. cmd is
|
||||
-- run. But if lain.terminal is a function, then terminal(cmd) is run.
|
||||
|
||||
function helpers.run_in_terminal(cmd)
|
||||
if type(terminal) == "function"
|
||||
then
|
||||
terminal(cmd)
|
||||
elseif type(terminal) == "string"
|
||||
then
|
||||
awful.util.spawn(terminal .. ' -e ' .. cmd)
|
||||
end
|
||||
end
|
||||
|
||||
-- }}}
|
||||
|
||||
-- {{{ Format units to one decimal point
|
||||
|
||||
function helpers.uformat(array, key, value, unit)
|
||||
for u, v in pairs(unit) do
|
||||
array["{"..key.."_"..u.."}"] = string.format("%.1f", value/v)
|
||||
end
|
||||
return array
|
||||
end
|
||||
|
||||
-- }}}
|
||||
|
||||
-- {{{ Read the first line of a file or return nil.
|
||||
|
||||
function helpers.first_line(f)
|
||||
|
@ -73,6 +44,21 @@ end
|
|||
|
||||
-- }}}
|
||||
|
||||
-- {{{ Timer maker
|
||||
|
||||
helpers.timer_table = {}
|
||||
|
||||
function helpers.newtimer(name, timeout, fun, nostart)
|
||||
helpers.timer_table[name] = timer({ timeout = timeout })
|
||||
helpers.timer_table[name]:connect_signal("timeout", fun)
|
||||
helpers.timer_table[name]:start()
|
||||
if not nostart then
|
||||
helpers.timer_table[name]:emit_signal("timeout")
|
||||
end
|
||||
end
|
||||
|
||||
-- }}}
|
||||
|
||||
-- {{{ A map utility
|
||||
|
||||
helpers.map_table = {}
|
||||
|
|
103
widgets/alsa.lua
103
widgets/alsa.lua
|
@ -2,102 +2,65 @@
|
|||
--[[
|
||||
|
||||
Licensed under GNU General Public License v2
|
||||
* (c) 2013, Luke Bonham
|
||||
* (c) 2010-2012, Peter Hofmann
|
||||
* (c) 2010, Adrian C. <anrxc@sysphere.org>
|
||||
* (c) 2013, Luke Bonham
|
||||
* (c) 2010, Adrian C. <anrxc@sysphere.org>
|
||||
|
||||
--]]
|
||||
|
||||
local markup = require("lain.util.markup")
|
||||
local run_in_terminal = require("lain.helpers").run_in_terminal
|
||||
local newtimer = require("lain.helpers").newtimer
|
||||
|
||||
local awful = require("awful")
|
||||
local beautiful = require("beautiful")
|
||||
local wibox = require("wibox")
|
||||
|
||||
local io = io
|
||||
local string = { format = string.format,
|
||||
match = string.match }
|
||||
local io = { popen = io.popen }
|
||||
local string = { match = string.match }
|
||||
|
||||
local setmetatable = setmetatable
|
||||
|
||||
-- ALSA volume infos
|
||||
-- nain.widgets.alsa
|
||||
local alsa = {
|
||||
volume = 0,
|
||||
mute = false,
|
||||
}
|
||||
-- ALSA volume
|
||||
-- lain.widgets.alsa
|
||||
local alsa = {}
|
||||
|
||||
function worker(args)
|
||||
local args = args or {}
|
||||
local channel = args.channel or "Master"
|
||||
local step = args.step or "1%"
|
||||
local header = args.header or " Vol "
|
||||
local header_color = args.header_color or beautiful.fg_normal or "#FFFFFF"
|
||||
local color = args.color or beautiful.fg_focus or "#FFFFFF"
|
||||
local function worker(args)
|
||||
local args = args or {}
|
||||
local timeout = args.timeout or 5
|
||||
local channel = args.channel or "Master"
|
||||
local settings = args.settings or function() end
|
||||
|
||||
local myvolume = wibox.widget.textbox()
|
||||
local myvolumeupdate = function()
|
||||
widget = wibox.widget.textbox('')
|
||||
|
||||
function update()
|
||||
local f = io.popen('amixer get ' .. channel)
|
||||
local mixer = f:read("*all")
|
||||
f:close()
|
||||
|
||||
local volume, mute = string.match(mixer, "([%d]+)%%.*%[([%l]*)")
|
||||
volume = {}
|
||||
|
||||
if volume == nil
|
||||
volume.level, volume.status = string.match(mixer, "([%d]+)%%.*%[([%l]*)")
|
||||
|
||||
if volume.level == nil
|
||||
then
|
||||
alsa.volume = 0
|
||||
else
|
||||
alsa.volume = volume
|
||||
volume.level = 0
|
||||
volume.status = "off"
|
||||
end
|
||||
|
||||
if mute == nil or mute == 'on'
|
||||
if volume.status == ""
|
||||
then
|
||||
alsa.mute = true
|
||||
mute = ''
|
||||
else
|
||||
alsa.mute = false
|
||||
mute = 'M'
|
||||
if volume.level == 0
|
||||
then
|
||||
volume.status = "off"
|
||||
else
|
||||
volume.status = "on"
|
||||
end
|
||||
end
|
||||
|
||||
local ret = markup(color, string.format("%d%s", volume, mute))
|
||||
myvolume:set_markup(markup(header_color, header) .. ret .. " ")
|
||||
settings()
|
||||
end
|
||||
|
||||
local myvolumetimer = timer({ timeout = 5 })
|
||||
myvolumetimer:connect_signal("timeout", myvolumeupdate)
|
||||
myvolumetimer:start()
|
||||
myvolumetimer:emit_signal("timeout")
|
||||
newtimer("alsa", timeout, update)
|
||||
|
||||
myvolume:buttons(awful.util.table.join(
|
||||
awful.button({}, 1,
|
||||
function()
|
||||
run_in_terminal('alsamixer')
|
||||
end),
|
||||
awful.button({}, 3,
|
||||
function()
|
||||
awful.util.spawn('amixer sset ' .. channel ' toggle')
|
||||
end),
|
||||
output = { widget = widget, notify = update }
|
||||
|
||||
awful.button({}, 4,
|
||||
function()
|
||||
awful.util.spawn('amixer sset ' .. channel .. ' ' .. step '+')
|
||||
myvolumeupdate()
|
||||
end),
|
||||
|
||||
awful.button({}, 5,
|
||||
function()
|
||||
awful.util.spawn('amixer sset ' .. channel .. ' ' .. step '-')
|
||||
myvolumeupdate()
|
||||
end)
|
||||
))
|
||||
|
||||
alsa.widget = myvolume
|
||||
alsa.channel = channel
|
||||
alsa.step = step
|
||||
alsa.notify = myvolumeupdate
|
||||
|
||||
return setmetatable(alsa, { __index = alsa.widget })
|
||||
return setmetatable(output, { __index = output.widget })
|
||||
end
|
||||
|
||||
return setmetatable(alsa, { __call = function(_, ...) return worker(...) end })
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
* (c) 2013, Rman
|
||||
--]]
|
||||
|
||||
local newtimer = require("lain.helpers").newtimer
|
||||
|
||||
local awful = require("awful")
|
||||
local beautiful = require("beautiful")
|
||||
local naughty = require("naughty")
|
||||
|
@ -32,12 +34,14 @@ local alsabar =
|
|||
unmute = "#A4CE8A"
|
||||
},
|
||||
|
||||
terminal = terminal or "xterm",
|
||||
mixer = terminal .. " -e alsamixer",
|
||||
|
||||
notifications =
|
||||
{
|
||||
font = beautiful.font:sub(beautiful.font:find(""), beautiful.font:find(" ")),
|
||||
font_size = "11",
|
||||
color = beautiful.fg_focus,
|
||||
bar_size = 18 -- Awesome default
|
||||
},
|
||||
|
||||
|
@ -49,9 +53,9 @@ function alsabar:notify()
|
|||
local preset =
|
||||
{
|
||||
title = "", text = "",
|
||||
timeout = 3,
|
||||
timeout = 15,
|
||||
font = alsabar.notifications.font .. " " .. alsabar.notifications.font_size,
|
||||
fg = beautiful.fg_focus
|
||||
fg = alsabar.notifications.color
|
||||
}
|
||||
|
||||
if alsabar._muted then
|
||||
|
@ -72,7 +76,7 @@ function alsabar:notify()
|
|||
end
|
||||
end
|
||||
|
||||
function worker(args)
|
||||
local function worker(args)
|
||||
local args = args or {}
|
||||
local width = args.width or 63
|
||||
local height = args.heigth or 1
|
||||
|
@ -85,6 +89,7 @@ function worker(args)
|
|||
alsabar.notifications = args.notifications or alsabar.notifications
|
||||
|
||||
alsabar.bar = awful.widget.progressbar()
|
||||
|
||||
alsabar.bar:set_background_color(alsabar.colors.background)
|
||||
alsabar.bar:set_color(alsabar.colors.unmute)
|
||||
alsabar.tooltip = awful.tooltip({ objects = { alsabar.bar } })
|
||||
|
@ -97,18 +102,18 @@ function worker(args)
|
|||
alsabar.bar:set_vertical(true)
|
||||
end
|
||||
|
||||
local myvolumebarupdate = function()
|
||||
function update()
|
||||
-- Get mixer control contents
|
||||
local f = io.popen("amixer get " .. alsabar.channel)
|
||||
local mixer = f:read("*all")
|
||||
f:close()
|
||||
|
||||
-- Capture mixer control state: [5%] ... ... [on]
|
||||
local volu, mute = string.match(mixer, "([%d]+)%%.*%[([%l]*)")
|
||||
-- Handle mixers without data
|
||||
local volu, mute = string.match(mixer, "([%d]+)%%.*%[([%l]*)")
|
||||
|
||||
if volu == nil then
|
||||
volu = 0
|
||||
mute = "off"
|
||||
volu = 0
|
||||
mute = "off"
|
||||
end
|
||||
|
||||
alsabar._current_level = tonumber(volu) / 100
|
||||
|
@ -126,10 +131,7 @@ function worker(args)
|
|||
end
|
||||
end
|
||||
|
||||
local myvolumebartimer = timer({ timeout = 5 })
|
||||
myvolumebartimer:connect_signal("timeout", myvolumebarupdate)
|
||||
myvolumebartimer:start()
|
||||
myvolumebartimer:emit_signal("timeout")
|
||||
newtimer("alsabar", 5, update)
|
||||
|
||||
alsabar.bar:buttons (awful.util.table.join (
|
||||
awful.button ({}, 1, function()
|
||||
|
@ -151,14 +153,15 @@ function worker(args)
|
|||
end)
|
||||
))
|
||||
|
||||
return { widget = alsabar.bar,
|
||||
channel = alsabar.channel,
|
||||
step = alsabar.step,
|
||||
notify = function()
|
||||
myvolumebarupdate()
|
||||
alsabar.notify()
|
||||
end
|
||||
}
|
||||
return {
|
||||
widget = alsabar.bar,
|
||||
channel = alsabar.channel,
|
||||
step = alsabar.step,
|
||||
notify = function()
|
||||
update()
|
||||
alsabar.notify()
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
return setmetatable(alsabar, { __call = function(_, ...) return worker(...) end })
|
||||
|
|
102
widgets/bat.lua
102
widgets/bat.lua
|
@ -7,10 +7,9 @@
|
|||
|
||||
--]]
|
||||
|
||||
local markup = require("lain.util.markup")
|
||||
local newtimer = require("lain.helpers").newtimer
|
||||
local first_line = require("lain.helpers").first_line
|
||||
|
||||
local beautiful = require("beautiful")
|
||||
local naughty = require("naughty")
|
||||
local wibox = require("wibox")
|
||||
|
||||
|
@ -21,25 +20,24 @@ local setmetatable = setmetatable
|
|||
|
||||
-- Battery infos
|
||||
-- lain.widgets.bat
|
||||
local bat = {
|
||||
status = "not present",
|
||||
perc = "N/A",
|
||||
time = "N/A",
|
||||
}
|
||||
local bat = { id = nil }
|
||||
|
||||
function worker(args)
|
||||
local function worker(args)
|
||||
local args = args or {}
|
||||
local timeout = args.timeout or 30
|
||||
local battery = args.battery or "BAT0"
|
||||
local show_all = args.show_all or false
|
||||
local refresh_timeout = args.refresh_timeout or 30
|
||||
local header = args.header or " Bat "
|
||||
local header_color = args.header_color or beautiful.fg_normal or "#FFFFFF"
|
||||
local color = args.color or beautiful.fg_focus or "#FFFFFF"
|
||||
local shadow = args.shadow or false
|
||||
local settings = args.settings or function() end
|
||||
|
||||
local mybattery = wibox.widget.textbox()
|
||||
bat_now = {
|
||||
status = "not present",
|
||||
perc = "N/A",
|
||||
time = "N/A",
|
||||
watt = "N/A"
|
||||
}
|
||||
|
||||
local mybatteryupdate = function()
|
||||
widget = wibox.widget.textbox('')
|
||||
|
||||
function update()
|
||||
local present = first_line("/sys/class/power_supply/"
|
||||
.. battery
|
||||
.. "/present")
|
||||
|
@ -58,90 +56,62 @@ function worker(args)
|
|||
local tot = first_line("/sys/class/power_supply/"
|
||||
.. battery ..
|
||||
"/energy_full")
|
||||
bat.status = first_line("/sys/class/power_supply/"
|
||||
bat_now.status = first_line("/sys/class/power_supply/"
|
||||
.. battery ..
|
||||
"/status")
|
||||
|
||||
local time_rat = 0
|
||||
if bat.status == "Charging"
|
||||
if bat_now.status == "Charging"
|
||||
then
|
||||
status = "(+)"
|
||||
time_rat = (tot - rem) / rate
|
||||
elseif bat.status == "Discharging"
|
||||
elseif bat_now.status == "Discharging"
|
||||
then
|
||||
status = "(-)"
|
||||
time_rat = rem / rate
|
||||
else
|
||||
status = "(.)"
|
||||
end
|
||||
|
||||
local hrs = math.floor(time_rat)
|
||||
local min = (time_rat - hrs) * 60
|
||||
bat.time = string.format("%02d:%02d", hrs, min)
|
||||
|
||||
local amount = (rem / tot) * 100
|
||||
|
||||
if shadow
|
||||
then
|
||||
bat.perc = string.format("%d", amount)
|
||||
else
|
||||
bat.perc = string.format("%d%%", amount)
|
||||
end
|
||||
|
||||
local watt = string.format("%.2fW", (rate * ratev) / 1e12)
|
||||
|
||||
if show_all
|
||||
then
|
||||
text = watt .. " " .. bat.perc .. " " .. bat.time .. " " .. bat.status
|
||||
else
|
||||
text = bat.perc
|
||||
end
|
||||
bat_now.time = string.format("%02d:%02d", hrs, min)
|
||||
bat_now.perc = (rem / tot) * 100
|
||||
bat_now.watt = string.format("%.2fW", (rate * ratev) / 1e12)
|
||||
|
||||
-- notifications for low and critical states
|
||||
if amount <= 5
|
||||
if bat_now.perc <= 5
|
||||
then
|
||||
naughty.notify{
|
||||
bat.id = naughty.notify({
|
||||
text = "shutdown imminent",
|
||||
title = "battery nearly exhausted",
|
||||
position = "top_right",
|
||||
timeout = 15,
|
||||
fg="#000000",
|
||||
bg="#ffffff",
|
||||
ontop = true
|
||||
}
|
||||
elseif amount <= 15
|
||||
ontop = true,
|
||||
replaces_id = bat.id
|
||||
}).id
|
||||
elseif bat.perc <= 15
|
||||
then
|
||||
old_id = naughty.notify{
|
||||
bat.id = naughty.notify({
|
||||
text = "plug the cable",
|
||||
title = "battery low",
|
||||
position = "top_right",
|
||||
timeout = 5,
|
||||
timeout = 15,
|
||||
fg="#202020",
|
||||
bg="#cdcdcd",
|
||||
ontop = true
|
||||
}
|
||||
ontop = true,
|
||||
replaces_id = bat.id
|
||||
}).id
|
||||
end
|
||||
else
|
||||
text = "none"
|
||||
|
||||
bat_now.perc = string.format("%d", bat_now.perc)
|
||||
end
|
||||
|
||||
if shadow
|
||||
then
|
||||
mybattery:set_text('')
|
||||
else
|
||||
mybattery:set_markup(markup(header_color, header)
|
||||
.. markup(color, text) .. " ")
|
||||
end
|
||||
settings()
|
||||
end
|
||||
|
||||
local mybatterytimer = timer({ timeout = refresh_timeout })
|
||||
mybatterytimer:connect_signal("timeout", mybatteryupdate)
|
||||
mybatterytimer:start()
|
||||
mybatterytimer:emit_signal("timeout")
|
||||
newtimer("bat", timeout, update)
|
||||
|
||||
bat.widget = mybattery
|
||||
|
||||
return setmetatable(bat, { __index = bat.widget })
|
||||
return widget
|
||||
end
|
||||
|
||||
return setmetatable(bat, { __call = function(_, ...) return worker(...) end })
|
||||
|
|
|
@ -13,7 +13,7 @@ local beautiful = require("beautiful")
|
|||
local naughty = require("naughty")
|
||||
|
||||
local io = io
|
||||
local os = { date = os.date }
|
||||
local os = { date = os.date }
|
||||
local tonumber = tonumber
|
||||
|
||||
local setmetatable = setmetatable
|
||||
|
@ -23,15 +23,6 @@ local setmetatable = setmetatable
|
|||
local calendar = {}
|
||||
local notification = nil
|
||||
|
||||
local function create(foreground, background)
|
||||
calendar.offset = 0
|
||||
calendar.icons_dir = icons_dir .. "cal/white/" -- default
|
||||
calendar.notify_icon = nil
|
||||
calendar.font_size = 12
|
||||
calendar.bg = background or beautiful.bg_normal or "#FFFFFF"
|
||||
calendar.fg = foreground or beautiful.fg_focus or "#FFFFFF"
|
||||
end
|
||||
|
||||
function calendar:hide()
|
||||
if notification ~= nil then
|
||||
naughty.destroy(notification)
|
||||
|
@ -59,7 +50,7 @@ function calendar:show(t_out, inc_offset)
|
|||
end
|
||||
|
||||
calendar.offset = 0
|
||||
calendar.notify_icon = calendar.icons_dir .. today .. ".png"
|
||||
calendar.notify_icon = calendar.icons .. today .. ".png"
|
||||
|
||||
-- bg and fg inverted to highlight today
|
||||
f = io.popen( init_t .. today ..
|
||||
|
@ -106,13 +97,23 @@ function calendar:show(t_out, inc_offset)
|
|||
|
||||
notification = naughty.notify({ text = c_text,
|
||||
icon = calendar.notify_icon,
|
||||
position = calendar.position,
|
||||
fg = calendar.fg,
|
||||
bg = calendar.bg,
|
||||
timeout = tims })
|
||||
end
|
||||
|
||||
function calendar:attach(widget, foreground, background)
|
||||
create(foreground, background)
|
||||
function calendar:attach(widget, args)
|
||||
local args = args or {}
|
||||
calendar.icons = args.icons or icons_dir .. "cal/white/"
|
||||
calendar.font_size = tonumber(args.font_size) or 12
|
||||
calendar.fg = args.fg or beautiful.fg_normal or "#FFFFFF"
|
||||
calendar.bg = args.bg or beautiful.bg_normal or "#FFFFFF"
|
||||
calendar.position = args.position or "top_right"
|
||||
|
||||
calendar.offset = 0
|
||||
calendar.notify_icon = nil
|
||||
|
||||
widget:connect_signal("mouse::enter", function () calendar:show() end)
|
||||
widget:connect_signal("mouse::leave", function () calendar:hide() end)
|
||||
widget:buttons(awful.util.table.join( awful.button({ }, 1, function ()
|
||||
|
|
|
@ -7,15 +7,15 @@
|
|||
|
||||
--]]
|
||||
|
||||
local markup = require("lain.util.markup")
|
||||
local first_line = require("lain.helpers").first_line
|
||||
local newtimer = require("lain.helpers").newtimer
|
||||
|
||||
local beautiful = require("beautiful")
|
||||
local wibox = require("wibox")
|
||||
|
||||
local math = { ceil = math.ceil }
|
||||
local string = { format = string.format,
|
||||
gmatch = string.gmatch }
|
||||
local tostring = tostring
|
||||
|
||||
local setmetatable = setmetatable
|
||||
|
||||
|
@ -26,17 +26,14 @@ local cpu = {
|
|||
last_active = 0
|
||||
}
|
||||
|
||||
function worker(args)
|
||||
local args = args or {}
|
||||
local refresh_timeout = args.refresh_timeout or 5
|
||||
local header = args.header or " Cpu "
|
||||
local header_color = args.header or beautiful.fg_normal or "#FFFFFF"
|
||||
local color = args.color or beautiful.fg_focus or "#FFFFFF"
|
||||
local footer = args.footer or "% "
|
||||
local function worker(args)
|
||||
local args = args or {}
|
||||
local timeout = args.timeout or 5
|
||||
local settings = args.settings or function() end
|
||||
|
||||
local w = wibox.widget.textbox()
|
||||
widget = wibox.widget.textbox('')
|
||||
|
||||
local cpuusageupdate = function()
|
||||
function update()
|
||||
-- Read the amount of time the CPUs have spent performing
|
||||
-- different kinds of work. Read the first line of /proc/stat
|
||||
-- which is the sum of all CPUs.
|
||||
|
@ -60,21 +57,19 @@ function worker(args)
|
|||
-- Read current data and calculate relative values.
|
||||
local dactive = active - cpu.last_active
|
||||
local dtotal = total - cpu.last_total
|
||||
local dta = math.ceil((dactive / dtotal) * 100)
|
||||
|
||||
w:set_markup(markup(header_color, header) .. markup(color, dta .. footer))
|
||||
usage = tostring(math.ceil((dactive / dtotal) * 100))
|
||||
|
||||
settings()
|
||||
|
||||
-- Save current data for the next run.
|
||||
cpu.last_active = active
|
||||
cpu.last_total = total
|
||||
end
|
||||
|
||||
local cpuusagetimer = timer({ timeout = refresh_timeout })
|
||||
cpuusagetimer:connect_signal("timeout", cpuusageupdate)
|
||||
cpuusagetimer:start()
|
||||
cpuusagetimer:emit_signal("timeout")
|
||||
newtimer("cpu", timeout, update)
|
||||
|
||||
return w
|
||||
return widget
|
||||
end
|
||||
|
||||
return setmetatable(cpu, { __call = function(_, ...) return worker(...) end })
|
||||
|
|
102
widgets/fs.lua
102
widgets/fs.lua
|
@ -8,7 +8,6 @@
|
|||
|
||||
--]]
|
||||
|
||||
local markup = require("lain.util.markup")
|
||||
local helpers = require("lain.helpers")
|
||||
|
||||
local beautiful = require("beautiful")
|
||||
|
@ -16,14 +15,16 @@ local wibox = require("wibox")
|
|||
local naughty = require("naughty")
|
||||
|
||||
local io = io
|
||||
local string = { match = string.match }
|
||||
local pairs = pairs
|
||||
local string = { match = string.match,
|
||||
format = string.format }
|
||||
local tonumber = tonumber
|
||||
|
||||
local setmetatable = setmetatable
|
||||
|
||||
-- File system disk space usage
|
||||
-- lain.widgets.fs
|
||||
local fs = {}
|
||||
local fs = { notification_preset = {} }
|
||||
local notification = nil
|
||||
|
||||
function fs:hide()
|
||||
|
@ -41,38 +42,29 @@ function fs:show(t_out)
|
|||
f:close()
|
||||
|
||||
notification = naughty.notify({
|
||||
preset = fs.notification_preset,
|
||||
text = ws,
|
||||
timeout = t_out,
|
||||
fg = fs.color,
|
||||
timeout = t_out
|
||||
})
|
||||
end
|
||||
|
||||
-- Variable definitions
|
||||
-- Units definitions
|
||||
local unit = { ["mb"] = 1024, ["gb"] = 1024^2 }
|
||||
|
||||
local function worker(args)
|
||||
local args = args or {}
|
||||
local args = args or {}
|
||||
local partition = args.partition or "/"
|
||||
local refresh_timeout = args.refresh_timeout or 600
|
||||
local header = args.header or " Hdd "
|
||||
local header_color = args.header_color or beautiful.fg_normal or "#FFFFFF"
|
||||
fs.color = args.color or beautiful.fg_focus or "#FFFFFF"
|
||||
local footer = args.footer or " "
|
||||
local shadow = args.shadow or false
|
||||
local timeout = args.timeout or 600
|
||||
local settings = args.settings or function() end
|
||||
|
||||
local myfs = wibox.widget.textbox()
|
||||
widget = wibox.widget.textbox('')
|
||||
|
||||
helpers.set_map("fs", false)
|
||||
|
||||
local fsupdate = function()
|
||||
local fs_info = {} -- Get data from df
|
||||
local f = io.popen("LC_ALL=C df -kP")
|
||||
function update()
|
||||
fs_info = {}
|
||||
|
||||
local function set_text()
|
||||
local info = fs_info['{' .. partition .. ' used_p}']
|
||||
myfs:set_markup(markup(header_color, header)
|
||||
.. markup(fs.color, info .. footer))
|
||||
end
|
||||
local f = io.popen("LC_ALL=C df -kP")
|
||||
|
||||
for line in f:lines() do -- Match: (size) (used)(avail)(use%) (mount)
|
||||
local s = string.match(line, "^.-[%s]([%d]+)")
|
||||
|
@ -80,55 +72,57 @@ local function worker(args)
|
|||
local m = string.match(line, "%%[%s]([%p%w]+)")
|
||||
|
||||
if u and m then -- Handle 1st line and broken regexp
|
||||
helpers.uformat(fs_info, m .. " used", u, unit)
|
||||
fs_info["{" .. m .. " used_p}"] = tonumber(p)
|
||||
fs_info[m .. " size_mb"] = string.format("%.1f", tonumber(s) / unit["mb"])
|
||||
fs_info[m .. " size_gb"] = string.format("%.1f", tonumber(s) / unit["gb"])
|
||||
fs_info[m .. " used_p"] = tonumber(p)
|
||||
fs_info[m .. " avail_p"] = 100 - tonumber(p)
|
||||
end
|
||||
end
|
||||
|
||||
f:close()
|
||||
|
||||
if shadow
|
||||
-- chosen partition easy stuff
|
||||
-- you can however check whatever partition else
|
||||
used = fs_info[partition .. " used_p"]
|
||||
available = fs_info[partition .. " avail_p"]
|
||||
size_mb = fs_info[partition .. " size_mb"]
|
||||
size_gb = fs_info[partition .. " size_gb"]
|
||||
|
||||
notification_preset = { fg = beautiful.fg_normal }
|
||||
|
||||
settings()
|
||||
|
||||
fs.notification_preset = notification_preset
|
||||
|
||||
if used >= 99 and not helpers.get_map("fs")
|
||||
then
|
||||
myfs:set_text('')
|
||||
naughty.notify({
|
||||
title = "warning",
|
||||
text = partition .. " ran out!\nmake some room",
|
||||
timeout = 8,
|
||||
fg = "#000000",
|
||||
bg = "#FFFFFF"
|
||||
})
|
||||
helpers.set_map("fs", true)
|
||||
else
|
||||
set_text()
|
||||
end
|
||||
|
||||
local part = fs_info['{' .. partition .. ' used_p}']
|
||||
|
||||
if part >= 90 then
|
||||
if part >= 99 and not helpers.get_map("fs") then
|
||||
naughty.notify({ title = "warning",
|
||||
text = partition .. " ran out!\n"
|
||||
.. "make some room",
|
||||
timeout = 8,
|
||||
position = "top_right",
|
||||
fg = beautiful.fg_urgent,
|
||||
bg = beautiful.bg_urgent })
|
||||
helpers.set_map("fs", true)
|
||||
end
|
||||
if shadow then set_text() end
|
||||
helpers.set_map("fs", false)
|
||||
end
|
||||
end
|
||||
|
||||
local fstimer = timer({ timeout = refresh_timeout })
|
||||
fstimer:connect_signal("timeout", fsupdate)
|
||||
fstimer:start()
|
||||
fstimer:emit_signal("timeout")
|
||||
helpers.newtimer("fs " .. partition, timeout, update)
|
||||
|
||||
myfs:connect_signal('mouse::enter', function () fs:show(0) end)
|
||||
myfs:connect_signal('mouse::leave', function () fs:hide() end)
|
||||
widget:connect_signal('mouse::enter', function () fs:show(0) end)
|
||||
widget:connect_signal('mouse::leave', function () fs:hide() end)
|
||||
|
||||
local fs_out =
|
||||
{
|
||||
widget = myfs,
|
||||
output = {
|
||||
widget = widget,
|
||||
show = function(t_out)
|
||||
fsupdate()
|
||||
update()
|
||||
fs:show(t_out)
|
||||
end
|
||||
}
|
||||
|
||||
return setmetatable(fs_out, { __index = fs_out.widget })
|
||||
return setmetatable(output, { __index = output.widget })
|
||||
end
|
||||
|
||||
return setmetatable(fs, { __call = function(_, ...) return worker(...) end })
|
||||
|
|
170
widgets/imap.lua
170
widgets/imap.lua
|
@ -6,160 +6,126 @@
|
|||
|
||||
--]]
|
||||
|
||||
local markup = require("lain.util.markup")
|
||||
local helpers = require("lain.helpers")
|
||||
|
||||
local awful = require("awful")
|
||||
local beautiful = require("beautiful")
|
||||
local naughty = require("naughty")
|
||||
local wibox = require("wibox")
|
||||
|
||||
local io = io
|
||||
local io = { popen = io.popen }
|
||||
local tonumber = tonumber
|
||||
local string = string
|
||||
local string = { len = string.len,
|
||||
format = string.format }
|
||||
|
||||
local setmetatable = setmetatable
|
||||
|
||||
-- Mail imap check
|
||||
-- Mail IMAP check
|
||||
-- lain.widgets.imap
|
||||
local imap = {}
|
||||
local imap = { stored = nil }
|
||||
|
||||
function worker(args)
|
||||
local args = args or {}
|
||||
local args = args or {}
|
||||
|
||||
local server = args.server
|
||||
local mail = args.mail
|
||||
local server = args.server
|
||||
local mail = args.mail
|
||||
local password = args.password
|
||||
|
||||
local port = args.port or "993"
|
||||
local refresh_timeout = args.refresh_timeout or 60
|
||||
local header = args.header or "Mail "
|
||||
local header_color = args.header_color or beautiful.fg_normal or "#FFFFFF"
|
||||
local color = args.color or beautiful.fg_focus or "#FFFFFF"
|
||||
local mail_encoding = args.mail_encoding or nil
|
||||
local maxlen = args.maxlen or 200
|
||||
local app = args.app or "mutt"
|
||||
local port = args.port or "993"
|
||||
local timeout = args.timeout or 60
|
||||
local encoding = args.encoding or nil
|
||||
local maxlen = args.maxlen or 200
|
||||
local is_plain = args.is_plain or false
|
||||
local shadow = args.shadow or false
|
||||
local settings = args.settings or function() end
|
||||
|
||||
local checkmail = helpers.scripts_dir .. "checkmail"
|
||||
|
||||
helpers.set_map(mail, true)
|
||||
helpers.set_map(mail .. " count", "0")
|
||||
|
||||
local checkmail = helpers.scripts_dir .. "checkmail"
|
||||
|
||||
if not is_plain
|
||||
then
|
||||
local f = io.popen(password)
|
||||
password = f:read("*all"):gsub("\n", ""):gsub("\r", "")
|
||||
f:close()
|
||||
if not imap.stored
|
||||
then
|
||||
local f = io.popen(password)
|
||||
password = f:read("*all"):gsub("\n", ""):gsub("\r", "")
|
||||
f:close()
|
||||
imap.stored = password
|
||||
else
|
||||
password = imap.stored
|
||||
end
|
||||
end
|
||||
|
||||
local myimapcheck = wibox.widget.textbox()
|
||||
widget = wibox.widget.textbox('')
|
||||
|
||||
local myimapcheckupdate = function()
|
||||
function set_nomail()
|
||||
if shadow
|
||||
then
|
||||
myimapcheck:set_text('')
|
||||
else
|
||||
myimapcheck:set_markup(markup(color, " no mail "))
|
||||
end
|
||||
end
|
||||
function update()
|
||||
to_execute = string.format("%s -s %s -u %s -p %s --port %s",
|
||||
checkmail, server, mail, password, port)
|
||||
|
||||
conn = io.popen("ip link show")
|
||||
check_conn = conn:read("*all")
|
||||
conn:close()
|
||||
|
||||
if not check_conn:find("state UP") then
|
||||
set_nomail()
|
||||
return
|
||||
end
|
||||
|
||||
to_execute = checkmail .. ' -s ' .. server ..
|
||||
' -u ' .. mail .. ' -p ' .. password
|
||||
.. ' --port ' .. port
|
||||
|
||||
if mail_encoding ~= nil
|
||||
if encoding ~= nil
|
||||
then
|
||||
to_execute = to_execute .. ' --encoding '
|
||||
.. mail_encoding
|
||||
to_execute = string.format("%s --encoding %s",
|
||||
to_execute, encoding)
|
||||
end
|
||||
|
||||
f = io.popen(to_execute)
|
||||
ws = f:read("*all")
|
||||
f:close()
|
||||
|
||||
mailcount = "0"
|
||||
|
||||
if ws:find("No new messages") ~= nil
|
||||
then
|
||||
helpers.set_map(mail, true)
|
||||
set_nomail()
|
||||
elseif ws:find("CheckMailError: invalid credentials") ~= nil
|
||||
then
|
||||
helpers.set_map(mail, true)
|
||||
myimapcheck:set_markup(" " .. markup(header_color, header) ..
|
||||
markup(color, "invalid credentials "))
|
||||
mailcount = "invalid credentials"
|
||||
else
|
||||
mailcount = ws:match("%d") or "?"
|
||||
|
||||
if helpers.get_map(mail .. " count") ~= mailcount and mailcount ~= "?"
|
||||
mailcount = ws:match("%d") or "0"
|
||||
if helpers.get_map(mail .. " count") ~= mailcount and mailcount ~= "0"
|
||||
then
|
||||
helpers.set_map(mail, true)
|
||||
helpers.set_map(mail .. " count", mailcount)
|
||||
end
|
||||
end
|
||||
|
||||
myimapcheck:set_markup(" " .. markup(header_color, header) ..
|
||||
markup(color, mailcount) .. " ")
|
||||
notification_preset = {
|
||||
icon = helpers.icons_dir .. "mail.png",
|
||||
timeout = 8,
|
||||
position = "top_left"
|
||||
}
|
||||
|
||||
if helpers.get_map(mail)
|
||||
settings()
|
||||
|
||||
|
||||
if helpers.get_map(mail) and tonumber(mailcount) >= 1
|
||||
then
|
||||
notify_title = ws:match(mail .. " has %d new message.?")
|
||||
ws = ws:gsub(notify_title, "", 1):gsub("\n", "", 2)
|
||||
|
||||
-- trying to remove useless infos
|
||||
ws = ws:gsub("--Content.%S+.-\n", "")
|
||||
ws = ws:gsub("--%d+.-\n", "")
|
||||
|
||||
if string.len(ws) > maxlen
|
||||
then
|
||||
if mailcount == "?"
|
||||
-- May happens sometimes using keyrings or other password fetchers.
|
||||
-- Since this should be automatically fixed in short times, we threat
|
||||
-- this exception delaying the update to the next timeout.
|
||||
then
|
||||
set_nomail()
|
||||
return
|
||||
elseif tonumber(mailcount) >= 1
|
||||
then
|
||||
notify_title = ws:match(mail .. " has %d new message.?")
|
||||
ws = ws:gsub(notify_title, "", 1):gsub("\n", "", 2)
|
||||
|
||||
ws = ws:gsub("--Content.%S+.-\n", "")
|
||||
ws = ws:gsub("--%d+.-\n", "")
|
||||
|
||||
if string.len(ws) > maxlen
|
||||
then
|
||||
ws = ws:sub(1, maxlen) .. "[...]"
|
||||
end
|
||||
|
||||
notify_title = notify_title:gsub("\n", "")
|
||||
end
|
||||
|
||||
naughty.notify({ title = notify_title,
|
||||
fg = color,
|
||||
text = ws,
|
||||
icon = beautiful.lain_mail_notify or
|
||||
helpers.icons_dir .. "mail.png",
|
||||
timeout = 8,
|
||||
position = "top_left" })
|
||||
|
||||
helpers.set_map(mail, false)
|
||||
ws = ws:sub(1, maxlen) .. "[...]"
|
||||
end
|
||||
|
||||
notify_title = notify_title:gsub("\n", "")
|
||||
|
||||
naughty.notify({
|
||||
preset = notification_preset,
|
||||
title = notify_title,
|
||||
text = ws
|
||||
})
|
||||
|
||||
helpers.set_map(mail, false)
|
||||
end
|
||||
end
|
||||
|
||||
local myimapchecktimer = timer({ timeout = refresh_timeout })
|
||||
myimapchecktimer:connect_signal("timeout", myimapcheckupdate)
|
||||
myimapchecktimer:start()
|
||||
myimapcheck:buttons(awful.util.table.join(
|
||||
awful.button({}, 0,
|
||||
helpers.newtimer(mail, timeout, update, true)
|
||||
|
||||
function()
|
||||
helpers.run_in_terminal(app)
|
||||
end)
|
||||
))
|
||||
|
||||
return myimapcheck
|
||||
return widget
|
||||
end
|
||||
|
||||
return setmetatable(imap, { __call = function(_, ...) return worker(...) end })
|
||||
|
|
|
@ -15,10 +15,6 @@
|
|||
local wrequire = require("lain.helpers").wrequire
|
||||
local setmetatable = setmetatable
|
||||
|
||||
local widgets =
|
||||
{
|
||||
_NAME = "lain.widgets",
|
||||
terminal = "xterm" -- X default
|
||||
}
|
||||
local widgets = { _NAME = "lain.widgets" }
|
||||
|
||||
return setmetatable(widgets, { __index = wrequire })
|
||||
|
|
|
@ -7,11 +7,8 @@
|
|||
|
||||
--]]
|
||||
|
||||
local markup = require("lain.util.markup")
|
||||
local run_in_terminal = require("lain.helpers").run_in_terminal
|
||||
local newtimer = require("lain.helpers").newtimer
|
||||
|
||||
local awful = require("awful")
|
||||
local beautiful = require("beautiful")
|
||||
local wibox = require("wibox")
|
||||
|
||||
local io = io
|
||||
|
@ -28,25 +25,20 @@ local setmetatable = setmetatable
|
|||
local maildir = {}
|
||||
|
||||
function worker(args)
|
||||
local args = args or {}
|
||||
local mailpath = args.mailpath or os.getenv("HOME") .. "/Mail"
|
||||
local args = args or {}
|
||||
local timeout = args.timeout or 60
|
||||
local mailpath = args.mailpath or os.getenv("HOME") .. "/Mail"
|
||||
local ignore_boxes = args.ignore_boxes or {}
|
||||
local refresh_timeout = args.refresh_timeout or 60
|
||||
local header = args.header or " Mail "
|
||||
local header_color = args.header_color or beautiful.fg_normal or "#FFFFFF"
|
||||
local color_newmail = args.color_newmail or beautiful.fg_focus or "#FFFFFF"
|
||||
local color_nomail = args.color_nomail or beautiful.fg_normal or "#FFFFFF"
|
||||
local app = args.app or "mutt"
|
||||
local shadow = args.shadow or false
|
||||
local settings = args.settings or function() end
|
||||
|
||||
local mymailcheck = wibox.widget.textbox()
|
||||
local mymailcheckupdate = function()
|
||||
widget = wibox.widget.textbox('')
|
||||
|
||||
function update()
|
||||
-- Find pathes to mailboxes.
|
||||
local p = io.popen("find " .. mailpath ..
|
||||
" -mindepth 1 -maxdepth 1 -type d" ..
|
||||
" -not -name .git")
|
||||
local boxes = {}
|
||||
local line = ""
|
||||
repeat
|
||||
line = p:read("*l")
|
||||
if line ~= nil
|
||||
|
@ -73,7 +65,8 @@ function worker(args)
|
|||
|
||||
table.sort(boxes)
|
||||
|
||||
local newmail = ""
|
||||
newmail = "no mail"
|
||||
|
||||
local count = 0
|
||||
for box, number in pairs(boxes)
|
||||
do
|
||||
|
@ -91,39 +84,12 @@ function worker(args)
|
|||
end
|
||||
end
|
||||
|
||||
if count == 1 then
|
||||
-- it will be only executed once
|
||||
for box, number in pairs(boxes)
|
||||
do -- it's useless to show only INBOX(x)
|
||||
if box == "INBOX" then newmail = number end
|
||||
end
|
||||
end
|
||||
|
||||
if newmail == ""
|
||||
then
|
||||
if shadow
|
||||
then
|
||||
mymailcheck:set_text('')
|
||||
else
|
||||
myimapcheck:set_markup(markup(color_nomail, " no mail "))
|
||||
end
|
||||
else
|
||||
myimapcheck:set_markup(" " .. markup(header_color, header) ..
|
||||
markup(color_newmail, newmail) .. " ")
|
||||
end
|
||||
settings()
|
||||
end
|
||||
|
||||
local mymailchecktimer = timer({ timeout = refresh_timeout })
|
||||
mymailchecktimer:connect_signal("timeout", mymailcheckupdate)
|
||||
mymailchecktimer:start()
|
||||
mymailcheck:buttons(awful.util.table.join(
|
||||
awful.button({}, 0,
|
||||
function()
|
||||
run_in_terminal(app)
|
||||
end)
|
||||
))
|
||||
newtimer(mailpath, timeout, update, true)
|
||||
|
||||
return mymailcheck
|
||||
return widget
|
||||
end
|
||||
|
||||
return setmetatable(maildir, { __call = function(_, ...) return worker(...) end })
|
||||
|
|
|
@ -9,10 +9,8 @@
|
|||
|
||||
--]]
|
||||
|
||||
local markup = require("lain.util.markup")
|
||||
local run_in_terminal = require("lain.helpers").run_in_terminal
|
||||
local newtimer = require("lain.helpers").newtimer
|
||||
|
||||
local beautiful = require("beautiful")
|
||||
local wibox = require("wibox")
|
||||
|
||||
local io = { lines = io.lines }
|
||||
|
@ -28,19 +26,14 @@ local setmetatable = setmetatable
|
|||
local mem = {}
|
||||
|
||||
function worker(args)
|
||||
local args = args or {}
|
||||
local refresh_timeout = args.refresh_timeout or 10
|
||||
local show_swap = args.show_swap or false
|
||||
local show_total = args.show_total or false
|
||||
local header = args.header or " Mem "
|
||||
local header_color = args.header or beautiful.fg_normal or "#FFFFFF"
|
||||
local color = args.color or beautiful.fg_focus or "#FFFFFF"
|
||||
local footer = args.footer or "MB "
|
||||
local args = args or {}
|
||||
local timeout = args.timeout or 3
|
||||
local settings = args.settings or function() end
|
||||
|
||||
local widg = wibox.widget.textbox()
|
||||
widget = wibox.widget.textbox('')
|
||||
|
||||
local upd = function()
|
||||
local mem = {}
|
||||
function update()
|
||||
mem = {}
|
||||
for line in io.lines("/proc/meminfo")
|
||||
do
|
||||
for k, v in string.gmatch(line, "([%a]+):[%s]+([%d]+).+")
|
||||
|
@ -58,30 +51,12 @@ function worker(args)
|
|||
used = mem.total - (mem.free + mem.buf + mem.cache)
|
||||
swapused = mem.swap - mem.swapf
|
||||
|
||||
if show_total
|
||||
then
|
||||
local fmt = "%" .. string.len(mem.total) .. ".0f/%.0f"
|
||||
widg:set_markup(markup(header_color, header) ..
|
||||
markup(color, string.format(fmt, used, mem.total) .. footer))
|
||||
else
|
||||
widg:set_markup(markup(header_color, header) ..
|
||||
markup(color, used .. footer))
|
||||
end
|
||||
|
||||
if show_swap
|
||||
then
|
||||
widg:set_markup(widg._layout.text .. ' ('
|
||||
.. string.format('%.0f '.. footer, swapused)
|
||||
.. ')')
|
||||
end
|
||||
settings()
|
||||
end
|
||||
|
||||
local tmr = timer({ timeout = refresh_timeout })
|
||||
tmr:connect_signal("timeout", upd)
|
||||
tmr:start()
|
||||
tmr:emit_signal("timeout")
|
||||
newtimer("mem", timeout, update)
|
||||
|
||||
return widg
|
||||
return widget
|
||||
end
|
||||
|
||||
return setmetatable(mem, { __call = function(_, ...) return worker(...) end })
|
||||
|
|
121
widgets/mpd.lua
121
widgets/mpd.lua
|
@ -7,10 +7,9 @@
|
|||
|
||||
--]]
|
||||
|
||||
local markup = require("lain.util.markup")
|
||||
local helpers = require("lain.helpers")
|
||||
|
||||
local awful = require("awful")
|
||||
local util = require("awful.util")
|
||||
local beautiful = require("beautiful")
|
||||
local naughty = require("naughty")
|
||||
local wibox = require("wibox")
|
||||
|
@ -27,111 +26,87 @@ local setmetatable = setmetatable
|
|||
local mpd = { id = nil }
|
||||
|
||||
function worker(args)
|
||||
local args = args or {}
|
||||
local password = args.password or ""
|
||||
local host = args.host or "127.0.0.1"
|
||||
local port = args.port or "6600"
|
||||
local args = args or {}
|
||||
local timeout = args.timeout or 1
|
||||
local password = args.password or ""
|
||||
local host = args.host or "127.0.0.1"
|
||||
local port = args.port or "6600"
|
||||
local music_dir = args.music_dir or os.getenv("HOME") .. "/Music"
|
||||
local refresh_timeout = args.refresh_timeout or 1
|
||||
local header_color = args.header_color or beautiful.fg_normal or "#FFFFFF"
|
||||
local color = args.color or beautiful.fg_focus or "#FFFFFF"
|
||||
local spr = args.spr or " "
|
||||
local footer = args.footer or ""
|
||||
local app = args.app or "ncmpcpp"
|
||||
local shadow = args.shadow or false
|
||||
local settings = args.settings or function() end
|
||||
|
||||
local mpdcover = helpers.scripts_dir .. "mpdcover"
|
||||
local mpdh = "telnet://"..host..":"..port
|
||||
local echo = "echo 'password "..password.."\nstatus\ncurrentsong\nclose'"
|
||||
local mpdh = "telnet://" .. host .. ":" .. port
|
||||
local echo = "echo 'password " .. password .. "\nstatus\ncurrentsong\nclose'"
|
||||
|
||||
local mympd = wibox.widget.textbox()
|
||||
widget = wibox.widget.textbox('')
|
||||
|
||||
helpers.set_map("current mpd track", nil)
|
||||
|
||||
local mympdupdate = function()
|
||||
local function set_nompd()
|
||||
if shadow
|
||||
then
|
||||
mympd:set_text('')
|
||||
else
|
||||
mympd:set_markup(markup(header_color, "mpd ") .. markup(color , "off") .. footer)
|
||||
end
|
||||
end
|
||||
|
||||
local mpd_state = {
|
||||
["{state}"] = "N/A",
|
||||
["{file}"] = "N/A",
|
||||
["{Artist}"] = "N/A",
|
||||
["{Title}"] = "N/A",
|
||||
["{Album}"] = "N/A",
|
||||
["{Date}"] = "N/A"
|
||||
function update()
|
||||
mpd_now = {
|
||||
state = "N/A",
|
||||
file = "N/A",
|
||||
artist = "N/A",
|
||||
title = "N/A",
|
||||
album = "N/A",
|
||||
date = "N/A"
|
||||
}
|
||||
|
||||
-- Get data from MPD server
|
||||
local f = io.popen(echo .. " | curl --connect-timeout 1 -fsm 3 " .. mpdh)
|
||||
|
||||
for line in f:lines() do
|
||||
for k, v in string.gmatch(line, "([%w]+):[%s](.*)$") do
|
||||
if k == "state" then mpd_state["{"..k.."}"] = v
|
||||
elseif k == "file" then mpd_state["{"..k.."}"] = v
|
||||
elseif k == "Artist" then mpd_state["{"..k.."}"] = awful.util.escape(v)
|
||||
elseif k == "Title" then mpd_state["{"..k.."}"] = awful.util.escape(v)
|
||||
elseif k == "Album" then mpd_state["{"..k.."}"] = awful.util.escape(v)
|
||||
elseif k == "Date" then mpd_state["{"..k.."}"] = awful.util.escape(v)
|
||||
if k == "state" then mpd_now.state = v
|
||||
elseif k == "file" then mpd_now.file = v
|
||||
elseif k == "Artist" then mpd_now.artist = util.escape(v)
|
||||
elseif k == "Title" then mpd_now.title = util.escape(v)
|
||||
elseif k == "Album" then mpd_now.album = util.escape(v)
|
||||
elseif k == "Date" then mpd_now.date = util.escape(v)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
f:close()
|
||||
|
||||
if mpd_state["{state}"] == "play"
|
||||
notification_preset = {
|
||||
title = "Now playing",
|
||||
text = mpd_now.artist .. " (" ..
|
||||
mpd_now.album .. ") - " ..
|
||||
mpd_now.date .. "\n" ..
|
||||
mpd_now.title,
|
||||
fg = beautiful.fg_normal or "#FFFFFF",
|
||||
bg = beautiful.bg_normal or "#000000",
|
||||
timeout = 6
|
||||
}
|
||||
|
||||
settings()
|
||||
|
||||
if mpd_now.state == "play"
|
||||
then
|
||||
if mpd_state["{Title}"] ~= helpers.get_map("current mpd track")
|
||||
if mpd_now.title ~= helpers.get_map("current mpd track")
|
||||
then
|
||||
helpers.set_map("current mpd track", mpd_state["{Title}"])
|
||||
helpers.set_map("current mpd track", mpd_now.title)
|
||||
|
||||
os.execute(mpdcover .. " '" .. music_dir .. "' '"
|
||||
.. mpd_state["{file}"] .. "'")
|
||||
.. mpd_now.file .. "'")
|
||||
|
||||
mpd.id = naughty.notify({
|
||||
title = "Now playing",
|
||||
text = mpd_state["{Artist}"] .. " (" ..
|
||||
mpd_state["{Album}"] .. ") - " ..
|
||||
mpd_state["{Date}"] .. "\n" ..
|
||||
mpd_state["{Title}"],
|
||||
preset = notification_preset,
|
||||
icon = "/tmp/mpdcover.png",
|
||||
fg = color,
|
||||
timeout = 6,
|
||||
replaces_id = mpd.id
|
||||
}).id
|
||||
end
|
||||
mympd:set_markup(markup(header_color, mpd_state["{Artist}"])
|
||||
.. spr ..
|
||||
markup(color, mpd_state["{Title}"]) .. footer)
|
||||
elseif mpd_state["{state}"] == "pause"
|
||||
elseif mpd_now.state ~= "pause"
|
||||
then
|
||||
mympd:set_markup(markup(header_color, "mpd")
|
||||
.. spr ..
|
||||
markup(color, "paused") .. footer)
|
||||
else
|
||||
helpers.set_map("current mpd track", nil)
|
||||
set_nompd()
|
||||
end
|
||||
end
|
||||
|
||||
local mympdtimer = timer({ timeout = refresh_timeout })
|
||||
mympdtimer:connect_signal("timeout", mympdupdate)
|
||||
mympdtimer:start()
|
||||
mympdtimer:emit_signal("timeout")
|
||||
helpers.newtimer("mpd", timeout, update)
|
||||
|
||||
mympd:buttons(awful.util.table.join(
|
||||
awful.button({}, 0,
|
||||
function()
|
||||
helpers.run_in_terminal(app)
|
||||
end)
|
||||
))
|
||||
output = { widget = widget, notify = update }
|
||||
|
||||
local mpd_out = { widget = mympd, notify = mympdupdate }
|
||||
|
||||
return setmetatable(mpd_out, { __index = mpd_out.widget })
|
||||
return setmetatable(output, { __index = output.widget })
|
||||
end
|
||||
|
||||
return setmetatable(mpd, { __call = function(_, ...) return worker(...) end })
|
||||
|
|
133
widgets/net.lua
133
widgets/net.lua
|
@ -7,33 +7,24 @@
|
|||
|
||||
--]]
|
||||
|
||||
local markup = require("lain.util.markup")
|
||||
local helpers = require("lain.helpers")
|
||||
|
||||
local awful = require("awful")
|
||||
local beautiful = require("beautiful")
|
||||
local notify_fg = require("beautiful").fg_focus
|
||||
local naughty = require("naughty")
|
||||
local wibox = require("wibox")
|
||||
|
||||
local io = io
|
||||
local tostring = tostring
|
||||
local string = { format = string.format }
|
||||
local string = { format = string.format,
|
||||
gsub = string.gsub }
|
||||
|
||||
local setmetatable = setmetatable
|
||||
|
||||
-- Network infos
|
||||
-- lain.widgets.net
|
||||
local net = {
|
||||
send = "0",
|
||||
recv = "0",
|
||||
last_t = {},
|
||||
last_r = {}
|
||||
}
|
||||
|
||||
net.units = {
|
||||
["b"] = 1,
|
||||
["kb"] = 1024,
|
||||
["mb"] = 1024^2,
|
||||
["gb"] = 1024^3
|
||||
last_t = 0,
|
||||
last_r = 0
|
||||
}
|
||||
|
||||
function net.get_device()
|
||||
|
@ -51,103 +42,61 @@ end
|
|||
function worker(args)
|
||||
local args = args or {}
|
||||
local iface = args.iface or net.get_device()
|
||||
local delta = args.refresh_timeout or 2
|
||||
local units = args.units or net.units["kb"]
|
||||
local spr = args.spr or " "
|
||||
local header = args.header or iface
|
||||
local header_color = args.header_color or beautiful.fg_normal or "#FFFFFF"
|
||||
local color_up = args.color_up or beautiful.fg_focus or "#FFFFFF"
|
||||
local color_down = args.color_down or beautiful.fg_focus or "#FFFFFF"
|
||||
local app = args.app or "sudo wifi-menu"
|
||||
local units = args.units or 1024 --kb
|
||||
local timeout = args.timeout or 2
|
||||
local settings = args.settings or function() end
|
||||
|
||||
widget = wibox.widget.textbox('')
|
||||
|
||||
helpers.set_map(iface, true)
|
||||
helpers.set_map("carrier", 0)
|
||||
|
||||
local mynet = wibox.widget.textbox()
|
||||
function update()
|
||||
if iface == "" then iface = net.get_device() end
|
||||
|
||||
local mynetupdate = function()
|
||||
if iface == "" then
|
||||
iface = net.get_device()
|
||||
header = iface
|
||||
end
|
||||
|
||||
local carrier = helpers.first_line('/sys/class/net/' .. iface ..
|
||||
'/carrier') or ""
|
||||
local state = helpers.first_line('/sys/class/net/' .. iface ..
|
||||
'/operstate')
|
||||
carrier = helpers.first_line('/sys/class/net/' .. iface ..
|
||||
'/carrier') or "0"
|
||||
state = helpers.first_line('/sys/class/net/' .. iface ..
|
||||
'/operstate') or "down"
|
||||
local now_t = helpers.first_line('/sys/class/net/' .. iface ..
|
||||
'/statistics/tx_bytes')
|
||||
'/statistics/tx_bytes') or 0
|
||||
local now_r = helpers.first_line('/sys/class/net/' .. iface ..
|
||||
'/statistics/rx_bytes')
|
||||
local text = '<span color="' .. header_color .. '">' .. header .. '</span> '
|
||||
'/statistics/rx_bytes') or 0
|
||||
|
||||
sent = tostring((now_t - net.last_t) / timeout / units)
|
||||
sent = string.gsub(string.format('%.1f', sent), ",", ".")
|
||||
|
||||
received = tostring((now_r - net.last_r) / timeout / units)
|
||||
received = string.gsub(string.format('%.1f', received), ",", ".")
|
||||
|
||||
settings()
|
||||
|
||||
net.last_t = now_t
|
||||
net.last_r = now_r
|
||||
|
||||
if carrier ~= "1"
|
||||
then
|
||||
if helpers.get_map(iface)
|
||||
then
|
||||
n_title = iface
|
||||
if n_title == "" then
|
||||
n_title = "network"
|
||||
header = "Net"
|
||||
end
|
||||
naughty.notify({ title = n_title, text = "no carrier",
|
||||
timeout = 7,
|
||||
position = "top_left",
|
||||
icon = beautiful.lain_no_net_notify or
|
||||
helpers.icons_dir .. "no_net.png",
|
||||
fg = beautiful.fg_focus or "#FFFFFF" })
|
||||
|
||||
mynet:set_markup(markup(header_color, header) .. markup(color_up, " Off"))
|
||||
if n_title == "" then n_title = "network" end
|
||||
naughty.notify({
|
||||
title = n_title,
|
||||
text = "no carrier",
|
||||
timeout = 7,
|
||||
position = "top_left",
|
||||
icon = helpers.icons_dir .. "no_net.png",
|
||||
fg = notify_fg or "#FFFFFF"
|
||||
})
|
||||
helpers.set_map(iface, false)
|
||||
end
|
||||
return
|
||||
else
|
||||
helpers.set_map(iface, true)
|
||||
end
|
||||
|
||||
if state == 'down' or not now_t or not now_r
|
||||
then
|
||||
mynet:set_markup(' ' .. text .. '-' .. ' ')
|
||||
return
|
||||
end
|
||||
|
||||
if net.last_t[iface] and net.last_t[iface]
|
||||
then
|
||||
net.send = tostring((now_t - net.last_t[iface]) / delta / units)
|
||||
net.recv = tostring((now_r - net.last_r[iface]) / delta / units)
|
||||
|
||||
text = text
|
||||
.. '<span color="' .. color_up .. '">'
|
||||
.. string.format('%.1f', net.send)
|
||||
.. '</span>'
|
||||
.. spr
|
||||
.. '<span color="' .. color_down .. '">'
|
||||
.. string.format('%.1f', net.recv)
|
||||
.. '</span>'
|
||||
|
||||
mynet:set_markup(' ' .. text .. ' ')
|
||||
else
|
||||
mynet:set_markup(' ' .. text .. '-' .. ' ')
|
||||
end
|
||||
|
||||
net.last_t[iface] = now_t
|
||||
net.last_r[iface] = now_r
|
||||
end
|
||||
|
||||
local mynettimer = timer({ timeout = delta })
|
||||
mynettimer:connect_signal("timeout", mynetupdate)
|
||||
mynettimer:start()
|
||||
mynettimer:emit_signal("timeout")
|
||||
helpers.newtimer(iface, timeout, update)
|
||||
|
||||
mynet:buttons(awful.util.table.join(
|
||||
awful.button({}, 0, function()
|
||||
helpers.run_in_terminal(app)
|
||||
mynetupdate()
|
||||
end)))
|
||||
|
||||
net.widget = mynet
|
||||
|
||||
return setmetatable(net, { __index = net.widget })
|
||||
return widget
|
||||
end
|
||||
|
||||
return setmetatable(net, { __call = function(_, ...) return worker(...) end })
|
||||
|
|
|
@ -7,11 +7,8 @@
|
|||
|
||||
--]]
|
||||
|
||||
local markup = require("lain.util.markup")
|
||||
local helpers = require("lain.helpers")
|
||||
local newtimer = require("lain.helpers").newtimer
|
||||
|
||||
local awful = require("awful")
|
||||
local beautiful = require("beautiful")
|
||||
local wibox = require("wibox")
|
||||
|
||||
local io = io
|
||||
|
@ -26,45 +23,24 @@ local sysload = {}
|
|||
|
||||
function worker(args)
|
||||
local args = args or {}
|
||||
local refresh_timeout = args.refresh_timeout or 5
|
||||
local show_all = args.show_all or false
|
||||
local header = args.header or " Load "
|
||||
local header_color = args.header_color or beautiful.fg_normal or "#FFFFFF"
|
||||
local color = args.color or beautiful.fg_focus or "#FFFFFF"
|
||||
local app = args.app or "top"
|
||||
local timeout = args.timeout or 5
|
||||
local settings = args.settings or function() end
|
||||
|
||||
local mysysload = wibox.widget.textbox()
|
||||
widget = wibox.widget.textbox('')
|
||||
|
||||
local mysysloadupdate = function()
|
||||
function update()
|
||||
local f = io.open("/proc/loadavg")
|
||||
local ret = f:read("*all")
|
||||
f:close()
|
||||
|
||||
a, b, c = string.match(ret, "([^%s]+) ([^%s]+) ([^%s]+)")
|
||||
|
||||
if show_all
|
||||
then
|
||||
local a, b, c = string.match(ret, "([^%s]+) ([^%s]+) ([^%s]+)")
|
||||
mysysload:set_text(string.format("%s %s %s", a, b, c))
|
||||
else
|
||||
local a = string.match(ret, "([^%s]+) ")
|
||||
mysysload:set_text(string.format("%s", a))
|
||||
end
|
||||
mysysload:set_markup(markup(header_color, header) ..
|
||||
markup(color, mysysload._layout.text .. " "))
|
||||
settings()
|
||||
end
|
||||
|
||||
local mysysloadtimer = timer({ timeout = refresh_timeout })
|
||||
mysysloadtimer:connect_signal("timeout", mysysloadupdate)
|
||||
mysysloadtimer:start()
|
||||
mysysloadtimer:emit_signal("timeout")
|
||||
newtimer("sysload", timeout, update)
|
||||
|
||||
mysysload:buttons(awful.util.table.join(
|
||||
awful.button({}, 0,
|
||||
function()
|
||||
helpers.run_in_terminal(app)
|
||||
end)
|
||||
))
|
||||
|
||||
return mysysload
|
||||
return widget
|
||||
end
|
||||
|
||||
return setmetatable(sysload, { __call = function(_, ...) return worker(...) end })
|
||||
|
|
|
@ -6,9 +6,8 @@
|
|||
|
||||
--]]
|
||||
|
||||
local markup = require("lain.util.markup")
|
||||
local newtimer = require("lain.helpers").newtimer
|
||||
|
||||
local beautiful = require("beautiful")
|
||||
local wibox = require("wibox")
|
||||
|
||||
local io = io
|
||||
|
@ -21,32 +20,22 @@ local setmetatable = setmetatable
|
|||
local temp = {}
|
||||
|
||||
function worker(args)
|
||||
local args = args or {}
|
||||
local refresh_timeout = args.refresh_timeout or 5
|
||||
local header = args.header or " Temp "
|
||||
local header_color = args.header_color or beautiful.fg_normal or "#FFFFFF"
|
||||
local color = args.color or beautiful.fg_focus or header_color
|
||||
local footer = args.footer or "C "
|
||||
local args = args or {}
|
||||
local timeout = args.timeout or 5
|
||||
local settings = args.settings or function() end
|
||||
|
||||
local mytemp = wibox.widget.textbox()
|
||||
widget = wibox.widget.textbox('')
|
||||
|
||||
local mytempupdate = function()
|
||||
function update()
|
||||
local f = io.open("/sys/class/thermal/thermal_zone0/temp")
|
||||
local ret = f:read("*all")
|
||||
coretemp_now = tonumber(f:read("*all")) / 1000
|
||||
f:close()
|
||||
|
||||
ret = tonumber(ret) / 1000
|
||||
|
||||
mytemp:set_markup(markup(header_color, header) ..
|
||||
markup(color, ret .. footer))
|
||||
settings()
|
||||
end
|
||||
|
||||
local mytemptimer = timer({ timeout = refresh_timeout })
|
||||
mytemptimer:connect_signal("timeout", mytempupdate)
|
||||
mytemptimer:start()
|
||||
mytemptimer:emit_signal("timeout")
|
||||
newtimer("coretemp", timeout, update)
|
||||
|
||||
return mytemp
|
||||
return widget
|
||||
end
|
||||
|
||||
return setmetatable(temp, { __call = function(_, ...) return worker(...) end })
|
||||
|
|
|
@ -6,9 +6,8 @@
|
|||
|
||||
--]]
|
||||
|
||||
local markup = require("lain.util.markup")
|
||||
local newtimer = require("lain.helpers").newtimer
|
||||
|
||||
local beautiful = require("beautiful")
|
||||
local naughty = require("naughty")
|
||||
local wibox = require("wibox")
|
||||
|
||||
|
@ -28,10 +27,9 @@ local setmetatable = setmetatable
|
|||
-- lain.widgets.yawn
|
||||
local yawn =
|
||||
{
|
||||
units = "",
|
||||
forecast = "",
|
||||
icon = wibox.widget.imagebox(),
|
||||
widget = wibox.widget.textbox()
|
||||
icon = wibox.widget.imagebox(),
|
||||
widget = wibox.widget.textbox(''),
|
||||
notification_preset = {}
|
||||
}
|
||||
|
||||
local project_path = debug.getinfo(1, 'S').source:match[[^@(.*/).*$]]
|
||||
|
@ -44,33 +42,32 @@ local weather_data = nil
|
|||
local notification = nil
|
||||
local city_id = nil
|
||||
local sky = nil
|
||||
local settings = {}
|
||||
local update_timer = nil
|
||||
|
||||
local function fetch_weather(args)
|
||||
local toshow = args.toshow or "forecast"
|
||||
local settings = function() end
|
||||
|
||||
local function fetch_weather()
|
||||
local url = api_url .. units_set .. city_id
|
||||
local f = io.popen("curl --connect-timeout 1 -fsm 2 '"
|
||||
.. url .. "'" )
|
||||
local text = f:read("*all")
|
||||
f:close()
|
||||
|
||||
-- handle no suitable icon found
|
||||
yawn.icon:set_image(icon_path .. "na.png")
|
||||
|
||||
-- In case of no connection or invalid city ID
|
||||
-- widgets won't display
|
||||
if text == "" or text:match("City not found")
|
||||
then
|
||||
sky = icon_path .. "na.png"
|
||||
yawn.icon:set_image(sky)
|
||||
if text == "" then
|
||||
weather_data = "Service not available at the moment."
|
||||
return "N/A"
|
||||
yawn.widget:set_text("N/A")
|
||||
else
|
||||
weather_data = "City not found!\n" ..
|
||||
"Are you sure " .. city_id ..
|
||||
" is your Yahoo city ID?"
|
||||
return "?"
|
||||
yawn.widget:set_text("?")
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- Processing raw data
|
||||
|
@ -88,8 +85,8 @@ local function fetch_weather(args)
|
|||
-- Getting info for text widget
|
||||
local now = weather_data:sub(weather_data:find("Now:")+5,
|
||||
weather_data:find("\n")-1)
|
||||
local forecast = now:sub(1, now:find(",")-1)
|
||||
local units = now:sub(now:find(",")+2, -2)
|
||||
forecast = now:sub(1, now:find(",")-1)
|
||||
units = now:sub(now:find(",")+2, -2)
|
||||
|
||||
-- Day/Night icon change
|
||||
local hour = tonumber(os.date("%H"))
|
||||
|
@ -110,14 +107,6 @@ local function fetch_weather(args)
|
|||
|
||||
sky = sky .. forecast:gsub(" ", ""):gsub("/", "") .. ".png"
|
||||
|
||||
-- In case there's no defined icon for current forecast
|
||||
f = io.popen(sky)
|
||||
if f == nil then
|
||||
sky = icon_path .. "na.png"
|
||||
else
|
||||
f:close()
|
||||
end
|
||||
|
||||
-- Localization
|
||||
local f = io.open(localizations_path .. language, "r")
|
||||
if language:find("en_") == nil and f ~= nil
|
||||
|
@ -132,21 +121,18 @@ local function fetch_weather(args)
|
|||
end
|
||||
|
||||
-- Finally setting infos
|
||||
both = weather_data:match(": %S+.-\n"):gsub(": ", "")
|
||||
yawn.icon:set_image(sky)
|
||||
widget = wibox.widget.textbox()
|
||||
|
||||
forecast = weather_data:match(": %S+.-,"):gsub(": ", ""):gsub(",", "\n")
|
||||
units = units:gsub(" ", "")
|
||||
notification_preset = {}
|
||||
-- anche notification preset, con fg, bg e position
|
||||
|
||||
yawn.forecast = markup(yawn.color, " " .. markup.font(beautiful.font, forecast) .. " ")
|
||||
yawn.units = markup(yawn.color, " " .. markup.font(beautiful.font, units))
|
||||
yawn.icon:set_image(sky)
|
||||
settings()
|
||||
|
||||
if toshow == "forecast" then
|
||||
return yawn.forecast
|
||||
elseif toshow == "units" then
|
||||
return yawn.units
|
||||
else
|
||||
return both
|
||||
end
|
||||
yawn.widget = widget
|
||||
yawn.notification_preset = notification_preset
|
||||
end
|
||||
|
||||
function yawn.hide()
|
||||
|
@ -159,41 +145,29 @@ end
|
|||
function yawn.show(t_out)
|
||||
if yawn.widget._layout.text == "?"
|
||||
then
|
||||
if update_timer ~= nil
|
||||
then
|
||||
update_timer:emit_signal("timeout")
|
||||
else
|
||||
fetch_weather(settings)
|
||||
end
|
||||
fetch_weather(settings)
|
||||
end
|
||||
|
||||
yawn.hide()
|
||||
|
||||
notification = naughty.notify({
|
||||
preset = yawn.notification_preset,
|
||||
text = weather_data,
|
||||
icon = sky,
|
||||
timeout = t_out,
|
||||
fg = yawn.color
|
||||
timeout = t_out
|
||||
})
|
||||
end
|
||||
|
||||
function yawn.register(id, args)
|
||||
local args = args or {}
|
||||
|
||||
settings = args
|
||||
|
||||
yawn.color = args.color or beautiful.fg_normal or "#FFFFFF"
|
||||
local args = args or {}
|
||||
local timeout = args.timeout or 600
|
||||
settings = args.settings or function() end
|
||||
|
||||
if args.u == "f" then units_set = '?u=f&w=' end
|
||||
|
||||
city_id = id
|
||||
|
||||
update_timer = timer({ timeout = 600 }) -- 10 mins
|
||||
update_timer:connect_signal("timeout", function()
|
||||
yawn.widget:set_markup(fetch_weather(settings))
|
||||
end)
|
||||
update_timer:start()
|
||||
update_timer:emit_signal("timeout")
|
||||
newtimer("yawn", timeout, fetch_weather)
|
||||
|
||||
yawn.icon:connect_signal("mouse::enter", function()
|
||||
yawn.show(0)
|
||||
|
@ -202,7 +176,7 @@ function yawn.register(id, args)
|
|||
yawn.hide()
|
||||
end)
|
||||
|
||||
return yawn
|
||||
return { icon = yawn.icon, widget = yawn.widget }
|
||||
end
|
||||
|
||||
function yawn.attach(widget, id, args)
|
||||
|
@ -217,6 +191,4 @@ function yawn.attach(widget, id, args)
|
|||
end)
|
||||
end
|
||||
|
||||
-- }}}
|
||||
|
||||
return setmetatable(yawn, { __call = function(_, ...) return yawn.register(...) end })
|
||||
|
|
Loading…
Reference in New Issue