diff --git a/back/src/Kyoo.Abstractions/Controllers/IScanner.cs b/back/src/Kyoo.Abstractions/Controllers/IScanner.cs new file mode 100644 index 00000000..62f14f9f --- /dev/null +++ b/back/src/Kyoo.Abstractions/Controllers/IScanner.cs @@ -0,0 +1,27 @@ +// Kyoo - A portable and vast media library solution. +// Copyright (c) Kyoo. +// +// See AUTHORS.md and LICENSE file in the project root for full license information. +// +// Kyoo is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// Kyoo is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Kyoo. If not, see . + +using System; +using System.Threading.Tasks; + +namespace Kyoo.Abstractions.Controllers; + +public interface IScanner +{ + Task SendRefreshRequest(string kind, Guid id); +} diff --git a/back/src/Kyoo.Core/Views/Resources/EpisodeApi.cs b/back/src/Kyoo.Core/Views/Resources/EpisodeApi.cs index 93b3063c..9fb268a0 100644 --- a/back/src/Kyoo.Core/Views/Resources/EpisodeApi.cs +++ b/back/src/Kyoo.Core/Views/Resources/EpisodeApi.cs @@ -41,6 +41,29 @@ namespace Kyoo.Core.Api; public class EpisodeApi(ILibraryManager libraryManager) : TranscoderApi(libraryManager.Episodes) { + /// + /// Refresh + /// + /// + /// Ask a metadata refresh. + /// + /// The ID or slug of the . + /// Nothing + /// No episode with the given ID or slug could be found. + [HttpPost("{identifier:id}/refresh")] + [PartialPermission(Kind.Write)] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task Refresh(Identifier identifier, [FromServices] IScanner scanner) + { + Guid id = await identifier.Match( + id => Task.FromResult(id), + async slug => (await libraryManager.Episodes.Get(slug)).Id + ); + await scanner.SendRefreshRequest(nameof(Episode), id); + return NoContent(); + } + /// /// Get episode's show /// diff --git a/back/src/Kyoo.RabbitMq/RabbitMqModule.cs b/back/src/Kyoo.RabbitMq/RabbitMqModule.cs index aba89bb2..45ff8c39 100644 --- a/back/src/Kyoo.RabbitMq/RabbitMqModule.cs +++ b/back/src/Kyoo.RabbitMq/RabbitMqModule.cs @@ -16,6 +16,7 @@ // You should have received a copy of the GNU General Public License // along with Kyoo. If not, see . +using Kyoo.Abstractions.Controllers; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -41,5 +42,6 @@ public static class RabbitMqModule return factory.CreateConnection(); }); builder.Services.AddSingleton(); + builder.Services.AddSingleton(); } } diff --git a/back/src/Kyoo.RabbitMq/ScannerProducer.cs b/back/src/Kyoo.RabbitMq/ScannerProducer.cs new file mode 100644 index 00000000..71c8f97a --- /dev/null +++ b/back/src/Kyoo.RabbitMq/ScannerProducer.cs @@ -0,0 +1,71 @@ +// Kyoo - A portable and vast media library solution. +// Copyright (c) Kyoo. +// +// See AUTHORS.md and LICENSE file in the project root for full license information. +// +// Kyoo is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// Kyoo is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Kyoo. If not, see . + +using System.Text; +using System.Text.Json; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Utils; +using RabbitMQ.Client; + +namespace Kyoo.RabbitMq; + +public class ScannerProducer : IScanner +{ + private readonly IModel _channel; + + public ScannerProducer(IConnection rabbitConnection) + { + _channel = rabbitConnection.CreateModel(); + _channel.QueueDeclare("scanner", exclusive: false, autoDelete: false); + } + + private IRepository.ResourceEventHandler _Publish( + string exchange, + string type, + string action + ) + where T : IResource, IQuery + { + return (T resource) => + { + Message message = + new() + { + Action = action, + Type = type, + Value = resource, + }; + _channel.BasicPublish( + exchange, + routingKey: message.AsRoutingKey(), + body: message.AsBytes() + ); + return Task.CompletedTask; + }; + } + + public Task SendRefreshRequest(string kind, Guid id) + { + var message = new { Action = "refresh", Kind = kind.ToLowerInvariant(), Id = id }; + var body = Encoding.UTF8.GetBytes(JsonSerializer.Serialize(message, Utility.JsonOptions)); + _channel.BasicPublish("", routingKey: "scanner", body: body); + return Task.CompletedTask; + } +} +