updated nuget for live tv

This commit is contained in:
Luke Pulverenti 2013-11-26 16:36:11 -05:00
parent af49f6d232
commit e05a84c789
17 changed files with 250 additions and 150 deletions

View File

@ -1,4 +1,5 @@
using MediaBrowser.Controller.LiveTv;
using System.Threading;
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Model.LiveTv;
using MediaBrowser.Model.Querying;
using ServiceStack.ServiceHost;
@ -49,6 +50,11 @@ namespace MediaBrowser.Api.LiveTv
[Api(Description = "Gets live tv recordings")]
public class GetRecordings : IReturn<QueryResult<RecordingInfoDto>>
{
[ApiMember(Name = "ServiceName", Description = "Optional filter by service.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public string ServiceName { get; set; }
[ApiMember(Name = "ChannelId", Description = "Optional filter by channel id.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public string ChannelId { get; set; }
}
[Route("/LiveTv/Programs", "GET")]
@ -80,7 +86,7 @@ namespace MediaBrowser.Api.LiveTv
if (!string.IsNullOrEmpty(serviceName))
{
services = services.Where(i => string.Equals(i.Name, serviceName, System.StringComparison.OrdinalIgnoreCase));
services = services.Where(i => string.Equals(i.Name, serviceName, StringComparison.OrdinalIgnoreCase));
}
return services;
@ -130,14 +136,20 @@ namespace MediaBrowser.Api.LiveTv
ServiceName = request.ServiceName,
ChannelIdList = (request.ChannelIds ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToArray(),
UserId = request.UserId
});
}, CancellationToken.None).Result;
return ToOptimizedResult(result);
}
public object Get(GetRecordings request)
{
var result = _liveTvManager.GetRecordings();
var result = _liveTvManager.GetRecordings(new RecordingQuery
{
ChannelId = request.ChannelId,
ServiceName = request.ServiceName
}, CancellationToken.None).Result;
return ToOptimizedResult(result);
}

View File

@ -3,6 +3,8 @@ using MediaBrowser.Model.Entities;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Threading;
using System.Threading.Tasks;
namespace MediaBrowser.Controller.Entities.Audio
{
@ -30,13 +32,24 @@ namespace MediaBrowser.Controller.Entities.Audio
{
if (IsAccessedByName)
{
throw new InvalidOperationException("Artists accessed by name do not have children.");
return new List<BaseItem>();
}
return base.ActualChildren;
}
}
protected override Task ValidateChildrenInternal(IProgress<double> progress, CancellationToken cancellationToken, bool? recursive = null, bool forceRefreshMetadata = false)
{
if (IsAccessedByName)
{
// Should never get in here anyway
return Task.FromResult(true);
}
return base.ValidateChildrenInternal(progress, cancellationToken, recursive, forceRefreshMetadata);
}
public override string GetClientTypeName()
{
if (IsAccessedByName)

View File

@ -25,12 +25,6 @@ namespace MediaBrowser.Controller.LiveTv
/// <value>The id of the channel.</value>
public string Id { get; set; }
/// <summary>
/// Gets or sets the name of the service.
/// </summary>
/// <value>The name of the service.</value>
public string ServiceName { get; set; }
/// <summary>
/// Gets or sets the type of the channel.
/// </summary>

View File

@ -1,6 +1,8 @@
using MediaBrowser.Model.LiveTv;
using System.Threading;
using MediaBrowser.Model.LiveTv;
using MediaBrowser.Model.Querying;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace MediaBrowser.Controller.LiveTv
{
@ -15,6 +17,13 @@ namespace MediaBrowser.Controller.LiveTv
/// <value>The services.</value>
IReadOnlyList<ILiveTvService> Services { get; }
/// <summary>
/// Schedules the recording.
/// </summary>
/// <param name="programId">The program identifier.</param>
/// <returns>Task.</returns>
Task ScheduleRecording(string programId);
/// <summary>
/// Adds the parts.
/// </summary>
@ -31,8 +40,10 @@ namespace MediaBrowser.Controller.LiveTv
/// <summary>
/// Gets the recordings.
/// </summary>
/// <param name="query">The query.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>QueryResult{RecordingInfoDto}.</returns>
QueryResult<RecordingInfoDto> GetRecordings();
Task<QueryResult<RecordingInfoDto>> GetRecordings(RecordingQuery query, CancellationToken cancellationToken);
/// <summary>
/// Gets the channel.
@ -53,7 +64,8 @@ namespace MediaBrowser.Controller.LiveTv
/// Gets the programs.
/// </summary>
/// <param name="query">The query.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>IEnumerable{ProgramInfo}.</returns>
QueryResult<ProgramInfoDto> GetPrograms(ProgramQuery query);
Task<QueryResult<ProgramInfoDto>> GetPrograms(ProgramQuery query, CancellationToken cancellationToken);
}
}

