Add runtime on the back

This commit is contained in:
Zoe Roux 2023-10-31 23:47:08 +01:00
parent 15a4280a36
commit c4f1e420f8
11 changed files with 95 additions and 24 deletions

View File

@ -99,6 +99,11 @@ namespace Kyoo.Abstractions.Models
/// </summary> /// </summary>
public int Rating { get; set; } public int Rating { get; set; }
/// <summary>
/// How long is this movie? (in minutes)
/// </summary>
public int? Runtime { get; set; }
/// <summary> /// <summary>
/// The date this show started airing. It can be null if this is unknown. /// The date this show started airing. It can be null if this is unknown.
/// </summary> /// </summary>

View File

@ -93,7 +93,12 @@ namespace Kyoo.Abstractions.Models
/// <summary> /// <summary>
/// How well this item is rated? (from 0 to 100). /// How well this item is rated? (from 0 to 100).
/// </summary> /// </summary>
public int Rating { get; set; } public int? Rating { get; set; }
/// <summary>
/// How long is this movie or episode? (in minutes)
/// </summary>
public int Runtime { get; set; }
/// <summary> /// <summary>
/// The date this movie aired. /// The date this movie aired.

View File

@ -133,6 +133,11 @@ namespace Kyoo.Abstractions.Models
/// </summary> /// </summary>
public string? Overview { get; set; } public string? Overview { get; set; }
/// <summary>
/// How long is this episode? (in minutes)
/// </summary>
public int Runtime { get; set; }
/// <summary> /// <summary>
/// The release date of this episode. It can be null if unknown. /// The release date of this episode. It can be null if unknown.
/// </summary> /// </summary>

View File

@ -82,6 +82,11 @@ namespace Kyoo.Abstractions.Models
/// </summary> /// </summary>
public int Rating { get; set; } public int Rating { get; set; }
/// <summary>
/// How long is this movie? (in minutes)
/// </summary>
public int Runtime { get; set; }
/// <summary> /// <summary>
/// The date this movie aired. /// The date this movie aired.
/// </summary> /// </summary>

View File

