From 4368f0cbe5eb3ef2eb2bbc6068ed174049bbfd67 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Sat, 28 Oct 2023 18:23:50 +0200 Subject: [PATCH] Setup meilsearch (part 1) --- .env.example | 2 +- back/Kyoo.sln | 6 ++ .../Kyoo.Abstractions/Models/SearchResult.cs | 38 +------- .../Kyoo.Meilisearch/Kyoo.Meilisearch.csproj | 16 ++++ .../src/Kyoo.Meilisearch/MeilisearchModule.cs | 95 +++++++++++++++++++ back/src/Kyoo.Meilisearch/SearchManager.cs | 58 +++++++++++ .../Kyoo.Postgresql/Kyoo.Postgresql.csproj | 2 +- 7 files changed, 179 insertions(+), 38 deletions(-) create mode 100644 back/src/Kyoo.Meilisearch/Kyoo.Meilisearch.csproj create mode 100644 back/src/Kyoo.Meilisearch/MeilisearchModule.cs create mode 100644 back/src/Kyoo.Meilisearch/SearchManager.cs diff --git a/.env.example b/.env.example index fa738787..715d611c 100644 --- a/.env.example +++ b/.env.example @@ -34,7 +34,7 @@ POSTGRES_DB=kyooDB POSTGRES_SERVER=postgres POSTGRES_PORT=5432 -MEILI_HTTP_ADDR="http://meilisearch:7700" +MEILI_HOST="http://meilisearch:7700" MEILI_MASTER_KEY="ghvjkgisbgkbgskegblfqbgjkebbhgwkjfb" # vi: ft=sh diff --git a/back/Kyoo.sln b/back/Kyoo.sln index bffe15ca..49a66538 100644 --- a/back/Kyoo.sln +++ b/back/Kyoo.sln @@ -15,6 +15,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{FEAE1B0E EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Host", "src\Kyoo.Host\Kyoo.Host.csproj", "{0938459E-2E2B-457F-8120-7D8CA93866A6}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Meilisearch", "src\Kyoo.Meilisearch\Kyoo.Meilisearch.csproj", "{F8E6018A-FD51-40EB-99FF-A26BA59F2762}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -61,6 +63,10 @@ Global {0938459E-2E2B-457F-8120-7D8CA93866A6}.Debug|Any CPU.Build.0 = Debug|Any CPU {0938459E-2E2B-457F-8120-7D8CA93866A6}.Release|Any CPU.ActiveCfg = Release|Any CPU {0938459E-2E2B-457F-8120-7D8CA93866A6}.Release|Any CPU.Build.0 = Release|Any CPU + {F8E6018A-FD51-40EB-99FF-A26BA59F2762}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F8E6018A-FD51-40EB-99FF-A26BA59F2762}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F8E6018A-FD51-40EB-99FF-A26BA59F2762}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F8E6018A-FD51-40EB-99FF-A26BA59F2762}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {0C8AA7EA-E723-4532-852F-35AA4E8AFED5} = {FEAE1B0E-D797-470F-9030-0EF743575ECC} diff --git a/back/src/Kyoo.Abstractions/Models/SearchResult.cs b/back/src/Kyoo.Abstractions/Models/SearchResult.cs index f10983eb..b47a4ad0 100644 --- a/back/src/Kyoo.Abstractions/Models/SearchResult.cs +++ b/back/src/Kyoo.Abstractions/Models/SearchResult.cs @@ -23,46 +23,12 @@ namespace Kyoo.Abstractions.Models /// /// Results of a search request. /// - public class SearchResult + public class SearchPage : Page + where T : class, IResource { /// /// The query of the search request. /// public string Query { get; init; } - - /// - /// The collections that matched the search. - /// - public ICollection Collections { get; init; } - - /// - /// The items that matched the search. - /// - public ICollection Items { get; init; } - - /// - /// The movies that matched the search. - /// - public ICollection Movies { get; init; } - - /// - /// The shows that matched the search. - /// - public ICollection Shows { get; init; } - - /// - /// The episodes that matched the search. - /// - public ICollection Episodes { get; init; } - - /// - /// The people that matched the search. - /// - public ICollection People { get; init; } - - /// - /// The studios that matched the search. - /// - public ICollection Studios { get; init; } } } diff --git a/back/src/Kyoo.Meilisearch/Kyoo.Meilisearch.csproj b/back/src/Kyoo.Meilisearch/Kyoo.Meilisearch.csproj new file mode 100644 index 00000000..06258288 --- /dev/null +++ b/back/src/Kyoo.Meilisearch/Kyoo.Meilisearch.csproj @@ -0,0 +1,16 @@ + + + enable + enable + Kyoo.Meilisearch + + + + + + + + + + + diff --git a/back/src/Kyoo.Meilisearch/MeilisearchModule.cs b/back/src/Kyoo.Meilisearch/MeilisearchModule.cs new file mode 100644 index 00000000..faa16057 --- /dev/null +++ b/back/src/Kyoo.Meilisearch/MeilisearchModule.cs @@ -0,0 +1,95 @@ +// 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 Autofac; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Meilisearch; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; + +namespace Kyoo.Meiliseach +{ + public class MeilisearchModule : IPlugin + { + /// + public string Name => "Meilisearch"; + + private readonly IConfiguration _configuration; + + public MeilisearchModule(IConfiguration configuration) + { + _configuration = configuration; + } + + /// + /// Init meilisearch indexes. + /// + /// The service list to retrieve the meilisearch client + public static async Task Initialize(IServiceProvider provider) + { + MeilisearchClient client = provider.GetRequiredService(); + + await _CreateIndex(client, "items", new Settings() + { + SearchableAttributes = new[] + { + nameof(LibraryItem.Name), + nameof(LibraryItem.Slug), + nameof(LibraryItem.Aliases), + nameof(LibraryItem.Path), + nameof(LibraryItem.Tags), + // Overview could be included as well but I think it would be better without. + }, + FilterableAttributes = new[] + { + nameof(LibraryItem.Genres), + nameof(LibraryItem.Status), + nameof(LibraryItem.AirDate), + nameof(LibraryItem.StudioID), + }, + SortableAttributes = new[] + { + nameof(LibraryItem.AirDate), + nameof(LibraryItem.AddedDate), + nameof(LibraryItem.Kind), + }, + DisplayedAttributes = new[] { nameof(LibraryItem.Id) }, + // TODO: Add stopwords + // TODO: Extend default ranking to add ratings. + }); + } + + private static async Task _CreateIndex(MeilisearchClient client, string index, Settings opts) + { + TaskInfo task = await client.CreateIndexAsync(index, "Id"); + await client.WaitForTaskAsync(task.TaskUid); + await client.Index(index).UpdateSettingsAsync(opts); + } + + /// + public void Configure(ContainerBuilder builder) + { + builder.RegisterInstance(new MeilisearchClient( + _configuration.GetValue("MEILI_HOST", "http://meilisearch:7700"), + _configuration.GetValue("MEILI_MASTER_KEY") + )).InstancePerLifetimeScope(); + builder.RegisterType().InstancePerLifetimeScope(); + } + } +} diff --git a/back/src/Kyoo.Meilisearch/SearchManager.cs b/back/src/Kyoo.Meilisearch/SearchManager.cs new file mode 100644 index 00000000..48081572 --- /dev/null +++ b/back/src/Kyoo.Meilisearch/SearchManager.cs @@ -0,0 +1,58 @@ +// 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 Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Utils; +using Meilisearch; + +namespace Kyoo.Meiliseach; + +public class SearchManager +{ + private readonly MeilisearchClient _client; + private readonly ILibraryManager _libraryManager; + + public SearchManager(MeilisearchClient client, ILibraryManager libraryManager) + { + _client = client; + _libraryManager = libraryManager; + + _libraryManager.Movies.OnCreated += (x) => _CreateOrUpdate("items", x); + _libraryManager.Movies.OnEdited += (x) => _CreateOrUpdate("items", x); + _libraryManager.Movies.OnDeleted += (x) => _Delete("items", x.Id); + } + + private Task _CreateOrUpdate(string index, IResource item) + { + return _client.Index(index).AddDocumentsAsync(new[] { item }); + } + + private Task _Delete(string index, int id) + { + return _client.Index(index).DeleteOneDocumentAsync(id); + } + + private async Task> _Search(string index, string? query, Include? include = default) + { + ISearchable res = await _client.Index(index).SearchAsync(query, new SearchQuery() + { + }); + throw new NotImplementedException(); + } +} diff --git a/back/src/Kyoo.Postgresql/Kyoo.Postgresql.csproj b/back/src/Kyoo.Postgresql/Kyoo.Postgresql.csproj index 64a1fd92..529c7338 100644 --- a/back/src/Kyoo.Postgresql/Kyoo.Postgresql.csproj +++ b/back/src/Kyoo.Postgresql/Kyoo.Postgresql.csproj @@ -22,6 +22,6 @@ - +