View File

@ -1,5 +1,4 @@
using MediaBrowser.Common.Net;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
@ -25,12 +24,12 @@ namespace MediaBrowser.Controller.LiveTv
Task<IEnumerable<ChannelInfo>> GetChannelsAsync(CancellationToken cancellationToken);
/// <summary>
/// Cancels the recording asynchronous.
/// Cancels the timer asynchronous.
/// </summary>
/// <param name="recordingId">The recording identifier.</param>
/// <param name="timerId">The timer identifier.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
Task CancelRecordingAsync(string recordingId, CancellationToken cancellationToken);
Task CancelTimerAsync(string timerId, CancellationToken cancellationToken);
/// <summary>
/// Deletes the recording asynchronous.
@ -41,15 +40,20 @@ namespace MediaBrowser.Controller.LiveTv
Task DeleteRecordingAsync(string recordingId, CancellationToken cancellationToken);
/// <summary>
/// Schedules the recording asynchronous.
/// Creates the timer asynchronous.
/// </summary>
/// <param name="name">The name for the recording</param>
/// <param name="channelId">The channel identifier.</param>
/// <param name="startTime">The start time.</param>
/// <param name="duration">The duration.</param>
/// <param name="info">The information.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
Task ScheduleRecordingAsync(string name, string channelId, DateTime startTime, TimeSpan duration, CancellationToken cancellationToken);
Task CreateTimerAsync(TimerInfo info, CancellationToken cancellationToken);
/// <summary>
/// Updates the timer asynchronous.
/// </summary>
/// <param name="info">The information.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
Task UpdateTimerAsync(TimerInfo info, CancellationToken cancellationToken);
/// <summary>
/// Gets the channel image asynchronous.
@ -66,6 +70,13 @@ namespace MediaBrowser.Controller.LiveTv
/// <returns>Task{IEnumerable{RecordingInfo}}.</returns>
Task<IEnumerable<RecordingInfo>> GetRecordingsAsync(CancellationToken cancellationToken);
/// <summary>
/// Gets the recordings asynchronous.
/// </summary>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{IEnumerable{RecordingInfo}}.</returns>
Task<IEnumerable<TimerInfo>> GetTimersAsync(CancellationToken cancellationToken);
/// <summary>
/// Gets the programs asynchronous.
/// </summary>

View File

@ -43,6 +43,12 @@ namespace MediaBrowser.Controller.LiveTv
/// </summary>
public DateTime EndDate { get; set; }
/// <summary>
/// Gets or sets the aspect ratio.
/// </summary>
/// <value>The aspect ratio.</value>
public string AspectRatio { get; set; }
/// <summary>
/// Genre of the program.
/// </summary>

View File

