initial
This commit is contained in:
commit
cf16d57e11
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
*.pyc
|
||||||
|
|
31
README.md
Normal file
31
README.md
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# i3pystatus
|
||||||
|
|
||||||
|
i3pystatus is a (hopefully growing) collection of python scripts for
|
||||||
|
status output compatible to i3status / i3bar of the i3 window manager.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
To install it, follow these steps:
|
||||||
|
|
||||||
|
cd ~/.config/i3status/
|
||||||
|
git clone git@github.com:janoliver/i3pystatus contrib
|
||||||
|
|
||||||
|
Add the following to `~/.config/i3status/config`:
|
||||||
|
|
||||||
|
general {
|
||||||
|
output_format = "i3bar"
|
||||||
|
colors = true
|
||||||
|
interval = 5
|
||||||
|
}
|
||||||
|
|
||||||
|
Change your i3wm config to the following:
|
||||||
|
|
||||||
|
# i3bar
|
||||||
|
bar {
|
||||||
|
status_command i3status | python2 ~/.config/i3status/contrib/wrapper.py
|
||||||
|
position top
|
||||||
|
workspace_buttons yes
|
||||||
|
}
|
||||||
|
|
||||||
|
And finally adjust the settings in `~/.config/i3status/contrib/wrapper.py`
|
||||||
|
as you like.
|
105
mailchecker.py
Normal file
105
mailchecker.py
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import json
|
||||||
|
from datetime import datetime,timedelta
|
||||||
|
import imaplib
|
||||||
|
|
||||||
|
|
||||||
|
class MailChecker(object):
|
||||||
|
"""
|
||||||
|
This class handles mailservers and outputs i3status compatible
|
||||||
|
json data for the accumulated unread count. The mail server
|
||||||
|
functionality is implemented in the subclass MailChecker.MailServer
|
||||||
|
"""
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
'color': '#ff0000',
|
||||||
|
'servers': []
|
||||||
|
}
|
||||||
|
|
||||||
|
servers = []
|
||||||
|
|
||||||
|
def __init__(self, settings = None):
|
||||||
|
self.settings.update(settings)
|
||||||
|
|
||||||
|
for server in settings['servers']:
|
||||||
|
srv = MailChecker.MailServer(server)
|
||||||
|
self.servers.append(srv)
|
||||||
|
|
||||||
|
def output(self):
|
||||||
|
unread = 0
|
||||||
|
for srv in self.servers:
|
||||||
|
unread += srv.get_unread_count()
|
||||||
|
|
||||||
|
if not unread:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return {'full_text' : '%d new emails' % unread,
|
||||||
|
'name' : 'newmail',
|
||||||
|
'urgent' : 'true',
|
||||||
|
'color' : self.settings['color']}
|
||||||
|
|
||||||
|
class MailServer:
|
||||||
|
"""
|
||||||
|
This class provides the functionality to connect
|
||||||
|
to a mail server and fetch the count of unread emails.
|
||||||
|
When the server connection is lost, it returns 0 and
|
||||||
|
tries to reconnect. It checks every 'pause' seconds.
|
||||||
|
"""
|
||||||
|
|
||||||
|
host = ""
|
||||||
|
port = ""
|
||||||
|
imap_class = imaplib.IMAP4
|
||||||
|
username = ""
|
||||||
|
password = ""
|
||||||
|
connection = None
|
||||||
|
pause = 30
|
||||||
|
unread_cache = 0
|
||||||
|
last_checked = datetime.now()
|
||||||
|
|
||||||
|
def __init__(self, settings_dict):
|
||||||
|
self.host = settings_dict['host']
|
||||||
|
self.port = settings_dict['port']
|
||||||
|
self.username = settings_dict['username']
|
||||||
|
self.password = settings_dict['password']
|
||||||
|
self.pause = settings_dict['pause']
|
||||||
|
|
||||||
|
if settings_dict['ssl']:
|
||||||
|
self.imap_class = imaplib.IMAP4_SSL
|
||||||
|
|
||||||
|
self.last_checked = \
|
||||||
|
datetime.now() - timedelta(seconds=self.pause)
|
||||||
|
|
||||||
|
def get_connection(self):
|
||||||
|
if not self.connection:
|
||||||
|
try:
|
||||||
|
self.connection = self.imap_class(self.host, self.port)
|
||||||
|
self.connection.login(self.username, self.password)
|
||||||
|
self.connection.select()
|
||||||
|
except Exception:
|
||||||
|
self.connection = None
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.connection.select()
|
||||||
|
except Exception,e:
|
||||||
|
|
||||||
|
print e
|
||||||
|
self.connection = None
|
||||||
|
|
||||||
|
return self.connection
|
||||||
|
|
||||||
|
def get_unread_count(self):
|
||||||
|
delta = datetime.now() - self.last_checked
|
||||||
|
|
||||||
|
if delta.total_seconds() > self.pause:
|
||||||
|
unread = 0
|
||||||
|
conn = self.get_connection()
|
||||||
|
if conn:
|
||||||
|
unread += len(conn.search(None,'UnSeen')[1][0].split())
|
||||||
|
|
||||||
|
self.unread_cache = unread
|
||||||
|
self.last_checked = datetime.now()
|
||||||
|
|
||||||
|
return self.unread_cache
|
63
statushandler.py
Normal file
63
statushandler.py
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import json
|
||||||
|
|
||||||
|
class I3statusHandler:
|
||||||
|
modules = []
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def register_module(self, module):
|
||||||
|
""" Register a new module. """
|
||||||
|
|
||||||
|
# check if module implemented the
|
||||||
|
# correct functions
|
||||||
|
if not hasattr(module, 'output'):
|
||||||
|
raise Exception("Module %s does not implement \
|
||||||
|
all the needed functions!".format(module))
|
||||||
|
|
||||||
|
self.modules.append(module)
|
||||||
|
|
||||||
|
def print_line(self, message):
|
||||||
|
""" Non-buffered printing to stdout. """
|
||||||
|
|
||||||
|
sys.stdout.write(message + '\n')
|
||||||
|
sys.stdout.flush()
|
||||||
|
|
||||||
|
def read_line(self):
|
||||||
|
""" Interrupted respecting reader for stdin. """
|
||||||
|
|
||||||
|
# try reading a line, removing any extra whitespace
|
||||||
|
try:
|
||||||
|
line = sys.stdin.readline().strip()
|
||||||
|
# i3status sends EOF, or an empty line
|
||||||
|
if not line:
|
||||||
|
sys.exit(3)
|
||||||
|
return line
|
||||||
|
# exit on ctrl-c
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
self.print_line(self.read_line())
|
||||||
|
self.print_line(self.read_line())
|
||||||
|
|
||||||
|
while True:
|
||||||
|
line, prefix = self.read_line(), ''
|
||||||
|
|
||||||
|
# ignore comma at start of lines
|
||||||
|
if line.startswith(','):
|
||||||
|
line, prefix = line[1:], ','
|
||||||
|
|
||||||
|
j = json.loads(line)
|
||||||
|
|
||||||
|
for module in self.modules:
|
||||||
|
output = module.output()
|
||||||
|
|
||||||
|
if output:
|
||||||
|
j.insert(0, module.output())
|
||||||
|
|
||||||
|
# and echo back new encoded json
|
||||||
|
self.print_line(prefix+json.dumps(j))
|
37
wrapper.py
Executable file
37
wrapper.py
Executable file
@ -0,0 +1,37 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import mailchecker
|
||||||
|
from statushandler import I3statusHandler
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
status = I3statusHandler()
|
||||||
|
|
||||||
|
#List the modules
|
||||||
|
mailsettings = {
|
||||||
|
'color': '#ff0000',
|
||||||
|
'servers': [
|
||||||
|
{
|
||||||
|
'host': 'www.testhost1.com',
|
||||||
|
'port': '993',
|
||||||
|
'ssl' : True,
|
||||||
|
'username': 'your_username',
|
||||||
|
'password': 'your_password',
|
||||||
|
'pause': 20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'host': 'www.testhost2.net',
|
||||||
|
'port': '993',
|
||||||
|
'ssl' : True,
|
||||||
|
'username': 'your_username',
|
||||||
|
'password': 'your_password',
|
||||||
|
'pause': 20
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
mailchecker = mailchecker.MailChecker(mailsettings)
|
||||||
|
status.register_module(mailchecker)
|
||||||
|
|
||||||
|
# start the handler
|
||||||
|
status.run()
|
Loading…
Reference in New Issue
Block a user