diff --git a/README.md b/README.md index 8e910d0..7f7da56 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,8 @@ battery status * battery_ident — (default: BAT0) + + ### clock @@ -52,12 +54,72 @@ This class shows a clock * format — stftime format string + + ### 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 @@ -72,6 +134,8 @@ unread posts in any bookmark in the mods.de forums. * username — (required) * password — (required) + + ### regex @@ -84,6 +148,8 @@ Simple regex file watcher * flags — Python.re flags + + ## Contribute To contribute a module, make sure it uses one of the Module classes. Most modules diff --git a/i3pystatus/mail/__init__.py b/i3pystatus/mail/__init__.py index a141a29..8c925e8 100644 --- a/i3pystatus/mail/__init__.py +++ b/i3pystatus/mail/__init__.py @@ -2,30 +2,56 @@ from i3pystatus import SettingsBase, IntervalModule class Backend(SettingsBase): - """Handle the details of checking for mail""" + """Handles the details of checking for mail""" unread = 0 - """Return number of unread mails + """Number of unread mails You'll probably implement that as a property""" 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",) - def run(self): - unread = sum(lambda backend: backend.unread, self.backends) + color = "#ffffff" + color_unread ="#ff0000" + format = "{unread} new email" + format_plural = "{unread} new emails" - if (unread == 0): - color = "#00FF00" + def init(self): + 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" else: - color = "#ff0000" + color = self.color_unread urgent = "true" + format = self.format + if unread > 1: + format = self.format_plural + self.output = { - "full_text" : "%d new email%s" % (unread, ("s" if unread > 1 else "")), - "name" : "newmail", + "full_text" : format.format(unread=unread), "urgent" : urgent, - "color" : color + "color" : color, } diff --git a/i3pystatus/mail/imap.py b/i3pystatus/mail/imap.py index f9d82da..baef9d7 100644 --- a/i3pystatus/mail/imap.py +++ b/i3pystatus/mail/imap.py @@ -12,6 +12,14 @@ class IMAP(Backend): """ 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) """ settings = required = ("servers",) @@ -34,6 +42,9 @@ class IMAP(Backend): imap_class = imaplib.IMAP4 connection = None + ssl = False + port = 143 + def __init__(self, settings_dict): self.__dict__.update(settings_dict) diff --git a/i3pystatus/mkdocs.py b/i3pystatus/mkdocs.py index 08a31b8..4b91329 100755 --- a/i3pystatus/mkdocs.py +++ b/i3pystatus/mkdocs.py @@ -7,22 +7,27 @@ from collections import namedtuple import textwrap import i3pystatus +import i3pystatus.mail IGNORE = ("__main__", "mkdocs") MODULE_FORMAT = """ -### {name} +{heading} {name} {doc} -{settings}\n""" +{settings} + +{endstring}\n""" class Module: name = "" doc = "" + endstring = "" - def __init__(self, cls, neighbours, module_name, module): + def __init__(self, cls, neighbours, module_name, module, heading): self.settings = [] self.cls = cls + self.heading = heading if neighbours == 1: self.name = module_name @@ -35,6 +40,10 @@ class Module: self.doc = module.__doc__ else: self.doc = "" + + if hasattr(self.cls, "_endstring"): + self.endstring = self.cls._endstring + self.get_settings() def get_settings(self): @@ -49,6 +58,8 @@ class Module: name=self.name, doc=textwrap.dedent(self.doc), settings=self.format_settings(), + heading=self.heading, + endstring=self.endstring ) class Setting: @@ -86,9 +97,12 @@ class Setting: return formatted -def get_modules(): +def get_modules(path=None): + if path is None: + path = i3pystatus.get_path() + 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: modules.append(get_module(finder, modname)) @@ -98,19 +112,27 @@ def get_module(finder, modname): fullname = "i3pystatus.{modname}".format(modname=modname) return (modname, finder.find_loader(fullname)[0].load_module(fullname)) -def get_all(): +def get_all(module_path, heading, finder=None): 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) 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) -with open("template.md", "r") as template: - moddoc = "".join(map(str, get_all())) +def generate_doc_for_module(module_path, heading="###", finder=None): + 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) \ No newline at end of file