@ -1,6 +1,5 @@
using MediaBrowser.Model.LiveTv;
using System;
using System.Collections.Generic;
namespace MediaBrowser.Controller.LiveTv
{
@ -21,12 +20,6 @@ namespace MediaBrowser.Controller.LiveTv
/// </summary>
public string ChannelName { get; set; }
/// <summary>
/// Gets or sets the program identifier.
/// </summary>
/// <value>The program identifier.</value>
public string ProgramId { get; set; }
/// <summary>
/// Name of the recording.
/// </summary>
@ -52,31 +45,5 @@ namespace MediaBrowser.Controller.LiveTv
/// </summary>
/// <value>The status.</value>
public RecordingStatus Status { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance is recurring.
/// </summary>
/// <value><c>true</c> if this instance is recurring; otherwise, <c>false</c>.</value>
public bool IsRecurring { get; set; }
/// <summary>
/// Parent recurring.
/// </summary>
public string RecurringParent { get; set; }
/// <summary>
/// Start date for the recurring, in UTC.
/// </summary>
public DateTime RecurrringStartDate { get; set; }
/// <summary>
/// End date for the recurring, in UTC
/// </summary>
public DateTime RecurringEndDate { get; set; }
/// <summary>
/// When do we need the recording?
/// </summary>
public List<string> DayMask { get; set; }
}
}

View File

