mirror of https://github.com/Squidex/squidex.git
6 changed files with 158 additions and 4 deletions
@ -0,0 +1,100 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.Azure.CognitiveServices.Vision.ComputerVision; |
||||
|
using Microsoft.Azure.CognitiveServices.Vision.ComputerVision.Models; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using Squidex.Domain.Apps.Core.Assets; |
||||
|
using Squidex.Domain.Apps.Entities.Assets; |
||||
|
using Squidex.Domain.Apps.Entities.Assets.Commands; |
||||
|
using Squidex.Infrastructure.Json.Objects; |
||||
|
using Squidex.Log; |
||||
|
|
||||
|
namespace Squidex.Extensions.Assets.Azure |
||||
|
{ |
||||
|
public sealed class AzureMetadataSource : IAssetMetadataSource |
||||
|
{ |
||||
|
private const long MaxSize = 5 * 1025 * 1024; |
||||
|
private readonly ISemanticLog log; |
||||
|
private readonly ComputerVisionClient client; |
||||
|
private readonly char[] trimChars = |
||||
|
{ |
||||
|
' ', |
||||
|
'_', |
||||
|
'-' |
||||
|
}; |
||||
|
private readonly List<VisualFeatureTypes?> features = new List<VisualFeatureTypes?> |
||||
|
{ |
||||
|
VisualFeatureTypes.Categories, |
||||
|
VisualFeatureTypes.Description, |
||||
|
VisualFeatureTypes.Color |
||||
|
}; |
||||
|
|
||||
|
public int Order => int.MaxValue; |
||||
|
|
||||
|
public AzureMetadataSource(IOptions<AzureMetadataSourceOptions> options, ISemanticLog log) |
||||
|
{ |
||||
|
client = new ComputerVisionClient(new ApiKeyServiceClientCredentials(options.Value.ApiKey)) |
||||
|
{ |
||||
|
Endpoint = options.Value.Endpoint |
||||
|
}; |
||||
|
|
||||
|
this.log = log; |
||||
|
} |
||||
|
|
||||
|
public async Task EnhanceAsync(UploadAssetCommand command) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
if (command.Type == AssetType.Image && command.File.FileSize <= MaxSize) |
||||
|
{ |
||||
|
using (var stream = command.File.OpenRead()) |
||||
|
{ |
||||
|
var result = await client.AnalyzeImageInStreamAsync(stream, features); |
||||
|
|
||||
|
command.Tags ??= new HashSet<string>(); |
||||
|
|
||||
|
if (result.Color?.DominantColorForeground != null) |
||||
|
{ |
||||
|
command.Tags.Add($"color/{result.Color.DominantColorForeground.Trim(trimChars).ToLowerInvariant()}"); |
||||
|
} |
||||
|
|
||||
|
if (result.Categories != null) |
||||
|
{ |
||||
|
foreach (var category in result.Categories.OrderByDescending(x => x.Score).Take(3)) |
||||
|
{ |
||||
|
command.Tags.Add($"category/{category.Name.Trim(trimChars).ToLowerInvariant()}"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
var description = result.Description?.Captions?.OrderByDescending(x => x.Confidence)?.FirstOrDefault()?.Text; |
||||
|
|
||||
|
if (description != null) |
||||
|
{ |
||||
|
command.Metadata["caption"] = JsonValue.Create(description); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
log.LogError(ex, w => w |
||||
|
.WriteProperty("action", "EnrichWithAssure") |
||||
|
.WriteProperty("status", "Failed")); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public IEnumerable<string> Format(IAssetEntity asset) |
||||
|
{ |
||||
|
yield break; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
namespace Squidex.Extensions.Assets.Azure |
||||
|
{ |
||||
|
public sealed class AzureMetataSourceOptions |
||||
|
{ |
||||
|
public string Endpoint { get; set; } |
||||
|
|
||||
|
public string ApiKey { get; set; } |
||||
|
|
||||
|
public bool IsConfigured() |
||||
|
{ |
||||
|
return |
||||
|
!string.IsNullOrWhiteSpace(Endpoint) && |
||||
|
!string.IsNullOrWhiteSpace(ApiKey); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,30 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using Microsoft.Extensions.Configuration; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using Squidex.Domain.Apps.Entities.Assets; |
||||
|
using Squidex.Infrastructure.Plugins; |
||||
|
|
||||
|
namespace Squidex.Extensions.Assets.Azure |
||||
|
{ |
||||
|
public sealed class AzureMetadataSourcePlugin : IPlugin |
||||
|
{ |
||||
|
public void ConfigureServices(IServiceCollection services, IConfiguration config) |
||||
|
{ |
||||
|
var options = config.GetSection("assets:azureCognitive").Get<AzureMetadataSourceOptions>(); |
||||
|
|
||||
|
if (options.IsConfigured()) |
||||
|
{ |
||||
|
services.AddSingleton<IAssetMetadataSource, AzureMetadataSource>(); |
||||
|
services.AddSingleton(Options.Create(options)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue