Example #1
0
def subscribe(source, handler):
  """Subscribes to a source.

  Also receives some past posts and adds propagate tasks for them.

  http://documentation.superfeedr.com/subscribers.html#addingfeedswithpubsubhubbub

  Args:
    source: Blogger, Tumblr, or WordPress
    handler: :class:`webapp2.RequestHandler`
  """
  if appengine_config.DEBUG:
    logging.info('Running in dev_appserver, not subscribing to Superfeedr')
    return

  data = {
    'hub.mode': 'subscribe',
    'hub.topic': source.feed_url(),
    'hub.callback': '%s/%s/notify/%s' % (
      util.host_url(handler), source.SHORT_NAME, source.key.id()),
    # TODO
    # 'hub.secret': 'xxx',
    'format': 'json',
    'retrieve': 'true',
    }

  logging.info('Adding Superfeedr subscription: %s', data)
  resp = util.requests_post(
    PUSH_API_URL, data=data,
    auth=HTTPBasicAuth(appengine_config.SUPERFEEDR_USERNAME,
                       appengine_config.SUPERFEEDR_TOKEN),
    headers=util.REQUEST_HEADERS)
  resp.raise_for_status()
  handle_feed(resp.text, source)
Example #2
0
  def _render_preview(self, result, include_link=False):
    """Renders a preview CreationResult as HTML.

    Args:
      result: CreationResult
      include_link: boolean

    Returns: CreationResult with the rendered HTML in content
    """
    state = {
      'source_key': self.source.key.urlsafe().decode(),
      'source_url': self.source_url(),
      'target_url': self.target_url(),
      'include_link': include_link,
    }
    vars = {
      'source': self.preprocess_source(self.source),
      'preview': result.content,
      'description': result.description,
      'webmention_endpoint': util.host_url(self) + '/publish/webmention',
      'state': util.encode_oauth_state(state),
    }
    vars.update(state)
    logging.info('Rendering preview with template vars %s', pprint.pformat(vars))
    return gr_source.creation_result(
      JINJA_ENV.get_template('preview.html').render(**vars))
Example #3
0
def subscribe(source, handler):
  """Subscribes to a source.

  Also receives some past posts and adds propagate tasks for them.

  http://documentation.superfeedr.com/subscribers.html#addingfeedswithpubsubhubbub

  Args:
    source: Blogger, Tumblr, or WordPress
    handler: :class:`webapp2.RequestHandler`
  """
  if appengine_config.DEBUG:
    logging.info('Running in dev_appserver, not subscribing to Superfeedr')
    return

  data = {
    'hub.mode': 'subscribe',
    'hub.topic': source.feed_url(),
    'hub.callback': '%s/%s/notify/%s' % (
      util.host_url(handler), source.SHORT_NAME, source.key.id()),
    # TODO
    # 'hub.secret': 'xxx',
    'format': 'json',
    'retrieve': 'true',
    }

  logging.info('Adding Superfeedr subscription: %s', data)
  resp = util.requests_post(
    PUSH_API_URL, data=data,
    auth=HTTPBasicAuth(appengine_config.SUPERFEEDR_USERNAME,
                       appengine_config.SUPERFEEDR_TOKEN),
    headers=util.REQUEST_HEADERS)
  resp.raise_for_status()
  handle_feed(resp.text, source)
Example #4
0
  def _render_preview(self, result, include_link=False):
    """Renders a preview CreationResult as HTML.

    Args:
      result: CreationResult
      include_link: boolean

    Returns: CreationResult with the rendered HTML in content
    """
    state = {
      'source_key': self.source.key.urlsafe(),
      'source_url': self.source_url(),
      'target_url': self.target_url(),
      'include_link': include_link,
    }
    vars = {
      'source': self.preprocess_source(self.source),
      'preview': result.content,
      'description': result.description,
      'webmention_endpoint': util.host_url(self) + '/publish/webmention',
      'state': util.encode_oauth_state(state),
    }
    vars.update(state)
    logging.info('Rendering preview with template vars %s', pprint.pformat(vars))
    return gr_source.creation_result(
      JINJA_ENV.get_template('preview.html').render(**vars))
Example #5
0
def subscribe(source):
    """Subscribes to a source.

  Also receives some past posts and adds propagate tasks for them.

  http://documentation.superfeedr.com/subscribers.html#addingfeedswithpubsubhubbub

  Args:
    source: Blogger, Tumblr, or WordPress
  """
    if appengine_info.LOCAL:
        logger.info('Running locally, not subscribing to Superfeedr')
        return

    data = {
        'hub.mode':
        'subscribe',
        'hub.topic':
        source.feed_url(),
        'hub.callback':
        util.host_url(f'/{source.SHORT_NAME}/notify/{source.key_id()}'),
        # TODO
        # 'hub.secret': 'xxx',
        'format':
        'json',
        'retrieve':
        'true',
    }

    logger.info(f'Adding Superfeedr subscription: {data}')
    resp = util.requests_post(PUSH_API_URL,
                              data=data,
                              auth=HTTPBasicAuth(SUPERFEEDR_USERNAME,
                                                 SUPERFEEDR_TOKEN))
    handle_feed(resp.json(), source)
Example #6
0
    def post(self):
        self.request.headers[
            'Content-Type'] = 'application/x-www-form-urlencoded'
        logging.debug('Params: %s', list(self.request.params.items()))
        if not self.lease(
                ndb.Key(urlsafe=self.request.params['response_key'])):
            return

        source = self.source = self.entity.source.get()
        if not source:
            logging.warning('Source not found! Dropping response.')
            return
        logging.info('Source: %s %s, %s', source.label(), source.key_id(),
                     source.bridgy_url(self))
        poll_estimate = self.entity.created - datetime.timedelta(seconds=61)
        logging.info('Created by this poll: %s/%s', util.host_url(self),
                     logs.url(poll_estimate, source.key))

        self.activities = [json_loads(a) for a in self.entity.activities_json]
        response_obj = json_loads(self.entity.response_json)
        if (not source.is_activity_public(response_obj) or
                not all(source.is_activity_public(a)
                        for a in self.activities)):
            logging.info('Response or activity is non-public. Dropping.')
            self.complete()
            return

        self.send_webmentions()
