diff --git a/back/Dockerfile.dev b/back/Dockerfile.dev
index 4b37417b..71a2f5bd 100644
--- a/back/Dockerfile.dev
+++ b/back/Dockerfile.dev
@@ -17,6 +17,7 @@ RUN dotnet restore
WORKDIR /kyoo
EXPOSE 5000
ENV DOTNET_USE_POLLING_FILE_WATCHER 1
-HEALTHCHECK --interval=5s CMD curl --fail http://localhost:5000/health || exit
+# HEALTHCHECK --interval=5s CMD curl --fail http://localhost:5000/health || exit
+HEALTHCHECK CMD true
CMD dotnet watch run --no-restore --project /app/src/Kyoo.Host
diff --git a/back/src/Kyoo.Abstractions/Models/News.cs b/back/src/Kyoo.Abstractions/Models/News.cs
new file mode 100644
index 00000000..feb763f4
--- /dev/null
+++ b/back/src/Kyoo.Abstractions/Models/News.cs
@@ -0,0 +1,147 @@
+// 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.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+
+namespace Kyoo.Abstractions.Models
+{
+ ///
+ /// The type of item, ether a show, a movie or a collection.
+ ///
+ public enum NewsKind
+ {
+ ///
+ /// The is an .
+ ///
+ Episode,
+
+ ///
+ /// The is a Movie.
+ ///
+ Movie,
+ }
+
+ ///
+ /// A new item
+ ///
+ public class News : IResource, IMetadata, IThumbnails, IAddedDate
+ {
+ ///
+ public int Id { get; set; }
+
+ ///
+ [MaxLength(256)]
+ public string Slug { get; set; }
+
+ ///
+ /// The title of this show.
+ ///
+ public string? Name { get; set; }
+
+ ///
+ /// A catchphrase for this movie.
+ ///
+ public string? Tagline { get; set; }
+
+ ///
+ /// The list of alternative titles of this show.
+ ///
+ public string[] Aliases { get; set; } = Array.Empty();
+
+ ///
+ /// The path of the movie video file.
+ ///
+ public string Path { get; set; }
+
+ ///
+ /// The summary of this show.
+ ///
+ public string? Overview { get; set; }
+
+ ///
+ /// A list of tags that match this movie.
+ ///
+ public string[] Tags { get; set; } = Array.Empty();
+
+ ///
+ /// The list of genres (themes) this show has.
+ ///
+ public Genre[] Genres { get; set; } = Array.Empty();
+
+ ///
+ /// Is this show airing, not aired yet or finished?
+ ///
+ public Status? Status { get; set; }
+
+ ///
+ /// The date this movie aired.
+ ///
+ public DateTime? AirDate { get; set; }
+
+ ///
+ public DateTime AddedDate { get; set; }
+
+ ///
+ public Image? Poster { get; set; }
+
+ ///
+ public Image? Thumbnail { get; set; }
+
+ ///
+ public Image? Logo { get; set; }
+
+ ///
+ /// A video of a few minutes that tease the content.
+ ///
+ public string? Trailer { get; set; }
+
+ ///
+ public Dictionary ExternalId { get; set; } = new();
+
+ ///
+ /// The season in witch this episode is in.
+ ///
+ public int? SeasonNumber { get; set; }
+
+ ///
+ /// The number of this episode in it's season.
+ ///
+ public int? EpisodeNumber { get; set; }
+
+ ///
+ /// The absolute number of this episode. It's an episode number that is not reset to 1 after a new season.
+ ///
+ public int? AbsoluteNumber { get; set; }
+
+ ///
+ /// Is the item a a movie or an episode?
+ ///
+ public NewsKind Kind { get; set; }
+
+ ///
+ /// Links to watch this movie.
+ ///
+ public VideoLinks Links => new()
+ {
+ Direct = $"/video/{Kind.ToString().ToLower()}/{Slug}/direct",
+ Hls = $"/video/{Kind.ToString().ToLower()}/{Slug}/master.m3u8",
+ };
+ }
+}
diff --git a/back/src/Kyoo.Abstractions/Models/Resources/Episode.cs b/back/src/Kyoo.Abstractions/Models/Resources/Episode.cs
index 24638cc9..6bb64121 100644
--- a/back/src/Kyoo.Abstractions/Models/Resources/Episode.cs
+++ b/back/src/Kyoo.Abstractions/Models/Resources/Episode.cs
@@ -23,7 +23,6 @@ using System.Linq;
using System.Text.RegularExpressions;
using EntityFrameworkCore.Projectables;
using JetBrains.Annotations;
-using Kyoo.Abstractions.Controllers;
using Kyoo.Abstractions.Models.Attributes;
namespace Kyoo.Abstractions.Models
diff --git a/back/src/Kyoo.Abstractions/Models/Resources/Interfaces/IThumbnails.cs b/back/src/Kyoo.Abstractions/Models/Resources/Interfaces/IThumbnails.cs
index 277bde24..a692e52b 100644
--- a/back/src/Kyoo.Abstractions/Models/Resources/Interfaces/IThumbnails.cs
+++ b/back/src/Kyoo.Abstractions/Models/Resources/Interfaces/IThumbnails.cs
@@ -20,7 +20,6 @@ using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
-using Kyoo.Abstractions.Models.Attributes;
namespace Kyoo.Abstractions.Models
{
@@ -60,24 +59,6 @@ namespace Kyoo.Abstractions.Models
[MaxLength(32)]
public string Blurhash { get; set; }
- [SerializeIgnore]
- public string Path { private get; set; }
-
- ///
- /// The url to retrieve the low quality image.
- ///
- public string Low => $"{Path}?quality=low";
-
- ///
- /// The url to retrieve the medium quality image.
- ///
- public string Medium => $"{Path}?quality=medium";
-
- ///
- /// The url to retrieve the high quality image.
- ///
- public string High => $"{Path}?quality=high";
-
public Image(string source, string? blurhash = null)
{
Source = source;
diff --git a/back/src/Kyoo.Core/Controllers/Repositories/NewsRepository.cs b/back/src/Kyoo.Core/Controllers/Repositories/NewsRepository.cs
new file mode 100644
index 00000000..708ead3b
--- /dev/null
+++ b/back/src/Kyoo.Core/Controllers/Repositories/NewsRepository.cs
@@ -0,0 +1,72 @@
+// 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.Collections.Generic;
+using System.Threading.Tasks;
+using Kyoo.Abstractions.Controllers;
+using Kyoo.Abstractions.Models;
+using Kyoo.Postgresql;
+
+namespace Kyoo.Core.Controllers
+{
+ ///
+ /// A local repository to handle shows
+ ///
+ public class NewsRepository : LocalRepository
+ {
+ ///
+ protected override Sort DefaultSort => new Sort.By(x => x.AddedDate);
+
+ public NewsRepository(DatabaseContext database, IThumbnailsManager thumbs)
+ : base(database, thumbs)
+ { }
+
+ ///
+ public override Task> Search(string query)
+ => throw new InvalidOperationException();
+
+ ///
+ public override Task Create(News obj)
+ => throw new InvalidOperationException();
+
+ ///
+ public override Task CreateIfNotExists(News obj)
+ => throw new InvalidOperationException();
+
+ ///
+ public override Task Edit(News edited)
+ => throw new InvalidOperationException();
+
+ ///
+ public override Task Patch(int id, Func> patch)
+ => throw new InvalidOperationException();
+
+ ///
+ public override Task Delete(int id)
+ => throw new InvalidOperationException();
+
+ ///
+ public override Task Delete(string slug)
+ => throw new InvalidOperationException();
+
+ ///
+ public override Task Delete(News obj)
+ => throw new InvalidOperationException();
+ }
+}
diff --git a/back/src/Kyoo.Core/CoreModule.cs b/back/src/Kyoo.Core/CoreModule.cs
index fcf16594..72c05456 100644
--- a/back/src/Kyoo.Core/CoreModule.cs
+++ b/back/src/Kyoo.Core/CoreModule.cs
@@ -59,6 +59,7 @@ namespace Kyoo.Core
builder.RegisterRepository();
builder.RegisterRepository();
builder.RegisterRepository();
+ builder.RegisterType().OwnedByLifetimeScope();
}
///
diff --git a/back/src/Kyoo.Core/Views/Helper/Serializers/JsonSerializerContract.cs b/back/src/Kyoo.Core/Views/Helper/Serializers/JsonSerializerContract.cs
index 76aacdea..d9ca24dc 100644
--- a/back/src/Kyoo.Core/Views/Helper/Serializers/JsonSerializerContract.cs
+++ b/back/src/Kyoo.Core/Views/Helper/Serializers/JsonSerializerContract.cs
@@ -58,7 +58,7 @@ namespace Kyoo.Core.Api
{
property.ShouldSerialize = _ =>
{
- ICollection fields = (ICollection)_httpContextAccessor.HttpContext!.Items["fields"]!;
+ ICollection? fields = (ICollection)_httpContextAccessor.HttpContext!.Items["fields"]!;
if (fields == null)
return false;
return fields.Contains(member.Name);
diff --git a/back/src/Kyoo.Core/Views/Resources/NewsApi.cs b/back/src/Kyoo.Core/Views/Resources/NewsApi.cs
new file mode 100644
index 00000000..e82e832b
--- /dev/null
+++ b/back/src/Kyoo.Core/Views/Resources/NewsApi.cs
@@ -0,0 +1,61 @@
+// 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.Collections.Generic;
+using System.Threading.Tasks;
+using Kyoo.Abstractions.Controllers;
+using Kyoo.Abstractions.Models;
+using Kyoo.Abstractions.Models.Attributes;
+using Kyoo.Abstractions.Models.Permissions;
+using Kyoo.Core.Controllers;
+using Microsoft.AspNetCore.Mvc;
+using static Kyoo.Abstractions.Models.Utils.Constants;
+
+namespace Kyoo.Core.Api
+{
+ ///
+ /// List new items added to kyoo.
+ ///
+ [Route("news")]
+ [Route("new", Order = AlternativeRoute)]
+ [ApiController]
+ [ResourceView]
+ [PartialPermission("LibraryItem")]
+ [ApiDefinition("News", Group = ResourcesGroup)]
+ public class NewsApi : BaseApi
+ {
+ private readonly NewsRepository _news;
+
+ public NewsApi(NewsRepository news)
+ {
+ _news = news;
+ }
+
+ public async Task>> GetAll(
+ [FromQuery] Dictionary where,
+ [FromQuery] Pagination pagination)
+ {
+ ICollection resources = await _news.GetNews(
+ ApiHelper.ParseWhere(where),
+ pagination
+ );
+
+ return Page(resources, pagination.Limit);
+ }
+ }
+}
diff --git a/back/src/Kyoo.Postgresql/DatabaseContext.cs b/back/src/Kyoo.Postgresql/DatabaseContext.cs
index 3e7232be..557ca197 100644
--- a/back/src/Kyoo.Postgresql/DatabaseContext.cs
+++ b/back/src/Kyoo.Postgresql/DatabaseContext.cs
@@ -100,6 +100,14 @@ namespace Kyoo.Postgresql
///
public DbSet LibraryItems { get; set; }
+ ///
+ /// The list of new items (episodes and movies).
+ ///
+ ///
+ /// This set is ready only, on most database this will be a view.
+ ///
+ public DbSet News { get; set; }
+
///
/// Add a many to many link between two resources.
///
@@ -283,6 +291,7 @@ namespace Kyoo.Postgresql
.UsingEntity(x => x.ToTable(LinkName()));
_HasMetadata(modelBuilder);
+ _HasMetadata(modelBuilder);
_HasMetadata(modelBuilder);
_HasMetadata(modelBuilder);
_HasMetadata(modelBuilder);
@@ -292,6 +301,7 @@ namespace Kyoo.Postgresql
_HasMetadata(modelBuilder);
_HasImages(modelBuilder);
+ _HasImages(modelBuilder);
_HasImages(modelBuilder);
_HasImages(modelBuilder);
_HasImages(modelBuilder);
@@ -300,6 +310,7 @@ namespace Kyoo.Postgresql
_HasImages(modelBuilder);
_HasAddedDate(modelBuilder);
+ _HasAddedDate(modelBuilder);
_HasAddedDate(modelBuilder);
_HasAddedDate(modelBuilder);
_HasAddedDate(modelBuilder);
@@ -347,6 +358,8 @@ namespace Kyoo.Postgresql
.Ignore(x => x.Links);
modelBuilder.Entity()
.Ignore(x => x.Links);
+ modelBuilder.Entity()
+ .Ignore(x => x.Links);
}
///
diff --git a/back/src/Kyoo.Postgresql/PostgresContext.cs b/back/src/Kyoo.Postgresql/PostgresContext.cs
index a55e8773..520758e7 100644
--- a/back/src/Kyoo.Postgresql/PostgresContext.cs
+++ b/back/src/Kyoo.Postgresql/PostgresContext.cs
@@ -51,6 +51,7 @@ namespace Kyoo.Postgresql
NpgsqlConnection.GlobalTypeMapper.MapEnum();
NpgsqlConnection.GlobalTypeMapper.MapEnum();
NpgsqlConnection.GlobalTypeMapper.MapEnum();
+ NpgsqlConnection.GlobalTypeMapper.MapEnum();
}
///
@@ -104,6 +105,7 @@ namespace Kyoo.Postgresql
modelBuilder.HasPostgresEnum();
modelBuilder.HasPostgresEnum();
modelBuilder.HasPostgresEnum();
+ modelBuilder.HasPostgresEnum();
modelBuilder.HasDbFunction(typeof(DatabaseContext).GetMethod(nameof(MD5))!)
.HasTranslation(args =>