@ -61,6 +61,7 @@ namespace Kyoo.Meiliseach
CamelCase.ConvertName(nameof(LibraryItem.AirDate)), CamelCase.ConvertName(nameof(LibraryItem.AirDate)),
CamelCase.ConvertName(nameof(LibraryItem.AddedDate)), CamelCase.ConvertName(nameof(LibraryItem.AddedDate)),
CamelCase.ConvertName(nameof(LibraryItem.Rating)), CamelCase.ConvertName(nameof(LibraryItem.Rating)),
CamelCase.ConvertName(nameof(LibraryItem.Runtime)),
}, },
DisplayedAttributes = new[] DisplayedAttributes = new[]
{ {

View File

@ -121,6 +121,10 @@ namespace Kyoo.Postgresql.Migrations
.HasColumnType("timestamp with time zone") .HasColumnType("timestamp with time zone")
.HasColumnName("release_date"); .HasColumnName("release_date");
b.Property<int>("Runtime")
.HasColumnType("integer")
.HasColumnName("runtime");
b.Property<int?>("SeasonId") b.Property<int?>("SeasonId")
.HasColumnType("integer") .HasColumnType("integer")
.HasColumnName("season_id"); .HasColumnName("season_id");
@ -212,10 +216,13 @@ namespace Kyoo.Postgresql.Migrations
.HasColumnName("path"); .HasColumnName("path");
b.Property<int>("Rating") b.Property<int>("Rating")
.IsRequired()
.HasColumnType("integer") .HasColumnType("integer")
.HasColumnName("rating"); .HasColumnName("rating");
b.Property<int>("Runtime")
.HasColumnType("integer")
.HasColumnName("runtime");
b.Property<string>("Slug") b.Property<string>("Slug")
.IsRequired() .IsRequired()
.HasMaxLength(256) .HasMaxLength(256)
@ -298,10 +305,13 @@ namespace Kyoo.Postgresql.Migrations
.HasColumnName("path"); .HasColumnName("path");
b.Property<int>("Rating") b.Property<int>("Rating")
.IsRequired()
.HasColumnType("integer") .HasColumnType("integer")
.HasColumnName("rating"); .HasColumnName("rating");
b.Property<int>("Runtime")
.HasColumnType("integer")
.HasColumnName("runtime");
b.Property<string>("Slug") b.Property<string>("Slug")
.IsRequired() .IsRequired()
.HasMaxLength(256) .HasMaxLength(256)
@ -402,10 +412,13 @@ namespace Kyoo.Postgresql.Migrations
.HasColumnName("path"); .HasColumnName("path");
b.Property<int>("Rating") b.Property<int>("Rating")
.IsRequired()
.HasColumnType("integer") .HasColumnType("integer")
.HasColumnName("rating"); .HasColumnName("rating");
b.Property<int>("Runtime")
.HasColumnType("integer")
.HasColumnName("runtime");
b.Property<int?>("SeasonNumber") b.Property<int?>("SeasonNumber")
.HasColumnType("integer") .HasColumnType("integer")
.HasColumnName("season_number"); .HasColumnName("season_number");
@ -628,7 +641,6 @@ namespace Kyoo.Postgresql.Migrations
.HasColumnName("overview"); .HasColumnName("overview");
b.Property<int>("Rating") b.Property<int>("Rating")
.IsRequired()
.HasColumnType("integer") .HasColumnType("integer")
.HasColumnName("rating"); .HasColumnName("rating");

View File

@ -34,21 +34,21 @@ namespace Kyoo.Postgresql.Migrations
s.id, s.slug, s.name, s.tagline, s.aliases, s.overview, s.tags, s.genres, s.status, s.id, s.slug, s.name, s.tagline, s.aliases, s.overview, s.tags, s.genres, s.status,
s.start_air, s.end_air, s.poster_source, s.poster_blurhash, s.thumbnail_source, s.thumbnail_blurhash, s.start_air, s.end_air, s.poster_source, s.poster_blurhash, s.thumbnail_source, s.thumbnail_blurhash,
s.logo_source, s.logo_blurhash, s.trailer, s.external_id, s.start_air AS air_date, NULL as path, s.logo_source, s.logo_blurhash, s.trailer, s.external_id, s.start_air AS air_date, NULL as path,
'show'::item_kind AS kind, s.added_date, s.rating 'show'::item_kind AS kind, s.added_date, s.rating, NULL AS runtime
FROM shows AS s FROM shows AS s
UNION ALL UNION ALL
SELECT SELECT
-m.id, m.slug, m.name, m.tagline, m.aliases, m.overview, m.tags, m.genres, m.status, -m.id, m.slug, m.name, m.tagline, m.aliases, m.overview, m.tags, m.genres, m.status,
m.air_date as start_air, m.air_date as end_air, m.poster_source, m.poster_blurhash, m.thumbnail_source, m.air_date as start_air, m.air_date as end_air, m.poster_source, m.poster_blurhash, m.thumbnail_source,
m.thumbnail_blurhash, m.logo_source, m.logo_blurhash, m.trailer, m.external_id, m.air_date, m.path, m.thumbnail_blurhash, m.logo_source, m.logo_blurhash, m.trailer, m.external_id, m.air_date, m.path,
'movie'::item_kind AS kind, m.added_date, m.rating 'movie'::item_kind AS kind, m.added_date, m.rating, m.runtime
FROM movies AS m FROM movies AS m
UNION ALL UNION ALL
SELECT SELECT
c.id + 10000 AS id, c.slug, c.name, NULL as tagline, NULL as alises, c.overview, NULL AS tags, NULL AS genres, 'unknown'::status AS status, c.id + 10000 AS id, c.slug, c.name, NULL as tagline, NULL as alises, c.overview, NULL AS tags, NULL AS genres, 'unknown'::status AS status,
NULL AS start_air, NULL AS end_air, c.poster_source, c.poster_blurhash, c.thumbnail_source, NULL AS start_air, NULL AS end_air, c.poster_source, c.poster_blurhash, c.thumbnail_source,
c.thumbnail_blurhash, c.logo_source, c.logo_blurhash, NULL as trailer, c.external_id, NULL AS air_date, NULL as path, c.thumbnail_blurhash, c.logo_source, c.logo_blurhash, NULL as trailer, c.external_id, NULL AS air_date, NULL as path,
'collection'::item_kind AS kind, c.added_date, NULL as rating 'collection'::item_kind AS kind, c.added_date, NULL AS rating, NULL AS runtime
FROM collections AS c FROM collections AS c
"); ");
@ -62,7 +62,7 @@ namespace Kyoo.Postgresql.Migrations
'episode'::news_kind AS kind, e.added_date, s.id AS show_id, s.slug AS show_slug, s.name AS show_name, 'episode'::news_kind AS kind, e.added_date, s.id AS show_id, s.slug AS show_slug, s.name AS show_name,
s.poster_source AS show_poster_source, s.poster_blurhash AS show_poster_blurhash, s.thumbnail_source AS show_thumbnail_source, s.poster_source AS show_poster_source, s.poster_blurhash AS show_poster_blurhash, s.thumbnail_source AS show_thumbnail_source,
s.thumbnail_blurhash AS show_thumbnail_blurhash, s.logo_source AS show_logo_source, s.logo_blurhash AS show_logo_blurhash, s.thumbnail_blurhash AS show_thumbnail_blurhash, s.logo_source AS show_logo_source, s.logo_blurhash AS show_logo_blurhash,
NULL as rating NULL as rating, e.runtime
FROM episodes AS e FROM episodes AS e
LEFT JOIN shows AS s ON e.show_id = s.id LEFT JOIN shows AS s ON e.show_id = s.id
UNION ALL UNION ALL
@ -72,7 +72,7 @@ namespace Kyoo.Postgresql.Migrations
m.logo_source, m.logo_blurhash, m.trailer, m.external_id, NULL AS season_number, NULL AS episode_number, NULL as absolute_number, m.logo_source, m.logo_blurhash, m.trailer, m.external_id, NULL AS season_number, NULL AS episode_number, NULL as absolute_number,
'movie'::news_kind AS kind, m.added_date, NULL AS show_id, NULL AS show_slug, NULL AS show_name, 'movie'::news_kind AS kind, m.added_date, NULL AS show_id, NULL AS show_slug, NULL AS show_name,
NULL AS show_poster_source, NULL AS show_poster_blurhash, NULL AS show_thumbnail_source, NULL AS show_thumbnail_blurhash, NULL AS show_poster_source, NULL AS show_poster_blurhash, NULL AS show_thumbnail_source, NULL AS show_thumbnail_blurhash,
NULL AS show_logo_source, NULL AS show_logo_blurhash, m.rating NULL AS show_logo_source, NULL AS show_logo_blurhash, m.rating, m.runtime
FROM movies AS m FROM movies AS m
"); ");
} }
@ -96,6 +96,20 @@ namespace Kyoo.Postgresql.Migrations
type: "integer", type: "integer",
nullable: false); nullable: false);
migrationBuilder.AddColumn<int>(
name: "runtime",
table: "movies",
type: "integer",
nullable: false,
defaultValue: 0);
migrationBuilder.AddColumn<int>(
name: "runtime",
table: "episodes",
type: "integer",
nullable: false,
defaultValue: 0);
CreateItemView(migrationBuilder); CreateItemView(migrationBuilder);
} }
@ -114,6 +128,14 @@ namespace Kyoo.Postgresql.Migrations
name: "rating", name: "rating",
table: "movies"); table: "movies");
migrationBuilder.DropColumn(
name: "runtime",
table: "movies");
migrationBuilder.DropColumn(
name: "runtime",
table: "episodes");
AddedDate.CreateItemView(migrationBuilder); AddedDate.CreateItemView(migrationBuilder);
} }
} }

