From 5a1fcc02c035c0a409c876bd14ec15cbf2aaf8a7 Mon Sep 17 00:00:00 2001 From: bZverok <137277669+bZverok@users.noreply.github.com> Date: Wed, 10 Apr 2024 12:22:31 +0300 Subject: [PATCH 1/6] added categories --- Apps.Wordpress/Apps.Wordpress.csproj | 2 +- Apps.Wordpress/WordpressApplication.cs | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Apps.Wordpress/Apps.Wordpress.csproj b/Apps.Wordpress/Apps.Wordpress.csproj index e31853e..a3acbba 100644 --- a/Apps.Wordpress/Apps.Wordpress.csproj +++ b/Apps.Wordpress/Apps.Wordpress.csproj @@ -9,7 +9,7 @@ Apps.Wordpress - + diff --git a/Apps.Wordpress/WordpressApplication.cs b/Apps.Wordpress/WordpressApplication.cs index 7273b50..6b237dc 100644 --- a/Apps.Wordpress/WordpressApplication.cs +++ b/Apps.Wordpress/WordpressApplication.cs @@ -1,9 +1,17 @@ using Blackbird.Applications.Sdk.Common; +using Blackbird.Applications.Sdk.Common.Metadata; namespace Apps.Wordpress { - public class WordpressApplication : IApplication + public class WordpressApplication : IApplication, ICategoryProvider { + + public IEnumerable Categories + { + get => [ApplicationCategory.Cms]; + set { } + } + public string Name { get => "Wordpress"; From e334183f69aab019a958e15a8605f12b6d75d815 Mon Sep 17 00:00:00 2001 From: vitalii-bezuhlyi Date: Tue, 16 Apr 2024 15:00:29 +0300 Subject: [PATCH 2/6] Updated csproj --- Apps.Wordpress/Apps.Wordpress.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Apps.Wordpress/Apps.Wordpress.csproj b/Apps.Wordpress/Apps.Wordpress.csproj index a3acbba..c0ee8eb 100644 --- a/Apps.Wordpress/Apps.Wordpress.csproj +++ b/Apps.Wordpress/Apps.Wordpress.csproj @@ -4,7 +4,7 @@ enable enable Wordpress (+ Polylang) - 1.1.2 + 1.1.3 The world’s most popular website builder Apps.Wordpress From 4de8042c35d12be53af739f02e26848b9d7f9607 Mon Sep 17 00:00:00 2001 From: bZverok <137277669+bZverok@users.noreply.github.com> Date: Tue, 11 Jun 2024 19:37:54 +0300 Subject: [PATCH 3/6] added polling events --- Apps.Wordpress/Apps.Wordpress.csproj | 2 +- .../Polling/Models/ContentPollingResult.cs | 8 + .../Memory/ContentCreatedPollingMemory.cs | 6 + .../Memory/ContentUpdatedPollingMemory.cs | 6 + Apps.Wordpress/Events/Polling/PollingList.cs | 164 ++++++++++++++++++ .../Models/Requests/Post/PostRequest.cs | 2 +- 6 files changed, 186 insertions(+), 2 deletions(-) create mode 100644 Apps.Wordpress/Events/Polling/Models/ContentPollingResult.cs create mode 100644 Apps.Wordpress/Events/Polling/Models/Memory/ContentCreatedPollingMemory.cs create mode 100644 Apps.Wordpress/Events/Polling/Models/Memory/ContentUpdatedPollingMemory.cs create mode 100644 Apps.Wordpress/Events/Polling/PollingList.cs diff --git a/Apps.Wordpress/Apps.Wordpress.csproj b/Apps.Wordpress/Apps.Wordpress.csproj index c0ee8eb..ac59494 100644 --- a/Apps.Wordpress/Apps.Wordpress.csproj +++ b/Apps.Wordpress/Apps.Wordpress.csproj @@ -9,7 +9,7 @@ Apps.Wordpress - + diff --git a/Apps.Wordpress/Events/Polling/Models/ContentPollingResult.cs b/Apps.Wordpress/Events/Polling/Models/ContentPollingResult.cs new file mode 100644 index 0000000..b7f1276 --- /dev/null +++ b/Apps.Wordpress/Events/Polling/Models/ContentPollingResult.cs @@ -0,0 +1,8 @@ +using Apps.Wordpress.Models.Entities; + +namespace Apps.Wordpress.Events.Polling.Models; + +public class ContentPollingResult +{ + public IEnumerable Items { get; set; } +} \ No newline at end of file diff --git a/Apps.Wordpress/Events/Polling/Models/Memory/ContentCreatedPollingMemory.cs b/Apps.Wordpress/Events/Polling/Models/Memory/ContentCreatedPollingMemory.cs new file mode 100644 index 0000000..bd04bad --- /dev/null +++ b/Apps.Wordpress/Events/Polling/Models/Memory/ContentCreatedPollingMemory.cs @@ -0,0 +1,6 @@ +namespace Apps.Wordpress.Events.Polling.Models.Memory; + +public class ContentCreatedPollingMemory +{ + public DateTime LastCreationDate { get; set; } +} \ No newline at end of file diff --git a/Apps.Wordpress/Events/Polling/Models/Memory/ContentUpdatedPollingMemory.cs b/Apps.Wordpress/Events/Polling/Models/Memory/ContentUpdatedPollingMemory.cs new file mode 100644 index 0000000..7b7024a --- /dev/null +++ b/Apps.Wordpress/Events/Polling/Models/Memory/ContentUpdatedPollingMemory.cs @@ -0,0 +1,6 @@ +namespace Apps.Wordpress.Events.Polling.Models.Memory; + +public class ContentUpdatedPollingMemory +{ + public DateTime LastModificationTime { get; set; } +} \ No newline at end of file diff --git a/Apps.Wordpress/Events/Polling/PollingList.cs b/Apps.Wordpress/Events/Polling/PollingList.cs new file mode 100644 index 0000000..a3a62b4 --- /dev/null +++ b/Apps.Wordpress/Events/Polling/PollingList.cs @@ -0,0 +1,164 @@ +using Apps.Wordpress.Api.RestSharp; +using Apps.Wordpress.Constants; +using Apps.Wordpress.DataSourceHandlers; +using Apps.Wordpress.Events.Polling.Models; +using Apps.Wordpress.Events.Polling.Models.Memory; +using Apps.Wordpress.Models.Dtos; +using Apps.Wordpress.Models.Entities; +using Blackbird.Applications.Sdk.Common; +using Blackbird.Applications.Sdk.Common.Dynamic; +using Blackbird.Applications.Sdk.Common.Invocation; +using Blackbird.Applications.Sdk.Common.Polling; +using Blackbird.Applications.Sdk.Utils.Extensions.String; +using RestSharp; + +namespace Apps.Wordpress.Events.Polling; + +[PollingEventList] +public class PollingList : BaseInvocable +{ + public PollingList(InvocationContext invocationContext) : base(invocationContext) + { + } + + [PollingEvent("On post created", "On a new post created")] + public Task> OnPostCreated( + PollingEventRequest request) + => PollContentCreation(request, new() + { + ["after"] = request.Memory?.LastCreationDate.ToString(Formats.ISO8601) ?? string.Empty + }, "posts", () => new() + { + LastCreationDate = DateTime.UtcNow + }); + + + [PollingEvent("On post updated", "On a specific post updated")] + public Task> OnPostUpdated( + PollingEventRequest request, + [PollingEventParameter] [Display("Post ID")] [DataSource(typeof(PostDataHandler))] + string? postId) + => PollContentChanges(request, postId, new() + { + ["modified_after"] = request.Memory?.LastModificationTime.ToString(Formats.ISO8601) ?? string.Empty + }, "posts", () => new() + { + LastModificationTime = DateTime.UtcNow + }); + + [PollingEvent("On page created", "On a new page created")] + public Task> OnPageCreated( + PollingEventRequest request) + => PollContentCreation(request, new() + { + ["after"] = request.Memory?.LastCreationDate.ToString(Formats.ISO8601) ?? string.Empty + }, "pages", () => new() + { + LastCreationDate = DateTime.UtcNow + }); + + + [PollingEvent("On page updated", "On a specific page updated")] + public Task> OnPageUpdated( + PollingEventRequest request, + [PollingEventParameter] [Display("Page ID")] [DataSource(typeof(PageDataHandler))] + string? pageId) + => PollContentChanges(request, pageId, new() + { + ["modified_after"] = request.Memory?.LastModificationTime.ToString(Formats.ISO8601) ?? string.Empty + }, "pages", () => new() + { + LastModificationTime = DateTime.UtcNow + }); + + private async Task> PollContentCreation( + PollingEventRequest request, Dictionary query, string endpoint, Func createMemory) + { + if (request.Memory is null) + { + return new() + { + FlyBird = false, + Memory = createMemory() + }; + } + + var items = await ListContentItems(endpoint.WithQuery(query)); + + if (!items.Any()) + { + return new() + { + FlyBird = false, + Memory = createMemory() + }; + } + + return new() + { + FlyBird = true, + Result = new() + { + Items = items.Select(x => new WordPressItem(x)).ToList() + }, + Memory = createMemory() + }; + } + + private async Task> PollContentChanges( + PollingEventRequest request, string? resourceId, Dictionary query, string endpoint, + Func createMemory) where T : ContentUpdatedPollingMemory + { + if (request.Memory is null) + { + return new() + { + FlyBird = false, + Memory = createMemory() + }; + } + + var items = string.IsNullOrWhiteSpace(resourceId) + ? await ListContentItems(endpoint.WithQuery(query)) + : await GetContentItem($"{endpoint}/{resourceId}", request.Memory); + + if (!items.Any()) + { + return new() + { + FlyBird = false, + Memory = createMemory() + }; + } + + return new() + { + FlyBird = true, + Result = new() + { + Items = items.Select(x => new WordPressItem(x)).ToList() + }, + Memory = createMemory() + }; + } + + private Task> ListContentItems(string endpoint) + { + var client = new WordpressRestClient(InvocationContext.AuthenticationCredentialsProviders); + var listRequest = + new WordpressRestRequest(endpoint, Method.Get, InvocationContext.AuthenticationCredentialsProviders); + + return client.Paginate(listRequest); + } + + private async Task> GetContentItem(string endpoint, ContentUpdatedPollingMemory memory) + { + var client = new WordpressRestClient(InvocationContext.AuthenticationCredentialsProviders); + var listRequest = + new WordpressRestRequest(endpoint, Method.Get, InvocationContext.AuthenticationCredentialsProviders); + + var item = await client.ExecuteWithHandling(listRequest); + + return item.ModifiedGmt > memory.LastModificationTime ? [item] : []; + } +} \ No newline at end of file diff --git a/Apps.Wordpress/Models/Requests/Post/PostRequest.cs b/Apps.Wordpress/Models/Requests/Post/PostRequest.cs index 4c4fe9a..2419e2a 100644 --- a/Apps.Wordpress/Models/Requests/Post/PostRequest.cs +++ b/Apps.Wordpress/Models/Requests/Post/PostRequest.cs @@ -6,7 +6,7 @@ namespace Apps.Wordpress.Models.Requests.Post { public class PostRequest { - [Display("Post")] + [Display("Post ID")] [DataSource(typeof(PostDataHandler))] public string Id { get; set; } } From 0292634995ecf6ba8bd9154e79cc9ac6c4ad60e4 Mon Sep 17 00:00:00 2001 From: bZverok <137277669+bZverok@users.noreply.github.com> Date: Wed, 12 Jun 2024 11:00:24 +0300 Subject: [PATCH 4/6] added docs --- Apps.Wordpress/Apps.Wordpress.csproj | 2 +- README.md | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Apps.Wordpress/Apps.Wordpress.csproj b/Apps.Wordpress/Apps.Wordpress.csproj index ac59494..2e85d21 100644 --- a/Apps.Wordpress/Apps.Wordpress.csproj +++ b/Apps.Wordpress/Apps.Wordpress.csproj @@ -4,7 +4,7 @@ enable enable Wordpress (+ Polylang) - 1.1.3 + 1.2.0 The world’s most popular website builder Apps.Wordpress diff --git a/README.md b/README.md index 19d7386..4b070ab 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,13 @@ Our post & page actions can also be extended to deal with more properties like s Let us know if you're interested! +## Events + +- **On post created** triggers when a new post is created. +- **On post updated** triggers when any post is updated. +- **On page created** triggers when a new page is created. +- **On page updated** triggers when any page is updated. + ## Feedback Do you want to use this app or do you have feedback on our implementation? Reach out to us using the [established channels](https://www.blackbird.io/) or create an issue. From 4a38a343e407580b8a00913fe1b9baf5e3684074 Mon Sep 17 00:00:00 2001 From: bZverok <137277669+bZverok@users.noreply.github.com> Date: Wed, 12 Jun 2024 19:51:38 +0300 Subject: [PATCH 5/6] added language input to polling events --- Apps.Wordpress/Apps.Wordpress.csproj | 2 +- Apps.Wordpress/Events/Polling/PollingList.cs | 37 ++++++++++++------- .../Models/Requests/LanguageRequest.cs | 12 ++++++ README.md | 8 ++-- 4 files changed, 40 insertions(+), 19 deletions(-) create mode 100644 Apps.Wordpress/Models/Requests/LanguageRequest.cs diff --git a/Apps.Wordpress/Apps.Wordpress.csproj b/Apps.Wordpress/Apps.Wordpress.csproj index 2e85d21..abee31d 100644 --- a/Apps.Wordpress/Apps.Wordpress.csproj +++ b/Apps.Wordpress/Apps.Wordpress.csproj @@ -4,7 +4,7 @@ enable enable Wordpress (+ Polylang) - 1.2.0 + 1.2.1 The world’s most popular website builder Apps.Wordpress diff --git a/Apps.Wordpress/Events/Polling/PollingList.cs b/Apps.Wordpress/Events/Polling/PollingList.cs index a3a62b4..8c65e77 100644 --- a/Apps.Wordpress/Events/Polling/PollingList.cs +++ b/Apps.Wordpress/Events/Polling/PollingList.cs @@ -5,11 +5,13 @@ using Apps.Wordpress.Events.Polling.Models.Memory; using Apps.Wordpress.Models.Dtos; using Apps.Wordpress.Models.Entities; +using Apps.Wordpress.Models.Requests; using Blackbird.Applications.Sdk.Common; using Blackbird.Applications.Sdk.Common.Dynamic; using Blackbird.Applications.Sdk.Common.Invocation; using Blackbird.Applications.Sdk.Common.Polling; using Blackbird.Applications.Sdk.Utils.Extensions.String; +using Blackbird.Applications.Sdk.Utils.Extensions.System; using RestSharp; namespace Apps.Wordpress.Events.Polling; @@ -21,51 +23,58 @@ public PollingList(InvocationContext invocationContext) : base(invocationContext { } - [PollingEvent("On post created", "On a new post created")] + [PollingEvent("On posts created", "On new posts are created")] public Task> OnPostCreated( - PollingEventRequest request) + PollingEventRequest request, + [PollingEventParameter] LanguageOptionalRequest languageRequest) => PollContentCreation(request, new() { - ["after"] = request.Memory?.LastCreationDate.ToString(Formats.ISO8601) ?? string.Empty + ["after"] = request.Memory?.LastCreationDate.ToString(Formats.ISO8601) ?? string.Empty, + ["lang"] = languageRequest.Language ?? string.Empty }, "posts", () => new() { LastCreationDate = DateTime.UtcNow }); - [PollingEvent("On post updated", "On a specific post updated")] + [PollingEvent("On posts updated", "On specific posts are updated")] public Task> OnPostUpdated( PollingEventRequest request, [PollingEventParameter] [Display("Post ID")] [DataSource(typeof(PostDataHandler))] - string? postId) + string? postId, [PollingEventParameter] LanguageOptionalRequest languageRequest) => PollContentChanges(request, postId, new() { - ["modified_after"] = request.Memory?.LastModificationTime.ToString(Formats.ISO8601) ?? string.Empty + ["modified_after"] = request.Memory?.LastModificationTime.ToString(Formats.ISO8601) ?? string.Empty, + ["lang"] = languageRequest.Language ?? string.Empty }, "posts", () => new() { LastModificationTime = DateTime.UtcNow }); - [PollingEvent("On page created", "On a new page created")] + [PollingEvent("On pages created", "On new pages are created")] public Task> OnPageCreated( - PollingEventRequest request) + PollingEventRequest request, + [PollingEventParameter] LanguageOptionalRequest languageRequest) => PollContentCreation(request, new() { - ["after"] = request.Memory?.LastCreationDate.ToString(Formats.ISO8601) ?? string.Empty + ["after"] = request.Memory?.LastCreationDate.ToString(Formats.ISO8601) ?? string.Empty, + ["lang"] = languageRequest.Language ?? string.Empty }, "pages", () => new() { LastCreationDate = DateTime.UtcNow }); - [PollingEvent("On page updated", "On a specific page updated")] + [PollingEvent("On pages updated", "On specific pages are updated")] public Task> OnPageUpdated( PollingEventRequest request, [PollingEventParameter] [Display("Page ID")] [DataSource(typeof(PageDataHandler))] - string? pageId) + string? pageId, + [PollingEventParameter] LanguageOptionalRequest languageRequest) => PollContentChanges(request, pageId, new() { - ["modified_after"] = request.Memory?.LastModificationTime.ToString(Formats.ISO8601) ?? string.Empty + ["modified_after"] = request.Memory?.LastModificationTime.ToString(Formats.ISO8601) ?? string.Empty, + ["lang"] = languageRequest.Language ?? string.Empty }, "pages", () => new() { LastModificationTime = DateTime.UtcNow @@ -83,7 +92,7 @@ private async Task> PollContentCre }; } - var items = await ListContentItems(endpoint.WithQuery(query)); + var items = await ListContentItems(endpoint.WithQuery(query.AllIsNotNull())); if (!items.Any()) { @@ -119,7 +128,7 @@ private async Task> PollContentCha } var items = string.IsNullOrWhiteSpace(resourceId) - ? await ListContentItems(endpoint.WithQuery(query)) + ? await ListContentItems(endpoint.WithQuery(query.AllIsNotNull())) : await GetContentItem($"{endpoint}/{resourceId}", request.Memory); if (!items.Any()) diff --git a/Apps.Wordpress/Models/Requests/LanguageRequest.cs b/Apps.Wordpress/Models/Requests/LanguageRequest.cs new file mode 100644 index 0000000..ba4f073 --- /dev/null +++ b/Apps.Wordpress/Models/Requests/LanguageRequest.cs @@ -0,0 +1,12 @@ +using Apps.Wordpress.DataSourceHandlers; +using Blackbird.Applications.Sdk.Common; +using Blackbird.Applications.Sdk.Common.Dynamic; + +namespace Apps.Wordpress.Models.Requests; + +public class LanguageOptionalRequest +{ + [Display("Language (P)")] + [DataSource(typeof(LanguageDataHandler))] + public string? Language { get; set; } +} \ No newline at end of file diff --git a/README.md b/README.md index 4b070ab..3c078ae 100644 --- a/README.md +++ b/README.md @@ -87,10 +87,10 @@ Let us know if you're interested! ## Events -- **On post created** triggers when a new post is created. -- **On post updated** triggers when any post is updated. -- **On page created** triggers when a new page is created. -- **On page updated** triggers when any page is updated. +- **On posts created** triggers when new posts are created. +- **On posts updated** triggers when any posts are updated. +- **On pages created** triggers when new pages are created. +- **On pages updated** triggers when any pages are updated. ## Feedback From 5a0e7e1490d37fd210fd3c40e5e84364c0187222 Mon Sep 17 00:00:00 2001 From: vitalii-bezuhlyi Date: Tue, 9 Jul 2024 18:20:56 +0300 Subject: [PATCH 6/6] Fixed DRA error --- Apps.Wordpress/Actions/PageActions.cs | 17 ++++++++++------- .../Api/RestSharp/WordpressRestClient.cs | 2 +- Apps.Wordpress/Apps.Wordpress.csproj | 4 ++-- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/Apps.Wordpress/Actions/PageActions.cs b/Apps.Wordpress/Actions/PageActions.cs index e53a028..6c46e47 100644 --- a/Apps.Wordpress/Actions/PageActions.cs +++ b/Apps.Wordpress/Actions/PageActions.cs @@ -23,6 +23,7 @@ using Blackbird.Applications.Sdk.Utils.Extensions.System; using Blackbird.Applications.Sdk.Utils.Html.Extensions; using Blackbird.Applications.Sdk.Utils.Parsers; +using Newtonsoft.Json; using RestSharp; namespace Apps.Wordpress.Actions; @@ -75,9 +76,10 @@ public async Task GetPageById([ActionParameter] PageRequest input { var client = new WordpressRestClient(Creds); var request = new WordpressRestRequest(Endpoint + $"/{input.Id}", Method.Get, Creds); - var post = await client.ExecuteWithHandling(request); + var post = await client.ExecuteWithHandling(request); - return new(post); + var dto = JsonConvert.DeserializeObject(post.Content!)!; + return new(dto); } [Action("Get page missing translations (P)", Description = "Gets all the languages that are missing for this page.")] @@ -114,14 +116,15 @@ public async Task GetTranslationByPage([ActionParameter] PageRequ [Action("Get page as HTML", Description = "Get page by id as HTML file")] public async Task GetPageByIdAsHtml([ActionParameter] PageRequest input) { - var client = new CustomWordpressClient(Creds); - var page = await client.Pages.GetByIDAsync(input.Id); - - var html = (page.Title.Rendered, page.Content.Rendered).AsHtml(); + var client = new WordpressRestClient(Creds); + var request = new WordpressRestRequest(Endpoint + $"/{input.Id}", Method.Get, Creds); + var post = await client.ExecuteWithHandling(request); + + var html = (post.Title.Rendered, post.Content.Rendered).AsHtml(); using var stream = new MemoryStream(Encoding.UTF8.GetBytes(html)); var file = await _fileManagementClient.UploadAsync(stream, MediaTypeNames.Text.Html, - $"{page.Title.Rendered}.html"); + $"{post.Title.Rendered}.html"); return new(file); } diff --git a/Apps.Wordpress/Api/RestSharp/WordpressRestClient.cs b/Apps.Wordpress/Api/RestSharp/WordpressRestClient.cs index 0f1f873..b70a859 100644 --- a/Apps.Wordpress/Api/RestSharp/WordpressRestClient.cs +++ b/Apps.Wordpress/Api/RestSharp/WordpressRestClient.cs @@ -39,7 +39,7 @@ public async Task> Paginate(RestRequest request) }); var response = await ExecuteWithHandling(request); - totalPages ??= int.Parse(response.Headers.First(x => x.Name == "X-Wp-Totalpages").Value.ToString()); + totalPages ??= int.Parse(response.Headers.First(x => x.Name!.Equals("X-Wp-Totalpages", StringComparison.OrdinalIgnoreCase)).Value.ToString()); var content = response.Content; var data = JsonConvert.DeserializeObject(response.Content); diff --git a/Apps.Wordpress/Apps.Wordpress.csproj b/Apps.Wordpress/Apps.Wordpress.csproj index abee31d..66c52c4 100644 --- a/Apps.Wordpress/Apps.Wordpress.csproj +++ b/Apps.Wordpress/Apps.Wordpress.csproj @@ -4,7 +4,7 @@ enable enable Wordpress (+ Polylang) - 1.2.1 + 1.2.2 The world’s most popular website builder Apps.Wordpress @@ -13,7 +13,7 @@ - +