From eb8cec907a50f3fd6df4b14ae10b910444017f92 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Tue, 10 Sep 2013 23:02:11 +0200 Subject: [PATCH] totally reworked widgets --- README.rst | 2 +- helpers.lua | 46 ++++-------- widgets/alsa.lua | 103 ++++++++----------------- widgets/alsabar.lua | 43 ++++++----- widgets/bat.lua | 102 +++++++++---------------- widgets/calendar.lua | 27 +++---- widgets/cpu.lua | 31 ++++---- widgets/fs.lua | 102 ++++++++++++------------- widgets/imap.lua | 170 +++++++++++++++++------------------------- widgets/init.lua | 6 +- widgets/maildir.lua | 60 ++++----------- widgets/mem.lua | 45 +++-------- widgets/mpd.lua | 121 ++++++++++++------------------ widgets/net.lua | 133 ++++++++++----------------------- widgets/sysload.lua | 44 +++-------- widgets/temp.lua | 31 +++----- widgets/yawn/init.lua | 88 ++++++++-------------- 17 files changed, 415 insertions(+), 739 deletions(-) diff --git a/README.rst b/README.rst index 2524de3..6ce1c47 100644 --- a/README.rst +++ b/README.rst @@ -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. diff --git a/helpers.lua b/helpers.lua index 7677768..a8c4cd7 100644 --- a/helpers.lua +++ b/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. --]] -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 = {} diff --git a/widgets/alsa.lua b/widgets/alsa.lua index 7c26908..8571ec6 100644 --- a/widgets/alsa.lua +++ b/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. + * (c) 2013, Luke Bonham + * (c) 2010, Adrian C. --]] -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 }) diff --git a/widgets/alsabar.lua b/widgets/alsabar.lua index 0421f5c..7f5fe87 100644 --- a/widgets/alsabar.lua +++ b/widgets/alsabar.lua @@ -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 }) diff --git a/widgets/bat.lua b/widgets/bat.lua index 0461607..5a811f0 100644 --- a/widgets/bat.lua +++ b/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 }) diff --git a/widgets/calendar.lua b/widgets/calendar.lua index e5f6e88..e28e735 100644 --- a/widgets/calendar.lua +++ b/widgets/calendar.lua @@ -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 () diff --git a/widgets/cpu.lua b/widgets/cpu.lua index 3890e5e..f9bbe72 100644 --- a/widgets/cpu.lua +++ b/widgets/cpu.lua @@ -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 }) diff --git a/widgets/fs.lua b/widgets/fs.lua index 344bd87..f934248 100644 --- a/widgets/fs.lua +++ b/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 }) diff --git a/widgets/imap.lua b/widgets/imap.lua index f06660b..2c7067c 100644 --- a/widgets/imap.lua +++ b/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 }) diff --git a/widgets/init.lua b/widgets/init.lua index 78cac9b..0e863ba 100644 --- a/widgets/init.lua +++ b/widgets/init.lua @@ -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 }) diff --git a/widgets/maildir.lua b/widgets/maildir.lua index 98de091..00ab771 100644 --- a/widgets/maildir.lua +++ b/widgets/maildir.lua @@ -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 }) diff --git a/widgets/mem.lua b/widgets/mem.lua index 3034e89..d0ff223 100644 --- a/widgets/mem.lua +++ b/widgets/mem.lua @@ -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 }) diff --git a/widgets/mpd.lua b/widgets/mpd.lua index 8db62ae..8ba1cde 100644 --- a/widgets/mpd.lua +++ b/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 }) diff --git a/widgets/net.lua b/widgets/net.lua index 18727f1..f05235b 100644 --- a/widgets/net.lua +++ b/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 = '' .. header .. ' ' + '/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 - .. '' - .. string.format('%.1f', net.send) - .. '' - .. spr - .. '' - .. string.format('%.1f', net.recv) - .. '' - - 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 }) diff --git a/widgets/sysload.lua b/widgets/sysload.lua index eb06828..6167d82 100644 --- a/widgets/sysload.lua +++ b/widgets/sysload.lua @@ -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 }) diff --git a/widgets/temp.lua b/widgets/temp.lua index 301bc1c..5b1ebf5 100644 --- a/widgets/temp.lua +++ b/widgets/temp.lua @@ -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 }) diff --git a/widgets/yawn/init.lua b/widgets/yawn/init.lua index 20c90b1..9bed983 100644 --- a/widgets/yawn/init.lua +++ b/widgets/yawn/init.lua @@ -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 })