aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Emby.Dlna/Profiles/WdtvLiveProfile.cs2
-rw-r--r--Emby.Dlna/Profiles/Xml/WDTV Live.xml2
-rw-r--r--Emby.Server.Implementations/Data/SqliteItemRepository.cs10
-rw-r--r--Emby.Server.Implementations/Dto/DtoService.cs2
-rw-r--r--Emby.Server.Implementations/Emby.Server.Implementations.csproj3
-rw-r--r--Emby.Server.Implementations/Intros/DefaultIntroProvider.cs394
-rw-r--r--Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs1
-rw-r--r--Emby.Server.Implementations/Sorting/BudgetComparer.cs39
-rw-r--r--Emby.Server.Implementations/Sorting/RevenueComparer.cs39
-rw-r--r--Emby.Server.Implementations/Updates/InstallationManager.cs18
-rw-r--r--MediaBrowser.Api/MediaBrowser.Api.csproj4
-rw-r--r--MediaBrowser.Api/Playback/Progressive/AudioService.cs1
-rw-r--r--MediaBrowser.Api/Sync/SyncHelper.cs85
-rw-r--r--MediaBrowser.Api/Sync/SyncJobWebSocketListener.cs120
-rw-r--r--MediaBrowser.Api/Sync/SyncJobsWebSocketListener.cs101
-rw-r--r--MediaBrowser.Api/Sync/SyncService.cs396
-rw-r--r--MediaBrowser.Controller/Entities/Folder.cs10
-rw-r--r--MediaBrowser.Controller/Entities/IHasBudget.cs18
-rw-r--r--MediaBrowser.Controller/Entities/Movies/Movie.cs14
-rw-r--r--MediaBrowser.Controller/Entities/MusicVideo.cs13
-rw-r--r--MediaBrowser.Controller/MediaBrowser.Controller.csproj1
-rw-r--r--MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs22
-rw-r--r--MediaBrowser.LocalMetadata/Parsers/BaseItemXmlParser.cs32
-rw-r--r--MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs16
-rw-r--r--MediaBrowser.Model/Querying/ItemFields.cs10
-rw-r--r--MediaBrowser.Model/Querying/ItemSortBy.cs8
-rw-r--r--MediaBrowser.Providers/Manager/ProviderUtils.cs20
-rw-r--r--MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs7
-rw-r--r--MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj3
-rw-r--r--MediaBrowser.Server.Mono/MonoAppHost.cs2
-rw-r--r--MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj3
-rw-r--r--MediaBrowser.ServerApplication/WindowsAppHost.cs2
-rw-r--r--MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs32
-rw-r--r--MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs16
-rw-r--r--README.md2
35 files changed, 51 insertions, 1397 deletions
diff --git a/Emby.Dlna/Profiles/WdtvLiveProfile.cs b/Emby.Dlna/Profiles/WdtvLiveProfile.cs
index 756882592..01e77baa2 100644
--- a/Emby.Dlna/Profiles/WdtvLiveProfile.cs
+++ b/Emby.Dlna/Profiles/WdtvLiveProfile.cs
@@ -125,7 +125,7 @@ namespace Emby.Dlna.Profiles
new DirectPlayProfile
{
- Container = "flac,ac3",
+ Container = "flac",
Type = DlnaProfileType.Audio
},
diff --git a/Emby.Dlna/Profiles/Xml/WDTV Live.xml b/Emby.Dlna/Profiles/Xml/WDTV Live.xml
index 775d25302..605a17df4 100644
--- a/Emby.Dlna/Profiles/Xml/WDTV Live.xml
+++ b/Emby.Dlna/Profiles/Xml/WDTV Live.xml
@@ -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" />
diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
index 1f72ebd54..e65ebeb04 100644
--- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs
+++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
@@ -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);
diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs
index 4ee3df7f5..8b6b388db 100644
--- a/Emby.Server.Implementations/Dto/DtoService.cs
+++ b/Emby.Server.Implementations/Dto/DtoService.cs
@@ -491,7 +491,7 @@ namespace Emby.Server.Implementations.Dto
}
}
- //if (!(item is LiveTvProgram))
+ if (!(item is LiveTvProgram))
{
dto.PlayAccess = item.GetPlayAccess(user);
}
diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj
index 13efb7bf9..50c01110f 100644
--- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj
+++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj
@@ -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" />
diff --git a/Emby.Server.Implementations/Intros/DefaultIntroProvider.cs b/Emby.Server.Implementations/Intros/DefaultIntroProvider.cs
deleted file mode 100644
index 4d19a0e9b..000000000
--- a/Emby.Server.Implementations/Intros/DefaultIntroProvider.cs
+++ /dev/null
@@ -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"
- }
- };
- }
- }
-
-}
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
index 8366c2d57..a939cec7b 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
@@ -162,7 +162,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
Id = channel.Path.GetMD5().ToString("N"),
IsInfiniteStream = true,
- SupportsDirectStream = false,
IsRemote = true
};
diff --git a/Emby.Server.Implementations/Sorting/BudgetComparer.cs b/Emby.Server.Implementations/Sorting/BudgetComparer.cs
deleted file mode 100644
index f3aef69f1..000000000
--- a/Emby.Server.Implementations/Sorting/BudgetComparer.cs
+++ /dev/null
@@ -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; }
- }
- }
-}
diff --git a/Emby.Server.Implementations/Sorting/RevenueComparer.cs b/Emby.Server.Implementations/Sorting/RevenueComparer.cs
deleted file mode 100644
index 62e43eac1..000000000
--- a/Emby.Server.Implementations/Sorting/RevenueComparer.cs
+++ /dev/null
@@ -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; }
- }
- }
-}
diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs
index 0420900c5..a13dd0569 100644
--- a/Emby.Server.Implementations/Updates/InstallationManager.cs
+++ b/Emby.Server.Implementations/Updates/InstallationManager.cs
@@ -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);
}
diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj
index 55ef65311..c2c8d1102 100644
--- a/MediaBrowser.Api/MediaBrowser.Api.csproj
+++ b/MediaBrowser.Api/MediaBrowser.Api.csproj
@@ -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" />
diff --git a/MediaBrowser.Api/Playback/Progressive/AudioService.cs b/MediaBrowser.Api/Playback/Progressive/AudioService.cs
index 04825c7a5..56d48baea 100644
--- a/MediaBrowser.Api/Playback/Progressive/AudioService.cs
+++ b/MediaBrowser.Api/Playback/Progressive/AudioService.cs
@@ -31,6 +31,7 @@ namespace MediaBrowser.Api.Playback.Progressive
/// <summary>
/// Class AudioService
/// </summary>
+ [Authenticated]
public class AudioService : BaseProgressiveStreamingService
{
/// <summary>
diff --git a/MediaBrowser.Api/Sync/SyncHelper.cs b/MediaBrowser.Api/Sync/SyncHelper.cs
deleted file mode 100644
index 116cd8060..000000000
--- a/MediaBrowser.Api/Sync/SyncHelper.cs
+++ /dev/null
@@ -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;
- }
- }
-}
diff --git a/MediaBrowser.Api/Sync/SyncJobWebSocketListener.cs b/MediaBrowser.Api/Sync/SyncJobWebSocketListener.cs
deleted file mode 100644
index ac9749a6d..000000000
--- a/MediaBrowser.Api/Sync/SyncJobWebSocketListener.cs
+++ /dev/null
@@ -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);
- }
- }
-}
diff --git a/MediaBrowser.Api/Sync/SyncJobsWebSocketListener.cs b/MediaBrowser.Api/Sync/SyncJobsWebSocketListener.cs
deleted file mode 100644
index 5f9d1ff0e..000000000
--- a/MediaBrowser.Api/Sync/SyncJobsWebSocketListener.cs
+++ /dev/null
@@ -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);
- }
- }
-}
diff --git a/MediaBrowser.Api/Sync/SyncService.cs b/MediaBrowser.Api/Sync/SyncService.cs
deleted file mode 100644
index e50d2b77f..000000000
--- a/MediaBrowser.Api/Sync/SyncService.cs
+++ /dev/null
@@ -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);
- }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs
index cdd503bba..a323a2439 100644
--- a/MediaBrowser.Controller/Entities/Folder.cs
+++ b/MediaBrowser.Controller/Entities/Folder.cs
@@ -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");
diff --git a/MediaBrowser.Controller/Entities/IHasBudget.cs b/MediaBrowser.Controller/Entities/IHasBudget.cs
deleted file mode 100644
index f697715c1..000000000
--- a/MediaBrowser.Controller/Entities/IHasBudget.cs
+++ /dev/null
@@ -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; }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/Movies/Movie.cs b/MediaBrowser.Controller/Entities/Movies/Movie.cs
index de465b2f5..dfa9ac416 100644
--- a/MediaBrowser.Controller/Entities/Movies/Movie.cs
+++ b/MediaBrowser.Controller/Entities/Movies/Movie.cs
@@ -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; }
@@ -46,18 +46,6 @@ namespace MediaBrowser.Controller.Entities.Movies
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>
/// <value>The name of the TMDB collection.</value>
diff --git a/MediaBrowser.Controller/Entities/MusicVideo.cs b/MediaBrowser.Controller/Entities/MusicVideo.cs
index e3fc4259a..c781ef85b 100644
--- a/MediaBrowser.Controller/Entities/MusicVideo.cs
+++ b/MediaBrowser.Controller/Entities/MusicVideo.cs
@@ -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()
diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
index db5a5009c..4ebee531f 100644
--- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj
+++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
@@ -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" />
diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
index 4e1a0a8d7..ad61f3e73 100644
--- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
+++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.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)
{
diff --git a/MediaBrowser.LocalMetadata/Parsers/BaseItemXmlParser.cs b/MediaBrowser.LocalMetadata/Parsers/BaseItemXmlParser.cs
index 9e36f2f95..a1fd71ab2 100644
--- a/MediaBrowser.LocalMetadata/Parsers/BaseItemXmlParser.cs
+++ b/MediaBrowser.LocalMetadata/Parsers/BaseItemXmlParser.cs
@@ -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();
diff --git a/MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs b/MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs
index e1bf4613b..6a2e2263b 100644
--- a/MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs
+++ b/MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs
@@ -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));
diff --git a/MediaBrowser.Model/Querying/ItemFields.cs b/MediaBrowser.Model/Querying/ItemFields.cs
index 5e1c17d1b..9698e374f 100644
--- a/MediaBrowser.Model/Querying/ItemFields.cs
+++ b/MediaBrowser.Model/Querying/ItemFields.cs
@@ -21,11 +21,6 @@
AwardSummary,
/// <summary>
- /// The budget
- /// </summary>
- Budget,
-
- /// <summary>
/// The can delete
/// </summary>
CanDelete,
@@ -174,11 +169,6 @@
RecursiveItemCount,
/// <summary>
- /// The revenue
- /// </summary>
- Revenue,
-
- /// <summary>
/// The season name
/// </summary>
SeasonName,
diff --git a/MediaBrowser.Model/Querying/ItemSortBy.cs b/MediaBrowser.Model/Querying/ItemSortBy.cs
index 6f4ebd0c5..b379298a5 100644
--- a/MediaBrowser.Model/Querying/ItemSortBy.cs
+++ b/MediaBrowser.Model/Querying/ItemSortBy.cs
@@ -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";
diff --git a/MediaBrowser.Providers/Manager/ProviderUtils.cs b/MediaBrowser.Providers/Manager/ProviderUtils.cs
index 5b53cd257..5281b8788 100644
--- a/MediaBrowser.Providers/Manager/ProviderUtils.cs
+++ b/MediaBrowser.Providers/Manager/ProviderUtils.cs
@@ -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;
diff --git a/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs b/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs
index ee634f157..0101478b8 100644
--- a/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs
+++ b/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs
@@ -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;
diff --git a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj
index 62c3e00a8..17d9767f6 100644
--- a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj
+++ b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj
@@ -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>
diff --git a/MediaBrowser.Server.Mono/MonoAppHost.cs b/MediaBrowser.Server.Mono/MonoAppHost.cs
index e9ded5cd5..811e0f444 100644
--- a/MediaBrowser.Server.Mono/MonoAppHost.cs
+++ b/MediaBrowser.Server.Mono/MonoAppHost.cs
@@ -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);
diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj
index 50b0aa21f..7ebbc3809 100644
--- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj
+++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj
@@ -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>
diff --git a/MediaBrowser.ServerApplication/WindowsAppHost.cs b/MediaBrowser.ServerApplication/WindowsAppHost.cs
index 9f11dc322..cc899462a 100644
--- a/MediaBrowser.ServerApplication/WindowsAppHost.cs
+++ b/MediaBrowser.ServerApplication/WindowsAppHost.cs
@@ -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);
diff --git a/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs b/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs
index 8a8560711..8a150e0c1 100644
--- a/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs
+++ b/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs
@@ -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();
diff --git a/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs b/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs
index 5a1c7bf13..100b9c36c 100644
--- a/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs
+++ b/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs
@@ -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)
{
diff --git a/README.md b/README.md
index ead2a2da3..7872cc3ed 100644
--- a/README.md
+++ b/README.md
@@ -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.