def poll(self, source): activities = source.get_activities(group_id=as_source.SELF, fetch_likes=True) resps = ndb.get_multi(ndb.Key('Response', util.trim_nulls(a['id'])) for a in activities) resps = {r.key.id(): r for r in resps if r} for activity in activities: obj = activity.get('object', {}) # have we already posted or started on this response? resp = resps.get(activity['id']) mf2 = microformats2.object_to_json(activity) mf2_props = microformats2.first_props(mf2.get('properties', {})) type = as_source.object_type(activity) if mf2_props.get('in-reply-to'): type = 'comment' # twitter reply if type not in TYPES or (resp and resp.status == 'complete'): continue elif resp: logging.info('Retrying %s', resp) else: resp = Response.get_or_insert(activity['id'], activity_json=json.dumps(activity)) logging.info('Created new Response: %s', resp) base_id = source.base_object(activity)['id'] base = source.get_activities(activity_id=base_id)[0] # make micropub call to create post # http://indiewebcamp.com/micropub # # include access token in both header and post body for compatibility # with servers that only support one or the other (for whatever reason). headers = {'Authorization': 'Bearer ' + MICROPUB_ACCESS_TOKEN} data = mf2_props data.update({ 'access_token': MICROPUB_ACCESS_TOKEN, 'h': 'entry', 'category[]': CATEGORIES.get(type), 'content': self.render(source, activity, base), 'name': base.get('content') or base.get('object', {}).get('content') }) for prop in 'url', 'author': if prop in data: del data[prop] result = self.urlopen(MICROPUB_ENDPOINT, headers=headers, data=util.trim_nulls(data)) resp.post_url = result.info().get('Location') logging.info('Created new post: %s', resp.post_url) resp.response_body = result.read() logging.info('Response body: %s', resp.response_body) resp.status = 'complete' resp.put()
def render(source, activity, base): obj = activity.get('object') or activity content = microformats2.render_content(obj) embed = source.embed_post(base) type = as_source.object_type(activity) content = activity.get('content', '') if type == 'share' and not content: content = 'retweeted this.' rendered = embed + content if type == 'comment' else content + embed mf2_class = {'like': 'u-like-of', 'share': 'u-repost-of', }.get(type, 'in-reply-to') url = base.get('url') rendered += '\n<a class="%s" href="%s"></a>' % (mf2_class, url) return rendered