Monthly Archives: December 2010

Running minidlna on Mac

These are my notes on installing [minidlna][minidlna], a [DLNA][dlna] server for Mac OS X. I compiled it from source and installed the supporting libraries from [MacPorts][macports].

Most of this was culled from [a thread on the minidlna forum][forum].

First install each of the following ports. The command for each would be something like `sudo port install libiconv`.

– libiconv
– sqlite3
– jpeg
– libexif
– libid3tag
– libogg
– libvorbis
– flac
– ffmpeg

Then check out the Mac branch of the current minidlna source from the CVS repository.

cvs -d:pserver:[email protected]:/cvsroot/minidlna checkout -r osx_port minidlna
cd minidlna

The current build script appears to miss out pulling in libiconv so I had to edit `configure.ac`, inserting a line to bring in `libiconv`.

AC_CHECK_LIB([iconv], [main],, AC_MSG_ERROR(Cannot find required library iconv.))

Now the build will work. Although I found I needed to run `autogen.sh` twice for it to generate all the necessary files.

source ENVIRONMENT.macports
sh genconfig.sh
sh autogen.sh
sh autogen.sh
./configure
make

This spits out the minidlna executable and a basic configuration file. Copy these to wherever you want them. Edit the `minidlna.conf` file, pointing it at the files you want to serve. There are examples of what to do in that configuration file.

And for testing purposes you can start the server from the build directory.

./minidlna -d -f minidlna.conf

Bingo.

I did try using [ushare][ushare], another DLNA server, but I couldn’t figure out how to persuade my Sony telly to successfully connect to it. So I gave up. I feel it is useful to give up quickly when something doesn’t work until you run out of alternatives, I consider this triage. I also consider my telly’s inability to work with ushare and the fact that the telly will only play a very limited set of video formats a mark against the promise of DLNA.

[minidlna]: http://sourceforge.net/projects/minidlna/
[dlna]: http://www.dlna.org/
[forum]: http://sourceforge.net/projects/minidlna/forums/forum/879956/topic/3412747
[macports]: http://www.macports.org/
[bravia]: http://www.sony.co.uk/hub/bravia-lcd-televisions
[ushare]: http://ushare.geexbox.org/

Class-based views for Bottle

I’m not convinced this is actually a good idea, but I have an approach for using class-based views as handlers for a route with [Bottle][bottle].

_(If you were mad keen on [Django’s][django] shift to [class-based views][cbv] you might reckon life wouldn’t be complete with a Bottle-based application until you employ classes for views. However Bottle’s use of decorators for tying URLs to views means it is less a natural fit than the same thing in Django.)_

The problem is that you can’t just decorate the method in your class using [`bottle.route`][route] because if you use that decorator on a method in a class you are telling Bottle to use the method before it has been bound to an instance of that class.

So although I wish it did, the following example will not work:

import bottle

class ViewClass(object):
@bottle.route(“/”)
def home_view(self):
return “My home page.”

obj = ViewClass()
bottle.run()

Running that will lead to errors about not enough arguments passed to the view method of your `ViewClass` instance.

Instead you need to register the route right after the object is created. This can be done in [the class’s `__new__` method][new]:

import bottle

class ViewClass(object):
def __new__(cls, *args, **kwargs):
obj = super(ViewClass, cls).__new__(cls, *args, **kwargs)
bottle.route(“/”)(obj.home_view)
return obj

def home_view(self):
return “My home page.”

obj = ViewClass()
bottle.run()

It works. It isn’t that pretty. You could achieve exactly the same thing by explicitly passing the `obj.home_view` method to `bottle.route` _after_ the instance is created. The advantage to doing this in the `__new__` method is it will happen automatically whenever `ViewClass` is instantiated.

And if you go down this path then [you should be aware of threads][threads]. Hey! Nice threads! Also I have a cold.

[bottle]: http://bottle.paws.de/
[cbv]: http://docs.djangoproject.com/en/dev/topics/class-based-views/
[django]: http://www.djangoproject.com/
[route]: http://bottle.paws.de/docs/dev/api.html#routing
[new]: http://docs.python.org/reference/datamodel.html#object.__new__
[threads]: http://bottle.paws.de/docs/dev/tutorial.html#accessing-request-data