kopia lustrzana https://github.com/snarfed/bridgy-fed
add new /render endpoint for rendering Responses as HTML
rodzic
6a65e2e74a
commit
98465907ff
4
app.yaml
4
app.yaml
|
|
@ -74,6 +74,10 @@ handlers:
|
||||||
script: salmon.app
|
script: salmon.app
|
||||||
secure: always
|
secure: always
|
||||||
|
|
||||||
|
- url: /render
|
||||||
|
script: render.app
|
||||||
|
secure: always
|
||||||
|
|
||||||
- url: /(acct:)?[^/]+/?
|
- url: /(acct:)?[^/]+/?
|
||||||
script: webfinger.app
|
script: webfinger.app
|
||||||
secure: always
|
secure: always
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
# coding=utf-8
|
||||||
|
"""Renders mf2 proxy pages based on stored Responses."""
|
||||||
|
import json
|
||||||
|
|
||||||
|
import appengine_config
|
||||||
|
|
||||||
|
from granary import as2, microformats2
|
||||||
|
from oauth_dropins.webutil.handlers import ModernHandler
|
||||||
|
from oauth_dropins.webutil import util
|
||||||
|
import webapp2
|
||||||
|
|
||||||
|
from models import Response
|
||||||
|
|
||||||
|
|
||||||
|
class RenderHandler(ModernHandler):
|
||||||
|
"""Fetches a stored Response and renders it as HTML."""
|
||||||
|
|
||||||
|
def get(self):
|
||||||
|
source = util.get_required_param(self, 'source')
|
||||||
|
target = util.get_required_param(self, 'target')
|
||||||
|
|
||||||
|
id = '%s %s' % (source, target)
|
||||||
|
resp = Response.get_by_id(id)
|
||||||
|
if not resp:
|
||||||
|
self.abort(404, 'No stored response for %s' % id)
|
||||||
|
|
||||||
|
if resp.source_mf2:
|
||||||
|
as1 = microformats2.json_to_object(json.loads(resp.source_mf2))
|
||||||
|
elif resp.source_as2:
|
||||||
|
as1 = as2.to_as1(json.loads(resp.source_as2))
|
||||||
|
elif resp.source_atom:
|
||||||
|
self.abort(501, 'Rendering HTML from Atom is not yet implemented.')
|
||||||
|
else:
|
||||||
|
self.abort(404, 'Stored response for %s has no data' % id)
|
||||||
|
|
||||||
|
self.response.write(microformats2.activities_to_html([as1]))
|
||||||
|
|
||||||
|
|
||||||
|
app = webapp2.WSGIApplication([
|
||||||
|
('/render', RenderHandler),
|
||||||
|
], debug=appengine_config.DEBUG)
|
||||||
|
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
# coding=utf-8
|
||||||
|
"""Unit tests for render.py."""
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import json
|
||||||
|
|
||||||
|
from models import Response
|
||||||
|
import testutil
|
||||||
|
from render import app
|
||||||
|
|
||||||
|
|
||||||
|
class RenderTest(testutil.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(RenderTest, self).setUp()
|
||||||
|
|
||||||
|
self.as2 = {
|
||||||
|
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||||
|
'type': 'Note',
|
||||||
|
'content': 'A ☕ reply',
|
||||||
|
'url': 'http://this/reply',
|
||||||
|
'inReplyTo': 'http://orig/post',
|
||||||
|
}
|
||||||
|
self.mf2 = {
|
||||||
|
'type': ['h-entry'],
|
||||||
|
'properties': {
|
||||||
|
'url': ['http://this/reply'],
|
||||||
|
'content': [{'value': 'A ☕ reply'}],
|
||||||
|
'in-reply-to': ['http://orig/post'],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
self.html = """\
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head><meta charset="utf-8"></head>
|
||||||
|
<body>
|
||||||
|
<article class="h-entry">
|
||||||
|
<span class="p-uid"></span>
|
||||||
|
<a class="u-url" href="http://this/reply">http://this/reply</a>
|
||||||
|
<div class="e-content p-name">
|
||||||
|
A ☕ reply
|
||||||
|
</div>
|
||||||
|
<a class="u-in-reply-to" href="http://orig/post"></a>
|
||||||
|
</article>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
"""
|
||||||
|
|
||||||
|
def test_render_errors(self):
|
||||||
|
for source, target in ('', ''), ('abc', ''), ('', 'xyz'):
|
||||||
|
resp = app.get_response('/render?source=%s&target=%s' % (source, target))
|
||||||
|
self.assertEquals(400, resp.status_int, resp.body)
|
||||||
|
|
||||||
|
# no Response
|
||||||
|
resp = app.get_response('/render?source=abc&target=xyz')
|
||||||
|
self.assertEquals(404, resp.status_int)
|
||||||
|
|
||||||
|
# no source data
|
||||||
|
Response(id='abc xyz').put()
|
||||||
|
resp = app.get_response('/render?source=abc&target=xyz')
|
||||||
|
self.assertEquals(404, resp.status_int)
|
||||||
|
|
||||||
|
def test_render_as2(self):
|
||||||
|
Response(id='abc xyz', source_as2=json.dumps(self.as2)).put()
|
||||||
|
resp = app.get_response('/render?source=abc&target=xyz')
|
||||||
|
self.assertEquals(200, resp.status_int)
|
||||||
|
self.assert_multiline_equals(self.html, resp.body.decode('utf-8'),
|
||||||
|
ignore_blanks=True)
|
||||||
|
|
||||||
|
def test_render_mf2(self):
|
||||||
|
Response(id='abc xyz', source_mf2=json.dumps(self.mf2)).put()
|
||||||
|
resp = app.get_response('/render?source=abc&target=xyz')
|
||||||
|
self.assertEquals(200, resp.status_int)
|
||||||
|
self.assert_multiline_equals(self.html, resp.body.decode('utf-8'),
|
||||||
|
ignore_blanks=True)
|
||||||
|
|
@ -5,8 +5,10 @@ import unittest
|
||||||
from google.appengine.datastore import datastore_stub_util
|
from google.appengine.datastore import datastore_stub_util
|
||||||
from google.appengine.ext import testbed
|
from google.appengine.ext import testbed
|
||||||
|
|
||||||
|
from oauth_dropins.webutil import testutil
|
||||||
|
|
||||||
class TestCase(unittest.TestCase):
|
|
||||||
|
class TestCase(unittest.TestCase, testutil.Asserts):
|
||||||
|
|
||||||
maxDiff = None
|
maxDiff = None
|
||||||
|
|
||||||
|
|
|
||||||
Ładowanie…
Reference in New Issue