PythonDaap is a (under development) DAAP client implemented in Python, and based on PyTunes by Davyd Madeley.
I’ve added the authentication stuff needed by recent copies of iTunes and a primitive object model that can download individual tracks, and has playlist support. I have a command-line shell similar to itshell (I also called mine itshell, just to be confusing), and it’s all quite usable.
Development copies of the code can be found in my subversion repository here, or there are release tarballs avaliable below.
Known users of PythonDaap:
Known packages of PythonDaap:
Files associated with this page:
| name | size | added |
|---|---|---|
| PythonDaap-0.7.1.tar.gz (release notes) | 25.3 KB | 2008-03-19 09:12 |
| PythonDaap-0.7.tar.gz (release notes) | 24.7 KB | 2007-03-12 19:26 |
| PythonDaap-0.6.tar.gz (release notes) | 24.7 KB | 2007-03-12 18:58 |
| PythonDaap-0.5.tar.gz (release notes) | 13.5 KB | 2007-02-12 17:48 |
| PythonDaap-0.4.tar.gz (release notes) | 13.4 KB | 2006-08-02 09:58 |
| PythonDaap-0.3.tar.gz (release notes) | 15.8 KB | 2006-05-12 23:59 |
| PythonDaap-0.2.tar.gz | 15.7 KB | 2006-05-12 23:59 |
You have latin-1 in your ID3 tags, probably. Can you try the svn version, and let me know if the problem goe away? I really should do another release..
Hi Tom,
Sorry for the delay, I never went back here after posting the comment.
I think now it should work as elisa mediacenter uses your project.
Do you plan on writing a simple server ?
Would It be easy with your code (I have sometime ago started to write a server, but never continued).
Nope, I have no plans to write a server - there are plenty of stand-alone daap servers out there. Having said that, none of them are written in python, and I'll happily take patches that will add the ability to serve files.
What is the license for this library? I would like to use it for an oss project, but I can't find the license terms anywhere.
Everything you can find under http://jerakeen.org/code can be assumed to be under the GPL. If you'd like an explicit LICENCE file in the tree, I can do that, but I hate bothering with this stuff.
Be aware that it won't talk to iTunes 7 libraries at the moment, and until someone else reverse-engineers the changes, there are no plans for it to. It'll happen soon, I'm sure.
After chatting to various people, I've relicensed it under the LGPL, and added an explicit LICENSE file to the dist.
Thanks for creating this! I'm working on implementing a DAAP plugin for exaile (www.exaile.org) using this.
One small feature request: support for detecting available shares automatically via avahi.
Keep up the good work!
Unlikely to happen - I mostly use this under Mac OS, where there are already system discovery libraries.
How do I get the track number, genre, etc.? DAAPTrack doesn't have an attribute for these, and using atom.getAtom always returns None.
I figured it out. You have to change a couple of things in python-daap though. At lines 509 and 534, the string list after 'meta' needs to be expanded to include daap.songgenre, daap.songyear, and daap.songtracknumber.
Could you please add this to your next release?
Sure. That list is a real pain to manage - every thing I add to it slows the client down just a little but more, and pushes the memory requirements up a little bit more. But these are things worth having.
Ok, committed to the svn repository. Test it with your app, and I'll roll another tarball.
I spoke a bit too soon. Functionally it's fine, but it gives me 2000+ lines of stuff like this in the terminal when I run it:
'mcty^@^@^@^B'
'mdcl^@^@^@7'
'mcnm^@^@^@^D'
'mcna^@^@^@^Y'
'mcty^@^@^@^B'
'mdcl^@^@^@0'
'mcnm^@^@^@^D'
'mcna^@^@^@^R'
'mcty^@^@^@^B'
'mdcl^@^@^@2'
'mcnm^@^@^@^D'
'mcna^@^@^@^T'
'mcty^@^@^@^B'
'mdcl^@^@^@2'
'mcnm^@^@^@^D'
'mcna^@^@^@^T'
'mcty^@^@^@^B'
'mdcl^@^@^@5'
'mcnm^@^@^@^D
And a bit (40-50 lines) of this stuff too:
('** %s %s %s', u'mctc', u'dmap.containercount', 'i')
('** %s %s %s', u'mrco', u'dmap.returnedcount', 'i')
('** %s %s %s', u'mtco', u'dmap.specifiedtotalcount', 'i')
('** %s %s %s', u'mlcl', u'dmap.listing', 'c')
('** %s %s %s', u'mlit', u'dmap.listingitem', 'c')
('** %s %s %s', u'mbcl', u'dmap.bag', 'c')
('** %s %s %s', u'msrv', u'dmap.serverinforesponse', 'c')
('** %s %s %s', u'msau', u'dmap.authenticationmethod', 'b')
Aside from this, it's working perfectly.
Tom, I've got another patch for you: Authentication! Now python-daap can access password-protected shares as well. It's dang easy to implement too. Just add
password = None
to the connect() params for DAAPClient (line 360), and add
if self.password:
import base64
b64 = base64.encodestring('%s:%s' % ('user', self.password))[:-1]
headers['Authorization'] = 'Basic %s' % b64
to DAAPClient._get_response(), at around line 384.
You have a small typo: pasword instead of password in the connect() params. One 's' can make a big difference. :)
Would you mind doing another release for the authentication support? It's a fairly important feature for the Exaile plugin I'm making, so I'd like to simply be able to point people here to get python-daap, instead of having to maintain my own tarball.
I noticed you added a section for packages. I have an Ubuntu Edgy package (ver 0.7) here: http://syzygy42.tuxfamily.org/dists/edgy/reacocard/
I'll also try to keep packages up-to-date for the latest Ubuntu version, but the URL will change to reflect that (feisty instead of edgy, etc.). You can also add that Exaile uses python-daap, via the soon-to-be-released Music Sharing plugin.
Thanks,
Aren
An update on the Ubuntu package, it's for feisty now, so it's here: http://syzygy42.tuxfamily.org/dists/feisty/reacocard/
It might just be better to link to frontpage: http://syzygy42.tuxfamily.org/
and say it's under the 'reacocard' component.
Well, I've just added python-daap-0.7 to Gentoo Portage since it's required for one of Exailes plugins per request.
Please note that the "params = {}" in your function definitions (e.g. _get_response, among others) won't do what you think they do:
def f(params={}):
print params
params['b'] = 'c'
>>> f()
{}
>>> f()
{'b': 'c'}
I suggest you replace it with something like this:
def f(params=None):
if params is None:
params = {}
Then you get:
>>> f()
{}
>>> f()
{}
Hello :)
I just tried PythonDAAP 0.7 under cygwin against an iTunes 7.5 with no password, and got this output:
$ python itshell.py
The python/daap interactive shell.
Type 'help' for help.
(no server): connect localhost
Connecting to 'localhost':3689
2007-12-12 18:00:59,789 DEBUG getting /content-codes
2007-12-12 18:00:59,807 DEBUG gunzipping data
2007-12-12 18:00:59,808 DEBUG expanded from 1929 bytes to 8056 bytes
2007-12-12 18:00:59,824 DEBUG getting /server-info
2007-12-12 18:00:59,835 DEBUG gunzipping data
2007-12-12 18:00:59,837 DEBUG expanded from 168 bytes to 240 bytes
2007-12-12 18:00:59,838 DEBUG DAAPObject: Unknown code ☺ for type aeFP, writing
raw data
2007-12-12 18:00:59,841 DEBUG DAAPObject: Unknown code ♥ for type msas, writing
raw data
2007-12-12 18:00:59,843 DEBUG getting /login
2007-12-12 18:00:59,854 DEBUG gunzipping data
2007-12-12 18:00:59,855 DEBUG expanded from 47 bytes to 32 bytes
2007-12-12 18:00:59,857 DEBUG Logged in as session 1947786654
2007-12-12 18:00:59,858 DEBUG getting /databases?session-id=1947786654
2007-12-12 18:00:59,869 DEBUG getting /logout?session-id=1947786654
Traceback (most recent call last):
File "itshell.py", line 202, in
shell.session.logout()
File "/usr/lib/python2.5/site-packages/daap.py", line 508, in logout
response = self.request("/logout")
File "/usr/lib/python2.5/site-packages/daap.py", line 492, in request
return self.connection.request(r, params, answers)
File "/usr/lib/python2.5/site-packages/daap.py", line 436, in request
raise DAAPError('DAAPClient: %s: Authentication failure'%r)
daap.DAAPError: DAAPClient: /logout: Authentication failure
Do you know what may be causing this? Thanks in advance.
To add to your known packages list - python-daap is packaged in Mandriva. 0.7.1 is (well, will be in an hour or two, currently on 0.7) in current Cooker (development distro) and /backports for 2008 and 2008 Spring (last two stable releases).
xerxas
2006-07-25 14:20 on PythonDaap in Code
Hi, I just tested PythonDaap against itunes 6.0.4 with an empty library and I get this traceback:
(no server): connect 192.168.0.102
Connecting to '192.168.0.102':3689
DEBUG: getting /content-codes
DEBUG: gunzipping data
DEBUG: expanded from 1611 bytes to 6580 bytes
Traceback (most recent call last):
File "itshell.py", line 189, in ?
shell.cmdloop()
File "/usr/lib/python2.4/cmd.py", line 142, in cmdloop
stop = self.onecmd(line)
File "/usr/lib/python2.4/cmd.py", line 219, in onecmd
return func(arg)
File "itshell.py", line 54, in do_connect
client.connect(server, port)
File "/home/r67894/PythonDaap-0.3/daap.py", line 358, in connect
self.getContentCodes() # practically required
File "/home/r67894/PythonDaap-0.3/daap.py", line 442, in getContentCodes
response = self.request('/content-codes')
File "/home/r67894/PythonDaap-0.3/daap.py", line 430, in request
return self.readResponse( content )
File "/home/r67894/PythonDaap-0.3/daap.py", line 436, in readResponse
object.processData(str)
File "/home/r67894/PythonDaap-0.3/daap.py", line 295, in processData
object.processData(str)
File "/home/r67894/PythonDaap-0.3/daap.py", line 295, in processData
object.processData(str)
File "/home/r67894/PythonDaap-0.3/daap.py", line 338, in processData
'utf-8')
UnicodeDecodeError: 'utf8' codec can't decode byte 0x8d in position 1: unexpected code byte