Posts about python (old posts, page 16)

2008-07-19 08:43

Urssus: July 19th

I confess I cheated and kept working on it yesterday after the blog post. OTOH, I will not touch it today ;-). Big functionality added, too.

  • Feed items (The things on the tree) now are updated when the background process checks them.
  • They are also updated when you read articles from a feed.
  • The filter thingie works, you type some text, and only the articles with that text are shown (see screenshot).
  • Added a widget (not dialog) for searching within the page, firefox-like (see screenshot)

The bad news is that the "next unread article" code and a few others is garbage. It's quite inefficient because I tried to be cheap and not create a coherent model for feeds.

However it works and you will never tell the difference unless you have 2000 articles between where you are and the next unread (in which case the window goes kinda nuts for a couple of seconds).

Still fun!

2008-07-18 15:43

Urssus again

Another day, another two hours of work on it.

What's new?

  • Some UI elements without code behind them (the "filter article" thingie), and a feed properties dialog.
  • A (IMVHO) better UI distribution than akregator. Consider this screenshot:

The article list and feed tree are the same size, but removing the tabs and moving the filter into a toolbar really makes the actual reading area quite larger.

  • Delegate all links from the reading area to the desktop's web browser (this is not a web browser yet ;-)
  • Progress report for web page loading (more useful once you can declare a feed as "load link directly")
  • Finished feed/article navigation (next/previous feed/article unread/any), and fixed bugs in the part that was already done.
  • Zoom in/out for the web view
  • Show/hide statusbar
  • Several bug fixes

And yes, still fun!

2008-07-17 16:21

Urssus improves

