Merge pull request #2476 from MediaBrowser/dev

Dev
This commit is contained in:
Luke 2017-02-18 03:33:34 -05:00 committed by GitHub
commit 0c4f78be3a
47 changed files with 469 additions and 357 deletions

View File

@ -863,7 +863,7 @@ namespace Emby.Server.Core
/// </summary>
private void ConfigureNotificationsRepository()
{
var repo = new SqliteNotificationsRepository(LogManager.GetLogger("SqliteNotificationsRepository"), ServerConfigurationManager.ApplicationPaths);
var repo = new SqliteNotificationsRepository(LogManager.GetLogger("SqliteNotificationsRepository"), ServerConfigurationManager.ApplicationPaths, FileSystemManager);
repo.Initialize();

View File

@ -3874,6 +3874,25 @@ namespace Emby.Server.Implementations.Data
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)
{
var clauses = new List<string>();
@ -4227,30 +4246,6 @@ namespace Emby.Server.Implementations.Data
{
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.Value)

View File

@ -492,7 +492,10 @@ namespace Emby.Server.Implementations.Dto
}
}
//if (!(item is LiveTvProgram))
{
dto.PlayAccess = item.GetPlayAccess(user);
}
if (fields.Contains(ItemFields.BasicSyncInfo) || fields.Contains(ItemFields.SyncInfo))
{
@ -994,7 +997,12 @@ namespace Emby.Server.Implementations.Dto
}
dto.MediaType = item.MediaType;
if (!(item is LiveTvProgram))
{
dto.LocationType = item.LocationType;
}
if (item.IsHD.HasValue && item.IsHD.Value)
{
dto.IsHD = item.IsHD;
@ -1102,7 +1110,10 @@ namespace Emby.Server.Implementations.Dto
}
dto.Type = item.GetClientTypeName();
if ((item.CommunityRating ?? 0) > 0)
{
dto.CommunityRating = item.CommunityRating;
}
if (fields.Contains(ItemFields.VoteCount))
{
@ -1410,8 +1421,6 @@ namespace Emby.Server.Implementations.Dto
dto.AirDays = series.AirDays;
dto.AirTime = series.AirTime;
dto.SeriesStatus = series.Status;
dto.AnimeSeriesIndex = series.AnimeSeriesIndex;
}
// Add SeasonInfo
@ -1473,10 +1482,13 @@ namespace Emby.Server.Implementations.Dto
SetBookProperties(dto, book);
}
if (fields.Contains(ItemFields.ProductionLocations))
{
if (item.ProductionLocations.Count > 0 || item is Movie)
{
dto.ProductionLocations = item.ProductionLocations.ToArray();
}
}
var photo = item as Photo;
if (photo != null)

View File

@ -409,17 +409,17 @@ namespace Emby.Server.Implementations.Library
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);
_fileSystem.DeleteDirectory(path, true);
_logger.Debug("Deleting path {0}", fileSystemInfo.FullName);
_fileSystem.DeleteDirectory(fileSystemInfo.FullName, true);
}
else if (_fileSystem.FileExists(path))
else
{
_logger.Debug("Deleting path {0}", path);
_fileSystem.DeleteFile(path);
_logger.Debug("Deleting path {0}", fileSystemInfo.FullName);
_fileSystem.DeleteFile(fileSystemInfo.FullName);
}
}
@ -818,30 +818,6 @@ namespace Emby.Server.Implementations.Library
return _userRootFolder;
}
public Guid? FindIdByPath(string path, bool? isFolder)
{
// If this returns multiple items it could be tricky figuring out which one is correct.
// In most cases, the newest one will be and the others obsolete but not yet cleaned up
var query = new InternalItemsQuery
{
Path = path,
IsFolder = isFolder,
SortBy = new[] { ItemSortBy.DateCreated },
SortOrder = SortOrder.Descending,
Limit = 1
};
var id = GetItemIds(query);
if (id.Count == 0)
{
return null;
}
return id[0];
}
public BaseItem FindByPath(string path, bool? isFolder)
{
// If this returns multiple items it could be tricky figuring out which one is correct.

View File

@ -248,6 +248,13 @@ namespace Emby.Server.Implementations.Library
}
}
var isPlayed = request.IsPlayed;
if (parents.OfType<ICollectionFolder>().Any(i => string.Equals(i.CollectionType, CollectionType.Music, StringComparison.OrdinalIgnoreCase)))
{
isPlayed = null;
}
if (parents.Count == 0)
{
parents = user.RootFolder.GetChildren(user, true)
@ -282,7 +289,7 @@ namespace Emby.Server.Implementations.Library
IsVirtualItem = false,
Limit = limit * 5,
SourceTypes = parents.Count == 0 ? new[] { SourceType.Library } : new SourceType[] { },
IsPlayed = request.IsPlayed
IsPlayed = isPlayed
}, parents);
}

