def get(self, stream_id):
   mode = self.request.GET['hub.mode']
   topic = self.request.GET['hub.topic']
   challenge = self.request.GET['hub.challenge']
   verify_token = self.request.GET['hub.verify_token']
   
   feedstream = FeedStream.get_by_key_name("z%s" % stream_id)
   if feedstream is None:
     logging.warn("feedstream not found in pshb subscription callback: %s" % topic)
     self.error(404)
     return
   if mode == 'unsubscribe':
     logging.info("pshb unsubscribe callback for %s" % topic)
     feedstream.pshb_is_subscribed = False
     feedstream.put()
     self.response.headers['Content-Type'] = 'text/plain'
     self.response.out.write(challenge)
     return
   if mode != 'subscribe':
     logging.warn("pshb mode unknown %s" % mode)
     self.error(400)
     return
   if feedstream.pshb_verify_token != verify_token:
     logging.warn("verify token's don't match. topic: %s verify_token: %s" % (topic, verify_token))
     self.error(400)
     return
   logging.info("pshb topic subscription callback for %s" % topic)
   feedstream.pshb_is_subscribed = True
   feedstream.put()
   self.response.headers['Content-Type'] = 'text/plain'
   self.response.out.write(challenge)
  def post(self, stream_id):
    """Handles Content Distribution notifications."""
    logging.debug(self.request.headers)
    logging.debug(self.request.body)

    feed = feedparser.parse(self.request.body)
    if feed.bozo:
      logging.error('Bozo feed data. %s: %r',
                     feed.bozo_exception.__class__.__name__,
                     feed.bozo_exception)
      if (hasattr(feed.bozo_exception, 'getLineNumber') and
          hasattr(feed.bozo_exception, 'getMessage')):
        line = feed.bozo_exception.getLineNumber()
        logging.error('Line %d: %s', line, feed.bozo_exception.getMessage())
        segment = self.request.body.split('\n')[line-1]
        logging.info('Body segment with error: %r', segment.decode('utf-8'))
      return self.response.set_status(500)

    feedstream = FeedStream.get_by_key_name("z%s" % stream_id)
    if feedstream is None:
      logging.warn("Discarding update from unknown feed '%s'", stream_id)
      self.error(404)
      return

    logging.info("Processing update for feed '%s'", feedstream.url)
    logging.info('Found %d entries', len(feed.entries))

    to_put = []  # batch datastore updates
    for entry in feed.entries:
      item = FeedItem.process_entry(entry, feedstream)
      if item is not None:
        to_put.append(item)
    if len(to_put) > 0:
      db.put(to_put)
      # update feed last_polled or http_last_modified so feed poller doesn't have to check this feed for a while
      feedstream.last_polled = datetime.utcnow()
      feedstream.put()
      #self.update_mavenn_activity(feedstream.stream_id, to_put)

    # Response headers (body can be empty) 
    # X-Hub-On-Behalf-Of
    self.response.set_status(200)
    self.response.out.write("ok");
 def post(self, key):
   stream = FeedStream.get_by_key_name("z%s" % key)
   db.delete(stream.items)
   stream.deleted = True
   stream.put()
   self.redirect('/admin/')
 def get(self, key):
   stream = FeedStream.get_by_key_name("z%s" % key)    
   self.generate('admin/delete.html', { "stream": stream })
 def get(self, key):
   stream = FeedStream.get_by_key_name("z%s" % key)    
   items = stream.items.order('-updated').fetch(10)
   self.generate('admin/view.html', { "items": items, "stream": stream })
 def get_stream(self, stream_id):
   return FeedStream.get_by_key_name("z%s" % stream_id)