23
23
from podgen .compat import string_types
24
24
import collections
25
25
import inspect
26
+ import warnings
26
27
27
28
28
29
_feedgen_version = podgen .version .version_str
@@ -272,14 +273,12 @@ def __init__(self, **kwargs):
272
273
273
274
.. note::
274
275
275
- You only need to worry about this attribute if you've `set up
276
- PubSubHubbub`_ for your podcast. PodGen does NOT include this
277
- functionality for you, and you must notify the hub of new content
278
- yourself.
276
+ You only need to worry about this attribute if you've :doc:`set up
277
+ PubSubHubbub </advanced/pubsubhubbub>` for your podcast.
279
278
280
279
.. note::
281
280
282
- In addition to setting this attribute, you should set the
281
+ In addition to setting this attribute, you must set the
283
282
:attr:`.feed_url` to the canonical URL of this feed. That way, there
284
283
is no confusion about which URL should be given to the PubSubHubbub
285
284
by the podcatcher when subscribing.
@@ -300,9 +299,11 @@ def __init__(self, **kwargs):
300
299
PubSubHubbub. The `latest version of the standard`_ specifically says
301
300
that publishers MUST use the Link header.
302
301
302
+ .. seealso:
303
+ The :doc:`guide on how to use PubSubHubbub </advanced/pubsubhubbub>`
304
+ A more detailed walk-through on how to use PubSubHubbub.
305
+
303
306
.. _PubSubHubbub: https://en.wikipedia.org/wiki/PubSubHubbub
304
- .. _set up PubSubHubbub:
305
- https://indieweb.org/How_to_publish_and_consume_PubSubHubbub
306
307
.. _Link header: https://tools.ietf.org/html/rfc5988#page-6
307
308
.. _latest version of the standard: http://pubsubhubbub.github.io/PubSubHubbub/pubsubhubbub-core-0.4.html#rfc.section.4
308
309
"""
@@ -744,6 +745,119 @@ def clear_episode_order(self):
744
745
for episode in self .episodes :
745
746
episode .position = None
746
747
748
+ @classmethod
749
+ def notify_multiple (cls , requests , feeds , timeout = 10.0 ):
750
+ """Notify the PubSubHubbub hubs of additions in multiple Podcasts.
751
+
752
+ When using PubSubHubbub, you must notify the hub whenever a feed has
753
+ new entries. Using this method, you can give a list of feeds
754
+ which all have new content. This saves time compared to
755
+ :meth:`~.Podcast.notify_hub` since they can be made into one request per
756
+ hub, instead of having one request per feed per hub.
757
+
758
+ The Podcast objects don't need to use the same PubSubHubbub hub.
759
+
760
+ :param requests: The requests module, or a Session object.
761
+ :type requests: requests or requests.Session
762
+ :param feeds: List of Podcast objects which have new or changed content
763
+ published.
764
+ :type feeds: :obj:`list` of :class:`.Podcast`
765
+ :param timeout: Number of seconds we can wait for the server to respond.
766
+ Applies to each hub separately. Defaults to ten seconds.
767
+ :type timeout: float
768
+ :warnings: UserWarning for each feed that has no value for
769
+ :attr:`~.Podcast.pubsubhubbub` and :attr:`~.Podcast.feed_url`.
770
+
771
+ .. note::
772
+
773
+ This method is blocking, and will return when the servers respond.
774
+
775
+ .. note::
776
+
777
+ For this to work for a given feed, it must have
778
+ :attr:`~.Podcast.feed_url` and :attr:`~.Podcast.pubsubhubbub` set
779
+ correctly.
780
+
781
+ .. seealso::
782
+
783
+ The instance method :meth:`~.Podcast.notify_hub`
784
+ For notifying a single hub about a single feed
785
+
786
+ The :doc:`guide on using PubSubHubbub </advanced/pubsubhubbub>`
787
+ For a step-for-step guide with examples.
788
+ """
789
+ # Which hubs should be notified about what feeds?
790
+ hubs = dict ()
791
+ for feed in feeds :
792
+ if feed .pubsubhubbub :
793
+ hubs .setdefault (feed .pubsubhubbub , []).append (feed )
794
+ else :
795
+ warnings .warn ("Cannot notify feed %s: pubsubhubbub not set"
796
+ % feed )
797
+
798
+ # We now have a dictionary which maps a hub to a list of its feeds
799
+ for hub , hub_feeds in iteritems (hubs ):
800
+ # Create the POST parameters
801
+ # Tell the PubSubHubbub we are notifying it of updates
802
+ params = [("hub.mode" , "publish" )]
803
+ # Tell the hub which feeds have been updated
804
+ for feed in hub_feeds :
805
+ if feed .feed_url :
806
+ params .append (("hub.url" , feed .feed_url ))
807
+ else :
808
+ warnings .warn ("Cannot notify feed %s: feed_url not set"
809
+ % feed )
810
+ # Do the notifying!
811
+ if len (params ) > 1 :
812
+ r = requests .post (hub , data = params , timeout = timeout )
813
+ r .raise_for_status ()
814
+ else :
815
+ # No feeds which we can notify this hub of...
816
+ pass
817
+
818
+ def notify_hub (self , requests , timeout = 5.0 ):
819
+ """Notify this podcast's PubSubHubbub hub about new episode(s).
820
+
821
+ When using PubSubHubbub, you must notify it whenever there's a new
822
+ episode available. Use this method to do
823
+ so, *after* the new episode is available -- the hub will check the feed
824
+ to figure out what's new once you do so.
825
+
826
+ :param requests: The requests module, or a Session object.
827
+ :type requests: requests or requests.Session
828
+ :param timeout: Number of seconds to wait for the hub to respond.
829
+ Defaults to five seconds.
830
+ :type timeout: float
831
+
832
+ .. note::
833
+
834
+ This method is blocking, and will return when the server responds.
835
+
836
+ .. note::
837
+
838
+ For this to work, this feed must have
839
+ :attr:`~.Podcast.feed_url` and :attr:`~.Podcast.pubsubhubbub` set
840
+ correctly.
841
+
842
+ .. seealso::
843
+
844
+ The class method :meth:`~.Podcast.notify_multiple`
845
+ For sending notifications about multiple feeds.
846
+
847
+ The :doc:`guide on using PubSubHubbub </advanced/pubsubhubbub>`
848
+ For a step-for-step guide with examples.
849
+ """
850
+ if not self .feed_url :
851
+ raise RuntimeError ("Cannot notify hub of this feed, since feed_url "
852
+ "is not set." )
853
+ elif not self .pubsubhubbub :
854
+ raise RuntimeError ("Cannot notify hub of this feed, since "
855
+ "pubsubhubbub is not set." )
856
+ else :
857
+ self .notify_multiple (requests , [self ], timeout = timeout )
858
+
859
+
860
+
747
861
@property
748
862
def last_updated (self ):
749
863
"""The last time the feed was generated. It defaults to the time and
0 commit comments