private async Task <MetadataResult <BoxSet> > GetShokoGroupedMetadata(BoxSetInfo info, CancellationToken cancellationToken) { var result = new MetadataResult <BoxSet>(); var config = Plugin.Instance.Configuration; Ordering.GroupFilterType filterByType = config.FilterOnLibraryTypes ? Ordering.GroupFilterType.Movies : Ordering.GroupFilterType.Default; var group = await ApiManager.GetGroupInfoByPath(info.Path, filterByType); if (group == null) { Logger.LogWarning($"Unable to find box-set info for path {info.Path}"); return(result); } var series = group.DefaultSeries; if (series.AniDB.Type != API.Models.SeriesType.Movie) { Logger.LogWarning($"File found, but not a movie! Skipping."); return(result); } var tags = await ApiManager.GetTags(series.Id); var(displayTitle, alternateTitle) = Text.GetSeriesTitles(series.AniDB.Titles, series.Shoko.Name, info.MetadataLanguage); result.Item = new BoxSet { Name = displayTitle, OriginalTitle = alternateTitle, Overview = Text.SanitizeTextSummary(series.AniDB.Description), PremiereDate = series.AniDB.AirDate, EndDate = series.AniDB.EndDate, ProductionYear = series.AniDB.AirDate?.Year, Tags = tags, CommunityRating = (float)((series.AniDB.Rating.Value * 10) / series.AniDB.Rating.MaxValue) }; result.Item.SetProviderId("Shoko Series", series.Id); result.Item.SetProviderId("Shoko Group", group.Id); if (config.AddAniDBId) { result.Item.SetProviderId("AniDB", series.AniDB.ID.ToString()); } result.HasMetadata = true; ApiManager.MarkSeriesAsFound(series.Id, group.Id); result.ResetPeople(); foreach (var person in await ApiManager.GetPeople(series.Id)) { result.AddPerson(person); } return(result); }
public GroupInfo GetGroupInfoForSeriesSync(string seriesId, Ordering.GroupFilterType filterByType = Ordering.GroupFilterType.Default) { if (SeriesIdToGroupIdDictionary.ContainsKey(seriesId)) { var groupId = SeriesIdToGroupIdDictionary[seriesId]; if (DataCache.TryGetValue <GroupInfo>($"group:{filterByType}:{groupId}", out var info)) { return(info); } return(GetGroupInfo(groupId, filterByType).GetAwaiter().GetResult()); } return(GetGroupInfoForSeries(seriesId, filterByType).GetAwaiter().GetResult()); }
public async Task <GroupInfo> GetGroupInfo(string groupId, Ordering.GroupFilterType filterByType = Ordering.GroupFilterType.Default) { if (string.IsNullOrEmpty(groupId)) { return(null); } if (DataCache.TryGetValue <GroupInfo>($"group:{filterByType}:{groupId}", out var info)) { return(info); } var group = await ShokoAPI.GetGroup(groupId); return(await CreateGroupInfo(group, groupId, filterByType)); }
public async Task <GroupInfo> GetGroupInfoForSeries(string seriesId, Ordering.GroupFilterType filterByType = Ordering.GroupFilterType.Default) { string groupId; if (SeriesIdToGroupIdDictionary.ContainsKey(seriesId)) { groupId = SeriesIdToGroupIdDictionary[seriesId]; } else { var group = await ShokoAPI.GetGroupFromSeries(seriesId); if (group == null) { return(null); } groupId = group.IDs.ID.ToString(); } return(await GetGroupInfo(groupId, filterByType)); }
public async Task <GroupInfo> GetGroupInfoByPath(string path, Ordering.GroupFilterType filterByType = Ordering.GroupFilterType.Default) { var partialPath = StripMediaFolder(path); var result = await ShokoAPI.GetSeriesPathEndsWith(partialPath); var seriesId = result?.FirstOrDefault()?.IDs?.ID.ToString(); if (string.IsNullOrEmpty(seriesId)) { return(null); } var groupInfo = await GetGroupInfoForSeries(seriesId, filterByType); if (groupInfo == null) { return(null); } return(groupInfo); }
private async Task <GroupInfo> CreateGroupInfo(Group group, string groupId, Ordering.GroupFilterType filterByType) { if (group == null) { return(null); } if (string.IsNullOrEmpty(groupId)) { groupId = group.IDs.ID.ToString(); } var cacheKey = $"group:{filterByType}:{groupId}"; GroupInfo groupInfo = null; if (DataCache.TryGetValue <GroupInfo>(cacheKey, out groupInfo)) { return(groupInfo); } var seriesList = await ShokoAPI.GetSeriesInGroup(groupId) .ContinueWith(async task => await Task.WhenAll(task.Result.Select(s => CreateSeriesInfo(s)))).Unwrap() .ContinueWith(l => l.Result.Where(s => s != null).ToList()); if (seriesList != null && seriesList.Count > 0) { switch (filterByType) { default: break; case Ordering.GroupFilterType.Movies: seriesList = seriesList.Where(s => s.AniDB.Type == SeriesType.Movie).ToList(); break; case Ordering.GroupFilterType.Others: seriesList = seriesList.Where(s => s.AniDB.Type != SeriesType.Movie).ToList(); break; } } // Return ealty if no series matched the filter or if the list was empty. if (seriesList == null || seriesList.Count == 0) { return(null); } // Order series list var orderingType = filterByType == Ordering.GroupFilterType.Movies ? Plugin.Instance.Configuration.MovieOrdering : Plugin.Instance.Configuration.SeasonOrdering; switch (orderingType) { case Ordering.OrderType.Default: break; case Ordering.OrderType.ReleaseDate: seriesList = seriesList.OrderBy(s => s?.AniDB?.AirDate ?? System.DateTime.MaxValue).ToList(); break; // Should not be selectable unless a user fiddles with DevTools in the browser to select the option. case Ordering.OrderType.Chronological: throw new System.Exception("Not implemented yet"); } // Select the targeted id if a group spesify a default series. int foundIndex = -1; int targetId = (group.IDs.DefaultSeries ?? 0); if (targetId != 0) { foundIndex = seriesList.FindIndex(s => s.Shoko.IDs.ID == targetId); } // Else select the default series as first-to-be-released. else { switch (orderingType) { // The list is already sorted by release date, so just return the first index. case Ordering.OrderType.ReleaseDate: foundIndex = 0; break; // We don't know how Shoko may have sorted it, so just find the earliest series case Ordering.OrderType.Default: // We can't be sure that the the series in the list was _released_ chronologically, so find the earliest series, and use that as a base. case Ordering.OrderType.Chronological: { var earliestSeries = seriesList.Aggregate((cur, nxt) => (cur == null || (nxt?.AniDB.AirDate ?? System.DateTime.MaxValue) < (cur.AniDB.AirDate ?? System.DateTime.MaxValue)) ? nxt : cur); foundIndex = seriesList.FindIndex(s => s == earliestSeries); break; } } } // Throw if we can't get a base point for seasons. if (foundIndex == -1) { throw new System.Exception("Unable to get a base-point for seasions withing the group"); } var groupGuid = GetGroupGuid(groupId); groupInfo = new GroupInfo { Id = groupId, Guid = groupGuid, Shoko = group, SeriesList = seriesList, DefaultSeries = seriesList[foundIndex], DefaultSeriesIndex = foundIndex, }; foreach (var series in seriesList) { SeriesIdToGroupIdDictionary[series.Id] = groupId; } DataCache.Set <GroupInfo>(cacheKey, groupInfo, DefaultTimeSpan); return(groupInfo); }
public GroupInfo GetGroupInfoByPathSync(string path, Ordering.GroupFilterType filterByType = Ordering.GroupFilterType.Default) { return(GetGroupInfoByPath(path, filterByType).GetAwaiter().GetResult()); }
public async Task <SeriesInfo> GetSeriesInfoFromGroup(string groupId, int seasonNumber, Ordering.GroupFilterType filterByType = Ordering.GroupFilterType.Default) { var groupInfo = await GetGroupInfo(groupId, filterByType); if (groupInfo == null) { return(null); } int seriesIndex = seasonNumber > 0 ? seasonNumber - 1 : seasonNumber; var index = groupInfo.DefaultSeriesIndex + seriesIndex; var seriesInfo = groupInfo.SeriesList[index]; if (seriesInfo == null) { return(null); } return(seriesInfo); }