Example #7
0
    def get(self, site=None):
        self.head(site)
        self.response.out.write("""\
<!DOCTYPE html>
<html><head>
<link rel="webmention" href="%s/publish/webmention">
</head>
<body>Nothing here! <a href="/about">Try the docs instead.</a></body>
</html>""" % util.host_url(self))
Example #8
0
  def get(self, site=None):
    self.head(site)
    self.response.out.write("""\
<!DOCTYPE html>
<html><head>
<link rel="webmention" href="%s/publish/webmention">
</head>
<body>Nothing here! <a href="/about">Try the docs instead.</a></body>
</html>""" % util.host_url(self))
Example #9
0
    def dispatch_request(self):
        token = request.values['token']

        domains = [d.key.id() for d in Domain.query(Domain.tokens == token)]
        if not domains:
            indieauth_start = util.host_url(f'/indieauth/start?token={token}')
            self.error(
                f'Not connected to Bridgy. <a href="{indieauth_start}" target="_blank"">Connect now!</a>',
                404)

        return jsonify(domains)
Example #10
0
    def test_host_url(self):
        with app.test_request_context():
            self.assertEqual('http://localhost/', util.host_url())
            self.assertEqual('http://localhost/asdf', util.host_url('asdf'))
            self.assertEqual('http://localhost/foo/bar',
                             util.host_url('/foo/bar'))

        with app.test_request_context(base_url='https://a.xyz', path='/foo'):
            self.assertEqual('https://a.xyz/', util.host_url())
            self.assertEqual('https://a.xyz/asdf', util.host_url('asdf'))
            self.assertEqual('https://a.xyz/foo/bar',
                             util.host_url('/foo/bar'))
Example #11
0
    def dispatch_request(self):
        logger.debug(f'Params: {list(request.values.items())}')
        if not self.lease(ndb.Key(urlsafe=request.values['response_key'])):
            return ('', ERROR_HTTP_RETURN_CODE) if getattr(g, 'failed',
                                                           None) else 'OK'

        source = g.source
        poll_estimate = self.entity.created - datetime.timedelta(seconds=61)
        poll_url = util.host_url(logs.url(poll_estimate, source.key))
        logger.info(f'Created by this poll: {poll_url}')

        self.activities = [json_loads(a) for a in self.entity.activities_json]
        response_obj = json_loads(self.entity.response_json)
        if (not source.is_activity_public(response_obj) or
                not all(source.is_activity_public(a)
                        for a in self.activities)):
            logger.info('Response or activity is non-public. Dropping.')
            self.complete()
            return ''

        self.send_webmentions()
        return ('',
                ERROR_HTTP_RETURN_CODE) if getattr(g, 'failed', None) else 'OK'
Example #12
0
    def source_url(self, target_url):
        # determine which activity to use
        try:
            activity = self.activities[0]
            if self.entity.urls_to_activity:
                urls_to_activity = json_loads(self.entity.urls_to_activity)
                if urls_to_activity:
                    activity = self.activities[urls_to_activity[target_url]]
        except (KeyError, IndexError):
            logging.warning(
                """\
Hit https://github.com/snarfed/bridgy/issues/237 KeyError!
target url %s not in urls_to_activity: %s
activities: %s""", target_url, self.entity.urls_to_activity, self.activities)
            self.abort(util.ERROR_HTTP_RETURN_CODE)

        # generate source URL
        id = activity['id']
        parsed = util.parse_tag_uri(id)
        post_id = parsed[1] if parsed else id
        parts = [
            util.host_url(self), self.entity.type, self.source.SHORT_NAME,
            self.source.key.string_id(), post_id
        ]

        if self.entity.type != 'post':
            # parse and add response id. (we know Response key ids are always tag URIs)
            _, response_id = util.parse_tag_uri(self.entity.key.string_id())
            reaction_id = response_id
            if self.entity.type in ('like', 'react', 'repost', 'rsvp'):
                response_id = response_id.split('_')[
                    -1]  # extract responder user id
            parts.append(response_id)
            if self.entity.type == 'react':
                parts.append(reaction_id)

        return '/'.join(parts)
Example #13
0
 def bridgy_url(self, handler):
   """Returns the Bridgy page URL for this source."""
   return util.host_url(handler) + self.bridgy_path()
Example #14
0
 def _last_poll_url(self, source):
     return '%s/%s' % (util.host_url(self),
                       logs.url(source.last_poll_attempt, source.key))
Example #15
0
 def _last_poll_url(self, source):
     return util.host_url(logs.url(source.last_poll_attempt, source.key))
Example #16
0
 def head(self, site=None):
     self.response.headers['Link'] = (
         '<%s/publish/webmention>; rel="webmention"' % util.host_url(self))
Example #17
0
 def app_url(self):
     return util.host_url()
Example #18
0
 def bridgy_url(self, handler):
     """Returns the Bridgy page URL for this source."""
     return util.host_url(handler) + self.bridgy_path()
Example #19
0
 def __init__(self, url):
     self.url = url
     self.host_url = u.host_url(url)
     self.path = u.path(url)
Example #20
0
 def head(self, site=None):
   self.response.headers['Link'] = (
     '<%s/publish/webmention>; rel="webmention"' % util.host_url(self))