{"action":"closed","number":2652,"pull_request":{"url":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls/2652","id":34852396,"html_url":"https://github.com/CenterForOpenScience/osf.io/pull/2652","diff_url":"https://github.com/CenterForOpenScience/osf.io/pull/2652.diff","patch_url":"https://github.com/CenterForOpenScience/osf.io/pull/2652.patch","issue_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/issues/2652","number":2652,"state":"closed","locked":false,"title":"[Ready for Code Review] feature/spam_admin","user":{"login":"himanshuo","id":5808841,"avatar_url":"https://avatars.githubusercontent.com/u/5808841?v=3","gravatar_id":"","url":"https://api.github.com/users/himanshuo","html_url":"https://github.com/himanshuo","followers_url":"https://api.github.com/users/himanshuo/followers","following_url":"https://api.github.com/users/himanshuo/following{/other_user}","gists_url":"https://api.github.com/users/himanshuo/gists{/gist_id}","starred_url":"https://api.github.com/users/himanshuo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/himanshuo/subscriptions","organizations_url":"https://api.github.com/users/himanshuo/orgs","repos_url":"https://api.github.com/users/himanshuo/repos","events_url":"https://api.github.com/users/himanshuo/events{/privacy}","received_events_url":"https://api.github.com/users/himanshuo/received_events","type":"User","site_admin":false},"body":"<h1>Purpose</h1>\r\nThis PR serves as the OSF connection to the Spam Assassin service created previously. It is a administration page for 'spam_admin' users to view a list of comments or projects that have been marked as spam. This serves to facilitate some human at COS in determining which things are spam or not. A notable issue this PR solves is that there is no conclusive way to determine what occurs when a comment is reported yet. This will fix this issue by allowing a human user to determine if the comment is actually spam.\r\n\r\n<h1>Changes</h1>\r\nWhen a user makes a new comment or edits an old one, it will be checked for spam by sending the comment to the spam assassin service. Comments will be marked as spam when the spam assassin service says so or when a user reports a comment as spam a given number of times (1 for now). For projects, as soon as a user tries to make his/her project public, we will send the project to the spam assassin service. If the service determines the project has spam elements, we mark it as spam. The user will still have full access to his/her project. The only difference is that the user will not be able to make the project public. The user will be alerted appropriately. \r\n\r\nThere is a separate admin page ('localhost:5000/spam_admin/') that allows a human COS people to easily view information about each comment or project that has been marked as possibly spam (as described above). We can now read through the comment and actually determine if it is spam or not. If we mark the comment as spam, it will delete the comment. In addition, it will also train the spam assassin service to make it smarter for the future. If we mark the comment as ham, then it will be treated as a normal non-spam comment in the future. The idea is similar for projects. The only difference is that we will not delete a project if it is marked as spam. Notably, if a comment or project was already conclusively determined to be ham or spam by a spam_admin, we will not check once again as it likely not going to change.\r\n\r\nTo become a spam_admin, a user (referring to a OSF class User ) has to have a spam_admin boolean field be equal to true. Non-spam_admin's can't access this page. Currently, a user that has email spam_admin@cos.com and full name spam_admin will automatically become a spam_admin.\r\n\r\nThere are also tests testing both the views of the spam_admin page and the functional changes in handling comments and making projects public. \r\n\r\n<h1>Side Effects</h1>\r\nThere can be a notable slowdown in making a project public if it is large enough. This is due to checking for whether it is spam or not.","created_at":"2015-05-06T19:41:41Z","updated_at":"2015-12-02T00:55:49Z","closed_at":"2015-12-02T00:55:49Z","merged_at":null,"merge_commit_sha":"10f4e9004081e382eba4c51aeb854abcdb567425","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls/2652/commits","review_comments_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls/2652/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/2652/comments","statuses_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/statuses/8edde213d3ff83232a5b58df958a29d44f9fe86a","head":{"label":"himanshuo:feature/spam_admin","ref":"feature/spam_admin","sha":"8edde213d3ff83232a5b58df958a29d44f9fe86a","user":{"login":"himanshuo","id":5808841,"avatar_url":"https://avatars.githubusercontent.com/u/5808841?v=3","gravatar_id":"","url":"https://api.github.com/users/himanshuo","html_url":"https://github.com/himanshuo","followers_url":"https://api.github.com/users/himanshuo/followers","following_url":"https://api.github.com/users/himanshuo/following{/other_user}","gists_url":"https://api.github.com/users/himanshuo/gists{/gist_id}","starred_url":"https://api.github.com/users/himanshuo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/himanshuo/subscriptions","organizations_url":"https://api.github.com/users/himanshuo/orgs","repos_url":"https://api.github.com/users/himanshuo/repos","events_url":"https://api.github.com/users/himanshuo/events{/privacy}","received_events_url":"https://api.github.com/users/himanshuo/received_events","type":"User","site_admin":false},"repo":{"id":33099847,"name":"osf.io","full_name":"himanshuo/osf.io","owner":{"login":"himanshuo","id":5808841,"avatar_url":"https://avatars.githubusercontent.com/u/5808841?v=3","gravatar_id":"","url":"https://api.github.com/users/himanshuo","html_url":"https://github.com/himanshuo","followers_url":"https://api.github.com/users/himanshuo/followers","following_url":"https://api.github.com/users/himanshuo/following{/other_user}","gists_url":"https://api.github.com/users/himanshuo/gists{/gist_id}","starred_url":"https://api.github.com/users/himanshuo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/himanshuo/subscriptions","organizations_url":"https://api.github.com/users/himanshuo/orgs","repos_url":"https://api.github.com/users/himanshuo/repos","events_url":"https://api.github.com/users/himanshuo/events{/privacy}","received_events_url":"https://api.github.com/users/himanshuo/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/himanshuo/osf.io","description":"Facilitating Open Science","fork":true,"url":"https://api.github.com/repos/himanshuo/osf.io","forks_url":"https://api.github.com/repos/himanshuo/osf.io/forks","keys_url":"https://api.github.com/repos/himanshuo/osf.io/keys{/key_id}","collaborators_url":"https://api.github.com/repos/himanshuo/osf.io/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/himanshuo/osf.io/teams","hooks_url":"https://api.github.com/repos/himanshuo/osf.io/hooks","issue_events_url":"https://api.github.com/repos/himanshuo/osf.io/issues/events{/number}","events_url":"https://api.github.com/repos/himanshuo/osf.io/events","assignees_url":"https://api.github.com/repos/himanshuo/osf.io/assignees{/user}","branches_url":"https://api.github.com/repos/himanshuo/osf.io/branches{/branch}","tags_url":"https://api.github.com/repos/himanshuo/osf.io/tags","blobs_url":"https://api.github.com/repos/himanshuo/osf.io/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/himanshuo/osf.io/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/himanshuo/osf.io/git/refs{/sha}","trees_url":"https://api.github.com/repos/himanshuo/osf.io/git/trees{/sha}","statuses_url":"https://api.github.com/repos/himanshuo/osf.io/statuses/{sha}","languages_url":"https://api.github.com/repos/himanshuo/osf.io/languages","stargazers_url":"https://api.github.com/repos/himanshuo/osf.io/stargazers","contributors_url":"https://api.github.com/repos/himanshuo/osf.io/contributors","subscribers_url":"https://api.github.com/repos/himanshuo/osf.io/subscribers","subscription_url":"https://api.github.com/repos/himanshuo/osf.io/subscription","commits_url":"https://api.github.com/repos/himanshuo/osf.io/commits{/sha}","git_commits_url":"https://api.github.com/repos/himanshuo/osf.io/git/commits{/sha}","comments_url":"https://api.github.com/repos/himanshuo/osf.io/comments{/number}","issue_comment_url":"https://api.github.com/repos/himanshuo/osf.io/issues/comments{/number}","contents_url":"https://api.github.com/repos/himanshuo/osf.io/contents/{+path}","compare_url":"https://api.github.com/repos/himanshuo/osf.io/compare/{base}...{head}","merges_url":"https://api.github.com/repos/himanshuo/osf.io/merges","archive_url":"https://api.github.com/repos/himanshuo/osf.io/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/himanshuo/osf.io/downloads","issues_url":"https://api.github.com/repos/himanshuo/osf.io/issues{/number}","pulls_url":"https://api.github.com/repos/himanshuo/osf.io/pulls{/number}","milestones_url":"https://api.github.com/repos/himanshuo/osf.io/milestones{/number}","notifications_url":"https://api.github.com/repos/himanshuo/osf.io/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/himanshuo/osf.io/labels{/name}","releases_url":"https://api.github.com/repos/himanshuo/osf.io/releases{/id}","created_at":"2015-03-30T02:46:51Z","updated_at":"2015-04-07T18:36:07Z","pushed_at":"2015-06-10T15:58:02Z","git_url":"git://github.com/himanshuo/osf.io.git","ssh_url":"git@github.com:himanshuo/osf.io.git","clone_url":"https://github.com/himanshuo/osf.io.git","svn_url":"https://github.com/himanshuo/osf.io","homepage":"http://osf.io","size":94580,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"develop"}},"base":{"label":"CenterForOpenScience:develop","ref":"develop","sha":"8874bc1a3b345c498fd98c1142c082ac83963709","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}","created_at":"2013-05-21T15:53:37Z","updated_at":"2015-12-01T16:31:23Z","pushed_at":"2015-12-02T00:55:48Z","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":222925,"stargazers_count":166,"watchers_count":166,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":134,"mirror_url":null,"open_issues_count":314,"forks":134,"open_issues":314,"watchers":166,"default_branch":"feature/admin-app"}},"_links":{"self":{"href":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls/2652"},"html":{"href":"https://github.com/CenterForOpenScience/osf.io/pull/2652"},"issue":{"href":"https://api.github.com/repos/CenterForOpenScience/osf.io/issues/2652"},"comments":{"href":"https://api.github.com/repos/CenterForOpenScience/osf.io/issues/2652/comments"},"review_comments":{"href":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls/2652/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/2652/commits"},"statuses":{"href":"https://api.github.com/repos/CenterForOpenScience/osf.io/statuses/8edde213d3ff83232a5b58df958a29d44f9fe86a"}},"merged":false,"mergeable":false,"mergeable_state":"dirty","merged_by":null,"comments":2,"review_comments":21,"commits":21,"additions":1583,"deletions":14,"changed_files":24}}