{"action":"created","comment":{"url":"https://api.github.com/repos/elifesciences/elife-bot/pulls/comments/176258723","pull_request_review_id":105930804,"id":176258723,"diff_hunk":"@@ -22,89 +21,109 @@\n Amazon SQS worker\n \"\"\"\n \n-\n-def work(ENV, flag):\n-    # Specify run environment settings\n-    settings = settings_lib.get_settings(ENV)\n-\n-    # Log\n-    identity = \"queue_worker_%s\" % os.getpid()\n-    log_file = \"queue_worker.log\"\n-    # logFile = None\n-    logger = log.logger(log_file, settings.setLevel, identity)\n-\n-    # Simple connect\n-    conn = boto.sqs.connect_to_region(settings.sqs_region,\n-                                      aws_access_key_id=settings.aws_access_key_id,\n-                                      aws_secret_access_key=settings.aws_secret_access_key)\n-    queue = conn.get_queue(settings.S3_monitor_queue)\n-    queue.set_message_class(S3SQSMessage)\n-\n-    rules = load_rules()\n-    application = newrelic.agent.application()\n-\n-    # Poll for an activity task indefinitely\n-    if queue is not None:\n-        while flag.green():\n-\n-            logger.info('reading message')\n-            queue_message = queue.read(30)\n-            # TODO : check for more-than-once delivery\n-            # ( Dynamo conditional write? http://tinyurl.com/of3tmop )\n-\n-            if queue_message is None:\n-                logger.info('no messages available')\n-            else:\n-                with newrelic.agent.BackgroundTask(application, name=queue_message.notification_type, group='queue_worker.py'):\n-                    logger.info('got message id: %s' % queue_message.id)\n-                    if queue_message.notification_type == 'S3Event':\n-                        info = S3NotificationInfo.from_S3SQSMessage(queue_message)\n-                        logger.info(\"S3NotificationInfo: %s\", info.to_dict())\n-                        workflow_name = get_starter_name(rules, info)\n-                        if workflow_name is None:\n-                            logger.info(\"Could not handle file %s in bucket %s\" % (info.file_name, info.bucket_name))\n-                            return False\n-\n-                        # build message\n-                        message = {\n-                            'workflow_name': workflow_name,\n-                            'workflow_data': info.to_dict()\n-                        }\n-\n-                        # send workflow initiation message\n-                        out_queue = conn.get_queue(settings.workflow_starter_queue)\n-                        m = Message()\n-                        m.set_body(json.dumps(message))\n-                        out_queue.write(m)\n-\n-                        # cancel incoming message\n-                        logger.info(\"cancelling message\")\n-                        queue.delete_message(queue_message)\n-                        logger.info(\"message cancelled\")\n-                    else:\n-                        # TODO : log\n-                        pass\n-            time.sleep(10)\n-\n-        logger.info(\"graceful shutdown\")\n-\n-    else:\n-        logger.error('error obtaining queue')\n-\n-\n-def load_rules():\n-    # load the rules from the YAML file\n-    stream = file('newFileWorkflows.yaml', 'r')\n-    return yaml.load(stream)\n-\n-\n-def get_starter_name(rules, info):\n-    for rule_name in rules:\n-        rule = rules[rule_name]\n-        if re.match(rule['bucket_name_pattern'], info.bucket_name) and \\\n-                re.match(rule['file_name_pattern'], info.file_name):\n-            return rule['starter_name']\n-        pass\n+class QueueWorker:\n+    def __init__(self, settings, logger=None):\n+        self.settings = settings\n+        if logger:\n+            self.logger = logger\n+        else:\n+            self.create_log()\n+        self.conn = None\n+        self.sleep_seconds = 10\n+\n+    def create_log(self):\n+        # Log\n+        identity = \"queue_worker_%s\" % os.getpid()\n+        log_file = \"queue_worker.log\"\n+        # logFile = None\n+        self.logger = log.logger(log_file, self.settings.setLevel, identity)\n+\n+    def connect(self):\n+        \"connect to the queue service\"\n+        if not self.conn:\n+            self.conn = boto.sqs.connect_to_region(\n+                self.settings.sqs_region,\n+                aws_access_key_id=self.settings.aws_access_key_id,\n+                aws_secret_access_key=self.settings.aws_secret_access_key)\n+\n+    def queues(self):\n+        \"get the queues\"\n+        self.connect()\n+        queue = self.conn.get_queue(self.settings.S3_monitor_queue)\n+        queue.set_message_class(S3SQSMessage)\n+        out_queue = self.conn.get_queue(self.settings.workflow_starter_queue)\n+        return queue, out_queue\n+\n+    def work(self, flag):\n+        \"read messages from the queue\"\n+\n+        # Simple connect to the queues\n+        queue, out_queue = self.queues()\n+\n+        rules = self.load_rules()\n+        application = newrelic.agent.application()\n+\n+        # Poll for an activity task indefinitely\n+        if queue is not None:\n+            while flag.green():\n+\n+                self.logger.info('reading message')\n+                queue_message = queue.read(30)\n+                # TODO : check for more-than-once delivery\n+                # ( Dynamo conditional write? http://tinyurl.com/of3tmop )\n+\n+                if queue_message is None:\n+                    self.logger.info('no messages available')\n+                else:\n+                    with newrelic.agent.BackgroundTask(application, name=queue_message.notification_type, group='queue_worker.py'):\n+                        self.logger.info('got message id: %s' % queue_message.id)\n+                        if queue_message.notification_type == 'S3Event':\n+                            info = S3NotificationInfo.from_S3SQSMessage(queue_message)\n+                            self.logger.info(\"S3NotificationInfo: %s\", info.to_dict())\n+                            workflow_name = self.get_starter_name(rules, info)\n+                            if workflow_name is None:\n+                                self.logger.info(\"Could not handle file %s in bucket %s\" % (info.file_name, info.bucket_name))\n+                                return False\n+\n+                            # build message\n+                            message = {\n+                                'workflow_name': workflow_name,\n+                                'workflow_data': info.to_dict()\n+                            }\n+\n+                            # send workflow initiation message\n+                            m = Message()\n+                            m.set_body(json.dumps(message))\n+                            out_queue.write(m)\n+\n+                            # cancel incoming message\n+                            self.logger.info(\"cancelling message\")\n+                            queue.delete_message(queue_message)\n+                            self.logger.info(\"message cancelled\")\n+                        else:\n+                            # TODO : log\n+                            pass\n+                time.sleep(self.sleep_seconds)\n+\n+            self.logger.info(\"graceful shutdown\")\n+\n+        else:\n+            self.logger.error('error obtaining queue')\n+\n+\n+    def load_rules(self):\n+        # load the rules from the YAML file\n+        stream = file('newFileWorkflows.yaml', 'r')\n+        return yaml.load(stream)\n+\n+\n+    def get_starter_name(self, rules, info):\n+        for rule_name in rules:\n+            rule = rules[rule_name]\n+            if re.match(rule['bucket_name_pattern'], info.bucket_name) and \\\n+                    re.match(rule['file_name_pattern'], info.file_name):\n+                return rule['starter_name']\n+            pass\n \n \n def reload_module(module_name):","path":"queue_worker.py","position":200,"original_position":200,"commit_id":"7d81dddf60662ed273a6103deeb40e7ced5bbc5e","original_commit_id":"7d81dddf60662ed273a6103deeb40e7ced5bbc5e","user":{"login":"gnott","id":1779115,"avatar_url":"https://avatars1.githubusercontent.com/u/1779115?v=4","gravatar_id":"","url":"https://api.github.com/users/gnott","html_url":"https://github.com/gnott","followers_url":"https://api.github.com/users/gnott/followers","following_url":"https://api.github.com/users/gnott/following{/other_user}","gists_url":"https://api.github.com/users/gnott/gists{/gist_id}","starred_url":"https://api.github.com/users/gnott/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gnott/subscriptions","organizations_url":"https://api.github.com/users/gnott/orgs","repos_url":"https://api.github.com/users/gnott/repos","events_url":"https://api.github.com/users/gnott/events{/privacy}","received_events_url":"https://api.github.com/users/gnott/received_events","type":"User","site_admin":false},"body":"I noticed it too before, and I wasn't sure. I couldn't find any usage of it here and I think it should be safe to remove. I'll remove it in this PR, and if anything is wrong we should notice it on end2end testing.","created_at":"2018-03-21T22:25:02Z","updated_at":"2018-03-21T22:25:02Z","html_url":"https://github.com/elifesciences/elife-bot/pull/664#discussion_r176258723","pull_request_url":"https://api.github.com/repos/elifesciences/elife-bot/pulls/664","author_association":"OWNER","_links":{"self":{"href":"https://api.github.com/repos/elifesciences/elife-bot/pulls/comments/176258723"},"html":{"href":"https://github.com/elifesciences/elife-bot/pull/664#discussion_r176258723"},"pull_request":{"href":"https://api.github.com/repos/elifesciences/elife-bot/pulls/664"}},"in_reply_to_id":176120656},"pull_request":{"url":"https://api.github.com/repos/elifesciences/elife-bot/pulls/664","id":175404390,"html_url":"https://github.com/elifesciences/elife-bot/pull/664","diff_url":"https://github.com/elifesciences/elife-bot/pull/664.diff","patch_url":"https://github.com/elifesciences/elife-bot/pull/664.patch","issue_url":"https://api.github.com/repos/elifesciences/elife-bot/issues/664","number":664,"state":"open","locked":false,"title":"Feature automate silent corrections","user":{"login":"gnott","id":1779115,"avatar_url":"https://avatars1.githubusercontent.com/u/1779115?v=4","gravatar_id":"","url":"https://api.github.com/users/gnott","html_url":"https://github.com/gnott","followers_url":"https://api.github.com/users/gnott/followers","following_url":"https://api.github.com/users/gnott/following{/other_user}","gists_url":"https://api.github.com/users/gnott/gists{/gist_id}","starred_url":"https://api.github.com/users/gnott/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gnott/subscriptions","organizations_url":"https://api.github.com/users/gnott/orgs","repos_url":"https://api.github.com/users/gnott/repos","events_url":"https://api.github.com/users/gnott/events{/privacy}","received_events_url":"https://api.github.com/users/gnott/received_events","type":"User","site_admin":false},"body":"Looks like silent corrections are working well, and this will connect the S3 notifications to start a new silent corrections workflow. \r\n\r\nI added a very basic test for ``queue_worker.py`` since it had no tests yet. It could probably be improved if I refactored it a bit where is it passed the ``settings``, instead if it being passed ``ENV``, then we could mock the settings in tests easier.","created_at":"2018-03-15T23:22:42Z","updated_at":"2018-03-21T22:25:02Z","closed_at":null,"merged_at":null,"merge_commit_sha":"9fbead40d89f7d011046574225d4682ecd9c61ba","assignee":null,"assignees":[],"requested_reviewers":[{"login":"Jenniferstrej","id":3025214,"avatar_url":"https://avatars0.githubusercontent.com/u/3025214?v=4","gravatar_id":"","url":"https://api.github.com/users/Jenniferstrej","html_url":"https://github.com/Jenniferstrej","followers_url":"https://api.github.com/users/Jenniferstrej/followers","following_url":"https://api.github.com/users/Jenniferstrej/following{/other_user}","gists_url":"https://api.github.com/users/Jenniferstrej/gists{/gist_id}","starred_url":"https://api.github.com/users/Jenniferstrej/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Jenniferstrej/subscriptions","organizations_url":"https://api.github.com/users/Jenniferstrej/orgs","repos_url":"https://api.github.com/users/Jenniferstrej/repos","events_url":"https://api.github.com/users/Jenniferstrej/events{/privacy}","received_events_url":"https://api.github.com/users/Jenniferstrej/received_events","type":"User","site_admin":false}],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/elifesciences/elife-bot/pulls/664/commits","review_comments_url":"https://api.github.com/repos/elifesciences/elife-bot/pulls/664/comments","review_comment_url":"https://api.github.com/repos/elifesciences/elife-bot/pulls/comments{/number}","comments_url":"https://api.github.com/repos/elifesciences/elife-bot/issues/664/comments","statuses_url":"https://api.github.com/repos/elifesciences/elife-bot/statuses/7d81dddf60662ed273a6103deeb40e7ced5bbc5e","head":{"label":"elifesciences:feature-automate-silent-corrections","ref":"feature-automate-silent-corrections","sha":"7d81dddf60662ed273a6103deeb40e7ced5bbc5e","user":{"login":"elifesciences","id":1777367,"avatar_url":"https://avatars2.githubusercontent.com/u/1777367?v=4","gravatar_id":"","url":"https://api.github.com/users/elifesciences","html_url":"https://github.com/elifesciences","followers_url":"https://api.github.com/users/elifesciences/followers","following_url":"https://api.github.com/users/elifesciences/following{/other_user}","gists_url":"https://api.github.com/users/elifesciences/gists{/gist_id}","starred_url":"https://api.github.com/users/elifesciences/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/elifesciences/subscriptions","organizations_url":"https://api.github.com/users/elifesciences/orgs","repos_url":"https://api.github.com/users/elifesciences/repos","events_url":"https://api.github.com/users/elifesciences/events{/privacy}","received_events_url":"https://api.github.com/users/elifesciences/received_events","type":"Organization","site_admin":false},"repo":{"id":7503542,"name":"elife-bot","full_name":"elifesciences/elife-bot","owner":{"login":"elifesciences","id":1777367,"avatar_url":"https://avatars2.githubusercontent.com/u/1777367?v=4","gravatar_id":"","url":"https://api.github.com/users/elifesciences","html_url":"https://github.com/elifesciences","followers_url":"https://api.github.com/users/elifesciences/followers","following_url":"https://api.github.com/users/elifesciences/following{/other_user}","gists_url":"https://api.github.com/users/elifesciences/gists{/gist_id}","starred_url":"https://api.github.com/users/elifesciences/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/elifesciences/subscriptions","organizations_url":"https://api.github.com/users/elifesciences/orgs","repos_url":"https://api.github.com/users/elifesciences/repos","events_url":"https://api.github.com/users/elifesciences/events{/privacy}","received_events_url":"https://api.github.com/users/elifesciences/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/elifesciences/elife-bot","description":"tools for creating an automatic publishing workflow. ","fork":false,"url":"https://api.github.com/repos/elifesciences/elife-bot","forks_url":"https://api.github.com/repos/elifesciences/elife-bot/forks","keys_url":"https://api.github.com/repos/elifesciences/elife-bot/keys{/key_id}","collaborators_url":"https://api.github.com/repos/elifesciences/elife-bot/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/elifesciences/elife-bot/teams","hooks_url":"https://api.github.com/repos/elifesciences/elife-bot/hooks","issue_events_url":"https://api.github.com/repos/elifesciences/elife-bot/issues/events{/number}","events_url":"https://api.github.com/repos/elifesciences/elife-bot/events","assignees_url":"https://api.github.com/repos/elifesciences/elife-bot/assignees{/user}","branches_url":"https://api.github.com/repos/elifesciences/elife-bot/branches{/branch}","tags_url":"https://api.github.com/repos/elifesciences/elife-bot/tags","blobs_url":"https://api.github.com/repos/elifesciences/elife-bot/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/elifesciences/elife-bot/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/elifesciences/elife-bot/git/refs{/sha}","trees_url":"https://api.github.com/repos/elifesciences/elife-bot/git/trees{/sha}","statuses_url":"https://api.github.com/repos/elifesciences/elife-bot/statuses/{sha}","languages_url":"https://api.github.com/repos/elifesciences/elife-bot/languages","stargazers_url":"https://api.github.com/repos/elifesciences/elife-bot/stargazers","contributors_url":"https://api.github.com/repos/elifesciences/elife-bot/contributors","subscribers_url":"https://api.github.com/repos/elifesciences/elife-bot/subscribers","subscription_url":"https://api.github.com/repos/elifesciences/elife-bot/subscription","commits_url":"https://api.github.com/repos/elifesciences/elife-bot/commits{/sha}","git_commits_url":"https://api.github.com/repos/elifesciences/elife-bot/git/commits{/sha}","comments_url":"https://api.github.com/repos/elifesciences/elife-bot/comments{/number}","issue_comment_url":"https://api.github.com/repos/elifesciences/elife-bot/issues/comments{/number}","contents_url":"https://api.github.com/repos/elifesciences/elife-bot/contents/{+path}","compare_url":"https://api.github.com/repos/elifesciences/elife-bot/compare/{base}...{head}","merges_url":"https://api.github.com/repos/elifesciences/elife-bot/merges","archive_url":"https://api.github.com/repos/elifesciences/elife-bot/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/elifesciences/elife-bot/downloads","issues_url":"https://api.github.com/repos/elifesciences/elife-bot/issues{/number}","pulls_url":"https://api.github.com/repos/elifesciences/elife-bot/pulls{/number}","milestones_url":"https://api.github.com/repos/elifesciences/elife-bot/milestones{/number}","notifications_url":"https://api.github.com/repos/elifesciences/elife-bot/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/elifesciences/elife-bot/labels{/name}","releases_url":"https://api.github.com/repos/elifesciences/elife-bot/releases{/id}","deployments_url":"https://api.github.com/repos/elifesciences/elife-bot/deployments","created_at":"2013-01-08T15:09:54Z","updated_at":"2018-03-16T01:23:10Z","pushed_at":"2018-03-20T10:37:11Z","git_url":"git://github.com/elifesciences/elife-bot.git","ssh_url":"git@github.com:elifesciences/elife-bot.git","clone_url":"https://github.com/elifesciences/elife-bot.git","svn_url":"https://github.com/elifesciences/elife-bot","homepage":null,"size":96351,"stargazers_count":14,"watchers_count":14,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":8,"mirror_url":null,"archived":false,"open_issues_count":36,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit"},"forks":8,"open_issues":36,"watchers":14,"default_branch":"develop"}},"base":{"label":"elifesciences:develop","ref":"develop","sha":"b93ab47865560841bd6c8a26159d1bfbfaac80ba","user":{"login":"elifesciences","id":1777367,"avatar_url":"https://avatars2.githubusercontent.com/u/1777367?v=4","gravatar_id":"","url":"https://api.github.com/users/elifesciences","html_url":"https://github.com/elifesciences","followers_url":"https://api.github.com/users/elifesciences/followers","following_url":"https://api.github.com/users/elifesciences/following{/other_user}","gists_url":"https://api.github.com/users/elifesciences/gists{/gist_id}","starred_url":"https://api.github.com/users/elifesciences/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/elifesciences/subscriptions","organizations_url":"https://api.github.com/users/elifesciences/orgs","repos_url":"https://api.github.com/users/elifesciences/repos","events_url":"https://api.github.com/users/elifesciences/events{/privacy}","received_events_url":"https://api.github.com/users/elifesciences/received_events","type":"Organization","site_admin":false},"repo":{"id":7503542,"name":"elife-bot","full_name":"elifesciences/elife-bot","owner":{"login":"elifesciences","id":1777367,"avatar_url":"https://avatars2.githubusercontent.com/u/1777367?v=4","gravatar_id":"","url":"https://api.github.com/users/elifesciences","html_url":"https://github.com/elifesciences","followers_url":"https://api.github.com/users/elifesciences/followers","following_url":"https://api.github.com/users/elifesciences/following{/other_user}","gists_url":"https://api.github.com/users/elifesciences/gists{/gist_id}","starred_url":"https://api.github.com/users/elifesciences/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/elifesciences/subscriptions","organizations_url":"https://api.github.com/users/elifesciences/orgs","repos_url":"https://api.github.com/users/elifesciences/repos","events_url":"https://api.github.com/users/elifesciences/events{/privacy}","received_events_url":"https://api.github.com/users/elifesciences/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/elifesciences/elife-bot","description":"tools for creating an automatic publishing workflow. ","fork":false,"url":"https://api.github.com/repos/elifesciences/elife-bot","forks_url":"https://api.github.com/repos/elifesciences/elife-bot/forks","keys_url":"https://api.github.com/repos/elifesciences/elife-bot/keys{/key_id}","collaborators_url":"https://api.github.com/repos/elifesciences/elife-bot/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/elifesciences/elife-bot/teams","hooks_url":"https://api.github.com/repos/elifesciences/elife-bot/hooks","issue_events_url":"https://api.github.com/repos/elifesciences/elife-bot/issues/events{/number}","events_url":"https://api.github.com/repos/elifesciences/elife-bot/events","assignees_url":"https://api.github.com/repos/elifesciences/elife-bot/assignees{/user}","branches_url":"https://api.github.com/repos/elifesciences/elife-bot/branches{/branch}","tags_url":"https://api.github.com/repos/elifesciences/elife-bot/tags","blobs_url":"https://api.github.com/repos/elifesciences/elife-bot/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/elifesciences/elife-bot/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/elifesciences/elife-bot/git/refs{/sha}","trees_url":"https://api.github.com/repos/elifesciences/elife-bot/git/trees{/sha}","statuses_url":"https://api.github.com/repos/elifesciences/elife-bot/statuses/{sha}","languages_url":"https://api.github.com/repos/elifesciences/elife-bot/languages","stargazers_url":"https://api.github.com/repos/elifesciences/elife-bot/stargazers","contributors_url":"https://api.github.com/repos/elifesciences/elife-bot/contributors","subscribers_url":"https://api.github.com/repos/elifesciences/elife-bot/subscribers","subscription_url":"https://api.github.com/repos/elifesciences/elife-bot/subscription","commits_url":"https://api.github.com/repos/elifesciences/elife-bot/commits{/sha}","git_commits_url":"https://api.github.com/repos/elifesciences/elife-bot/git/commits{/sha}","comments_url":"https://api.github.com/repos/elifesciences/elife-bot/comments{/number}","issue_comment_url":"https://api.github.com/repos/elifesciences/elife-bot/issues/comments{/number}","contents_url":"https://api.github.com/repos/elifesciences/elife-bot/contents/{+path}","compare_url":"https://api.github.com/repos/elifesciences/elife-bot/compare/{base}...{head}","merges_url":"https://api.github.com/repos/elifesciences/elife-bot/merges","archive_url":"https://api.github.com/repos/elifesciences/elife-bot/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/elifesciences/elife-bot/downloads","issues_url":"https://api.github.com/repos/elifesciences/elife-bot/issues{/number}","pulls_url":"https://api.github.com/repos/elifesciences/elife-bot/pulls{/number}","milestones_url":"https://api.github.com/repos/elifesciences/elife-bot/milestones{/number}","notifications_url":"https://api.github.com/repos/elifesciences/elife-bot/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/elifesciences/elife-bot/labels{/name}","releases_url":"https://api.github.com/repos/elifesciences/elife-bot/releases{/id}","deployments_url":"https://api.github.com/repos/elifesciences/elife-bot/deployments","created_at":"2013-01-08T15:09:54Z","updated_at":"2018-03-16T01:23:10Z","pushed_at":"2018-03-20T10:37:11Z","git_url":"git://github.com/elifesciences/elife-bot.git","ssh_url":"git@github.com:elifesciences/elife-bot.git","clone_url":"https://github.com/elifesciences/elife-bot.git","svn_url":"https://github.com/elifesciences/elife-bot","homepage":null,"size":96351,"stargazers_count":14,"watchers_count":14,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":8,"mirror_url":null,"archived":false,"open_issues_count":36,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit"},"forks":8,"open_issues":36,"watchers":14,"default_branch":"develop"}},"_links":{"self":{"href":"https://api.github.com/repos/elifesciences/elife-bot/pulls/664"},"html":{"href":"https://github.com/elifesciences/elife-bot/pull/664"},"issue":{"href":"https://api.github.com/repos/elifesciences/elife-bot/issues/664"},"comments":{"href":"https://api.github.com/repos/elifesciences/elife-bot/issues/664/comments"},"review_comments":{"href":"https://api.github.com/repos/elifesciences/elife-bot/pulls/664/comments"},"review_comment":{"href":"https://api.github.com/repos/elifesciences/elife-bot/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/elifesciences/elife-bot/pulls/664/commits"},"statuses":{"href":"https://api.github.com/repos/elifesciences/elife-bot/statuses/7d81dddf60662ed273a6103deeb40e7ced5bbc5e"}},"author_association":"OWNER"}}
{"actor":{"display_login":"gnott"}}