def _get_afi_reports( self, yeswehack_client: YesWeHackApiClient, program: Program, ) -> List[Report]: program_slug = cast(str, program.slug) filters = { 'filter[trackingStatus][0]': 'AFI', } synchronize_options = cast(SynchronizeOptions, program.synchronize_options) feedback_options = cast(FeedbackOptions, program.feedback_options) include_tracked = any(( synchronize_options.upload_private_comments, synchronize_options.upload_public_comments, synchronize_options.upload_details_updates, synchronize_options.upload_rewards, synchronize_options.upload_status_updates, feedback_options.download_tracker_comments, feedback_options.issue_closed_to_report_afv, ), ) if include_tracked: filters['filter[trackingStatus][1]'] = 'T' try: return yeswehack_client.get_program_reports( slug=program_slug, filters=filters, ) except YesWeHackApiClientError as e: raise SynchronizerError( f'Unable to get AFI/T reports for program {program_slug}', ) from e
def _create_tracker_issue(self, ) -> TrackerIssue: try: tracker_issue = self._tracker_client.send_report( report=self._report, ) except TrackerClientError as send_error: raise SynchronizerError( f'Unable to send report #{self._report.report_id} to {self._tracker_name}', ) from send_error return tracker_issue
def _download_comment( self, tracker_issue: TrackerIssue, tracker_comment: TrackerIssueComment, ) -> None: attachments = {} for attachment_key, attachment in tracker_comment.attachments.items(): try: uploaded_attachment = self._yeswehack_client.post_report_attachment( report=self._report, filename=attachment.filename, file_content=attachment.content, file_type=attachment.mime_type, ) except YesWeHackApiClientError as upload_attachment_error: raise SynchronizerError( f'Unable to upload attachment {attachment.filename} for report #{self._report.report_id}', ) from upload_attachment_error attachments[attachment_key] = uploaded_attachment try: self._yeswehack_client.post_report_tracker_message( report=self._report, tracker_name=self._tracker_name, issue_id=tracker_issue.issue_id, issue_url=tracker_issue.issue_url, comment=self._message_formatter.format_download_comment( comment=tracker_comment, attachments=attachments, ), attachments=[ uploaded_attachment.name for attachment_key, uploaded_attachment in attachments.items() ], ) except YesWeHackApiClientError as tracker_message_error: raise SynchronizerError( f'Unable to download comment {tracker_comment.comment_id} for report #{self._report.report_id}', ) from tracker_message_error
def _get_tracker_issue_comments( self, tracker_issue: TrackerIssue, exclude_comments: Optional[List[str]] = None, ) -> TrackerIssueComments: try: return self._tracker_client.get_tracker_issue_comments( issue_id=tracker_issue.issue_id, exclude_comments=exclude_comments, ) except TrackerClientError as issue_comments_error: raise SynchronizerError( f'Unable to get issue comments for #{tracker_issue.issue_id}', ) from issue_comments_error
def _send_logs( self, tracker_issue: TrackerIssue, logs: List[Log], ) -> SendLogsResult: try: return self._tracker_client.send_logs( tracker_issue=tracker_issue, logs=logs, ) except TrackerClientError as send_error: raise SynchronizerError( f'Unable to send logs for #{self._report.report_id} to {self._tracker_name}', ) from send_error
def _update_tracking_status( self, tracker_issue: TrackerIssue, ) -> None: message = self._message_formatter.format_tracking_status_update_message( tracker_type=self._tracker_client.tracker_type, tracker_issue=tracker_issue, ) try: self._yeswehack_client.put_report_tracking_status( report=self._report, status='T', tracker_name=self._tracker_name, issue_id=tracker_issue.issue_id, issue_url=tracker_issue.issue_url, comment=message, ) except YesWeHackApiClientError as tracking_status_error: raise SynchronizerError( f'Unable to update tracking status for report #{self._report.report_id}', ) from tracking_status_error
def _post_report_tracker_update( self, tracker_issue: TrackerIssue, tracker_issue_state: TrackerIssueState, send_logs_result: SendLogsResult, download_comments_result: DownloadCommentsResult, new_report_status: Optional[Tuple[str, str]], issue_status: str, ) -> None: post_update = any(( send_logs_result.added_comments, download_comments_result.downloaded_comments, tracker_issue_state.changed, ), ) if post_update: try: self._yeswehack_client.post_report_tracker_update( report=self._report, tracker_name=self._tracker_name, issue_id=tracker_issue.issue_id, issue_url=tracker_issue.issue_url, token=StateEncryptor.encrypt( key=self._report.report_id, state=tracker_issue_state, ), comment=self._message_formatter. format_synchronization_done_message( tracker_type=self._tracker_client.tracker_type, report=self._report, send_logs_result=send_logs_result, download_comments_result=download_comments_result, new_report_status=new_report_status, issue_status=issue_status, ), ) except YesWeHackApiClientError as tracker_update_error: raise SynchronizerError( f'Unable to post tracker update for report #{self._report.report_id}', ) from tracker_update_error
def synchronize_report(self, ) -> SynchronizeReportResult: """ Synchronize a YesWeHack report and a tracker issue. Raises: SynchronizerError: if a synchronization error occur Returns: the result of the synchronization """ tracker_issue = self._get_tracker_issue_from_logs() is_existing_issue = tracker_issue is not None if not is_existing_issue: tracker_issue = self._create_tracker_issue() if not isinstance(tracker_issue, TrackerIssue): raise SynchronizerError( f'Unable to create new or get existing issue for #{self._report.report_id} in {self._tracker_name}', ) if self._report.tracking_status != 'T' or not is_existing_issue: self._update_tracking_status(tracker_issue=tracker_issue, ) tracker_issue_state = TrackerIssueState( closed=False, bugtracker_name=self._tracker_name, ) logs = self._report.logs if is_existing_issue: log_state = self._get_last_tracker_update_log() if log_state: last_tracker_update_log, tracker_issue_state = log_state if last_tracker_update_log: logs = self._report.get_logs_after( log=last_tracker_update_log, ) send_logs_result = self._send_synchronizable_logs( tracker_issue=tracker_issue, logs=logs, ) for added_comment in send_logs_result.added_comments: tracker_issue_state.add_downloaded_comment( added_comment.comment_id) download_comments_result = self._download_comments( tracker_issue=tracker_issue, exclude_comments=tracker_issue_state.downloaded_comments, ) for downloaded_comment in download_comments_result.downloaded_comments: tracker_issue_state.add_downloaded_comment(downloaded_comment) new_report_status = self._update_report_status( tracker_issue=tracker_issue, tracker_issue_state=tracker_issue_state, ) issue_status = self._get_issue_status_change( tracker_issue=tracker_issue, tracker_issue_state=tracker_issue_state, ) tracker_issue_state.closed = tracker_issue.closed self._post_report_tracker_update( tracker_issue=tracker_issue, tracker_issue_state=tracker_issue_state, send_logs_result=send_logs_result, download_comments_result=download_comments_result, new_report_status=new_report_status, issue_status=issue_status, ) return SynchronizeReportResult( is_existing_issue=is_existing_issue, new_report_status=new_report_status, send_logs_result=send_logs_result, download_comments_result=download_comments_result, )