Hi guys, I've made a Python script which you can use to get notifications of the latest questions. It scrapes the unanswered-questions page and informs you via libnotify. Just click on the notification button to open a browser window on the question.
- Why not use an RSS reader? Well, this is more customized than an RSS reader. Not only does it tell you that there are new messages, but it tells you their title and tags without you having to switch windows. Moreover, it identifies questions by their IDs rather than by their titles, so if a question changes its title, you won't get a new notification.
- Why not read from the RSS feed? It's generally updated less quickly. In the highly competitive world of SO, a couple of minutes can make a difference in rep.
- How do I use it? Copy and paste into your favorite editor, edit the settings at the top, save and run it in the background. You may not notice anything for a few minutes, since it doesn't show anything until it encounters a new question.
- Dependencies? You should probably get this from your package manager, but I've included links to the sources as well: pygobject, python-notify, python-lxml (with installation instructions).
- Isn't this not-a-question? Yeah, but it seems that past users have submitted their SO 'addons' here as well.
Do let me know if you find it useful (or useless), and if there are any bugs, or if you think there should be more features.
- The last script gave the same timeout whether one or three notifications showed up at once. I have changed it to increment the timeout per additional notification; the topmost notification expires first, so read them from top to bottom.
- The script now sends out a notification after initialization, to let you know that something's alive.
#! /usr/bin/python import subprocess import time import gobject import pynotify import urllib from lxml import etree import thread # CONFIGURATION browser = "chrome" # however you call it at the command line notify_timeout = 5000 # ms tagnames = "c++ or c or python or optimization or .net or asp.net or c# or java" scrape_site = "http://stackoverflow.com/" # or serverfault, or superuser... scrape_url = scrape_site + "unanswered/tagged?tagnames=" + urllib.quote(tagnames) + "&tab=newest" refresh_rate = 60 # seconds # END CONFIGURATION def find_new_qns(url): old_ids = set() while True: try: data = urllib.urlopen(url).read(1000000) except Exception as inst: # IOErrors happen now and then, just ignore them # print type(inst), inst continue html = etree.HTML(data) summaries = html.xpath("//div[@class='question-summary']") if len(old_ids) == 0: old_ids = set([summary.attrib["id"] for summary in summaries]) new_qn_count = 0 for summary in summaries: if summary.attrib["id"] not in old_ids: new_qn_count += 1 old_ids.add(summary.attrib["id"]) title = summary.xpath( "descendant::a[@class='question-hyperlink']") tags = \ summary.xpath("descendant::a[@class='post-tag']/text()") notify(title.text, " ".join(tags), scrape_site + title.attrib["href"], notify_timeout*new_qn_count**0.8) if len(old_ids) > 1000: old_ids = set([summary.attrib["id"] for summary in summaries]) time.sleep(refresh_rate) def notify(title, message, target_url, timeout): def notify_thread(title, message, target_url): note = pynotify.Notification(title, message) if target_url is not None: note.add_action(target_url, "View", lambda n,url: subprocess.call([browser, url])) note.connect("closed", lambda n: loop.quit()) note.set_timeout(int(timeout)) note.show() loop = gobject.MainLoop() loop.run() thread.start_new_thread(notify_thread, (title, message, target_url)) if __name__ == '__main__': gobject.threads_init() pynotify.init("stackoverflow-notify") # if we've got this far, the libraries are basically there. # ... hopefully the versions are sufficiently recent. # let the user know we're alive notify("Stack Exchange Notifier Initialized.", "", None, notify_timeout) find_new_qns(scrape_url)