home *** CD-ROM | disk | FTP | other *** search
/ Freelog 125 / Freelog_MarsAvril2015_No125.iso / Internet / gpodder / gpodder-portable.exe / gpodder-portable / src / mygpoclient / feeds.py < prev    next >
Text File  |  2014-10-30  |  5KB  |  161 lines

  1. # -*- coding: utf-8 -*-
  2. # mygpo-feedservice Client
  3. # Copyright (C) 2011 Stefan K├╢gl
  4. #
  5. # This program is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation, either version 3 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program.  If not, see <http://www.gnu.org/licenses/>.
  17.  
  18. from __future__ import absolute_import
  19.  
  20. import urllib, urlparse, time
  21. from datetime import datetime
  22. from email import utils
  23.  
  24. import mygpoclient.json
  25.  
  26. try:
  27.     # Prefer the usage of the simplejson module, as it
  28.     # is most likely newer if it's installed as module
  29.     # than the built-in json module (and is mandatory
  30.     # in Python versions before 2.6, anyway).
  31.     import simplejson as json
  32. except ImportError:
  33.     # Python 2.6 ships the "json" module by default
  34.     import json
  35.  
  36.  
  37. BASE_URL='http://mygpo-feedservice.appspot.com'
  38.  
  39.  
  40. class FeedServiceResponse(list):
  41.     """
  42.     Encapsulates the relevant data of a mygpo-feedservice response
  43.     """
  44.  
  45.     def __init__(self, feeds, last_modified, feed_urls):
  46.         super(FeedServiceResponse, self).__init__(feeds)
  47.         self.last_modified = last_modified
  48.         self.feed_urls = feed_urls
  49.         self.indexed_feeds = {}
  50.         for feed in feeds:
  51.             for url in feed['urls']:
  52.                 self.indexed_feeds[url] = feed
  53.  
  54.  
  55.     def get_feeds(self):
  56.         """
  57.         Returns the parsed feeds in order of the initial request
  58.         """
  59.         return (self.get_feed(url) for url in self.feed_urls)
  60.  
  61.  
  62.     def get_feed(self, url):
  63.         """
  64.         Returns the parsed feed for the given URL
  65.         """
  66.         return self.indexed_feeds.get(url, None)
  67.  
  68.  
  69. class FeedserviceClient(mygpoclient.json.JsonClient):
  70.     """A special-cased JsonClient for mygpo-feedservice"""
  71.  
  72.     def __init__(self, username=None, password=None, base_url=BASE_URL):
  73.         self._base_url = base_url
  74.         super(FeedserviceClient, self).__init__(username, password)
  75.  
  76.     def _prepare_request(self, method, uri, data):
  77.         """Sets headers required by mygpo-feedservice
  78.  
  79.         Expects a dict with keys feed_urls and (optionally) last_modified"""
  80.  
  81.         # send URLs as POST data to avoid any length
  82.         # restrictions for the query parameters
  83.         post_data = [('url', feed_url) for feed_url in data['feed_urls']]
  84.         post_data = urllib.urlencode(post_data)
  85.  
  86.         # call _prepare_request directly from HttpClient, because
  87.         # JsonClient would JSON-encode our POST-data
  88.         request = mygpoclient.http.HttpClient._prepare_request(method, uri, post_data)
  89.         request.add_header('Accept', 'application/json')
  90.         request.add_header('Accept-Encoding', 'gzip')
  91.  
  92.         last_modified = data.get('last_modified', None)
  93.         if last_modified is not None:
  94.             request.add_header('If-Modified-Since', self.format_header_date(last_modified))
  95.  
  96.         return request
  97.  
  98.  
  99.     def _process_response(self, response):
  100.         """ Extract Last-modified header and passes response body
  101.             to JsonClient for decoding"""
  102.  
  103.         last_modified = self.parse_header_date(response.headers['last-modified'])
  104.         feeds = super(FeedserviceClient, self)._process_response(response)
  105.         return feeds, last_modified
  106.  
  107.  
  108.     def parse_feeds(self, feed_urls, last_modified=None, strip_html=False,
  109.                 use_cache=True, inline_logo=False, scale_logo=None,
  110.                 logo_format=None):
  111.         """
  112.         Passes the given feed-urls to mygpo-feedservice to be parsed
  113.         and returns the response
  114.         """
  115.  
  116.         url = self.build_url(strip_html=strip_html, use_cache=use_cache,
  117.                 inline_logo=inline_logo, scale_logo=scale_logo,
  118.                 logo_format=logo_format)
  119.  
  120.         request_data = dict(feed_urls=feed_urls, last_modified=last_modified)
  121.  
  122.         feeds, last_modified = self.POST(url, request_data)
  123.  
  124.         return FeedServiceResponse(feeds, last_modified, feed_urls)
  125.  
  126.  
  127.     def build_url(self, **kwargs):
  128.         """
  129.         Parameter such as strip_html, scale_logo, etc are pased as kwargs
  130.         """
  131.  
  132.         query_url = urlparse.urljoin(self._base_url, 'parse')
  133.  
  134.         args = kwargs.items()
  135.         args = filter(lambda (k, v): v is not None, args)
  136.  
  137.         # boolean flags are represented as 1 and 0 in the query-string
  138.         args = map(lambda (k, v): (k, int(v) if isinstance(v, bool) else v), args)
  139.         args = urllib.urlencode(dict(args))
  140.  
  141.         url = '%s?%s' % (query_url, args)
  142.         return url
  143.  
  144.  
  145.     @staticmethod
  146.     def parse_header_date(date_str):
  147.         """
  148.         Parses dates in RFC2822 format to datetime objects
  149.         """
  150.         if not date_str:
  151.             return None
  152.         ts = time.mktime(utils.parsedate(date_str))
  153.         return datetime.utcfromtimestamp(ts)
  154.  
  155.     @staticmethod
  156.     def format_header_date(datetime_obj):
  157.         """
  158.         Formats the given datetime object for use in HTTP headers
  159.         """
  160.         return utils.formatdate(time.mktime(datetime_obj.timetuple()))
  161.