Skip to content

Commit

Permalink
mf2, as2: add tag-of support
Browse files Browse the repository at this point in the history
  • Loading branch information
snarfed committed Jul 6, 2018
1 parent bd10cf4 commit 7629800
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 12 deletions.
13 changes: 11 additions & 2 deletions granary/as2.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ def _invert(d):
'collection': 'Collection',
'comment': 'Note',
'event': 'Event',
'hashtag': 'Tag', # not in AS2 spec; needed for correct round trip conversion
'image': 'Image',
'note': 'Note',
'person': 'Person',
Expand Down Expand Up @@ -80,6 +81,10 @@ def all_from_as1(field, type=None):
for elem in util.pop_list(obj, field)]

images = all_from_as1('image', type='Image')
inner_objs = all_from_as1('object')
if len(inner_objs) == 1:
inner_objs = inner_objs[0]

obj.update({
'type': type,
'name': obj.pop('displayName', None),
Expand All @@ -89,7 +94,7 @@ def all_from_as1(field, type=None):
'image': images,
'inReplyTo': util.trim_nulls([orig.get('id') or orig.get('url')
for orig in obj.get('inReplyTo', [])]),
'object': from_as1(obj.get('object'), context=None),
'object': inner_objs,
'tag': all_from_as1('tags')
})

Expand Down Expand Up @@ -158,14 +163,18 @@ def all_to_as1(field):
if as1_img not in images:
images.append(as1_img)

inner_objs = all_to_as1('object')
if len(inner_objs) == 1:
inner_objs = inner_objs[0]

obj.update({
'displayName': obj.pop('name', None),
'actor': to_as1(obj.get('actor')),
'attachments': all_to_as1('attachment'),
'image': images,
'inReplyTo': [url_or_as1(orig) for orig in util.get_list(obj, 'inReplyTo')],
'location': url_or_as1(obj.get('location')),
'object': to_as1(obj.get('object')),
'object': inner_objs,
'tags': all_to_as1('tag'),
})

