{"action":"created","comment":{"url":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls/comments/61086521","id":61086521,"diff_hunk":"@@ -1,96 +1,124 @@\n from __future__ import unicode_literals\n \n from django.shortcuts import render\n-from django.contrib.auth.decorators import login_required\n from django.core.mail import send_mail\n-from django.http import HttpResponseNotFound\n from django.views.generic import FormView, ListView\n-from django.utils.decorators import method_decorator\n-from django.core.urlresolvers import reverse\n from django.views.defaults import page_not_found\n \n from modularodm import Q\n from website.project.model import Comment\n from website.settings import SUPPORT_EMAIL\n \n-from admin.common_auth.logs import update_admin_log, CONFIRM_HAM, CONFIRM_SPAM\n+from admin.base.utils import OSFAdmin\n+from admin.common_auth.logs import (\n+    update_admin_log,\n+    CONFIRM_HAM,\n+    CONFIRM_SPAM,\n+    USER_EMAILED,\n+)\n from admin.spam.serializers import serialize_comment\n from admin.spam.forms import EmailForm, ConfirmForm\n+from admin.spam.templatetags.spam_extras import reverse_spam_detail\n \n+STATUS = dict(\n+    UNKNOWN=Comment.UNKNOWN,\n+    SPAM=Comment.SPAM,\n+    HAM=Comment.HAM,\n+    FLAGGED=Comment.FLAGGED,\n+)\n \n-class EmailFormView(FormView):\n \n+class EmailFormView(OSFAdmin, FormView):\n+    \"\"\" Allow authorized admin user to Email spammers, use judiciously\n+\n+    Gets user data and supplies email template. Logs mail sent to user.\n+    \"\"\"\n     form_class = EmailForm\n     template_name = \"spam/email.html\"\n-    spam_id = None\n-    page = 1\n-\n-    def __init__(self):\n-        self.spam = None\n-        super(EmailFormView, self).__init__()\n \n     def get(self, request, *args, **kwargs):\n-        spam_id = kwargs.get('spam_id', None)\n-        self.spam_id = spam_id\n-        self.page = request.GET.get('page', 1)\n         try:\n-            self.spam = serialize_comment(Comment.load(spam_id))\n-        except (AttributeError, TypeError):\n-            return HttpResponseNotFound(\n-                '<h1>Spam comment ({}) not found.</h1>'.format(spam_id)\n+            return super(EmailFormView, self).get(request, *args, **kwargs)\n+        except AttributeError:\n+            return page_not_found(\n+                request,\n+                AttributeError(\n+                    'Spam with id {} not found.'.format(kwargs.get('spam_id'))\n+                )\n             )\n-        form = self.get_form()\n-        context = {\n-            'comment': self.spam,\n-            'page_number': request.GET.get('page', 1),\n-            'form': form\n-        }\n-        return render(request, self.template_name, context)\n \n     def post(self, request, *args, **kwargs):\n-        spam_id = kwargs.get('spam_id', None)\n-        self.spam_id = spam_id\n-        self.page = request.GET.get('page', 1)\n         try:\n-            self.spam = serialize_comment(Comment.load(spam_id))\n-        except (AttributeError, TypeError):\n-            return HttpResponseNotFound(\n-                '<h1>Spam comment ({}) not found.</h1>'.format(spam_id)\n+            return super(EmailFormView, self).post(request, *args, **kwargs)\n+        except AttributeError:\n+            return page_not_found(\n+                request,\n+                AttributeError(\n+                    'Spam with id {} not found.'.format(kwargs.get('spam_id'))\n+                )\n             )\n-        return super(EmailFormView, self).post(request, *args, **kwargs)\n+\n+    def get_context_data(self, **kwargs):\n+        kwargs.setdefault(\n+            'comment',\n+            serialize_comment(Comment.load(self.kwargs.get('spam_id')))\n+        )\n+        kwargs.setdefault('page_number', self.request.GET.get('page', '1'))\n+        kwargs.setdefault('status', self.request.GET.get('status', '1'))\n+        return super(EmailFormView, self).get_context_data(**kwargs)\n \n     def get_initial(self):\n+        spam = serialize_comment(Comment.load(self.kwargs.get('spam_id')))\n         self.initial = {\n-            'author': self.spam['author'].fullname,\n-            'email': [(r, r) for r in self.spam['author'].emails],\n+            'author': spam['author'].fullname,\n+            'email': [(r, r) for r in spam['author'].emails],\n             'subject': 'Reports of spam',\n             'message': render(\n                 None,\n                 'spam/email_template.html',\n-                {'item': self.spam}\n+                {'item': spam}\n             ).content,\n         }\n         return super(EmailFormView, self).get_initial()\n \n     def form_valid(self, form):\n+        message = form.cleaned_data.get('message')\n+        email = form.cleaned_data.get('email')\n+        update_admin_log(","path":"admin/spam/views.py","position":124,"original_position":124,"commit_id":"bfb49de40732017ab3044af8b33279adfcef7691","original_commit_id":"bfb49de40732017ab3044af8b33279adfcef7691","user":{"login":"cwisecarver","id":3709,"avatar_url":"https://avatars.githubusercontent.com/u/3709?v=3","gravatar_id":"","url":"https://api.github.com/users/cwisecarver","html_url":"https://github.com/cwisecarver","followers_url":"https://api.github.com/users/cwisecarver/followers","following_url":"https://api.github.com/users/cwisecarver/following{/other_user}","gists_url":"https://api.github.com/users/cwisecarver/gists{/gist_id}","starred_url":"https://api.github.com/users/cwisecarver/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cwisecarver/subscriptions","organizations_url":"https://api.github.com/users/cwisecarver/orgs","repos_url":"https://api.github.com/users/cwisecarver/repos","events_url":"https://api.github.com/users/cwisecarver/events{/privacy}","received_events_url":"https://api.github.com/users/cwisecarver/received_events","type":"User","site_admin":false},"body":"Would you maybe want to log after you email? If there's an exception sending the mail we will have a log of something that didn't happen.","created_at":"2016-04-26T13:40:53Z","updated_at":"2016-04-26T13:40:53Z","html_url":"https://github.com/CenterForOpenScience/osf.io/pull/5446#discussion_r61086521","pull_request_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls/5446","_links":{"self":{"href":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls/comments/61086521"},"html":{"href":"https://github.com/CenterForOpenScience/osf.io/pull/5446#discussion_r61086521"},"pull_request":{"href":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls/5446"}}},"pull_request":{"url":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls/5446","id":66037433,"html_url":"https://github.com/CenterForOpenScience/osf.io/pull/5446","diff_url":"https://github.com/CenterForOpenScience/osf.io/pull/5446.diff","patch_url":"https://github.com/CenterForOpenScience/osf.io/pull/5446.patch","issue_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/issues/5446","number":5446,"state":"open","locked":false,"title":"[Feature] Admin Spam Refactor","user":{"login":"Ghalko","id":5169088,"avatar_url":"https://avatars.githubusercontent.com/u/5169088?v=3","gravatar_id":"","url":"https://api.github.com/users/Ghalko","html_url":"https://github.com/Ghalko","followers_url":"https://api.github.com/users/Ghalko/followers","following_url":"https://api.github.com/users/Ghalko/following{/other_user}","gists_url":"https://api.github.com/users/Ghalko/gists{/gist_id}","starred_url":"https://api.github.com/users/Ghalko/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Ghalko/subscriptions","organizations_url":"https://api.github.com/users/Ghalko/orgs","repos_url":"https://api.github.com/users/Ghalko/repos","events_url":"https://api.github.com/users/Ghalko/events{/privacy}","received_events_url":"https://api.github.com/users/Ghalko/received_events","type":"User","site_admin":false},"body":"## Proposal\r\nRefactor many small issues that are listed in ADM-83\r\n\r\n## Repercussions\r\nCleaner and more security.","created_at":"2016-04-11T18:12:53Z","updated_at":"2016-04-26T13:40:53Z","closed_at":null,"merged_at":null,"merge_commit_sha":"cd018cdd97c41c60cb10e890b19c3c9be20ab186","assignee":null,"milestone":{"url":"https://api.github.com/repos/CenterForOpenScience/osf.io/milestones/68","html_url":"https://github.com/CenterForOpenScience/osf.io/milestones/69.0.0","labels_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/milestones/68/labels","id":1704484,"number":68,"title":"69.0.0","description":"","creator":{"login":"sloria","id":2379650,"avatar_url":"https://avatars.githubusercontent.com/u/2379650?v=3","gravatar_id":"","url":"https://api.github.com/users/sloria","html_url":"https://github.com/sloria","followers_url":"https://api.github.com/users/sloria/followers","following_url":"https://api.github.com/users/sloria/following{/other_user}","gists_url":"https://api.github.com/users/sloria/gists{/gist_id}","starred_url":"https://api.github.com/users/sloria/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sloria/subscriptions","organizations_url":"https://api.github.com/users/sloria/orgs","repos_url":"https://api.github.com/users/sloria/repos","events_url":"https://api.github.com/users/sloria/events{/privacy}","received_events_url":"https://api.github.com/users/sloria/received_events","type":"User","site_admin":false},"open_issues":19,"closed_issues":7,"state":"open","created_at":"2016-04-13T19:02:06Z","updated_at":"2016-04-25T16:36:25Z","due_on":null,"closed_at":null},"commits_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls/5446/commits","review_comments_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls/5446/comments","review_comment_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls/comments{/number}","comments_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/issues/5446/comments","statuses_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/statuses/bfb49de40732017ab3044af8b33279adfcef7691","head":{"label":"Ghalko:feature/admin_spam_refactor","ref":"feature/admin_spam_refactor","sha":"bfb49de40732017ab3044af8b33279adfcef7691","user":{"login":"Ghalko","id":5169088,"avatar_url":"https://avatars.githubusercontent.com/u/5169088?v=3","gravatar_id":"","url":"https://api.github.com/users/Ghalko","html_url":"https://github.com/Ghalko","followers_url":"https://api.github.com/users/Ghalko/followers","following_url":"https://api.github.com/users/Ghalko/following{/other_user}","gists_url":"https://api.github.com/users/Ghalko/gists{/gist_id}","starred_url":"https://api.github.com/users/Ghalko/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Ghalko/subscriptions","organizations_url":"https://api.github.com/users/Ghalko/orgs","repos_url":"https://api.github.com/users/Ghalko/repos","events_url":"https://api.github.com/users/Ghalko/events{/privacy}","received_events_url":"https://api.github.com/users/Ghalko/received_events","type":"User","site_admin":false},"repo":{"id":31034068,"name":"osf.io","full_name":"Ghalko/osf.io","owner":{"login":"Ghalko","id":5169088,"avatar_url":"https://avatars.githubusercontent.com/u/5169088?v=3","gravatar_id":"","url":"https://api.github.com/users/Ghalko","html_url":"https://github.com/Ghalko","followers_url":"https://api.github.com/users/Ghalko/followers","following_url":"https://api.github.com/users/Ghalko/following{/other_user}","gists_url":"https://api.github.com/users/Ghalko/gists{/gist_id}","starred_url":"https://api.github.com/users/Ghalko/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Ghalko/subscriptions","organizations_url":"https://api.github.com/users/Ghalko/orgs","repos_url":"https://api.github.com/users/Ghalko/repos","events_url":"https://api.github.com/users/Ghalko/events{/privacy}","received_events_url":"https://api.github.com/users/Ghalko/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/Ghalko/osf.io","description":"Facilitating Open Science","fork":true,"url":"https://api.github.com/repos/Ghalko/osf.io","forks_url":"https://api.github.com/repos/Ghalko/osf.io/forks","keys_url":"https://api.github.com/repos/Ghalko/osf.io/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Ghalko/osf.io/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Ghalko/osf.io/teams","hooks_url":"https://api.github.com/repos/Ghalko/osf.io/hooks","issue_events_url":"https://api.github.com/repos/Ghalko/osf.io/issues/events{/number}","events_url":"https://api.github.com/repos/Ghalko/osf.io/events","assignees_url":"https://api.github.com/repos/Ghalko/osf.io/assignees{/user}","branches_url":"https://api.github.com/repos/Ghalko/osf.io/branches{/branch}","tags_url":"https://api.github.com/repos/Ghalko/osf.io/tags","blobs_url":"https://api.github.com/repos/Ghalko/osf.io/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Ghalko/osf.io/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Ghalko/osf.io/git/refs{/sha}","trees_url":"https://api.github.com/repos/Ghalko/osf.io/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Ghalko/osf.io/statuses/{sha}","languages_url":"https://api.github.com/repos/Ghalko/osf.io/languages","stargazers_url":"https://api.github.com/repos/Ghalko/osf.io/stargazers","contributors_url":"https://api.github.com/repos/Ghalko/osf.io/contributors","subscribers_url":"https://api.github.com/repos/Ghalko/osf.io/subscribers","subscription_url":"https://api.github.com/repos/Ghalko/osf.io/subscription","commits_url":"https://api.github.com/repos/Ghalko/osf.io/commits{/sha}","git_commits_url":"https://api.github.com/repos/Ghalko/osf.io/git/commits{/sha}","comments_url":"https://api.github.com/repos/Ghalko/osf.io/comments{/number}","issue_comment_url":"https://api.github.com/repos/Ghalko/osf.io/issues/comments{/number}","contents_url":"https://api.github.com/repos/Ghalko/osf.io/contents/{+path}","compare_url":"https://api.github.com/repos/Ghalko/osf.io/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Ghalko/osf.io/merges","archive_url":"https://api.github.com/repos/Ghalko/osf.io/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Ghalko/osf.io/downloads","issues_url":"https://api.github.com/repos/Ghalko/osf.io/issues{/number}","pulls_url":"https://api.github.com/repos/Ghalko/osf.io/pulls{/number}","milestones_url":"https://api.github.com/repos/Ghalko/osf.io/milestones{/number}","notifications_url":"https://api.github.com/repos/Ghalko/osf.io/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Ghalko/osf.io/labels{/name}","releases_url":"https://api.github.com/repos/Ghalko/osf.io/releases{/id}","deployments_url":"https://api.github.com/repos/Ghalko/osf.io/deployments","created_at":"2015-02-19T20:02:48Z","updated_at":"2015-03-30T13:32:39Z","pushed_at":"2016-04-25T20:42:37Z","git_url":"git://github.com/Ghalko/osf.io.git","ssh_url":"git@github.com:Ghalko/osf.io.git","clone_url":"https://github.com/Ghalko/osf.io.git","svn_url":"https://github.com/Ghalko/osf.io","homepage":"http://osf.io","size":127571,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":1,"forks":1,"open_issues":1,"watchers":0,"default_branch":"develop"}},"base":{"label":"CenterForOpenScience:develop","ref":"develop","sha":"16c48443064bb3cadef72166ddf1fea8149b2fd9","user":{"login":"CenterForOpenScience","id":3344584,"avatar_url":"https://avatars.githubusercontent.com/u/3344584?v=3","gravatar_id":"","url":"https://api.github.com/users/CenterForOpenScience","html_url":"https://github.com/CenterForOpenScience","followers_url":"https://api.github.com/users/CenterForOpenScience/followers","following_url":"https://api.github.com/users/CenterForOpenScience/following{/other_user}","gists_url":"https://api.github.com/users/CenterForOpenScience/gists{/gist_id}","starred_url":"https://api.github.com/users/CenterForOpenScience/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CenterForOpenScience/subscriptions","organizations_url":"https://api.github.com/users/CenterForOpenScience/orgs","repos_url":"https://api.github.com/users/CenterForOpenScience/repos","events_url":"https://api.github.com/users/CenterForOpenScience/events{/privacy}","received_events_url":"https://api.github.com/users/CenterForOpenScience/received_events","type":"Organization","site_admin":false},"repo":{"id":10199599,"name":"osf.io","full_name":"CenterForOpenScience/osf.io","owner":{"login":"CenterForOpenScience","id":3344584,"avatar_url":"https://avatars.githubusercontent.com/u/3344584?v=3","gravatar_id":"","url":"https://api.github.com/users/CenterForOpenScience","html_url":"https://github.com/CenterForOpenScience","followers_url":"https://api.github.com/users/CenterForOpenScience/followers","following_url":"https://api.github.com/users/CenterForOpenScience/following{/other_user}","gists_url":"https://api.github.com/users/CenterForOpenScience/gists{/gist_id}","starred_url":"https://api.github.com/users/CenterForOpenScience/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CenterForOpenScience/subscriptions","organizations_url":"https://api.github.com/users/CenterForOpenScience/orgs","repos_url":"https://api.github.com/users/CenterForOpenScience/repos","events_url":"https://api.github.com/users/CenterForOpenScience/events{/privacy}","received_events_url":"https://api.github.com/users/CenterForOpenScience/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/CenterForOpenScience/osf.io","description":"Facilitating Open Science","fork":false,"url":"https://api.github.com/repos/CenterForOpenScience/osf.io","forks_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/forks","keys_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/keys{/key_id}","collaborators_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/teams","hooks_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/hooks","issue_events_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/issues/events{/number}","events_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/events","assignees_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/assignees{/user}","branches_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/branches{/branch}","tags_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/tags","blobs_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/git/refs{/sha}","trees_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/git/trees{/sha}","statuses_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/statuses/{sha}","languages_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/languages","stargazers_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/stargazers","contributors_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/contributors","subscribers_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/subscribers","subscription_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/subscription","commits_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/commits{/sha}","git_commits_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/git/commits{/sha}","comments_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/comments{/number}","issue_comment_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/issues/comments{/number}","contents_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/contents/{+path}","compare_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/compare/{base}...{head}","merges_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/merges","archive_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/downloads","issues_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/issues{/number}","pulls_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls{/number}","milestones_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/milestones{/number}","notifications_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/labels{/name}","releases_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/releases{/id}","deployments_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/deployments","created_at":"2013-05-21T15:53:37Z","updated_at":"2016-04-20T16:42:44Z","pushed_at":"2016-04-26T13:22:47Z","git_url":"git://github.com/CenterForOpenScience/osf.io.git","ssh_url":"git@github.com:CenterForOpenScience/osf.io.git","clone_url":"https://github.com/CenterForOpenScience/osf.io.git","svn_url":"https://github.com/CenterForOpenScience/osf.io","homepage":"http://osf.io","size":273558,"stargazers_count":212,"watchers_count":212,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":164,"mirror_url":null,"open_issues_count":229,"forks":164,"open_issues":229,"watchers":212,"default_branch":"develop"}},"_links":{"self":{"href":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls/5446"},"html":{"href":"https://github.com/CenterForOpenScience/osf.io/pull/5446"},"issue":{"href":"https://api.github.com/repos/CenterForOpenScience/osf.io/issues/5446"},"comments":{"href":"https://api.github.com/repos/CenterForOpenScience/osf.io/issues/5446/comments"},"review_comments":{"href":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls/5446/comments"},"review_comment":{"href":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls/5446/commits"},"statuses":{"href":"https://api.github.com/repos/CenterForOpenScience/osf.io/statuses/bfb49de40732017ab3044af8b33279adfcef7691"}}}}