Example #1
0
 def test_activities_to_jsonfeed_name_is_not_title(self):
     self.assert_equals([{
       'content_html': 'a microblog post',
     }], activities_to_jsonfeed([{
         'content': 'a microblog post',
         'displayName': 'a microblog post',
     }], {})['items'])
Example #2
0
 def test_activities_to_jsonfeed_attachment_without_url(self):
     self.assert_equals([{'content_text': ''}], activities_to_jsonfeed([{
       'attachments': [{
         'content': 'foo',
         'objectType': 'note',
       }],
     }], {})['items'])
Example #3
0
 def test_activities_to_jsonfeed_skip_people(self):
     self.assert_equals({
       'version': 'https://jsonfeed.org/version/1',
       'title': 'JSON Feed',
     }, activities_to_jsonfeed([{
       'objectType': 'person',
       'displayName': 'somebody',
     }], {}))
Example #4
0
 def test_activities_to_jsonfeed_extra_fields(self):
     self.assert_equals({
       'version': 'https://jsonfeed.org/version/1',
       'title': 'a something',
       'feed_url': 'http://a/feed',
       'home_page_url': 'http://a/home',
     }, activities_to_jsonfeed(
       [], {}, title='a something', feed_url='http://a/feed',
       home_page_url='http://a/home'))
Example #5
0
 def test_activities_to_jsonfeed_image_attachment(self):
     self.assert_equals([{
       'content_text': '',
       'attachments': [{
         'url': 'http://pict/ure.jpg',
         'mime_type': 'image/jpeg',
       }],
     }], activities_to_jsonfeed([{
       'attachments': [{'image': {'url': 'http://pict/ure.jpg'}}],
     }], {})['items'])
Example #6
0
 def test_activities_to_jsonfeed_ignore_other_attachment_types(self):
     self.assert_equals([{'content_text': ''}], activities_to_jsonfeed([{
       'attachments': [{
         'url': 'http://quoted/tweet',
         'objectType': 'note',
       }, {
         'url': 'http://some/one',
         'objectType': 'person',
       }],
     }], {})['items'])
Example #7
0
 def test_activities_to_jsonfeed_no_content(self):
     self.assert_equals({
       'version': 'https://jsonfeed.org/version/1',
       'title': 'JSON Feed',
       'items': [{
         'image': 'http://no/content',
         'content_text': '',
       }],
     }, activities_to_jsonfeed([{
       'image': [{'url': 'http://no/content'}],
     }], {}))
Example #8
0
 def test_activities_to_jsonfeed_ignore_other_attachment_types(self):
     self.assert_equals([{
         'content_html':
         '\n<p>\n<a class="link" href="http://some/one">\n</a>\n</p>'
     }],
                        activities_to_jsonfeed([{
                            'attachments': [{
                                'url': 'http://quoted/tweet',
                                'objectType': 'note',
                            }, {
                                'url': 'http://some/one',
                                'objectType': 'person',
                            }],
                        }], {})['items'])
Example #9
0
 def test_activities_to_jsonfeed_image_attachment(self):
     self.assert_equals([{
         'content_html':
         '\n<p>\n<img class="u-photo" src="http://pict/ure.jpg" alt="" />\n</p>',
         'attachments': [{
             'url': 'http://pict/ure.jpg',
             'mime_type': 'image/jpeg',
         }],
     }],
                        activities_to_jsonfeed([{
                            'attachments': [{
                                'image': {
                                    'url': 'http://pict/ure.jpg'
                                }
                            }],
                        }], {})['items'])
Example #10
0
 def test_activities_to_jsonfeed_ignore_other_attachment_types(self):
     self.assert_equals(
         {
             'version': 'https://jsonfeed.org/version/1',
             'title': 'JSON Feed',
             'items': [{
                 'content_text': ''
             }],
         },
         activities_to_jsonfeed([{
             'attachments': [{
                 'url': 'http://quoted/tweet',
                 'objectType': 'note',
             }, {
                 'url': 'http://some/one',
                 'objectType': 'person',
             }],
         }], {}))