@ -0,0 +1,67 @@
using MediaBrowser.Model.LiveTv;
using System;
using System.Collections.Generic;
namespace MediaBrowser.Controller.LiveTv
{
public class TimerInfo
{
/// <summary>
/// Id of the recording.
/// </summary>
public string Id { get; set; }
/// <summary>
/// ChannelId of the recording.
/// </summary>
public string ChannelId { get; set; }
/// <summary>
/// ChannelName of the recording.
/// </summary>
public string ChannelName { get; set; }
/// <summary>
/// Name of the recording.
/// </summary>
public string Name { get; set; }
/// <summary>
/// Description of the recording.
/// </summary>
public string Description { get; set; }
/// <summary>
/// The start date of the recording, in UTC.
/// </summary>
public DateTime StartDate { get; set; }
/// <summary>
/// The end date of the recording, in UTC.
/// </summary>
public DateTime EndDate { get; set; }
/// <summary>
/// Gets or sets the status.
/// </summary>
/// <value>The status.</value>
public RecordingStatus Status { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance is recurring.
/// </summary>
/// <value><c>true</c> if this instance is recurring; otherwise, <c>false</c>.</value>
public bool IsRecurring { get; set; }
/// <summary>
/// Gets or sets the recurring days.
/// </summary>
/// <value>The recurring days.</value>
public List<DayOfWeek> RecurringDays { get; set; }
public TimerInfo()
{
RecurringDays = new List<DayOfWeek>();
}
}
}

View File

@ -110,6 +110,7 @@
<Compile Include="LiveTv\ILiveTvService.cs" />
<Compile Include="LiveTv\ProgramInfo.cs" />
<Compile Include="LiveTv\RecordingInfo.cs" />
<Compile Include="LiveTv\TimerInfo.cs" />
<Compile Include="Localization\ILocalizationManager.cs" />
<Compile Include="Notifications\INotificationsRepository.cs" />
<Compile Include="Notifications\NotificationUpdateEventArgs.cs" />

View File

@ -29,10 +29,10 @@ namespace MediaBrowser.Model.LiveTv
public float? CommunityRating { get; set; }
/// <summary>
/// Gets or sets the recording identifier.
/// Gets or sets the aspect ratio.
/// </summary>
/// <value>The recording identifier.</value>
public string RecordingId { get; set; }
/// <value>The aspect ratio.</value>
public string AspectRatio { get; set; }
/// <summary>
/// Gets or sets the official rating.
@ -89,6 +89,18 @@ namespace MediaBrowser.Model.LiveTv
/// <value>The original air date.</value>
public DateTime? OriginalAirDate { get; set; }
/// <summary>
/// Gets or sets the recording identifier.
/// </summary>
/// <value>The recording identifier.</value>
public string RecordingId { get; set; }
/// <summary>
/// Gets or sets the recording status.
/// </summary>
/// <value>The recording status.</value>
public RecordingStatus? RecordingStatus { get; set; }
public ProgramInfoDto()
{
Genres = new List<string>();

View File

@ -51,11 +51,6 @@ namespace MediaBrowser.Model.LiveTv
/// </summary>
public DateTime EndDate { get; set; }
/// <summary>
/// IsRecurring recording?
/// </summary>
public bool IsRecurring { get; set; }
/// <summary>
/// Gets or sets the status.
/// </summary>

View File

@ -5,6 +5,16 @@
/// </summary>
public class RecordingQuery
{
/// <summary>
/// Gets or sets the channel identifier.
/// </summary>
/// <value>The channel identifier.</value>
public string ChannelId { get; set; }
/// <summary>
/// Gets or sets the name of the service.
/// </summary>
/// <value>The name of the service.</value>
public string ServiceName { get; set; }
}
}

View File

@ -207,7 +207,7 @@ namespace MediaBrowser.Server.Implementations.Dto
if (!string.IsNullOrEmpty(image))
{
dto.PrimaryImageTag = _imageProcessor.GetImageCacheTag(user, ImageType.Primary, image);
dto.PrimaryImageTag = GetImageCacheTag(user, ImageType.Primary, image);
try
{
@ -285,13 +285,7 @@ namespace MediaBrowser.Server.Implementations.Dto
if (!string.IsNullOrEmpty(imagePath))
{
try
{
info.PrimaryImageTag = _imageProcessor.GetImageCacheTag(item, ImageType.Primary, imagePath);
}
catch (IOException)
{
}
info.PrimaryImageTag = GetImageCacheTag(item, ImageType.Primary, imagePath);
}
return info;

View File

@ -41,9 +41,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv
private List<Channel> _channels = new List<Channel>();
private List<ProgramInfoDto> _programs = new List<ProgramInfoDto>();
private List<RecordingInfoDto> _recordings = new List<RecordingInfoDto>();
private readonly SemaphoreSlim _updateSemaphore = new SemaphoreSlim(1, 1);
public LiveTvManager(IServerApplicationPaths appPaths, IFileSystem fileSystem, ILogger logger, IItemRepository itemRepo, IImageProcessor imageProcessor, IUserManager userManager, ILocalizationManager localization, IUserDataManager userDataManager, IDtoService dtoService)
{
@ -104,11 +101,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv
return dto;
}
private ILiveTvService GetService(ChannelInfo channel)
{
return _services.FirstOrDefault(i => string.Equals(channel.ServiceName, i.Name, StringComparison.OrdinalIgnoreCase));
}
private Guid? GetLogoImageTag(Channel info)
{
var path = info.PrimaryImagePath;
@ -210,7 +202,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv
Quality = program.Quality,
OriginalAirDate = program.OriginalAirDate,
Audio = program.Audio,
CommunityRating = program.CommunityRating
CommunityRating = program.CommunityRating,
AspectRatio = program.AspectRatio
};
}
@ -228,9 +221,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv
return name.ToLower().GetMD5();
}
private async Task<Channel> GetChannel(ChannelInfo channelInfo, CancellationToken cancellationToken)
private async Task<Channel> GetChannel(ChannelInfo channelInfo, string serviceName, CancellationToken cancellationToken)
{
var path = Path.Combine(_appPaths.ItemsByNamePath, "channels", _fileSystem.GetValidFilename(channelInfo.ServiceName), _fileSystem.GetValidFilename(channelInfo.Name));
var path = Path.Combine(_appPaths.ItemsByNamePath, "channels", _fileSystem.GetValidFilename(serviceName), _fileSystem.GetValidFilename(channelInfo.Name));
var fileInfo = new DirectoryInfo(path);
@ -249,7 +242,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
isNew = true;
}
var id = GetInternalChannelId(channelInfo.ServiceName, channelInfo.Id);
var id = GetInternalChannelId(serviceName, channelInfo.Id);
var item = _itemRepo.RetrieveItem(id) as Channel;
@ -264,7 +257,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
Path = path,
ChannelId = channelInfo.Id,
ChannelNumber = channelInfo.Number,
ServiceName = channelInfo.ServiceName
ServiceName = serviceName
};
isNew = true;
@ -278,7 +271,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
return item;
}
public QueryResult<ProgramInfoDto> GetPrograms(ProgramQuery query)
public async Task<QueryResult<ProgramInfoDto>> GetPrograms(ProgramQuery query, CancellationToken cancellationToken)
{
IEnumerable<ProgramInfoDto> programs = _programs
.OrderBy(i => i.StartDate)
@ -298,6 +291,21 @@ namespace MediaBrowser.Server.Implementations.LiveTv
var returnArray = programs.ToArray();
var recordings = await GetRecordings(new RecordingQuery
{
}, cancellationToken).ConfigureAwait(false);
foreach (var program in returnArray)
{
var recording = recordings.Items
.FirstOrDefault(i => string.Equals(i.ProgramId, program.Id));
program.RecordingId = recording == null ? null : recording.Id;
program.RecordingStatus = recording == null ? (RecordingStatus?)null : recording.Status;
}
return new QueryResult<ProgramInfoDto>
{
Items = returnArray,
@ -306,27 +314,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv
}
internal async Task RefreshChannels(IProgress<double> progress, CancellationToken cancellationToken)
{
await _updateSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
try
{
await RefreshChannelsInternal(progress, cancellationToken).ConfigureAwait(false);
}
finally
{
_updateSemaphore.Release();
}
await RefreshRecordings(new Progress<double>(), cancellationToken).ConfigureAwait(false);
}
private async Task RefreshChannelsInternal(IProgress<double> progress, CancellationToken cancellationToken)
{
// Avoid implicitly captured closure
var currentCancellationToken = cancellationToken;
var channelTasks = _services.Select(i => i.GetChannelsAsync(currentCancellationToken));
var channelTasks = _services.Select(i => GetChannels(i, currentCancellationToken));
progress.Report(10);
@ -343,11 +335,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv
{
try
{
var item = await GetChannel(channelInfo, cancellationToken).ConfigureAwait(false);
var item = await GetChannel(channelInfo.Item2, channelInfo.Item1, cancellationToken).ConfigureAwait(false);
var service = GetService(channelInfo);
var service = _services.First(i => string.Equals(channelInfo.Item1, i.Name, StringComparison.OrdinalIgnoreCase));
var channelPrograms = await service.GetProgramsAsync(channelInfo.Id, cancellationToken).ConfigureAwait(false);
var channelPrograms = await service.GetProgramsAsync(channelInfo.Item2.Id, cancellationToken).ConfigureAwait(false);
programs.AddRange(channelPrograms.Select(program => GetProgramInfoDto(program, item)));
@ -359,7 +351,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
}
catch (Exception ex)
{
_logger.ErrorException("Error getting channel information for {0}", ex, channelInfo.Name);
_logger.ErrorException("Error getting channel information for {0}", ex, channelInfo.Item2.Name);
}
numComplete++;
@ -373,32 +365,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv
_channels = list;
}
internal async Task RefreshRecordings(IProgress<double> progress, CancellationToken cancellationToken)
private async Task<IEnumerable<Tuple<string, ChannelInfo>>> GetChannels(ILiveTvService service, CancellationToken cancellationToken)
{
await _updateSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
var channels = await service.GetChannelsAsync(cancellationToken).ConfigureAwait(false);
try
{
await RefreshRecordingsInternal(progress, cancellationToken).ConfigureAwait(false);
}
finally
{
_updateSemaphore.Release();
}
}
private async Task RefreshRecordingsInternal(IProgress<double> progress, CancellationToken cancellationToken)
{
var list = new List<RecordingInfoDto>();
foreach (var service in _services)
{
var recordings = await GetRecordings(service, cancellationToken).ConfigureAwait(false);
list.AddRange(recordings);
}
_recordings = list;
return channels.Select(i => new Tuple<string, ChannelInfo>(service.Name, i));
}
private async Task<IEnumerable<RecordingInfoDto>> GetRecordings(ILiveTvService service, CancellationToken cancellationToken)
@ -419,7 +390,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv
Description = info.Description,
EndDate = info.EndDate,
Name = info.Name,
IsRecurring = info.IsRecurring,
StartDate = info.StartDate,
Id = id,
ExternalId = info.Id,
@ -427,17 +397,27 @@ namespace MediaBrowser.Server.Implementations.LiveTv
Status = info.Status
};
if (!string.IsNullOrEmpty(info.ProgramId))
{
dto.ProgramId = GetInternalProgramIdId(service.Name, info.ProgramId).ToString("N");
}
return dto;
}
public QueryResult<RecordingInfoDto> GetRecordings()
public async Task<QueryResult<RecordingInfoDto>> GetRecordings(RecordingQuery query, CancellationToken cancellationToken)
{
var returnArray = _recordings.ToArray();
var list = new List<RecordingInfoDto>();
foreach (var service in GetServices(query.ServiceName, query.ChannelId))
{
var recordings = await GetRecordings(service, cancellationToken).ConfigureAwait(false);
list.AddRange(recordings);
}
if (!string.IsNullOrEmpty(query.ChannelId))
{
list = list.Where(i => string.Equals(i.ChannelId, query.ChannelId))
.ToList();
}
var returnArray = list.ToArray();
return new QueryResult<RecordingInfoDto>
{
@ -445,5 +425,31 @@ namespace MediaBrowser.Server.Implementations.LiveTv
TotalRecordCount = returnArray.Length
};
}
private IEnumerable<ILiveTvService> GetServices(string serviceName, string channelId)
{
IEnumerable<ILiveTvService> services = _services;
if (string.IsNullOrEmpty(serviceName) && !string.IsNullOrEmpty(channelId))
{
var channelIdGuid = new Guid(channelId);
serviceName = _channels.Where(i => i.Id == channelIdGuid)
.Select(i => i.ServiceName)
.FirstOrDefault();
}
if (!string.IsNullOrEmpty(serviceName))
{
services = services.Where(i => string.Equals(i.Name, serviceName, StringComparison.OrdinalIgnoreCase));
}
return services;
}
public Task ScheduleRecording(string programId)
{
throw new NotImplementedException();
}
}
}

