Skip to main content


Showing posts from April, 2008

We're engaged.

Further updates as warranted.
Read more

How BitTorrent Private Trackers Work

I'd like to use BitTorrent for sharing files with Nessie . So, I started doing some research about private trackers. It took me quite a while to scrape together enough information about BitTorrent protocols to figure out how private trackers work. (It would have helped if I had found the official BitTorrent specifications sooner.) It turns out to be quite simple. Basically torrent trackers and clients exchange dictionaries of meta-data . In the meta-data sent from the client to the tracker is a passkey (with the key name 'key'). The passkey is per-user and added to the announce URL in the .torrent file which is dynamically generated for each registered user that downloads it. The tracker then uses that key like a session key in a web app. The key can be used for connection limiting, ratio tracking, IP restriction, etc. Useful! When trackers send data back to the clients, a private flag bit is set (with the key name 'private'). Well behaved clients will then refra
Read more

Finding your public IP address in Python

I came across a nice code snippet today to accomplish this. Naturally, this doesn't work for NAT. def GetPublicIpAddress(): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.connect(('', 80)) return s.getsockname()[0] Another great snippet for finding the IP address of a given network interface is in the ASPN Python Cookbook .
Read more

Learning wxPython

I spent some time today picking up wxPython to add a GUI to Nessie. Here's a few things I learned: wxPython defaults to logging errors into a wx window on Windows and Mac. That's pretty useless if your application crashes and the window disappears immediately. To redirect output to your console use: wx.App(redirect=False) The wxPython style guide suggests using sizers for laying out your application. The most useful of these is the GridBagSizer (basically a table where items can span multiple cells). Unfortunately, the API for this sizer is a bit cumbersome. It requires you to specify the coordinates for each item in the grid. That's fine until you want to insert a new row and end up shifting all the following coordinates by one. I wrote a quick factory wrapper around the GridBagSizer that I think makes for a nicer API. class GridBagSizerFactory(object): def __init__(self, hgap, vgap): self.sizer = wx.GridBagSizer(hgap, vgap) self._row = 0 self._col = 0 def
Read more