Jira now works too. Too many changes to document still.
This commit is contained in:
parent
a11bd66fbc
commit
504655d19a
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
|
|
||||||
//#include "BugzillaJSONStructs.generated.h"
|
#include "BugzillaJSONStructs.generated.h"
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -4,4 +4,4 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
|
|
||||||
//#include "JiraJSONStructs.generated.h"
|
#include "JiraJSONStructs.generated.h"
|
||||||
|
|||||||
@ -21,13 +21,17 @@ void UBugMarkerSubsystem::Initialize(FSubsystemCollectionBase &Collection)
|
|||||||
this->ServerAPI = NewObject<UServerBugzillaAPI>(this);
|
this->ServerAPI = NewObject<UServerBugzillaAPI>(this);
|
||||||
break;
|
break;
|
||||||
case EBugReportPlatform::Jira:
|
case EBugReportPlatform::Jira:
|
||||||
// this->ServerAPI = NewObject<UServerJiraAPI>(this);
|
this->ServerAPI = NewObject<UServerJiraAPI>(this);
|
||||||
// break;
|
break;
|
||||||
default:
|
default:
|
||||||
this->ServerAPI = NewObject<UServerAPI>(this);
|
this->ServerAPI = NewObject<UServerAPI>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this->ServerAPI)
|
if (this->ServerAPI)
|
||||||
|
{
|
||||||
|
this->ServerAPI->Initialize();
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
UE_LOG(BugMarkerSubsystemLog, Error, TEXT("Could not create Server API class; this will certainly crash eventually"));
|
UE_LOG(BugMarkerSubsystemLog, Error, TEXT("Could not create Server API class; this will certainly crash eventually"));
|
||||||
}
|
}
|
||||||
@ -79,6 +83,7 @@ void UBugMarkerSubsystem::HideBugMarkers()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void UBugMarkerSubsystem::PrepareSubmissionFormData()
|
void UBugMarkerSubsystem::PrepareSubmissionFormData()
|
||||||
{
|
{
|
||||||
this->ServerAPI->FormDataResponse.BindUObject(this, &UBugMarkerSubsystem::FormPrepResponseCallback);
|
this->ServerAPI->FormDataResponse.BindUObject(this, &UBugMarkerSubsystem::FormPrepResponseCallback);
|
||||||
@ -106,7 +111,7 @@ void UBugMarkerSubsystem::LoadNewBatch()
|
|||||||
const FUnrealzillaBugData BugData = this->BugBatch[0];
|
const FUnrealzillaBugData BugData = this->BugBatch[0];
|
||||||
|
|
||||||
FString LocationString, UpVectorString;
|
FString LocationString, UpVectorString;
|
||||||
BugData.MapLocation.Split(":", &LocationString, &UpVectorString);
|
BugData.MarkerLocation.Split(":", &LocationString, &UpVectorString);
|
||||||
|
|
||||||
FString LocationX, LocationY, LocationZ;
|
FString LocationX, LocationY, LocationZ;
|
||||||
LocationString.Split(",", &LocationX, &LocationY);
|
LocationString.Split(",", &LocationX, &LocationY);
|
||||||
|
|||||||
@ -36,7 +36,7 @@ void UBugSubmissionForm::NativeOnInitialized()
|
|||||||
{
|
{
|
||||||
this->ShowProcessingOverlayLoading();
|
this->ShowProcessingOverlayLoading();
|
||||||
|
|
||||||
UBugMarkerSubsystem *BugMarkerSubsystem = UGameplayStatics::GetPlayerController(this, 0)->GetLocalPlayer()->GetSubsystem<UBugMarkerSubsystem>();
|
UBugMarkerSubsystem *BugMarkerSubsystem = UBugMarkerSubsystem::GetBugMarkerSubsystem(this);
|
||||||
BugMarkerSubsystem->FormPrepResponse.BindUObject(this, &UBugSubmissionForm::PrepareFormData);
|
BugMarkerSubsystem->FormPrepResponse.BindUObject(this, &UBugSubmissionForm::PrepareFormData);
|
||||||
BugMarkerSubsystem->PrepareSubmissionFormData();
|
BugMarkerSubsystem->PrepareSubmissionFormData();
|
||||||
|
|
||||||
@ -95,13 +95,13 @@ void UBugSubmissionForm::ShowProcessingOverlayLoading()
|
|||||||
this->ProcessingRequestErrorBox->SetVisibility(ESlateVisibility::Collapsed);
|
this->ProcessingRequestErrorBox->SetVisibility(ESlateVisibility::Collapsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UBugSubmissionForm::ShowProcessingOverlayMessage(const FString Message, const bool bExitAfterConfirm)
|
void UBugSubmissionForm::ShowProcessingOverlayMessage(const FUnrealzillaErrorData &Error)
|
||||||
{
|
{
|
||||||
this->ProcessingRequestErrorText->SetText(FText::AsCultureInvariant(Message));
|
this->ProcessingRequestErrorText->SetText(FText::AsCultureInvariant(Error.ErrorMessage));
|
||||||
this->ProcessingRequestOverlay->SetVisibility(ESlateVisibility::Visible);
|
this->ProcessingRequestOverlay->SetVisibility(ESlateVisibility::Visible);
|
||||||
this->ProcessingRequestThrobber->SetVisibility(ESlateVisibility::Collapsed);
|
this->ProcessingRequestThrobber->SetVisibility(ESlateVisibility::Collapsed);
|
||||||
this->ProcessingRequestErrorBox->SetVisibility(ESlateVisibility::Visible);
|
this->ProcessingRequestErrorBox->SetVisibility(ESlateVisibility::Visible);
|
||||||
if (bExitAfterConfirm)
|
if (Error.bCancelForm)
|
||||||
{
|
{
|
||||||
this->ProcessingRequestErrorButton->OnClicked().AddUObject(this, &UBugSubmissionForm::CancelForm);
|
this->ProcessingRequestErrorButton->OnClicked().AddUObject(this, &UBugSubmissionForm::CancelForm);
|
||||||
}
|
}
|
||||||
@ -123,12 +123,13 @@ void UBugSubmissionForm::SubmitForm()
|
|||||||
PostData.Component = this->ComponentButton->GetText().ToString();
|
PostData.Component = this->ComponentButton->GetText().ToString();
|
||||||
PostData.Severity = this->SeverityButton->GetText().ToString();
|
PostData.Severity = this->SeverityButton->GetText().ToString();
|
||||||
PostData.MapName = this->MapName.ToString();
|
PostData.MapName = this->MapName.ToString();
|
||||||
PostData.MapLocation = this->MarkerLocation.ToString();
|
PostData.MarkerLocation = this->MarkerLocation.ToString();
|
||||||
PostData.Summary = this->SummaryEntryBox->GetText().ToString();
|
PostData.Summary = this->SummaryEntryBox->GetText().ToString();
|
||||||
PostData.Comment = this->CommentEntryBox->GetText().ToString();
|
PostData.Comment = this->CommentEntryBox->GetText().ToString();
|
||||||
|
|
||||||
UBugMarkerSubsystem *BugMarkerSubsystem = UGameplayStatics::GetPlayerController(this, 0)->GetLocalPlayer()->GetSubsystem<UBugMarkerSubsystem>();
|
UBugMarkerSubsystem *BugMarkerSubsystem = UBugMarkerSubsystem::GetBugMarkerSubsystem(this);
|
||||||
BugMarkerSubsystem->FormPostResponse.BindUObject(this, &UBugSubmissionForm::UpdateReportMarker);
|
BugMarkerSubsystem->FormPostResponse.BindUObject(this, &UBugSubmissionForm::UpdateReportMarker);
|
||||||
|
BugMarkerSubsystem->ErrorResponse.BindUObject(this, &UBugSubmissionForm::ShowProcessingOverlayMessage);
|
||||||
BugMarkerSubsystem->SubmitForm(PostData);
|
BugMarkerSubsystem->SubmitForm(PostData);
|
||||||
|
|
||||||
this->OnFormSubmit.ExecuteIfBound();
|
this->OnFormSubmit.ExecuteIfBound();
|
||||||
@ -136,7 +137,16 @@ void UBugSubmissionForm::SubmitForm()
|
|||||||
|
|
||||||
void UBugSubmissionForm::UpdateReportMarker(const FUnrealzillaBugData &BugData)
|
void UBugSubmissionForm::UpdateReportMarker(const FUnrealzillaBugData &BugData)
|
||||||
{
|
{
|
||||||
this->BugMarkerActor->SetBugData(BugData);
|
UBugMarkerSubsystem *BugMarkerSubsystem = UBugMarkerSubsystem::GetBugMarkerSubsystem(this);
|
||||||
|
if (BugMarkerSubsystem->AreMarkersVisible())
|
||||||
|
{
|
||||||
|
this->BugMarkerActor->SetBugData(BugData);
|
||||||
|
BugMarkerSubsystem->AddBugMarker(this->BugMarkerActor);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->BugMarkerActor->Destroy();
|
||||||
|
}
|
||||||
this->CloseForm();
|
this->CloseForm();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,5 +169,5 @@ void UBugSubmissionForm::CloseForm()
|
|||||||
|
|
||||||
void UBugSubmissionForm::ErrorResponseCallback(const FUnrealzillaErrorData &Error)
|
void UBugSubmissionForm::ErrorResponseCallback(const FUnrealzillaErrorData &Error)
|
||||||
{
|
{
|
||||||
this->ShowProcessingOverlayMessage(Error.ErrorMessage);
|
this->ShowProcessingOverlayMessage(Error);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,20 +30,17 @@ void UServerAPI::ServerConnectionError(const EHttpRequestStatus::Type Status)
|
|||||||
{
|
{
|
||||||
switch (Status) {
|
switch (Status) {
|
||||||
case EHttpRequestStatus::Failed_ConnectionError:
|
case EHttpRequestStatus::Failed_ConnectionError:
|
||||||
this->CreateError("Unable to connect to the server");
|
this->CreateError("There was an error connecting to the server. Please retry.", true);
|
||||||
//this->ShowProcessingOverlayMessage("Unable to connect to the server", true);
|
|
||||||
break;
|
|
||||||
case EHttpRequestStatus::NotStarted:
|
|
||||||
this->CreateError("Connection could not start");
|
|
||||||
//this->ShowProcessingOverlayMessage("Connection could not start", true);
|
|
||||||
break;
|
break;
|
||||||
case EHttpRequestStatus::Failed:
|
case EHttpRequestStatus::Failed:
|
||||||
this->CreateError("Connection failed");
|
this->CreateError("Connection to the server completed but then failed.", true);
|
||||||
//this->ShowProcessingOverlayMessage("Connection failed", true);
|
break;
|
||||||
|
case EHttpRequestStatus::NotStarted:
|
||||||
|
this->CreateError("Connection was not started.");
|
||||||
|
break;
|
||||||
|
case EHttpRequestStatus::Processing:
|
||||||
|
this->CreateError("Connection is still being processed.");
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
this->CreateError("Request failed for unknown reasons");
|
|
||||||
//this->ShowProcessingOverlayMessage("Request failed for unknown reasons", true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,11 +80,12 @@ void UServerAPI::CreateError(const EErrorVerb &Verb, const FBugzillaJSONBugRespo
|
|||||||
Error.DocumentationLink = Data.documentation;
|
Error.DocumentationLink = Data.documentation;
|
||||||
this->ErrorResponse.Execute(Error);
|
this->ErrorResponse.Execute(Error);
|
||||||
}
|
}
|
||||||
void UServerAPI::CreateError(const FString &ErrorMessage)
|
void UServerAPI::CreateError(const FString &ErrorMessage, const bool bCancelForm)
|
||||||
{
|
{
|
||||||
FUnrealzillaErrorData Error;
|
FUnrealzillaErrorData Error;
|
||||||
Error.ErrorVerb = EErrorVerb::None;
|
Error.ErrorVerb = EErrorVerb::None;
|
||||||
Error.ErrorMessage = ErrorMessage;
|
Error.ErrorMessage = ErrorMessage;
|
||||||
|
Error.bCancelForm = bCancelForm;
|
||||||
this->ErrorResponse.Execute(Error);
|
this->ErrorResponse.Execute(Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@
|
|||||||
#include "Kismet/GameplayStatics.h"
|
#include "Kismet/GameplayStatics.h"
|
||||||
|
|
||||||
|
|
||||||
UServerBugzillaAPI::UServerBugzillaAPI()
|
void UServerBugzillaAPI::Initialize()
|
||||||
{
|
{
|
||||||
this->FullURL = UServerAPI::URLBuilder(
|
this->FullURL = UServerAPI::URLBuilder(
|
||||||
GetDefault<UUnrealzillaGlobalSettings>()->BugzillaSubmissionServer,
|
GetDefault<UUnrealzillaGlobalSettings>()->BugzillaSubmissionServer,
|
||||||
@ -74,7 +74,7 @@ void UServerBugzillaAPI::ListOfBugsResponse(FHttpRequestPtr Request, FHttpRespon
|
|||||||
Bug.Summary = BugzillaData.summary;
|
Bug.Summary = BugzillaData.summary;
|
||||||
Bug.Component = BugzillaData.component;
|
Bug.Component = BugzillaData.component;
|
||||||
Bug.MapName = BugzillaData.cf_mapname;
|
Bug.MapName = BugzillaData.cf_mapname;
|
||||||
Bug.MapLocation = BugzillaData.cf_location;
|
Bug.MarkerLocation = BugzillaData.cf_location;
|
||||||
Bug.Platform = BugzillaData.platform;
|
Bug.Platform = BugzillaData.platform;
|
||||||
Bug.OperatingSystem = BugzillaData.op_sys;
|
Bug.OperatingSystem = BugzillaData.op_sys;
|
||||||
Bug.Severity = BugzillaData.severity;
|
Bug.Severity = BugzillaData.severity;
|
||||||
@ -140,7 +140,7 @@ void UServerBugzillaAPI::SendFormData(const FUnrealzillaPostData &PostData)
|
|||||||
TMap<FString, FString> QueryData;
|
TMap<FString, FString> QueryData;
|
||||||
QueryData.Add("api_key", GetDefault<UUnrealzillaGlobalSettings>()->BugzillaAPIKey);
|
QueryData.Add("api_key", GetDefault<UUnrealzillaGlobalSettings>()->BugzillaAPIKey);
|
||||||
|
|
||||||
const FString DefaultStatus = GetDefault<UUnrealzillaGlobalSettings>()->DefaultStatus;
|
const FString DefaultStatus = GetDefault<UUnrealzillaGlobalSettings>()->BugzillaDefaultStatus;
|
||||||
|
|
||||||
FBugzillaJSONPostBug PostDataJSON;
|
FBugzillaJSONPostBug PostDataJSON;
|
||||||
PostDataJSON.product = GetDefault<UUnrealzillaGlobalSettings>()->BugzillaProductName;
|
PostDataJSON.product = GetDefault<UUnrealzillaGlobalSettings>()->BugzillaProductName;
|
||||||
@ -150,7 +150,7 @@ void UServerBugzillaAPI::SendFormData(const FUnrealzillaPostData &PostData)
|
|||||||
PostDataJSON.component = PostData.Component;
|
PostDataJSON.component = PostData.Component;
|
||||||
PostDataJSON.severity = PostData.Severity;
|
PostDataJSON.severity = PostData.Severity;
|
||||||
PostDataJSON.cf_mapname = PostData.MapName;
|
PostDataJSON.cf_mapname = PostData.MapName;
|
||||||
PostDataJSON.cf_location = PostData.MapLocation;
|
PostDataJSON.cf_location = PostData.MarkerLocation;
|
||||||
PostDataJSON.summary = PostData.Summary;
|
PostDataJSON.summary = PostData.Summary;
|
||||||
PostDataJSON.description = PostData.Comment;
|
PostDataJSON.description = PostData.Comment;
|
||||||
if (!DefaultStatus.IsEmpty())
|
if (!DefaultStatus.IsEmpty())
|
||||||
@ -278,7 +278,7 @@ void UServerBugzillaAPI::ServerPOSTUpdateMarkerResponse(FHttpRequestPtr Request,
|
|||||||
Bug.Summary = ResponseData.bugs[0].summary;
|
Bug.Summary = ResponseData.bugs[0].summary;
|
||||||
Bug.Component = ResponseData.bugs[0].component;
|
Bug.Component = ResponseData.bugs[0].component;
|
||||||
Bug.MapName = ResponseData.bugs[0].cf_mapname;
|
Bug.MapName = ResponseData.bugs[0].cf_mapname;
|
||||||
Bug.MapLocation = ResponseData.bugs[0].cf_location;
|
Bug.MarkerLocation = ResponseData.bugs[0].cf_location;
|
||||||
Bug.Platform = ResponseData.bugs[0].platform;
|
Bug.Platform = ResponseData.bugs[0].platform;
|
||||||
Bug.OperatingSystem = ResponseData.bugs[0].op_sys;
|
Bug.OperatingSystem = ResponseData.bugs[0].op_sys;
|
||||||
Bug.Severity = ResponseData.bugs[0].severity;
|
Bug.Severity = ResponseData.bugs[0].severity;
|
||||||
|
|||||||
@ -10,437 +10,332 @@
|
|||||||
#include "Kismet/GameplayStatics.h"
|
#include "Kismet/GameplayStatics.h"
|
||||||
|
|
||||||
|
|
||||||
UServerJiraAPI::UServerJiraAPI()
|
void UServerJiraAPI::Initialize()
|
||||||
{
|
{
|
||||||
this->FullURL = UServerAPI::URLBuilder(
|
this->FullURL = UServerAPI::URLBuilder(
|
||||||
GetDefault<UUnrealzillaGlobalSettings>()->JiraSubmissionServer,
|
GetDefault<UUnrealzillaGlobalSettings>()->JiraSubmissionServer,
|
||||||
GetDefault<UUnrealzillaGlobalSettings>()->JiraRESTURI
|
GetDefault<UUnrealzillaGlobalSettings>()->JiraRESTURI
|
||||||
);
|
);
|
||||||
|
|
||||||
|
FHttpModule &HttpModule = FHttpModule::Get();
|
||||||
|
|
||||||
|
// Get board data
|
||||||
|
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> BoardRequest = HttpModule.CreateRequest();
|
||||||
|
BoardRequest->SetVerb(TEXT("GET"));
|
||||||
|
BoardRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
|
||||||
|
BoardRequest->AppendToHeader(TEXT("Authorization"), TEXT("Basic ") + this->GenerateAuthString());
|
||||||
|
BoardRequest->SetURL(this->FullURL + "agile/1.0/board");
|
||||||
|
BoardRequest->OnProcessRequestComplete().BindUObject(this, &UServerJiraAPI::ListOfBoardsResponse);
|
||||||
|
BoardRequest->ProcessRequest();
|
||||||
|
|
||||||
|
// Get custom field data
|
||||||
|
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> FieldsRequest = HttpModule.CreateRequest();
|
||||||
|
FieldsRequest->SetVerb(TEXT("GET"));
|
||||||
|
FieldsRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
|
||||||
|
FieldsRequest->AppendToHeader(TEXT("Authorization"), TEXT("Basic ") + this->GenerateAuthString());
|
||||||
|
FieldsRequest->SetURL(this->FullURL + "api/2/field");
|
||||||
|
FieldsRequest->OnProcessRequestComplete().BindUObject(this, &UServerJiraAPI::ListOfFieldsResponse);
|
||||||
|
FieldsRequest->ProcessRequest();
|
||||||
|
}
|
||||||
|
void UServerJiraAPI::ListOfBoardsResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success)
|
||||||
|
{
|
||||||
|
if (Success)
|
||||||
|
{
|
||||||
|
const FString &JSONResponse = Response->GetContentAsString();
|
||||||
|
|
||||||
|
TSharedPtr<FJsonObject> JSON = MakeShareable(new FJsonObject);
|
||||||
|
const TSharedRef<TJsonReader<>> &Reader = TJsonReaderFactory<>::Create(JSONResponse);
|
||||||
|
if (FJsonSerializer::Deserialize(Reader, JSON))
|
||||||
|
{
|
||||||
|
const TArray<TSharedPtr<FJsonValue>> &BoardsArray = JSON->GetArrayField("values");
|
||||||
|
for (const TSharedPtr<FJsonValue> &BoardValue : BoardsArray)
|
||||||
|
{
|
||||||
|
const TSharedPtr<FJsonObject> &Board = BoardValue->AsObject();
|
||||||
|
const TSharedPtr<FJsonObject> &Location = Board->GetObjectField("location");
|
||||||
|
if (Location->GetStringField("projectName") == GetDefault<UUnrealzillaGlobalSettings>()->JiraProjectName)
|
||||||
|
{
|
||||||
|
this->BoardID = Board->GetIntegerField("id");
|
||||||
|
this->ProjectID = Location->GetIntegerField("projectId");
|
||||||
|
this->ProjectKey = Location->GetStringField("projectKey");
|
||||||
|
this->ProjectAvatarURI = Location->GetStringField("avatarURI");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->CreateError("Could not retrieve board data.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->CreateError("Could not retrieve board data.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void UServerJiraAPI::ListOfFieldsResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success)
|
||||||
|
{
|
||||||
|
if (Success)
|
||||||
|
{
|
||||||
|
const FString &JSONResponse = "{\"fields\":" + Response->GetContentAsString() + "}";
|
||||||
|
|
||||||
|
TSharedPtr<FJsonObject> JSON = MakeShareable(new FJsonObject);
|
||||||
|
const TSharedRef<TJsonReader<>> &Reader = TJsonReaderFactory<>::Create(JSONResponse);
|
||||||
|
if (FJsonSerializer::Deserialize(Reader, JSON))
|
||||||
|
{
|
||||||
|
const TArray<TSharedPtr<FJsonValue>> &FieldArray = JSON->GetArrayField("fields");
|
||||||
|
for (const TSharedPtr<FJsonValue> &FieldValue : FieldArray)
|
||||||
|
{
|
||||||
|
const TSharedPtr<FJsonObject> &Field = FieldValue->AsObject();
|
||||||
|
const FString &Name = Field->GetStringField("name");
|
||||||
|
const FString &Key = Field->GetStringField("key");
|
||||||
|
if (Name == GetDefault<UUnrealzillaGlobalSettings>()->JiraMapNameField)
|
||||||
|
{
|
||||||
|
this->MapNameCustomField = Key;
|
||||||
|
}
|
||||||
|
else if (Name == GetDefault<UUnrealzillaGlobalSettings>()->JiraMarkerLocationField)
|
||||||
|
{
|
||||||
|
this->MarkerLocationCustomField = Key;
|
||||||
|
}
|
||||||
|
else if (Name == GetDefault<UUnrealzillaGlobalSettings>()->JiraDepartmentField)
|
||||||
|
{
|
||||||
|
this->DepartmentCustomField = Key;
|
||||||
|
}
|
||||||
|
else if (Name == GetDefault<UUnrealzillaGlobalSettings>()->JiraSeverityField)
|
||||||
|
{
|
||||||
|
this->SeverityCustomField = Key;
|
||||||
|
}
|
||||||
|
else if (Name == GetDefault<UUnrealzillaGlobalSettings>()->JiraPlatformField)
|
||||||
|
{
|
||||||
|
this->PlatformCustomField = Key;
|
||||||
|
}
|
||||||
|
else if (Name == GetDefault<UUnrealzillaGlobalSettings>()->JiraVersionField)
|
||||||
|
{
|
||||||
|
this->VersionCustomField = Key;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this->MapNameCustomField.IsEmpty() &&
|
||||||
|
!this->MarkerLocationCustomField.IsEmpty() &&
|
||||||
|
!this->DepartmentCustomField.IsEmpty() &&
|
||||||
|
!this->SeverityCustomField.IsEmpty() &&
|
||||||
|
!this->PlatformCustomField.IsEmpty() &&
|
||||||
|
!this->VersionCustomField.IsEmpty())
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->CreateError("Could not deserialise JSON.");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void UServerJiraAPI::ReturnListOfBugs()
|
void UServerJiraAPI::ReturnListOfBugs()
|
||||||
{
|
{
|
||||||
const FString FullURL = GetDefault<UUnrealzillaGlobalSettings>()->JiraSubmissionServer + "/rest";
|
|
||||||
|
|
||||||
TArray<FString> StatusQueries;
|
|
||||||
if (GetDefault<UUnrealzillaGlobalSettings>()->bShowUnresolvedBugs)
|
|
||||||
{
|
|
||||||
for (const FString Unresolved : GetDefault<UUnrealzillaGlobalSettings>()->UnresolvedStatuses)
|
|
||||||
{
|
|
||||||
StatusQueries.Add("status=" + Unresolved);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (GetDefault<UUnrealzillaGlobalSettings>()->bShowInProgressBugs)
|
|
||||||
{
|
|
||||||
for (const FString InProgress : GetDefault<UUnrealzillaGlobalSettings>()->InProgressStatuses)
|
|
||||||
{
|
|
||||||
StatusQueries.Add("status=" + InProgress);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (GetDefault<UUnrealzillaGlobalSettings>()->bShowResolvedBugs)
|
|
||||||
{
|
|
||||||
for (const FString Resolved : GetDefault<UUnrealzillaGlobalSettings>()->ResolvedStatuses)
|
|
||||||
{
|
|
||||||
StatusQueries.Add("status=" + Resolved);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
StatusQueries.Add("cf_mapname=" + this->GetWorld()->GetMapName().RightChop(this->GetWorld()->StreamingLevelsPrefix.Len()));
|
|
||||||
StatusQueries.Add("api_key=" + GetDefault<UUnrealzillaGlobalSettings>()->JiraAPIKey);
|
|
||||||
const FString QueryString = FString::Join(StatusQueries, TEXT("&"));
|
|
||||||
|
|
||||||
FHttpModule &HttpModule = FHttpModule::Get();
|
FHttpModule &HttpModule = FHttpModule::Get();
|
||||||
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> SeverityRequest = HttpModule.CreateRequest();
|
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> SeverityRequest = HttpModule.CreateRequest();
|
||||||
SeverityRequest->SetVerb(TEXT("GET"));
|
SeverityRequest->SetVerb(TEXT("GET"));
|
||||||
SeverityRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
|
SeverityRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
|
||||||
SeverityRequest->SetURL(FullURL + "/bug" + "?" + QueryString);
|
SeverityRequest->AppendToHeader(TEXT("Authorization"), TEXT("Basic ") + this->GenerateAuthString());
|
||||||
|
SeverityRequest->SetURL(this->FullURL + "agile/1.0/board/" + FString::FromInt(this->BoardID) + "/issue?expand=names&fields=summary,description,issuetype,status,priority" + (this->MapNameCustomField.IsEmpty()?"":(","+this->MapNameCustomField)) + (this->MarkerLocationCustomField.IsEmpty()?"":(","+this->MarkerLocationCustomField)));
|
||||||
SeverityRequest->OnProcessRequestComplete().BindUObject(this, &UServerJiraAPI::ListOfBugsResponse);
|
SeverityRequest->OnProcessRequestComplete().BindUObject(this, &UServerJiraAPI::ListOfBugsResponse);
|
||||||
SeverityRequest->ProcessRequest();
|
SeverityRequest->ProcessRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UServerJiraAPI::ListOfBugsResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success)
|
void UServerJiraAPI::ListOfBugsResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success)
|
||||||
{
|
{
|
||||||
if (Success)
|
if (Success)
|
||||||
{
|
{
|
||||||
FBugzillaJSONBugResponse ResponseData;
|
TArray<FUnrealzillaBugData> BugData;
|
||||||
FString JSONResponse = Response->GetContentAsString();
|
|
||||||
FJsonObjectConverter::JsonObjectStringToUStruct(JSONResponse, &ResponseData);
|
|
||||||
|
|
||||||
if (!ResponseData.error)
|
const FString JSONResponse = Response->GetContentAsString();
|
||||||
|
|
||||||
|
TSharedPtr<FJsonObject> JSON = MakeShareable(new FJsonObject);
|
||||||
|
const TSharedRef<TJsonReader<>> &Reader = TJsonReaderFactory<>::Create(JSONResponse);
|
||||||
|
if (FJsonSerializer::Deserialize(Reader, JSON))
|
||||||
{
|
{
|
||||||
TArray<FUnrealzillaBugData> BugData;
|
const TArray<TSharedPtr<FJsonValue>> &IssuesArray = JSON->GetArrayField("issues");
|
||||||
for (const FBugzillaJSONBugData &BugzillaData : ResponseData.bugs)
|
for (const TSharedPtr<FJsonValue> &IssueValue : IssuesArray)
|
||||||
{
|
{
|
||||||
FUnrealzillaBugData Bug;
|
const TSharedPtr<FJsonObject> &Issue = IssueValue->AsObject();
|
||||||
Bug.ID = BugzillaData.id;
|
const TSharedPtr<FJsonObject> &Fields = Issue->GetObjectField("fields");
|
||||||
Bug.Summary = BugzillaData.summary;
|
const TSharedPtr<FJsonObject> &Status = Fields->GetObjectField("status");
|
||||||
Bug.Component = BugzillaData.component;
|
const FString StatusName = Status->GetStringField("name");
|
||||||
Bug.MapName = BugzillaData.cf_mapname;
|
|
||||||
Bug.MapLocation = BugzillaData.cf_location;
|
if ((GetDefault<UUnrealzillaGlobalSettings>()->bShowUnresolvedBugs && GetDefault<UUnrealzillaGlobalSettings>()->UnresolvedStatuses.Contains(StatusName)) ||
|
||||||
Bug.Platform = BugzillaData.platform;
|
(GetDefault<UUnrealzillaGlobalSettings>()->bShowInProgressBugs && GetDefault<UUnrealzillaGlobalSettings>()->InProgressStatuses.Contains(StatusName)) ||
|
||||||
Bug.OperatingSystem = BugzillaData.op_sys;
|
(GetDefault<UUnrealzillaGlobalSettings>()->bShowResolvedBugs && GetDefault<UUnrealzillaGlobalSettings>()->ResolvedStatuses.Contains(StatusName)))
|
||||||
Bug.Severity = BugzillaData.severity;
|
{
|
||||||
Bug.Status = BugzillaData.status;
|
const TSharedPtr<FJsonObject> &Priority = Fields->GetObjectField("priority");
|
||||||
Bug.Resolution = BugzillaData.resolution;
|
|
||||||
Bug.DuplicateOf = BugzillaData.dupe_of;
|
FUnrealzillaBugData Bug;
|
||||||
Bug.bIsOpen = BugzillaData.is_open;
|
Bug.ID = Issue->GetNumberField("id");
|
||||||
BugData.Add(Bug);
|
Bug.Status = StatusName;
|
||||||
|
Bug.Summary = Fields->GetStringField("summary");
|
||||||
|
Bug.Severity = Priority->GetStringField("name");
|
||||||
|
//Bug.Component = BugzillaData.component;
|
||||||
|
//Bug.Platform = BugzillaData.platform;
|
||||||
|
//Bug.OperatingSystem = BugzillaData.op_sys;
|
||||||
|
//Bug.Resolution = BugzillaData.resolution;
|
||||||
|
//Bug.DuplicateOf = BugzillaData.dupe_of;
|
||||||
|
//Bug.bIsOpen = BugzillaData.is_open;
|
||||||
|
if (!this->MapNameCustomField.IsEmpty())
|
||||||
|
{
|
||||||
|
Bug.MapName = Fields->GetStringField(this->MapNameCustomField);
|
||||||
|
}
|
||||||
|
if (!this->MarkerLocationCustomField.IsEmpty())
|
||||||
|
{
|
||||||
|
Bug.MarkerLocation = Fields->GetStringField(this->MarkerLocationCustomField);
|
||||||
|
}
|
||||||
|
|
||||||
|
BugData.Add(Bug);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this->BugDataResponse.Execute(BugData);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this->CreateError(EErrorVerb::GET, ResponseData);
|
this->CreateError("Could not deserialise JSON.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this->BugDataResponse.Execute(BugData);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->ServerConnectionError(Request->GetStatus());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UServerJiraAPI::PrepareForm()
|
void UServerJiraAPI::PrepareForm()
|
||||||
{
|
{
|
||||||
const FString FullURL = GetDefault<UUnrealzillaGlobalSettings>()->JiraSubmissionServer + "/rest";
|
|
||||||
|
|
||||||
// Assemble query data into key:value pairs
|
// Assemble query data into key:value pairs
|
||||||
TMap<FString, FString> QueryData;
|
TMap<FString, FString> QueryData;
|
||||||
QueryData.Add("api_key", GetDefault<UUnrealzillaGlobalSettings>()->JiraAPIKey);
|
QueryData.Add("issuetypeNames", GetDefault<UUnrealzillaGlobalSettings>()->JiraBugIssueType);
|
||||||
|
QueryData.Add("expand", "projects.issuetypes.fields");
|
||||||
const FString QueryString = UServerAPI::FormatQueryString(QueryData);
|
const FString QueryString = UServerAPI::FormatQueryString(QueryData);
|
||||||
|
|
||||||
// Query the server for information about the current product
|
// Keep track of how many of these tasks have completed so we can check their completion status later.
|
||||||
FHttpModule &HttpModule = FHttpModule::Get();
|
this->FieldListsCompletion = 0;
|
||||||
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> ProductRequest = HttpModule.CreateRequest();
|
this->FieldListsCompletionMax = 2;
|
||||||
ProductRequest->SetVerb(TEXT("GET"));
|
|
||||||
ProductRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
|
|
||||||
ProductRequest->SetURL(FullURL + "/product/" + GetDefault<UUnrealzillaGlobalSettings>()->JiraProjectName + "?" + QueryString);
|
|
||||||
ProductRequest->OnProcessRequestComplete().BindUObject(this, &UServerJiraAPI::ServerProductInfoResponse);
|
|
||||||
ProductRequest->ProcessRequest();
|
|
||||||
|
|
||||||
// Send a second query to retrieve severity options
|
|
||||||
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> SeverityRequest = HttpModule.CreateRequest();
|
|
||||||
SeverityRequest->SetVerb(TEXT("GET"));
|
|
||||||
SeverityRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
|
|
||||||
SeverityRequest->SetURL(FullURL + "/field/bug/bug_severity" + "?" + QueryString);
|
|
||||||
SeverityRequest->OnProcessRequestComplete().BindUObject(this, &UServerJiraAPI::ServerSeverityInfoResponse);
|
|
||||||
SeverityRequest->ProcessRequest();
|
|
||||||
|
|
||||||
// Send a third query to retrieve platform options
|
|
||||||
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> PlatformsRequest = HttpModule.CreateRequest();
|
|
||||||
PlatformsRequest->SetVerb(TEXT("GET"));
|
|
||||||
PlatformsRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
|
|
||||||
PlatformsRequest->SetURL(FullURL + "/field/bug/rep_platform" + "?" + QueryString);
|
|
||||||
PlatformsRequest->OnProcessRequestComplete().BindUObject(this, &UServerJiraAPI::ServerPlatformInfoResponse);
|
|
||||||
PlatformsRequest->ProcessRequest();
|
|
||||||
|
|
||||||
// Send a final query to retrieve OS options
|
|
||||||
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> OSRequest = HttpModule.CreateRequest();
|
|
||||||
OSRequest->SetVerb(TEXT("GET"));
|
|
||||||
OSRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
|
|
||||||
OSRequest->SetURL(FullURL + "/field/bug/op_sys" + "?" + QueryString);
|
|
||||||
OSRequest->OnProcessRequestComplete().BindUObject(this, &UServerJiraAPI::ServerOSInfoResponse);
|
|
||||||
OSRequest->ProcessRequest();
|
|
||||||
}
|
|
||||||
|
|
||||||
void UServerJiraAPI::SendFormData(const FUnrealzillaPostData &PostData)
|
|
||||||
{
|
|
||||||
const FString FullURL = GetDefault<UUnrealzillaGlobalSettings>()->JiraSubmissionServer + "/rest";
|
|
||||||
const FString RequestURL = "/bug";
|
|
||||||
|
|
||||||
// Assemble query data into key:value pairs
|
|
||||||
TMap<FString, FString> QueryData;
|
|
||||||
QueryData.Add("api_key", GetDefault<UUnrealzillaGlobalSettings>()->JiraAPIKey);
|
|
||||||
|
|
||||||
const FString DefaultStatus = GetDefault<UUnrealzillaGlobalSettings>()->DefaultStatus;
|
|
||||||
|
|
||||||
FBugzillaJSONPostBug PostDataJSON;
|
|
||||||
PostDataJSON.product = GetDefault<UUnrealzillaGlobalSettings>()->JiraProjectName;
|
|
||||||
PostDataJSON.version = PostData.Version;
|
|
||||||
PostDataJSON.platform = PostData.Platform;
|
|
||||||
PostDataJSON.op_sys = PostData.OS;
|
|
||||||
PostDataJSON.component = PostData.Component;
|
|
||||||
PostDataJSON.severity = PostData.Severity;
|
|
||||||
PostDataJSON.cf_mapname = PostData.MapName;
|
|
||||||
PostDataJSON.cf_location = PostData.MapLocation;
|
|
||||||
PostDataJSON.summary = PostData.Summary;
|
|
||||||
PostDataJSON.description = PostData.Comment;
|
|
||||||
if (!DefaultStatus.IsEmpty())
|
|
||||||
{
|
|
||||||
PostDataJSON.status = DefaultStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PostDataJSON.version.IsEmpty())
|
|
||||||
{
|
|
||||||
this->CreateError("You must select a version number.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (PostDataJSON.platform.IsEmpty() || PostDataJSON.op_sys.IsEmpty())
|
|
||||||
{
|
|
||||||
PostDataJSON.platform = "All";
|
|
||||||
PostDataJSON.op_sys = "All";
|
|
||||||
}
|
|
||||||
if (PostDataJSON.component.IsEmpty())
|
|
||||||
{
|
|
||||||
this->CreateError("You must select a component.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (PostDataJSON.severity.IsEmpty())
|
|
||||||
{
|
|
||||||
this->CreateError("You must select a severity level.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (PostDataJSON.summary.IsEmpty())
|
|
||||||
{
|
|
||||||
this->CreateError("You must provide a summary.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
FString PostJsonString;
|
|
||||||
FJsonObjectConverter::UStructToJsonObjectString(PostDataJSON, PostJsonString);
|
|
||||||
|
|
||||||
FHttpModule &HttpModule = FHttpModule::Get();
|
FHttpModule &HttpModule = FHttpModule::Get();
|
||||||
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> Request = HttpModule.CreateRequest();
|
|
||||||
Request->SetVerb(TEXT("POST"));
|
// Send a query to retrieve field options
|
||||||
Request->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
|
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> FieldsRequest = HttpModule.CreateRequest();
|
||||||
Request->SetURL(FullURL + RequestURL + "?" + UServerAPI::FormatQueryString(QueryData));
|
FieldsRequest->SetVerb(TEXT("GET"));
|
||||||
Request->SetContentAsString(PostJsonString);
|
FieldsRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
|
||||||
Request->OnProcessRequestComplete().BindUObject(this, &UServerJiraAPI::ServerPOSTResponse);
|
FieldsRequest->AppendToHeader(TEXT("Authorization"), TEXT("Basic ") + this->GenerateAuthString());
|
||||||
Request->ProcessRequest();
|
FieldsRequest->SetURL(this->FullURL + "api/2/issue/createmeta?" + QueryString);
|
||||||
|
FieldsRequest->OnProcessRequestComplete().BindUObject(this, &UServerJiraAPI::ServerFieldOptionsResponse);
|
||||||
|
FieldsRequest->ProcessRequest();
|
||||||
|
|
||||||
|
// Send a second query to retrieve version numbers
|
||||||
|
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> VersionsRequest = HttpModule.CreateRequest();
|
||||||
|
VersionsRequest->SetVerb(TEXT("GET"));
|
||||||
|
VersionsRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
|
||||||
|
VersionsRequest->AppendToHeader(TEXT("Authorization"), TEXT("Basic ") + this->GenerateAuthString());
|
||||||
|
VersionsRequest->SetURL(this->FullURL + "api/2/project/" + FString::FromInt(this->ProjectID) + "/version");
|
||||||
|
VersionsRequest->OnProcessRequestComplete().BindUObject(this, &UServerJiraAPI::ServerVersionsResponse);
|
||||||
|
VersionsRequest->ProcessRequest();
|
||||||
}
|
}
|
||||||
|
void UServerJiraAPI::ServerFieldOptionsResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success)
|
||||||
|
|
||||||
void UServerJiraAPI::ServerPOSTResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success)
|
|
||||||
{
|
{
|
||||||
if (Success)
|
if (Success)
|
||||||
{
|
{
|
||||||
FBugzillaJSONPostResponse ResponseData;
|
const FString &JSONResponse = Response->GetContentAsString();
|
||||||
FString JSONResponse = Response->GetContentAsString();
|
|
||||||
FJsonObjectConverter::JsonObjectStringToUStruct(JSONResponse, &ResponseData);
|
|
||||||
|
|
||||||
if (ResponseData.error)
|
TSharedPtr<FJsonObject> JSON = MakeShareable(new FJsonObject);
|
||||||
|
const TSharedRef<TJsonReader<>> &Reader = TJsonReaderFactory<>::Create(JSONResponse);
|
||||||
|
if (FJsonSerializer::Deserialize(Reader, JSON))
|
||||||
{
|
{
|
||||||
this->CreateError(EErrorVerb::POST, ResponseData);
|
const TArray<TSharedPtr<FJsonValue>> &ProjectsArray = JSON->GetArrayField("projects");
|
||||||
}
|
for (const TSharedPtr<FJsonValue> &ProjectValue : ProjectsArray)
|
||||||
else
|
|
||||||
{
|
|
||||||
// Use the response's bug ID to get the info from the newly filed bug report and update its marker
|
|
||||||
|
|
||||||
const FString FullURL = GetDefault<UUnrealzillaGlobalSettings>()->JiraSubmissionServer + "/rest";
|
|
||||||
|
|
||||||
TArray<FString> StatusQueries;
|
|
||||||
StatusQueries.Add("id=" + FString::FromInt(ResponseData.id));
|
|
||||||
if (GetDefault<UUnrealzillaGlobalSettings>()->bShowUnresolvedBugs)
|
|
||||||
{
|
{
|
||||||
for (const FString Unresolved : GetDefault<UUnrealzillaGlobalSettings>()->UnresolvedStatuses)
|
const TSharedPtr<FJsonObject> &Project = ProjectValue->AsObject();
|
||||||
|
if (Project->GetStringField("name") == GetDefault<UUnrealzillaGlobalSettings>()->JiraProjectName)
|
||||||
{
|
{
|
||||||
StatusQueries.Add("status=" + Unresolved);
|
const TArray<TSharedPtr<FJsonValue>> &IssueTypes = Project->GetArrayField("issuetypes");
|
||||||
}
|
for (const TSharedPtr<FJsonValue> &IssueTypeValue : IssueTypes)
|
||||||
}
|
|
||||||
if (GetDefault<UUnrealzillaGlobalSettings>()->bShowInProgressBugs)
|
|
||||||
{
|
|
||||||
for (const FString InProgress : GetDefault<UUnrealzillaGlobalSettings>()->InProgressStatuses)
|
|
||||||
{
|
|
||||||
StatusQueries.Add("status=" + InProgress);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (GetDefault<UUnrealzillaGlobalSettings>()->bShowResolvedBugs)
|
|
||||||
{
|
|
||||||
for (const FString Resolved : GetDefault<UUnrealzillaGlobalSettings>()->ResolvedStatuses)
|
|
||||||
{
|
|
||||||
StatusQueries.Add("status=" + Resolved);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
StatusQueries.Add("cf_mapname=" + this->GetWorld()->GetMapName().RightChop(this->GetWorld()->StreamingLevelsPrefix.Len()));
|
|
||||||
StatusQueries.Add("api_key=" + GetDefault<UUnrealzillaGlobalSettings>()->JiraAPIKey);
|
|
||||||
const FString QueryString = FString::Join(StatusQueries, TEXT("&"));
|
|
||||||
|
|
||||||
FHttpModule &HttpModule = FHttpModule::Get();
|
|
||||||
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> SeverityRequest = HttpModule.CreateRequest();
|
|
||||||
SeverityRequest->SetVerb(TEXT("GET"));
|
|
||||||
SeverityRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
|
|
||||||
SeverityRequest->SetURL(FullURL + "/bug" + "?" + QueryString);
|
|
||||||
SeverityRequest->OnProcessRequestComplete().BindUObject(this, &UServerJiraAPI::ServerPOSTUpdateMarkerResponse);
|
|
||||||
SeverityRequest->ProcessRequest();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this->ServerConnectionError(Request->GetStatus());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UServerJiraAPI::ServerPOSTUpdateMarkerResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success)
|
|
||||||
{
|
|
||||||
if (Success)
|
|
||||||
{
|
|
||||||
FBugzillaJSONBugResponse ResponseData;
|
|
||||||
FString JSONResponse = Response->GetContentAsString();
|
|
||||||
FJsonObjectConverter::JsonObjectStringToUStruct(JSONResponse, &ResponseData);
|
|
||||||
|
|
||||||
if (ResponseData.error)
|
|
||||||
{
|
|
||||||
this->CreateError(EErrorVerb::GET, ResponseData);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!ResponseData.bugs.IsEmpty())
|
|
||||||
{
|
|
||||||
TArray<FUnrealzillaBugData> BugData;
|
|
||||||
FUnrealzillaBugData Bug;
|
|
||||||
Bug.ID = ResponseData.bugs[0].id;
|
|
||||||
Bug.Summary = ResponseData.bugs[0].summary;
|
|
||||||
Bug.Component = ResponseData.bugs[0].component;
|
|
||||||
Bug.MapName = ResponseData.bugs[0].cf_mapname;
|
|
||||||
Bug.MapLocation = ResponseData.bugs[0].cf_location;
|
|
||||||
Bug.Platform = ResponseData.bugs[0].platform;
|
|
||||||
Bug.OperatingSystem = ResponseData.bugs[0].op_sys;
|
|
||||||
Bug.Severity = ResponseData.bugs[0].severity;
|
|
||||||
Bug.Status = ResponseData.bugs[0].status;
|
|
||||||
Bug.Resolution = ResponseData.bugs[0].resolution;
|
|
||||||
Bug.DuplicateOf = ResponseData.bugs[0].dupe_of;
|
|
||||||
Bug.bIsOpen = ResponseData.bugs[0].is_open;
|
|
||||||
BugData.Add(Bug);
|
|
||||||
this->BugDataResponse.Execute(BugData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this->ServerConnectionError(Request->GetStatus());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UServerJiraAPI::ServerProductInfoResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success)
|
|
||||||
{
|
|
||||||
if (Success)
|
|
||||||
{
|
|
||||||
FBugzillaJSONProductResponse ResponseData;
|
|
||||||
FString JSONResponse = Response->GetContentAsString();
|
|
||||||
FJsonObjectConverter::JsonObjectStringToUStruct(JSONResponse, &ResponseData);
|
|
||||||
|
|
||||||
if (ResponseData.error)
|
|
||||||
{
|
|
||||||
//this->ShowProcessingOverlayMessage(ResponseData.message);
|
|
||||||
this->CreateError(EErrorVerb::GET, ResponseData);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!ResponseData.products.IsEmpty())
|
|
||||||
{
|
|
||||||
const FBugzillaJSONProductData &ProductData = ResponseData.products[0];
|
|
||||||
if (ProductData.name == GetDefault<UUnrealzillaGlobalSettings>()->JiraProjectName)
|
|
||||||
{
|
|
||||||
for (const FBugzillaJSONComponentData &ComponentData : ProductData.components)
|
|
||||||
{
|
{
|
||||||
this->ComponentsList.Add(ComponentData.name);
|
const TSharedPtr<FJsonObject> &IssueType = IssueTypeValue->AsObject();
|
||||||
|
const TSharedPtr<FJsonObject> &Fields = IssueType->GetObjectField("fields");
|
||||||
|
|
||||||
|
// After all that boilerplate code, finally get all available field options here
|
||||||
|
{
|
||||||
|
// Components
|
||||||
|
const TSharedPtr<FJsonObject> &Department = Fields->GetObjectField(this->DepartmentCustomField);
|
||||||
|
const TArray<TSharedPtr<FJsonValue>> &AllowedDepartmentsArray = Department->GetArrayField("allowedValues");
|
||||||
|
for (const TSharedPtr<FJsonValue> &AllowedDepartmentsValue : AllowedDepartmentsArray)
|
||||||
|
{
|
||||||
|
const TSharedPtr<FJsonObject> &Value = AllowedDepartmentsValue->AsObject();
|
||||||
|
this->ComponentsList.Add(Value->GetStringField("value"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bug severity
|
||||||
|
const TSharedPtr<FJsonObject> &Severity = Fields->GetObjectField(this->SeverityCustomField);
|
||||||
|
const TArray<TSharedPtr<FJsonValue>> &AllowedSeveritiesArray = Severity->GetArrayField("allowedValues");
|
||||||
|
for (const TSharedPtr<FJsonValue> &AllowedSeveritiesValue : AllowedSeveritiesArray)
|
||||||
|
{
|
||||||
|
const TSharedPtr<FJsonObject> &Value = AllowedSeveritiesValue->AsObject();
|
||||||
|
this->SeverityList.Add(Value->GetStringField("value"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Platform
|
||||||
|
const TSharedPtr<FJsonObject> &Platform = Fields->GetObjectField(this->PlatformCustomField);
|
||||||
|
const TArray<TSharedPtr<FJsonValue>> &PlatformsArray = Platform->GetArrayField("allowedValues");
|
||||||
|
for (const TSharedPtr<FJsonValue> &PlatformsValue : PlatformsArray)
|
||||||
|
{
|
||||||
|
const TSharedPtr<FJsonObject> &Value = PlatformsValue->AsObject();
|
||||||
|
this->PlatformsList.Add(Value->GetStringField("value"));
|
||||||
|
|
||||||
|
// Also get children and add them to the OS list here
|
||||||
|
const TArray<TSharedPtr<FJsonValue>> &ChildrenArray = Value->GetArrayField("children");
|
||||||
|
for (const TSharedPtr<FJsonValue> &ChildValue : ChildrenArray)
|
||||||
|
{
|
||||||
|
const TSharedPtr<FJsonObject> &Child = ChildValue->AsObject();
|
||||||
|
this->OSList.AddUnique(Child->GetStringField("value"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (const FBugzillaJSONVersionData &VersionData : ProductData.versions)
|
|
||||||
{
|
|
||||||
this->VersionsList.Add(VersionData.name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this->CheckIfAllFormResponsesAreIn();
|
break;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FStringFormatOrderedArguments Args;
|
|
||||||
Args.Add(FStringFormatArg(GetDefault<UUnrealzillaGlobalSettings>()->JiraProjectName));
|
|
||||||
//this->ShowProcessingOverlayMessage(FString::Format(TEXT("Could not find data for a product called {0}"), Args), true);
|
|
||||||
this->CreateError(FString::Format(TEXT("Could not find data for a product called {0}"), Args));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this->ServerConnectionError(Request->GetStatus());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UServerJiraAPI::ServerSeverityInfoResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success)
|
|
||||||
{
|
|
||||||
if (Success)
|
|
||||||
{
|
|
||||||
FBugzillaJSONFieldResponse ResponseData;
|
|
||||||
FString JSONResponse = Response->GetContentAsString();
|
|
||||||
FJsonObjectConverter::JsonObjectStringToUStruct(JSONResponse, &ResponseData);
|
|
||||||
|
|
||||||
if (ResponseData.error)
|
|
||||||
{
|
|
||||||
//this->ShowProcessingOverlayMessage(ResponseData.message);
|
|
||||||
this->CreateError(EErrorVerb::GET, ResponseData);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!ResponseData.fields.IsEmpty() && ResponseData.fields[0].name == "bug_severity")
|
|
||||||
{
|
|
||||||
for (const FBugzillaJSONFieldValueData &FieldValue : ResponseData.fields[0].values)
|
|
||||||
{
|
|
||||||
this->SeverityList.Add(FieldValue.name);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this->CheckIfAllFormResponsesAreIn();
|
this->CheckIfAllFormResponsesAreIn();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->CreateError("Could not deserialise JSON.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this->ServerConnectionError(Request->GetStatus());
|
this->ServerConnectionError(Request->GetStatus());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void UServerJiraAPI::ServerVersionsResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success)
|
||||||
void UServerJiraAPI::ServerPlatformInfoResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success)
|
|
||||||
{
|
{
|
||||||
if (Success)
|
if (Success)
|
||||||
{
|
{
|
||||||
FBugzillaJSONFieldResponse ResponseData;
|
const FString &JSONResponse = Response->GetContentAsString();
|
||||||
FString JSONResponse = Response->GetContentAsString();
|
|
||||||
FJsonObjectConverter::JsonObjectStringToUStruct(JSONResponse, &ResponseData);
|
|
||||||
|
|
||||||
if (ResponseData.error)
|
TSharedPtr<FJsonObject> JSON = MakeShareable(new FJsonObject);
|
||||||
|
const TSharedRef<TJsonReader<>> &Reader = TJsonReaderFactory<>::Create(JSONResponse);
|
||||||
|
if (FJsonSerializer::Deserialize(Reader, JSON))
|
||||||
{
|
{
|
||||||
//this->ShowProcessingOverlayMessage(ResponseData.message);
|
const TArray<TSharedPtr<FJsonValue>> &ValuesArray = JSON->GetArrayField("values");
|
||||||
this->CreateError(EErrorVerb::GET, ResponseData);
|
for (const TSharedPtr<FJsonValue> &ValueObject : ValuesArray)
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!ResponseData.fields.IsEmpty() && ResponseData.fields[0].name == "rep_platform")
|
|
||||||
{
|
{
|
||||||
for (const FBugzillaJSONFieldValueData &FieldValue : ResponseData.fields[0].values)
|
const TSharedPtr<FJsonObject> &Value = ValueObject->AsObject();
|
||||||
{
|
this->VersionsList.Add(Value->GetStringField("name"));
|
||||||
this->PlatformsList.Add(FieldValue.name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this->CheckIfAllFormResponsesAreIn();
|
this->CheckIfAllFormResponsesAreIn();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this->ServerConnectionError(Request->GetStatus());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UServerJiraAPI::ServerOSInfoResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success)
|
|
||||||
{
|
|
||||||
if (Success)
|
|
||||||
{
|
|
||||||
FBugzillaJSONFieldResponse ResponseData;
|
|
||||||
FString JSONResponse = Response->GetContentAsString();
|
|
||||||
FJsonObjectConverter::JsonObjectStringToUStruct(JSONResponse, &ResponseData);
|
|
||||||
|
|
||||||
if (ResponseData.error)
|
|
||||||
{
|
|
||||||
//this->ShowProcessingOverlayMessage(ResponseData.message);
|
|
||||||
this->CreateError(EErrorVerb::GET, ResponseData);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!ResponseData.fields.IsEmpty() && ResponseData.fields[0].name == "op_sys")
|
this->CreateError("Could not deserialise JSON.");
|
||||||
{
|
|
||||||
for (const FBugzillaJSONFieldValueData &FieldValue : ResponseData.fields[0].values)
|
|
||||||
{
|
|
||||||
this->OSList.Add(FieldValue.name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this->CheckIfAllFormResponsesAreIn();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -448,12 +343,14 @@ void UServerJiraAPI::ServerOSInfoResponse(FHttpRequestPtr Request, FHttpResponse
|
|||||||
this->ServerConnectionError(Request->GetStatus());
|
this->ServerConnectionError(Request->GetStatus());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UServerJiraAPI::CheckIfAllFormResponsesAreIn()
|
void UServerJiraAPI::CheckIfAllFormResponsesAreIn()
|
||||||
{
|
{
|
||||||
if (!this->ComponentsList.IsEmpty() && !this->VersionsList.IsEmpty() && !this->SeverityList.IsEmpty() &&
|
this->FieldListsCompletion++;
|
||||||
!this->PlatformsList.IsEmpty() && !this->OSList.IsEmpty())
|
|
||||||
|
if (this->FieldListsCompletion == this->FieldListsCompletionMax)
|
||||||
{
|
{
|
||||||
|
this->FieldListsCompletion = this->FieldListsCompletionMax = 0;
|
||||||
|
|
||||||
FUnrealzillaFormPrepData Data;
|
FUnrealzillaFormPrepData Data;
|
||||||
|
|
||||||
Data.ComponentsList = this->ComponentsList;
|
Data.ComponentsList = this->ComponentsList;
|
||||||
@ -468,10 +365,6 @@ void UServerJiraAPI::CheckIfAllFormResponsesAreIn()
|
|||||||
{
|
{
|
||||||
Data.DetectedVersion = GameVersion;
|
Data.DetectedVersion = GameVersion;
|
||||||
}
|
}
|
||||||
else if (this->VersionsList.Contains("unspecified"))
|
|
||||||
{
|
|
||||||
Data.DetectedVersion = "unspecified";
|
|
||||||
}
|
|
||||||
else if (this->VersionsList.Contains("Latest"))
|
else if (this->VersionsList.Contains("Latest"))
|
||||||
{
|
{
|
||||||
Data.DetectedVersion = "Latest";
|
Data.DetectedVersion = "Latest";
|
||||||
@ -526,3 +419,196 @@ void UServerJiraAPI::CheckIfAllFormResponsesAreIn()
|
|||||||
this->OSList.Empty();
|
this->OSList.Empty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UServerJiraAPI::SendFormData(const FUnrealzillaPostData &PostData)
|
||||||
|
{
|
||||||
|
if (PostData.Summary.IsEmpty())
|
||||||
|
{
|
||||||
|
this->CreateError("You must provide a summary.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TSharedPtr<FJsonObject> JSONPostFields = MakeShareable(new FJsonObject());
|
||||||
|
JSONPostFields->SetStringField("summary", PostData.Summary);
|
||||||
|
JSONPostFields->SetStringField("description", PostData.Comment);
|
||||||
|
JSONPostFields->SetStringField(this->MapNameCustomField, PostData.MapName);
|
||||||
|
JSONPostFields->SetStringField(this->MarkerLocationCustomField, PostData.MarkerLocation);
|
||||||
|
|
||||||
|
TSharedPtr<FJsonObject> Project = MakeShareable(new FJsonObject());
|
||||||
|
Project->SetStringField("key", this->ProjectKey);
|
||||||
|
JSONPostFields->SetObjectField("project", Project);
|
||||||
|
|
||||||
|
TSharedPtr<FJsonObject> IssueType = MakeShareable(new FJsonObject());
|
||||||
|
IssueType->SetStringField("name", GetDefault<UUnrealzillaGlobalSettings>()->JiraBugIssueType);
|
||||||
|
JSONPostFields->SetObjectField("issuetype", IssueType);
|
||||||
|
|
||||||
|
//const FString DefaultStatus = GetDefault<UUnrealzillaGlobalSettings>()->JiraDefaultStatus;
|
||||||
|
//if (!DefaultStatus.IsEmpty())
|
||||||
|
//{
|
||||||
|
// TSharedPtr<FJsonObject> Status = MakeShareable(new FJsonObject());
|
||||||
|
// Status->SetStringField("name", DefaultStatus);
|
||||||
|
// JSONPostFields->SetObjectField("status", Status);
|
||||||
|
//}
|
||||||
|
|
||||||
|
if (!GetDefault<UUnrealzillaGlobalSettings>()->JiraVersionField.IsEmpty() && !PostData.Version.IsEmpty())
|
||||||
|
{
|
||||||
|
TSharedPtr<FJsonObject> Version = MakeShareable(new FJsonObject());
|
||||||
|
Version->SetStringField("name", PostData.Version);
|
||||||
|
JSONPostFields->SetObjectField(this->VersionCustomField, Version);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetDefault<UUnrealzillaGlobalSettings>()->JiraPlatformField.IsEmpty() && !PostData.Platform.IsEmpty())
|
||||||
|
{
|
||||||
|
TSharedPtr<FJsonObject> PlatformCascade = MakeShareable(new FJsonObject());
|
||||||
|
TSharedPtr<FJsonObject> OSCascade = MakeShareable(new FJsonObject());
|
||||||
|
PlatformCascade->SetStringField("value", PostData.Platform);
|
||||||
|
if (!PostData.OS.IsEmpty())
|
||||||
|
{
|
||||||
|
OSCascade->SetStringField("value", PostData.OS);
|
||||||
|
PlatformCascade->SetObjectField("child", OSCascade);
|
||||||
|
}
|
||||||
|
JSONPostFields->SetObjectField(this->PlatformCustomField, PlatformCascade);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetDefault<UUnrealzillaGlobalSettings>()->JiraDepartmentField.IsEmpty() && !PostData.Component.IsEmpty())
|
||||||
|
{
|
||||||
|
TSharedPtr<FJsonObject> Category = MakeShareable(new FJsonObject());
|
||||||
|
Category->SetStringField("value", PostData.Component);
|
||||||
|
JSONPostFields->SetObjectField(this->DepartmentCustomField, Category);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetDefault<UUnrealzillaGlobalSettings>()->JiraSeverityField.IsEmpty() && !PostData.Severity.IsEmpty())
|
||||||
|
{
|
||||||
|
TSharedPtr<FJsonObject> Severity = MakeShareable(new FJsonObject());
|
||||||
|
Severity->SetStringField("value", PostData.Severity);
|
||||||
|
JSONPostFields->SetObjectField(this->SeverityCustomField, Severity);
|
||||||
|
}
|
||||||
|
|
||||||
|
TSharedPtr<FJsonObject> JSONPostObject = MakeShareable(new FJsonObject());
|
||||||
|
JSONPostObject->SetObjectField("fields", JSONPostFields);
|
||||||
|
FString PostJsonString;
|
||||||
|
TSharedRef<TJsonWriter<>> Writer = TJsonWriterFactory<>::Create(&PostJsonString);
|
||||||
|
FJsonSerializer::Serialize(JSONPostObject.ToSharedRef(), Writer);
|
||||||
|
|
||||||
|
FHttpModule &HttpModule = FHttpModule::Get();
|
||||||
|
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> PostRequest = HttpModule.CreateRequest();
|
||||||
|
PostRequest->SetVerb(TEXT("POST"));
|
||||||
|
PostRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
|
||||||
|
PostRequest->AppendToHeader(TEXT("Authorization"), TEXT("Basic ") + this->GenerateAuthString());
|
||||||
|
PostRequest->SetURL(this->FullURL + "api/2/issue");
|
||||||
|
PostRequest->SetContentAsString(PostJsonString);
|
||||||
|
PostRequest->OnProcessRequestComplete().BindUObject(this, &UServerJiraAPI::ServerPOSTResponse);
|
||||||
|
PostRequest->ProcessRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void UServerJiraAPI::ServerPOSTResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success)
|
||||||
|
{
|
||||||
|
if (Success)
|
||||||
|
{
|
||||||
|
const FString &JSONResponse = Response->GetContentAsString();
|
||||||
|
|
||||||
|
TSharedPtr<FJsonObject> JSON = MakeShareable(new FJsonObject);
|
||||||
|
const TSharedRef<TJsonReader<>> &Reader = TJsonReaderFactory<>::Create(JSONResponse);
|
||||||
|
if (FJsonSerializer::Deserialize(Reader, JSON))
|
||||||
|
{
|
||||||
|
// I'm not sure what is meant to show up in the "errorMessages" array, but this is where we handle that.
|
||||||
|
const TArray<TSharedPtr<FJsonValue>> &ErrorMessageArray = JSON->GetArrayField("errorMessages");
|
||||||
|
if (!ErrorMessageArray.IsEmpty())
|
||||||
|
{
|
||||||
|
// Handle error messages here
|
||||||
|
}
|
||||||
|
|
||||||
|
const TSharedPtr<FJsonObject> &Errors = JSON->GetObjectField("errors");
|
||||||
|
TArray<FString> ErrorStringBuilder;
|
||||||
|
TArray<FString> ErrorKeys;
|
||||||
|
Errors->Values.GenerateKeyArray(ErrorKeys);
|
||||||
|
for (const FString &ErrorKey : ErrorKeys)
|
||||||
|
{
|
||||||
|
FStringFormatOrderedArguments Args;
|
||||||
|
Args.Add(FStringFormatArg(ErrorKey));
|
||||||
|
Args.Add(FStringFormatArg(Errors->GetStringField(ErrorKey)));
|
||||||
|
ErrorStringBuilder.Add(FString::Format(TEXT("{0}: {1}"), Args));
|
||||||
|
}
|
||||||
|
const FString &ErrorString = FString::Join(ErrorStringBuilder, TEXT("\n"));
|
||||||
|
if (!ErrorString.IsEmpty())
|
||||||
|
{
|
||||||
|
this->CreateError(ErrorString);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//const int32 &NewBugID = FCString::Atoi(*JSON->GetStringField("id"));
|
||||||
|
//const FString &NewBugKey = JSON->GetStringField("key");
|
||||||
|
const FString &NewBugURI = JSON->GetStringField("self");
|
||||||
|
|
||||||
|
FHttpModule &HttpModule = FHttpModule::Get();
|
||||||
|
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> NewBugRequest = HttpModule.CreateRequest();
|
||||||
|
NewBugRequest->SetVerb(TEXT("GET"));
|
||||||
|
NewBugRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
|
||||||
|
NewBugRequest->AppendToHeader(TEXT("Authorization"), TEXT("Basic ") + this->GenerateAuthString());
|
||||||
|
NewBugRequest->SetURL(NewBugURI);
|
||||||
|
NewBugRequest->OnProcessRequestComplete().BindUObject(this, &UServerJiraAPI::ServerPOSTUpdateMarkerResponse);
|
||||||
|
NewBugRequest->ProcessRequest();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->CreateError("Could not deserialise JSON.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->ServerConnectionError(Request->GetStatus());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UServerJiraAPI::ServerPOSTUpdateMarkerResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success)
|
||||||
|
{
|
||||||
|
if (Success)
|
||||||
|
{
|
||||||
|
const FString &JSONResponse = Response->GetContentAsString();
|
||||||
|
|
||||||
|
TSharedPtr<FJsonObject> JSON = MakeShareable(new FJsonObject);
|
||||||
|
const TSharedRef<TJsonReader<>> &Reader = TJsonReaderFactory<>::Create(JSONResponse);
|
||||||
|
if (FJsonSerializer::Deserialize(Reader, JSON))
|
||||||
|
{
|
||||||
|
if (JSON->HasTypedField<EJson::Object>("fields"))
|
||||||
|
{
|
||||||
|
const TSharedPtr<FJsonObject> &Fields = JSON->GetObjectField("fields");
|
||||||
|
const TSharedPtr<FJsonObject> &PlatformFields = Fields->GetObjectField(this->PlatformCustomField);
|
||||||
|
|
||||||
|
TArray<FUnrealzillaBugData> BugData;
|
||||||
|
FUnrealzillaBugData Bug;
|
||||||
|
Bug.ID = JSON->GetIntegerField("id");
|
||||||
|
Bug.Summary = Fields->GetStringField("summary");
|
||||||
|
Bug.Component = Fields->GetObjectField(this->DepartmentCustomField)->GetStringField("value");
|
||||||
|
Bug.MapName = Fields->GetStringField(this->MapNameCustomField);
|
||||||
|
Bug.MarkerLocation = Fields->GetStringField(this->MarkerLocationCustomField);
|
||||||
|
Bug.Platform = PlatformFields->GetStringField("value");
|
||||||
|
Bug.OperatingSystem = PlatformFields->GetObjectField("child")->GetStringField("value");
|
||||||
|
Bug.Severity = Fields->GetObjectField(this->SeverityCustomField)->GetStringField("value");
|
||||||
|
Bug.Status = Fields->GetObjectField("status")->GetStringField("name");
|
||||||
|
Bug.Resolution = Fields->GetStringField("resolution");
|
||||||
|
BugData.Add(Bug);
|
||||||
|
this->BugDataResponse.Execute(BugData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->CreateError("Could not deserialise JSON.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->ServerConnectionError(Request->GetStatus());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const FString UServerJiraAPI::GenerateAuthString() const
|
||||||
|
{
|
||||||
|
return FBase64::Encode(
|
||||||
|
GetDefault<UUnrealzillaGlobalSettings>()->JiraUsername +
|
||||||
|
":" +
|
||||||
|
GetDefault<UUnrealzillaGlobalSettings>()->JiraAPIKey
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@ -29,6 +29,8 @@ public:
|
|||||||
FString ErrorMessage;
|
FString ErrorMessage;
|
||||||
UPROPERTY(BlueprintReadOnly)
|
UPROPERTY(BlueprintReadOnly)
|
||||||
FString DocumentationLink;
|
FString DocumentationLink;
|
||||||
|
UPROPERTY(BlueprintReadOnly)
|
||||||
|
bool bCancelForm = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
USTRUCT(Blueprintable)
|
USTRUCT(Blueprintable)
|
||||||
@ -45,7 +47,7 @@ public:
|
|||||||
UPROPERTY(BlueprintReadOnly)
|
UPROPERTY(BlueprintReadOnly)
|
||||||
FString MapName;
|
FString MapName;
|
||||||
UPROPERTY(BlueprintReadOnly)
|
UPROPERTY(BlueprintReadOnly)
|
||||||
FString MapLocation;
|
FString MarkerLocation;
|
||||||
UPROPERTY(BlueprintReadOnly)
|
UPROPERTY(BlueprintReadOnly)
|
||||||
FString Platform;
|
FString Platform;
|
||||||
UPROPERTY(BlueprintReadOnly)
|
UPROPERTY(BlueprintReadOnly)
|
||||||
@ -105,7 +107,7 @@ public:
|
|||||||
UPROPERTY(BlueprintReadOnly)
|
UPROPERTY(BlueprintReadOnly)
|
||||||
FString MapName;
|
FString MapName;
|
||||||
UPROPERTY(BlueprintReadOnly)
|
UPROPERTY(BlueprintReadOnly)
|
||||||
FString MapLocation;
|
FString MarkerLocation;
|
||||||
UPROPERTY(BlueprintReadOnly)
|
UPROPERTY(BlueprintReadOnly)
|
||||||
FString Summary;
|
FString Summary;
|
||||||
UPROPERTY(BlueprintReadOnly)
|
UPROPERTY(BlueprintReadOnly)
|
||||||
|
|||||||
@ -29,6 +29,8 @@ public:
|
|||||||
UFUNCTION(BlueprintPure)
|
UFUNCTION(BlueprintPure)
|
||||||
bool AreMarkersVisible() const { return !this->BugMarkers.IsEmpty(); }
|
bool AreMarkersVisible() const { return !this->BugMarkers.IsEmpty(); }
|
||||||
|
|
||||||
|
void AddBugMarker(ABugMarkerActor *Marker) { this->BugMarkers.Add(Marker); }
|
||||||
|
|
||||||
void PrepareSubmissionFormData();
|
void PrepareSubmissionFormData();
|
||||||
|
|
||||||
void SubmitForm(const struct FUnrealzillaPostData &PostData);
|
void SubmitForm(const struct FUnrealzillaPostData &PostData);
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "BugzillaJSONStructs.h"
|
|
||||||
#include "GameFramework/Pawn.h"
|
#include "GameFramework/Pawn.h"
|
||||||
|
|
||||||
#include "BugPlacerPawn.generated.h"
|
#include "BugPlacerPawn.generated.h"
|
||||||
|
|||||||
@ -81,7 +81,7 @@ private:
|
|||||||
UFUNCTION(BlueprintCallable)
|
UFUNCTION(BlueprintCallable)
|
||||||
void ShowProcessingOverlayLoading();
|
void ShowProcessingOverlayLoading();
|
||||||
UFUNCTION(BlueprintCallable)
|
UFUNCTION(BlueprintCallable)
|
||||||
void ShowProcessingOverlayMessage(const FString Message, const bool bExitAfterConfirm = false);
|
void ShowProcessingOverlayMessage(const struct FUnrealzillaErrorData &Error);
|
||||||
UFUNCTION(BlueprintCallable)
|
UFUNCTION(BlueprintCallable)
|
||||||
void HideProcessingOverlay();
|
void HideProcessingOverlay();
|
||||||
|
|
||||||
|
|||||||
@ -21,6 +21,8 @@ class UNREALZILLA_API UServerAPI : public UObject
|
|||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
virtual void Initialize() {}
|
||||||
|
|
||||||
virtual void ReturnListOfBugs();
|
virtual void ReturnListOfBugs();
|
||||||
virtual void PrepareForm();
|
virtual void PrepareForm();
|
||||||
virtual void SendFormData(const FUnrealzillaPostData &PostData);
|
virtual void SendFormData(const FUnrealzillaPostData &PostData);
|
||||||
@ -46,7 +48,7 @@ protected:
|
|||||||
void CreateError(const EErrorVerb &Verb, const FBugzillaJSONProductResponse &Data);
|
void CreateError(const EErrorVerb &Verb, const FBugzillaJSONProductResponse &Data);
|
||||||
void CreateError(const EErrorVerb &Verb, const FBugzillaJSONFieldResponse &Data);
|
void CreateError(const EErrorVerb &Verb, const FBugzillaJSONFieldResponse &Data);
|
||||||
void CreateError(const EErrorVerb &Verb, const FBugzillaJSONBugResponse &Data);
|
void CreateError(const EErrorVerb &Verb, const FBugzillaJSONBugResponse &Data);
|
||||||
void CreateError(const FString &ErrorMessage);
|
void CreateError(const FString &ErrorMessage, const bool bCancelForm = false);
|
||||||
|
|
||||||
static const FString URLBuilder(const FString &Server, const FString &Path);
|
static const FString URLBuilder(const FString &Server, const FString &Path);
|
||||||
static const FString FormatQueryString(const TMap<FString, FString> &QueryData);
|
static const FString FormatQueryString(const TMap<FString, FString> &QueryData);
|
||||||
|
|||||||
@ -16,7 +16,7 @@ class UNREALZILLA_API UServerBugzillaAPI : public UServerAPI
|
|||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UServerBugzillaAPI();
|
virtual void Initialize() override;
|
||||||
|
|
||||||
virtual void ReturnListOfBugs() override;
|
virtual void ReturnListOfBugs() override;
|
||||||
virtual void PrepareForm() override;
|
virtual void PrepareForm() override;
|
||||||
|
|||||||
@ -16,20 +16,39 @@ class UNREALZILLA_API UServerJiraAPI : public UServerAPI
|
|||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UServerJiraAPI();
|
virtual void Initialize() override;
|
||||||
|
|
||||||
virtual void ReturnListOfBugs() override;
|
virtual void ReturnListOfBugs() override;
|
||||||
virtual void PrepareForm() override;
|
virtual void PrepareForm() override;
|
||||||
virtual void SendFormData(const FUnrealzillaPostData &PostData) override;
|
virtual void SendFormData(const FUnrealzillaPostData &PostData) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void ListOfBoardsResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success);
|
||||||
|
void ListOfFieldsResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success);
|
||||||
|
|
||||||
void ListOfBugsResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success);
|
void ListOfBugsResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success);
|
||||||
|
|
||||||
void ServerPOSTResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success);
|
void ServerPOSTResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success);
|
||||||
|
|
||||||
void ServerPOSTUpdateMarkerResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success);
|
void ServerPOSTUpdateMarkerResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success);
|
||||||
void ServerProductInfoResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success);
|
void ServerFieldOptionsResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success);
|
||||||
void ServerSeverityInfoResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success);
|
void ServerVersionsResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success);
|
||||||
void ServerPlatformInfoResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success);
|
|
||||||
void ServerOSInfoResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success);
|
|
||||||
void CheckIfAllFormResponsesAreIn();
|
void CheckIfAllFormResponsesAreIn();
|
||||||
|
|
||||||
|
const FString GenerateAuthString() const;
|
||||||
|
|
||||||
|
int32 BoardID = -1;
|
||||||
|
int32 ProjectID = -1;
|
||||||
|
FString ProjectKey;
|
||||||
|
FString ProjectAvatarURI;
|
||||||
|
|
||||||
|
FString MapNameCustomField;
|
||||||
|
FString MarkerLocationCustomField;
|
||||||
|
FString DepartmentCustomField;
|
||||||
|
FString SeverityCustomField;
|
||||||
|
FString PlatformCustomField;
|
||||||
|
FString VersionCustomField;
|
||||||
|
|
||||||
|
uint8 FieldListsCompletion = 0;
|
||||||
|
uint8 FieldListsCompletionMax = 0;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -36,12 +36,12 @@ public:
|
|||||||
UPROPERTY(Config, BlueprintReadOnly, EditDefaultsOnly, Category="Bug Placement", meta=(DisplayName="Arbitrary Placement Distance"))
|
UPROPERTY(Config, BlueprintReadOnly, EditDefaultsOnly, Category="Bug Placement", meta=(DisplayName="Arbitrary Placement Distance"))
|
||||||
float ArbitraryBugPlacementDistance = 250.0f;
|
float ArbitraryBugPlacementDistance = 250.0f;
|
||||||
|
|
||||||
// The status to use when filing a new bug. A status such as "UNCONFIRMED" is suggested.
|
|
||||||
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Reporting")
|
|
||||||
FString DefaultStatus;
|
|
||||||
// The viewport depth of the bug report interface widget.
|
// The viewport depth of the bug report interface widget.
|
||||||
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Reporting")
|
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Reporting")
|
||||||
int32 BugReportWidgetDepth = 10000;
|
int32 BugReportWidgetDepth = 10000;
|
||||||
|
// The status to use when filing a new bug. Usually the default is sufficient.
|
||||||
|
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Reporting|Bugzilla", meta=(DisplayName="Default Status"))
|
||||||
|
FString BugzillaDefaultStatus = "UNCONFIRMED";
|
||||||
// The Bugzilla server where bugs will be posted.
|
// The Bugzilla server where bugs will be posted.
|
||||||
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Reporting|Bugzilla", meta=(DisplayName="Server"))
|
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Reporting|Bugzilla", meta=(DisplayName="Server"))
|
||||||
FString BugzillaSubmissionServer;
|
FString BugzillaSubmissionServer;
|
||||||
@ -64,13 +64,43 @@ public:
|
|||||||
// The name of the project for which bugs will be posted.
|
// The name of the project for which bugs will be posted.
|
||||||
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Reporting|Jira", meta=(DisplayName="Project Name"))
|
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Reporting|Jira", meta=(DisplayName="Project Name"))
|
||||||
FString JiraProjectName;
|
FString JiraProjectName;
|
||||||
// The username to use when posting bugs.
|
// The username to use when posting bugs. Should be the user's full email address.
|
||||||
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Reporting|Jira", meta=(DisplayName="Username"))
|
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Reporting|Jira", meta=(DisplayName="Email"))
|
||||||
FString JiraUsername;
|
FString JiraUsername;
|
||||||
// The API key to use when posting bugs. Using the account password should work here, but it is
|
// The API key to use when posting bugs. Using the account password might work here, but it is
|
||||||
// highly recommended that you generate a proper API key in the Atlassian account of the above user.
|
// highly recommended that you generate a proper API key in the Atlassian account of the above user.
|
||||||
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Reporting|Jira", meta=(DisplayName="API Key"))
|
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Reporting|Jira", meta=(DisplayName="API Key"))
|
||||||
FString JiraAPIKey;
|
FString JiraAPIKey;
|
||||||
|
// Name of the Jira issue type used for bugs. Should simply be "Bug", but if you use something different
|
||||||
|
// it can be changed here.
|
||||||
|
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Reporting|Jira", meta=(DisplayName="Bug Issue Type"))
|
||||||
|
FString JiraBugIssueType = "Bug";
|
||||||
|
// Name of the Jira custom field where the map name should be stored. This field is required, and must be
|
||||||
|
// configured in Jira. The custom field must be a Text Field.
|
||||||
|
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Reporting|Jira", meta=(DisplayName="Map Name Field"))
|
||||||
|
FString JiraMapNameField;
|
||||||
|
// Name of the Jira custom field where the bug location should be stored. This field is required, and must
|
||||||
|
// be configured in Jira. The custom field must be a Text Field.
|
||||||
|
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Reporting|Jira", meta=(DisplayName="Marker Location Field"))
|
||||||
|
FString JiraMarkerLocationField;
|
||||||
|
// Name of the Jira custom field where the department name should be stored. This serves a similar function to
|
||||||
|
// "Component" in Bugzilla; it's meant to indicate what department in a company should be responsible for fixing
|
||||||
|
// the bug. The custom field must be a single-choice select list.
|
||||||
|
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Reporting|Jira|Optional Fields", meta=(DisplayName="Department Field"))
|
||||||
|
FString JiraDepartmentField;
|
||||||
|
// Name of the Jira custom field where the severity should be stored. The custom field must be a single-choice select list.
|
||||||
|
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Reporting|Jira|Optional Fields", meta=(DisplayName="Severity Field"))
|
||||||
|
FString JiraSeverityField;
|
||||||
|
// Name of the Jira custom field where the hardware and OS used to find the bug should be stored. The custom field
|
||||||
|
// must be a cascading select list, with the first dropdown being hardware, and the second being the operating system.
|
||||||
|
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Reporting|Jira|Optional Fields", meta=(DisplayName="Platform Field"))
|
||||||
|
FString JiraPlatformField;
|
||||||
|
// Name of the Jira custom field where the game's version number should be stored. The custom field must be a Version
|
||||||
|
// select list, and "Releases" must be enabled in your project features and configured with the version numbers you
|
||||||
|
// wish to track bugs for. Unrealzilla will automatically fill this in with the version number from the project settings,
|
||||||
|
// and will simply not fill this field in if it can't find a matching version number configured for the project.
|
||||||
|
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Reporting|Jira|Optional Fields", meta=(DisplayName="Version Field"))
|
||||||
|
FString JiraVersionField;
|
||||||
|
|
||||||
// Whether to show unresolved bugs when displaying bug report markers.
|
// Whether to show unresolved bugs when displaying bug report markers.
|
||||||
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Markers|Unresolved")
|
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Markers|Unresolved")
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user