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 @@
-
+