diff --git a/Bynder/Sample/ApiSample.cs b/Bynder/Sample/ApiSample.cs index 6c566c9..4893f04 100644 --- a/Bynder/Sample/ApiSample.cs +++ b/Bynder/Sample/ApiSample.cs @@ -54,6 +54,15 @@ public static async Task Main(string[] args) await MediaSample.MediaSampleAsync(); return; } + + // Run samples related to modifying media + if (args[0].Equals("ModifyMediaSample")) + { + Console.WriteLine("Running samples for the modification of media..."); + await ModifyMediaSample.ModifyMediaSampleAsync(); + return; + } + // Run samples related to collections if (args[0].Equals("CollectionsSample")) { Console.WriteLine("Running samples for collections..."); diff --git a/Bynder/Sample/ModifyMediaSample.cs b/Bynder/Sample/ModifyMediaSample.cs new file mode 100644 index 0000000..01afaaa --- /dev/null +++ b/Bynder/Sample/ModifyMediaSample.cs @@ -0,0 +1,179 @@ +// Copyright (c) Bynder. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. + +using System; +using Bynder.Sdk.Service; +using Bynder.Sample.Utils; +using Bynder.Sdk.Settings; +using System.Threading.Tasks; +using System.Linq; +using Bynder.Sdk.Query.Asset; +using Bynder.Sdk.Model; +using System.Collections.Generic; +using Newtonsoft.Json.Linq; + +namespace Bynder.Sample +{ + public class ModifyMediaSample + { + private IBynderClient _bynderClient; + + public static async Task ModifyMediaSampleAsync() + { + var configuration = Configuration.FromJson("Config.json"); + var apiSample = new ModifyMediaSample(configuration); + await apiSample.AuthenticateWithOAuth2Async( + useClientCredentials: configuration.RedirectUri == null + ); + await apiSample.RunModifyMediaSampleAsync(); + } + + private ModifyMediaSample(Configuration configuration) + { + _bynderClient = ClientFactory.Create(configuration); + } + + private async Task RunModifyMediaSampleAsync() + { + var assetService = _bynderClient.GetAssetService(); + // Get a list of media with limit 10 + Console.WriteLine("Listing media with limit of 10: "); + var mediaList = await assetService.GetMediaListAsync(new MediaQuery { Limit = 10 }); + foreach (Media media in mediaList) + { + Console.WriteLine($"Media ID: {media.Id}"); + Console.WriteLine($"Media Name: {media.Name}"); + } + + // Get the media info + Console.WriteLine("Enter the media ID to modify: "); + var mediaId = Console.ReadLine(); + var mediaInformationQuery = new MediaInformationQuery + { + MediaId = mediaId.Trim() + }; + var mediaInfo = await assetService.GetMediaInfoAsync(mediaInformationQuery); + Console.WriteLine($"ID: {mediaInfo.Id}"); + Console.WriteLine($"Name: {mediaInfo.Name}"); + + + // datePublished + Console.WriteLine($"---\r\nTest with datePublished"); + Console.WriteLine($"datePublished is currently set to: {mediaInfo.DatePublished}"); + Console.WriteLine("New value (use ISO8601 format: yyyy-mm-ddThh:mm:ssZ, or n = now, or leave empty to erase): "); + var cmd = Console.ReadLine(); + var query = new ModifyMediaQuery(mediaId); + if (cmd.ToLower().StartsWith("n")) + { + query.PublishedDate = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ssZ"); + } + else if (string.IsNullOrEmpty(cmd)) + { + query.PublishedDate = ""; + } + else + { + query.PublishedDate = cmd; + } + await assetService.ModifyMediaAsync(query); + Console.WriteLine("The asset has been modified. It takes a few seconds for changes come through. Hit enter when you want to retrieve the asset again."); + Console.ReadLine(); + mediaInfo = await assetService.GetMediaInfoAsync(mediaInformationQuery); + Console.WriteLine($"datePublished is now set to: {mediaInfo.DatePublished}"); + + // isArchived (boolean) + Console.WriteLine($"---\r\nTest with boolean value (isArchived)"); + Console.WriteLine($"isArchived is currently set to: {mediaInfo.IsArchived}"); + Console.WriteLine("New value (t=true, f=false, n=not set): "); + cmd = Console.ReadLine(); + query = new ModifyMediaQuery(mediaId); + if (cmd.ToLower().StartsWith("t")) + { + query.Archive = true; + } + else if (cmd.ToLower().StartsWith("f")) + { + query.Archive = false; + } + await assetService.ModifyMediaAsync(query); + Console.WriteLine("The asset has been modified. It takes a few seconds for changes come through. Hit enter when you want to retrieve the asset again."); + Console.ReadLine(); + mediaInfo = await assetService.GetMediaInfoAsync(mediaInformationQuery); + Console.WriteLine($"isArchived is now set to: {mediaInfo.IsArchived}"); + + // Copyright message + Console.WriteLine($"---\r\nTest with string value (copyright)"); + Console.WriteLine($"Copyright message is currently set to {mediaInfo.Copyright}"); + Console.WriteLine($"Please supply a new value for the copyright message, or hit enter to erase it"); + + cmd = Console.ReadLine(); + query = new ModifyMediaQuery(mediaId); + query.Copyright = string.IsNullOrEmpty(cmd) ? "" : cmd; + await assetService.ModifyMediaAsync(query); + Console.WriteLine("The asset has been modified. It takes a few seconds for changes come through. Hit enter when you want to retrieve the asset again."); + Console.ReadLine(); + mediaInfo = await assetService.GetMediaInfoAsync(mediaInformationQuery); + Console.WriteLine($"Copyright message is now set to {mediaInfo.Copyright}"); + + // Metaproperties + if (!(mediaInfo.PropertyOptionsDictionary?.Keys?.Any() ?? false)) + { + Console.WriteLine("This media item has no meta properties, please choose a different one the next time! Bye for now."); + return; + } + var metaprop = mediaInfo.PropertyOptionsDictionary.FirstOrDefault(); + var metaPropertyName = metaprop.Key.Replace("property_", ""); + + Console.WriteLine($"---\r\nTest with metaproperties"); + Console.WriteLine($"Meta property {metaprop.Key} is currently set to {metaprop.Value.ToString()}"); + Console.WriteLine($"Please supply a new value for the meta property, or hit enter to erase it"); + + cmd = Console.ReadLine(); + + // get ID of the meta property + var metaProperties = await assetService.GetMetapropertiesAsync(); + var metaProperty = metaProperties.Values.FirstOrDefault(mp => mp.Name == metaPropertyName); + if (metaProperty == null) + { + throw new Exception("Unable to find property with name " + metaprop.Key.Replace("property_", "")); + } + + query = new ModifyMediaQuery(mediaId); + query.MetapropertyOptions = new Dictionary>() + { + { + metaProperty.Id, + string.IsNullOrEmpty(cmd) ? [] : [cmd] + } + }; + await assetService.ModifyMediaAsync(query); + Console.WriteLine("The asset has been modified. It takes a few seconds for changes come through. Hit enter when you want to retrieve the asset again."); + Console.ReadLine(); + mediaInfo = await assetService.GetMediaInfoAsync(mediaInformationQuery); + if (mediaInfo.PropertyOptionsDictionary?.TryGetValue("property_" + metaPropertyName, out JToken value) ?? false) + { + Console.WriteLine($"Meta property {metaPropertyName} is now set to {value.ToString()}"); + } + else + { + Console.WriteLine($"Asset has no value for metaproperty {metaPropertyName}"); + } + } + + private async Task AuthenticateWithOAuth2Async(bool useClientCredentials) + { + if (useClientCredentials) + { + await _bynderClient.GetOAuthService().GetAccessTokenAsync(); + } + else + { + Browser.Launch(_bynderClient.GetOAuthService().GetAuthorisationUrl("state example")); + Console.WriteLine("Insert the code: "); + var code = Console.ReadLine(); + await _bynderClient.GetOAuthService().GetAccessTokenAsync(code); + } + } + + } +} diff --git a/Bynder/Sample/Properties/launchSettings.json b/Bynder/Sample/Properties/launchSettings.json index 865d3b8..6c8a765 100644 --- a/Bynder/Sample/Properties/launchSettings.json +++ b/Bynder/Sample/Properties/launchSettings.json @@ -36,5 +36,9 @@ "commandName": "Project", "commandLineArgs": "AssetUsageSample" }, + "Run ModifyMediaSample": { + "commandName": "Project", + "commandLineArgs": "ModifyMediaSample" + } } } \ No newline at end of file diff --git a/Bynder/Sdk/Api/RequestSender/HttpRequestSender.cs b/Bynder/Sdk/Api/RequestSender/HttpRequestSender.cs index 1eac981..dfb81c0 100644 --- a/Bynder/Sdk/Api/RequestSender/HttpRequestSender.cs +++ b/Bynder/Sdk/Api/RequestSender/HttpRequestSender.cs @@ -1,4 +1,4 @@ -// Copyright (c) Bynder. All rights reserved. +// Copyright (c) Bynder. All rights reserved. // Licensed under the MIT License. See LICENSE file in the project root for full license information. using System.Net.Http; @@ -32,7 +32,11 @@ public string UserAgent public async Task SendHttpRequest(HttpRequestMessage httpRequest) { httpRequest.Headers.Add("User-Agent", UserAgent); - var response = await _httpClient.SendAsync(httpRequest).ConfigureAwait(false); + var response = await _httpClient.SendAsync(httpRequest).ConfigureAwait(false); + if (!response.IsSuccessStatusCode) + { + var content = response.Content.ReadAsStringAsync().Result; + } response.EnsureSuccessStatusCode(); return response; } diff --git a/Bynder/Sdk/Query/Asset/ModifyMediaQuery.cs b/Bynder/Sdk/Query/Asset/ModifyMediaQuery.cs index fe571b7..4b6b03d 100644 --- a/Bynder/Sdk/Query/Asset/ModifyMediaQuery.cs +++ b/Bynder/Sdk/Query/Asset/ModifyMediaQuery.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using Bynder.Sdk.Api.Converters; using Bynder.Sdk.Query.Decoder; @@ -41,17 +41,23 @@ public ModifyMediaQuery(string mediaId) [ApiField("copyright")] public string Copyright { get; set; } + /// + /// Published date for the media + /// + [ApiField("datePublished")] + public string PublishedDate { get; set; } + /// /// Indicates if the media is archived /// [ApiField("archive")] - public bool Archive { get; set; } + public bool? Archive { get; set; } /// /// Indicates if the media is public /// [ApiField("isPublic")] - public bool IsPublic { get; set; } + public bool? IsPublic { get; set; } /// /// Metaproperty options to set on the asset. diff --git a/Bynder/Sdk/Query/Decoder/QueryDecoder.cs b/Bynder/Sdk/Query/Decoder/QueryDecoder.cs index 345219b..a945447 100644 --- a/Bynder/Sdk/Query/Decoder/QueryDecoder.cs +++ b/Bynder/Sdk/Query/Decoder/QueryDecoder.cs @@ -1,8 +1,9 @@ -// Copyright (c) Bynder. All rights reserved. +// Copyright (c) Bynder. All rights reserved. // Licensed under the MIT License. See LICENSE file in the project root for full license information. using System; using System.Collections.Generic; +using System.Linq; using System.Reflection; using Bynder.Sdk.Api.Converters; @@ -43,46 +44,41 @@ public IDictionary GetParameters(object query) /// collection to add the converted values private void ConvertProperty(PropertyInfo propertyInfo, object query, IDictionary parameters) { - foreach (var attribute in propertyInfo.GetCustomAttributes(true)) + var apiField = propertyInfo.GetCustomAttributes(true).FirstOrDefault(a => a is ApiField) as ApiField; + if (apiField == null) { - if (attribute is ApiField apiField) - { - object value = propertyInfo.GetValue(query); - if (value == null) - { - return; - } + return; + } - if (apiField.Converter == null) - { - AddParam(parameters, apiField.ApiName, value.ToString()); - } - else if (Activator.CreateInstance(apiField.Converter) is ITypeToStringConverter stringConverter - && stringConverter.CanConvert(propertyInfo.PropertyType)) - { - AddParam(parameters, apiField.ApiName, stringConverter.Convert(value)); - } - else if (Activator.CreateInstance(apiField.Converter) is ITypeToDictionaryConverter dictConverter - && dictConverter.CanConvert(propertyInfo.PropertyType)) - { - foreach (var item in dictConverter.Convert(value)) - { - AddParam(parameters, $"{apiField.ApiName}.{item.Key}", item.Value); - } - } + object value = propertyInfo.GetValue(query); + if (value == null) + { + return; + } - // No need to continue. Only one ApiField attribute per property - return; + if (apiField.Converter == null) + { + AddParam(parameters, apiField.ApiName, value.ToString()); + } + else if (Activator.CreateInstance(apiField.Converter) is ITypeToStringConverter stringConverter + && stringConverter.CanConvert(propertyInfo.PropertyType)) + { + AddParam(parameters, apiField.ApiName, stringConverter.Convert(value)); + } + else if (Activator.CreateInstance(apiField.Converter) is ITypeToDictionaryConverter dictConverter + && dictConverter.CanConvert(propertyInfo.PropertyType)) + { + foreach (var item in dictConverter.Convert(value)) + { + AddParam(parameters, $"{apiField.ApiName}.{item.Key}", item.Value); } } + } private void AddParam(IDictionary parameters, string key, string value) { - if (!string.IsNullOrEmpty(value)) - { - parameters.Add(key, value); - } + parameters.Add(key, value); } } diff --git a/Bynder/Test/Utils/QueryParameterTest.cs b/Bynder/Test/Utils/QueryParameterTest.cs new file mode 100644 index 0000000..3c85a66 --- /dev/null +++ b/Bynder/Test/Utils/QueryParameterTest.cs @@ -0,0 +1,68 @@ +using Bynder.Sdk.Api.Requests; +using Bynder.Sdk.Query.Asset; +using Bynder.Sdk.Query.Decoder; +using Bynder.Sdk.Utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace Bynder.Test.Utils +{ + public class QueryParameterTest + { + [Fact] + public void BooleanPropertiesSetWhenModified() + { + ModifyMediaQuery query = new ModifyMediaQuery("") + { + Archive = false, + }; + + var parametersAsString = GetQueryParameters(query); + Assert.DoesNotContain("isPublic=", parametersAsString); + Assert.Contains("archive=False", parametersAsString); + } + + [Fact] + public void MetaPropertyCanBeDeleted() + { + ModifyMediaQuery query = new ModifyMediaQuery("") + { + MetapropertyOptions = new Dictionary>() + { + { + "TestProp", + [] + } + } + }; + var parametersAsString = GetQueryParameters(query); + Assert.Contains("metaproperty.TestProp=", parametersAsString); + } + + [Fact] + public void StringPropertyCanBeErased() + { + ModifyMediaQuery query = new ModifyMediaQuery("") + { + Name = "", + Copyright = null, + }; + var parametersAsString = GetQueryParameters(query); + + Assert.Contains("name=", parametersAsString); + Assert.DoesNotContain("copyright=", parametersAsString); + } + + private string GetQueryParameters(ModifyMediaQuery query) + { + QueryDecoder queryDecoder = new QueryDecoder(); + var parameters = queryDecoder.GetParameters(query); + return Url.ConvertToQuery(parameters); + } + + } +}