i3pystatus/modsde.py
enkore db94df07a3 With small changes, comes great change
Introduced asynchronous plugins that gather their data on different
intervals than the mainloop. Here it is used for the modsde plugin.

The statushandler has a new class Module, which acts as documentation
for the API


These changes let the output evenly flow, even if an async plugin hangs
due to network problems or similiar issues.
2013-02-11 21:01:38 +01:00

93 lines
2.7 KiB
Python

#!/usr/bin/env python
import sys
import json
import time
import threading
import urllib.request, urllib.parse, urllib.error, urllib.request, urllib.error, urllib.parse
import re
import http.cookiejar
import xml.etree.ElementTree as ET
class LoginError(Exception):
pass
class ModsDeChecker(object):
"""
This class returns i3status parsable output of the number of
unread posts in any bookmark in the mods.de forums.
"""
async = True
output = None
login_url = "http://login.mods.de/"
bookmark_url = "http://forum.mods.de/bb/xml/bookmarks.php"
opener = None
cj = None
logged_in = False
settings = {
"color": "#7181fe",
"pause": 20,
"username": "",
"password": "",
"offset": 0,
}
def __init__(self, settings = None):
self.settings.update(settings)
self.cj = http.cookiejar.CookieJar()
self.opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(self.cj))
self.thread = threading.Thread(target=self.mainloop)
self.thread.daemon = True
self.thread.start()
def mainloop(self):
while True:
unread = self.get_unread_count()
if not unread:
self.output = None
else:
self.output = {"full_text" : "%d new posts in bookmarks" % unread,
"name" : "modsde",
"urgent" : "true",
"color" : self.settings["color"]}
time.sleep(self.settings["pause"])
def get_unread_count(self):
if not self.logged_in:
self.login()
try:
f = self.opener.open(self.bookmark_url)
root = ET.fromstring(f.read())
return int(root.attrib["newposts"]) - self.settings["offset"]
except Exception:
self.cj.clear()
self.opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(self.cj))
self.logged_in = False
def login(self):
data = urllib.parse.urlencode({
"login_username": self.settings["username"],
"login_password": self.settings["password"],
"login_lifetime": "31536000"
})
response = self.opener.open(self.login_url, data.encode("ascii"))
m = re.search("http://forum.mods.de/SSO.php[^']*", response.read().decode("ISO-8859-15"))
self.cj.clear()
if m and m.group(0):
# get the cookie
response = self.opener.open(m.group(0))
for cookie in self.cj:
self.cj.clear
self.logged_in = True
self.opener.addheaders.append(('Cookie', '{}={}'.format(cookie.name, cookie.value)))
return True