def user_to_actor(self, user): """Converts a user to an actor. Args: user: dict, a decoded JSON Facebook user Returns: an ActivityStreams actor dict, ready to be JSON-encoded """ if not user: return {} id = user.get("id") username = user.get("username") handle = username or id if not handle: return {} url = user.get("link") if not url: url = "http://facebook.com/" + handle # facebook implements this as a 302 redirect image_url = "http://graph.facebook.com/%s/picture?type=large" % handle actor = { "displayName": user.get("name"), "image": {"url": image_url}, "id": self.tag_uri(handle), "updated": util.maybe_iso8601_to_rfc3339(user.get("updated_time")), "url": url, "username": username, "description": user.get("bio"), } location = user.get("location") if location: actor["location"] = {"id": location.get("id"), "displayName": location.get("name")} return util.trim_nulls(actor)
def post_to_object(self, post): """Converts a post to an object. Args: post: dict, a decoded JSON post Returns: an ActivityStreams object dict, ready to be JSON-encoded """ object = {} id = post.get("id") if not id: return {} post_type = post.get("type") status_type = post.get("status_type") url = "http://facebook.com/" + id.replace("_", "/posts/") picture = post.get("picture") message = post.get("message") if not message: message = post.get("story") display_name = None data = post.get("data", {}) for field in ("object", "song"): obj = data.get(field) if obj: id = obj.get("id") post_type = obj.get("type") url = obj.get("url") display_name = obj.get("title") object_type = OBJECT_TYPES.get(post_type) author = self.user_to_actor(post.get("from")) link = post.get("link", "") if link.startswith("/gifts/"): object_type = "product" if not object_type: if picture and not message: object_type = "image" else: object_type = "note" object = { "id": self.tag_uri(str(id)), "objectType": object_type, "published": util.maybe_iso8601_to_rfc3339(post.get("created_time")), "updated": util.maybe_iso8601_to_rfc3339(post.get("updated_time")), "author": author, "content": message, # FB post ids are of the form USERID_POSTID "url": url, "image": {"url": picture}, "displayName": display_name, } # tags tags = itertools.chain( post.get("to", {}).get("data", []), post.get("with_tags", {}).get("data", []), *post.get("message_tags", {}).values() ) object["tags"] = [ { "objectType": OBJECT_TYPES.get(t.get("type"), "person"), "id": self.tag_uri(t.get("id")), "url": "http://facebook.com/%s" % t.get("id"), "displayName": t.get("name"), "startIndex": t.get("offset"), "length": t.get("length"), } for t in tags ] # is there an attachment? prefer to represent it as a picture (ie image # object), but if not, fall back to a link. att = { "url": link if link else url, "image": {"url": picture}, "displayName": post.get("name"), "summary": post.get("caption"), "content": post.get("description"), } if picture and picture.endswith("_s.jpg") and (post_type == "photo" or status_type == "added_photos"): # a picture the user posted. get a larger size. att.update({"objectType": "image", "image": {"url": picture[:-6] + "_o.jpg"}}) object["attachments"] = [att] elif link and not link.startswith("/gifts/"): att["objectType"] = "article" object["attachments"] = [att] # location place = post.get("place") if place: id = place.get("id") object["location"] = {"displayName": place.get("name"), "id": id, "url": "http://facebook.com/" + id} location = place.get("location", None) if isinstance(location, dict): lat = location.get("latitude") lon = location.get("longitude") if lat and lon: object["location"].update( { "latitude": lat, "longitude": lon, # ISO 6709 location string. details: http://en.wikipedia.org/wiki/ISO_6709 "position": "%+f%+f/" % (lat, lon), } ) # comments go in the replies field, according to the "Responses for # Activity Streams" extension spec: # http://activitystrea.ms/specs/json/replies/1.0/ comments = post.get("comments", {}).get("data") if comments: items = [self.comment_to_object(c) for c in comments] object["replies"] = {"items": items, "totalItems": len(items)} return util.trim_nulls(object)