{"action":"created","comment":{"url":"https://api.github.com/repos/fle-internal/content-curation/pulls/comments/87105122","pull_request_review_id":7730818,"id":87105122,"diff_hunk":"@@ -0,0 +1,218 @@\n+import copy\n+import json\n+import logging\n+import re\n+from django.http import Http404, HttpResponse, HttpResponseBadRequest, HttpResponseRedirect\n+from django.views.decorators.csrf import csrf_exempt\n+from django.views.generic.edit import FormView\n+from django.shortcuts import render, get_object_or_404, redirect, render_to_response\n+from django.contrib.sites.shortcuts import get_current_site\n+from django.contrib.auth import authenticate, login, logout\n+from django.contrib.auth.decorators import login_required\n+from django.conf import settings\n+from django.core.exceptions import ObjectDoesNotExist\n+from django.core.context_processors import csrf\n+from django.db.models import Q\n+from django.template.loader import render_to_string\n+from contentcuration.models import Channel, User, Invitation\n+from contentcuration.forms import InvitationForm, InvitationAcceptForm, RegistrationForm\n+from registration.backends.hmac.views import RegistrationView\n+\n+\n+\"\"\" REGISTRATION/INVITATION ENDPOINTS \"\"\"\n+@csrf_exempt\n+def send_invitation_email(request):\n+    if request.method != 'POST':\n+        raise HttpResponseBadRequest(\"Only POST requests are allowed on this endpoint.\")\n+    else:\n+        data = json.loads(request.body)\n+\n+        try:\n+            user_email = data[\"user_email\"]\n+            channel_id = data[\"channel_id\"]\n+            retrieved_user = User.objects.get_or_create(email = user_email)\n+            recipient = retrieved_user[0]\n+            channel = Channel.objects.get(id=channel_id)\n+            invitation = Invitation.objects.get_or_create(invited = recipient,\n+                                                        email = user_email,\n+                                                        sender=request.user,\n+                                                        channel_id = channel_id,\n+                                                        first_name=recipient.first_name if recipient.is_active else \"Guest\",\n+                                                        last_name=recipient.last_name if recipient.is_active else \" \")[0]\n+            ctx_dict = {    'sender' : request.user,\n+                            'site' : get_current_site(request),\n+                            'user' : recipient,\n+                            'channel_id' : channel_id,\n+                            'invitation_key': invitation.id,\n+                            'is_new': recipient.is_active is False,\n+                            'channel': channel.name\n+                        }\n+            subject = render_to_string('permissions/permissions_email_subject.txt', ctx_dict)\n+            message = render_to_string('permissions/permissions_email.txt', ctx_dict)\n+            # message_html = render_to_string('permissions/permissions_email.html', ctx_dict)\n+            recipient.email_user(subject, message, settings.DEFAULT_FROM_EMAIL,) #html_message=message_html,)\n+            # recipient.email_user(subject, message, settings.DEFAULT_FROM_EMAIL,)\n+        except KeyError:\n+            raise ObjectDoesNotExist(\"Missing attribute from data: {}\".format(data))\n+\n+        return HttpResponse(json.dumps({\n+                \"id\": invitation.pk,\n+                \"invited\": invitation.invited_id,\n+                \"email\": invitation.email,\n+                \"sender\": invitation.sender_id,\n+                \"channel\": invitation.channel_id,\n+                \"first_name\": invitation.first_name,\n+                \"last_name\": invitation.last_name,\n+            }))\n+\n+class InvitationAcceptView(FormView):\n+    form_class = InvitationAcceptForm\n+    template_name = 'permissions/permissions_confirm.html'\n+    invitation = None\n+\n+    def get_initial(self):\n+        initial = self.initial.copy()\n+        return {'userid': self.kwargs[\"user_id\"]}\n+\n+    def get_form_kwargs(self):\n+        kwargs = super(InvitationAcceptView, self).get_form_kwargs()\n+        kwargs.update({'user': self.user()})\n+        return kwargs\n+\n+    def get_success_url(self):\n+        return \"/channels/\" + self.kwargs[\"channel_id\"] + \"/edit\"\n+\n+    def dispatch(self, *args, **kwargs):\n+        user = self.user()\n+        try:\n+            self.invitation = Invitation.objects.get(id = self.kwargs['invitation_link'])\n+        except ObjectDoesNotExist:\n+            logging.debug(\"No invitation found.\")\n+            channel = Channel.objects.get(id=self.kwargs[\"channel_id\"])\n+            if user in channel.editors.all():\n+                return super(InvitationAcceptView, self).dispatch(*args, **kwargs)\n+            return redirect(\"/invitation_fail\")","path":"contentcuration/contentcuration/view/registration_views.py","position":94,"original_position":94,"commit_id":"d955a2208cff621284e7651d125cac6dcfba2818","original_commit_id":"609960c72d6af0133531886df0244337e568dbee","user":{"login":"jamalex","id":618416,"avatar_url":"https://avatars.githubusercontent.com/u/618416?v=3","gravatar_id":"","url":"https://api.github.com/users/jamalex","html_url":"https://github.com/jamalex","followers_url":"https://api.github.com/users/jamalex/followers","following_url":"https://api.github.com/users/jamalex/following{/other_user}","gists_url":"https://api.github.com/users/jamalex/gists{/gist_id}","starred_url":"https://api.github.com/users/jamalex/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jamalex/subscriptions","organizations_url":"https://api.github.com/users/jamalex/orgs","repos_url":"https://api.github.com/users/jamalex/repos","events_url":"https://api.github.com/users/jamalex/events{/privacy}","received_events_url":"https://api.github.com/users/jamalex/received_events","type":"User","site_admin":false},"body":"Use `reverse`.","created_at":"2016-11-08T23:09:55Z","updated_at":"2016-11-08T23:09:55Z","html_url":"https://github.com/fle-internal/content-curation/pull/98#discussion_r87105122","pull_request_url":"https://api.github.com/repos/fle-internal/content-curation/pulls/98","_links":{"self":{"href":"https://api.github.com/repos/fle-internal/content-curation/pulls/comments/87105122"},"html":{"href":"https://github.com/fle-internal/content-curation/pull/98#discussion_r87105122"},"pull_request":{"href":"https://api.github.com/repos/fle-internal/content-curation/pulls/98"}}},"pull_request":{"url":"https://api.github.com/repos/fle-internal/content-curation/pulls/98","id":92705865,"html_url":"https://github.com/fle-internal/content-curation/pull/98","diff_url":"https://github.com/fle-internal/content-curation/pull/98.diff","patch_url":"https://github.com/fle-internal/content-curation/pull/98.patch","issue_url":"https://api.github.com/repos/fle-internal/content-curation/issues/98","number":98,"state":"open","locked":false,"title":"Added support for ricecooker","user":{"login":"jayoshih","id":7447496,"avatar_url":"https://avatars.githubusercontent.com/u/7447496?v=3","gravatar_id":"","url":"https://api.github.com/users/jayoshih","html_url":"https://github.com/jayoshih","followers_url":"https://api.github.com/users/jayoshih/followers","following_url":"https://api.github.com/users/jayoshih/following{/other_user}","gists_url":"https://api.github.com/users/jayoshih/gists{/gist_id}","starred_url":"https://api.github.com/users/jayoshih/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jayoshih/subscriptions","organizations_url":"https://api.github.com/users/jayoshih/orgs","repos_url":"https://api.github.com/users/jayoshih/repos","events_url":"https://api.github.com/users/jayoshih/events{/privacy}","received_events_url":"https://api.github.com/users/jayoshih/received_events","type":"User","site_admin":false},"body":"Added chunking and authentication to rice cooker","created_at":"2016-11-08T02:45:34Z","updated_at":"2016-11-08T23:09:55Z","closed_at":null,"merged_at":null,"merge_commit_sha":"76bc7cd4d46819f0d6af2976eece707b97992410","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/fle-internal/content-curation/pulls/98/commits","review_comments_url":"https://api.github.com/repos/fle-internal/content-curation/pulls/98/comments","review_comment_url":"https://api.github.com/repos/fle-internal/content-curation/pulls/comments{/number}","comments_url":"https://api.github.com/repos/fle-internal/content-curation/issues/98/comments","statuses_url":"https://api.github.com/repos/fle-internal/content-curation/statuses/d955a2208cff621284e7651d125cac6dcfba2818","head":{"label":"jayoshih:recent","ref":"recent","sha":"d955a2208cff621284e7651d125cac6dcfba2818","user":{"login":"jayoshih","id":7447496,"avatar_url":"https://avatars.githubusercontent.com/u/7447496?v=3","gravatar_id":"","url":"https://api.github.com/users/jayoshih","html_url":"https://github.com/jayoshih","followers_url":"https://api.github.com/users/jayoshih/followers","following_url":"https://api.github.com/users/jayoshih/following{/other_user}","gists_url":"https://api.github.com/users/jayoshih/gists{/gist_id}","starred_url":"https://api.github.com/users/jayoshih/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jayoshih/subscriptions","organizations_url":"https://api.github.com/users/jayoshih/orgs","repos_url":"https://api.github.com/users/jayoshih/repos","events_url":"https://api.github.com/users/jayoshih/events{/privacy}","received_events_url":"https://api.github.com/users/jayoshih/received_events","type":"User","site_admin":false},"repo":{"id":38459600,"name":"content-curation","full_name":"jayoshih/content-curation","owner":{"login":"jayoshih","id":7447496,"avatar_url":"https://avatars.githubusercontent.com/u/7447496?v=3","gravatar_id":"","url":"https://api.github.com/users/jayoshih","html_url":"https://github.com/jayoshih","followers_url":"https://api.github.com/users/jayoshih/followers","following_url":"https://api.github.com/users/jayoshih/following{/other_user}","gists_url":"https://api.github.com/users/jayoshih/gists{/gist_id}","starred_url":"https://api.github.com/users/jayoshih/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jayoshih/subscriptions","organizations_url":"https://api.github.com/users/jayoshih/orgs","repos_url":"https://api.github.com/users/jayoshih/repos","events_url":"https://api.github.com/users/jayoshih/events{/privacy}","received_events_url":"https://api.github.com/users/jayoshih/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/jayoshih/content-curation","description":null,"fork":true,"url":"https://api.github.com/repos/jayoshih/content-curation","forks_url":"https://api.github.com/repos/jayoshih/content-curation/forks","keys_url":"https://api.github.com/repos/jayoshih/content-curation/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jayoshih/content-curation/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jayoshih/content-curation/teams","hooks_url":"https://api.github.com/repos/jayoshih/content-curation/hooks","issue_events_url":"https://api.github.com/repos/jayoshih/content-curation/issues/events{/number}","events_url":"https://api.github.com/repos/jayoshih/content-curation/events","assignees_url":"https://api.github.com/repos/jayoshih/content-curation/assignees{/user}","branches_url":"https://api.github.com/repos/jayoshih/content-curation/branches{/branch}","tags_url":"https://api.github.com/repos/jayoshih/content-curation/tags","blobs_url":"https://api.github.com/repos/jayoshih/content-curation/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jayoshih/content-curation/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jayoshih/content-curation/git/refs{/sha}","trees_url":"https://api.github.com/repos/jayoshih/content-curation/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jayoshih/content-curation/statuses/{sha}","languages_url":"https://api.github.com/repos/jayoshih/content-curation/languages","stargazers_url":"https://api.github.com/repos/jayoshih/content-curation/stargazers","contributors_url":"https://api.github.com/repos/jayoshih/content-curation/contributors","subscribers_url":"https://api.github.com/repos/jayoshih/content-curation/subscribers","subscription_url":"https://api.github.com/repos/jayoshih/content-curation/subscription","commits_url":"https://api.github.com/repos/jayoshih/content-curation/commits{/sha}","git_commits_url":"https://api.github.com/repos/jayoshih/content-curation/git/commits{/sha}","comments_url":"https://api.github.com/repos/jayoshih/content-curation/comments{/number}","issue_comment_url":"https://api.github.com/repos/jayoshih/content-curation/issues/comments{/number}","contents_url":"https://api.github.com/repos/jayoshih/content-curation/contents/{+path}","compare_url":"https://api.github.com/repos/jayoshih/content-curation/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jayoshih/content-curation/merges","archive_url":"https://api.github.com/repos/jayoshih/content-curation/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jayoshih/content-curation/downloads","issues_url":"https://api.github.com/repos/jayoshih/content-curation/issues{/number}","pulls_url":"https://api.github.com/repos/jayoshih/content-curation/pulls{/number}","milestones_url":"https://api.github.com/repos/jayoshih/content-curation/milestones{/number}","notifications_url":"https://api.github.com/repos/jayoshih/content-curation/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jayoshih/content-curation/labels{/name}","releases_url":"https://api.github.com/repos/jayoshih/content-curation/releases{/id}","deployments_url":"https://api.github.com/repos/jayoshih/content-curation/deployments","created_at":"2015-07-02T22:18:07Z","updated_at":"2016-05-18T21:39:29Z","pushed_at":"2016-11-08T22:57:47Z","git_url":"git://github.com/jayoshih/content-curation.git","ssh_url":"git@github.com:jayoshih/content-curation.git","clone_url":"https://github.com/jayoshih/content-curation.git","svn_url":"https://github.com/jayoshih/content-curation","homepage":null,"size":150331,"stargazers_count":0,"watchers_count":0,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":0,"forks":1,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"fle-internal:unicef_demo","ref":"unicef_demo","sha":"22f571552f100448e4cc8639c5979e914507dc15","user":{"login":"fle-internal","id":6564452,"avatar_url":"https://avatars.githubusercontent.com/u/6564452?v=3","gravatar_id":"","url":"https://api.github.com/users/fle-internal","html_url":"https://github.com/fle-internal","followers_url":"https://api.github.com/users/fle-internal/followers","following_url":"https://api.github.com/users/fle-internal/following{/other_user}","gists_url":"https://api.github.com/users/fle-internal/gists{/gist_id}","starred_url":"https://api.github.com/users/fle-internal/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fle-internal/subscriptions","organizations_url":"https://api.github.com/users/fle-internal/orgs","repos_url":"https://api.github.com/users/fle-internal/repos","events_url":"https://api.github.com/users/fle-internal/events{/privacy}","received_events_url":"https://api.github.com/users/fle-internal/received_events","type":"Organization","site_admin":false},"repo":{"id":35178170,"name":"content-curation","full_name":"fle-internal/content-curation","owner":{"login":"fle-internal","id":6564452,"avatar_url":"https://avatars.githubusercontent.com/u/6564452?v=3","gravatar_id":"","url":"https://api.github.com/users/fle-internal","html_url":"https://github.com/fle-internal","followers_url":"https://api.github.com/users/fle-internal/followers","following_url":"https://api.github.com/users/fle-internal/following{/other_user}","gists_url":"https://api.github.com/users/fle-internal/gists{/gist_id}","starred_url":"https://api.github.com/users/fle-internal/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fle-internal/subscriptions","organizations_url":"https://api.github.com/users/fle-internal/orgs","repos_url":"https://api.github.com/users/fle-internal/repos","events_url":"https://api.github.com/users/fle-internal/events{/privacy}","received_events_url":"https://api.github.com/users/fle-internal/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/fle-internal/content-curation","description":null,"fork":false,"url":"https://api.github.com/repos/fle-internal/content-curation","forks_url":"https://api.github.com/repos/fle-internal/content-curation/forks","keys_url":"https://api.github.com/repos/fle-internal/content-curation/keys{/key_id}","collaborators_url":"https://api.github.com/repos/fle-internal/content-curation/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/fle-internal/content-curation/teams","hooks_url":"https://api.github.com/repos/fle-internal/content-curation/hooks","issue_events_url":"https://api.github.com/repos/fle-internal/content-curation/issues/events{/number}","events_url":"https://api.github.com/repos/fle-internal/content-curation/events","assignees_url":"https://api.github.com/repos/fle-internal/content-curation/assignees{/user}","branches_url":"https://api.github.com/repos/fle-internal/content-curation/branches{/branch}","tags_url":"https://api.github.com/repos/fle-internal/content-curation/tags","blobs_url":"https://api.github.com/repos/fle-internal/content-curation/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/fle-internal/content-curation/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/fle-internal/content-curation/git/refs{/sha}","trees_url":"https://api.github.com/repos/fle-internal/content-curation/git/trees{/sha}","statuses_url":"https://api.github.com/repos/fle-internal/content-curation/statuses/{sha}","languages_url":"https://api.github.com/repos/fle-internal/content-curation/languages","stargazers_url":"https://api.github.com/repos/fle-internal/content-curation/stargazers","contributors_url":"https://api.github.com/repos/fle-internal/content-curation/contributors","subscribers_url":"https://api.github.com/repos/fle-internal/content-curation/subscribers","subscription_url":"https://api.github.com/repos/fle-internal/content-curation/subscription","commits_url":"https://api.github.com/repos/fle-internal/content-curation/commits{/sha}","git_commits_url":"https://api.github.com/repos/fle-internal/content-curation/git/commits{/sha}","comments_url":"https://api.github.com/repos/fle-internal/content-curation/comments{/number}","issue_comment_url":"https://api.github.com/repos/fle-internal/content-curation/issues/comments{/number}","contents_url":"https://api.github.com/repos/fle-internal/content-curation/contents/{+path}","compare_url":"https://api.github.com/repos/fle-internal/content-curation/compare/{base}...{head}","merges_url":"https://api.github.com/repos/fle-internal/content-curation/merges","archive_url":"https://api.github.com/repos/fle-internal/content-curation/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/fle-internal/content-curation/downloads","issues_url":"https://api.github.com/repos/fle-internal/content-curation/issues{/number}","pulls_url":"https://api.github.com/repos/fle-internal/content-curation/pulls{/number}","milestones_url":"https://api.github.com/repos/fle-internal/content-curation/milestones{/number}","notifications_url":"https://api.github.com/repos/fle-internal/content-curation/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/fle-internal/content-curation/labels{/name}","releases_url":"https://api.github.com/repos/fle-internal/content-curation/releases{/id}","deployments_url":"https://api.github.com/repos/fle-internal/content-curation/deployments","created_at":"2015-05-06T19:18:28Z","updated_at":"2016-02-05T15:08:29Z","pushed_at":"2016-11-08T22:57:48Z","git_url":"git://github.com/fle-internal/content-curation.git","ssh_url":"git@github.com:fle-internal/content-curation.git","clone_url":"https://github.com/fle-internal/content-curation.git","svn_url":"https://github.com/fle-internal/content-curation","homepage":null,"size":150297,"stargazers_count":2,"watchers_count":2,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":13,"mirror_url":null,"open_issues_count":4,"forks":13,"open_issues":4,"watchers":2,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/fle-internal/content-curation/pulls/98"},"html":{"href":"https://github.com/fle-internal/content-curation/pull/98"},"issue":{"href":"https://api.github.com/repos/fle-internal/content-curation/issues/98"},"comments":{"href":"https://api.github.com/repos/fle-internal/content-curation/issues/98/comments"},"review_comments":{"href":"https://api.github.com/repos/fle-internal/content-curation/pulls/98/comments"},"review_comment":{"href":"https://api.github.com/repos/fle-internal/content-curation/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/fle-internal/content-curation/pulls/98/commits"},"statuses":{"href":"https://api.github.com/repos/fle-internal/content-curation/statuses/d955a2208cff621284e7651d125cac6dcfba2818"}}}}
{"actor":{"display_login":"jamalex"}}