Example #11
0
 def test_activities_to_jsonfeed_image_attachment(self):
     self.assert_equals(
         {
             'version':
             'https://jsonfeed.org/version/1',
             'title':
             'JSON Feed',
             'items': [{
                 'content_text':
                 '',
                 'attachments': [{
                     'url': 'http://pict/ure.jpg',
                     'mime_type': 'image/jpeg',
                 }],
             }],
         },
         activities_to_jsonfeed([{
             'attachments': [{
                 'image': {
                     'url': 'http://pict/ure.jpg'
                 }
             }],
         }], {}))
Example #12
0
    def write_response(self,
                       response,
                       actor=None,
                       url=None,
                       title=None,
                       hfeed=None):
        """Converts ActivityStreams activities and writes them out.

    Args:
      response: response dict with values based on OpenSocial ActivityStreams
        REST API, as returned by Source.get_activities_response()
      actor: optional ActivityStreams actor dict for current user. Only used
        for Atom and JSON Feed output.
      url: the input URL
      title: string, used in feed output (Atom, JSON Feed, RSS)
      hfeed: dict, parsed mf2 h-feed, if available
    """
        format = self.request.get('format') or self.request.get(
            'output') or 'json'
        if format not in FORMATS:
            raise exc.HTTPBadRequest('Invalid format: %s, expected one of %r' %
                                     (format, FORMATS))

        if 'plaintext' in self.request.params:
            # override content type
            self.response.headers['Content-Type'] = 'text/plain'
        else:
            content_type = FORMATS.get(format)
            if content_type:
                self.response.headers['Content-Type'] = content_type

        if self.request.method == 'HEAD':
            return

        activities = response['items']
        try:
            if format in ('as1', 'json', 'activitystreams'):
                self.response.out.write(json_dumps(response, indent=2))
            elif format == 'as2':
                response.update({
                    'items': [as2.from_as1(a) for a in activities],
                    'totalItems':
                    response.pop('totalResults', None),
                    'updated':
                    response.pop('updatedSince', None),
                    'filtered':
                    None,
                    'sorted':
                    None,
                })
                self.response.out.write(
                    json_dumps(util.trim_nulls(response), indent=2))
            elif format == 'atom':
                hub = self.request.get('hub')
                reader = self.request.get('reader', 'true').lower()
                if reader not in ('true', 'false'):
                    self.abort(400,
                               'reader param must be either true or false')
                if not actor and hfeed:
                    actor = microformats2.json_to_object({
                        'properties':
                        hfeed.get('properties', {}),
                    })
                self.response.out.write(
                    atom.activities_to_atom(activities,
                                            actor,
                                            host_url=url
                                            or self.request.host_url + '/',
                                            request_url=self.request.url,
                                            xml_base=util.base_url(url),
                                            title=title,
                                            rels={'hub': hub} if hub else None,
                                            reader=(reader == 'true')))
                self.response.headers.add(
                    'Link', str('<%s>; rel="self"' % self.request.url))
                if hub:
                    self.response.headers.add('Link',
                                              str('<%s>; rel="hub"' % hub))
            elif format == 'rss':
                if not title:
                    title = 'Feed for %s' % url
                self.response.out.write(
                    rss.from_activities(activities,
                                        actor,
                                        title=title,
                                        feed_url=self.request.url,
                                        hfeed=hfeed,
                                        home_page_url=util.base_url(url)))
            elif format in ('as1-xml', 'xml'):
                self.response.out.write(XML_TEMPLATE % util.to_xml(response))
            elif format == 'html':
                self.response.out.write(
                    microformats2.activities_to_html(activities))
            elif format in ('mf2-json', 'json-mf2'):
                items = [microformats2.activity_to_json(a) for a in activities]
                self.response.out.write(json_dumps({'items': items}, indent=2))
            elif format == 'jsonfeed':
                try:
                    jf = jsonfeed.activities_to_jsonfeed(
                        activities,
                        actor=actor,
                        title=title,
                        feed_url=self.request.url)
                except TypeError as e:
                    raise exc.HTTPBadRequest('Unsupported input data: %s' % e)
                self.response.out.write(json_dumps(jf, indent=2))
        except ValueError as e:
            logging.warning('converting to output format failed',
                            stack_info=True)
            self.abort(400, 'Could not convert to %s: %s' % (format, str(e)))
