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)
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
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())
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
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
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)
async def stop(self): if not self.running: return LOG.info("Stopping webhook") await self.http.stop()