From f6c92e59b015c39fb4307724fbca427800c91540 Mon Sep 17 00:00:00 2001 From: vitalii-bezuhlyi Date: Thu, 10 Oct 2024 12:30:07 +0300 Subject: [PATCH 1/2] Preparation for checkpoints --- Apps.Crowdin/Apps.Crowdin.csproj | 2 +- .../Request/File/GetFileOptionalRequest.cs | 9 + .../Project/GetProjectOptionalRequest.cs | 12 + .../Models/Request/Project/ProjectRequest.cs | 2 +- .../GetSourceStringOptionalRequest.cs | 9 + .../GetSuggestionOptionalRequest.cs | 9 + .../Request/Task/GetTaskOptionalRequest.cs | 9 + .../Webhooks/Lists/ProjectWebhookList.cs | 292 ++++++++++++++++-- 8 files changed, 312 insertions(+), 32 deletions(-) create mode 100644 Apps.Crowdin/Models/Request/File/GetFileOptionalRequest.cs create mode 100644 Apps.Crowdin/Models/Request/Project/GetProjectOptionalRequest.cs create mode 100644 Apps.Crowdin/Models/Request/SourceString/GetSourceStringOptionalRequest.cs create mode 100644 Apps.Crowdin/Models/Request/Suggestions/GetSuggestionOptionalRequest.cs create mode 100644 Apps.Crowdin/Models/Request/Task/GetTaskOptionalRequest.cs diff --git a/Apps.Crowdin/Apps.Crowdin.csproj b/Apps.Crowdin/Apps.Crowdin.csproj index 2b0e6c7..e400715 100644 --- a/Apps.Crowdin/Apps.Crowdin.csproj +++ b/Apps.Crowdin/Apps.Crowdin.csproj @@ -5,7 +5,7 @@ enable Crowdin Cloud-based solution that streamlines localization management - 1.0.13 + 1.0.14 Apps.Crowdin diff --git a/Apps.Crowdin/Models/Request/File/GetFileOptionalRequest.cs b/Apps.Crowdin/Models/Request/File/GetFileOptionalRequest.cs new file mode 100644 index 0000000..0c76a40 --- /dev/null +++ b/Apps.Crowdin/Models/Request/File/GetFileOptionalRequest.cs @@ -0,0 +1,9 @@ +using Blackbird.Applications.Sdk.Common; + +namespace Apps.Crowdin.Models.Request.File; + +public class GetFileOptionalRequest +{ + [Display("File ID")] + public string? FileId { get; set; } +} \ No newline at end of file diff --git a/Apps.Crowdin/Models/Request/Project/GetProjectOptionalRequest.cs b/Apps.Crowdin/Models/Request/Project/GetProjectOptionalRequest.cs new file mode 100644 index 0000000..442624a --- /dev/null +++ b/Apps.Crowdin/Models/Request/Project/GetProjectOptionalRequest.cs @@ -0,0 +1,12 @@ +using Apps.Crowdin.DataSourceHandlers; +using Blackbird.Applications.Sdk.Common; +using Blackbird.Applications.Sdk.Common.Dynamic; + +namespace Apps.Crowdin.Models.Request.Project; + +public class GetProjectOptionalRequest +{ + [Display("Project ID")] + [DataSource(typeof(ProjectDataHandler))] + public string? ProjectId { get; set; } +} \ No newline at end of file diff --git a/Apps.Crowdin/Models/Request/Project/ProjectRequest.cs b/Apps.Crowdin/Models/Request/Project/ProjectRequest.cs index a9894fd..efc6d3b 100644 --- a/Apps.Crowdin/Models/Request/Project/ProjectRequest.cs +++ b/Apps.Crowdin/Models/Request/Project/ProjectRequest.cs @@ -6,7 +6,7 @@ namespace Apps.Crowdin.Models.Request.Project; public class ProjectRequest { - [Display("Project")] + [Display("Project ID")] [DataSource(typeof(ProjectDataHandler))] public string ProjectId { get; set; } } \ No newline at end of file diff --git a/Apps.Crowdin/Models/Request/SourceString/GetSourceStringOptionalRequest.cs b/Apps.Crowdin/Models/Request/SourceString/GetSourceStringOptionalRequest.cs new file mode 100644 index 0000000..6aa7e03 --- /dev/null +++ b/Apps.Crowdin/Models/Request/SourceString/GetSourceStringOptionalRequest.cs @@ -0,0 +1,9 @@ +using Blackbird.Applications.Sdk.Common; + +namespace Apps.Crowdin.Models.Request.SourceString; + +public class GetSourceStringOptionalRequest +{ + [Display("String ID")] + public string? StringId { get; set; } +} \ No newline at end of file diff --git a/Apps.Crowdin/Models/Request/Suggestions/GetSuggestionOptionalRequest.cs b/Apps.Crowdin/Models/Request/Suggestions/GetSuggestionOptionalRequest.cs new file mode 100644 index 0000000..5d3d2ca --- /dev/null +++ b/Apps.Crowdin/Models/Request/Suggestions/GetSuggestionOptionalRequest.cs @@ -0,0 +1,9 @@ +using Blackbird.Applications.Sdk.Common; + +namespace Apps.Crowdin.Models.Request.Suggestions; + +public class GetSuggestionOptionalRequest +{ + [Display("Suggestion ID")] + public string? SuggestionId { get; set; } +} \ No newline at end of file diff --git a/Apps.Crowdin/Models/Request/Task/GetTaskOptionalRequest.cs b/Apps.Crowdin/Models/Request/Task/GetTaskOptionalRequest.cs new file mode 100644 index 0000000..114244e --- /dev/null +++ b/Apps.Crowdin/Models/Request/Task/GetTaskOptionalRequest.cs @@ -0,0 +1,9 @@ +using Blackbird.Applications.Sdk.Common; + +namespace Apps.Crowdin.Models.Request.Task; + +public class GetTaskOptionalRequest +{ + [Display("Task ID")] + public string? TaskId { get; set; } +} \ No newline at end of file diff --git a/Apps.Crowdin/Webhooks/Lists/ProjectWebhookList.cs b/Apps.Crowdin/Webhooks/Lists/ProjectWebhookList.cs index b07c04d..3194603 100644 --- a/Apps.Crowdin/Webhooks/Lists/ProjectWebhookList.cs +++ b/Apps.Crowdin/Webhooks/Lists/ProjectWebhookList.cs @@ -1,4 +1,9 @@ -using Apps.Crowdin.Webhooks.Handlers.Project.File; +using Apps.Crowdin.Models.Request.File; +using Apps.Crowdin.Models.Request.Project; +using Apps.Crowdin.Models.Request.SourceString; +using Apps.Crowdin.Models.Request.Suggestions; +using Apps.Crowdin.Models.Request.Task; +using Apps.Crowdin.Webhooks.Handlers.Project.File; using Apps.Crowdin.Webhooks.Handlers.Project.Project; using Apps.Crowdin.Webhooks.Handlers.Project.String; using Apps.Crowdin.Webhooks.Handlers.Project.StringComment; @@ -29,43 +34,137 @@ namespace Apps.Crowdin.Webhooks.Lists; [WebhookList] public class ProjectWebhookList { - #region File + #region File [Webhook("On file added", typeof(FileAddedHandler), Description = "On file added")] public Task> OnFileAdded(WebhookRequest webhookRequest) => HandleWehookRequest(webhookRequest); [Webhook("On file approved", typeof(FileApprovedHandler), Description = "On file approved")] - public Task> OnFileApproved(WebhookRequest webhookRequest) - => HandleWehookRequest(webhookRequest); + public Task> OnFileApproved(WebhookRequest webhookRequest, + [WebhookParameter] GetProjectOptionalRequest projectOptionalRequest, + [WebhookParameter] GetFileOptionalRequest fileOptionalRequest) + { + var result = HandleWehookRequest(webhookRequest); + + if (projectOptionalRequest.ProjectId != null && + projectOptionalRequest.ProjectId != result.Result.Result?.File.ProjectId) + { + return Task.FromResult(PreflightResponse()); + } + + if(fileOptionalRequest.FileId != null && + fileOptionalRequest.FileId != result.Result.Result?.File.Id) + { + return Task.FromResult(PreflightResponse()); + } + + return result; + } [Webhook("On file deleted", typeof(FileDeletedHandler), Description = "On file deleted")] public Task> OnFileDeleted(WebhookRequest webhookRequest) => HandleWehookRequest(webhookRequest); [Webhook("On file reverted", typeof(FileRevertedHandler), Description = "On file reverted")] - public Task> OnFileReverted(WebhookRequest webhookRequest) - => HandleWehookRequest(webhookRequest); + public Task> OnFileReverted(WebhookRequest webhookRequest, + [WebhookParameter] GetProjectOptionalRequest projectOptionalRequest, + [WebhookParameter] GetFileOptionalRequest fileOptionalRequest) + { + var result = HandleWehookRequest(webhookRequest); + + if (projectOptionalRequest.ProjectId != null && + projectOptionalRequest.ProjectId != result.Result.Result?.File.ProjectId) + { + return Task.FromResult(PreflightResponse()); + } + + if(fileOptionalRequest.FileId != null && + fileOptionalRequest.FileId != result.Result.Result?.File.Id) + { + return Task.FromResult(PreflightResponse()); + } + + return result; + } [Webhook("On file translated", typeof(FileTranslatedHandler), Description = "On file fully translated")] - public Task> OnFileTranslated(WebhookRequest webhookRequest) - => HandleWehookRequest(webhookRequest); + public Task> OnFileTranslated(WebhookRequest webhookRequest, + [WebhookParameter] GetProjectOptionalRequest projectOptionalRequest, + [WebhookParameter] GetFileOptionalRequest fileOptionalRequest) + { + var result = HandleWehookRequest(webhookRequest); + + if (projectOptionalRequest.ProjectId != null && + projectOptionalRequest.ProjectId != result.Result.Result?.File.ProjectId) + { + return Task.FromResult(PreflightResponse()); + } + + if(fileOptionalRequest.FileId != null && + fileOptionalRequest.FileId != result.Result.Result?.File.Id) + { + return Task.FromResult(PreflightResponse()); + } + + return result; + } [Webhook("On file updated", typeof(FileUpdatedHandler), Description = "On file updated")] - public Task> OnFileUpdated(WebhookRequest webhookRequest) - => HandleWehookRequest(webhookRequest); + public Task> OnFileUpdated(WebhookRequest webhookRequest, + [WebhookParameter] GetProjectOptionalRequest projectOptionalRequest, + [WebhookParameter] GetFileOptionalRequest fileOptionalRequest) + { + var result = HandleWehookRequest(webhookRequest); + + if (projectOptionalRequest.ProjectId != null && + projectOptionalRequest.ProjectId != result.Result.Result?.File.ProjectId) + { + return Task.FromResult(PreflightResponse()); + } + + if(fileOptionalRequest.FileId != null && + fileOptionalRequest.FileId != result.Result.Result?.File.Id) + { + return Task.FromResult(PreflightResponse()); + } + + return result; + } #endregion #region Project [Webhook("On project approved", typeof(ProjectApprovedHandler), Description = "On project approved")] - public Task> OnProjectApproved(WebhookRequest webhookRequest) - => HandleWehookRequest(webhookRequest); + public Task> OnProjectApproved(WebhookRequest webhookRequest, + [WebhookParameter] GetProjectOptionalRequest projectOptionalRequest) + { + var result = HandleWehookRequest(webhookRequest); + + if (projectOptionalRequest.ProjectId != null && + projectOptionalRequest.ProjectId != result.Result.Result?.Project.Id) + { + return Task.FromResult(PreflightResponse()); + } + + return result; + } [Webhook("On project translated", typeof(ProjectTranslatedHandler), Description = "On project translated")] - public Task> OnProjectTranslated(WebhookRequest webhookRequest) - => HandleWehookRequest(webhookRequest); + public Task> OnProjectTranslated(WebhookRequest webhookRequest, + [WebhookParameter] GetProjectOptionalRequest projectOptionalRequest) + { + var result = HandleWehookRequest(webhookRequest); + + if (projectOptionalRequest.ProjectId != null && + projectOptionalRequest.ProjectId != result.Result.Result?.Project.Id) + { + return Task.FromResult(PreflightResponse()); + } + + return result; + } [Webhook("On project built", typeof(ProjectBuiltHandler), Description = "On project built")] public Task> OnProjectBuilt(WebhookRequest webhookRequest) @@ -76,34 +175,81 @@ public Task> OnProjectBuilt(Webhook #region String [Webhook("On string added", typeof(StringAddedHandler), Description = "On string added")] - public Task> OnStringAdded(WebhookRequest webhookRequest) - => HandleWehookRequest, SourceStringWebhookResponse>(webhookRequest); + public Task> OnStringAdded(WebhookRequest webhookRequest, + [WebhookParameter] GetProjectOptionalRequest projectOptionalRequest, + [WebhookParameter] GetFileOptionalRequest fileOptionalRequest) + { + var result = HandleWehookRequest, SourceStringWebhookResponse>(webhookRequest); + + if (projectOptionalRequest.ProjectId != null && + projectOptionalRequest.ProjectId != result.Result.Result?.String.ProjectId) + { + return Task.FromResult(PreflightResponse()); + } + + if(fileOptionalRequest.FileId != null && + fileOptionalRequest.FileId != result.Result.Result?.String.FileId) + { + return Task.FromResult(PreflightResponse()); + } + + return result; + } [Webhook("On string deleted", typeof(StringDeletedHandler), Description = "On string deleted")] public Task> OnStringDeleted(WebhookRequest webhookRequest) => HandleWehookRequest, SourceStringWebhookResponse>(webhookRequest); [Webhook("On string updated", typeof(StringUpdatedHandler), Description = "On string updated")] - public Task> OnStringUpdated(WebhookRequest webhookRequest) - => HandleWehookRequest, SourceStringWebhookResponse>(webhookRequest); + public Task> OnStringUpdated(WebhookRequest webhookRequest, + [WebhookParameter] GetProjectOptionalRequest projectOptionalRequest, + [WebhookParameter] GetFileOptionalRequest fileOptionalRequest, + [WebhookParameter] GetSourceStringOptionalRequest stringOptionalRequest) + { + var result =HandleWehookRequest, SourceStringWebhookResponse>(webhookRequest); + + if (projectOptionalRequest.ProjectId != null && + projectOptionalRequest.ProjectId != result.Result.Result?.String.ProjectId) + { + return Task.FromResult(PreflightResponse()); + } + + if(fileOptionalRequest.FileId != null && + fileOptionalRequest.FileId != result.Result.Result?.String.FileId) + { + return Task.FromResult(PreflightResponse()); + } + + if(stringOptionalRequest.StringId != null && + stringOptionalRequest.StringId != result.Result.Result?.String.Id) + { + return Task.FromResult(PreflightResponse()); + } + + return result; + } #endregion #region StringComment - [Webhook("On string comment created", typeof(StringCommentCreatedHandler), Description = "On string comment created")] + [Webhook("On string comment created", typeof(StringCommentCreatedHandler), + Description = "On string comment created")] public Task> OnStringCommentCreated(WebhookRequest webhookRequest) => HandleWehookRequest(webhookRequest); - [Webhook("On string comment deleted", typeof(StringCommentDeletedHandler), Description = "On string comment deleted")] + [Webhook("On string comment deleted", typeof(StringCommentDeletedHandler), + Description = "On string comment deleted")] public Task> OnStringCommentDeleted(WebhookRequest webhookRequest) => HandleWehookRequest(webhookRequest); - [Webhook("On string comment restored", typeof(StringCommentRestoredHandler), Description = "On string comment restored")] + [Webhook("On string comment restored", typeof(StringCommentRestoredHandler), + Description = "On string comment restored")] public Task> OnStringCommentRestored(WebhookRequest webhookRequest) => HandleWehookRequest(webhookRequest); - [Webhook("On string comment updated", typeof(StringCommentUpdatedHandler), Description = "On string comment updated")] + [Webhook("On string comment updated", typeof(StringCommentUpdatedHandler), + Description = "On string comment updated")] public Task> OnStringCommentUpdated(WebhookRequest webhookRequest) => HandleWehookRequest(webhookRequest); @@ -116,16 +262,53 @@ public Task> OnSuggestionAdded(Webhoo => HandleWehookRequest(webhookRequest); [Webhook("On suggestion approved", typeof(SuggestionApprovedHandler), Description = "On suggestion approved")] - public Task> OnSuggestionApproved(WebhookRequest webhookRequest) - => HandleWehookRequest(webhookRequest); + public Task> OnSuggestionApproved(WebhookRequest webhookRequest, + [WebhookParameter] GetProjectOptionalRequest projectOptionalRequest, + [WebhookParameter] GetSuggestionOptionalRequest fileOptionalRequest) + { + var result = HandleWehookRequest(webhookRequest); + + if (projectOptionalRequest.ProjectId != null && + projectOptionalRequest.ProjectId != result.Result.Result?.ProjectId) + { + return Task.FromResult(PreflightResponse()); + } + + if(fileOptionalRequest.SuggestionId != null && + fileOptionalRequest.SuggestionId != result.Result.Result?.Id) + { + return Task.FromResult(PreflightResponse()); + } + + return result; + } [Webhook("On suggestion deleted", typeof(SuggestionDeletedHandler), Description = "On suggestion deleted")] public Task> OnSuggestionDeleted(WebhookRequest webhookRequest) => HandleWehookRequest(webhookRequest); - [Webhook("On suggestion disapproved", typeof(SuggestionDisapprovedHandler), Description = "On suggestion disapproved")] - public Task> OnSuggestionDisapproved(WebhookRequest webhookRequest) - => HandleWehookRequest(webhookRequest); + [Webhook("On suggestion disapproved", typeof(SuggestionDisapprovedHandler), + Description = "On suggestion disapproved")] + public Task> OnSuggestionDisapproved(WebhookRequest webhookRequest, + [WebhookParameter] GetProjectOptionalRequest projectOptionalRequest, + [WebhookParameter] GetSuggestionOptionalRequest fileOptionalRequest) + { + var result = HandleWehookRequest(webhookRequest); + + if (projectOptionalRequest.ProjectId != null && + projectOptionalRequest.ProjectId != result.Result.Result?.ProjectId) + { + return Task.FromResult(PreflightResponse()); + } + + if(fileOptionalRequest.SuggestionId != null && + fileOptionalRequest.SuggestionId != result.Result.Result?.Id) + { + return Task.FromResult(PreflightResponse()); + } + + return result; + } [Webhook("On suggestion updated", typeof(SuggestionUpdatedHandler), Description = "On suggestion updated")] public Task> OnSuggestionUpdated(WebhookRequest webhookRequest) @@ -144,15 +327,36 @@ public Task> OnTaskDeleted(WebhookRequest w => HandleWehookRequest(webhookRequest); [Webhook("On task status changed", typeof(TaskStatusChangedHandler), Description = "On task status changed")] - public Task> OnTaskStatusChanged(WebhookRequest webhookRequest) - => HandleWehookRequest(webhookRequest); + public Task> OnTaskStatusChanged(WebhookRequest webhookRequest, + [WebhookParameter] GetProjectOptionalRequest projectOptionalRequest, + [WebhookParameter] GetTaskOptionalRequest taskOptionalRequest) + { + var result = HandleWehookRequest(webhookRequest); + + if (projectOptionalRequest.ProjectId != null && + projectOptionalRequest.ProjectId != result.Result.Result?.ProjectId) + { + return Task.FromResult(PreflightResponse()); + } + + if(taskOptionalRequest.TaskId != null && + taskOptionalRequest.TaskId != result.Result.Result?.Id) + { + return Task.FromResult(PreflightResponse()); + } + + return result; + } #endregion #region Translation [Webhook("On translation updated", typeof(TranslationUpdatedHandler), Description = "On translation updated")] - public WebhookResponse OnTranslationUpdated(WebhookRequest webhookRequest) + public WebhookResponse OnTranslationUpdated(WebhookRequest webhookRequest, + [WebhookParameter] GetProjectOptionalRequest projectOptionalRequest, + [WebhookParameter] GetFileOptionalRequest fileOptionalRequest, + [WebhookParameter] GetSourceStringOptionalRequest sourceStringOptionalRequest) { var data = JsonConvert.DeserializeObject(webhookRequest.Body.ToString()); @@ -161,6 +365,24 @@ public WebhookResponse OnTranslationUpdated(W var result = new TranslationUpdatedWebhookResponse(); result.ConfigureResponse(data); + + if (projectOptionalRequest.ProjectId != null && + projectOptionalRequest.ProjectId != result.NewTranslation.SourceString.ProjectId) + { + return PreflightResponse(); + } + + if(fileOptionalRequest.FileId != null && + fileOptionalRequest.FileId != result.NewTranslation.SourceString.FileId) + { + return PreflightResponse(); + } + + if(sourceStringOptionalRequest.StringId != null && + sourceStringOptionalRequest.StringId != result.NewTranslation.SourceString.Id) + { + return PreflightResponse(); + } return new WebhookResponse { @@ -186,4 +408,14 @@ public async Task> HandleWehookRequest(WebhookRequest Result = result }; } + + private static WebhookResponse PreflightResponse() + where T : class + { + return new WebhookResponse + { + ReceivedWebhookRequestType = WebhookRequestType.Preflight, + Result = null + }; + } } \ No newline at end of file From ce13e954929b4a440bda3fa3743cf1d9a93f75ed Mon Sep 17 00:00:00 2001 From: vitalii-bezuhlyi Date: Thu, 10 Oct 2024 12:44:25 +0300 Subject: [PATCH 2/2] Minor improvements --- .../Webhooks/Lists/ProjectWebhookList.cs | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/Apps.Crowdin/Webhooks/Lists/ProjectWebhookList.cs b/Apps.Crowdin/Webhooks/Lists/ProjectWebhookList.cs index 3194603..db0b20b 100644 --- a/Apps.Crowdin/Webhooks/Lists/ProjectWebhookList.cs +++ b/Apps.Crowdin/Webhooks/Lists/ProjectWebhookList.cs @@ -258,8 +258,26 @@ public Task> OnStringCommentUpdate #region Suggestion [Webhook("On suggestion added", typeof(SuggestionAddedHandler), Description = "On suggestion added")] - public Task> OnSuggestionAdded(WebhookRequest webhookRequest) - => HandleWehookRequest(webhookRequest); + public Task> OnSuggestionAdded(WebhookRequest webhookRequest, + [WebhookParameter] GetProjectOptionalRequest projectOptionalRequest, + [WebhookParameter] GetSuggestionOptionalRequest fileOptionalRequest) + { + var result = HandleWehookRequest(webhookRequest); + + if (projectOptionalRequest.ProjectId != null && + projectOptionalRequest.ProjectId != result.Result.Result?.ProjectId) + { + return Task.FromResult(PreflightResponse()); + } + + if(fileOptionalRequest.SuggestionId != null && + fileOptionalRequest.SuggestionId != result.Result.Result?.Id) + { + return Task.FromResult(PreflightResponse()); + } + + return result; + } [Webhook("On suggestion approved", typeof(SuggestionApprovedHandler), Description = "On suggestion approved")] public Task> OnSuggestionApproved(WebhookRequest webhookRequest,