1

I used to subscribe new podcasts by calling "rhythmbox [url of podcast]", but that is no longer working due to this bug. It just opens Rhythmbox instead of opening and subscribing. (although it does pre-fill it if you happen to click "add" in the podcast section)

Is there some new way GTK3 apps are supposed to communicate with each other, or is there just no way for an app to simply tell Rhythmbox to subscribe a certain podcast?

Update: Looking at an answer here I found the following with a lot of tab key in iPython:

from gi.repository import RB
 ....
In [2]: RB.PodcastManager.insert_feed_url
Out[2]: gi.FunctionInfo(insert_feed_url)

In [3]: RB.PodcastManager.insert_feed_url('http://feeds.feedburner.com/NodeUp')
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-3-b6415d6bfb17> in <module>()
----> 1 RB.PodcastManager.insert_feed_url('http://feeds.feedburner.com/NodeUp')

TypeError: insert_feed_url() takes exactly 2 arguments (1 given)

This seems like the right API, but what are the arguments? Will it work in systems pre-GTK3?

Update Going through the Python api here, I think I almost have it:

from gi.repository import RB
mypod = RB.PodcastChannel() #Creates blank podcast object
RB.podcast_parse_load_feed(mypod, 'http://wpdevtable.com/feed/podcast/', False)
#loads mypod.url, mypod.description etc.

RB.PodcastManager.add_parsed_feed(mypod); #fails

It appears the documentation on add_parsed_feed is incorrect, and wants 2 arguments, not 1. I know internally class' functions are defined with def thing(self, firstarg), is this causing a problem here with Python bindings to Rhythmbox somehow? Why can I not add the parsed podcast into Rhythmbox?

Community
  • 1
  • 1
NoBugs
  • 9,310
  • 13
  • 80
  • 146

1 Answers1

1

You need to instantiate the PodcastManager object before you call add_parsed_feed, so that self will be implicitly provided as the first argument:

manager = RB.PodcastManager()
manager.add_parsed_feed(mypod)

or

RB.PodcastManager().add_parsed_feed(mypod)

When you call it this way, the add_parsed_feed method is bound to the RB.PodcastManager instance you created. When you call a bound method, the instance it's bound to (manager, in this case) will automatically be provided as the first argument (which will end up being self inside of add_parsed_feed)..

On the other hand, when you call RB.PodcastManager.add_parsed_feed, the add_parsed_feed method isn't bound to any instance of RB.PodcastManager, so Python can't automatically provide that instance as the first argument. That's why you get the error about only one argument being provided.

Edit:

Note that it doesn't look like using this API works properly; it always seems to segfault for me, even if I use it from the Python console embedded into Rhythmbox. Getting the behavior you want is actually really easy if you don't mind editing the Rhythmbox source code and building it yourself - it's just a one line change. In shell/rb-shell.c, in the rb_shell_load_uri function, change this line:

rb_podcast_source_add_feed (shell->priv->podcast_source, uri);

To this:

rb_podcast_manager_subscribe_feed (shell->priv->podcast_manager, uri, TRUE);

Then rebuild. Now, when you include a podcast URI when you start rhythmbox, it will subscribe to the feed and start playing.

Here's the change in patch form:

diff --git a/shell/rb-shell.c b/shell/rb-shell.c
index 77526d9..e426396 100644
--- a/shell/rb-shell.c
+++ b/shell/rb-shell.c
@@ -2995,7 +2995,7 @@ rb_shell_load_uri (RBShell *shell,
        /* If the URI points to a Podcast, pass it on to the Podcast source */
        if (rb_uri_could_be_podcast (uri, NULL)) {
                rb_shell_select_page (shell, RB_DISPLAY_PAGE (shell->priv->podcast_source));
-               rb_podcast_source_add_feed (shell->priv->podcast_source, uri);
+               rb_podcast_manager_subscribe_feed (shell->priv->podcast_manager, uri, TRUE);
                return TRUE;
        }
dano
  • 91,354
  • 19
  • 222
  • 219
  • Nice, how did you know to try this? It seems the documentation is sparse in this area, too bad it seems there isn't a simple command-line subscribe command? – NoBugs Sep 05 '14 at 03:25
  • @NoBugs It's just basic Python syntax that anyone familiar with object oriented programming in Python would know to use. It's not unique to the `RB` API or anything like that. You can read more about the difference between bound and unbound methods [here](https://www.inkling.com/read/learning-python-mark-lutz-4th/chapter-30/methods-are-objects-bound-or). – dano Sep 05 '14 at 03:31
  • @NoBugs Or for a more general overview of classes in Python, see [here](https://docs.python.org/2/tutorial/classes.html). – dano Sep 05 '14 at 03:35
  • I get it, in RB they use initial capital to imply it's a class that needs to be created. And the documentation here shows it's a class, and `add_parsed_feed` isn't static. https://lazka.github.io/pgi-docs/#RB-3.0/classes/PodcastManager.html#RB.PodcastManager – NoBugs Sep 05 '14 at 03:38
  • Thanks, I'm familiar with how classes work in Python, but I should review that - isn't it different when it's a class based on bound C code as in Rhythmbox-Python api? – NoBugs Sep 05 '14 at 03:41
  • @NoBugs There are some subtle differences (for example, the type of `RB.PodcastManager.add_parsed_feed` is `gi.FunctionInfo` instead of the expected `instancemethod`), but the basic stuff is exactly the same. A class is still a class, and you call instance methods of that class exactly the same way you would if the class was pure Python. – dano Sep 05 '14 at 03:54
  • @NoBugs I took a look at the Rhythmbox source and figured out how to bring the functionality that used to be there back. See my edit. – dano Sep 06 '14 at 00:26
  • Thanks for digging into this! Could you please select "confirm" on that bug, and give them these details? https://bugs.launchpad.net/ubuntu/+source/rhythmbox/+bug/1051442 – NoBugs Sep 07 '14 at 05:11
  • @NoBugs I confirmed it on Launchpad, but you may be better off reporting it upstream: https://bugzilla.gnome.org/enter_bug.cgi?product=rhythmbox. You're welcome to include the patch with the report - it's just a one-liner, nothing I feel too strongly about having credit for :) – dano Sep 07 '14 at 22:49
  • I just ran `strace -q -y -o rhythmboxtrace -e open rhythmbox` and saw that it's reading `~/.config/dconf/user` and other files - would it be possible to directly configure the RB database there? Or any other way without requiring a recompiled Rhythmbox? – NoBugs Sep 09 '14 at 07:12
  • @NoBugs I'm not sure what you would change in the database to alter this behavior. I didn't see anything in the source that indicated there is a way to change how rhythmbox behaves in this case without actually changing rhythmbox code. There is a DBus API you could try using to subscribe, but that would require first starting rhythmbox, then executing the script. – dano Sep 09 '14 at 15:48
  • I don't think the DBUS api is working, possibly the same bug? I tried the example here and got org.freedesktop.DBus.Error.ServiceUnknown: The name org. gnome.Rhythmbox was not provided by any .service files http://blog.mafr.de/2006/12/10/controlling-rhythmbox-using-dbus/ – NoBugs Sep 10 '14 at 04:24
  • Are they trying to be more Apple-y and not give public api for most features? :) – NoBugs Sep 10 '14 at 04:27
  • @NoBugs I'm not sure what the issue with the DBus API is. Maybe they've dropped support for it? And actually, the `rhythmbox ` behavior looks like something they did on purpose, rather than a bug; they're using a completely different API when they detect a podcast uri is provided than the one you use to subscribe. That's just my impression from spending an hour or so looking at the code, though. – dano Sep 10 '14 at 04:37