commit
2b54990975
|
@ -125,7 +125,7 @@ namespace Emby.Dlna.Profiles
|
|||
|
||||
new DirectPlayProfile
|
||||
{
|
||||
Container = "flac,ac3",
|
||||
Container = "flac",
|
||||
Type = DlnaProfileType.Audio
|
||||
},
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
<DirectPlayProfile container="asf" audioCodec="mp2,ac3" videoCodec="mpeg2video" type="Video" />
|
||||
<DirectPlayProfile container="mp3" audioCodec="mp2,mp3" type="Audio" />
|
||||
<DirectPlayProfile container="mp4" audioCodec="mp4" type="Audio" />
|
||||
<DirectPlayProfile container="flac,ac3" type="Audio" />
|
||||
<DirectPlayProfile container="flac" type="Audio" />
|
||||
<DirectPlayProfile container="asf" audioCodec="wmav2,wmapro,wmavoice" type="Audio" />
|
||||
<DirectPlayProfile container="ogg" audioCodec="vorbis" type="Audio" />
|
||||
<DirectPlayProfile container="jpeg,png,gif,bmp,tiff" type="Photo" />
|
||||
|
|
|
@ -3388,10 +3388,10 @@ namespace Emby.Server.Implementations.Data
|
|||
var includeTypes = query.IncludeItemTypes.SelectMany(MapIncludeItemTypes).ToArray();
|
||||
if (includeTypes.Length == 1)
|
||||
{
|
||||
whereClauses.Add("type=@type" + paramSuffix);
|
||||
whereClauses.Add("type=@type");
|
||||
if (statement != null)
|
||||
{
|
||||
statement.TryBind("@type" + paramSuffix, includeTypes[0]);
|
||||
statement.TryBind("@type", includeTypes[0]);
|
||||
}
|
||||
}
|
||||
else if (includeTypes.Length > 1)
|
||||
|
@ -4936,7 +4936,7 @@ namespace Emby.Server.Implementations.Data
|
|||
ParentId = query.ParentId,
|
||||
IsPlayed = query.IsPlayed
|
||||
};
|
||||
var whereClauses = GetWhereClauses(typeSubQuery, null, "itemTypes");
|
||||
var whereClauses = GetWhereClauses(typeSubQuery, null);
|
||||
|
||||
whereClauses.Add("guid in (select ItemId from ItemValues where ItemValues.CleanValue=A.CleanName AND " + typeClause + ")");
|
||||
|
||||
|
@ -5072,7 +5072,7 @@ namespace Emby.Server.Implementations.Data
|
|||
|
||||
if (typeSubQuery != null)
|
||||
{
|
||||
GetWhereClauses(typeSubQuery, null, "itemTypes");
|
||||
GetWhereClauses(typeSubQuery, null);
|
||||
}
|
||||
BindSimilarParams(query, statement);
|
||||
GetWhereClauses(innerQuery, statement);
|
||||
|
@ -5110,7 +5110,7 @@ namespace Emby.Server.Implementations.Data
|
|||
|
||||
if (typeSubQuery != null)
|
||||
{
|
||||
GetWhereClauses(typeSubQuery, null, "itemTypes");
|
||||
GetWhereClauses(typeSubQuery, null);
|
||||
}
|
||||
BindSimilarParams(query, statement);
|
||||
GetWhereClauses(innerQuery, statement);
|
||||
|
|
|
@ -491,7 +491,7 @@ namespace Emby.Server.Implementations.Dto
|
|||
}
|
||||
}
|
||||
|
||||
//if (!(item is LiveTvProgram))
|
||||
if (!(item is LiveTvProgram))
|
||||
{
|
||||
dto.PlayAccess = item.GetPlayAccess(user);
|
||||
}
|
||||
|
|
|
@ -104,7 +104,6 @@
|
|||
<Compile Include="HttpServer\StreamWriter.cs" />
|
||||
<Compile Include="HttpServer\SwaggerService.cs" />
|
||||
<Compile Include="Images\BaseDynamicImageProvider.cs" />
|
||||
<Compile Include="Intros\DefaultIntroProvider.cs" />
|
||||
<Compile Include="IO\FileRefresher.cs" />
|
||||
<Compile Include="IO\MbLinkShortcutHandler.cs" />
|
||||
<Compile Include="IO\ThrottledStream.cs" />
|
||||
|
@ -238,7 +237,6 @@
|
|||
<Compile Include="Sorting\AlbumComparer.cs" />
|
||||
<Compile Include="Sorting\AlphanumComparator.cs" />
|
||||
<Compile Include="Sorting\ArtistComparer.cs" />
|
||||
<Compile Include="Sorting\BudgetComparer.cs" />
|
||||
<Compile Include="Sorting\CommunityRatingComparer.cs" />
|
||||
<Compile Include="Sorting\CriticRatingComparer.cs" />
|
||||
<Compile Include="Sorting\DateCreatedComparer.cs" />
|
||||
|
@ -257,7 +255,6 @@
|
|||
<Compile Include="Sorting\PremiereDateComparer.cs" />
|
||||
<Compile Include="Sorting\ProductionYearComparer.cs" />
|
||||
<Compile Include="Sorting\RandomComparer.cs" />
|
||||
<Compile Include="Sorting\RevenueComparer.cs" />
|
||||
<Compile Include="Sorting\RuntimeComparer.cs" />
|
||||
<Compile Include="Sorting\SeriesSortNameComparer.cs" />
|
||||
<Compile Include="Sorting\SortNameComparer.cs" />
|
||||
|
|
|
@ -1,394 +0,0 @@
|
|||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Common.Security;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.Model.Extensions;
|
||||
using MediaBrowser.Model.Globalization;
|
||||
|
||||
namespace Emby.Server.Implementations.Intros
|
||||
{
|
||||
public class DefaultIntroProvider : IIntroProvider
|
||||
{
|
||||
private readonly ISecurityManager _security;
|
||||
private readonly ILocalizationManager _localization;
|
||||
private readonly IConfigurationManager _serverConfig;
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
private readonly IMediaSourceManager _mediaSourceManager;
|
||||
|
||||
public DefaultIntroProvider(ISecurityManager security, ILocalizationManager localization, IConfigurationManager serverConfig, ILibraryManager libraryManager, IFileSystem fileSystem, IMediaSourceManager mediaSourceManager)
|
||||
{
|
||||
_security = security;
|
||||
_localization = localization;
|
||||
_serverConfig = serverConfig;
|
||||
_libraryManager = libraryManager;
|
||||
_fileSystem = fileSystem;
|
||||
_mediaSourceManager = mediaSourceManager;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<IntroInfo>> GetIntros(BaseItem item, User user)
|
||||
{
|
||||
var config = GetOptions();
|
||||
|
||||
if (item is Movie)
|
||||
{
|
||||
if (!config.EnableIntrosForMovies)
|
||||
{
|
||||
return new List<IntroInfo>();
|
||||
}
|
||||
}
|
||||
else if (item is Episode)
|
||||
{
|
||||
if (!config.EnableIntrosForEpisodes)
|
||||
{
|
||||
return new List<IntroInfo>();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return new List<IntroInfo>();
|
||||
}
|
||||
|
||||
var ratingLevel = string.IsNullOrWhiteSpace(item.OfficialRating)
|
||||
? null
|
||||
: _localization.GetRatingLevel(item.OfficialRating);
|
||||
|
||||
var candidates = new List<ItemWithTrailer>();
|
||||
|
||||
var trailerTypes = new List<TrailerType>();
|
||||
var sourceTypes = new List<SourceType>();
|
||||
|
||||
if (config.EnableIntrosFromMoviesInLibrary)
|
||||
{
|
||||
trailerTypes.Add(TrailerType.LocalTrailer);
|
||||
sourceTypes.Add(SourceType.Library);
|
||||
}
|
||||
|
||||
if (IsSupporter)
|
||||
{
|
||||
if (config.EnableIntrosFromUpcomingTrailers)
|
||||
{
|
||||
trailerTypes.Add(TrailerType.ComingSoonToTheaters);
|
||||
sourceTypes.Clear();
|
||||
}
|
||||
if (config.EnableIntrosFromUpcomingDvdMovies)
|
||||
{
|
||||
trailerTypes.Add(TrailerType.ComingSoonToDvd);
|
||||
sourceTypes.Clear();
|
||||
}
|
||||
if (config.EnableIntrosFromUpcomingStreamingMovies)
|
||||
{
|
||||
trailerTypes.Add(TrailerType.ComingSoonToStreaming);
|
||||
sourceTypes.Clear();
|
||||
}
|
||||
if (config.EnableIntrosFromSimilarMovies)
|
||||
{
|
||||
trailerTypes.Add(TrailerType.Archive);
|
||||
sourceTypes.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
if (trailerTypes.Count > 0)
|
||||
{
|
||||
if (trailerTypes.Count >= 5)
|
||||
{
|
||||
trailerTypes.Clear();
|
||||
}
|
||||
|
||||
// hack - can't filter by user library because local trailers get TopParentId =null in the db.
|
||||
// for now we have to use a post-query filter afterwards to solve that
|
||||
var trailerResult = _libraryManager.GetItemList(new InternalItemsQuery
|
||||
{
|
||||
IncludeItemTypes = new[] { typeof(Trailer).Name },
|
||||
TrailerTypes = trailerTypes.ToArray(),
|
||||
SimilarTo = item,
|
||||
//IsPlayed = config.EnableIntrosForWatchedContent ? (bool?)null : false,
|
||||
MaxParentalRating = config.EnableIntrosParentalControl ? ratingLevel : null,
|
||||
BlockUnratedItems = config.EnableIntrosParentalControl ? new[] { UnratedItem.Trailer } : new UnratedItem[] { },
|
||||
|
||||
// Account for duplicates by imdb id, since the database doesn't support this yet
|
||||
Limit = config.TrailerLimit * 4,
|
||||
SourceTypes = sourceTypes.ToArray()
|
||||
})
|
||||
.Where(i => string.IsNullOrWhiteSpace(i.GetProviderId(MetadataProviders.Imdb)) || !string.Equals(i.GetProviderId(MetadataProviders.Imdb), item.GetProviderId(MetadataProviders.Imdb), StringComparison.OrdinalIgnoreCase))
|
||||
.Where(i => i.IsVisibleStandalone(user))
|
||||
.Where(i => config.EnableIntrosForWatchedContent || !i.IsPlayed(user))
|
||||
.Take(config.TrailerLimit);
|
||||
|
||||
candidates.AddRange(trailerResult.Select(i => new ItemWithTrailer
|
||||
{
|
||||
Item = i,
|
||||
Type = i.SourceType == SourceType.Channel ? ItemWithTrailerType.ChannelTrailer : ItemWithTrailerType.ItemWithTrailer,
|
||||
LibraryManager = _libraryManager
|
||||
}));
|
||||
}
|
||||
|
||||
return GetResult(item, candidates, config);
|
||||
}
|
||||
|
||||
private IEnumerable<IntroInfo> GetResult(BaseItem item, IEnumerable<ItemWithTrailer> candidates, CinemaModeConfiguration config)
|
||||
{
|
||||
var customIntros = !string.IsNullOrWhiteSpace(config.CustomIntroPath) ?
|
||||
GetCustomIntros(config) :
|
||||
new List<IntroInfo>();
|
||||
|
||||
var mediaInfoIntros = !string.IsNullOrWhiteSpace(config.MediaInfoIntroPath) ?
|
||||
GetMediaInfoIntros(config, item) :
|
||||
new List<IntroInfo>();
|
||||
|
||||
// Avoid implicitly captured closure
|
||||
return candidates.Select(i => i.IntroInfo)
|
||||
.Concat(customIntros.Take(1))
|
||||
.Concat(mediaInfoIntros);
|
||||
}
|
||||
|
||||
private CinemaModeConfiguration GetOptions()
|
||||
{
|
||||
return _serverConfig.GetConfiguration<CinemaModeConfiguration>("cinemamode");
|
||||
}
|
||||
|
||||
private List<IntroInfo> GetCustomIntros(CinemaModeConfiguration options)
|
||||
{
|
||||
try
|
||||
{
|
||||
return GetCustomIntroFiles(options, true, false)
|
||||
.OrderBy(i => Guid.NewGuid())
|
||||
.Select(i => new IntroInfo
|
||||
{
|
||||
Path = i
|
||||
|
||||
}).ToList();
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
return new List<IntroInfo>();
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<IntroInfo> GetMediaInfoIntros(CinemaModeConfiguration options, BaseItem item)
|
||||
{
|
||||
try
|
||||
{
|
||||
var hasMediaSources = item as IHasMediaSources;
|
||||
|
||||
if (hasMediaSources == null)
|
||||
{
|
||||
return new List<IntroInfo>();
|
||||
}
|
||||
|
||||
var mediaSource = _mediaSourceManager.GetStaticMediaSources(hasMediaSources, false)
|
||||
.FirstOrDefault();
|
||||
|
||||
if (mediaSource == null)
|
||||
{
|
||||
return new List<IntroInfo>();
|
||||
}
|
||||
|
||||
var videoStream = mediaSource.MediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Video);
|
||||
var audioStream = mediaSource.MediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Audio);
|
||||
|
||||
var allIntros = GetCustomIntroFiles(options, false, true)
|
||||
.OrderBy(i => Guid.NewGuid())
|
||||
.Select(i => new IntroInfo
|
||||
{
|
||||
Path = i
|
||||
|
||||
}).ToList();
|
||||
|
||||
var returnResult = new List<IntroInfo>();
|
||||
|
||||
if (videoStream != null)
|
||||
{
|
||||
returnResult.AddRange(GetMediaInfoIntrosByVideoStream(allIntros, videoStream).Take(1));
|
||||
}
|
||||
|
||||
if (audioStream != null)
|
||||
{
|
||||
returnResult.AddRange(GetMediaInfoIntrosByAudioStream(allIntros, audioStream).Take(1));
|
||||
}
|
||||
|
||||
returnResult.AddRange(GetMediaInfoIntrosByTags(allIntros, item.Tags).Take(1));
|
||||
|
||||
return returnResult.DistinctBy(i => i.Path, StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
return new List<IntroInfo>();
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<IntroInfo> GetMediaInfoIntrosByVideoStream(List<IntroInfo> allIntros, MediaStream stream)
|
||||
{
|
||||
var codec = stream.Codec;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(codec))
|
||||
{
|
||||
return new List<IntroInfo>();
|
||||
}
|
||||
|
||||
return allIntros
|
||||
.Where(i => IsMatch(i.Path, codec))
|
||||
.OrderBy(i => Guid.NewGuid());
|
||||
}
|
||||
|
||||
private IEnumerable<IntroInfo> GetMediaInfoIntrosByAudioStream(List<IntroInfo> allIntros, MediaStream stream)
|
||||
{
|
||||
var codec = stream.Codec;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(codec))
|
||||
{
|
||||
return new List<IntroInfo>();
|
||||
}
|
||||
|
||||
return allIntros
|
||||
.Where(i => IsAudioMatch(i.Path, stream))
|
||||
.OrderBy(i => Guid.NewGuid());
|
||||
}
|
||||
|
||||
private IEnumerable<IntroInfo> GetMediaInfoIntrosByTags(List<IntroInfo> allIntros, List<string> tags)
|
||||
{
|
||||
return allIntros
|
||||
.Where(i => tags.Any(t => IsMatch(i.Path, t)))
|
||||
.OrderBy(i => Guid.NewGuid());
|
||||
}
|
||||
|
||||
private bool IsMatch(string file, string attribute)
|
||||
{
|
||||
var filename = Path.GetFileNameWithoutExtension(file) ?? string.Empty;
|
||||
filename = Normalize(filename);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(filename))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
attribute = Normalize(attribute);
|
||||
if (string.IsNullOrWhiteSpace(attribute))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return string.Equals(filename, attribute, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
private string Normalize(string value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
private bool IsAudioMatch(string path, MediaStream stream)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(stream.Codec))
|
||||
{
|
||||
if (IsMatch(path, stream.Codec))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(stream.Profile))
|
||||
{
|
||||
if (IsMatch(path, stream.Profile))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private IEnumerable<string> GetCustomIntroFiles(CinemaModeConfiguration options, bool enableCustomIntros, bool enableMediaInfoIntros)
|
||||
{
|
||||
var list = new List<string>();
|
||||
|
||||
if (enableCustomIntros && !string.IsNullOrWhiteSpace(options.CustomIntroPath))
|
||||
{
|
||||
list.AddRange(_fileSystem.GetFilePaths(options.CustomIntroPath, true)
|
||||
.Where(_libraryManager.IsVideoFile));
|
||||
}
|
||||
|
||||
if (enableMediaInfoIntros && !string.IsNullOrWhiteSpace(options.MediaInfoIntroPath))
|
||||
{
|
||||
list.AddRange(_fileSystem.GetFilePaths(options.MediaInfoIntroPath, true)
|
||||
.Where(_libraryManager.IsVideoFile));
|
||||
}
|
||||
|
||||
return list.Distinct(StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetAllIntroFiles()
|
||||
{
|
||||
return GetCustomIntroFiles(GetOptions(), true, true);
|
||||
}
|
||||
|
||||
private bool IsSupporter
|
||||
{
|
||||
get { return _security.IsMBSupporter; }
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "Default"; }
|
||||
}
|
||||
|
||||
internal class ItemWithTrailer
|
||||
{
|
||||
internal BaseItem Item;
|
||||
internal ItemWithTrailerType Type;
|
||||
internal ILibraryManager LibraryManager;
|
||||
|
||||
public IntroInfo IntroInfo
|
||||
{
|
||||
get
|
||||
{
|
||||
var id = Item.Id;
|
||||
|
||||
if (Type == ItemWithTrailerType.ItemWithTrailer)
|
||||
{
|
||||
var hasTrailers = Item as IHasTrailers;
|
||||
|
||||
if (hasTrailers != null)
|
||||
{
|
||||
id = hasTrailers.LocalTrailerIds.FirstOrDefault();
|
||||
}
|
||||
}
|
||||
return new IntroInfo
|
||||
{
|
||||
ItemId = id
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal enum ItemWithTrailerType
|
||||
{
|
||||
ChannelTrailer,
|
||||
ItemWithTrailer
|
||||
}
|
||||
}
|
||||
|
||||
public class CinemaModeConfigurationFactory : IConfigurationFactory
|
||||
{
|
||||
public IEnumerable<ConfigurationStore> GetConfigurations()
|
||||
{
|
||||
return new[]
|
||||
{
|
||||
new ConfigurationStore
|
||||
{
|
||||
ConfigurationType = typeof(CinemaModeConfiguration),
|
||||
Key = "cinemamode"
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -162,7 +162,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
|||
|
||||
Id = channel.Path.GetMD5().ToString("N"),
|
||||
IsInfiniteStream = true,
|
||||
SupportsDirectStream = false,
|
||||
IsRemote = true
|
||||
};
|
||||
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Sorting;
|
||||
using MediaBrowser.Model.Querying;
|
||||
|
||||
namespace Emby.Server.Implementations.Sorting
|
||||
{
|
||||
public class BudgetComparer : IBaseItemComparer
|
||||
{
|
||||
/// <summary>
|
||||
/// Compares the specified x.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
/// <returns>System.Int32.</returns>
|
||||
public int Compare(BaseItem x, BaseItem y)
|
||||
{
|
||||
return GetValue(x).CompareTo(GetValue(y));
|
||||
}
|
||||
|
||||
private double GetValue(BaseItem x)
|
||||
{
|
||||
var hasBudget = x as IHasBudget;
|
||||
if (hasBudget != null)
|
||||
{
|
||||
return hasBudget.Budget ?? 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name.
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
public string Name
|
||||
{
|
||||
get { return ItemSortBy.Budget; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Sorting;
|
||||
using MediaBrowser.Model.Querying;
|
||||
|
||||
namespace Emby.Server.Implementations.Sorting
|
||||
{
|
||||
public class RevenueComparer : IBaseItemComparer
|
||||
{
|
||||
/// <summary>
|
||||
/// Compares the specified x.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
/// <returns>System.Int32.</returns>
|
||||
public int Compare(BaseItem x, BaseItem y)
|
||||
{
|
||||
return GetValue(x).CompareTo(GetValue(y));
|
||||
}
|
||||
|
||||
private double GetValue(BaseItem x)
|
||||
{
|
||||
var hasBudget = x as IHasBudget;
|
||||
if (hasBudget != null)
|
||||
{
|
||||
return hasBudget.Revenue ?? 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name.
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
public string Name
|
||||
{
|
||||
get { return ItemSortBy.Revenue; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -162,15 +162,15 @@ namespace Emby.Server.Implementations.Updates
|
|||
string packageType = null,
|
||||
Version applicationVersion = null)
|
||||
{
|
||||
var data = new Dictionary<string, string>
|
||||
{
|
||||
{ "key", _securityManager.SupporterKey },
|
||||
{ "mac", _applicationHost.SystemId },
|
||||
{ "systemid", _applicationHost.SystemId }
|
||||
};
|
||||
|
||||
if (withRegistration)
|
||||
{
|
||||
var data = new Dictionary<string, string>
|
||||
{
|
||||
{ "key", _securityManager.SupporterKey },
|
||||
{ "mac", _applicationHost.SystemId },
|
||||
{ "systemid", _applicationHost.SystemId }
|
||||
};
|
||||
|
||||
using (var json = await _httpClient.Post("https://www.mb3admin.com/admin/service/package/retrieveall", data, cancellationToken).ConfigureAwait(false))
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
@ -353,7 +353,7 @@ namespace Emby.Server.Implementations.Updates
|
|||
/// <returns>Task{PackageVersionInfo}.</returns>
|
||||
public async Task<PackageVersionInfo> GetPackage(string name, string guid, PackageVersionClass classification, Version version)
|
||||
{
|
||||
var packages = await GetAvailablePackages(CancellationToken.None).ConfigureAwait(false);
|
||||
var packages = await GetAvailablePackages(CancellationToken.None, false).ConfigureAwait(false);
|
||||
|
||||
var package = packages.FirstOrDefault(p => string.Equals(p.guid, guid ?? "none", StringComparison.OrdinalIgnoreCase))
|
||||
?? packages.FirstOrDefault(p => p.name.Equals(name, StringComparison.OrdinalIgnoreCase));
|
||||
|
@ -376,7 +376,7 @@ namespace Emby.Server.Implementations.Updates
|
|||
/// <returns>Task{PackageVersionInfo}.</returns>
|
||||
public async Task<PackageVersionInfo> GetLatestCompatibleVersion(string name, string guid, Version currentServerVersion, PackageVersionClass classification = PackageVersionClass.Release)
|
||||
{
|
||||
var packages = await GetAvailablePackages(CancellationToken.None).ConfigureAwait(false);
|
||||
var packages = await GetAvailablePackages(CancellationToken.None, false).ConfigureAwait(false);
|
||||
|
||||
return GetLatestCompatibleVersion(packages, name, guid, currentServerVersion, classification);
|
||||
}
|
||||
|
|
|
@ -134,10 +134,6 @@
|
|||
<Compile Include="SearchService.cs" />
|
||||
<Compile Include="Session\SessionsService.cs" />
|
||||
<Compile Include="SimilarItemsHelper.cs" />
|
||||
<Compile Include="Sync\SyncHelper.cs" />
|
||||
<Compile Include="Sync\SyncJobWebSocketListener.cs" />
|
||||
<Compile Include="Sync\SyncJobsWebSocketListener.cs" />
|
||||
<Compile Include="Sync\SyncService.cs" />
|
||||
<Compile Include="System\ActivityLogService.cs" />
|
||||
<Compile Include="System\ActivityLogWebSocketListener.cs" />
|
||||
<Compile Include="System\SystemService.cs" />
|
||||
|
|
|
@ -31,6 +31,7 @@ namespace MediaBrowser.Api.Playback.Progressive
|
|||
/// <summary>
|
||||
/// Class AudioService
|
||||
/// </summary>
|
||||
[Authenticated]
|
||||
public class AudioService : BaseProgressiveStreamingService
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
@ -1,85 +0,0 @@
|
|||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Sync;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Api.Sync
|
||||
{
|
||||
public static class SyncHelper
|
||||
{
|
||||
public static List<SyncJobOption> GetSyncOptions(List<BaseItemDto> items)
|
||||
{
|
||||
List<SyncJobOption> options = new List<SyncJobOption>();
|
||||
|
||||
foreach (BaseItemDto item in items)
|
||||
{
|
||||
if (item.SupportsSync ?? false)
|
||||
{
|
||||
if (item.IsVideo)
|
||||
{
|
||||
options.Add(SyncJobOption.Quality);
|
||||
options.Add(SyncJobOption.Profile);
|
||||
if (items.Count > 1)
|
||||
{
|
||||
options.Add(SyncJobOption.UnwatchedOnly);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (item.IsAudio)
|
||||
{
|
||||
options.Add(SyncJobOption.Quality);
|
||||
options.Add(SyncJobOption.Profile);
|
||||
break;
|
||||
}
|
||||
if (item.IsMusicGenre || item.IsArtist|| item.IsType("musicalbum"))
|
||||
{
|
||||
options.Add(SyncJobOption.Quality);
|
||||
options.Add(SyncJobOption.Profile);
|
||||
options.Add(SyncJobOption.ItemLimit);
|
||||
break;
|
||||
}
|
||||
if ((item.IsFolder ?? false) && !item.IsMusicGenre && !item.IsArtist && !item.IsType("musicalbum") && !item.IsGameGenre)
|
||||
{
|
||||
options.Add(SyncJobOption.Quality);
|
||||
options.Add(SyncJobOption.Profile);
|
||||
options.Add(SyncJobOption.UnwatchedOnly);
|
||||
break;
|
||||
}
|
||||
if (item.IsGenre)
|
||||
{
|
||||
options.Add(SyncJobOption.SyncNewContent);
|
||||
options.Add(SyncJobOption.ItemLimit);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (BaseItemDto item in items)
|
||||
{
|
||||
if (item.SupportsSync ?? false)
|
||||
{
|
||||
if ((item.IsFolder ?? false) || item.IsGameGenre || item.IsMusicGenre || item.IsGenre || item.IsArtist || item.IsStudio || item.IsPerson)
|
||||
{
|
||||
options.Add(SyncJobOption.SyncNewContent);
|
||||
options.Add(SyncJobOption.ItemLimit);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
public static List<SyncJobOption> GetSyncOptions(SyncCategory category)
|
||||
{
|
||||
List<SyncJobOption> options = new List<SyncJobOption>();
|
||||
|
||||
options.Add(SyncJobOption.Quality);
|
||||
options.Add(SyncJobOption.Profile);
|
||||
options.Add(SyncJobOption.UnwatchedOnly);
|
||||
options.Add(SyncJobOption.SyncNewContent);
|
||||
options.Add(SyncJobOption.ItemLimit);
|
||||
|
||||
return options;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,120 +0,0 @@
|
|||
using MediaBrowser.Controller.Sync;
|
||||
using MediaBrowser.Model.Events;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Model.Sync;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Threading;
|
||||
|
||||
namespace MediaBrowser.Api.Sync
|
||||
{
|
||||
/// <summary>
|
||||
/// Class SessionInfoWebSocketListener
|
||||
/// </summary>
|
||||
class SyncJobWebSocketListener : BasePeriodicWebSocketListener<CompleteSyncJobInfo, WebSocketListenerState>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the name.
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
protected override string Name
|
||||
{
|
||||
get { return "SyncJob"; }
|
||||
}
|
||||
|
||||
private readonly ISyncManager _syncManager;
|
||||
private string _jobId;
|
||||
|
||||
public SyncJobWebSocketListener(ILogger logger, ISyncManager syncManager, ITimerFactory timerFactory)
|
||||
: base(logger, timerFactory)
|
||||
{
|
||||
_syncManager = syncManager;
|
||||
_syncManager.SyncJobCancelled += _syncManager_SyncJobCancelled;
|
||||
_syncManager.SyncJobUpdated += _syncManager_SyncJobUpdated;
|
||||
_syncManager.SyncJobItemCreated += _syncManager_SyncJobItemCreated;
|
||||
_syncManager.SyncJobItemUpdated += _syncManager_SyncJobItemUpdated;
|
||||
}
|
||||
|
||||
void _syncManager_SyncJobItemUpdated(object sender, GenericEventArgs<SyncJobItem> e)
|
||||
{
|
||||
if (string.Equals(e.Argument.Id, _jobId, StringComparison.Ordinal))
|
||||
{
|
||||
SendData(false);
|
||||
}
|
||||
}
|
||||
|
||||
void _syncManager_SyncJobItemCreated(object sender, GenericEventArgs<SyncJobItem> e)
|
||||
{
|
||||
if (string.Equals(e.Argument.Id, _jobId, StringComparison.Ordinal))
|
||||
{
|
||||
SendData(true);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void ParseMessageParams(string[] values)
|
||||
{
|
||||
base.ParseMessageParams(values);
|
||||
|
||||
if (values.Length > 0)
|
||||
{
|
||||
_jobId = values[0];
|
||||
}
|
||||
}
|
||||
|
||||
void _syncManager_SyncJobUpdated(object sender, GenericEventArgs<SyncJob> e)
|
||||
{
|
||||
if (string.Equals(e.Argument.Id, _jobId, StringComparison.Ordinal))
|
||||
{
|
||||
SendData(false);
|
||||
}
|
||||
}
|
||||
|
||||
void _syncManager_SyncJobCancelled(object sender, GenericEventArgs<SyncJob> e)
|
||||
{
|
||||
if (string.Equals(e.Argument.Id, _jobId, StringComparison.Ordinal))
|
||||
{
|
||||
SendData(true);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the data to send.
|
||||
/// </summary>
|
||||
/// <param name="state">The state.</param>
|
||||
/// <returns>Task{SystemInfo}.</returns>
|
||||
protected override Task<CompleteSyncJobInfo> GetDataToSend(WebSocketListenerState state)
|
||||
{
|
||||
var job = _syncManager.GetJob(_jobId);
|
||||
var items = _syncManager.GetJobItems(new SyncJobItemQuery
|
||||
{
|
||||
AddMetadata = true,
|
||||
JobId = _jobId
|
||||
});
|
||||
|
||||
var info = new CompleteSyncJobInfo
|
||||
{
|
||||
Job = job,
|
||||
JobItems = items.Items.ToList()
|
||||
};
|
||||
|
||||
return Task.FromResult(info);
|
||||
}
|
||||
|
||||
protected override bool SendOnTimer
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Dispose(bool dispose)
|
||||
{
|
||||
_syncManager.SyncJobCancelled -= _syncManager_SyncJobCancelled;
|
||||
_syncManager.SyncJobUpdated -= _syncManager_SyncJobUpdated;
|
||||
|
||||
base.Dispose(dispose);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,101 +0,0 @@
|
|||
using MediaBrowser.Controller.Sync;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Model.Sync;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Threading;
|
||||
|
||||
namespace MediaBrowser.Api.Sync
|
||||
{
|
||||
/// <summary>
|
||||
/// Class SessionInfoWebSocketListener
|
||||
/// </summary>
|
||||
class SyncJobsWebSocketListener : BasePeriodicWebSocketListener<IEnumerable<SyncJob>, WebSocketListenerState>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the name.
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
protected override string Name
|
||||
{
|
||||
get { return "SyncJobs"; }
|
||||
}
|
||||
|
||||
private readonly ISyncManager _syncManager;
|
||||
private string _userId;
|
||||
private string _targetId;
|
||||
|
||||
public SyncJobsWebSocketListener(ILogger logger, ISyncManager syncManager, ITimerFactory timerFactory)
|
||||
: base(logger, timerFactory)
|
||||
{
|
||||
_syncManager = syncManager;
|
||||
_syncManager.SyncJobCancelled += _syncManager_SyncJobCancelled;
|
||||
_syncManager.SyncJobCreated += _syncManager_SyncJobCreated;
|
||||
_syncManager.SyncJobUpdated += _syncManager_SyncJobUpdated;
|
||||
}
|
||||
|
||||
protected override void ParseMessageParams(string[] values)
|
||||
{
|
||||
base.ParseMessageParams(values);
|
||||
|
||||
if (values.Length > 0)
|
||||
{
|
||||
_userId = values[0];
|
||||
}
|
||||
|
||||
if (values.Length > 1)
|
||||
{
|
||||
_targetId = values[1];
|
||||
}
|
||||
}
|
||||
|
||||
void _syncManager_SyncJobUpdated(object sender, Model.Events.GenericEventArgs<SyncJob> e)
|
||||
{
|
||||
SendData(false);
|
||||
}
|
||||
|
||||
void _syncManager_SyncJobCreated(object sender, Model.Events.GenericEventArgs<SyncJobCreationResult> e)
|
||||
{
|
||||
SendData(true);
|
||||
}
|
||||
|
||||
void _syncManager_SyncJobCancelled(object sender, Model.Events.GenericEventArgs<SyncJob> e)
|
||||
{
|
||||
SendData(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the data to send.
|
||||
/// </summary>
|
||||
/// <param name="state">The state.</param>
|
||||
/// <returns>Task{SystemInfo}.</returns>
|
||||
protected override async Task<IEnumerable<SyncJob>> GetDataToSend(WebSocketListenerState state)
|
||||
{
|
||||
var jobs = await _syncManager.GetJobs(new SyncJobQuery
|
||||
{
|
||||
UserId = _userId,
|
||||
TargetId = _targetId
|
||||
|
||||
}).ConfigureAwait(false);
|
||||
|
||||
return jobs.Items;
|
||||
}
|
||||
|
||||
protected override bool SendOnTimer
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Dispose(bool dispose)
|
||||
{
|
||||
_syncManager.SyncJobCancelled -= _syncManager_SyncJobCancelled;
|
||||
_syncManager.SyncJobCreated -= _syncManager_SyncJobCreated;
|
||||
_syncManager.SyncJobUpdated -= _syncManager_SyncJobUpdated;
|
||||
|
||||
base.Dispose(dispose);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,396 +0,0 @@
|
|||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Net;
|
||||
using MediaBrowser.Controller.Sync;
|
||||
using MediaBrowser.Model.Querying;
|
||||
using MediaBrowser.Model.Sync;
|
||||
using MediaBrowser.Model.Users;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Services;
|
||||
|
||||
namespace MediaBrowser.Api.Sync
|
||||
{
|
||||
[Route("/Sync/Jobs/{Id}", "DELETE", Summary = "Cancels a sync job.")]
|
||||
public class CancelSyncJob : IReturnVoid
|
||||
{
|
||||
[ApiMember(Name = "Id", Description = "Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
|
||||
public string Id { get; set; }
|
||||
}
|
||||
|
||||
[Route("/Sync/Jobs/{Id}", "GET", Summary = "Gets a sync job.")]
|
||||
public class GetSyncJob : IReturn<SyncJob>
|
||||
{
|
||||
[ApiMember(Name = "Id", Description = "Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
|
||||
public string Id { get; set; }
|
||||
}
|
||||
|
||||
[Route("/Sync/Jobs/{Id}", "POST", Summary = "Updates a sync job.")]
|
||||
public class UpdateSyncJob : SyncJob, IReturnVoid
|
||||
{
|
||||
}
|
||||
|
||||
[Route("/Sync/JobItems", "GET", Summary = "Gets sync job items.")]
|
||||
public class GetSyncJobItems : SyncJobItemQuery, IReturn<QueryResult<SyncJobItem>>
|
||||
{
|
||||
}
|
||||
|
||||
[Route("/Sync/JobItems/{Id}/Enable", "POST", Summary = "Enables a cancelled or queued sync job item")]
|
||||
public class EnableSyncJobItem : IReturnVoid
|
||||
{
|
||||
[ApiMember(Name = "Id", Description = "Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
|
||||
public string Id { get; set; }
|
||||
}
|
||||
|
||||
[Route("/Sync/JobItems/{Id}/MarkForRemoval", "POST", Summary = "Marks a job item for removal")]
|
||||
public class MarkJobItemForRemoval : IReturnVoid
|
||||
{
|
||||
[ApiMember(Name = "Id", Description = "Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
|
||||
public string Id { get; set; }
|
||||
}
|
||||
|
||||
[Route("/Sync/JobItems/{Id}/UnmarkForRemoval", "POST", Summary = "Unmarks a job item for removal")]
|
||||
public class UnmarkJobItemForRemoval : IReturnVoid
|
||||
{
|
||||
[ApiMember(Name = "Id", Description = "Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
|
||||
public string Id { get; set; }
|
||||
}
|
||||
|
||||
[Route("/Sync/JobItems/{Id}", "DELETE", Summary = "Cancels a sync job item")]
|
||||
public class CancelSyncJobItem : IReturnVoid
|
||||
{
|
||||
[ApiMember(Name = "Id", Description = "Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
|
||||
public string Id { get; set; }
|
||||
}
|
||||
|
||||
[Route("/Sync/Items/Cancel", "POST", Summary = "Cancels items from a sync target")]
|
||||
[Route("/Sync/{TargetId}/Items", "DELETE", Summary = "Cancels items from a sync target")]
|
||||
public class CancelItems : IReturnVoid
|
||||
{
|
||||
[ApiMember(Name = "TargetId", Description = "TargetId", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "Items")]
|
||||
public string TargetId { get; set; }
|
||||
|
||||
[ApiMember(Name = "ItemIds", Description = "ItemIds", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "Items")]
|
||||
public string ItemIds { get; set; }
|
||||
}
|
||||
|
||||
[Route("/Sync/Jobs", "GET", Summary = "Gets sync jobs.")]
|
||||
public class GetSyncJobs : SyncJobQuery, IReturn<QueryResult<SyncJob>>
|
||||
{
|
||||
}
|
||||
|
||||
[Route("/Sync/Jobs", "POST", Summary = "Gets sync jobs.")]
|
||||
public class CreateSyncJob : SyncJobRequest, IReturn<SyncJobCreationResult>
|
||||
{
|
||||
}
|
||||
|
||||
[Route("/Sync/Targets", "GET", Summary = "Gets a list of available sync targets.")]
|
||||
public class GetSyncTargets : IReturn<List<SyncTarget>>
|
||||
{
|
||||
[ApiMember(Name = "UserId", Description = "UserId", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
|
||||
public string UserId { get; set; }
|
||||
}
|
||||
|
||||
[Route("/Sync/Options", "GET", Summary = "Gets a list of available sync targets.")]
|
||||
public class GetSyncDialogOptions : IReturn<SyncDialogOptions>
|
||||
{
|
||||
[ApiMember(Name = "UserId", Description = "UserId", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
|
||||
public string UserId { get; set; }
|
||||
|
||||
[ApiMember(Name = "ItemIds", Description = "ItemIds", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
|
||||
public string ItemIds { get; set; }
|
||||
|
||||
[ApiMember(Name = "ParentId", Description = "ParentId", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
|
||||
public string ParentId { get; set; }
|
||||
|
||||
[ApiMember(Name = "TargetId", Description = "TargetId", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
|
||||
public string TargetId { get; set; }
|
||||
|
||||
[ApiMember(Name = "Category", Description = "Category", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
|
||||
public SyncCategory? Category { get; set; }
|
||||
}
|
||||
|
||||
[Route("/Sync/JobItems/{Id}/Transferred", "POST", Summary = "Reports that a sync job item has successfully been transferred.")]
|
||||
public class ReportSyncJobItemTransferred : IReturnVoid
|
||||
{
|
||||
[ApiMember(Name = "Id", Description = "Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
|
||||
public string Id { get; set; }
|
||||
}
|
||||
|
||||
[Route("/Sync/JobItems/{Id}/File", "GET", Summary = "Gets a sync job item file")]
|
||||
public class GetSyncJobItemFile
|
||||
{
|
||||
[ApiMember(Name = "Id", Description = "Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
|
||||
public string Id { get; set; }
|
||||
}
|
||||
|
||||
[Route("/Sync/JobItems/{Id}/AdditionalFiles", "GET", Summary = "Gets a sync job item file")]
|
||||
public class GetSyncJobItemAdditionalFile
|
||||
{
|
||||
[ApiMember(Name = "Id", Description = "Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
|
||||
public string Id { get; set; }
|
||||
|
||||
[ApiMember(Name = "Name", Description = "Name", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
|
||||
public string Name { get; set; }
|
||||
}
|
||||
|
||||
[Route("/Sync/OfflineActions", "POST", Summary = "Reports an action that occurred while offline.")]
|
||||
public class ReportOfflineActions : List<UserAction>, IReturnVoid
|
||||
{
|
||||
}
|
||||
|
||||
[Route("/Sync/Items/Ready", "GET", Summary = "Gets ready to download sync items.")]
|
||||
public class GetReadySyncItems : IReturn<List<SyncedItem>>
|
||||
{
|
||||
[ApiMember(Name = "TargetId", Description = "TargetId", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
|
||||
public string TargetId { get; set; }
|
||||
}
|
||||
|
||||
[Route("/Sync/Data", "POST", Summary = "Syncs data between device and server")]
|
||||
public class SyncData : SyncDataRequest, IReturn<SyncDataResponse>
|
||||
{
|
||||
}
|
||||
|
||||
[Authenticated]
|
||||
public class SyncService : BaseApiService
|
||||
{
|
||||
private readonly ISyncManager _syncManager;
|
||||
private readonly IDtoService _dtoService;
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
private readonly IUserManager _userManager;
|
||||
private readonly IAuthorizationContext _authContext;
|
||||
|
||||
public SyncService(ISyncManager syncManager, IDtoService dtoService, ILibraryManager libraryManager, IUserManager userManager, IAuthorizationContext authContext)
|
||||
{
|
||||
_syncManager = syncManager;
|
||||
_dtoService = dtoService;
|
||||
_libraryManager = libraryManager;
|
||||
_userManager = userManager;
|
||||
_authContext = authContext;
|
||||
}
|
||||
|
||||
public object Get(GetSyncTargets request)
|
||||
{
|
||||
var result = _syncManager.GetSyncTargets(request.UserId);
|
||||
|
||||
return ToOptimizedResult(result);
|
||||
}
|
||||
|
||||
public async Task<object> Get(GetSyncJobs request)
|
||||
{
|
||||
var result = await _syncManager.GetJobs(request).ConfigureAwait(false);
|
||||
|
||||
return ToOptimizedResult(result);
|
||||
}
|
||||
|
||||
public object Get(GetSyncJobItems request)
|
||||
{
|
||||
var result = _syncManager.GetJobItems(request);
|
||||
|
||||
return ToOptimizedResult(result);
|
||||
}
|
||||
|
||||
public object Get(GetSyncJob request)
|
||||
{
|
||||
var result = _syncManager.GetJob(request.Id);
|
||||
|
||||
return ToOptimizedResult(result);
|
||||
}
|
||||
|
||||
public void Delete(CancelSyncJob request)
|
||||
{
|
||||
var task = _syncManager.CancelJob(request.Id);
|
||||
|
||||
Task.WaitAll(task);
|
||||
}
|
||||
|
||||
public async Task<object> Post(CreateSyncJob request)
|
||||
{
|
||||
var result = await _syncManager.CreateJob(request).ConfigureAwait(false);
|
||||
|
||||
return ToOptimizedResult(result);
|
||||
}
|
||||
|
||||
public void Any(CancelItems request)
|
||||
{
|
||||
var itemIds = request.ItemIds.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
var task = _syncManager.CancelItems(request.TargetId, itemIds);
|
||||
|
||||
Task.WaitAll(task);
|
||||
}
|
||||
|
||||
public void Post(ReportSyncJobItemTransferred request)
|
||||
{
|
||||
var task = _syncManager.ReportSyncJobItemTransferred(request.Id);
|
||||
|
||||
Task.WaitAll(task);
|
||||
}
|
||||
|
||||
public async Task<object> Get(GetSyncJobItemFile request)
|
||||
{
|
||||
var jobItem = _syncManager.GetJobItem(request.Id);
|
||||
|
||||
if (jobItem == null)
|
||||
{
|
||||
throw new ResourceNotFoundException();
|
||||
}
|
||||
|
||||
if (jobItem.Status < SyncJobItemStatus.ReadyToTransfer)
|
||||
{
|
||||
throw new ArgumentException("The job item is not yet ready for transfer.");
|
||||
}
|
||||
|
||||
await _syncManager.ReportSyncJobItemTransferBeginning(request.Id).ConfigureAwait(false);
|
||||
|
||||
return await ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions
|
||||
{
|
||||
Path = jobItem.OutputPath,
|
||||
OnError = () =>
|
||||
{
|
||||
var failedTask = _syncManager.ReportSyncJobItemTransferFailed(request.Id);
|
||||
Task.WaitAll(failedTask);
|
||||
}
|
||||
|
||||
}).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task<object> Get(GetSyncDialogOptions request)
|
||||
{
|
||||
var result = new SyncDialogOptions();
|
||||
|
||||
result.Targets = _syncManager.GetSyncTargets(request.UserId)
|
||||
.ToList();
|
||||
|
||||
var auth = _authContext.GetAuthorizationInfo(Request);
|
||||
var authenticatedUser = _userManager.GetUserById(auth.UserId);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(request.TargetId))
|
||||
{
|
||||
result.Targets = result.Targets
|
||||
.Where(i => string.Equals(i.Id, request.TargetId, StringComparison.OrdinalIgnoreCase))
|
||||
.ToList();
|
||||
|
||||
result.QualityOptions = _syncManager
|
||||
.GetQualityOptions(request.TargetId, authenticatedUser)
|
||||
.ToList();
|
||||
|
||||
result.ProfileOptions = _syncManager
|
||||
.GetProfileOptions(request.TargetId, authenticatedUser)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
if (request.Category.HasValue)
|
||||
{
|
||||
result.Options = SyncHelper.GetSyncOptions(request.Category.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
var dtoOptions = new DtoOptions
|
||||
{
|
||||
Fields = new List<ItemFields>
|
||||
{
|
||||
ItemFields.SyncInfo,
|
||||
ItemFields.BasicSyncInfo
|
||||
}
|
||||
};
|
||||
|
||||
var items = request.ItemIds.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
|
||||
.Select(_libraryManager.GetItemById)
|
||||
.Where(i => i != null);
|
||||
|
||||
var dtos = (await _dtoService.GetBaseItemDtos(items, dtoOptions, authenticatedUser).ConfigureAwait(false));
|
||||
|
||||
result.Options = SyncHelper.GetSyncOptions(dtos);
|
||||
}
|
||||
|
||||
return ToOptimizedResult(result);
|
||||
}
|
||||
|
||||
public void Post(ReportOfflineActions request)
|
||||
{
|
||||
var task = PostAsync(request);
|
||||
|
||||
Task.WaitAll(task);
|
||||
}
|
||||
|
||||
public async Task PostAsync(ReportOfflineActions request)
|
||||
{
|
||||
foreach (var action in request)
|
||||
{
|
||||
await _syncManager.ReportOfflineAction(action).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<object> Get(GetReadySyncItems request)
|
||||
{
|
||||
var result = await _syncManager.GetReadySyncItems(request.TargetId).ConfigureAwait(false);
|
||||
|
||||
return ToOptimizedResult(result);
|
||||
}
|
||||
|
||||
public async Task<object> Post(SyncData request)
|
||||
{
|
||||
var response = await _syncManager.SyncData(request).ConfigureAwait(false);
|
||||
|
||||
return ToOptimizedResult(response);
|
||||
}
|
||||
|
||||
public void Post(UpdateSyncJob request)
|
||||
{
|
||||
var task = _syncManager.UpdateJob(request);
|
||||
|
||||
Task.WaitAll(task);
|
||||
}
|
||||
|
||||
public Task<object> Get(GetSyncJobItemAdditionalFile request)
|
||||
{
|
||||
var jobItem = _syncManager.GetJobItem(request.Id);
|
||||
|
||||
if (jobItem.Status < SyncJobItemStatus.ReadyToTransfer)
|
||||
{
|
||||
throw new ArgumentException("The job item is not yet ready for transfer.");
|
||||
}
|
||||
|
||||
var file = jobItem.AdditionalFiles.FirstOrDefault(i => string.Equals(i.Name, request.Name, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (file == null)
|
||||
{
|
||||
throw new ArgumentException("Sync job additional file not found.");
|
||||
}
|
||||
|
||||
return ResultFactory.GetStaticFileResult(Request, file.Path);
|
||||
}
|
||||
|
||||
public void Post(EnableSyncJobItem request)
|
||||
{
|
||||
var task = _syncManager.ReEnableJobItem(request.Id);
|
||||
|
||||
Task.WaitAll(task);
|
||||
}
|
||||
|
||||
public void Delete(CancelSyncJobItem request)
|
||||
{
|
||||
var task = _syncManager.CancelJobItem(request.Id);
|
||||
|
||||
Task.WaitAll(task);
|
||||
}
|
||||
|
||||
public void Post(MarkJobItemForRemoval request)
|
||||
{
|
||||
var task = _syncManager.MarkJobItemForRemoval(request.Id);
|
||||
|
||||
Task.WaitAll(task);
|
||||
}
|
||||
|
||||
public void Post(UnmarkJobItemForRemoval request)
|
||||
{
|
||||
var task = _syncManager.UnmarkJobItemForRemoval(request.Id);
|
||||
|
||||
Task.WaitAll(task);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -756,11 +756,6 @@ namespace MediaBrowser.Controller.Entities
|
|||
Logger.Debug("Query requires post-filtering due to ItemSortBy.AiredEpisodeOrder");
|
||||
return true;
|
||||
}
|
||||
if (query.SortBy.Contains(ItemSortBy.Budget, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
Logger.Debug("Query requires post-filtering due to ItemSortBy.Budget");
|
||||
return true;
|
||||
}
|
||||
if (query.SortBy.Contains(ItemSortBy.GameSystem, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
Logger.Debug("Query requires post-filtering due to ItemSortBy.GameSystem");
|
||||
|
@ -776,11 +771,6 @@ namespace MediaBrowser.Controller.Entities
|
|||
Logger.Debug("Query requires post-filtering due to ItemSortBy.Players");
|
||||
return true;
|
||||
}
|
||||
if (query.SortBy.Contains(ItemSortBy.Revenue, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
Logger.Debug("Query requires post-filtering due to ItemSortBy.Revenue");
|
||||
return true;
|
||||
}
|
||||
if (query.SortBy.Contains(ItemSortBy.VideoBitRate, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
Logger.Debug("Query requires post-filtering due to ItemSortBy.VideoBitRate");
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public interface IHasBudget
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the budget.
|
||||
/// </summary>
|
||||
/// <value>The budget.</value>
|
||||
double? Budget { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the revenue.
|
||||
/// </summary>
|
||||
/// <value>The revenue.</value>
|
||||
double? Revenue { get; set; }
|
||||
}
|
||||
}
|
|
@ -17,7 +17,7 @@ namespace MediaBrowser.Controller.Entities.Movies
|
|||
/// <summary>
|
||||
/// Class Movie
|
||||
/// </summary>
|
||||
public class Movie : Video, IHasSpecialFeatures, IHasBudget, IHasTrailers, IHasAwards, IHasMetascore, IHasLookupInfo<MovieInfo>, ISupportsBoxSetGrouping
|
||||
public class Movie : Video, IHasSpecialFeatures, IHasTrailers, IHasAwards, IHasMetascore, IHasLookupInfo<MovieInfo>, ISupportsBoxSetGrouping
|
||||
{
|
||||
public List<Guid> SpecialFeatureIds { get; set; }
|
||||
|
||||
|
@ -45,18 +45,6 @@ namespace MediaBrowser.Controller.Entities.Movies
|
|||
/// <value>The taglines.</value>
|
||||
public List<string> Taglines { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the budget.
|
||||
/// </summary>
|
||||
/// <value>The budget.</value>
|
||||
public double? Budget { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the revenue.
|
||||
/// </summary>
|
||||
/// <value>The revenue.</value>
|
||||
public double? Revenue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the TMDB collection.
|
||||
/// </summary>
|
||||
|
|
|
@ -6,19 +6,8 @@ using MediaBrowser.Model.Serialization;
|
|||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public class MusicVideo : Video, IHasArtist, IHasMusicGenres, IHasBudget, IHasLookupInfo<MusicVideoInfo>
|
||||
public class MusicVideo : Video, IHasArtist, IHasMusicGenres, IHasLookupInfo<MusicVideoInfo>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the budget.
|
||||
/// </summary>
|
||||
/// <value>The budget.</value>
|
||||
public double? Budget { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the revenue.
|
||||
/// </summary>
|
||||
/// <value>The revenue.</value>
|
||||
public double? Revenue { get; set; }
|
||||
public List<string> Artists { get; set; }
|
||||
|
||||
public MusicVideo()
|
||||
|
|
|
@ -109,7 +109,6 @@
|
|||
<Compile Include="Entities\GameGenre.cs" />
|
||||
<Compile Include="Entities\GameSystem.cs" />
|
||||
<Compile Include="Entities\IHasAspectRatio.cs" />
|
||||
<Compile Include="Entities\IHasBudget.cs" />
|
||||
<Compile Include="Entities\IHasDisplayOrder.cs" />
|
||||
<Compile Include="Entities\IHasId.cs" />
|
||||
<Compile Include="Entities\IHasImages.cs" />
|
||||
|
|
|
@ -154,6 +154,23 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||
{
|
||||
return "mpegts";
|
||||
}
|
||||
if (string.Equals(container, "mpg", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return "mpeg";
|
||||
}
|
||||
// For these need to find out the ffmpeg names
|
||||
if (string.Equals(container, "m2ts", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (string.Equals(container, "wmv", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (string.Equals(container, "vob", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return container;
|
||||
}
|
||||
|
@ -1477,7 +1494,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||
//inputModifier += " -noaccurate_seek";
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(state.InputContainer))
|
||||
if (!string.IsNullOrWhiteSpace(state.InputContainer) && state.VideoType == VideoType.VideoFile)
|
||||
{
|
||||
var inputFormat = GetInputFormat(state.InputContainer);
|
||||
if (!string.IsNullOrWhiteSpace(inputFormat))
|
||||
|
@ -1486,7 +1503,8 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||
}
|
||||
}
|
||||
|
||||
if (state.RunTimeTicks.HasValue && string.IsNullOrWhiteSpace(encodingOptions.HardwareAccelerationType))
|
||||
// Only do this for video files due to sometimes unpredictable codec names coming from BDInfo
|
||||
if (state.RunTimeTicks.HasValue && string.IsNullOrWhiteSpace(encodingOptions.HardwareAccelerationType) && state.VideoType == VideoType.VideoFile)
|
||||
{
|
||||
foreach (var stream in state.MediaSource.MediaStreams)
|
||||
{
|
||||
|
|
|
@ -207,38 +207,6 @@ namespace MediaBrowser.LocalMetadata.Parsers
|
|||
break;
|
||||
}
|
||||
|
||||
case "Budget":
|
||||
{
|
||||
var text = reader.ReadElementContentAsString();
|
||||
var hasBudget = item as IHasBudget;
|
||||
if (hasBudget != null)
|
||||
{
|
||||
double value;
|
||||
if (double.TryParse(text, NumberStyles.Any, _usCulture, out value))
|
||||
{
|
||||
hasBudget.Budget = value;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case "Revenue":
|
||||
{
|
||||
var text = reader.ReadElementContentAsString();
|
||||
var hasBudget = item as IHasBudget;
|
||||
if (hasBudget != null)
|
||||
{
|
||||
double value;
|
||||
if (double.TryParse(text, NumberStyles.Any, _usCulture, out value))
|
||||
{
|
||||
hasBudget.Revenue = value;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case "Metascore":
|
||||
{
|
||||
var text = reader.ReadElementContentAsString();
|
||||
|
|
|
@ -37,7 +37,6 @@ namespace MediaBrowser.LocalMetadata.Savers
|
|||
"AudioDbArtistId",
|
||||
"AwardSummary",
|
||||
"BirthDate",
|
||||
"Budget",
|
||||
|
||||
// Deprecated. No longer saving in this field.
|
||||
"certification",
|
||||
|
@ -90,7 +89,6 @@ namespace MediaBrowser.LocalMetadata.Savers
|
|||
"PremiereDate",
|
||||
"ProductionYear",
|
||||
"Rating",
|
||||
"Revenue",
|
||||
"RottenTomatoesId",
|
||||
"RunningTime",
|
||||
|
||||
|
@ -435,20 +433,6 @@ namespace MediaBrowser.LocalMetadata.Savers
|
|||
writer.WriteElementString("AwardSummary", hasAwards.AwardSummary);
|
||||
}
|
||||
|
||||
var hasBudget = item as IHasBudget;
|
||||
if (hasBudget != null)
|
||||
{
|
||||
if (hasBudget.Budget.HasValue)
|
||||
{
|
||||
writer.WriteElementString("Budget", hasBudget.Budget.Value.ToString(UsCulture));
|
||||
}
|
||||
|
||||
if (hasBudget.Revenue.HasValue)
|
||||
{
|
||||
writer.WriteElementString("Revenue", hasBudget.Revenue.Value.ToString(UsCulture));
|
||||
}
|
||||
}
|
||||
|
||||
if (item.CommunityRating.HasValue)
|
||||
{
|
||||
writer.WriteElementString("Rating", item.CommunityRating.Value.ToString(UsCulture));
|
||||
|
|
|
@ -20,11 +20,6 @@
|
|||
/// </summary>
|
||||
AwardSummary,
|
||||
|
||||
/// <summary>
|
||||
/// The budget
|
||||
/// </summary>
|
||||
Budget,
|
||||
|
||||
/// <summary>
|
||||
/// The can delete
|
||||
/// </summary>
|
||||
|
@ -173,11 +168,6 @@
|
|||
|
||||
RecursiveItemCount,
|
||||
|
||||
/// <summary>
|
||||
/// The revenue
|
||||
/// </summary>
|
||||
Revenue,
|
||||
|
||||
/// <summary>
|
||||
/// The season name
|
||||
/// </summary>
|
||||
|
|
|
@ -20,14 +20,6 @@ namespace MediaBrowser.Model.Querying
|
|||
/// </summary>
|
||||
public const string Artist = "Artist";
|
||||
/// <summary>
|
||||
/// The budget
|
||||
/// </summary>
|
||||
public const string Budget = "Budget";
|
||||
/// <summary>
|
||||
/// The revenue
|
||||
/// </summary>
|
||||
public const string Revenue = "Revenue";
|
||||
/// <summary>
|
||||
/// The date created
|
||||
/// </summary>
|
||||
public const string DateCreated = "DateCreated";
|
||||
|
|
|
@ -195,7 +195,6 @@ namespace MediaBrowser.Providers.Manager
|
|||
}
|
||||
|
||||
MergeAlbumArtist(source, target, lockedFields, replaceData);
|
||||
MergeBudget(source, target, lockedFields, replaceData);
|
||||
MergeMetascore(source, target, lockedFields, replaceData);
|
||||
MergeCriticRating(source, target, lockedFields, replaceData);
|
||||
MergeAwards(source, target, lockedFields, replaceData);
|
||||
|
@ -247,25 +246,6 @@ namespace MediaBrowser.Providers.Manager
|
|||
}
|
||||
}
|
||||
|
||||
private static void MergeBudget(BaseItem source, BaseItem target, List<MetadataFields> lockedFields, bool replaceData)
|
||||
{
|
||||
var sourceHasBudget = source as IHasBudget;
|
||||
var targetHasBudget = target as IHasBudget;
|
||||
|
||||
if (sourceHasBudget != null && targetHasBudget != null)
|
||||
{
|
||||
if (replaceData || !targetHasBudget.Budget.HasValue)
|
||||
{
|
||||
targetHasBudget.Budget = sourceHasBudget.Budget;
|
||||
}
|
||||
|
||||
if (replaceData || !targetHasBudget.Revenue.HasValue)
|
||||
{
|
||||
targetHasBudget.Revenue = sourceHasBudget.Revenue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void MergeMetascore(BaseItem source, BaseItem target, List<MetadataFields> lockedFields, bool replaceData)
|
||||
{
|
||||
var sourceCast = source as IHasMetascore;
|
||||
|
|
|
@ -136,13 +136,6 @@ namespace MediaBrowser.Providers.Movies
|
|||
|
||||
movie.HomePageUrl = movieData.homepage;
|
||||
|
||||
var hasBudget = movie as IHasBudget;
|
||||
if (hasBudget != null)
|
||||
{
|
||||
hasBudget.Budget = movieData.budget;
|
||||
hasBudget.Revenue = movieData.revenue;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(movieData.tagline))
|
||||
{
|
||||
movie.Tagline = movieData.tagline;
|
||||
|
|
|
@ -61,6 +61,9 @@
|
|||
<Reference Include="Emby.Common.Implementations">
|
||||
<HintPath>..\ThirdParty\emby\Emby.Common.Implementations.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Emby.Server.CinemaMode">
|
||||
<HintPath>..\ThirdParty\emby\Emby.Server.CinemaMode.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Emby.Server.Connect">
|
||||
<HintPath>..\ThirdParty\emby\Emby.Server.Connect.dll</HintPath>
|
||||
</Reference>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using Emby.Server.CinemaMode;
|
||||
using Emby.Server.Connect;
|
||||
using Emby.Server.Core;
|
||||
using Emby.Server.Implementations;
|
||||
|
@ -58,6 +59,7 @@ namespace MediaBrowser.Server.Mono
|
|||
{
|
||||
var list = new List<Assembly>();
|
||||
|
||||
list.Add(typeof(DefaultIntroProvider).Assembly);
|
||||
list.Add(typeof(LinuxIsoManager).Assembly);
|
||||
list.Add(typeof(ConnectManager).Assembly);
|
||||
list.Add(typeof(SyncManager).Assembly);
|
||||
|
|
|
@ -67,6 +67,9 @@
|
|||
<Reference Include="Emby.Common.Implementations">
|
||||
<HintPath>..\ThirdParty\emby\Emby.Common.Implementations.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Emby.Server.CinemaMode">
|
||||
<HintPath>..\ThirdParty\emby\Emby.Server.CinemaMode.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Emby.Server.Connect">
|
||||
<HintPath>..\ThirdParty\emby\Emby.Server.Connect.dll</HintPath>
|
||||
</Reference>
|
||||
|
|
|
@ -4,6 +4,7 @@ using System.Diagnostics;
|
|||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices.ComTypes;
|
||||
using Emby.Server.CinemaMode;
|
||||
using Emby.Server.Connect;
|
||||
using Emby.Server.Core;
|
||||
using Emby.Server.Implementations;
|
||||
|
@ -55,6 +56,7 @@ namespace MediaBrowser.ServerApplication
|
|||
//list.Add(typeof(PismoIsoManager).Assembly);
|
||||
}
|
||||
|
||||
list.Add(typeof(DefaultIntroProvider).Assembly);
|
||||
list.Add(typeof(ConnectManager).Assembly);
|
||||
list.Add(typeof(SyncManager).Assembly);
|
||||
list.Add(GetType().Assembly);
|
||||
|
|
|
@ -320,38 +320,6 @@ namespace MediaBrowser.XbmcMetadata.Parsers
|
|||
break;
|
||||
}
|
||||
|
||||
case "budget":
|
||||
{
|
||||
var text = reader.ReadElementContentAsString();
|
||||
var hasBudget = item as IHasBudget;
|
||||
if (hasBudget != null)
|
||||
{
|
||||
double value;
|
||||
if (double.TryParse(text, NumberStyles.Any, _usCulture, out value))
|
||||
{
|
||||
hasBudget.Budget = value;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case "revenue":
|
||||
{
|
||||
var text = reader.ReadElementContentAsString();
|
||||
var hasBudget = item as IHasBudget;
|
||||
if (hasBudget != null)
|
||||
{
|
||||
double value;
|
||||
if (double.TryParse(text, NumberStyles.Any, _usCulture, out value))
|
||||
{
|
||||
hasBudget.Revenue = value;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case "metascore":
|
||||
{
|
||||
var text = reader.ReadElementContentAsString();
|
||||
|
|
|
@ -50,8 +50,6 @@ namespace MediaBrowser.XbmcMetadata.Savers
|
|||
"rottentomatoesid",
|
||||
"language",
|
||||
"tvcomid",
|
||||
"budget",
|
||||
"revenue",
|
||||
"tagline",
|
||||
"studio",
|
||||
"genre",
|
||||
|
@ -685,20 +683,6 @@ namespace MediaBrowser.XbmcMetadata.Savers
|
|||
writer.WriteElementString("votes", item.VoteCount.Value.ToString(UsCulture));
|
||||
}
|
||||
|
||||
var hasBudget = item as IHasBudget;
|
||||
if (hasBudget != null)
|
||||
{
|
||||
if (hasBudget.Budget.HasValue)
|
||||
{
|
||||
writer.WriteElementString("budget", hasBudget.Budget.Value.ToString(UsCulture));
|
||||
}
|
||||
|
||||
if (hasBudget.Revenue.HasValue)
|
||||
{
|
||||
writer.WriteElementString("revenue", hasBudget.Revenue.Value.ToString(UsCulture));
|
||||
}
|
||||
}
|
||||
|
||||
var hasMetascore = item as IHasMetascore;
|
||||
if (hasMetascore != null && hasMetascore.Metascore.HasValue)
|
||||
{
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
Emby Server
|
||||
============
|
||||
|
||||
Emby Server is a home media server built on top of other popular open source technologies such as **Service Stack**, **jQuery**, **jQuery mobile**, and **Mono**.
|
||||
Emby Server is a personal media server with apps on just about every device.
|
||||
|
||||
It features a REST-based API with built-in documention to facilitate client development. We also have client libraries for our API to enable rapid development.
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
using System.Reflection;
|
||||
|
||||
[assembly: AssemblyVersion("3.2.4.1")]
|
||||
[assembly: AssemblyVersion("3.2.5.1")]
|
||||
|
|
Loading…
Reference in New Issue
Block a user