Example #13
0
    def write_response(self, response, actor=None, url=None, title=None):
        """Converts ActivityStreams activities and writes them out.

    Args:
      response: response dict with values based on OpenSocial ActivityStreams
        REST API, as returned by Source.get_activities_response()
      actor: optional ActivityStreams actor dict for current user. Only used
        for Atom and JSON Feed output.
      url: the input URL
      title: string, Used in Atom and JSON Feed output
    """
        expected_formats = ('activitystreams', 'json', 'atom', 'xml', 'html',
                            'json-mf2', 'jsonfeed')
        format = self.request.get('format') or self.request.get(
            'output') or 'json'
        if format not in expected_formats:
            raise exc.HTTPBadRequest('Invalid format: %s, expected one of %r' %
                                     (format, expected_formats))

        activities = response['items']

        if format in ('json', 'activitystreams'):
            # list of official MIME types:
            # https://www.iana.org/assignments/media-types/media-types.xhtml
            self.response.headers['Content-Type'] = 'application/json'
            self.response.out.write(json.dumps(response, indent=2))
        elif format == 'atom':
            self.response.headers['Content-Type'] = 'application/atom+xml'
            hub = self.request.get('hub')
            reader = self.request.get('reader', 'true').lower()
            if reader not in ('true', 'false'):
                self.abort(400, 'reader param must be either true or false')
            self.response.out.write(
                atom.activities_to_atom(activities,
                                        actor,
                                        host_url=url
                                        or self.request.host_url + '/',
                                        request_url=self.request.url,
                                        xml_base=util.base_url(url),
                                        title=title,
                                        rels={'hub': hub} if hub else None,
                                        reader=(reader == 'true')))
            self.response.headers.add(
                'Link', str('<%s>; rel="self"' % self.request.url))
            if hub:
                self.response.headers.add('Link', str('<%s>; rel="hub"' % hub))
        elif format == 'xml':
            self.response.headers['Content-Type'] = 'application/xml'
            self.response.out.write(XML_TEMPLATE % util.to_xml(response))
        elif format == 'html':
            self.response.headers['Content-Type'] = 'text/html'
            self.response.out.write(
                microformats2.activities_to_html(activities))
        elif format == 'json-mf2':
            self.response.headers['Content-Type'] = 'application/json'
            items = [microformats2.activity_to_json(a) for a in activities]
            self.response.out.write(json.dumps({'items': items}, indent=2))
        elif format == 'jsonfeed':
            self.response.headers['Content-Type'] = 'application/json'
            try:
                jf = jsonfeed.activities_to_jsonfeed(activities,
                                                     actor=actor,
                                                     title=title,
                                                     feed_url=self.request.url)
            except TypeError as e:
                raise exc.HTTPBadRequest('Unsupported input data: %s' % e)
            self.response.out.write(json.dumps(jf, indent=2))

        if 'plaintext' in self.request.params:
            # override response content type
            self.response.headers['Content-Type'] = 'text/plain'
