// 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.Text.RegularExpressions;
using JetBrains.Annotations;
using Kyoo.Abstractions.Controllers;
using Kyoo.Abstractions.Models.Attributes;
namespace Kyoo.Abstractions.Models
{
///
/// A class to represent a single show's episode.
///
public class Episode : IResource, IMetadata, IThumbnails
{
///
public int ID { get; set; }
///
[Computed] public string Slug
{
get
{
if (ShowSlug != null || Show != null)
return GetSlug(ShowSlug ?? Show.Slug, SeasonNumber, EpisodeNumber, AbsoluteNumber);
return ShowID != 0
? GetSlug(ShowID.ToString(), SeasonNumber, EpisodeNumber, AbsoluteNumber)
: null;
}
[UsedImplicitly] [NotNull] private set
{
if (value == null)
throw new ArgumentNullException(nameof(value));
Match match = Regex.Match(value, @"(?.+)-s(?\d+)e(?\d+)");
if (match.Success)
{
ShowSlug = match.Groups["show"].Value;
SeasonNumber = int.Parse(match.Groups["season"].Value);
EpisodeNumber = int.Parse(match.Groups["episode"].Value);
}
else
{
match = Regex.Match(value, @"(?.+)-(?\d+)");
if (match.Success)
{
ShowSlug = match.Groups["show"].Value;
AbsoluteNumber = int.Parse(match.Groups["absolute"].Value);
}
else
ShowSlug = value;
SeasonNumber = null;
EpisodeNumber = null;
}
}
}
///
/// The slug of the Show that contain this episode. If this is not set, this episode is ill-formed.
///
[SerializeIgnore] public string ShowSlug { private get; set; }
///
/// The ID of the Show containing this episode.
///
[SerializeIgnore] public int ShowID { get; set; }
///
/// The show that contains this episode. This must be explicitly loaded via a call to .
///
[LoadableRelation(nameof(ShowID))] public Show Show { get; set; }
///
/// The ID of the Season containing this episode.
///
[SerializeIgnore] public int? SeasonID { get; set; }
///
/// The season that contains this episode.
/// This must be explicitly loaded via a call to .
///
///
/// This can be null if the season is unknown and the episode is only identified
/// by it's .
///
[LoadableRelation(nameof(SeasonID))] public Season Season { get; set; }
///
/// 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; }
///
/// The path of the video file for this episode. Any format supported by a is allowed.
///
[SerializeIgnore] public string Path { get; set; }
///
public Dictionary Images { get; set; }
///
/// The path of this episode's thumbnail.
/// By default, the http path for the thumbnail is returned from the public API.
/// This can be disabled using the internal query flag.
///
[SerializeAs("{HOST}/api/episodes/{Slug}/thumbnail")]
[Obsolete("Use Images instead of this, this is only kept for the API response.")]
public string Thumb => Images?.GetValueOrDefault(Models.Images.Thumbnail);
///
/// The title of this episode.
///
public string Title { get; set; }
///
/// The overview of this episode.
///
public string Overview { get; set; }
///
/// The release date of this episode. It can be null if unknown.
///
public DateTime? ReleaseDate { get; set; }
///
[EditableRelation] [LoadableRelation] public ICollection ExternalIDs { get; set; }
///
/// The list of tracks this episode has. This lists video, audio and subtitles available.
///
[EditableRelation] [LoadableRelation] public ICollection