Today's 2 hours:

  • An about dialog (not wired to the UI yet)
  • Icons on the feed tree (not favicons, though)
  • Handle a few more feed quirks
  • A status message queue, so subprocesses can post their progress in the status bar.
  • UI for importOPML
  • Implemented "Next Article" and "Next Feed". This Model/View Qt thing is kinda painful (but powerful!)
  • Use of Mako templates to display the articles pretty and neat
  • Menu & Shortcuts following Akreggator
  • Added several fields to the Post and Feed models to make them more useful (which means the DB changed, but that's to be expected at this stage). These include things like "unread" and "author" and "link" ;-)

Still fun!

2008-07-16 21:44

A programming challenge for myself

I worked on uRSSus for a couple of hours again, and it's working pretty nicely.

  • Really uses the ORM
  • Multiprocessing for a non-blocking UI (python-processing is awesome)
  • Adapts to the quirks of some feeds (why on earth would someone do a feed without dates? It's AOL FanHouse!)

I intend to keep working like this for a couple of weeks, and see how far I can get in feature parity to akregator.

No, I don't expect to reach feature parity, I only want to strive for it. SInce I lack the focusand/or energy for a multi year commitment it requires to write the average free software, I want to see how far a sprint gets me.


So far, it's fun.

2008-07-15 23:38

The world lamest GUI newsreader... in 130 LOC

I started this as an experiment to see how hard it was to build apps using QT and Elixir. This is how it looks after two hours of coding:


And here's the code:

You will need:

  • PyQt 4.4 or later
  • Mark Pilgrim's feedparser
  • Python 2.5 (or whenever elementtree got included)
  • A OPML file
  • The Python SQLite bindings
  • Elixir (the declarative layer over SQL Alchemy)

You can find the real code at

And then you can use these 131 LOC ;-)

# -*- coding: utf-8 -*-

# Mark Pilgrim's feed parser
import feedparser as fp

# DB Classes
from elixir import *

metadata.bind = "sqlite:///urssus.sqlite"
metadata.bind.echo = True

class Feed(Entity):
  htmlUrl     = Field(Text)
  xmlUrl      = Field(Text)
  title       = Field(Text)
  text        = Field(Text)
  description = Field(Text)
  children    = OneToMany('Feed')
  parent      = ManyToOne('Feed')
  posts       = OneToMany('Post')
  def __repr__(self):
    return self.text

  def update(self):

class Post(Entity):
  feed        = ManyToOne('Feed')
  title       = Field(Text)
  post_id     = Field(Text)
  content     = Field(Text)

# This is just temporary

# UI Classes
from PyQt4 import QtGui, QtCore
from Ui_main import Ui_MainWindow

class MainWindow(QtGui.QMainWindow):
  def __init__(self):

    # Set up the UI from designer

    # Initialize the tree from the Feeds

    # Internal function
    def addSubTree(parent, node):
      if not node.children:
        for child in node.children:
          addSubTree(nn, child)

    for root in roots:
      addSubTree(iroot, root)


    QtCore.QObject.connect(self.ui.feeds, QtCore.SIGNAL("clicked(QModelIndex)"), self.openFeed)
    QtCore.QObject.connect(self.ui.posts, QtCore.SIGNAL("clicked(QModelIndex)"), self.openPost)

  def openFeed(self, index):

    if not feed.xmlUrl:

    for post in d['entries']:
      print post
      print '----------------------------------\n\n'
      if 'content' in post:
        posts.append(Post(feed=feed, title=post['title'], post_id=post['id'], content='<hr>'.join([ c.value for c in post['content']])))
      elif 'summary' in post:
        posts.append(Post(feed=feed, title=post['title'], post_id=post['id'], content=post['summary']))
      elif 'value' in post:
        posts.append(Post(feed=feed, title=post['title'], post_id=post['id'], content=post['value']))

    for post in posts:

  def openPost(self, index):

if __name__ == "__main__":
  import sys
  # For starters, lets import a OPML file into the DB so we have some data to work with
  from xml.etree import ElementTree
  tree = ElementTree.parse(sys.argv[1])
  for outline in tree.findall("//outline"):
    if xu:
      if current:

2008-06-26 14:56

Creating and sending nice HTML+Text mails from python

I decided I needed an automatic report of some things on my email every day, and I wanted it to look nice both in plain text and HTML. Here's what I came up with.

Let's assume you created the HTML version using whatever mechanism you wish, and have it in a variable called "report".

Here's the imports we will use:

import smtplib,email,os,tempfile
from email.MIMEText import MIMEText
from email.MIMEMultipart import MIMEMultipart
from email.Charset import Charset

And here's the code:

# Create a HTML mail part
hpart=MIMEText(reporte, _subtype='html', _charset='utf-8')

# Create a plain text mail part
# Ugly and requires links, but makes for a great-looking plain text version ;-)
tpart=MIMEText(os.popen('links -dump %s'%tf,'r').read(), _subtype='plain', _charset='utf-8')

# Create the message with both parts attached

# Standard headers (add all you need, for example, date)
msg['Subject'] = 'Report'
msg['From']    = '[email protected]'
msg['To']      = '[email protected]'

#If you need to use SMTP authentication, change accordingly
smtp.sendmail('[email protected]','[email protected]',msg.as_string())

2008-06-20 14:23

Adding MSN notifications to Argus

I am a user of Argus as a monitoring software. Since it's very flexible and easy to extend, I wanted to add MSN alerts, the same way I had added SMS alerts a while ago. It was easier than I thought!

  1. Install msnlib

  2. Install the example msnbot, modified so do_work is like this:

    def do_work():
       Here you do your stuff and send messages using m.sendmsg()
       This is the only place your code lives
       # wait a bit for everything to settle down (sync taking efect
       # basically)
       for d in sys.argv[3].split('+'):
               print m.sendmsg(d,msg)
       # give time to send the messages
       # and then quit
  3. Define a custom notification in argus like this:

    Method "msn" {
       command: /usr/local/bin/msnbot [email protected] mypass %R >/tmp/XXX 2>&1
       send: %M\n
  4. Wherever you want MSN notifications, add this (on notify or escalate directives, using as many guys MSN addresses as you need):

    msn:[email protected][email protected]

That's it.

2008-04-23 22:20

My first impressions of Google App Engine

Since I got my invitation and am tired of Haloscan not being reachable from home (not their fault, probably), I decided that my first project would be a comment hosting app.

In other words, something a bit HaloScan-like.

Since I have very limited resources, it will probably not be useful for many people, but I am learning about App Engine, and at the same time probably making my blog a wee bit more comfortable.

Some random thoughts:

  • Can I put Google ads in app engine apps?
  • Does anyone else need this kind of app? I intend to make it open, so anyone can register its blog in it and use it. 500MB (the max DB size) are a lot of comments. Like a million of them.
  • I intend to use Yahoo's YUI RTE for editing. So my app will be hosted in Yahoo and Google. Cool :-D
  • It's basically just Django. Sure, no UNIQUE, no CRUD (ok, there is Google's, which is kinda lame... hire one of the Django guys and mke him work on it ;-), but it's the same thing, give or take a few bytes, specially using djangoforms.
  • webapp is... ok, it's rather ugly. Routing the requests is annoying, you can't do things like passing parts of the URL as parameters...
  • The User/DataStore APIs are ok, they feel a bit limited but they have a lot of scope in other ways (as in, there are a few million registered users and many TB of data stored ;-)

All things considered, a nice thing to use, specially at the cost.

2008-04-15 16:14

Linux as a windows crutch: Sending SMS

Suppose you want to send SMS messages from windows through a bluetooth connection to a phone.

I am sure you can make it work. On the other hand, I already had it working on Linux... so you can just use this on a friendly Linux box, and send SMS messages by accessing a special URL:

#!/usr/bin/env python
from colubrid import BaseApplication, HttpResponse, execute
import os

class SMSApplication(BaseApplication):

  def process_request(self):
      numero = self.request.args.get('numero')
      mensaje = self.request.args.get('mensaje')
      [entrada,salida]=os.popen4('/usr/bin/gnokii --sendsms %s'%numero,mode='rw')
      response = HttpResponse(msg)
      response['Content-Type'] = 'text/plain'
      return response

if __name__ == '__main__':
  execute(SMSApplication,debug=True, hostname='mybox.domain.internal', port=8080,reload=True)

If someone opens http://mybox.domain.internal:8080/?numero=1234?mensaje=hola%20mundo it sends "hola mundo" to the 1234 number.

I suppose I could call this a web telephony service or somesuch, but it's actually just the 5'solution that came to mind.

It uses a silly little not-a-web-framework called colubrid instead of something you may know, because I wanted to keep it simple, and it doesn't get much simpler than this.

Contents © 2000-2019 Roberto Alsina