Example #14
0
  def write_response(self, response, actor=None, url=None, title=None,
                     hfeed=None):
    """Converts ActivityStreams activities and writes them out.

    Args:
      response: response dict with values based on OpenSocial ActivityStreams
        REST API, as returned by Source.get_activities_response()
      actor: optional ActivityStreams actor dict for current user. Only used
        for Atom and JSON Feed output.
      url: the input URL
      title: string, used in feed output (Atom, JSON Feed, RSS)
      hfeed: dict, parsed mf2 h-feed, if available
    """
    format = self.request.get('format') or self.request.get('output') or 'json'
    if format not in FORMATS:
      raise exc.HTTPBadRequest('Invalid format: %s, expected one of %r' %
                               (format, FORMATS))

    activities = response['items']

    try:
      if format in ('as1', 'json', 'activitystreams'):
        # list of official MIME types:
        # https://www.iana.org/assignments/media-types/media-types.xhtml
        self.response.headers['Content-Type'] = \
          'application/json' if format == 'json' else 'application/stream+json'
        self.response.out.write(json.dumps(response, indent=2))
      elif format == 'as2':
        self.response.headers['Content-Type'] = 'application/activity+json'
        response.update({
          'items': [as2.from_as1(a) for a in activities],
          'totalItems': response.pop('totalResults', None),
          'updated': response.pop('updatedSince', None),
          'filtered': None,
          'sorted': None,
        })
        self.response.out.write(json.dumps(util.trim_nulls(response), indent=2))
      elif format == 'atom':
        self.response.headers['Content-Type'] = 'application/atom+xml'
        hub = self.request.get('hub')
        reader = self.request.get('reader', 'true').lower()
        if reader not in ('true', 'false'):
          self.abort(400, 'reader param must be either true or false')
        self.response.out.write(atom.activities_to_atom(
          activities, actor,
          host_url=url or self.request.host_url + '/',
          request_url=self.request.url,
          xml_base=util.base_url(url),
          title=title,
          rels={'hub': hub} if hub else None,
          reader=(reader == 'true')))
        self.response.headers.add('Link', str('<%s>; rel="self"' % self.request.url))
        if hub:
          self.response.headers.add('Link', str('<%s>; rel="hub"' % hub))
      elif format == 'rss':
        self.response.headers['Content-Type'] = 'application/rss+xml'
        if not title:
          title = 'Feed for %s' % url
        self.response.out.write(rss.from_activities(
          activities, actor, title=title,
          feed_url=self.request.url, hfeed=hfeed,
          home_page_url=util.base_url(url)))
      elif format in ('as1-xml', 'xml'):
        self.response.headers['Content-Type'] = 'application/xml'
        self.response.out.write(XML_TEMPLATE % util.to_xml(response))
      elif format == 'html':
        self.response.headers['Content-Type'] = 'text/html'
        self.response.out.write(microformats2.activities_to_html(activities))
      elif format in ('mf2-json', 'json-mf2'):
        self.response.headers['Content-Type'] = 'application/json'
        items = [microformats2.activity_to_json(a) for a in activities]
        self.response.out.write(json.dumps({'items': items}, indent=2))
      elif format == 'jsonfeed':
        self.response.headers['Content-Type'] = 'application/json'
        try:
          jf = jsonfeed.activities_to_jsonfeed(activities, actor=actor, title=title,
                                               feed_url=self.request.url)
        except TypeError as e:
          raise exc.HTTPBadRequest('Unsupported input data: %s' % e)
        self.response.out.write(json.dumps(jf, indent=2))
    except ValueError as e:
      logging.warning('converting to output format failed', exc_info=True)
      self.abort(400, 'Could not convert to %s: %s' % (format, str(e)))

    if 'plaintext' in self.request.params:
      # override response content type
      self.response.headers['Content-Type'] = 'text/plain'
Example #15
0
def activity_to_jsonfeed(obj):
    return jsonfeed.activities_to_jsonfeed([{'object': obj}], ACTOR)
Example #16
0
 def test_activities_to_jsonfeed_not_list(self):
   for bad in None, 3, 'asdf', {'not': 'a list'}:
     with self.assertRaises(TypeError):
       activities_to_jsonfeed(bad)
Example #17
0
def activity_to_jsonfeed(obj):
  return jsonfeed.activities_to_jsonfeed([{'object': obj}], ACTOR)
Example #18
0
def activity_to_jsonfeed(activity):
  return jsonfeed.activities_to_jsonfeed([activity], ACTOR)
Example #19
0
 def test_activities_to_jsonfeed_empty(self):
     self.assert_equals({
       'version': 'https://jsonfeed.org/version/1',
       'title': 'JSON Feed',
     }, activities_to_jsonfeed([], {}))