Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v3-tags #97

Merged
merged 10 commits into from
Sep 18, 2024
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -402,4 +402,4 @@ FodyWeavers.xsd
### VisualStudio Patch ###
# Additional files built by Visual Studio

# End of https://www.toptal.com/developers/gitignore/api/visualstudio
# End of https://www.toptal.com/developers/gitignore/api/visualstudio
74 changes: 66 additions & 8 deletions Bynder/Sample/TagsSample.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using System.Collections.Generic;
using Bynder.Sdk.Query.Asset;
using Bynder.Sdk.Model;
using Bynder.Sdk.Service.Asset;

namespace Bynder.Sample
{
Expand All @@ -33,25 +34,82 @@ private TagsSample(Configuration configuration) {

private async Task RunTagsSampleAsync()
{
var assetService = _bynderClient.GetAssetService();
Console.WriteLine("Getting tags with a limit of 10: ");
var tags = await _bynderClient.GetAssetService().GetTagsAsync(new GetTagsQuery{Limit = 10});
var tags = await assetService.GetTagsAsync(new GetTagsQuery{Limit = 10});
foreach(Tag tag in tags){
Console.WriteLine($"Tag Id: {tag.ID}");
Console.WriteLine($"Tag Name: {tag.TagName}");
Console.WriteLine($"Tag MediaCount: {tag.MediaCount}");
}

Console.WriteLine("Enter the media ID to add a tag to: ");
var mediaIdAddTag = Console.ReadLine();
var mediaId = Console.ReadLine();
Console.WriteLine("Enter the tag ID to add to the media: ");
var tagIdAddToMedia = Console.ReadLine();
List<string> mediasAddTag = new List<string>
var tagId = Console.ReadLine();
await assetService.AddTagToMediaAsync(new AddTagToMediaQuery(tagId, [ mediaId ]));

Console.WriteLine("Hit enter to view the asset (it may take a few seconds before the tag is registered)");
Console.ReadKey();
var asset = await assetService.GetMediaInfoAsync(new MediaInformationQuery() { MediaId = mediaId });
ShowTags(asset);

Console.WriteLine("Enter a new tag to add to the same media: ");
var anotherTag = Console.ReadLine();
if (asset.Tags == null)
{
asset.Tags = [anotherTag];
}
else
{
asset.Tags.Add(anotherTag);
}

await assetService.ModifyMediaAsync(new ModifyMediaQuery(mediaId) { Tags = asset.Tags } );

Console.WriteLine("Hit enter to view the asset (it may take a few seconds before the tag is registered)");
Console.ReadKey();
asset = await assetService.GetMediaInfoAsync(new MediaInformationQuery() { MediaId = mediaId });
ShowTags(asset);

Console.WriteLine("Hit enter to remove the tags again");
Console.ReadKey();

foreach (var tag in asset.Tags)
{
var matchingTags = await assetService.GetTagsAsync(new GetTagsQuery() { Keyword = tag });
if (matchingTags.Any())
{
var tagToRemove = matchingTags.FirstOrDefault(t => t.TagName.Equals(tag, StringComparison.InvariantCultureIgnoreCase));
Console.WriteLine($"Removing tag {tagToRemove.TagName} with id {tagToRemove.ID}");
await assetService.RemoveTagFromMediaAsync(tagToRemove.ID, [mediaId]);
}
else
{
Console.WriteLine($"Error: after adding tag with name '{tag}' to asset {mediaId}, tag cannot be found in Bynder");
}
}

Console.WriteLine("Hit enter to view the asset (it may take a few seconds before the tags have been removed)");
Console.ReadKey();

asset = await assetService.GetMediaInfoAsync(new MediaInformationQuery() { MediaId = mediaId });
ShowTags(asset);

}

private async void ShowTags(Media asset)
{
if (asset.Tags?.Any() ?? false)
{
Console.WriteLine($"Media with name {asset.Name} now has the following tags: {string.Join(',', asset.Tags)}");
}
else
{
mediaIdAddTag
};
await _bynderClient.GetAssetService().AddTagToMediaAsync(new AddTagToMediaQuery(tagIdAddToMedia, mediasAddTag));
Console.WriteLine($"Media with name {asset.Name} has no tags");
}
}

private async Task AuthenticateWithOAuth2Async(bool useClientCredentials)
{
if (useClientCredentials)
Expand Down
79 changes: 41 additions & 38 deletions Bynder/Sdk/Query/Asset/GetTagsQuery.cs
Original file line number Diff line number Diff line change
@@ -1,41 +1,44 @@
using Bynder.Sdk.Api.Converters;
using Bynder.Sdk.Model;
using Bynder.Sdk.Query.Decoder;

namespace Bynder.Sdk.Query.Asset
using Bynder.Sdk.Query.Decoder;
namespace Bynder.Sdk.Query.Asset
{
public class GetTagsQuery
{
/// <summary>
/// Maximum number of results.
/// </summary>
[ApiField("limit")]
public int Limit { get; set; }

/// <summary>
/// Offset page for results: return the N-th set of limit-results.
/// </summary>
[ApiField("page")]
public int Page { get; set; }

/// <summary>
/// <para>Order of the returned list of tags. </para>
/// <para>See <see cref="TagsOrderBy"/> for possible values.</para>
/// </summary>
[ApiField("orderBy", Converter = typeof(TagsOrderByConverter))]
public TagsOrderBy OrderBy { get; set; }

/// <summary>
/// Search on matching names.
/// </summary>
[ApiField("keyword")]
public string Keyword { get; set; }

/// <summary>
/// Minimum media count that the returned tags should have.
/// </summary>
[ApiField("mincount")]
public int MinCount { get; set; }

}
}
public class GetTagsQuerySimple
{
/// <summary>
/// Maximum number of results.
/// </summary>
[ApiField("limit")]
public int Limit { get; set; }

/// <summary>
/// Offset page for results: return the N-th set of limit-results.
/// </summary>
[ApiField("page")]
public int Page { get; set; }

/// <summary>
/// <para>Order of the returned list of tags. </para>
/// <para>See <see cref="TagsOrderBy"/> for possible values.</para>
/// </summary>
[ApiField("orderBy", Converter = typeof(TagsOrderByConverter))]
public TagsOrderBy OrderBy { get; set; }

/// <summary>
/// Search on matching names.
/// </summary>
[ApiField("keyword")]
public string Keyword { get; set; }
}
public class GetTagsQuery : GetTagsQuerySimple
{

/// <summary>
/// Minimum media count that the returned tags should have.
/// </summary>
[ApiField("mincount")]
public int MinCount { get; set; }

}
}
9 changes: 8 additions & 1 deletion Bynder/Sdk/Query/Asset/ModifyMediaQuery.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using Bynder.Sdk.Api.Converters;
using Bynder.Sdk.Query.Decoder;

Expand Down Expand Up @@ -68,6 +68,13 @@ public void AddMetapropertyOptions(string metapropertyId, IList<string> optionId
{
MetapropertyOptions.Add(metapropertyId, optionIds);
}

/// <summary>
/// Tags that will be added to the asset
/// </summary>
[ApiField("tags", Converter = typeof(ListConverter))]
public IList<string> Tags { get; set; }

}
}