View File

@ -1172,7 +1172,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
};
var isAudio = false;
await new LiveStreamHelper(_mediaEncoder, _logger).AddMediaInfoWithProbe(stream, isAudio, false, cancellationToken).ConfigureAwait(false);
await new LiveStreamHelper(_mediaEncoder, _logger).AddMediaInfoWithProbe(stream, isAudio, cancellationToken).ConfigureAwait(false);
return new List<MediaSourceInfo>
{

View File

@ -260,7 +260,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
{
_logger.Info("Calling recording process.WaitForExit for {0}", _targetPath);
if (_process.WaitForExit(5000))
if (_process.WaitForExit(10000))
{
return;
}

View File

@ -22,7 +22,7 @@ namespace Emby.Server.Implementations.LiveTv
_logger = logger;
}
public async Task AddMediaInfoWithProbe(MediaSourceInfo mediaSource, bool isAudio, bool assumeInterlaced, CancellationToken cancellationToken)
public async Task AddMediaInfoWithProbe(MediaSourceInfo mediaSource, bool isAudio, CancellationToken cancellationToken)
{
var originalRuntime = mediaSource.RunTimeTicks;
@ -96,17 +96,6 @@ namespace Emby.Server.Implementations.LiveTv
videoStream.IsAVC = null;
}
if (assumeInterlaced)
{
foreach (var mediaStream in mediaSource.MediaStreams)
{
if (mediaStream.Type == MediaStreamType.Video)
{
mediaStream.IsInterlaced = true;
}
}
}
// Try to estimate this
mediaSource.InferTotalBitrate(true);
}

View File

@ -607,6 +607,10 @@ namespace Emby.Server.Implementations.LiveTv
item.Audio = info.Audio;
item.ChannelId = channel.Id.ToString("N");
item.CommunityRating = item.CommunityRating ?? info.CommunityRating;
if ((item.CommunityRating ?? 0).Equals(0))
{
item.CommunityRating = null;
}
item.EpisodeTitle = info.EpisodeTitle;
item.ExternalId = info.Id;

View File

@ -126,14 +126,12 @@ namespace Emby.Server.Implementations.LiveTv
var keys = openToken.Split(new[] { StreamIdDelimeter }, 3);
var mediaSourceId = keys.Length >= 3 ? keys[2] : null;
IDirectStreamProvider directStreamProvider = null;
var assumeInterlaced = false;
if (string.Equals(keys[0], typeof(LiveTvChannel).Name, StringComparison.OrdinalIgnoreCase))
{
var info = await _liveTvManager.GetChannelStream(keys[1], mediaSourceId, cancellationToken).ConfigureAwait(false);
stream = info.Item1;
directStreamProvider = info.Item2;
assumeInterlaced = info.Item3;
}
else
{
@ -148,7 +146,7 @@ namespace Emby.Server.Implementations.LiveTv
}
else
{
await new LiveStreamHelper(_mediaEncoder, _logger).AddMediaInfoWithProbe(stream, isAudio, assumeInterlaced, cancellationToken).ConfigureAwait(false);
await new LiveStreamHelper(_mediaEncoder, _logger).AddMediaInfoWithProbe(stream, isAudio, cancellationToken).ConfigureAwait(false);
}
}
catch (Exception ex)

View File