View File

@ -1,4 +1,4 @@
// <auto-generated /> // <auto-generated />
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Kyoo.Abstractions.Models; using Kyoo.Abstractions.Models;
@ -118,6 +118,10 @@ namespace Kyoo.Postgresql.Migrations
.HasColumnType("timestamp with time zone") .HasColumnType("timestamp with time zone")
.HasColumnName("release_date"); .HasColumnName("release_date");
b.Property<int>("Runtime")
.HasColumnType("integer")
.HasColumnName("runtime");
b.Property<int?>("SeasonId") b.Property<int?>("SeasonId")
.HasColumnType("integer") .HasColumnType("integer")
.HasColumnName("season_id"); .HasColumnName("season_id");
@ -209,10 +213,13 @@ namespace Kyoo.Postgresql.Migrations
.HasColumnName("path"); .HasColumnName("path");
b.Property<int>("Rating") b.Property<int>("Rating")
.IsRequired()
.HasColumnType("integer") .HasColumnType("integer")
.HasColumnName("rating"); .HasColumnName("rating");
b.Property<int>("Runtime")
.HasColumnType("integer")
.HasColumnName("runtime");
b.Property<string>("Slug") b.Property<string>("Slug")
.IsRequired() .IsRequired()
.HasMaxLength(256) .HasMaxLength(256)
@ -295,10 +302,13 @@ namespace Kyoo.Postgresql.Migrations
.HasColumnName("path"); .HasColumnName("path");
b.Property<int>("Rating") b.Property<int>("Rating")
.IsRequired()
.HasColumnType("integer") .HasColumnType("integer")
.HasColumnName("rating"); .HasColumnName("rating");
b.Property<int>("Runtime")
.HasColumnType("integer")
.HasColumnName("runtime");
b.Property<string>("Slug") b.Property<string>("Slug")
.IsRequired() .IsRequired()
.HasMaxLength(256) .HasMaxLength(256)
@ -399,10 +409,13 @@ namespace Kyoo.Postgresql.Migrations
.HasColumnName("path"); .HasColumnName("path");
b.Property<int>("Rating") b.Property<int>("Rating")
.IsRequired()
.HasColumnType("integer") .HasColumnType("integer")
.HasColumnName("rating"); .HasColumnName("rating");
b.Property<int>("Runtime")
.HasColumnType("integer")
.HasColumnName("runtime");
b.Property<int?>("SeasonNumber") b.Property<int?>("SeasonNumber")
.HasColumnType("integer") .HasColumnType("integer")
.HasColumnName("season_number"); .HasColumnName("season_number");
@ -625,7 +638,6 @@ namespace Kyoo.Postgresql.Migrations
.HasColumnName("overview"); .HasColumnName("overview");
b.Property<int>("Rating") b.Property<int>("Rating")
.IsRequired()
.HasColumnType("integer") .HasColumnType("integer")
.HasColumnName("rating"); .HasColumnName("rating");

