def retrieve(self, request, pk): try: author = Author.objects.get(pk=pk) except: print("DID WE GET HERE?", pk) return Response("Invalid author ID specified", status=404) url = get_author_url(pk) data = { "id": url, "host": get_host_url(), "displayName": author.displayName or author.user.username, "url": url, "friends": get_author_summaries(get_friends(url)) } if (author.github): data["github"] = author.github if (author.user.first_name): data["firstName"] = author.user.first_name if (author.user.last_name): data["lastName"] = author.user.last_name if (author.user.email): data["email"] = author.user.email if (author.bio): data["bio"] = author.bio return Response(data)
def get_images(postId): images = Posts.objects.filter(post_id=postId).exclude( contentType__contains="text") url = [] host_url = get_host_url() for img in images: image_url = urljoin(host_url, "posts", str(img.id), "image") url.append(image_url) return url
def get_summary(instance): url = instance.get_url() summary = { "host": get_host_url(), "url": url, "id": url, "displayName": instance.get_display_name() } if (instance.github): summary["github"] = instance.github return summary
def test_custom_size(self): post = Posts.objects.create(visibility="PUBLIC", author=self.author1) comments = [] for i in range(0, 100): comments.append( Comments.objects.create(post=post, comment="Hello{0}".format(i), author=self.author1.get_url())) res = self.client.get("/posts/{0}/comments/".format(post.id), { "page": 0, "size": 25 }) self.assertEqual(res.status_code, 200) self.maxDiff = None author_details = { "id": self.author1.get_url(), "url": self.author1.get_url(), "host": get_host_url(), "displayName": self.author1.get_display_name() } expected_comments = [] for i in range(99, 74, -1): expected_comments.append({ "author": author_details, "comment": comments[i].comment, "contentType": comments[i].contentType, "published": date_to_str(comments[i].published), "id": str(comments[i].id) }) self.assertEqual( res.json(), { "query": "comments", "count": 100, "size": 25, "next": "http://testserver/posts/{0}/comments/?page=1".format(post.id), "comments": expected_comments })
def to_representation(self, instance): representation = super(PostsSerializer, self).to_representation(instance) # From https://docs.djangoproject.com/en/dev/topics/db/queries/#limiting-querysets representation['comments'] = CommentsSerializer( instance.comments.all().order_by('-published')[:PAGE_SIZE], many=True, read_only=True).data representation['author'] = get_summary(instance.author) # TODO: integration with other servers if (not instance.origin): representation["origin"] = get_host_url() + "/posts/" + str( instance.id) if (not instance.source): representation["source"] = representation["origin"] del representation["post_id"] return representation
def get_author_summaries(authorUrls): summaries = [] localAuthors = [] for authorUrl in authorUrls: if (is_external_host(authorUrl)): # open a server util with the author url sUtil = ServerUtil(authorUrl=authorUrl) if not sUtil.valid_server(): print("authorUrl found, but not in DB", authorUrl) continue # We couldn't find a server that matches the friend URL base # split the id from the URL and ask the external server about them success, authorInfo = sUtil.get_author_info( authorUrl.split("/author/")[1]) if not success: continue # We couldn't successfully fetch from an external server # PITA Point: Some servers don't store their IDs as the actual # location where you can GET the author summary, just use the ID # if you don't want to hate yourself, even though HOST will be # the correct location to get the service. summaries.append({ "id": authorUrl, "host": sUtil.get_base_url(), "url": authorUrl, "displayName": authorInfo["displayName"] }) else: localAuthors.append(get_author_id(authorUrl)) authors = Author.objects.filter(pk__in=localAuthors) host = get_host_url() for author in authors: url = get_author_url(str(author.id)) summaries.append({ "id": url, "host": host, "url": url, "displayName": author.get_display_name() }) return summaries
def get_next(self, instance): return "{}/posts/{}/comments".format(get_host_url(), instance.id)
def visible_posts(self, request): print("visible_posts endpoint hit") xUser = request.META.get("HTTP_X_REQUEST_USER_ID") page = int(request.query_params.get("page", 0)) + 1 # Must offset page by 1 if page < 1: return Response({ "query": "posts", "message": "Page number must be positive", "success": False }, status=400) size = int(request.query_params.get("size", DEFAULT_POST_PAGE_SIZE)) if size < 0 or size > 100: return Response({ "query": "posts", "message": "Size was invalid", "success": False }, status=400) # Only return public posts if the user isn't authenticated if request.user.is_anonymous: posts = Posts.objects.all().filter(visibility__in=["PUBLIC"], unlisted=False) elif ServerUtil.is_server(request.user): sUtil = ServerUtil(user=request.user) if not sUtil.is_valid(): return Response("This shouldn't happen, server=server!", status=500) elif not xUser: print("No xUser specified, sending all public posts") posts = Posts.objects.all().filter(visibility__in=["PUBLIC"]) elif not sUtil.author_from_this_server(xUser): return Response( "You're trying to access posts for a user that doesn't belong to you. user: "******" server: " + sUtil.get_base_url(), status=400) else: followedByXUser = Follow.objects.values_list("followed", flat=True).filter(follower=xUser) friendsOfXUser = Follow.objects.values_list("follower", flat=True).filter(followed=xUser, follower__in=followedByXUser) friends = [] friends += sUtil.get_friends_of(xUser.split("/author/")[1]) friends += friendsOfXUser friends = list(set(friends)) foafs = [] foafs += friends for friend in friends: print("friend of", xUser, ":", friend) # First check if it's an external user sUtil = ServerUtil(authorUrl=friend) if sUtil.is_valid(): foafs += sUtil.get_friends_of(friend.split("/author/")[1]) else: # it's not external (local), or we don't have that node anymore peopleFollowedByFriend = Follow.objects.values_list("followed", flat=True).filter( follower=friend) friendFriends = Follow.objects.values_list("follower", flat=True).filter(followed=friend, follower__in=peopleFollowedByFriend) foafs += friendFriends baseUrl = get_host_url() foafs = list(set(foafs)) friends = [get_author_id(x) for x in friends if x.startswith(baseUrl)] foafs = [get_author_id(x) for x in foafs if x.startswith(baseUrl)] posts = Posts.objects.all().filter(visibility="PUBLIC", unlisted=False) posts |= Posts.objects.all().filter(visibility="FRIENDS", author_id__in=friends, unlisted=False) posts |= Posts.objects.all().filter(visibility="FOAF", author_id__in=foafs, unlisted=False) posts |= Posts.objects.all().filter(visibility="PRIVATE", visibleTo__contains=[xUser], unlisted=False) else: requestingAuthor = request.user.author.id # Should be guaranteed because not anon # Get direct friends and FOAFs into a dictionary requesterFriends = {} requesterFOAFs = {} for friend in get_friends_from_pk(requestingAuthor): # friend = friend.split("/")[-1] # these are actually "urls", so grab the uuid requesterFriends[friend] = True for friend in requesterFriends: for foaf in get_friends(friend): # friend = friend.split("/")[-1] # these are actually "urls", so grab the uuid # Ensure we don't add direct friends as an FOAF if not requesterFriends.get(foaf, False): requesterFOAFs[foaf] = True try: # Grab the requesting user's posts posts = Posts.objects.all().filter(author=requestingAuthor, unlisted=False) # Grab all public posts posts |= Posts.objects.all().filter(visibility__in=["PUBLIC"], unlisted=False) host_url = get_host_url() # Grab posts from direct friends for friend in requesterFriends: if not friend.startswith(host_url): continue posts |= Posts.objects.all().filter(author=get_author_id(friend), visibility__in=["FRIENDS", "FOAF", "SERVERONLY"], unlisted=False) # Posts from FOAFs for friend in requesterFOAFs: if not friend.startswith(host_url): continue posts |= Posts.objects.all().filter(author=get_author_id(friend), visibility__in=["FOAF"], unlisted=False) # PRIVATE posts that the author can see posts |= Posts.objects.all().filter(visibility="PRIVATE", visibleTo__contains=[get_author_url(str(requestingAuthor))], unlisted=False) except: print("got except!") return Response(status=500) pages = Paginator(posts, size) current_page = pages.page(page) posts = PostsSerializer(current_page, many=True) response = { "query": "posts", "count": pages.count, "size": size, "posts": posts.data } add_page_details_to_response(request, response, current_page, page - 1) return Response(response, status=200)
def get_url(self): return urljoin(get_host_url(), "author", str(self.id))
def get_author_url(id): return urljoin(get_host_url(), "author", id)