163 lines
6.7 KiB
C#
163 lines
6.7 KiB
C#
using Modules.Library.Domain.Entities.MediaContent.CommonProperties;
|
|
|
|
namespace Modules.Library.Domain.Entities.MediaContent.Items.Anime;
|
|
|
|
public class AnimeTitle : Entity
|
|
{
|
|
public CommonProperties.CommonProperties CommonProperties { get; protected set; } = default!;
|
|
|
|
private readonly List<AnimeItem> _items = [];
|
|
public IReadOnlyCollection<AnimeItem> Items => _items.ToList().AsReadOnly();
|
|
|
|
public bool Completed { get; private set; }
|
|
public TimeSpan ExpirationTime { get; private set; }
|
|
|
|
private AnimeTitle() { }
|
|
|
|
private AnimeTitle(Models.AnimeTitle title)
|
|
{
|
|
Id = title.Id;
|
|
Deleted = title.Deleted;
|
|
CommonProperties = MediaContent.CommonProperties.CommonProperties.New(title.CommonProperties);
|
|
Completed = title.Completed;
|
|
ExpirationTime = title.ExpirationTime;
|
|
foreach(var item in title.Items)
|
|
{
|
|
if (item is Models.AnimeEpisode episode)
|
|
{
|
|
_items.Add(AnimeEpisode.New(episode));
|
|
}
|
|
else if (item is Models.AnimeSeason season)
|
|
{
|
|
_items.Add(AnimeSeason.New(season));
|
|
}
|
|
}
|
|
}
|
|
|
|
public AnimeTitle(Guid nameOriginalLanguageId, string nameOriginal)
|
|
{
|
|
CommonProperties = new CommonProperties.CommonProperties(nameOriginalLanguageId, nameOriginal);
|
|
}
|
|
|
|
public static AnimeTitle New(Models.AnimeTitle title) => new(title);
|
|
|
|
public AnimeEpisode AddEpisode(AnimeEpisodeType episodeType, int? number = null) =>
|
|
CreateAndAddEpisode(episodeType, number:number);
|
|
public AnimeEpisode AddEpisodeAsVariant(AnimeEpisodeType episodeType, ushort order, int? number = null) =>
|
|
CreateAndAddEpisode(episodeType, order, number: number);
|
|
|
|
private AnimeEpisode CreateAndAddEpisode(AnimeEpisodeType type, ushort? order = null, ushort? variant = null, int? number = null)
|
|
{
|
|
StructureAction(() =>
|
|
{
|
|
(order, variant) = AnimeItem.GetOrderAndVariant(_items, order, variant);
|
|
number ??= _items.OfType<AnimeEpisode>().Select(q => q.Number).DefaultIfEmpty(-1).Max() + 1;
|
|
_items.Add(new AnimeEpisode(this, null, type, order.Value, variant.Value, number));
|
|
CheckIfCompleted();
|
|
});
|
|
return _items.OfType<AnimeEpisode>().OrderByDescending(q => q.Order).ThenByDescending(q => q.Variant).First();
|
|
}
|
|
|
|
public AnimeEpisode AddEpisode(AnimeEpisodeType episodeType, Guid nameOriginalLanguageId, string nameOriginal, int? number = null) =>
|
|
CreateAndAddEpisode(episodeType, nameOriginalLanguageId, nameOriginal, number:number);
|
|
|
|
public AnimeEpisode AddEpisodeAsVariant(AnimeEpisodeType episodeType, Guid nameOriginalLanguageId, string nameOriginal, ushort order, int? number = null) =>
|
|
CreateAndAddEpisode(episodeType, nameOriginalLanguageId, nameOriginal, order, number:number);
|
|
|
|
private AnimeEpisode CreateAndAddEpisode(AnimeEpisodeType type, Guid nameOriginalLanguageId, string nameOriginal,
|
|
ushort? order = null, ushort? variant = null, int? number = null)
|
|
{
|
|
StructureAction(() =>
|
|
{
|
|
(order, variant) = AnimeItem.GetOrderAndVariant(_items, order, variant);
|
|
number ??= _items.OfType<AnimeEpisode>().Select(q => q.Number).DefaultIfEmpty(-1).Max() + 1;
|
|
_items.Add(new AnimeEpisode(this, null, type, nameOriginalLanguageId, nameOriginal, order.Value, variant.Value, number));
|
|
CheckIfCompleted();
|
|
});
|
|
return _items.OfType<AnimeEpisode>().OrderByDescending(q => q.Order).ThenByDescending(q => q.Variant).First();
|
|
}
|
|
|
|
public void RemoveEpisode(ushort order, ushort variant)
|
|
{
|
|
var episode = _items.OfType<AnimeEpisode>().FirstOrDefault(q => q.Order == order && q.Variant == variant) ??
|
|
throw new Exception("EpisodeNotFoundException");
|
|
_items.Remove(episode);
|
|
}
|
|
|
|
public AnimeSeason AddSeason()
|
|
{
|
|
StructureAction(() =>
|
|
{
|
|
(ushort order, _) = AnimeItem.GetOrderAndVariant(_items);
|
|
var number = _items.OfType<AnimeSeason>().Select(q => q.Number).DefaultIfEmpty(-1).Max() + 1;
|
|
var season = new AnimeSeason(this, order, number);
|
|
_items.Add(season);
|
|
});
|
|
return _items.OfType<AnimeSeason>().OrderByDescending(q => q.Order).ThenByDescending(q => q.Variant).First();
|
|
}
|
|
|
|
public AnimeSeason AddSeason(Guid nameOriginalLanguageId, string nameOriginal, int? number = null)
|
|
{
|
|
StructureAction(() =>
|
|
{
|
|
(ushort order, _) = AnimeItem.GetOrderAndVariant(_items);
|
|
number ??= _items.OfType<AnimeSeason>().Select(q => q.Number).DefaultIfEmpty(-1).Max() + 1;
|
|
var season = new AnimeSeason(this, nameOriginalLanguageId, nameOriginal, order, number);
|
|
_items.Add(season);
|
|
});
|
|
return _items.OfType<AnimeSeason>().OrderByDescending(q => q.Order).ThenByDescending(q => q.Variant).First();
|
|
}
|
|
|
|
/*
|
|
public void AddSeasonAsVariant(AnimeEpisodeType episodeType, ushort order)
|
|
{
|
|
if (order < 0 || order > _shadow.items.Select(q => q.order).DefaultIfEmpty<ushort>(0).Max())
|
|
throw new ArgumentOutOfRangeException(nameof(order));
|
|
|
|
var episode = new AnimeEpisodeShadow
|
|
{
|
|
type = episodeType,
|
|
order = order,
|
|
variant = AnimeItem.GetNewVariant(_shadow.items, order),
|
|
number = _shadow.items.OfType<AnimeEpisodeShadow>().FirstOrDefault(q => q.order == order)?.number,
|
|
};
|
|
_shadow.items.Add(episode);
|
|
CheckIsCompleted();
|
|
}
|
|
*/
|
|
|
|
//public void RemoveSeason(ushort order, ushort variant)
|
|
public void RemoveSeason(ushort order)
|
|
{
|
|
var season = _items.OfType<AnimeSeason>().FirstOrDefault(q => q.Order == order) ??
|
|
throw new Exception("SeasonNotFoundException");
|
|
_items.Remove(season);
|
|
}
|
|
|
|
public void SetCompleted() => Completed = true;
|
|
|
|
public void SetNotCompleted() => Completed = false;
|
|
|
|
public void SetExpirationTime(TimeSpan value) => StructureAction(() => ExpirationTime = value);
|
|
|
|
public void Delete() => Deleted = true;
|
|
|
|
internal void CheckIfCompleted()
|
|
{
|
|
var itemsQuery = Items.AsQueryable();
|
|
var ucompletedSeasons = itemsQuery
|
|
.Any(q => !q.CommonProperties.ReleaseDate.HasValue);
|
|
var lastEpisodeReleaseDate = itemsQuery
|
|
.OrderByDescending(q => q.CommonProperties.ReleaseDate)
|
|
.FirstOrDefault()?.CommonProperties.ReleaseDate;
|
|
if (ucompletedSeasons || lastEpisodeReleaseDate >= DateTime.UtcNow - ExpirationTime) SetNotCompleted();
|
|
else SetCompleted();
|
|
}
|
|
|
|
|
|
protected void StructureAction(Action action)
|
|
{
|
|
action();
|
|
CheckIfCompleted();
|
|
}
|
|
} |