View File

@ -139,6 +139,7 @@ class TheMovieDatabase(Provider):
if movie["status"] == "Released" if movie["status"] == "Released"
else MovieStatus.PLANNED, else MovieStatus.PLANNED,
rating=round(float(movie["vote_average"]) * 10), rating=round(float(movie["vote_average"]) * 10),
runtime=int(movie["runtime"]),
studios=[self.to_studio(x) for x in movie["production_companies"]], studios=[self.to_studio(x) for x in movie["production_companies"]],
genres=[ genres=[
self.genre_map[x["id"]] self.genre_map[x["id"]]
@ -423,6 +424,7 @@ class TheMovieDatabase(Provider):
season_number=episode["season_number"], season_number=episode["season_number"],
episode_number=episode["episode_number"], episode_number=episode["episode_number"],
absolute_number=absolute, absolute_number=absolute,
runtime=int(episode["runtime"]),
release_date=datetime.strptime(episode["air_date"], "%Y-%m-%d").date() release_date=datetime.strptime(episode["air_date"], "%Y-%m-%d").date()
if episode["air_date"] if episode["air_date"]
else None, else None,

View File

@ -26,6 +26,7 @@ class Episode:
season_number: Optional[int] season_number: Optional[int]
episode_number: Optional[int] episode_number: Optional[int]
absolute_number: Optional[int] absolute_number: Optional[int]
runtime: int
release_date: Optional[date | int] release_date: Optional[date | int]
thumbnail: Optional[str] thumbnail: Optional[str]
external_id: dict[str, MetadataID] external_id: dict[str, MetadataID]

View File

@ -30,18 +30,19 @@ class MovieTranslation:
@dataclass @dataclass
class Movie: class Movie:
original_language: Optional[str] = None original_language: Optional[str]
aliases: list[str] = field(default_factory=list) aliases: list[str]
air_date: Optional[date | int] = None air_date: Optional[date | int]
status: Status = Status.UNKNOWN status: Status
rating: int = None rating: int
path: Optional[str] = None runtime: int
studios: list[Studio] = field(default_factory=list) studios: list[Studio]
genres: list[Genre] = field(default_factory=list) genres: list[Genre]
# TODO: handle staff # TODO: handle staff
# staff: list[Staff] # staff: list[Staff]
external_id: dict[str, MetadataID] = field(default_factory=dict) external_id: dict[str, MetadataID]
path: Optional[str] = None
translations: dict[str, MovieTranslation] = field(default_factory=dict) translations: dict[str, MovieTranslation] = field(default_factory=dict)
def to_kyoo(self): def to_kyoo(self):