This commit is contained in:
enkore 2013-02-23 23:00:14 +01:00
parent 3f46ab24c6
commit 9e6af3661a
4 changed files with 150 additions and 25 deletions

View File

@ -44,6 +44,8 @@ battery status
* battery_ident — (default: BAT0) * battery_ident — (default: BAT0)
### clock ### clock
@ -52,12 +54,72 @@ This class shows a clock
* format — stftime format string * format — stftime format string
### mail ### mail
Generic mail checker
The `backends` setting determines the backends to use. Currently available are:
* backends — List of backends (instances of i3pystatus.mail.xxx)
* color — (default: #ffffff)
* color_unread — (default: #ff0000)
* format — (default: {unread} new email)
* format_plural — (default: {unread} new emails)
Currently available backends are:
#### imap
This class handles IMAP mailservers. The mail server
functionality is implemented in the subclass IMAP.MailServer
The servers parameter should be a list of dicts containing the following
items:
* host
* port (optional, defaults to 143)
* username
* password
* ssl (optional, defaults to False)
* servers — (required)
#### notmuchmail
This class uses the notmuch python bindings to check for the
number of messages in the notmuch database with the tags "inbox"
and "unread"
* db_path — (required)
#### thunderbird
This class listens for dbus signals emitted by
the dbus-sender extension for thunderbird.
Requires
* python-dbus
* python-gobject2
* backends — (required)
* color
### modsde ### modsde
@ -72,6 +134,8 @@ unread posts in any bookmark in the mods.de forums.
* username — (required) * username — (required)
* password — (required) * password — (required)
### regex ### regex
@ -84,6 +148,8 @@ Simple regex file watcher
* flags — Python.re flags * flags — Python.re flags
## Contribute ## Contribute
To contribute a module, make sure it uses one of the Module classes. Most modules To contribute a module, make sure it uses one of the Module classes. Most modules

View File

@ -2,30 +2,56 @@
from i3pystatus import SettingsBase, IntervalModule from i3pystatus import SettingsBase, IntervalModule
class Backend(SettingsBase): class Backend(SettingsBase):
"""Handle the details of checking for mail""" """Handles the details of checking for mail"""
unread = 0 unread = 0
"""Return number of unread mails """Number of unread mails
You'll probably implement that as a property""" You'll probably implement that as a property"""
class Mail(IntervalModule): class Mail(IntervalModule):
settings = ("backends", "color",) """
Generic mail checker
The `backends` setting determines the backends to use. Currently available are:
"""
_endstring = """
Currently available backends are:
!!i3pystatus.mail!!"""
settings = (
("backends", "List of backends (instances of i3pystatus.mail.xxx)"),
"color", "color_unread", "format", "format_plural"
)
required = ("backends",) required = ("backends",)
def run(self): color = "#ffffff"
unread = sum(lambda backend: backend.unread, self.backends) color_unread ="#ff0000"
format = "{unread} new email"
format_plural = "{unread} new emails"
if (unread == 0): def init(self):
color = "#00FF00" for backend in self.backends:
pass
def run(self):
unread = sum(map(lambda backend: backend.unread, self.backends))
if not unread:
color = self.color
urgent = "false" urgent = "false"
else: else:
color = "#ff0000" color = self.color_unread
urgent = "true" urgent = "true"
format = self.format
if unread > 1:
format = self.format_plural
self.output = { self.output = {
"full_text" : "%d new email%s" % (unread, ("s" if unread > 1 else "")), "full_text" : format.format(unread=unread),
"name" : "newmail",
"urgent" : urgent, "urgent" : urgent,
"color" : color "color" : color,
} }

View File

@ -12,6 +12,14 @@ class IMAP(Backend):
""" """
This class handles IMAP mailservers. The mail server This class handles IMAP mailservers. The mail server
functionality is implemented in the subclass IMAP.MailServer functionality is implemented in the subclass IMAP.MailServer
The servers parameter should be a list of dicts containing the following
items:
* host
* port (optional, defaults to 143)
* username
* password
* ssl (optional, defaults to False)
""" """
settings = required = ("servers",) settings = required = ("servers",)
@ -34,6 +42,9 @@ class IMAP(Backend):
imap_class = imaplib.IMAP4 imap_class = imaplib.IMAP4
connection = None connection = None
ssl = False
port = 143
def __init__(self, settings_dict): def __init__(self, settings_dict):
self.__dict__.update(settings_dict) self.__dict__.update(settings_dict)

View File

@ -7,22 +7,27 @@ from collections import namedtuple
import textwrap import textwrap
import i3pystatus import i3pystatus
import i3pystatus.mail
IGNORE = ("__main__", "mkdocs") IGNORE = ("__main__", "mkdocs")
MODULE_FORMAT = """ MODULE_FORMAT = """
### {name} {heading} {name}
{doc} {doc}
{settings}\n""" {settings}
{endstring}\n"""
class Module: class Module:
name = "" name = ""
doc = "" doc = ""
endstring = ""
def __init__(self, cls, neighbours, module_name, module): def __init__(self, cls, neighbours, module_name, module, heading):
self.settings = [] self.settings = []
self.cls = cls self.cls = cls
self.heading = heading
if neighbours == 1: if neighbours == 1:
self.name = module_name self.name = module_name
@ -35,6 +40,10 @@ class Module:
self.doc = module.__doc__ self.doc = module.__doc__
else: else:
self.doc = "" self.doc = ""
if hasattr(self.cls, "_endstring"):
self.endstring = self.cls._endstring
self.get_settings() self.get_settings()
def get_settings(self): def get_settings(self):
@ -49,6 +58,8 @@ class Module:
name=self.name, name=self.name,
doc=textwrap.dedent(self.doc), doc=textwrap.dedent(self.doc),
settings=self.format_settings(), settings=self.format_settings(),
heading=self.heading,
endstring=self.endstring
) )
class Setting: class Setting:
@ -86,9 +97,12 @@ class Setting:
return formatted return formatted
def get_modules(): def get_modules(path=None):
if path is None:
path = i3pystatus.get_path()
modules = [] modules = []
for finder, modname, ispkg in pkgutil.iter_modules(i3pystatus.get_path()): for finder, modname, ispkg in pkgutil.iter_modules(path):
if modname not in IGNORE: if modname not in IGNORE:
modules.append(get_module(finder, modname)) modules.append(get_module(finder, modname))
@ -98,19 +112,27 @@ def get_module(finder, modname):
fullname = "i3pystatus.{modname}".format(modname=modname) fullname = "i3pystatus.{modname}".format(modname=modname)
return (modname, finder.find_loader(fullname)[0].load_module(fullname)) return (modname, finder.find_loader(fullname)[0].load_module(fullname))
def get_all(): def get_all(module_path, heading, finder=None):
mods = [] mods = []
finder = i3pystatus.ModuleFinder() if finder is None:
finder = i3pystatus.ModuleFinder()
for name, module in get_modules(): for name, module in get_modules(module_path):
classes = finder.search_module(module) classes = finder.search_module(module)
for cls in classes: for cls in classes:
mods.append(Module(cls, neighbours=len(classes), module_name=name, module=module)) mods.append(Module(cls, neighbours=len(classes), module_name=name, module=module, heading=heading))
return sorted(mods, key=lambda module: module.name) return sorted(mods, key=lambda module: module.name)
with open("template.md", "r") as template: def generate_doc_for_module(module_path, heading="###", finder=None):
moddoc = "".join(map(str, get_all())) return "".join(map(str, get_all(module_path, heading, finder)))
print(template.read().replace("!!module_doc!!", moddoc)) with open("template.md", "r") as template:
tpl = template.read()
tpl = tpl.replace("!!module_doc!!", generate_doc_for_module(i3pystatus.__path__))
finder = i3pystatus.ClassFinder(baseclass=i3pystatus.mail.Backend, exclude=[i3pystatus.mail.Backend])
tpl = tpl.replace("!!i3pystatus.mail!!", generate_doc_for_module(i3pystatus.mail.__path__, "####", finder))
print(tpl)