Skip to content

Commit

Permalink
REST API: cache secondary mf2 html fetches as well as primary
Browse files Browse the repository at this point in the history
to handle errors like this:

```
Traceback (most recent call last):
...
File "app.py", line 150, in get
  mf2, fetch_mf2_func=lambda url: mf2py.parse(url=url))
File "microformats2.py", line 728, in find_author
  author = mf2util.find_author(parsed, 'http://123', **kwargs)
File ".../mf2util.py", line 300, in find_author
  parsed = fetch_mf2_func(author_page)
File "app.py", line 150, in <lambda>
  mf2, fetch_mf2_func=lambda url: mf2py.parse(url=url))
...
File ".../requests/packages/urllib3/contrib/appengine.py", line 109, in urlopen
  raise TimeoutError(self, e)
TimeoutError: (<requests.packages.urllib3.contrib.appengine.AppEngineManager object at 0xfb387410>, DeadlineExceededError('Deadline exceeded while waiting for HTTP response from URL: https://aaronparecki.com/',))
```
  • Loading branch information
snarfed committed Mar 14, 2017
1 parent 65b440f commit d74ce20
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 28 deletions.
57 changes: 31 additions & 26 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,37 @@ def get(self):
if input not in expected_inputs:
raise exc.HTTPBadRequest('Invalid input: %s, expected one of %r' %
(input, expected_inputs))
url = util.get_required_param(self, 'url')
url, body = self._urlopen(util.get_required_param(self, 'url'))

# decode data
mf2 = None
if input == 'html':
mf2 = mf2py.parse(doc=body, url=url)
elif input == 'json-mf2':
mf2 = json.loads(body)
mf2.setdefault('rels', {}) # mf2util expects rels

actor = None
title = None
if mf2:
def fetch_mf2_func(url):
_, doc = self._urlopen(url)
return mf2py.parse(doc=doc, url=url)
actor = microformats2.find_author(mf2, fetch_mf2_func=fetch_mf2_func)
title = mf2util.interpret_feed(mf2, url).get('name')

if input == 'activitystreams':
activities = json.loads(body)
elif input == 'html':
activities = microformats2.html_to_activities(body, url, actor)
elif input == 'json-mf2':
activities = [microformats2.json_to_object(item, actor=actor)
for item in mf2.get('items', [])]

self.write_response(source.Source.make_activities_base_response(activities),
url=url, actor=actor, title=title)

def _urlopen(self, url):
# check if request is cached
cache = self.request.get('cache', '').lower() != 'false'
cache_key = 'U %s' % url
Expand Down Expand Up @@ -135,31 +164,7 @@ def get(self):
logging.info('Caching response in %r', cache_key)
memcache.set(cache_key, {'url': url, 'body': body}, URL_CACHE_TIME)

# decode data
mf2 = None
if input == 'html':
mf2 = mf2py.parse(doc=body, url=url)
elif input == 'json-mf2':
mf2 = json.loads(body)
mf2.setdefault('rels', {}) # mf2util expects rels

actor = None
title = None
if mf2:
actor = microformats2.find_author(
mf2, fetch_mf2_func=lambda url: mf2py.parse(url=url))
title = mf2util.interpret_feed(mf2, url).get('name')

if input == 'activitystreams':
activities = json.loads(body)
elif input == 'html':
activities = microformats2.html_to_activities(body, url, actor)
elif input == 'json-mf2':
activities = [microformats2.json_to_object(item, actor=actor)
for item in mf2.get('items', [])]

self.write_response(source.Source.make_activities_base_response(activities),
url=url, actor=actor, title=title)
return url, body


application = webapp2.WSGIApplication([
Expand Down
4 changes: 2 additions & 2 deletions test_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,12 +193,12 @@ def test_url_html_to_atom_rel_author(self):
<a href="/author" rel="author"></a>,
"""
})
self.expect_requests_get('http://my/author', """
self.expect_urlopen('http://my/author', """
<div class="h-card">
<a class="u-url" href="http://my/author">Someone Else</a>
<img class="u-photo" src="http://someone/picture" />
</div>
""", headers=mox.IgnoreArg(), timeout=None)
""", timeout=15)
self.mox.ReplayAll()

resp = app.application.get_response(
Expand Down

0 comments on commit d74ce20

Please sign in to comment.