Expand Down
2 changes: 1 addition & 1 deletion granary/github.py
Original file line number Diff line number Diff line change
Expand Up @@ -648,9 +648,9 @@ def _create(self, obj, preview=None, include_link=source.OMIT_LINK,
else:
resp = self.rest(REST_API_ISSUE_LABELS % (owner, repo, number), labels).json()
return source.creation_result({
'id': resp.get('id'),
'url': base_url,
'type': 'tag',
'tags': labels,
})

else: # new issue
Expand Down
32 changes: 24 additions & 8 deletions granary/microformats2.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
$event_times
$location
$categories
$in_reply_tos
$links
$children
$comments
</article>
Expand All @@ -59,7 +59,7 @@
$photos
</span>
""")
IN_REPLY_TO = string.Template(' <a class="u-in-reply-to" href="$url"></a>')
LINK = string.Template(' <a class="u-$cls" href="$url"></a>')
AS_TO_MF2_TYPE = {
'event': ['h-event'],
'person': ['h-card'],
Expand All @@ -76,6 +76,7 @@
'reply': ('comment', None),
'repost': ('activity', 'share'),
'rsvp': ('activity', None), # json_to_object() will generate verb from rsvp
'tag': ('activity', 'tag'),
}
# ISO 6709 location string. http://en.wikipedia.org/wiki/ISO_6709
ISO_6709_RE = re.compile(r'^([-+][0-9.]+)([-+][0-9.]+).*/$')
Expand Down Expand Up @@ -198,8 +199,7 @@ def object_to_json(obj, trim_nulls=True, entry_class='h-entry',
summary = primary.get('summary')
author = obj.get('author', obj.get('actor', {}))

in_reply_tos = obj.get(
'inReplyTo', obj.get('context', {}).get('inReplyTo', []))
in_reply_tos = obj.get('inReplyTo', obj.get('context', {}).get('inReplyTo', []))
is_rsvp = obj_type in ('rsvp-yes', 'rsvp-no', 'rsvp-maybe')
if (is_rsvp or obj_type == 'react') and obj.get('object'):
objs = obj['object']
Expand Down Expand Up @@ -253,13 +253,18 @@ def object_to_json(obj, trim_nulls=True, entry_class='h-entry',
}

# hashtags and person tags
if obj_type == 'tag':
ret['properties']['tag-of'] = util.get_urls(obj, 'target')

tags = obj.get('tags', []) or get_first(obj, 'object', {}).get('tags', [])
if not tags and obj_type == 'tag':
tags = util.get_list(obj, 'object')
ret['properties']['category'] = []
for tag in tags:
if tag.get('objectType') == 'person':
ret['properties']['category'].append(
object_to_json(tag, entry_class='u-category h-card'))
elif tag.get('objectType') == 'hashtag':
elif tag.get('objectType') == 'hashtag' or obj_type == 'tag':
name = tag.get('displayName')
if name:
ret['properties']['category'].append(name)
Expand Down Expand Up @@ -357,6 +362,10 @@ def fetch(url):
mf2_types = mf2.get('type') or []
if 'h-geo' in mf2_types or 'p-location' in mf2_types:
mf2_type = 'location'
elif 'tag-of' in props:
# TODO: remove once this is in mf2util
# https://github.com/kylewm/mf2util/issues/18
mf2_type = 'tag'
else:
# mf2 'photo' type is a note or article *with* a photo, but AS 'photo' type
# *is* a photo. so, special case photo type to fall through to underlying
Expand Down Expand Up @@ -449,6 +458,10 @@ def absolute_urls(prop):
'object': objects[0] if len(objects) == 1 else objects,
'actor': author,
})
if as_verb == 'tag':
obj['target'] = {'url': prop['tag-of']}
assert not obj.get('object')
obj['object'] = obj.pop('tags')
else:
obj.update({
'inReplyTo': [{'url': url} for url in in_reply_tos],
Expand Down Expand Up @@ -555,8 +568,11 @@ def json_to_html(obj, parent_props=None):
return hcard_to_html(obj, parent_props)

props = copy.copy(obj.get('properties', {}))
in_reply_tos = '\n'.join(IN_REPLY_TO.substitute(url=url)
for url in get_string_urls(props.get('in-reply-to', [])))

links = []
for prop in 'in-reply-to', 'tag-of':
links.extend(LINK.substitute(cls=prop, url=url)
for url in get_string_urls(props.get(prop, [])))

prop = first_props(props)
prop.setdefault('uid', '')
Expand Down Expand Up @@ -663,7 +679,7 @@ def json_to_html(obj, parent_props=None):
location=hcard_to_html(location, ['p-location']),
categories='\n'.join(people + tags),
attachments='\n'.join(attachments),
in_reply_tos=in_reply_tos,
links='\n'.join(links),
invitees='\n'.join([hcard_to_html(i, ['p-invitee'])
for i in props.get('invitee', [])]),
content=content_html,
Expand Down
2 changes: 1 addition & 1 deletion granary/test/test_github.py
Original file line number Diff line number Diff line change
Expand Up @@ -972,9 +972,9 @@ def test_create_add_label(self):

result = self.gh.create(TAG_ACTIVITY)
self.assert_equals({
'id': 'DEF456',
'url': 'https://github.com/foo/bar/issues/456',
'type': 'tag',
'tags': ['one'],
}, result.content, result)

def test_preview_add_label(self):
Expand Down
12 changes: 12 additions & 0 deletions granary/test/testdata/tag_of.as.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"objectType": "activity",
"verb": "tag",
"object": [{
"objectType": "hashtag",
"displayName": "one"
}, {
"objectType": "hashtag",
"displayName": "two"
}],
"target": {"url": "https://github.com/foo/bar/issues/456"}
}
9 changes: 9 additions & 0 deletions granary/test/testdata/tag_of.as2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Add",
"object": [
{"name": "one", "type": "Tag"},
{"name": "two", "type": "Tag"}
],
"target": {"url": "https://github.com/foo/bar/issues/456"}
}
9 changes: 9 additions & 0 deletions granary/test/testdata/tag_of.mf2.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<article class="h-entry">
<span class="p-uid"></span>
<span class="p-name"></span>
<div class="">
</div>
<span class="u-category">one</span>
<span class="u-category">two</span>
<a class="u-tag-of" href="https://github.com/foo/bar/issues/456"></a>
</article>
10 changes: 10 additions & 0 deletions granary/test/testdata/tag_of.mf2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"type": ["h-entry"],
"properties": {
"category": [
"one",
"two"
],
"tag-of": ["https://github.com/foo/bar/issues/456"]
}
}

0 comments on commit 7629800

Please sign in to comment.