def praw_to_object(self, thing, type): """ Converts a praw object to an object. currently only returns public content Note that this will make external API calls to lazily load some attrs Args: thing: a praw object, Submission or Comment type: string to denote whether to get submission or comment content Returns: an ActivityStreams object dict, ready to be JSON-encoded """ obj = {} id = getattr(thing, 'id', None) if not id: return {} published = util.maybe_timestamp_to_iso8601(getattr(thing, 'created_utc', None)) obj = { 'id': self.tag_uri(id), 'published': published, 'to': [{ 'objectType': 'group', 'alias': '@public', }], } user = getattr(thing, 'author', None) if user: obj['author'] = self.praw_to_actor(user) username = obj['author'].get('username') obj['url'] = self.BASE_URL + thing.permalink if type == 'submission': obj['content'] = getattr(thing, 'title', None) obj['objectType'] = 'note' obj['tags'] = [ {'objectType': 'article', 'url': t, 'displayName': t, } for t in util.extract_links(getattr(thing, 'selftext', None)) ] elif type == 'comment': obj['content'] = getattr(thing, 'body_html', None) obj['objectType'] = 'comment' reply_to = thing.parent() if reply_to: obj['inReplyTo'] = [{ 'id': self.tag_uri(getattr(reply_to, 'id', None)), 'url': self.BASE_URL + getattr(reply_to, 'permalink', None), }] return self.postprocess_object(obj)
def user_to_actor(self, user): """Converts a dict user to an actor. Args: user: json user Returns: an ActivityStreams actor dict, ready to be JSON-encoded """ username = user.get('name') if not username: return {} # trying my best to grab all the urls from the profile description description = '' subreddit = user.get('subreddit') if subreddit: user_url = self.BASE_URL + subreddit.get('url') urls = [user_url] description = subreddit.get('public_description') profile_urls = util.extract_links(description) urls += util.trim_nulls(profile_urls) else: urls = [self.BASE_URL + '/user/' + username] image = user.get('icon_img') return util.trim_nulls({ 'objectType': 'person', 'displayName': username, 'image': { 'url': image }, 'id': self.tag_uri(username), # numeric_id is our own custom field that always has the source's numeric # user id, if available. 'numeric_id': user.get('id'), 'published': util.maybe_timestamp_to_iso8601(user.get('created_utc')), 'url': urls[0], 'urls': [{ 'value': u } for u in urls] if len(urls) > 1 else None, 'username': username, 'description': description, })
def praw_to_object(self, thing, type): """ Converts a praw object to an object. currently only returns public content Args: thing: a praw object, Submission or Comment type: string to denote whether to get submission or comment content Returns: an ActivityStreams object dict, ready to be JSON-encoded """ obj = {} id = thing.id if not id: return {} published = util.maybe_timestamp_to_iso8601(thing.created_utc) obj = { 'id': self.tag_uri(id), 'published': published, 'to': [{ 'objectType': 'group', 'alias': '@public', }], } user = thing.author if user: obj['author'] = self.praw_to_actor(user) username = obj['author'].get('username') obj['url'] = self.BASE_URL + thing.permalink if type == 'submission': obj['content'] = thing.title obj['objectType'] = 'note' obj['tags'] = [{ 'objectType': 'article', 'url': t, 'displayName': t, } for t in util.extract_links(thing.selftext)] elif type == 'comment': obj['content'] = thing.body obj['objectType'] = 'comment' reply_to = thing.parent() if reply_to: obj['inReplyTo'] = [{ 'id': self.tag_uri(reply_to.id), 'url': self.BASE_URL + reply_to.permalink, }] return self.postprocess_object(obj)
def user_to_actor(self, account): """Converts a Mastodon account to an AS1 actor. Args: account: dict, Mastodon account Returns: dict, AS1 actor """ domain = self.DOMAIN username = account.get('username') # parse acct. it's just username for local accounts but fully qualified # address for remote accounts, eg [email protected]. acct = account.get('acct') or '' split = acct.split('@') if len(split) in (2, 3): acct_username, acct_domain = split[-2:] if acct_domain: domain = acct_domain if not username: username = acct[-2] elif acct_username and username != acct_username: raise ValueError('username %s and acct %s conflict!' % (username, acct)) if not username: return {} url = account.get('url') # mastodon's 'Web site' fields are HTML links, so extract their URLs web_sites = sum((util.extract_links(f.get('value')) for f in (account.get('fields') or [])), []) # account.created_at is string ISO8601 in Mastodon, int timestamp in Pixelfed published = account.get('created_at') if util.is_int(published) or util.is_float(published): published = util.maybe_timestamp_to_iso8601(published) return util.trim_nulls({ 'objectType': 'person', 'id': util.tag_uri(domain, username), 'numeric_id': account.get('id'), 'username': username, 'displayName': account.get('display_name') or acct or username, 'url': url, 'urls': [{'value': u} for u in [url] + web_sites], 'image': {'url': account.get('avatar')}, 'published': published, 'description': account.get('note'), })