Email maildir naughty hoover
I'd like to share a bit of code I wrote for my mail setup. I wanted something like the Delightful imap widget, but without the bloat of all the Delightful modules, that works with maildirs and in combination with vicious.
This module allows to wrap a naughty popup with maildir info around a widget in the style of
Calendar_widget#Module_for_3.4.
I'm currently using it in combination with the maildir widget from vicious, which I configured to
display an envelope image in case i have new mail. placing the mouse over this widget then opens
the naughty popup.
here is a screenshot:
code and usage
I have a file "mailhoover.lua" wich contains the following. (get it here: https://github.com/pazz/configs/raw/master/.config/awesome/mailhoover.lua)
local string = string
--local print = print
local tostring = tostring
local io = io
local table = table
local pairs = pairs
local capi = {
mouse = mouse,
screen = screen
}
local awful = require("awful")
local naughty = require("naughty")
local beautiful = require('beautiful')
module("mailhoover")
local popup
local account_format = "<span color='" .. beautiful.fg_urgent .."'><b>%s</b></span>"
local dir_format = "<span color='" .. beautiful.fg_normal .."'><b>%s</b></span>"
local newmail_format = "<span color='" .. beautiful.fg_urgent .. "'>%s</span>"
local oldmail_format = "<span color='" .. beautiful.fg_focus .. "'>%s</span>"
function addToWidget(mywidget, maildirs, accountname)
mywidget:add_signal('mouse::enter', function ()
local info = read_maildirs(maildirs)
popup = naughty.notify({
title = string.format(account_format,accountname),
text = info,
timeout = 0,
hover_timeout = 0.5,
screen = capi.mouse.screen
})
end)
mywidget:add_signal('mouse::leave', function () naughty.destroy(popup) end)
end
function read_maildirs(md)
local info = ""
local count = 0
for i=1, #md do
mdir = md[i]
mails = {}
-- Recursively find new messages
local f = io.popen("find "..mdir.." -type f -wholename '*/new/*'")
for line in f:lines() do
table.insert(mails,format_mail(newmail_format,line))
end
f:close()
-- Recursively find "old" messages lacking the Seen flag
local f = io.popen("find "..mdir.." -type f -regex '.*/cur/.*2,[^S]*$'")
for line in f:lines() do
table.insert(mails,format_mail(oldmail_format,line))
end
f:close()
if #mails>0 then info = info .. string.format(dir_format,mdir) .. ':\n' end
for m=1, #mails do
info = info .. mails[m]
end
end
return info
end
function format_mail(template,mailpath)
mailfile = io.open(mailpath,"r")
for line in mailfile:lines() do
if line:find("^Subject:") then subject = string.match(line, "^Subject: (.*)%s?") end
if line:find("^From:") then
from = string.match(line, "^From: (.*)")
from = string.gsub(from, "<.*>","")
end
end
mailfile:close()
return string.format(" %-30s %s\n", from, subject)
end
This is part of my rc.lua.
require('mailhoover')
...
mailicon = widget({ type = 'imagebox', name = 'mailicon'})
mailfolders = {
'/home/pazz/mail/uoe/INBOX',
'/home/pazz/mail/uoe/lists.seminars',
}
mailhoover.addToWidget(mailicon, mailfolders, ACCOUNTNAME')
vicious.register(mailicon, vicious.widgets.mdir,
function (widget, args)
if args[1] > 0 then
mailicon.image = image(beautiful.widget_mail)
else
mailicon.image = image(beautiful.widget_nomail)
end
return nil
end, 10, mailfolders)
mailbuttons = awful.util.table.join(
awful.button({ }, 1, function () awful.util.spawn(mail_cmd) end)
)
mailicon:buttons(mailbuttons)
The important bit is the line
mailhoover.addToWidget(mailicon, mailfolders, 'ACCOUNTNAME')
that adds the mouseover effect to the widget "mailicon". the second argument is a table of maildir locations, the third is the title of the naughty-message. The colours used are taken from beautiful.fg_urgent,beautiful.fg_normal and beautiful.fg_focus.
non-features/bugs
- encoding problems: some subject lines still don't display correctly
- it would ne nice to have the popup triggered by a global keycombo instead of having to point the mouse over the widget
- vertical alignment of from and subject lines needs some fixing