Пример #1
0
    async def start(self):
        if self.running:
            return

        LOG.info(
            f"Starting webhook on http://{self.config.host if self.config.host is not None else 'localhost'}:{self.config.port}{self.config.path}")
        self._setup_http()
        await self.http.start(host=self.config.host, port=self.config.port)
Пример #2
0
    def get_issue(self, repo_name: str, pr_id: int) -> Optional[Issue]:
        issue: Optional[Issue]
        try:
            repo = self.client.get_repo(repo_name, lazy=True)
            pr = repo.get_pull(pr_id)
            issue = Issue(pr)
        except github.UnknownObjectException:
            issue = None

        LOG.debug(f"Lookup {repo_name}/PR #{pr_id}: {issue}")
        return issue
Пример #3
0
    async def _verify_event(self, request: web.Request):
        header_signature = request.headers.get('X-Hub-Signature')
        if header_signature is None:
            return web.Response(status=403)

        sha_name, signature = header_signature.split('=')
        body = await request.read()
        mac = hmac.new(self.secret, msg=body, digestmod=sha_name)
        if not hmac.compare_digest(str(mac.hexdigest()), str(signature)):
            LOG.error("Invalid webhook event payload signature!")
            return web.Response(status=403)

        await self._handle_event(await request.json())
Пример #4
0
    async def end_vote(self, vote: Vote):
        # get latest poll/issue data
        LOG.debug(f"Ending vote {vote}")
        try:
            await vote.update()
        except Exception as err:
            LOG.exception(f"Error updating vote data: {vote}")
            raise err

        # check if vote was cancelled or otherwise invalidated
        labels = vote.config.github.labels
        actions = []
        if not vote.exists:
            # vote cancelled - cleanup
            LOG.info(
                f"Vote {vote} has been cancelled. Cleaning up any labels/messages"
            )
            actions = []
            if vote.issue.exists and labels.vote_in_progress in vote.issue.labels:
                actions.append(vote.issue.remove_label(
                    labels.vote_in_progress))
            if vote.poll is not None and vote.poll.exists:
                actions.append(_try_unpin(vote.poll.msg, "Vote cancelled"))
        else:
            # vote exists, close
            LOG.info(
                f"Vote {vote} is closing. Doing cleanup and adding result labels"
            )
            result_label = labels.vote_accepted if vote.poll.is_vote_accepted(
            ) else labels.vote_rejected
            actions.append(
                vote.poll.msg.channel.send(embed=_display_vote_end(vote)))
            actions.append(vote.issue.remove_label(labels.vote_in_progress))
            actions.append(vote.issue.add_label(result_label))
            actions.append(_try_unpin(vote.poll.msg, "Vote finished"))

        # execute
        if len(actions) > 0:
            try:
                await asyncio.gather(*actions)
            except Exception as err:
                LOG.exception(f"Error ending vote {vote}")
                raise err
Пример #5
0
    async def start_vote(self, bot: Red, vote: Vote):
        # config this vote will use
        emojis = vote.config.discord.media
        labels = vote.config.github.labels

        channel = bot.get_channel(vote.config.discord.channel_id)
        if channel is None:
            LOG.error(
                f"Error looking up channel_id found in channel conf. channel_id={vote.config.discord.channel_id}"
            )
            raise NoChannel()

        # action to start polling
        async def create_poll():
            embed = _display_vote_start(vote)

            # create msg with menu items
            poll_msg = await channel.send(embed=embed)
            await asyncio.gather(poll_msg.add_reaction(emojis.aye_vote_emoji),
                                 poll_msg.add_reaction(emojis.nay_vote_emoji),
                                 _try_pin(poll_msg, "Voting has started"))

            vote.poll = Poll(
                poll_msg, emojis.aye_vote_emoji, emojis.nay_vote_emoji
            )  # legacy, passing emojis here but should just keep that in config

        # actions needed to start vote
        actions = [
            create_poll(),
            vote.issue.remove_label(labels.needs_vote),
            vote.issue.add_label(labels.vote_in_progress)
        ]

        # remove previous vote results
        for other_label in [
                labels.vote_rejected, labels.vote_accepted,
                labels.vote_in_progress
        ]:
            if other_label in vote.issue.labels:
                actions.append(vote.issue.remove_label(other_label))

        # execute
        LOG.debug(f"Starting vote {vote}")
        try:
            await asyncio.gather(*actions)
            LOG.info(f"Started vote {vote}")
        except Exception as err:
            LOG.exception(f"Error starting vote {vote}")
            raise err

        return vote
Пример #6
0
 async def sleep_voting_period(self, vote: Vote):
     remaining_seconds = vote.remaining_seconds()
     if remaining_seconds > 0:
         LOG.debug(
             f"Waiting {remaining_seconds} seconds before polling {vote}")
         await asyncio.sleep(remaining_seconds)
Пример #7
0
    async def stop(self):
        if not self.running:
            return

        LOG.info("Stopping webhook")
        await self.http.stop()