23 changes: 22 additions & 1 deletion Bynder/Sdk/Service/Asset/AssetService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using Bynder.Sdk.Model;
using Bynder.Sdk.Query.Asset;
using Bynder.Sdk.Query.Upload;
using System.Web;

namespace Bynder.Sdk.Service.Asset
{
Expand Down Expand Up @@ -179,11 +180,17 @@ public async Task<Status> ModifyMediaAsync(ModifyMediaQuery query)
/// <returns>Check <see cref="IAssetService"/> for more information</returns>
public async Task<IList<Tag>> GetTagsAsync(GetTagsQuery query)
{
var queryToUse = string.IsNullOrEmpty(query.Keyword) ? query : new GetTagsQuerySimple() {
Keyword = query.Keyword,
Limit = query.Limit,
OrderBy = query.OrderBy,
Page = query.Page
};
return await _requestSender.SendRequestAsync(new ApiRequest<IList<Tag>>
{
Path = "/api/v4/tags/",
HTTPMethod = HttpMethod.Get,
Query = query
Query = queryToUse
}).ConfigureAwait(false);
}

Expand All @@ -201,6 +208,20 @@ public async Task<Status> AddTagToMediaAsync(AddTagToMediaQuery query)
}).ConfigureAwait(false);
}

/// <summary>
/// Check <see cref="IAssetService"/> for more information
/// </summary>
/// <returns>Check <see cref="IAssetService"/> for more information</returns>
public async Task<Status> RemoveTagFromMediaAsync(string tagId, IEnumerable<string> assetIds)
{
var encodedIdList = HttpUtility.UrlEncode(string.Join(",", assetIds));
return await _requestSender.SendRequestAsync(new ApiRequest
{
Path = $"/api/v4/tags/{tagId}/media/?deleteIds={encodedIdList}",
HTTPMethod = HttpMethod.Delete,
}).ConfigureAwait(false);
}

/// <summary>
/// Create an asset usage operation to track usage of Bynder assets in third party applications.
/// </summary>
Expand Down
9 changes: 9 additions & 0 deletions Bynder/Sdk/Service/Asset/IAssetService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,15 @@ public interface IAssetService
/// <exception cref="HttpRequestException">Can be thrown when requests to server can't be completed or HTTP code returned by server is an error</exception>
Task<Status> AddTagToMediaAsync(AddTagToMediaQuery query);

/// <summary>
/// Remove tags from asset
/// </summary>
/// <param name="tagId">Id of the tag to remove</param>
/// <param name="assetIds">Ids of the assets from which the tag should be removed</param>
/// <returns>Task representing the upload</returns>
/// <exception cref="HttpRequestException">Can be thrown when requests to server can't be completed or HTTP code returned by server is an error</exception>
Task<Status> RemoveTagFromMediaAsync(string tagId, IEnumerable<string> assetIds);

/// <summary>
/// Create an asset usage operation to track usage of Bynder assets in third party applications.
/// </summary>
Expand Down
19 changes: 19 additions & 0 deletions Bynder/Test/Service/Asset/AssetServiceTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,25 @@ public async Task GetTagsCallsRequestSenderWithValidRequest()
));
}

[Fact]
public async Task GetTagsByKeywordCallsRequestSenderWithValidRequest()
{
var result = new Status { Message = "Accepted", StatusCode = 202 };
_apiRequestSenderMock.Setup(sender => sender.SendRequestAsync(It.IsAny<ApiRequest>()))
.ReturnsAsync(result);
var query = new GetTagsQuery { Keyword = "test" };
await _assetService.GetTagsAsync(query);

_apiRequestSenderMock.Verify(sender => sender.SendRequestAsync(
It.Is<ApiRequest<IList<Tag>>>(req =>
req.Path == "/api/v4/tags/"
&& req.HTTPMethod == HttpMethod.Get
&& req.Query is GetTagsQuerySimple
&& (req.Query as GetTagsQuerySimple).Keyword == query.Keyword
)
));
}

[Fact]
public async Task AddTagToMediaCallsRequestSenderWithValidRequest()
{
Expand Down