View File

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaBrowser.Common.Internal</id>
<version>3.0.250</version>
<version>3.0.251</version>
<title>MediaBrowser.Common.Internal</title>
<authors>Luke</authors>
<owners>ebr,Luke,scottisafool</owners>
@ -12,7 +12,7 @@
<description>Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption.</description>
<copyright>Copyright © Media Browser 2013</copyright>
<dependencies>
<dependency id="MediaBrowser.Common" version="3.0.250" />
<dependency id="MediaBrowser.Common" version="3.0.251" />
<dependency id="NLog" version="2.1.0" />
<dependency id="ServiceStack.Text" version="3.9.58" />
<dependency id="SimpleInjector" version="2.3.6" />

View File

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaBrowser.Common</id>
<version>3.0.250</version>
<version>3.0.251</version>
<title>MediaBrowser.Common</title>
<authors>Media Browser Team</authors>
<owners>ebr,Luke,scottisafool</owners>

View File

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>MediaBrowser.Server.Core</id>
<version>3.0.250</version>
<version>3.0.251</version>
<title>Media Browser.Server.Core</title>
<authors>Media Browser Team</authors>
<owners>ebr,Luke,scottisafool</owners>
@ -12,7 +12,7 @@
<description>Contains core components required to build plugins for Media Browser Server.</description>
<copyright>Copyright © Media Browser 2013</copyright>
<dependencies>
<dependency id="MediaBrowser.Common" version="3.0.250" />
<dependency id="MediaBrowser.Common" version="3.0.251" />
</dependencies>
</metadata>
<files>