@ -8,6 +8,7 @@ using System.Threading.Tasks;
using Emby.Server.Implementations.Data;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Notifications;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Notifications;
using SQLitePCL.pretty;
@ -16,8 +17,11 @@ namespace Emby.Server.Implementations.Notifications
{
public class SqliteNotificationsRepository : BaseSqliteRepository, INotificationsRepository
{
public SqliteNotificationsRepository(ILogger logger, IServerApplicationPaths appPaths) : base(logger)
protected IFileSystem FileSystem { get; private set; }
public SqliteNotificationsRepository(ILogger logger, IServerApplicationPaths appPaths, IFileSystem fileSystem) : base(logger)
{
FileSystem = fileSystem;
DbFilePath = Path.Combine(appPaths.DataPath, "notifications.db");
}
@ -26,6 +30,22 @@ namespace Emby.Server.Implementations.Notifications
////public event EventHandler<NotificationUpdateEventArgs> NotificationUpdated;
public void Initialize()
{
try
{
InitializeInternal();
}
catch (Exception ex)
{
Logger.ErrorException("Error loading notifications database file. Will reset and retry.", ex);
FileSystem.DeleteFile(DbFilePath);
InitializeInternal();
}
}
private void InitializeInternal()
{
using (var connection = CreateConnection())
{

View File

@ -59,6 +59,7 @@
<Compile Include="IHasDtoOptions.cs" />
<Compile Include="Playback\MediaInfoService.cs" />
<Compile Include="Playback\TranscodingThrottler.cs" />
<Compile Include="Playback\UniversalAudioService.cs" />
<Compile Include="PlaylistService.cs" />
<Compile Include="Reports\Activities\ReportActivitiesBuilder.cs" />
<Compile Include="Reports\Common\HeaderActivitiesMetadata.cs" />

View File

@ -126,14 +126,10 @@ namespace MediaBrowser.Api.Playback
/// <summary>
/// Gets the output file path.
/// </summary>
/// <param name="state">The state.</param>
/// <returns>System.String.</returns>
private string GetOutputFilePath(StreamState state)
private string GetOutputFilePath(StreamState state, string outputFileExtension)
{
var folder = ServerConfigurationManager.ApplicationPaths.TranscodingTempPath;
var outputFileExtension = GetOutputFileExtension(state);
var data = GetCommandLineArguments("dummy\\dummy", state, false);
data += "-" + (state.Request.DeviceId ?? string.Empty);
@ -876,11 +872,16 @@ namespace MediaBrowser.Api.Playback
var container = Path.GetExtension(state.RequestedUrl);
if (string.IsNullOrEmpty(container))
{
container = request.Container;
}
if (string.IsNullOrEmpty(container))
{
container = request.Static ?
state.InputContainer :
(Path.GetExtension(GetOutputFilePath(state)) ?? string.Empty).TrimStart('.');
GetOutputFileExtension(state);
}
state.OutputContainer = (container ?? string.Empty).TrimStart('.');
@ -923,7 +924,10 @@ namespace MediaBrowser.Api.Playback
ApplyDeviceProfileSettings(state);
}
state.OutputFilePath = GetOutputFilePath(state);
var ext = string.IsNullOrWhiteSpace(state.OutputContainer)
? GetOutputFileExtension(state)
: ("." + state.OutputContainer);
state.OutputFilePath = GetOutputFilePath(state, ext);
return state;
}

View File

@ -18,9 +18,6 @@ using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.IO;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Services;
using MimeTypes = MediaBrowser.Model.Net.MimeTypes;

View File

@ -146,7 +146,7 @@ namespace MediaBrowser.Api.Playback
Task.WaitAll(task);
}
public async Task<object> Post(GetPostedPlaybackInfo request)
public async Task<PlaybackInfoResponse> GetPlaybackInfo(GetPostedPlaybackInfo request)
{
var authInfo = _authContext.GetAuthorizationInfo(Request);
@ -172,7 +172,14 @@ namespace MediaBrowser.Api.Playback
SetDeviceSpecificData(request.Id, info, profile, authInfo, request.MaxStreamingBitrate ?? profile.MaxStreamingBitrate, request.StartTimeTicks ?? 0, mediaSourceId, request.AudioStreamIndex, request.SubtitleStreamIndex, request.MaxAudioChannels, request.UserId);
}
return ToOptimizedResult(info);
return info;
}
public async Task<object> Post(GetPostedPlaybackInfo request)
{
var result = await GetPlaybackInfo(request).ConfigureAwait(false);
return ToOptimizedResult(result);
}
private T Clone<T>(T obj)

View File

@ -26,8 +26,6 @@ namespace MediaBrowser.Api.Playback.Progressive
[Route("/Audio/{Id}/stream", "HEAD", Summary = "Gets an audio stream")]
public class GetAudioStream : StreamRequest
{
[ApiMember(Name = "Container", Description = "Container", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Container { get; set; }
}
/// <summary>

View File

@ -22,6 +22,9 @@ namespace MediaBrowser.Api.Playback
[ApiMember(Name = "DeviceId", Description = "The device id of the client requesting. Used to stop encoding processes when needed.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public string DeviceId { get; set; }
[ApiMember(Name = "Container", Description = "Container", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Container { get; set; }
/// <summary>
/// Gets or sets the audio codec.
/// </summary>

View File

@ -0,0 +1,248 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using MediaBrowser.Api.Playback.Hls;
using MediaBrowser.Api.Playback.Progressive;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Devices;
using MediaBrowser.Controller.Dlna;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.MediaInfo;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Services;
namespace MediaBrowser.Api.Playback
{
public class BaseUniversalRequest
{
/// <summary>
/// Gets or sets the id.
/// </summary>
/// <value>The id.</value>
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Id { get; set; }
[ApiMember(Name = "MediaSourceId", Description = "The media version id, if playing an alternate version", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string MediaSourceId { get; set; }
[ApiMember(Name = "DeviceId", Description = "The device id of the client requesting. Used to stop encoding processes when needed.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public string DeviceId { get; set; }
public string Token { get; set; }
public string UserId { get; set; }
public string AudioCodec { get; set; }
public string Container { get; set; }
public int? MaxAudioChannels { get; set; }
public long? MaxStreamingBitrate { get; set; }
[ApiMember(Name = "StartTimeTicks", Description = "Optional. Specify a starting offset, in ticks. 1 tick = 10000 ms", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
public long? StartTimeTicks { get; set; }
}
[Route("/Audio/{Id}/universal.{Container}", "GET", Summary = "Gets an audio stream")]
[Route("/Audio/{Id}/universal", "GET", Summary = "Gets an audio stream")]
[Route("/Audio/{Id}/universal.{Container}", "HEAD", Summary = "Gets an audio stream")]
[Route("/Audio/{Id}/universal", "HEAD", Summary = "Gets an audio stream")]
public class GetUniversalAudioStream : BaseUniversalRequest
{
}
//[Authenticated]
public class UniversalAudioService : BaseApiService
{
public UniversalAudioService(IServerConfigurationManager serverConfigurationManager, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IDlnaManager dlnaManager, IDeviceManager deviceManager, ISubtitleEncoder subtitleEncoder, IMediaSourceManager mediaSourceManager, IZipClient zipClient, IJsonSerializer jsonSerializer, IAuthorizationContext authorizationContext, IImageProcessor imageProcessor, INetworkManager networkManager)
{
ServerConfigurationManager = serverConfigurationManager;
UserManager = userManager;
LibraryManager = libraryManager;
IsoManager = isoManager;
MediaEncoder = mediaEncoder;
FileSystem = fileSystem;
DlnaManager = dlnaManager;
DeviceManager = deviceManager;
SubtitleEncoder = subtitleEncoder;
MediaSourceManager = mediaSourceManager;
ZipClient = zipClient;
JsonSerializer = jsonSerializer;
AuthorizationContext = authorizationContext;
ImageProcessor = imageProcessor;
NetworkManager = networkManager;
}
protected IServerConfigurationManager ServerConfigurationManager { get; private set; }
protected IUserManager UserManager { get; private set; }
protected ILibraryManager LibraryManager { get; private set; }
protected IIsoManager IsoManager { get; private set; }
protected IMediaEncoder MediaEncoder { get; private set; }
protected IFileSystem FileSystem { get; private set; }
protected IDlnaManager DlnaManager { get; private set; }
protected IDeviceManager DeviceManager { get; private set; }
protected ISubtitleEncoder SubtitleEncoder { get; private set; }
protected IMediaSourceManager MediaSourceManager { get; private set; }
protected IZipClient ZipClient { get; private set; }
protected IJsonSerializer JsonSerializer { get; private set; }
protected IAuthorizationContext AuthorizationContext { get; private set; }
protected IImageProcessor ImageProcessor { get; private set; }
protected INetworkManager NetworkManager { get; private set; }
public Task<object> Get(GetUniversalAudioStream request)
{
return GetUniversalStream(request, false);
}
public Task<object> Head(GetUniversalAudioStream request)
{
return GetUniversalStream(request, true);
}
private DeviceProfile GetDeviceProfile(GetUniversalAudioStream request)
{
var deviceProfile = new DeviceProfile();
var directPlayProfiles = new List<DirectPlayProfile>();
directPlayProfiles.Add(new DirectPlayProfile
{
Type = DlnaProfileType.Audio,
Container = request.Container
});
deviceProfile.DirectPlayProfiles = directPlayProfiles.ToArray();
deviceProfile.TranscodingProfiles = new[]
{
new TranscodingProfile
{
Type = DlnaProfileType.Audio,
Context = EncodingContext.Streaming,
Container = "ts",
AudioCodec = "aac",
Protocol = "hls"
}
};
return deviceProfile;
}
private async Task<object> GetUniversalStream(GetUniversalAudioStream request, bool isHeadRequest)
{
var deviceProfile = GetDeviceProfile(request);
AuthorizationContext.GetAuthorizationInfo(Request).DeviceId = request.DeviceId;
var mediaInfoService = new MediaInfoService(MediaSourceManager, DeviceManager, LibraryManager, ServerConfigurationManager, NetworkManager, MediaEncoder, UserManager, JsonSerializer, AuthorizationContext)
{
Request = Request
};
var playbackInfoResult = await mediaInfoService.GetPlaybackInfo(new GetPostedPlaybackInfo
{
Id = request.Id,
MaxAudioChannels = request.MaxAudioChannels,
MaxStreamingBitrate = request.MaxStreamingBitrate,
StartTimeTicks = request.StartTimeTicks,
UserId = request.UserId,
DeviceProfile = deviceProfile,
MediaSourceId = request.MediaSourceId
}).ConfigureAwait(false);
var mediaSource = playbackInfoResult.MediaSources[0];
var isStatic = mediaSource.SupportsDirectStream;
if (!isStatic && string.Equals(mediaSource.TranscodingSubProtocol, "hls", StringComparison.OrdinalIgnoreCase))
{
var service = new DynamicHlsService(ServerConfigurationManager,
UserManager,
LibraryManager,
IsoManager,
MediaEncoder,
FileSystem,
DlnaManager,
SubtitleEncoder,
DeviceManager,
MediaSourceManager,
ZipClient,
JsonSerializer,
AuthorizationContext,
NetworkManager)
{
Request = Request
};
var transcodingProfile = deviceProfile.TranscodingProfiles[0];
var newRequest = new GetMasterHlsAudioPlaylist
{
AudioBitRate = isStatic ? (int?)null : Convert.ToInt32(Math.Min(request.MaxStreamingBitrate ?? 192000, int.MaxValue)),
AudioCodec = transcodingProfile.AudioCodec,
Container = ".m3u8",
DeviceId = request.DeviceId,
Id = request.Id,
MaxAudioChannels = request.MaxAudioChannels,
MediaSourceId = mediaSource.Id,
PlaySessionId = playbackInfoResult.PlaySessionId,
StartTimeTicks = request.StartTimeTicks,
Static = isStatic
};
if (isHeadRequest)
{
return service.Head(newRequest);
}
return service.Get(newRequest);
}
else
{
var service = new AudioService(ServerConfigurationManager,
UserManager,
LibraryManager,
IsoManager,
MediaEncoder,
FileSystem,
DlnaManager,
SubtitleEncoder,
DeviceManager,
MediaSourceManager,
ZipClient,
JsonSerializer,
AuthorizationContext,
ImageProcessor)
{
Request = Request
};
var newRequest = new GetAudioStream
{
AudioBitRate = isStatic ? (int?)null : Convert.ToInt32(Math.Min(request.MaxStreamingBitrate ?? 192000, int.MaxValue)),
//AudioCodec = request.AudioCodec,
Container = isStatic ? null : ("." + mediaSource.TranscodingContainer),
DeviceId = request.DeviceId,
Id = request.Id,
MaxAudioChannels = request.MaxAudioChannels,
MediaSourceId = mediaSource.Id,
PlaySessionId = playbackInfoResult.PlaySessionId,
StartTimeTicks = request.StartTimeTicks,
Static = isStatic
};
if (isHeadRequest)
{
return service.Head(newRequest);
}
return service.Get(newRequest);
}
}
}
}

View File

@ -317,12 +317,6 @@ namespace MediaBrowser.Api.Reports
query.MaxParentalRating = _localization.GetRatingLevel(request.MaxOfficialRating);
}
// Albums
if (!string.IsNullOrEmpty(request.Albums))
{
query.AlbumNames = request.Albums.Split('|');
}
return query;
}

View File

@ -245,25 +245,15 @@ namespace MediaBrowser.Api.UserLibrary
User user = null;
BaseItem parentItem;
List<BaseItem> libraryItems = null;
if (!string.IsNullOrWhiteSpace(request.UserId))
{
user = UserManager.GetUserById(request.UserId);
parentItem = string.IsNullOrEmpty(request.ParentId) ? user.RootFolder : LibraryManager.GetItemById(request.ParentId);
if (RequiresLibraryItems(request, dtoOptions))
{
libraryItems = user.RootFolder.GetRecursiveChildren(user).ToList();
}
}
else
{
parentItem = string.IsNullOrEmpty(request.ParentId) ? LibraryManager.RootFolder : LibraryManager.GetItemById(request.ParentId);
if (RequiresLibraryItems(request, dtoOptions))
{
libraryItems = LibraryManager.RootFolder.GetRecursiveChildren().ToList();
}
}
IEnumerable<BaseItem> items;
@ -307,8 +297,6 @@ namespace MediaBrowser.Api.UserLibrary
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);
var ibnItemsArray = filteredItems.ToList();
@ -334,15 +322,7 @@ namespace MediaBrowser.Api.UserLibrary
}
IEnumerable<Tuple<BaseItem, List<BaseItem>>> tuples;
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 tuples = ibnItems.Select(i => new Tuple<BaseItem, List<BaseItem>>(i, new List<BaseItem>()));
var syncProgess = DtoService.GetSyncedItemProgress(dtoOptions);
var dtos = tuples.Select(i => DtoService.GetItemByNameDto(i.Item1, dtoOptions, i.Item2, syncProgess, user));
@ -352,52 +332,6 @@ namespace MediaBrowser.Api.UserLibrary
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>
/// Filters the items.
/// </summary>

View File

@ -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)]
public string Albums { get; set; }
public string AlbumIds { get; set; }
/// <summary>
/// Gets or sets the item ids.
/// </summary>

View File

@ -9,6 +9,7 @@ using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Services;
@ -359,15 +360,30 @@ namespace MediaBrowser.Api.UserLibrary
}
// ExcludeArtistIds
if (!string.IsNullOrEmpty(request.ExcludeArtistIds))
if (!string.IsNullOrWhiteSpace(request.ExcludeArtistIds))
{
query.ExcludeArtistIds = request.ExcludeArtistIds.Split('|');
}
if (!string.IsNullOrWhiteSpace(request.AlbumIds))
{
query.AlbumIds = request.AlbumIds.Split('|');
}
// 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

View File

@ -360,7 +360,8 @@ namespace MediaBrowser.Api.UserLibrary
var currentUser = user;
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 =>
{
if (i.PremiereDate.HasValue)

View File

@ -2078,9 +2078,31 @@ namespace MediaBrowser.Controller.Entities
/// Gets the file system path to delete when the item is to be deleted
/// </summary>
/// <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)

View File

@ -4,6 +4,7 @@ using MediaBrowser.Model.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Serialization;
namespace MediaBrowser.Controller.Entities
@ -97,11 +98,17 @@ namespace MediaBrowser.Controller.Entities
return list;
}
public override IEnumerable<string> GetDeletePaths()
public override IEnumerable<FileSystemMetadata> GetDeletePaths()
{
if (!DetectIsInMixedFolder())
{
return new[] { System.IO.Path.GetDirectoryName(Path) };
return new[] {
new FileSystemMetadata
{
FullName = System.IO.Path.GetDirectoryName(Path),
IsDirectory = true
}
};
}
return base.GetDeletePaths();

View File

@ -141,7 +141,7 @@ namespace MediaBrowser.Controller.Entities
public string ExternalSeriesId { get; set; }
public string ExternalId { get; set; }
public string[] AlbumNames { get; set; }
public string[] AlbumIds { get; set; }
public string[] ArtistIds { get; set; }
public string[] ExcludeArtistIds { get; set; }
public string AncestorWithPresentationUniqueKey { get; set; }
@ -202,7 +202,7 @@ namespace MediaBrowser.Controller.Entities
EnableTotalRecordCount = true;
DtoOptions = new DtoOptions();
AlbumNames = new string[] { };
AlbumIds = new string[] { };
ArtistIds = new string[] { };
ExcludeArtistIds = new string[] { };
ExcludeProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

View File

@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Serialization;
namespace MediaBrowser.Controller.Entities.TV
@ -319,9 +320,15 @@ namespace MediaBrowser.Controller.Entities.TV
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()
@ -338,7 +345,6 @@ namespace MediaBrowser.Controller.Entities.TV
if (series != null)
{
id.SeriesProviderIds = series.ProviderIds;
id.AnimeSeriesIndex = series.AnimeSeriesIndex;
}
id.IsMissingEpisode = IsMissingEpisode;

View File

@ -251,7 +251,6 @@ namespace MediaBrowser.Controller.Entities.TV
if (series != null)
{
id.SeriesProviderIds = series.ProviderIds;
id.AnimeSeriesIndex = series.AnimeSeriesIndex;
}
return id;

View File

@ -19,8 +19,6 @@ namespace MediaBrowser.Controller.Entities.TV
/// </summary>
public class Series : Folder, IHasTrailers, IHasDisplayOrder, IHasLookupInfo<SeriesInfo>, IMetadataContainer
{
public int? AnimeSeriesIndex { get; set; }
public Series()
{
AirDays = new List<DayOfWeek>();
@ -554,8 +552,6 @@ namespace MediaBrowser.Controller.Entities.TV
{
var info = GetItemLookupInfo<SeriesInfo>();
info.AnimeSeriesIndex = AnimeSeriesIndex;
return info;
}

View File

@ -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;
}

View File

@ -477,11 +477,17 @@ namespace MediaBrowser.Controller.Entities
}
}
public override IEnumerable<string> GetDeletePaths()
public override IEnumerable<FileSystemMetadata> GetDeletePaths()
{
if (!DetectIsInMixedFolder())
{
return new[] { ContainingFolderPath };
return new[] {
new FileSystemMetadata
{
FullName = System.IO.Path.GetDirectoryName(Path),
IsDirectory = true
}
};
}
return base.GetDeletePaths();

View File

@ -62,8 +62,6 @@ namespace MediaBrowser.Controller.Library
/// <returns>BaseItem.</returns>
BaseItem FindByPath(string path, bool? isFolder);
Guid? FindIdByPath(string path, bool? isFolder);
/// <summary>
/// Gets the artist.
/// </summary>

View File

@ -8,7 +8,6 @@ namespace MediaBrowser.Controller.Providers
public Dictionary<string, string> SeriesProviderIds { get; set; }
public int? IndexNumberEnd { get; set; }
public int? AnimeSeriesIndex { get; set; }
public bool IsMissingEpisode { get; set; }
public bool IsVirtualUnaired { get; set; }

View File

@ -6,7 +6,6 @@ namespace MediaBrowser.Controller.Providers
public class SeasonInfo : ItemLookupInfo
{
public Dictionary<string, string> SeriesProviderIds { get; set; }
public int? AnimeSeriesIndex { get; set; }
public SeasonInfo()
{

View File

@ -2,6 +2,5 @@ namespace MediaBrowser.Controller.Providers
{
public class SeriesInfo : ItemLookupInfo
{
public int? AnimeSeriesIndex { get; set; }
}
}

View File

@ -69,21 +69,6 @@ namespace MediaBrowser.LocalMetadata.Parsers
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":
{
var status = reader.ReadElementContentAsString();

View File

@ -606,9 +606,20 @@ namespace MediaBrowser.Model.Dlna
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)
{
int defaultBitrate = audioStream == null ? 192000 : audioStream.BitRate ?? 192000;
int defaultBitrate = audioStream == null ? 192000 : audioStream.BitRate ?? GetDefaultAudioBitrateIfUnknown(audioStream);
// Reduce the bitrate if we're downmixing
if (targetAudioChannels.HasValue && audioStream != null && audioStream.Channels.HasValue && targetAudioChannels.Value < audioStream.Channels.Value)
{

View File

@ -85,8 +85,6 @@ namespace MediaBrowser.Model.Dto
public float? Metascore { get; set; }
public bool? HasDynamicCategories { get; set; }
public int? AnimeSeriesIndex { get; set; }
/// <summary>
/// Gets or sets a value indicating whether [supports synchronize].
/// </summary>
@ -263,7 +261,7 @@ namespace MediaBrowser.Model.Dto
/// Gets or sets the play access.
/// </summary>
/// <value>The play access.</value>
public PlayAccess PlayAccess { get; set; }
public PlayAccess? PlayAccess { get; set; }
/// <summary>
/// Gets or sets the aspect ratio.
@ -759,7 +757,7 @@ namespace MediaBrowser.Model.Dto
/// Gets or sets the type of the location.
/// </summary>
/// <value>The type of the location.</value>
public LocationType LocationType { get; set; }
public LocationType? LocationType { get; set; }
/// <summary>
/// Gets or sets the type of the iso.

View File

@ -96,8 +96,7 @@ namespace MediaBrowser.Providers.TV
try
{
int seasonNumber = AdjustForSeriesOffset(series, season.IndexNumber.Value);
AddImages(list, seasonNumber, path, cancellationToken);
AddImages(list, season.IndexNumber.Value, path, cancellationToken);
}
catch (FileNotFoundException)
{
@ -139,15 +138,6 @@ namespace MediaBrowser.Providers.TV
.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)
{
var root = _json.DeserializeFromFile<FanartSeriesProvider.RootObject>(path);

View File

@ -203,9 +203,8 @@ namespace MediaBrowser.Providers.TV
CancellationToken cancellationToken)
{
var existingEpisodes = (from s in series
let seasonOffset = TvdbSeriesProvider.GetSeriesOffset(s.ProviderIds) ?? ((s.AnimeSeriesIndex ?? 1) - 1)
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();
var lookup = episodeLookup as IList<Tuple<int, int>> ?? episodeLookup.ToList();
@ -248,7 +247,6 @@ namespace MediaBrowser.Providers.TV
var now = DateTime.UtcNow;
var targetSeries = DetermineAppropriateSeries(series, tuple.Item1);
var seasonOffset = TvdbSeriesProvider.GetSeriesOffset(targetSeries.ProviderIds) ?? ((targetSeries.AnimeSeriesIndex ?? 1) - 1);
var unairedThresholdDays = 2;
now = now.AddDays(0 - unairedThresholdDays);
@ -259,7 +257,7 @@ namespace MediaBrowser.Providers.TV
{
// tvdb has a lot of nearly blank episodes
_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;
}
@ -268,7 +266,7 @@ namespace MediaBrowser.Providers.TV
{
// tvdb has a lot of nearly blank episodes
_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;
}
@ -279,13 +277,11 @@ namespace MediaBrowser.Providers.TV
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)) ??
seriesAndOffsets.FirstOrDefault(s => s.Series.GetRecursiveChildren().OfType<Season>().Any(season => (season.IndexNumber + s.SeasonOffset) == 1)) ??
seriesAndOffsets.OrderBy(s => s.Series.GetRecursiveChildren().OfType<Season>().Select(season => season.IndexNumber + s.SeasonOffset).Min()).First();
return bestMatch.Series;
return seriesAndOffsets.FirstOrDefault(s => s.GetRecursiveChildren().OfType<Season>().Any(season => (season.IndexNumber) == seasonNumber)) ??
seriesAndOffsets.FirstOrDefault(s => s.GetRecursiveChildren().OfType<Season>().Any(season => (season.IndexNumber) == 1)) ??
seriesAndOffsets.OrderBy(s => s.GetRecursiveChildren().OfType<Season>().Select(season => season.IndexNumber).Min()).First();
}
/// <summary>
@ -296,9 +292,8 @@ namespace MediaBrowser.Providers.TV
bool allowMissingEpisodes)
{
var existingEpisodes = (from s in series
let seasonOffset = TvdbSeriesProvider.GetSeriesOffset(s.ProviderIds) ?? ((s.AnimeSeriesIndex ?? 1) - 1)
from c in s.GetRecursiveChildren().OfType<Episode>()
select new { SeasonOffset = seasonOffset, Episode = c })
select new { Episode = c })
.ToList();
var physicalEpisodes = existingEpisodes
@ -314,12 +309,12 @@ namespace MediaBrowser.Providers.TV
{
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;
// If there's a physical episode with the same season and episode number, delete it
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)))
{
return true;
@ -371,28 +366,27 @@ namespace MediaBrowser.Providers.TV
IEnumerable<Tuple<int, int>> episodeLookup)
{
var existingSeasons = (from s in series
let seasonOffset = TvdbSeriesProvider.GetSeriesOffset(s.ProviderIds) ?? ((s.AnimeSeriesIndex ?? 1) - 1)
from c in s.Children.OfType<Season>()
select new { SeasonOffset = seasonOffset, Season = c })
select c)
.ToList();
var physicalSeasons = existingSeasons
.Where(i => i.Season.LocationType != LocationType.Virtual)
.Where(i => i.LocationType != LocationType.Virtual)
.ToList();
var virtualSeasons = existingSeasons
.Where(i => i.Season.LocationType == LocationType.Virtual)
.Where(i => i.LocationType == LocationType.Virtual)
.ToList();
var seasonsToRemove = virtualSeasons
.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 (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;
}
@ -408,13 +402,13 @@ namespace MediaBrowser.Providers.TV
// Season does not have a 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();
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);

View File

@ -59,7 +59,6 @@ namespace MediaBrowser.Providers.TV
{
// Process images
var seriesDataPath = TvdbSeriesProvider.GetSeriesDataPath(_config.ApplicationPaths, series.ProviderIds);
var indexOffset = TvdbSeriesProvider.GetSeriesOffset(series.ProviderIds) ?? 0;
var nodes = TvdbEpisodeProvider.Current.GetEpisodeXmlNodes(seriesDataPath, episode.GetLookupInfo());

View File

@ -99,15 +99,6 @@ namespace MediaBrowser.Providers.TV
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)
{
var settings = xmlReaderSettingsFactory.Create(false);

View File

@ -76,10 +76,6 @@ namespace MediaBrowser.Providers.TV
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);
}
catch (FileNotFoundException)

View File

@ -27,9 +27,6 @@ namespace MediaBrowser.Providers.TV
{
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 static TvdbSeriesProvider Current { get; private set; }
private readonly IZipClient _zipClient;
@ -123,23 +120,6 @@ namespace MediaBrowser.Providers.TV
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>
/// Fetches the series data.
/// </summary>

View File

@ -65,22 +65,6 @@ namespace MediaBrowser.XbmcMetadata.Parsers
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":
{
var status = reader.ReadElementContentAsString();

View File

@ -83,11 +83,6 @@ namespace MediaBrowser.XbmcMetadata.Savers
{
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)
@ -101,8 +96,7 @@ namespace MediaBrowser.XbmcMetadata.Savers
"episode",
"status",
"airs_time",
"airs_dayofweek",
"animeseriesindex"
"airs_dayofweek"
});
return list;
}

View File

@ -1,3 +1,3 @@
using System.Reflection;
[assembly: AssemblyVersion("3.2.1.108")]
[assembly: AssemblyVersion("3.2.1.109")]