I have an itch I want to scratch in Rhythmbox, and I’ve been looking at the Python bindings for writing plugins. It’s clear that you can do a lot of stuff, but there is no documentation specific to the Python bindings. There is the Plugin Writing Guide, which is conceptually useful, and there are the C-specific development docs, but there’s a piece missing.
Update 2013-06-23: From the comments, there’s now a nice tool available to generate the docs from several versions, available from http://www.donaghhorgan.com/projects/rhythmbox/rhythmbox-documentation-generator/, and several pre-generated sets available for download at http://www.donaghhorgan.com/misc/rhythmbox-python-documentation/. Great work Donagh, thanks for leaving the links!
I ended up figuring out how to generate the docs for the python bindings from the .gir files produced by the build.
A browseable copy of the docs:
A copy of the .gir XML files generated by a rhythmbox build:
A tarball of the docs:
The rest of this post is justification for going to all of this trouble, plus the actual commands I used to generate the html from the .gir files
Tell me a story…
Trying to learn from what’s already there, I found that the Magnatune plugin might be a useful thing to study. Among other things, activating it causes a new Group “Stores” to show up in the sources list, with a member of Magnatunes. I want to do something similar. Looking at the code showed me a lot of interesting things, but not how to learn more about those things. Take for instance this line, which is pretty obviously related to “turning on” the Stores group:
group = RB.DisplayPageGroup.get_by_id ("stores")
Well, ok, but where do
get_by_id come from? A little bit of grepping through the git repo showed that the “real” call was likely
rb_display_page_group_get_by_id(), defined in sources/rb-display-page-group.c. That’s nice, but no real indication of how the two were hooked together, or how to figure out what the other bindings would be named.
After nosing into the bindings/ directory I realized that the bindings were generated programmatically at build time. Hoping that the build would leave behind usable map files, I downloaded the distribution, spent way too long figuring out the pre-reqs, and finally got it configured. I ran
make in bindings/ and was rewarded with gi/RB-3.0.gir and MPID-3.0.gir, which appeared to be XML documents defining the C-Python bindings. This was about the best I had hoped for, but since it was still so hard to read I decided to see if there was an automatic documenter for .gir files. Turns out there is. With a little bit of fiddling (and this page) I managed to turn out fairly usable HTML documentation for the bindings. Doesn’t get me any closer to my plugin, but at least it lets me feel like I accomplished something tonight.
Since I couldn’t google up these docs anywhere else, I’m posting all of my work product and the results here. Share and enjoy!
The process to generate the docs from the .gir files was reasonably straight forward. The only issue has to do with RB-3.0.gir “including” MPID-3.0.gir and the tool’s search path. I used a kludgy method to allow
g-ir-doc-tool to locate MPID-3.0.gir that I’m not especially proud of, but it got done. The following commands generate .page output from the .gir files, then turn the .page output into .html. I’m leaving in the error output and my solution to trying to find MPID-3.0.gir file for posterity
$ cd ~/swap/rhythmbox/rhythmbox-2.97/bindings/gi $ mkdir ~/swap/rhythmbox/binding-docs $ g-ir-doc-tool --language Python -o ~/swap/rhythmbox/binding-docs/ ./RB-3.0.gir Couldn't find include 'MPID-3.0.gir' (search path: ['gir-1.0', '/usr/share/gir-1.0', '/usr/share/gir-1.0', '/usr/share/gir-1.0']) $ mkdir gir-1.0 $ ln -s ../MPID-3.0.gir gir-1.0/ $ g-ir-doc-tool --language Python -o ~/swap/rhythmbox/binding-docs/ ./RB-3.0.gir $ cd ~/swap/rhythmbox/binding-docs $ /bin/ls -1 | wc -l 1169 $ yelp-build html . $ /bin/ls -1 | wc -l 2345
There’s a tarball of that output, and it can also be browsed directly. To complete the loop, here’s the page describing the RB.DisplayPageGroup.get_by_id(). I wish this form of the documentation would retain C function that’s being called on the backend (that info is in the .gir file), but it’s better than nothing.