clean related files when deleting items
This commit is contained in:
parent
36f8eb1149
commit
6091e00e18
|
@ -3874,6 +3874,25 @@ namespace Emby.Server.Implementations.Data
|
||||||
whereClauses.Add(clause);
|
whereClauses.Add(clause);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (query.AlbumIds.Length > 0)
|
||||||
|
{
|
||||||
|
var clauses = new List<string>();
|
||||||
|
var index = 0;
|
||||||
|
foreach (var albumId in query.AlbumIds)
|
||||||
|
{
|
||||||
|
var paramName = "@AlbumIds" + index;
|
||||||
|
|
||||||
|
clauses.Add("Album in (select Name from typedbaseitems where guid=" + paramName + ")");
|
||||||
|
if (statement != null)
|
||||||
|
{
|
||||||
|
statement.TryBind(paramName, albumId.ToGuidParamValue());
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
var clause = "(" + string.Join(" OR ", clauses.ToArray()) + ")";
|
||||||
|
whereClauses.Add(clause);
|
||||||
|
}
|
||||||
|
|
||||||
if (query.ExcludeArtistIds.Length > 0)
|
if (query.ExcludeArtistIds.Length > 0)
|
||||||
{
|
{
|
||||||
var clauses = new List<string>();
|
var clauses = new List<string>();
|
||||||
|
@ -4227,30 +4246,6 @@ namespace Emby.Server.Implementations.Data
|
||||||
{
|
{
|
||||||
whereClauses.Add("ProviderIds like '%tvdb=%'");
|
whereClauses.Add("ProviderIds like '%tvdb=%'");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (query.AlbumNames.Length > 0)
|
|
||||||
{
|
|
||||||
var clause = "(";
|
|
||||||
|
|
||||||
var index = 0;
|
|
||||||
foreach (var name in query.AlbumNames)
|
|
||||||
{
|
|
||||||
if (index > 0)
|
|
||||||
{
|
|
||||||
clause += " OR ";
|
|
||||||
}
|
|
||||||
clause += "Album=@AlbumName" + index;
|
|
||||||
|
|
||||||
if (statement != null)
|
|
||||||
{
|
|
||||||
statement.TryBind("@AlbumName" + index, name);
|
|
||||||
}
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
|
|
||||||
clause += ")";
|
|
||||||
whereClauses.Add(clause);
|
|
||||||
}
|
|
||||||
if (query.HasThemeSong.HasValue)
|
if (query.HasThemeSong.HasValue)
|
||||||
{
|
{
|
||||||
if (query.HasThemeSong.Value)
|
if (query.HasThemeSong.Value)
|
||||||
|
|
|
@ -492,7 +492,10 @@ namespace Emby.Server.Implementations.Dto
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dto.PlayAccess = item.GetPlayAccess(user);
|
//if (!(item is LiveTvProgram))
|
||||||
|
{
|
||||||
|
dto.PlayAccess = item.GetPlayAccess(user);
|
||||||
|
}
|
||||||
|
|
||||||
if (fields.Contains(ItemFields.BasicSyncInfo) || fields.Contains(ItemFields.SyncInfo))
|
if (fields.Contains(ItemFields.BasicSyncInfo) || fields.Contains(ItemFields.SyncInfo))
|
||||||
{
|
{
|
||||||
|
@ -994,7 +997,12 @@ namespace Emby.Server.Implementations.Dto
|
||||||
}
|
}
|
||||||
|
|
||||||
dto.MediaType = item.MediaType;
|
dto.MediaType = item.MediaType;
|
||||||
dto.LocationType = item.LocationType;
|
|
||||||
|
if (!(item is LiveTvProgram))
|
||||||
|
{
|
||||||
|
dto.LocationType = item.LocationType;
|
||||||
|
}
|
||||||
|
|
||||||
if (item.IsHD.HasValue && item.IsHD.Value)
|
if (item.IsHD.HasValue && item.IsHD.Value)
|
||||||
{
|
{
|
||||||
dto.IsHD = item.IsHD;
|
dto.IsHD = item.IsHD;
|
||||||
|
@ -1102,7 +1110,10 @@ namespace Emby.Server.Implementations.Dto
|
||||||
}
|
}
|
||||||
|
|
||||||
dto.Type = item.GetClientTypeName();
|
dto.Type = item.GetClientTypeName();
|
||||||
dto.CommunityRating = item.CommunityRating;
|
if ((item.CommunityRating ?? 0) > 0)
|
||||||
|
{
|
||||||
|
dto.CommunityRating = item.CommunityRating;
|
||||||
|
}
|
||||||
|
|
||||||
if (fields.Contains(ItemFields.VoteCount))
|
if (fields.Contains(ItemFields.VoteCount))
|
||||||
{
|
{
|
||||||
|
@ -1410,8 +1421,6 @@ namespace Emby.Server.Implementations.Dto
|
||||||
dto.AirDays = series.AirDays;
|
dto.AirDays = series.AirDays;
|
||||||
dto.AirTime = series.AirTime;
|
dto.AirTime = series.AirTime;
|
||||||
dto.SeriesStatus = series.Status;
|
dto.SeriesStatus = series.Status;
|
||||||
|
|
||||||
dto.AnimeSeriesIndex = series.AnimeSeriesIndex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add SeasonInfo
|
// Add SeasonInfo
|
||||||
|
@ -1473,9 +1482,12 @@ namespace Emby.Server.Implementations.Dto
|
||||||
SetBookProperties(dto, book);
|
SetBookProperties(dto, book);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.ProductionLocations.Count > 0 || item is Movie)
|
if (fields.Contains(ItemFields.ProductionLocations))
|
||||||
{
|
{
|
||||||
dto.ProductionLocations = item.ProductionLocations.ToArray();
|
if (item.ProductionLocations.Count > 0 || item is Movie)
|
||||||
|
{
|
||||||
|
dto.ProductionLocations = item.ProductionLocations.ToArray();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var photo = item as Photo;
|
var photo = item as Photo;
|
||||||
|
|
|
@ -409,17 +409,17 @@ namespace Emby.Server.Implementations.Library
|
||||||
|
|
||||||
if (options.DeleteFileLocation && locationType != LocationType.Remote && locationType != LocationType.Virtual)
|
if (options.DeleteFileLocation && locationType != LocationType.Remote && locationType != LocationType.Virtual)
|
||||||
{
|
{
|
||||||
foreach (var path in item.GetDeletePaths().ToList())
|
foreach (var fileSystemInfo in item.GetDeletePaths().ToList())
|
||||||
{
|
{
|
||||||
if (_fileSystem.DirectoryExists(path))
|
if (fileSystemInfo.IsDirectory)
|
||||||
{
|
{
|
||||||
_logger.Debug("Deleting path {0}", path);
|
_logger.Debug("Deleting path {0}", fileSystemInfo.FullName);
|
||||||
_fileSystem.DeleteDirectory(path, true);
|
_fileSystem.DeleteDirectory(fileSystemInfo.FullName, true);
|
||||||
}
|
}
|
||||||
else if (_fileSystem.FileExists(path))
|
else
|
||||||
{
|
{
|
||||||
_logger.Debug("Deleting path {0}", path);
|
_logger.Debug("Deleting path {0}", fileSystemInfo.FullName);
|
||||||
_fileSystem.DeleteFile(path);
|
_fileSystem.DeleteFile(fileSystemInfo.FullName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -607,6 +607,10 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
item.Audio = info.Audio;
|
item.Audio = info.Audio;
|
||||||
item.ChannelId = channel.Id.ToString("N");
|
item.ChannelId = channel.Id.ToString("N");
|
||||||
item.CommunityRating = item.CommunityRating ?? info.CommunityRating;
|
item.CommunityRating = item.CommunityRating ?? info.CommunityRating;
|
||||||
|
if ((item.CommunityRating ?? 0).Equals(0))
|
||||||
|
{
|
||||||
|
item.CommunityRating = null;
|
||||||
|
}
|
||||||
|
|
||||||
item.EpisodeTitle = info.EpisodeTitle;
|
item.EpisodeTitle = info.EpisodeTitle;
|
||||||
item.ExternalId = info.Id;
|
item.ExternalId = info.Id;
|
||||||
|
|
|
@ -317,12 +317,6 @@ namespace MediaBrowser.Api.Reports
|
||||||
query.MaxParentalRating = _localization.GetRatingLevel(request.MaxOfficialRating);
|
query.MaxParentalRating = _localization.GetRatingLevel(request.MaxOfficialRating);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Albums
|
|
||||||
if (!string.IsNullOrEmpty(request.Albums))
|
|
||||||
{
|
|
||||||
query.AlbumNames = request.Albums.Split('|');
|
|
||||||
}
|
|
||||||
|
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -245,25 +245,15 @@ namespace MediaBrowser.Api.UserLibrary
|
||||||
|
|
||||||
User user = null;
|
User user = null;
|
||||||
BaseItem parentItem;
|
BaseItem parentItem;
|
||||||
List<BaseItem> libraryItems = null;
|
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(request.UserId))
|
if (!string.IsNullOrWhiteSpace(request.UserId))
|
||||||
{
|
{
|
||||||
user = UserManager.GetUserById(request.UserId);
|
user = UserManager.GetUserById(request.UserId);
|
||||||
parentItem = string.IsNullOrEmpty(request.ParentId) ? user.RootFolder : LibraryManager.GetItemById(request.ParentId);
|
parentItem = string.IsNullOrEmpty(request.ParentId) ? user.RootFolder : LibraryManager.GetItemById(request.ParentId);
|
||||||
|
|
||||||
if (RequiresLibraryItems(request, dtoOptions))
|
|
||||||
{
|
|
||||||
libraryItems = user.RootFolder.GetRecursiveChildren(user).ToList();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
parentItem = string.IsNullOrEmpty(request.ParentId) ? LibraryManager.RootFolder : LibraryManager.GetItemById(request.ParentId);
|
parentItem = string.IsNullOrEmpty(request.ParentId) ? LibraryManager.RootFolder : LibraryManager.GetItemById(request.ParentId);
|
||||||
if (RequiresLibraryItems(request, dtoOptions))
|
|
||||||
{
|
|
||||||
libraryItems = LibraryManager.RootFolder.GetRecursiveChildren().ToList();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IEnumerable<BaseItem> items;
|
IEnumerable<BaseItem> items;
|
||||||
|
@ -307,8 +297,6 @@ namespace MediaBrowser.Api.UserLibrary
|
||||||
|
|
||||||
var filteredItems = FilterItems(request, extractedItems, user);
|
var filteredItems = FilterItems(request, extractedItems, user);
|
||||||
|
|
||||||
filteredItems = FilterByLibraryItems(request, filteredItems.Cast<IItemByName>(), user, libraryItems).Cast<BaseItem>();
|
|
||||||
|
|
||||||
filteredItems = LibraryManager.Sort(filteredItems, user, request.GetOrderBy(), request.SortOrder ?? SortOrder.Ascending);
|
filteredItems = LibraryManager.Sort(filteredItems, user, request.GetOrderBy(), request.SortOrder ?? SortOrder.Ascending);
|
||||||
|
|
||||||
var ibnItemsArray = filteredItems.ToList();
|
var ibnItemsArray = filteredItems.ToList();
|
||||||
|
@ -334,15 +322,7 @@ namespace MediaBrowser.Api.UserLibrary
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IEnumerable<Tuple<BaseItem, List<BaseItem>>> tuples;
|
var tuples = ibnItems.Select(i => new Tuple<BaseItem, List<BaseItem>>(i, new List<BaseItem>()));
|
||||||
if (dtoOptions.Fields.Contains(ItemFields.ItemCounts))
|
|
||||||
{
|
|
||||||
tuples = ibnItems.Select(i => new Tuple<BaseItem, List<BaseItem>>(i, ((IItemByName)i).GetTaggedItems(libraryItems).ToList()));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tuples = ibnItems.Select(i => new Tuple<BaseItem, List<BaseItem>>(i, new List<BaseItem>()));
|
|
||||||
}
|
|
||||||
|
|
||||||
var syncProgess = DtoService.GetSyncedItemProgress(dtoOptions);
|
var syncProgess = DtoService.GetSyncedItemProgress(dtoOptions);
|
||||||
var dtos = tuples.Select(i => DtoService.GetItemByNameDto(i.Item1, dtoOptions, i.Item2, syncProgess, user));
|
var dtos = tuples.Select(i => DtoService.GetItemByNameDto(i.Item1, dtoOptions, i.Item2, syncProgess, user));
|
||||||
|
@ -352,52 +332,6 @@ namespace MediaBrowser.Api.UserLibrary
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool RequiresLibraryItems(GetItemsByName request, DtoOptions options)
|
|
||||||
{
|
|
||||||
var filters = request.GetFilters().ToList();
|
|
||||||
|
|
||||||
if (filters.Contains(ItemFilter.IsPlayed))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filters.Contains(ItemFilter.IsUnplayed))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (request.IsPlayed.HasValue)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return options.Fields.Contains(ItemFields.ItemCounts);
|
|
||||||
}
|
|
||||||
|
|
||||||
private IEnumerable<IItemByName> FilterByLibraryItems(GetItemsByName request, IEnumerable<IItemByName> items, User user, IEnumerable<BaseItem> libraryItems)
|
|
||||||
{
|
|
||||||
var filters = request.GetFilters().ToList();
|
|
||||||
|
|
||||||
if (filters.Contains(ItemFilter.IsPlayed))
|
|
||||||
{
|
|
||||||
items = items.Where(i => i.GetTaggedItems(libraryItems).All(l => l.IsPlayed(user)));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filters.Contains(ItemFilter.IsUnplayed))
|
|
||||||
{
|
|
||||||
items = items.Where(i => i.GetTaggedItems(libraryItems).All(l => l.IsUnplayed(user)));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (request.IsPlayed.HasValue)
|
|
||||||
{
|
|
||||||
var val = request.IsPlayed.Value;
|
|
||||||
|
|
||||||
items = items.Where(i => i.GetTaggedItems(libraryItems).All(l => l.IsPlayed(user)) == val);
|
|
||||||
}
|
|
||||||
|
|
||||||
return items;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Filters the items.
|
/// Filters the items.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -277,6 +277,8 @@ namespace MediaBrowser.Api.UserLibrary
|
||||||
[ApiMember(Name = "Albums", Description = "Optional. If specified, results will be filtered based on album. This allows multiple, pipe delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
|
[ApiMember(Name = "Albums", Description = "Optional. If specified, results will be filtered based on album. This allows multiple, pipe delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
|
||||||
public string Albums { get; set; }
|
public string Albums { get; set; }
|
||||||
|
|
||||||
|
public string AlbumIds { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the item ids.
|
/// Gets or sets the item ids.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -9,6 +9,7 @@ using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using MediaBrowser.Controller.Entities.Audio;
|
||||||
using MediaBrowser.Model.Globalization;
|
using MediaBrowser.Model.Globalization;
|
||||||
using MediaBrowser.Model.Services;
|
using MediaBrowser.Model.Services;
|
||||||
|
|
||||||
|
@ -359,15 +360,30 @@ namespace MediaBrowser.Api.UserLibrary
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExcludeArtistIds
|
// ExcludeArtistIds
|
||||||
if (!string.IsNullOrEmpty(request.ExcludeArtistIds))
|
if (!string.IsNullOrWhiteSpace(request.ExcludeArtistIds))
|
||||||
{
|
{
|
||||||
query.ExcludeArtistIds = request.ExcludeArtistIds.Split('|');
|
query.ExcludeArtistIds = request.ExcludeArtistIds.Split('|');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(request.AlbumIds))
|
||||||
|
{
|
||||||
|
query.AlbumIds = request.AlbumIds.Split('|');
|
||||||
|
}
|
||||||
|
|
||||||
// Albums
|
// Albums
|
||||||
if (!string.IsNullOrEmpty(request.Albums))
|
if (!string.IsNullOrEmpty(request.Albums))
|
||||||
{
|
{
|
||||||
query.AlbumNames = request.Albums.Split('|');
|
query.AlbumIds = request.Albums.Split('|').Select(i =>
|
||||||
|
{
|
||||||
|
return _libraryManager.GetItemList(new InternalItemsQuery
|
||||||
|
{
|
||||||
|
IncludeItemTypes = new[] { typeof(MusicAlbum).Name },
|
||||||
|
Name = i,
|
||||||
|
Limit = 1
|
||||||
|
|
||||||
|
}).Select(album => album.Id.ToString("N")).FirstOrDefault();
|
||||||
|
|
||||||
|
}).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Studios
|
// Studios
|
||||||
|
|
|
@ -360,7 +360,8 @@ namespace MediaBrowser.Api.UserLibrary
|
||||||
var currentUser = user;
|
var currentUser = user;
|
||||||
|
|
||||||
var dtos = series
|
var dtos = series
|
||||||
.GetRecursiveChildren(i => i is Episode && i.ParentIndexNumber.HasValue && i.ParentIndexNumber.Value == 0)
|
.GetEpisodes(user)
|
||||||
|
.Where(i => i.ParentIndexNumber.HasValue && i.ParentIndexNumber.Value == 0)
|
||||||
.OrderBy(i =>
|
.OrderBy(i =>
|
||||||
{
|
{
|
||||||
if (i.PremiereDate.HasValue)
|
if (i.PremiereDate.HasValue)
|
||||||
|
|
|
@ -156,7 +156,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
{
|
{
|
||||||
if (SupportsIsInMixedFolderDetection)
|
if (SupportsIsInMixedFolderDetection)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return IsInMixedFolder;
|
return IsInMixedFolder;
|
||||||
|
@ -2078,9 +2078,31 @@ namespace MediaBrowser.Controller.Entities
|
||||||
/// Gets the file system path to delete when the item is to be deleted
|
/// Gets the file system path to delete when the item is to be deleted
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public virtual IEnumerable<string> GetDeletePaths()
|
public virtual IEnumerable<FileSystemMetadata> GetDeletePaths()
|
||||||
{
|
{
|
||||||
return new[] { Path };
|
return new[] {
|
||||||
|
new FileSystemMetadata
|
||||||
|
{
|
||||||
|
FullName = Path,
|
||||||
|
IsDirectory = IsFolder
|
||||||
|
}
|
||||||
|
}.Concat(GetLocalMetadataFilesToDelete());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<FileSystemMetadata> GetLocalMetadataFilesToDelete()
|
||||||
|
{
|
||||||
|
if (IsFolder || !IsInMixedFolder)
|
||||||
|
{
|
||||||
|
return new List<FileSystemMetadata>();
|
||||||
|
}
|
||||||
|
|
||||||
|
var filename = System.IO.Path.GetFileNameWithoutExtension(Path);
|
||||||
|
var extensions = new[] { ".nfo", ".xml", ".srt" }.ToList();
|
||||||
|
extensions.AddRange(SupportedImageExtensionsList);
|
||||||
|
|
||||||
|
return FileSystem.GetFiles(System.IO.Path.GetDirectoryName(Path))
|
||||||
|
.Where(i => extensions.Contains(i.Extension, StringComparer.OrdinalIgnoreCase) && System.IO.Path.GetFileNameWithoutExtension(i.FullName).StartsWith(filename, StringComparison.OrdinalIgnoreCase))
|
||||||
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool AllowsMultipleImages(ImageType type)
|
public bool AllowsMultipleImages(ImageType type)
|
||||||
|
|
|
@ -4,6 +4,7 @@ using MediaBrowser.Model.Entities;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.Serialization;
|
using MediaBrowser.Model.Serialization;
|
||||||
|
|
||||||
namespace MediaBrowser.Controller.Entities
|
namespace MediaBrowser.Controller.Entities
|
||||||
|
@ -97,11 +98,17 @@ namespace MediaBrowser.Controller.Entities
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IEnumerable<string> GetDeletePaths()
|
public override IEnumerable<FileSystemMetadata> GetDeletePaths()
|
||||||
{
|
{
|
||||||
if (!DetectIsInMixedFolder())
|
if (!DetectIsInMixedFolder())
|
||||||
{
|
{
|
||||||
return new[] { System.IO.Path.GetDirectoryName(Path) };
|
return new[] {
|
||||||
|
new FileSystemMetadata
|
||||||
|
{
|
||||||
|
FullName = System.IO.Path.GetDirectoryName(Path),
|
||||||
|
IsDirectory = true
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return base.GetDeletePaths();
|
return base.GetDeletePaths();
|
||||||
|
|
|
@ -141,7 +141,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
public string ExternalSeriesId { get; set; }
|
public string ExternalSeriesId { get; set; }
|
||||||
public string ExternalId { get; set; }
|
public string ExternalId { get; set; }
|
||||||
|
|
||||||
public string[] AlbumNames { get; set; }
|
public string[] AlbumIds { get; set; }
|
||||||
public string[] ArtistIds { get; set; }
|
public string[] ArtistIds { get; set; }
|
||||||
public string[] ExcludeArtistIds { get; set; }
|
public string[] ExcludeArtistIds { get; set; }
|
||||||
public string AncestorWithPresentationUniqueKey { get; set; }
|
public string AncestorWithPresentationUniqueKey { get; set; }
|
||||||
|
@ -202,7 +202,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
EnableTotalRecordCount = true;
|
EnableTotalRecordCount = true;
|
||||||
|
|
||||||
DtoOptions = new DtoOptions();
|
DtoOptions = new DtoOptions();
|
||||||
AlbumNames = new string[] { };
|
AlbumIds = new string[] { };
|
||||||
ArtistIds = new string[] { };
|
ArtistIds = new string[] { };
|
||||||
ExcludeArtistIds = new string[] { };
|
ExcludeArtistIds = new string[] { };
|
||||||
ExcludeProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
ExcludeProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
|
@ -5,6 +5,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.Serialization;
|
using MediaBrowser.Model.Serialization;
|
||||||
|
|
||||||
namespace MediaBrowser.Controller.Entities.TV
|
namespace MediaBrowser.Controller.Entities.TV
|
||||||
|
@ -319,10 +320,16 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IEnumerable<string> GetDeletePaths()
|
public override IEnumerable<FileSystemMetadata> GetDeletePaths()
|
||||||
{
|
{
|
||||||
return new[] { Path };
|
return new[] {
|
||||||
}
|
new FileSystemMetadata
|
||||||
|
{
|
||||||
|
FullName = Path,
|
||||||
|
IsDirectory = IsFolder
|
||||||
|
}
|
||||||
|
}.Concat(GetLocalMetadataFilesToDelete());
|
||||||
|
}
|
||||||
|
|
||||||
public override UnratedItem GetBlockUnratedType()
|
public override UnratedItem GetBlockUnratedType()
|
||||||
{
|
{
|
||||||
|
@ -338,7 +345,6 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||||
if (series != null)
|
if (series != null)
|
||||||
{
|
{
|
||||||
id.SeriesProviderIds = series.ProviderIds;
|
id.SeriesProviderIds = series.ProviderIds;
|
||||||
id.AnimeSeriesIndex = series.AnimeSeriesIndex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
id.IsMissingEpisode = IsMissingEpisode;
|
id.IsMissingEpisode = IsMissingEpisode;
|
||||||
|
|
|
@ -251,7 +251,6 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||||
if (series != null)
|
if (series != null)
|
||||||
{
|
{
|
||||||
id.SeriesProviderIds = series.ProviderIds;
|
id.SeriesProviderIds = series.ProviderIds;
|
||||||
id.AnimeSeriesIndex = series.AnimeSeriesIndex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
|
|
|
@ -19,8 +19,6 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Series : Folder, IHasTrailers, IHasDisplayOrder, IHasLookupInfo<SeriesInfo>, IMetadataContainer
|
public class Series : Folder, IHasTrailers, IHasDisplayOrder, IHasLookupInfo<SeriesInfo>, IMetadataContainer
|
||||||
{
|
{
|
||||||
public int? AnimeSeriesIndex { get; set; }
|
|
||||||
|
|
||||||
public Series()
|
public Series()
|
||||||
{
|
{
|
||||||
AirDays = new List<DayOfWeek>();
|
AirDays = new List<DayOfWeek>();
|
||||||
|
@ -554,8 +552,6 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||||
{
|
{
|
||||||
var info = GetItemLookupInfo<SeriesInfo>();
|
var info = GetItemLookupInfo<SeriesInfo>();
|
||||||
|
|
||||||
info.AnimeSeriesIndex = AnimeSeriesIndex;
|
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1719,53 +1719,6 @@ namespace MediaBrowser.Controller.Entities
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Artists
|
|
||||||
if (query.ArtistIds.Length > 0)
|
|
||||||
{
|
|
||||||
var audio = item as IHasArtist;
|
|
||||||
|
|
||||||
//if (!(audio != null && query.ArtistNames.Any(audio.HasAnyArtist)))
|
|
||||||
//{
|
|
||||||
// return false;
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Albums
|
|
||||||
if (query.AlbumNames.Length > 0)
|
|
||||||
{
|
|
||||||
var audio = item as Audio.Audio;
|
|
||||||
|
|
||||||
if (audio != null)
|
|
||||||
{
|
|
||||||
if (!query.AlbumNames.Any(a => string.Equals(a, audio.Album, StringComparison.OrdinalIgnoreCase)))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var album = item as MusicAlbum;
|
|
||||||
|
|
||||||
if (album != null)
|
|
||||||
{
|
|
||||||
if (!query.AlbumNames.Any(a => string.Equals(a, album.Name, StringComparison.OrdinalIgnoreCase)))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var musicVideo = item as MusicVideo;
|
|
||||||
|
|
||||||
if (musicVideo != null)
|
|
||||||
{
|
|
||||||
if (!query.AlbumNames.Any(a => string.Equals(a, musicVideo.Album, StringComparison.OrdinalIgnoreCase)))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -477,11 +477,17 @@ namespace MediaBrowser.Controller.Entities
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IEnumerable<string> GetDeletePaths()
|
public override IEnumerable<FileSystemMetadata> GetDeletePaths()
|
||||||
{
|
{
|
||||||
if (!DetectIsInMixedFolder())
|
if (!DetectIsInMixedFolder())
|
||||||
{
|
{
|
||||||
return new[] { ContainingFolderPath };
|
return new[] {
|
||||||
|
new FileSystemMetadata
|
||||||
|
{
|
||||||
|
FullName = System.IO.Path.GetDirectoryName(Path),
|
||||||
|
IsDirectory = true
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return base.GetDeletePaths();
|
return base.GetDeletePaths();
|
||||||
|
|
|
@ -8,7 +8,6 @@ namespace MediaBrowser.Controller.Providers
|
||||||
public Dictionary<string, string> SeriesProviderIds { get; set; }
|
public Dictionary<string, string> SeriesProviderIds { get; set; }
|
||||||
|
|
||||||
public int? IndexNumberEnd { get; set; }
|
public int? IndexNumberEnd { get; set; }
|
||||||
public int? AnimeSeriesIndex { get; set; }
|
|
||||||
|
|
||||||
public bool IsMissingEpisode { get; set; }
|
public bool IsMissingEpisode { get; set; }
|
||||||
public bool IsVirtualUnaired { get; set; }
|
public bool IsVirtualUnaired { get; set; }
|
||||||
|
|
|
@ -6,7 +6,6 @@ namespace MediaBrowser.Controller.Providers
|
||||||
public class SeasonInfo : ItemLookupInfo
|
public class SeasonInfo : ItemLookupInfo
|
||||||
{
|
{
|
||||||
public Dictionary<string, string> SeriesProviderIds { get; set; }
|
public Dictionary<string, string> SeriesProviderIds { get; set; }
|
||||||
public int? AnimeSeriesIndex { get; set; }
|
|
||||||
|
|
||||||
public SeasonInfo()
|
public SeasonInfo()
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,6 +2,5 @@ namespace MediaBrowser.Controller.Providers
|
||||||
{
|
{
|
||||||
public class SeriesInfo : ItemLookupInfo
|
public class SeriesInfo : ItemLookupInfo
|
||||||
{
|
{
|
||||||
public int? AnimeSeriesIndex { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -69,21 +69,6 @@ namespace MediaBrowser.LocalMetadata.Parsers
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case "AnimeSeriesIndex":
|
|
||||||
{
|
|
||||||
var number = reader.ReadElementContentAsString();
|
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(number))
|
|
||||||
{
|
|
||||||
int num;
|
|
||||||
|
|
||||||
if (int.TryParse(number, out num))
|
|
||||||
{
|
|
||||||
item.AnimeSeriesIndex = num;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "Status":
|
case "Status":
|
||||||
{
|
{
|
||||||
var status = reader.ReadElementContentAsString();
|
var status = reader.ReadElementContentAsString();
|
||||||
|
|
|
@ -606,9 +606,20 @@ namespace MediaBrowser.Model.Dlna
|
||||||
return playlistItem;
|
return playlistItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int GetDefaultAudioBitrateIfUnknown(MediaStream audioStream)
|
||||||
|
{
|
||||||
|
if ((audioStream.Channels ?? 0) >= 6)
|
||||||
|
{
|
||||||
|
return 384000;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 192000;
|
||||||
|
}
|
||||||
|
|
||||||
private int GetAudioBitrate(string subProtocol, long? maxTotalBitrate, int? targetAudioChannels, string targetAudioCodec, MediaStream audioStream)
|
private int GetAudioBitrate(string subProtocol, long? maxTotalBitrate, int? targetAudioChannels, string targetAudioCodec, MediaStream audioStream)
|
||||||
{
|
{
|
||||||
int defaultBitrate = audioStream == null ? 192000 : audioStream.BitRate ?? 192000;
|
int defaultBitrate = audioStream == null ? 192000 : audioStream.BitRate ?? GetDefaultAudioBitrateIfUnknown(audioStream);
|
||||||
|
|
||||||
// Reduce the bitrate if we're downmixing
|
// Reduce the bitrate if we're downmixing
|
||||||
if (targetAudioChannels.HasValue && audioStream != null && audioStream.Channels.HasValue && targetAudioChannels.Value < audioStream.Channels.Value)
|
if (targetAudioChannels.HasValue && audioStream != null && audioStream.Channels.HasValue && targetAudioChannels.Value < audioStream.Channels.Value)
|
||||||
{
|
{
|
||||||
|
|
|
@ -85,8 +85,6 @@ namespace MediaBrowser.Model.Dto
|
||||||
public float? Metascore { get; set; }
|
public float? Metascore { get; set; }
|
||||||
public bool? HasDynamicCategories { get; set; }
|
public bool? HasDynamicCategories { get; set; }
|
||||||
|
|
||||||
public int? AnimeSeriesIndex { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a value indicating whether [supports synchronize].
|
/// Gets or sets a value indicating whether [supports synchronize].
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -263,7 +261,7 @@ namespace MediaBrowser.Model.Dto
|
||||||
/// Gets or sets the play access.
|
/// Gets or sets the play access.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The play access.</value>
|
/// <value>The play access.</value>
|
||||||
public PlayAccess PlayAccess { get; set; }
|
public PlayAccess? PlayAccess { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the aspect ratio.
|
/// Gets or sets the aspect ratio.
|
||||||
|
@ -759,7 +757,7 @@ namespace MediaBrowser.Model.Dto
|
||||||
/// Gets or sets the type of the location.
|
/// Gets or sets the type of the location.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The type of the location.</value>
|
/// <value>The type of the location.</value>
|
||||||
public LocationType LocationType { get; set; }
|
public LocationType? LocationType { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the type of the iso.
|
/// Gets or sets the type of the iso.
|
||||||
|
|
|
@ -96,8 +96,7 @@ namespace MediaBrowser.Providers.TV
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
int seasonNumber = AdjustForSeriesOffset(series, season.IndexNumber.Value);
|
AddImages(list, season.IndexNumber.Value, path, cancellationToken);
|
||||||
AddImages(list, seasonNumber, path, cancellationToken);
|
|
||||||
}
|
}
|
||||||
catch (FileNotFoundException)
|
catch (FileNotFoundException)
|
||||||
{
|
{
|
||||||
|
@ -139,15 +138,6 @@ namespace MediaBrowser.Providers.TV
|
||||||
.ThenByDescending(i => i.VoteCount ?? 0);
|
.ThenByDescending(i => i.VoteCount ?? 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int AdjustForSeriesOffset(Series series, int seasonNumber)
|
|
||||||
{
|
|
||||||
var offset = TvdbSeriesProvider.GetSeriesOffset(series.ProviderIds);
|
|
||||||
if (offset != null)
|
|
||||||
return (int)(seasonNumber + offset);
|
|
||||||
|
|
||||||
return seasonNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddImages(List<RemoteImageInfo> list, int seasonNumber, string path, CancellationToken cancellationToken)
|
private void AddImages(List<RemoteImageInfo> list, int seasonNumber, string path, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var root = _json.DeserializeFromFile<FanartSeriesProvider.RootObject>(path);
|
var root = _json.DeserializeFromFile<FanartSeriesProvider.RootObject>(path);
|
||||||
|
|
|
@ -203,9 +203,8 @@ namespace MediaBrowser.Providers.TV
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var existingEpisodes = (from s in series
|
var existingEpisodes = (from s in series
|
||||||
let seasonOffset = TvdbSeriesProvider.GetSeriesOffset(s.ProviderIds) ?? ((s.AnimeSeriesIndex ?? 1) - 1)
|
|
||||||
from c in s.GetRecursiveChildren().OfType<Episode>()
|
from c in s.GetRecursiveChildren().OfType<Episode>()
|
||||||
select new Tuple<int, Episode>((c.ParentIndexNumber ?? 0) + seasonOffset, c))
|
select new Tuple<int, Episode>((c.ParentIndexNumber ?? 0) , c))
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
var lookup = episodeLookup as IList<Tuple<int, int>> ?? episodeLookup.ToList();
|
var lookup = episodeLookup as IList<Tuple<int, int>> ?? episodeLookup.ToList();
|
||||||
|
@ -248,7 +247,6 @@ namespace MediaBrowser.Providers.TV
|
||||||
var now = DateTime.UtcNow;
|
var now = DateTime.UtcNow;
|
||||||
|
|
||||||
var targetSeries = DetermineAppropriateSeries(series, tuple.Item1);
|
var targetSeries = DetermineAppropriateSeries(series, tuple.Item1);
|
||||||
var seasonOffset = TvdbSeriesProvider.GetSeriesOffset(targetSeries.ProviderIds) ?? ((targetSeries.AnimeSeriesIndex ?? 1) - 1);
|
|
||||||
|
|
||||||
var unairedThresholdDays = 2;
|
var unairedThresholdDays = 2;
|
||||||
now = now.AddDays(0 - unairedThresholdDays);
|
now = now.AddDays(0 - unairedThresholdDays);
|
||||||
|
@ -259,7 +257,7 @@ namespace MediaBrowser.Providers.TV
|
||||||
{
|
{
|
||||||
// tvdb has a lot of nearly blank episodes
|
// tvdb has a lot of nearly blank episodes
|
||||||
_logger.Info("Creating virtual missing episode {0} {1}x{2}", targetSeries.Name, tuple.Item1, tuple.Item2);
|
_logger.Info("Creating virtual missing episode {0} {1}x{2}", targetSeries.Name, tuple.Item1, tuple.Item2);
|
||||||
await AddEpisode(targetSeries, tuple.Item1 - seasonOffset, tuple.Item2, cancellationToken).ConfigureAwait(false);
|
await AddEpisode(targetSeries, tuple.Item1, tuple.Item2, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
hasChanges = true;
|
hasChanges = true;
|
||||||
}
|
}
|
||||||
|
@ -268,7 +266,7 @@ namespace MediaBrowser.Providers.TV
|
||||||
{
|
{
|
||||||
// tvdb has a lot of nearly blank episodes
|
// tvdb has a lot of nearly blank episodes
|
||||||
_logger.Info("Creating virtual unaired episode {0} {1}x{2}", targetSeries.Name, tuple.Item1, tuple.Item2);
|
_logger.Info("Creating virtual unaired episode {0} {1}x{2}", targetSeries.Name, tuple.Item1, tuple.Item2);
|
||||||
await AddEpisode(targetSeries, tuple.Item1 - seasonOffset, tuple.Item2, cancellationToken).ConfigureAwait(false);
|
await AddEpisode(targetSeries, tuple.Item1, tuple.Item2, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
hasChanges = true;
|
hasChanges = true;
|
||||||
}
|
}
|
||||||
|
@ -279,13 +277,11 @@ namespace MediaBrowser.Providers.TV
|
||||||
|
|
||||||
private Series DetermineAppropriateSeries(IEnumerable<Series> series, int seasonNumber)
|
private Series DetermineAppropriateSeries(IEnumerable<Series> series, int seasonNumber)
|
||||||
{
|
{
|
||||||
var seriesAndOffsets = series.Select(s => new { Series = s, SeasonOffset = TvdbSeriesProvider.GetSeriesOffset(s.ProviderIds) ?? ((s.AnimeSeriesIndex ?? 1) - 1) }).ToList();
|
var seriesAndOffsets = series.ToList();
|
||||||
|
|
||||||
var bestMatch = seriesAndOffsets.FirstOrDefault(s => s.Series.GetRecursiveChildren().OfType<Season>().Any(season => (season.IndexNumber + s.SeasonOffset) == seasonNumber)) ??
|
return seriesAndOffsets.FirstOrDefault(s => s.GetRecursiveChildren().OfType<Season>().Any(season => (season.IndexNumber) == seasonNumber)) ??
|
||||||
seriesAndOffsets.FirstOrDefault(s => s.Series.GetRecursiveChildren().OfType<Season>().Any(season => (season.IndexNumber + s.SeasonOffset) == 1)) ??
|
seriesAndOffsets.FirstOrDefault(s => s.GetRecursiveChildren().OfType<Season>().Any(season => (season.IndexNumber) == 1)) ??
|
||||||
seriesAndOffsets.OrderBy(s => s.Series.GetRecursiveChildren().OfType<Season>().Select(season => season.IndexNumber + s.SeasonOffset).Min()).First();
|
seriesAndOffsets.OrderBy(s => s.GetRecursiveChildren().OfType<Season>().Select(season => season.IndexNumber).Min()).First();
|
||||||
|
|
||||||
return bestMatch.Series;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -296,9 +292,8 @@ namespace MediaBrowser.Providers.TV
|
||||||
bool allowMissingEpisodes)
|
bool allowMissingEpisodes)
|
||||||
{
|
{
|
||||||
var existingEpisodes = (from s in series
|
var existingEpisodes = (from s in series
|
||||||
let seasonOffset = TvdbSeriesProvider.GetSeriesOffset(s.ProviderIds) ?? ((s.AnimeSeriesIndex ?? 1) - 1)
|
|
||||||
from c in s.GetRecursiveChildren().OfType<Episode>()
|
from c in s.GetRecursiveChildren().OfType<Episode>()
|
||||||
select new { SeasonOffset = seasonOffset, Episode = c })
|
select new { Episode = c })
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
var physicalEpisodes = existingEpisodes
|
var physicalEpisodes = existingEpisodes
|
||||||
|
@ -314,12 +309,12 @@ namespace MediaBrowser.Providers.TV
|
||||||
{
|
{
|
||||||
if (i.Episode.IndexNumber.HasValue && i.Episode.ParentIndexNumber.HasValue)
|
if (i.Episode.IndexNumber.HasValue && i.Episode.ParentIndexNumber.HasValue)
|
||||||
{
|
{
|
||||||
var seasonNumber = i.Episode.ParentIndexNumber.Value + i.SeasonOffset;
|
var seasonNumber = i.Episode.ParentIndexNumber.Value;
|
||||||
var episodeNumber = i.Episode.IndexNumber.Value;
|
var episodeNumber = i.Episode.IndexNumber.Value;
|
||||||
|
|
||||||
// If there's a physical episode with the same season and episode number, delete it
|
// If there's a physical episode with the same season and episode number, delete it
|
||||||
if (physicalEpisodes.Any(p =>
|
if (physicalEpisodes.Any(p =>
|
||||||
p.Episode.ParentIndexNumber.HasValue && (p.Episode.ParentIndexNumber.Value + p.SeasonOffset) == seasonNumber &&
|
p.Episode.ParentIndexNumber.HasValue && (p.Episode.ParentIndexNumber.Value) == seasonNumber &&
|
||||||
p.Episode.ContainsEpisodeNumber(episodeNumber)))
|
p.Episode.ContainsEpisodeNumber(episodeNumber)))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
@ -371,28 +366,27 @@ namespace MediaBrowser.Providers.TV
|
||||||
IEnumerable<Tuple<int, int>> episodeLookup)
|
IEnumerable<Tuple<int, int>> episodeLookup)
|
||||||
{
|
{
|
||||||
var existingSeasons = (from s in series
|
var existingSeasons = (from s in series
|
||||||
let seasonOffset = TvdbSeriesProvider.GetSeriesOffset(s.ProviderIds) ?? ((s.AnimeSeriesIndex ?? 1) - 1)
|
|
||||||
from c in s.Children.OfType<Season>()
|
from c in s.Children.OfType<Season>()
|
||||||
select new { SeasonOffset = seasonOffset, Season = c })
|
select c)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
var physicalSeasons = existingSeasons
|
var physicalSeasons = existingSeasons
|
||||||
.Where(i => i.Season.LocationType != LocationType.Virtual)
|
.Where(i => i.LocationType != LocationType.Virtual)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
var virtualSeasons = existingSeasons
|
var virtualSeasons = existingSeasons
|
||||||
.Where(i => i.Season.LocationType == LocationType.Virtual)
|
.Where(i => i.LocationType == LocationType.Virtual)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
var seasonsToRemove = virtualSeasons
|
var seasonsToRemove = virtualSeasons
|
||||||
.Where(i =>
|
.Where(i =>
|
||||||
{
|
{
|
||||||
if (i.Season.IndexNumber.HasValue)
|
if (i.IndexNumber.HasValue)
|
||||||
{
|
{
|
||||||
var seasonNumber = i.Season.IndexNumber.Value + i.SeasonOffset;
|
var seasonNumber = i.IndexNumber.Value;
|
||||||
|
|
||||||
// If there's a physical season with the same number, delete it
|
// If there's a physical season with the same number, delete it
|
||||||
if (physicalSeasons.Any(p => p.Season.IndexNumber.HasValue && (p.Season.IndexNumber.Value + p.SeasonOffset) == seasonNumber && string.Equals(p.Season.Series.PresentationUniqueKey, i.Season.Series.PresentationUniqueKey, StringComparison.Ordinal)))
|
if (physicalSeasons.Any(p => p.IndexNumber.HasValue && (p.IndexNumber.Value) == seasonNumber && string.Equals(p.Series.PresentationUniqueKey, i.Series.PresentationUniqueKey, StringComparison.Ordinal)))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -408,13 +402,13 @@ namespace MediaBrowser.Providers.TV
|
||||||
|
|
||||||
// Season does not have a number
|
// Season does not have a number
|
||||||
// Remove if there are no episodes directly in series without a season number
|
// Remove if there are no episodes directly in series without a season number
|
||||||
return i.Season.Series.GetRecursiveChildren().OfType<Episode>().All(s => s.ParentIndexNumber.HasValue || s.IsInSeasonFolder);
|
return i.Series.GetRecursiveChildren().OfType<Episode>().All(s => s.ParentIndexNumber.HasValue || s.IsInSeasonFolder);
|
||||||
})
|
})
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
var hasChanges = false;
|
var hasChanges = false;
|
||||||
|
|
||||||
foreach (var seasonToRemove in seasonsToRemove.Select(s => s.Season))
|
foreach (var seasonToRemove in seasonsToRemove)
|
||||||
{
|
{
|
||||||
_logger.Info("Removing virtual season {0} {1}", seasonToRemove.Series.Name, seasonToRemove.IndexNumber);
|
_logger.Info("Removing virtual season {0} {1}", seasonToRemove.Series.Name, seasonToRemove.IndexNumber);
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,6 @@ namespace MediaBrowser.Providers.TV
|
||||||
{
|
{
|
||||||
// Process images
|
// Process images
|
||||||
var seriesDataPath = TvdbSeriesProvider.GetSeriesDataPath(_config.ApplicationPaths, series.ProviderIds);
|
var seriesDataPath = TvdbSeriesProvider.GetSeriesDataPath(_config.ApplicationPaths, series.ProviderIds);
|
||||||
var indexOffset = TvdbSeriesProvider.GetSeriesOffset(series.ProviderIds) ?? 0;
|
|
||||||
|
|
||||||
var nodes = TvdbEpisodeProvider.Current.GetEpisodeXmlNodes(seriesDataPath, episode.GetLookupInfo());
|
var nodes = TvdbEpisodeProvider.Current.GetEpisodeXmlNodes(seriesDataPath, episode.GetLookupInfo());
|
||||||
|
|
||||||
|
|
|
@ -99,15 +99,6 @@ namespace MediaBrowser.Providers.TV
|
||||||
return new RemoteImageInfo[] { };
|
return new RemoteImageInfo[] { };
|
||||||
}
|
}
|
||||||
|
|
||||||
private int AdjustForSeriesOffset(Series series, int seasonNumber)
|
|
||||||
{
|
|
||||||
var offset = TvdbSeriesProvider.GetSeriesOffset(series.ProviderIds);
|
|
||||||
if (offset != null)
|
|
||||||
return (seasonNumber + offset.Value);
|
|
||||||
|
|
||||||
return seasonNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static IEnumerable<RemoteImageInfo> GetImages(string xmlPath, string preferredLanguage, int seasonNumber, IXmlReaderSettingsFactory xmlReaderSettingsFactory, IFileSystem fileSystem, CancellationToken cancellationToken)
|
internal static IEnumerable<RemoteImageInfo> GetImages(string xmlPath, string preferredLanguage, int seasonNumber, IXmlReaderSettingsFactory xmlReaderSettingsFactory, IFileSystem fileSystem, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var settings = xmlReaderSettingsFactory.Create(false);
|
var settings = xmlReaderSettingsFactory.Create(false);
|
||||||
|
|
|
@ -76,10 +76,6 @@ namespace MediaBrowser.Providers.TV
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var seriesOffset = TvdbSeriesProvider.GetSeriesOffset(item.ProviderIds);
|
|
||||||
if (seriesOffset != null && seriesOffset.Value != 0)
|
|
||||||
return TvdbSeasonImageProvider.GetImages(path, language, seriesOffset.Value + 1, _xmlReaderSettingsFactory, _fileSystem, cancellationToken);
|
|
||||||
|
|
||||||
return GetImages(path, language, cancellationToken);
|
return GetImages(path, language, cancellationToken);
|
||||||
}
|
}
|
||||||
catch (FileNotFoundException)
|
catch (FileNotFoundException)
|
||||||
|
|
|
@ -27,9 +27,6 @@ namespace MediaBrowser.Providers.TV
|
||||||
{
|
{
|
||||||
public class TvdbSeriesProvider : IRemoteMetadataProvider<Series, SeriesInfo>, IHasOrder
|
public class TvdbSeriesProvider : IRemoteMetadataProvider<Series, SeriesInfo>, IHasOrder
|
||||||
{
|
{
|
||||||
private const string TvdbSeriesOffset = "TvdbSeriesOffset";
|
|
||||||
private const string TvdbSeriesOffsetFormat = "{0}-{1}";
|
|
||||||
|
|
||||||
internal readonly SemaphoreSlim TvDbResourcePool = new SemaphoreSlim(2, 2);
|
internal readonly SemaphoreSlim TvDbResourcePool = new SemaphoreSlim(2, 2);
|
||||||
internal static TvdbSeriesProvider Current { get; private set; }
|
internal static TvdbSeriesProvider Current { get; private set; }
|
||||||
private readonly IZipClient _zipClient;
|
private readonly IZipClient _zipClient;
|
||||||
|
@ -123,23 +120,6 @@ namespace MediaBrowser.Providers.TV
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static int? GetSeriesOffset(Dictionary<string, string> seriesProviderIds)
|
|
||||||
{
|
|
||||||
string idString;
|
|
||||||
if (!seriesProviderIds.TryGetValue(TvdbSeriesOffset, out idString))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
var parts = idString.Split('-');
|
|
||||||
if (parts.Length < 2)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
int offset;
|
|
||||||
if (int.TryParse(parts[1], out offset))
|
|
||||||
return offset;
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Fetches the series data.
|
/// Fetches the series data.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -65,22 +65,6 @@ namespace MediaBrowser.XbmcMetadata.Parsers
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case "animeseriesindex":
|
|
||||||
{
|
|
||||||
var number = reader.ReadElementContentAsString();
|
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(number))
|
|
||||||
{
|
|
||||||
int num;
|
|
||||||
|
|
||||||
if (int.TryParse(number, out num))
|
|
||||||
{
|
|
||||||
item.AnimeSeriesIndex = num;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case "status":
|
case "status":
|
||||||
{
|
{
|
||||||
var status = reader.ReadElementContentAsString();
|
var status = reader.ReadElementContentAsString();
|
||||||
|
|
|
@ -83,11 +83,6 @@ namespace MediaBrowser.XbmcMetadata.Savers
|
||||||
{
|
{
|
||||||
writer.WriteElementString("airs_dayofweek", series.AirDays[0].ToString());
|
writer.WriteElementString("airs_dayofweek", series.AirDays[0].ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (series.AnimeSeriesIndex.HasValue)
|
|
||||||
{
|
|
||||||
writer.WriteElementString("animeseriesindex", series.AnimeSeriesIndex.Value.ToString(CultureInfo.InvariantCulture));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override List<string> GetTagsUsed(IHasMetadata item)
|
protected override List<string> GetTagsUsed(IHasMetadata item)
|
||||||
|
@ -101,8 +96,7 @@ namespace MediaBrowser.XbmcMetadata.Savers
|
||||||
"episode",
|
"episode",
|
||||||
"status",
|
"status",
|
||||||
"airs_time",
|
"airs_time",
|
||||||
"airs_dayofweek",
|
"airs_dayofweek"
|
||||||
"animeseriesindex"
|
|
||||||
});
|
});
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user