diff --git a/MediaBrowser.Api/ConfigurationService.cs b/MediaBrowser.Api/ConfigurationService.cs
index 7b6e5ed19e..ce6ca015de 100644
--- a/MediaBrowser.Api/ConfigurationService.cs
+++ b/MediaBrowser.Api/ConfigurationService.cs
@@ -122,53 +122,12 @@ namespace MediaBrowser.Api
return ToOptimizedResult(result);
}
- const string XbmcMetadata = "Xbmc Nfo";
- const string MediaBrowserMetadata = "Media Browser Xml";
-
public void Post(AutoSetMetadataOptions request)
{
- var service = AutoDetectMetadataService();
-
- Logger.Info("Setting preferred metadata format to " + service);
-
- var serviceToDisable = string.Equals(service, XbmcMetadata) ?
- MediaBrowserMetadata :
- XbmcMetadata;
-
- _configurationManager.DisableMetadataService(serviceToDisable);
+ _configurationManager.DisableMetadataService("Media Browser Xml");
_configurationManager.SaveConfiguration();
}
- private string AutoDetectMetadataService()
- {
- try
- {
- var paths = _libraryManager.GetDefaultVirtualFolders()
- .SelectMany(i => i.Locations)
- .Distinct(StringComparer.OrdinalIgnoreCase)
- .Select(i => new DirectoryInfo(i))
- .ToList();
-
- if (paths.SelectMany(i => i.EnumerateFiles("*.xml", SearchOption.AllDirectories))
- .Any())
- {
- return XbmcMetadata;
- }
-
- if (paths.SelectMany(i => i.EnumerateFiles("*.xml", SearchOption.AllDirectories))
- .Any(i => string.Equals(i.Name, "series.xml", StringComparison.OrdinalIgnoreCase) || string.Equals(i.Name, "movie.xml", StringComparison.OrdinalIgnoreCase)))
- {
- return MediaBrowserMetadata;
- }
- }
- catch (Exception)
- {
-
- }
-
- return XbmcMetadata;
- }
-
///
/// Posts the specified configuraiton.
///
diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs
index 7289ac0862..ed777cafe0 100644
--- a/MediaBrowser.Api/Playback/BaseStreamingService.cs
+++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs
@@ -1978,6 +1978,7 @@ namespace MediaBrowser.Api.Playback
state.TargetPacketLength,
state.TargetTimestamp,
state.IsTargetAnamorphic,
+ state.IsTargetCabac,
state.TargetRefFrames);
if (mediaProfile != null)
@@ -2067,6 +2068,7 @@ namespace MediaBrowser.Api.Playback
state.TargetPacketLength,
state.TranscodeSeekInfo,
state.IsTargetAnamorphic,
+ state.IsTargetCabac,
state.TargetRefFrames
).FirstOrDefault() ?? string.Empty;
diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
index 30ba25ae47..97565cdc3d 100644
--- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
+++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
@@ -501,7 +501,7 @@ namespace MediaBrowser.Api.Playback.Hls
private void AppendPlaylist(StringBuilder builder, string url, int bitrate, string subtitleGroup)
{
- var header = "#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=" + bitrate.ToString(UsCulture);
+ var header = "#EXT-X-STREAM-INF:BANDWIDTH=" + bitrate.ToString(UsCulture);
if (!string.IsNullOrWhiteSpace(subtitleGroup))
{
diff --git a/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs b/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs
index 6e77e5eabd..35f714cb18 100644
--- a/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs
+++ b/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs
@@ -1,5 +1,4 @@
-using System.Threading;
-using MediaBrowser.Common.IO;
+using MediaBrowser.Common.IO;
using MediaBrowser.Model.Logging;
using ServiceStack.Web;
using System;
@@ -49,9 +48,7 @@ namespace MediaBrowser.Api.Playback.Progressive
/// The response stream.
public void WriteTo(Stream responseStream)
{
- var task = WriteToAsync(responseStream);
-
- Task.WaitAll(task);
+ WriteToInternal(responseStream);
}
///
@@ -59,12 +56,12 @@ namespace MediaBrowser.Api.Playback.Progressive
///
/// The response stream.
/// Task.
- public async Task WriteToAsync(Stream responseStream)
+ private void WriteToInternal(Stream responseStream)
{
try
{
- await new ProgressiveFileCopier(_fileSystem, _job)
- .StreamFile(Path, responseStream).ConfigureAwait(false);
+ new ProgressiveFileCopier(_fileSystem, _job)
+ .StreamFile(Path, responseStream);
}
catch (Exception ex)
{
@@ -95,16 +92,16 @@ namespace MediaBrowser.Api.Playback.Progressive
_job = job;
}
- public async Task StreamFile(string path, Stream outputStream)
+ public void StreamFile(string path, Stream outputStream)
{
var eofCount = 0;
long position = 0;
- using (var fs = _fileSystem.GetFileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, true))
+ using (var fs = _fileSystem.GetFileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, false))
{
while (eofCount < 15)
{
- await CopyToAsyncInternal(fs, outputStream, 81920, CancellationToken.None).ConfigureAwait(false);
+ CopyToInternal(fs, outputStream, 81920);
var fsPosition = fs.Position;
@@ -118,7 +115,8 @@ namespace MediaBrowser.Api.Playback.Progressive
{
eofCount++;
}
- await Task.Delay(100).ConfigureAwait(false);
+ var task = Task.Delay(100);
+ Task.WaitAll(task);
}
else
{
@@ -130,13 +128,13 @@ namespace MediaBrowser.Api.Playback.Progressive
}
}
- private async Task CopyToAsyncInternal(Stream source, Stream destination, int bufferSize, CancellationToken cancellationToken)
+ private void CopyToInternal(Stream source, Stream destination, int bufferSize)
{
byte[] array = new byte[bufferSize];
int count;
- while ((count = await source.ReadAsync(array, 0, array.Length, cancellationToken).ConfigureAwait(false)) != 0)
+ while ((count = source.Read(array, 0, array.Length)) != 0)
{
- await destination.WriteAsync(array, 0, count, cancellationToken).ConfigureAwait(false);
+ destination.Write(array, 0, count);
_bytesWritten += count;
diff --git a/MediaBrowser.Api/Playback/StaticRemoteStreamWriter.cs b/MediaBrowser.Api/Playback/StaticRemoteStreamWriter.cs
index 8f9fa11db1..ada2a98a15 100644
--- a/MediaBrowser.Api/Playback/StaticRemoteStreamWriter.cs
+++ b/MediaBrowser.Api/Playback/StaticRemoteStreamWriter.cs
@@ -2,7 +2,6 @@
using ServiceStack.Web;
using System.Collections.Generic;
using System.IO;
-using System.Threading.Tasks;
namespace MediaBrowser.Api.Playback
{
@@ -41,22 +40,7 @@ namespace MediaBrowser.Api.Playback
/// The response stream.
public void WriteTo(Stream responseStream)
{
- var task = WriteToAsync(responseStream);
-
- Task.WaitAll(task);
- }
-
- ///
- /// Writes to async.
- ///
- /// The response stream.
- /// Task.
- public async Task WriteToAsync(Stream responseStream)
- {
- using (_response)
- {
- await _response.Content.CopyToAsync(responseStream, 819200).ConfigureAwait(false);
- }
+ _response.Content.CopyTo(responseStream, 819200);
}
}
}
diff --git a/MediaBrowser.Api/Playback/StreamState.cs b/MediaBrowser.Api/Playback/StreamState.cs
index 8f45c95daa..832eb3ca87 100644
--- a/MediaBrowser.Api/Playback/StreamState.cs
+++ b/MediaBrowser.Api/Playback/StreamState.cs
@@ -418,5 +418,18 @@ namespace MediaBrowser.Api.Playback
return false;
}
}
+
+ public bool? IsTargetCabac
+ {
+ get
+ {
+ if (Request.Static)
+ {
+ return VideoStream == null ? null : VideoStream.IsCabac;
+ }
+
+ return true;
+ }
+ }
}
}
diff --git a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs
index 093b904f1f..43db03b428 100644
--- a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs
+++ b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs
@@ -434,21 +434,9 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
throw exception;
}
- catch (HttpRequestException ex)
- {
- _logger.ErrorException("Error getting response from " + options.Url, ex);
-
- throw new HttpException(ex.Message, ex);
- }
- catch (WebException ex)
- {
- throw GetException(ex, options);
- }
catch (Exception ex)
{
- _logger.ErrorException("Error getting response from " + options.Url, ex);
-
- throw;
+ throw GetException(ex, options);
}
finally
{
@@ -636,21 +624,10 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
return GetResponseInfo(httpResponse, tempFile, contentLength);
}
}
- catch (OperationCanceledException ex)
- {
- throw GetTempFileException(ex, options, tempFile);
- }
- catch (HttpRequestException ex)
- {
- throw GetTempFileException(ex, options, tempFile);
- }
- catch (WebException ex)
- {
- throw GetTempFileException(ex, options, tempFile);
- }
catch (Exception ex)
{
- throw GetTempFileException(ex, options, tempFile);
+ DeleteTempFile(tempFile);
+ throw GetException(ex, options);
}
finally
{
@@ -675,44 +652,25 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
protected static readonly CultureInfo UsCulture = new CultureInfo("en-US");
- ///
- /// Handles the temp file exception.
- ///
- /// The ex.
- /// The options.
- /// The temp file.
- /// Task.
- ///
- private Exception GetTempFileException(Exception ex, HttpRequestOptions options, string tempFile)
+ private Exception GetException(Exception ex, HttpRequestOptions options)
{
- var operationCanceledException = ex as OperationCanceledException;
+ var webException = ex as WebException
+ ?? ex.InnerException as WebException;
- if (operationCanceledException != null)
+ if (webException != null)
{
- // Cleanup
- DeleteTempFile(tempFile);
-
- return GetCancellationException(options.Url, options.CancellationToken, operationCanceledException);
+ return GetException(webException, options);
}
- _logger.ErrorException("Error getting response from " + options.Url, ex);
-
- // Cleanup
- DeleteTempFile(tempFile);
-
- var httpRequestException = ex as HttpRequestException;
+ var operationCanceledException = ex as OperationCanceledException
+ ?? ex.InnerException as OperationCanceledException;
- if (httpRequestException != null)
+ if (operationCanceledException != null)
{
- return new HttpException(ex.Message, ex);
+ return GetCancellationException(options.Url, options.CancellationToken, operationCanceledException);
}
- var webException = ex as WebException;
-
- if (webException != null)
- {
- throw GetException(webException, options);
- }
+ _logger.ErrorException("Error getting response from " + options.Url, ex);
return ex;
}
diff --git a/MediaBrowser.Controller/Connect/UserLinkResult.cs b/MediaBrowser.Controller/Connect/UserLinkResult.cs
index 4ed57cfc2d..16ebfc70a3 100644
--- a/MediaBrowser.Controller/Connect/UserLinkResult.cs
+++ b/MediaBrowser.Controller/Connect/UserLinkResult.cs
@@ -4,5 +4,7 @@ namespace MediaBrowser.Controller.Connect
public class UserLinkResult
{
public bool IsPending { get; set; }
+ public bool IsNewUserInvitation { get; set; }
+ public string GuestDisplayName { get; set; }
}
}
diff --git a/MediaBrowser.Controller/Entities/CollectionFolder.cs b/MediaBrowser.Controller/Entities/CollectionFolder.cs
index 4b90741c09..a10742f01e 100644
--- a/MediaBrowser.Controller/Entities/CollectionFolder.cs
+++ b/MediaBrowser.Controller/Entities/CollectionFolder.cs
@@ -74,7 +74,8 @@ namespace MediaBrowser.Controller.Entities
{
FileInfo = new DirectoryInfo(path),
Path = path,
- Parent = Parent
+ Parent = Parent,
+ CollectionType = CollectionType
};
// Gather child folder and files
diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs
index 4614f2f8a3..4abdde8ddd 100644
--- a/MediaBrowser.Controller/Entities/Folder.cs
+++ b/MediaBrowser.Controller/Entities/Folder.cs
@@ -736,7 +736,9 @@ namespace MediaBrowser.Controller.Entities
/// IEnumerable{BaseItem}.
protected virtual IEnumerable GetNonCachedChildren(IDirectoryService directoryService)
{
- return LibraryManager.ResolvePaths(GetFileSystemChildren(directoryService), directoryService, this);
+ var collectionType = LibraryManager.FindCollectionType(this);
+
+ return LibraryManager.ResolvePaths(GetFileSystemChildren(directoryService), directoryService, this, collectionType);
}
///
@@ -745,7 +747,16 @@ namespace MediaBrowser.Controller.Entities
/// IEnumerable{BaseItem}.
protected IEnumerable GetCachedChildren()
{
- return ItemRepository.GetChildren(Id).Select(RetrieveChild).Where(i => i != null);
+ var childrenItems = ItemRepository.GetChildrenItems(Id).Select(RetrieveChild).Where(i => i != null);
+
+ //var children = ItemRepository.GetChildren(Id).Select(RetrieveChild).Where(i => i != null).ToList();
+
+ //if (children.Count != childrenItems.Count)
+ //{
+ // var b = this;
+ //}
+
+ return childrenItems;
}
///
@@ -770,6 +781,29 @@ namespace MediaBrowser.Controller.Entities
return item;
}
+ private BaseItem RetrieveChild(BaseItem child)
+ {
+ var item = LibraryManager.GetMemoryItemById(child.Id);
+
+ if (item != null)
+ {
+ if (item is IByReferenceItem)
+ {
+ return LibraryManager.GetOrAddByReferenceItem(item);
+ }
+
+ item.Parent = this;
+ }
+ else
+ {
+ child.Parent = this;
+ LibraryManager.RegisterItem(child);
+ item = child;
+ }
+
+ return item;
+ }
+
public virtual Task> GetItems(InternalItemsQuery query)
{
var user = query.User;
diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs
index 951513962c..f935648822 100644
--- a/MediaBrowser.Controller/Library/ILibraryManager.cs
+++ b/MediaBrowser.Controller/Library/ILibraryManager.cs
@@ -17,30 +17,14 @@ namespace MediaBrowser.Controller.Library
///
public interface ILibraryManager
{
- ///
- /// Resolves the item.
- ///
- /// The args.
- /// BaseItem.
- BaseItem ResolveItem(ItemResolveArgs args);
-
- ///
- /// Resolves a path into a BaseItem
- ///
- /// The file info.
- /// The directory service.
- /// The parent.
- /// BaseItem.
- ///
- BaseItem ResolvePath(FileSystemInfo fileInfo, IDirectoryService directoryService, Folder parent = null);
-
///
/// Resolves the path.
///
/// The file information.
/// The parent.
+ /// Type of the collection.
/// BaseItem.
- BaseItem ResolvePath(FileSystemInfo fileInfo, Folder parent = null);
+ BaseItem ResolvePath(FileSystemInfo fileInfo, Folder parent = null, string collectionType = null);
///
/// Resolves a set of files into a list of BaseItem
@@ -49,8 +33,9 @@ namespace MediaBrowser.Controller.Library
/// The files.
/// The directory service.
/// The parent.
+ /// Type of the collection.
/// List{``0}.
- List ResolvePaths(IEnumerable files, IDirectoryService directoryService, Folder parent)
+ List ResolvePaths(IEnumerable files, IDirectoryService directoryService, Folder parent, string collectionType = null)
where T : BaseItem;
///
@@ -151,6 +136,13 @@ namespace MediaBrowser.Controller.Library
/// BaseItem.
BaseItem GetItemById(Guid id);
+ ///
+ /// Gets the memory item by identifier.
+ ///
+ /// The identifier.
+ /// BaseItem.
+ BaseItem GetMemoryItemById(Guid id);
+
///
/// Gets the intros.
///
diff --git a/MediaBrowser.Controller/Library/ItemResolveArgs.cs b/MediaBrowser.Controller/Library/ItemResolveArgs.cs
index c1fcdc9feb..d1692aabf0 100644
--- a/MediaBrowser.Controller/Library/ItemResolveArgs.cs
+++ b/MediaBrowser.Controller/Library/ItemResolveArgs.cs
@@ -230,29 +230,18 @@ namespace MediaBrowser.Controller.Library
}
///
- /// Gets the name of the meta file by.
+ /// Determines whether [contains meta file by name] [the specified name].
///
/// The name.
- /// FileSystemInfo.
- ///
- public FileSystemInfo GetMetaFileByName(string name)
+ /// true if [contains meta file by name] [the specified name]; otherwise, false.
+ public bool ContainsMetaFileByName(string name)
{
if (string.IsNullOrEmpty(name))
{
throw new ArgumentNullException();
}
- return GetFileSystemEntryByName(name);
- }
-
- ///
- /// Determines whether [contains meta file by name] [the specified name].
- ///
- /// The name.
- /// true if [contains meta file by name] [the specified name]; otherwise, false.
- public bool ContainsMetaFileByName(string name)
- {
- return GetMetaFileByName(name) != null;
+ return GetFileSystemEntryByName(name) != null;
}
///
@@ -265,20 +254,13 @@ namespace MediaBrowser.Controller.Library
return GetFileSystemEntryByName(name) != null;
}
- private bool _collectionTypeDiscovered;
- private string _collectionType;
-
public string GetCollectionType()
{
- if (!_collectionTypeDiscovered)
- {
- _collectionType = Parent == null ? null : _libraryManager.FindCollectionType(Parent);
- _collectionTypeDiscovered = true;
- }
-
- return _collectionType;
+ return CollectionType;
}
+ public string CollectionType { get; set; }
+
#region Equality Overrides
///
diff --git a/MediaBrowser.Controller/Library/TVUtils.cs b/MediaBrowser.Controller/Library/TVUtils.cs
index 34486182b7..c85a8f3354 100644
--- a/MediaBrowser.Controller/Library/TVUtils.cs
+++ b/MediaBrowser.Controller/Library/TVUtils.cs
@@ -284,7 +284,7 @@ namespace MediaBrowser.Controller.Library
{
if (IsSeasonFolder(child.FullName, directoryService, fileSystem))
{
- logger.Debug("{0} is a series because of season folder {1}.", path, child.FullName);
+ //logger.Debug("{0} is a series because of season folder {1}.", path, child.FullName);
return true;
}
diff --git a/MediaBrowser.Controller/Persistence/IItemRepository.cs b/MediaBrowser.Controller/Persistence/IItemRepository.cs
index 02bca739f4..edaa15c9df 100644
--- a/MediaBrowser.Controller/Persistence/IItemRepository.cs
+++ b/MediaBrowser.Controller/Persistence/IItemRepository.cs
@@ -33,7 +33,7 @@ namespace MediaBrowser.Controller.Persistence
/// The cancellation token.
/// Task.
Task DeleteItem(Guid id, CancellationToken cancellationToken);
-
+
///
/// Gets the critic reviews.
///
@@ -41,6 +41,13 @@ namespace MediaBrowser.Controller.Persistence
/// Task{IEnumerable{ItemReview}}.
IEnumerable GetCriticReviews(Guid itemId);
+ ///
+ /// Gets the children items.
+ ///
+ /// The parent identifier.
+ /// IEnumerable<BaseItem>.
+ IEnumerable GetChildrenItems(Guid parentId);
+
///
/// Saves the critic reviews.
///
@@ -101,7 +108,7 @@ namespace MediaBrowser.Controller.Persistence
/// The type.
/// IEnumerable{Guid}.
IEnumerable GetItemsOfType(Type type);
-
+
///
/// Saves the children.
///
diff --git a/MediaBrowser.Controller/Resolvers/EntityResolutionHelper.cs b/MediaBrowser.Controller/Resolvers/EntityResolutionHelper.cs
index 7d9c9d8769..5b40073226 100644
--- a/MediaBrowser.Controller/Resolvers/EntityResolutionHelper.cs
+++ b/MediaBrowser.Controller/Resolvers/EntityResolutionHelper.cs
@@ -246,7 +246,7 @@ namespace MediaBrowser.Controller.Resolvers
if (config.UseFileCreationTimeForDateAdded)
{
- item.DateModified = fileSystem.GetCreationTimeUtc(info);
+ item.DateCreated = fileSystem.GetCreationTimeUtc(info);
}
else
{
diff --git a/MediaBrowser.Controller/Session/SessionInfo.cs b/MediaBrowser.Controller/Session/SessionInfo.cs
index 53a8d5a7cb..d8a2464d64 100644
--- a/MediaBrowser.Controller/Session/SessionInfo.cs
+++ b/MediaBrowser.Controller/Session/SessionInfo.cs
@@ -80,6 +80,12 @@ namespace MediaBrowser.Controller.Session
/// The last activity date.
public DateTime LastActivityDate { get; set; }
+ ///
+ /// Gets or sets the last playback check in.
+ ///
+ /// The last playback check in.
+ public DateTime LastPlaybackCheckIn { get; set; }
+
///
/// Gets or sets the name of the device.
///
diff --git a/MediaBrowser.Dlna/Didl/DidlBuilder.cs b/MediaBrowser.Dlna/Didl/DidlBuilder.cs
index 912612d299..5e08d80311 100644
--- a/MediaBrowser.Dlna/Didl/DidlBuilder.cs
+++ b/MediaBrowser.Dlna/Didl/DidlBuilder.cs
@@ -149,6 +149,7 @@ namespace MediaBrowser.Dlna.Didl
streamInfo.TargetPacketLength,
streamInfo.TranscodeSeekInfo,
streamInfo.IsTargetAnamorphic,
+ streamInfo.IsTargetCabac,
streamInfo.TargetRefFrames);
foreach (var contentFeature in contentFeatureList)
@@ -270,6 +271,7 @@ namespace MediaBrowser.Dlna.Didl
streamInfo.TargetPacketLength,
streamInfo.TargetTimestamp,
streamInfo.IsTargetAnamorphic,
+ streamInfo.IsTargetCabac,
streamInfo.TargetRefFrames);
var filename = url.Substring(0, url.IndexOf('?'));
diff --git a/MediaBrowser.Dlna/PlayTo/PlayToController.cs b/MediaBrowser.Dlna/PlayTo/PlayToController.cs
index 7d06185740..1989c437aa 100644
--- a/MediaBrowser.Dlna/PlayTo/PlayToController.cs
+++ b/MediaBrowser.Dlna/PlayTo/PlayToController.cs
@@ -452,19 +452,9 @@ namespace MediaBrowser.Dlna.PlayTo
private void AddItemFromId(Guid id, List list)
{
var item = _libraryManager.GetItemById(id);
- if (item.IsFolder)
+ if (item.MediaType == MediaType.Audio || item.MediaType == MediaType.Video)
{
- foreach (var childId in _itemRepository.GetChildren(item.Id))
- {
- AddItemFromId(childId, list);
- }
- }
- else
- {
- if (item.MediaType == MediaType.Audio || item.MediaType == MediaType.Video)
- {
- list.Add(item);
- }
+ list.Add(item);
}
}
@@ -537,6 +527,7 @@ namespace MediaBrowser.Dlna.PlayTo
streamInfo.TargetPacketLength,
streamInfo.TranscodeSeekInfo,
streamInfo.IsTargetAnamorphic,
+ streamInfo.IsTargetCabac,
streamInfo.TargetRefFrames);
return list.FirstOrDefault();
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Android.xml b/MediaBrowser.Dlna/Profiles/Xml/Android.xml
index 6cc20db406..0b4f9f7b18 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Android.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Android.xml
@@ -51,6 +51,7 @@
+
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml b/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml
index b056e31278..90a4ef55d4 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml
@@ -29,8 +29,8 @@
DMS-1.50
http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_HD_50_AC3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_HD_50_AC3_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_HD_50_AC3_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/mpeg:DLNA.ORG_PN=MP3;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/L16;rate=44100;channels=1:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/L16;rate=44100;channels=2:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/L16;rate=48000;channels=1:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/L16;rate=48000;channels=2:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMA_BASE;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMA_FULL;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_SM;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_MED;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_LRG;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_TN;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG1;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_PS_PAL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_PS_NTSC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_EU;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_EU_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_EU_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_NA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_NA_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_NA_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_KO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_KO_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_KO_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-msvideo:DLNA.ORG_PN=AVI;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-matroska:DLNA.ORG_PN=MATROSKA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_SD_AAC_MULT5;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_SD_MPEG1_L3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_SD_AC3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_HD_720p_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_HD_1080i_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_HP_HD_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_LPCM;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=MPEG4_P2_MP4_ASP_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=MPEG4_P2_MP4_SP_L6_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=MPEG4_P2_MP4_NDSD;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_AAC_MULT5;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_AAC_MULT5_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_SD_AAC_MULT5_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_MPEG1_L3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_MPEG1_L3_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_SD_MPEG1_L3_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_AAC_MULT5;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_AAC_MULT5_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_HD_AAC_MULT5_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_MPEG1_L3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_MPEG1_L3_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_HD_MPEG1_L3_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_HD_50_LPCM_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_BASE;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_FULL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVHIGH_FULL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_PRO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVHIGH_PRO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-asf:DLNA.ORG_PN=VC1_ASF_AP_L1_WMA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-asf:DLNA.ORG_PN=VC1_ASF_AP_L2_WMA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-asf:DLNA.ORG_PN=VC1_ASF_AP_L3_WMA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000
40
- true
- true
+ false
+ false
false
false
diff --git a/MediaBrowser.MediaInfo/MediaInfoLib.cs b/MediaBrowser.MediaInfo/MediaInfoLib.cs
index 64842edcbe..fa644aee0a 100644
--- a/MediaBrowser.MediaInfo/MediaInfoLib.cs
+++ b/MediaBrowser.MediaInfo/MediaInfoLib.cs
@@ -24,6 +24,12 @@ namespace MediaBrowser.MediaInfo
result.IsInterlaced = text.IndexOf("interlac", StringComparison.OrdinalIgnoreCase) != -1;
}
+ text = GetValue(lib, videoStreamIndex, new[] { "Format_Settings_CABAC", "Format_Settings_CABAC/String" });
+ if (!string.IsNullOrWhiteSpace(text))
+ {
+ result.IsCabac = string.Equals(text, "yes", StringComparison.OrdinalIgnoreCase);
+ }
+
int bitDepth;
text = GetValue(lib, videoStreamIndex, new[] { "BitDepth", "BitDepth/String" });
@@ -51,6 +57,7 @@ namespace MediaBrowser.MediaInfo
public class MediaInfoResult
{
+ public bool? IsCabac { get; set; }
public bool? IsInterlaced { get; set; }
public int? BitDepth { get; set; }
public int? RefFrames { get; set; }
diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj
index 45e761f0aa..5c117e6054 100644
--- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj
+++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj
@@ -1088,9 +1088,6 @@
Users\AuthenticationResult.cs
-
- Weather\WeatherUnits.cs
-
Properties\SharedVersion.cs
diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
index f261ac42d7..34fcd819ae 100644
--- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
+++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
@@ -1047,9 +1047,6 @@
Users\AuthenticationResult.cs
-
- Weather\WeatherUnits.cs
-
Properties\SharedVersion.cs
diff --git a/MediaBrowser.Model/Dlna/ConditionProcessor.cs b/MediaBrowser.Model/Dlna/ConditionProcessor.cs
index 4fedb36d6e..e0a8e239e1 100644
--- a/MediaBrowser.Model/Dlna/ConditionProcessor.cs
+++ b/MediaBrowser.Model/Dlna/ConditionProcessor.cs
@@ -19,6 +19,7 @@ namespace MediaBrowser.Model.Dlna
int? packetLength,
TransportStreamTimestamp? timestamp,
bool? isAnamorphic,
+ bool? isCabac,
int? refFrames)
{
switch (condition.Property)
@@ -31,6 +32,8 @@ namespace MediaBrowser.Model.Dlna
return true;
case ProfileConditionValue.IsAnamorphic:
return IsConditionSatisfied(condition, isAnamorphic);
+ case ProfileConditionValue.IsCabac:
+ return IsConditionSatisfied(condition, isCabac);
case ProfileConditionValue.VideoFramerate:
return IsConditionSatisfied(condition, videoFramerate);
case ProfileConditionValue.VideoLevel:
diff --git a/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs b/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs
index 5ded415aa5..a3eeecff2f 100644
--- a/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs
+++ b/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs
@@ -116,6 +116,7 @@ namespace MediaBrowser.Model.Dlna
int? packetLength,
TranscodeSeekInfo transcodeSeekInfo,
bool? isAnamorphic,
+ bool? isCabac,
int? refFrames)
{
// first bit means Time based seek supported, second byte range seek supported (not sure about the order now), so 01 = only byte seek, 10 = time based, 11 = both, 00 = none
@@ -156,6 +157,7 @@ namespace MediaBrowser.Model.Dlna
packetLength,
timestamp,
isAnamorphic,
+ isCabac,
refFrames);
List orgPnValues = new List();
diff --git a/MediaBrowser.Model/Dlna/DeviceProfile.cs b/MediaBrowser.Model/Dlna/DeviceProfile.cs
index 94de34a282..66f5936158 100644
--- a/MediaBrowser.Model/Dlna/DeviceProfile.cs
+++ b/MediaBrowser.Model/Dlna/DeviceProfile.cs
@@ -281,6 +281,7 @@ namespace MediaBrowser.Model.Dlna
int? packetLength,
TransportStreamTimestamp timestamp,
bool? isAnamorphic,
+ bool? isCabac,
int? refFrames)
{
container = StringHelper.TrimStart((container ?? string.Empty), '.');
@@ -315,7 +316,7 @@ namespace MediaBrowser.Model.Dlna
var anyOff = false;
foreach (ProfileCondition c in i.Conditions)
{
- if (!conditionProcessor.IsVideoConditionSatisfied(c, audioBitrate, audioChannels, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, refFrames))
+ if (!conditionProcessor.IsVideoConditionSatisfied(c, audioBitrate, audioChannels, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isCabac, refFrames))
{
anyOff = true;
break;
diff --git a/MediaBrowser.Model/Dlna/ProfileConditionValue.cs b/MediaBrowser.Model/Dlna/ProfileConditionValue.cs
index 27abf9878e..ae6dc74c8c 100644
--- a/MediaBrowser.Model/Dlna/ProfileConditionValue.cs
+++ b/MediaBrowser.Model/Dlna/ProfileConditionValue.cs
@@ -16,6 +16,7 @@
VideoProfile = 11,
VideoTimestamp = 12,
IsAnamorphic = 13,
- RefFrames = 14
+ RefFrames = 14,
+ IsCabac = 15
}
}
\ No newline at end of file
diff --git a/MediaBrowser.Model/Dlna/Profiles/AndroidProfile.cs b/MediaBrowser.Model/Dlna/Profiles/AndroidProfile.cs
index 1f27e5991c..04b4a808d4 100644
--- a/MediaBrowser.Model/Dlna/Profiles/AndroidProfile.cs
+++ b/MediaBrowser.Model/Dlna/Profiles/AndroidProfile.cs
@@ -114,7 +114,8 @@ namespace MediaBrowser.Model.Dlna.Profiles
new ProfileCondition(ProfileConditionType.LessThanEqual, ProfileConditionValue.Width, "1920"),
new ProfileCondition(ProfileConditionType.LessThanEqual, ProfileConditionValue.Height, "1080"),
new ProfileCondition(ProfileConditionType.LessThanEqual, ProfileConditionValue.VideoBitDepth, "8"),
- new ProfileCondition(ProfileConditionType.NotEquals, ProfileConditionValue.IsAnamorphic, "true")
+ new ProfileCondition(ProfileConditionType.NotEquals, ProfileConditionValue.IsAnamorphic, "true"),
+ new ProfileCondition(ProfileConditionType.Equals, ProfileConditionValue.IsCabac, "true")
}
},
diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs
index 227fb3ad6e..792e6de912 100644
--- a/MediaBrowser.Model/Dlna/StreamBuilder.cs
+++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs
@@ -419,6 +419,7 @@ namespace MediaBrowser.Model.Dlna
string videoProfile = videoStream == null ? null : videoStream.Profile;
float? videoFramerate = videoStream == null ? null : videoStream.AverageFrameRate ?? videoStream.AverageFrameRate;
bool? isAnamorphic = videoStream == null ? null : videoStream.IsAnamorphic;
+ bool? isCabac = videoStream == null ? null : videoStream.IsCabac;
int? audioBitrate = audioStream == null ? null : audioStream.BitRate;
int? audioChannels = audioStream == null ? null : audioStream.Channels;
@@ -431,7 +432,7 @@ namespace MediaBrowser.Model.Dlna
// Check container conditions
foreach (ProfileCondition i in conditions)
{
- if (!conditionProcessor.IsVideoConditionSatisfied(i, audioBitrate, audioChannels, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, refFrames))
+ if (!conditionProcessor.IsVideoConditionSatisfied(i, audioBitrate, audioChannels, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isCabac, refFrames))
{
return null;
}
@@ -458,7 +459,7 @@ namespace MediaBrowser.Model.Dlna
foreach (ProfileCondition i in conditions)
{
- if (!conditionProcessor.IsVideoConditionSatisfied(i, audioBitrate, audioChannels, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, refFrames))
+ if (!conditionProcessor.IsVideoConditionSatisfied(i, audioBitrate, audioChannels, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isCabac, refFrames))
{
return null;
}
@@ -647,6 +648,7 @@ namespace MediaBrowser.Model.Dlna
}
case ProfileConditionValue.AudioProfile:
case ProfileConditionValue.IsAnamorphic:
+ case ProfileConditionValue.IsCabac:
case ProfileConditionValue.Has64BitOffsets:
case ProfileConditionValue.PacketLength:
case ProfileConditionValue.VideoTimestamp:
diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs
index 58848ff50e..4c03201f16 100644
--- a/MediaBrowser.Model/Dlna/StreamInfo.cs
+++ b/MediaBrowser.Model/Dlna/StreamInfo.cs
@@ -456,6 +456,19 @@ namespace MediaBrowser.Model.Dlna
}
}
+ public bool? IsTargetCabac
+ {
+ get
+ {
+ if (IsDirectStream)
+ {
+ return TargetVideoStream == null ? null : TargetVideoStream.IsCabac;
+ }
+
+ return true;
+ }
+ }
+
public int? TargetWidth
{
get
diff --git a/MediaBrowser.Model/Entities/MediaStream.cs b/MediaBrowser.Model/Entities/MediaStream.cs
index b71f68d183..4a9b765c23 100644
--- a/MediaBrowser.Model/Entities/MediaStream.cs
+++ b/MediaBrowser.Model/Entities/MediaStream.cs
@@ -175,5 +175,11 @@ namespace MediaBrowser.Model.Entities
///
/// true if this instance is anamorphic; otherwise, false.
public bool? IsAnamorphic { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether this instance is cabac.
+ ///
+ /// null if [is cabac] contains no value, true if [is cabac]; otherwise, false.
+ public bool? IsCabac { get; set; }
}
}
diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj
index bb6f94b110..32f655ae75 100644
--- a/MediaBrowser.Model/MediaBrowser.Model.csproj
+++ b/MediaBrowser.Model/MediaBrowser.Model.csproj
@@ -402,7 +402,6 @@
-
diff --git a/MediaBrowser.Model/Querying/ItemsResult.cs b/MediaBrowser.Model/Querying/ItemsResult.cs
index b3f771e4b4..3b9c59733c 100644
--- a/MediaBrowser.Model/Querying/ItemsResult.cs
+++ b/MediaBrowser.Model/Querying/ItemsResult.cs
@@ -5,26 +5,7 @@ namespace MediaBrowser.Model.Querying
///
/// Represents the result of a query for items
///
- public class ItemsResult
+ public class ItemsResult : QueryResult
{
- ///
- /// The set of items returned based on sorting, paging, etc
- ///
- /// The items.
- public BaseItemDto[] Items { get; set; }
-
- ///
- /// The total number of records available
- ///
- /// The total record count.
- public int TotalRecordCount { get; set; }
-
- ///
- /// Initializes a new instance of the class.
- ///
- public ItemsResult()
- {
- Items = new BaseItemDto[] { };
- }
}
}
diff --git a/MediaBrowser.Model/Weather/WeatherUnits.cs b/MediaBrowser.Model/Weather/WeatherUnits.cs
deleted file mode 100644
index d27982e956..0000000000
--- a/MediaBrowser.Model/Weather/WeatherUnits.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-namespace MediaBrowser.Model.Weather
-{
- ///
- /// Enum WeatherUnits
- ///
- public enum WeatherUnits
- {
- ///
- /// The fahrenheit
- ///
- Fahrenheit,
- ///
- /// The celsius
- ///
- Celsius
- }
-}
\ No newline at end of file
diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs
index ee7ce7f26b..8e6fff38cc 100644
--- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs
+++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs
@@ -286,6 +286,7 @@ namespace MediaBrowser.Providers.MediaInfo
{
var result = new MediaInfoLib().GetVideoInfo(video.Path);
+ videoStream.IsCabac = result.IsCabac ?? videoStream.IsCabac;
videoStream.IsInterlaced = result.IsInterlaced ?? videoStream.IsInterlaced;
videoStream.BitDepth = result.BitDepth ?? videoStream.BitDepth;
videoStream.RefFrames = result.RefFrames;
diff --git a/MediaBrowser.Providers/Movies/FanArtMovieUpdatesPostScanTask.cs b/MediaBrowser.Providers/Movies/FanArtMovieUpdatesPostScanTask.cs
index 0c78136719..2936fec0ec 100644
--- a/MediaBrowser.Providers/Movies/FanArtMovieUpdatesPostScanTask.cs
+++ b/MediaBrowser.Providers/Movies/FanArtMovieUpdatesPostScanTask.cs
@@ -18,7 +18,7 @@ namespace MediaBrowser.Providers.Movies
{
class FanartMovieUpdatesPostScanTask : ILibraryPostScanTask
{
- private const string UpdatesUrl = "http://api.fanart.tv/webservice/newmovies/{0}/{1}/";
+ private const string UpdatesUrl = "http://webservice.fanart.tv/v3/movies/latest?api_key={0}&date={1}";
///
/// The _HTTP client
@@ -118,11 +118,26 @@ namespace MediaBrowser.Providers.Movies
return new List();
}
- var updates = _jsonSerializer.DeserializeFromString>(json);
+ var updates = _jsonSerializer.DeserializeFromString>(json);
var existingDictionary = existingIds.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
- return updates.Select(i => i.id).Where(existingDictionary.ContainsKey);
+ return updates.SelectMany(i =>
+ {
+ var list = new List();
+
+ if (!string.IsNullOrWhiteSpace(i.imdb_id))
+ {
+ list.Add(i.imdb_id);
+ }
+ if (!string.IsNullOrWhiteSpace(i.tmdb_id))
+ {
+ list.Add(i.tmdb_id);
+ }
+
+ return list;
+
+ }).Where(existingDictionary.ContainsKey);
}
}
}
@@ -136,7 +151,7 @@ namespace MediaBrowser.Providers.Movies
{
_logger.Info("Updating movie " + id);
- await FanartMovieImageProvider.Current.DownloadMovieXml(id, cancellationToken).ConfigureAwait(false);
+ await FanartMovieImageProvider.Current.DownloadMovieJson(id, cancellationToken).ConfigureAwait(false);
numComplete++;
double percent = numComplete;
@@ -157,9 +172,10 @@ namespace MediaBrowser.Providers.Movies
return (dateTime - new DateTime(1970, 1, 1).ToUniversalTime()).TotalSeconds;
}
- public class FanArtUpdate
+ public class RootObject
{
- public string id { get; set; }
+ public string tmdb_id { get; set; }
+ public string imdb_id { get; set; }
public string name { get; set; }
public string new_images { get; set; }
public string total_images { get; set; }
diff --git a/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs b/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs
index 9af0b17b78..1d47ee9b92 100644
--- a/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs
+++ b/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs
@@ -1,25 +1,22 @@
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.IO;
using MediaBrowser.Common.Net;
-using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Providers;
-using MediaBrowser.Model.Channels;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Providers;
+using MediaBrowser.Model.Serialization;
using MediaBrowser.Providers.Music;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
-using System.Text;
using System.Threading;
using System.Threading.Tasks;
-using System.Xml;
namespace MediaBrowser.Providers.Movies
{
@@ -29,16 +26,19 @@ namespace MediaBrowser.Providers.Movies
private readonly IServerConfigurationManager _config;
private readonly IHttpClient _httpClient;
private readonly IFileSystem _fileSystem;
+ private readonly IJsonSerializer _json;
- private const string FanArtBaseUrl = "http://api.fanart.tv/webservice/movie/{0}/{1}/xml/all/1/1";
+ private const string FanArtBaseUrl = "http://webservice.fanart.tv/v3/movies/{1}?api_key={0}";
+ // &client_key=52c813aa7b8c8b3bb87f4797532a2f8c
internal static FanartMovieImageProvider Current;
- public FanartMovieImageProvider(IServerConfigurationManager config, IHttpClient httpClient, IFileSystem fileSystem)
+ public FanartMovieImageProvider(IServerConfigurationManager config, IHttpClient httpClient, IFileSystem fileSystem, IJsonSerializer json)
{
_config = config;
_httpClient = httpClient;
_fileSystem = fileSystem;
+ _json = json;
Current = this;
}
@@ -88,13 +88,13 @@ namespace MediaBrowser.Providers.Movies
if (!string.IsNullOrEmpty(movieId))
{
- await EnsureMovieXml(movieId, cancellationToken).ConfigureAwait(false);
+ await EnsureMovieJson(movieId, cancellationToken).ConfigureAwait(false);
- var xmlPath = GetFanartXmlPath(movieId);
+ var path = GetFanartJsonPath(movieId);
try
{
- AddImages(list, xmlPath, cancellationToken);
+ AddImages(list, path, cancellationToken);
}
catch (FileNotFoundException)
{
@@ -130,198 +130,63 @@ namespace MediaBrowser.Providers.Movies
.ThenByDescending(i => i.CommunityRating ?? 0);
}
- private void AddImages(List list, string xmlPath, CancellationToken cancellationToken)
+ private void AddImages(List list, string path, CancellationToken cancellationToken)
{
- using (var streamReader = new StreamReader(xmlPath, Encoding.UTF8))
- {
- // Use XmlReader for best performance
- using (var reader = XmlReader.Create(streamReader, new XmlReaderSettings
- {
- CheckCharacters = false,
- IgnoreProcessingInstructions = true,
- IgnoreComments = true,
- ValidationType = ValidationType.None
- }))
- {
- reader.MoveToContent();
-
- // Loop through each element
- while (reader.Read())
- {
- cancellationToken.ThrowIfCancellationRequested();
+ var root = _json.DeserializeFromFile(path);
- if (reader.NodeType == XmlNodeType.Element)
- {
- switch (reader.Name)
- {
- case "movie":
- {
- using (var subReader = reader.ReadSubtree())
- {
- AddImages(list, subReader, cancellationToken);
- }
- break;
- }
-
- default:
- reader.Skip();
- break;
- }
- }
- }
- }
- }
+ AddImages(list, root, cancellationToken);
}
- private void AddImages(List list, XmlReader reader, CancellationToken cancellationToken)
+ private void AddImages(List list, RootObject obj, CancellationToken cancellationToken)
{
- reader.MoveToContent();
-
- while (reader.Read())
- {
- if (reader.NodeType == XmlNodeType.Element)
- {
- switch (reader.Name)
- {
- case "hdmoviecleararts":
- {
- using (var subReader = reader.ReadSubtree())
- {
- PopulateImageCategory(list, subReader, cancellationToken, ImageType.Art, 1000, 562);
- }
- break;
- }
- case "hdmovielogos":
- {
- using (var subReader = reader.ReadSubtree())
- {
- PopulateImageCategory(list, subReader, cancellationToken, ImageType.Logo, 800, 310);
- }
- break;
- }
- case "moviediscs":
- {
- using (var subReader = reader.ReadSubtree())
- {
- PopulateImageCategory(list, subReader, cancellationToken, ImageType.Disc, 1000, 1000);
- }
- break;
- }
- case "movieposters":
- {
- using (var subReader = reader.ReadSubtree())
- {
- PopulateImageCategory(list, subReader, cancellationToken, ImageType.Primary, 1000, 1426);
- }
- break;
- }
- case "movielogos":
- {
- using (var subReader = reader.ReadSubtree())
- {
- PopulateImageCategory(list, subReader, cancellationToken, ImageType.Logo, 400, 155);
- }
- break;
- }
- case "moviearts":
- {
- using (var subReader = reader.ReadSubtree())
- {
- PopulateImageCategory(list, subReader, cancellationToken, ImageType.Art, 500, 281);
- }
- break;
- }
- case "moviethumbs":
- {
- using (var subReader = reader.ReadSubtree())
- {
- PopulateImageCategory(list, subReader, cancellationToken, ImageType.Thumb, 1000, 562);
- }
- break;
- }
- case "moviebanners":
- {
- using (var subReader = reader.ReadSubtree())
- {
- PopulateImageCategory(list, subReader, cancellationToken, ImageType.Banner, 1000, 185);
- }
- break;
- }
- case "moviebackgrounds":
- {
- using (var subReader = reader.ReadSubtree())
- {
- PopulateImageCategory(list, subReader, cancellationToken, ImageType.Backdrop, 1920, 1080);
- }
- break;
- }
- default:
- {
- using (reader.ReadSubtree())
- {
- }
- break;
- }
- }
- }
- }
+ PopulateImages(list, obj.hdmovieclearart, ImageType.Art, 1000, 562);
+ PopulateImages(list, obj.hdmovielogo, ImageType.Logo, 800, 310);
+ PopulateImages(list, obj.moviedisc, ImageType.Disc, 1000, 1000);
+ PopulateImages(list, obj.movieposter, ImageType.Primary, 1000, 1426);
+ PopulateImages(list, obj.movielogo, ImageType.Logo, 400, 155);
+ PopulateImages(list, obj.movieart, ImageType.Art, 500, 281);
+ PopulateImages(list, obj.moviethumb, ImageType.Thumb, 1000, 562);
+ PopulateImages(list, obj.moviebanner, ImageType.Banner, 1000, 185);
+ PopulateImages(list, obj.moviebackground, ImageType.Backdrop, 1920, 1080);
}
- private void PopulateImageCategory(List list, XmlReader reader, CancellationToken cancellationToken, ImageType type, int width, int height)
+ private void PopulateImages(List list, List images, ImageType type, int width, int height)
{
- reader.MoveToContent();
+ if (images == null)
+ {
+ return;
+ }
- while (reader.Read())
+ list.AddRange(images.Select(i =>
{
- cancellationToken.ThrowIfCancellationRequested();
+ var url = i.url;
- if (reader.NodeType == XmlNodeType.Element)
+ if (!string.IsNullOrEmpty(url))
{
- switch (reader.Name)
+ var likesString = i.likes;
+ int likes;
+
+ var info = new RemoteImageInfo
+ {
+ RatingType = RatingType.Likes,
+ Type = type,
+ Width = width,
+ Height = height,
+ ProviderName = Name,
+ Url = url,
+ Language = i.lang
+ };
+
+ if (!string.IsNullOrEmpty(likesString) && int.TryParse(likesString, NumberStyles.Any, _usCulture, out likes))
{
- case "hdmovielogo":
- case "moviedisc":
- case "hdmovieclearart":
- case "movieposter":
- case "movielogo":
- case "movieart":
- case "moviethumb":
- case "moviebanner":
- case "moviebackground":
- {
- var url = reader.GetAttribute("url");
-
- if (!string.IsNullOrEmpty(url))
- {
- var likesString = reader.GetAttribute("likes");
- int likes;
-
- var info = new RemoteImageInfo
- {
- RatingType = RatingType.Likes,
- Type = type,
- Width = width,
- Height = height,
- ProviderName = Name,
- Url = url,
- Language = reader.GetAttribute("lang")
- };
-
- if (!string.IsNullOrEmpty(likesString) && int.TryParse(likesString, NumberStyles.Any, _usCulture, out likes))
- {
- info.CommunityRating = likes;
- }
-
- list.Add(info);
- }
- break;
- }
- default:
- reader.Skip();
- break;
+ info.CommunityRating = likes;
}
+
+ return info;
}
- }
+
+ return null;
+ }).Where(i => i != null));
}
public int Order
@@ -347,13 +212,17 @@ namespace MediaBrowser.Providers.Movies
}
var id = item.GetProviderId(MetadataProviders.Tmdb);
+ if (string.IsNullOrEmpty(id))
+ {
+ id = item.GetProviderId(MetadataProviders.Imdb);
+ }
if (!string.IsNullOrEmpty(id))
{
// Process images
- var xmlPath = GetFanartXmlPath(id);
+ var path = GetFanartJsonPath(id);
- var fileInfo = new FileInfo(xmlPath);
+ var fileInfo = new FileInfo(path);
return !fileInfo.Exists || _fileSystem.GetLastWriteTimeUtc(fileInfo) > date;
}
@@ -364,12 +233,12 @@ namespace MediaBrowser.Providers.Movies
///
/// Gets the movie data path.
///
- /// The app paths.
- /// The TMDB id.
+ /// The application paths.
+ /// The identifier.
/// System.String.
- internal static string GetMovieDataPath(IApplicationPaths appPaths, string tmdbId)
+ internal static string GetMovieDataPath(IApplicationPaths appPaths, string id)
{
- var dataPath = Path.Combine(GetMoviesDataPath(appPaths), tmdbId);
+ var dataPath = Path.Combine(GetMoviesDataPath(appPaths), id);
return dataPath;
}
@@ -386,27 +255,27 @@ namespace MediaBrowser.Providers.Movies
return dataPath;
}
- public string GetFanartXmlPath(string tmdbId)
+ public string GetFanartJsonPath(string id)
{
- var movieDataPath = GetMovieDataPath(_config.ApplicationPaths, tmdbId);
- return Path.Combine(movieDataPath, "fanart.xml");
+ var movieDataPath = GetMovieDataPath(_config.ApplicationPaths, id);
+ return Path.Combine(movieDataPath, "fanart.json");
}
///
- /// Downloads the movie XML.
+ /// Downloads the movie json.
///
- /// The TMDB id.
+ /// The identifier.
/// The cancellation token.
/// Task.
- internal async Task DownloadMovieXml(string tmdbId, CancellationToken cancellationToken)
+ internal async Task DownloadMovieJson(string id, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
- var url = string.Format(FanArtBaseUrl, FanartArtistProvider.ApiKey, tmdbId);
+ var url = string.Format(FanArtBaseUrl, FanartArtistProvider.ApiKey, id);
- var xmlPath = GetFanartXmlPath(tmdbId);
+ var path = GetFanartJsonPath(id);
- Directory.CreateDirectory(Path.GetDirectoryName(xmlPath));
+ Directory.CreateDirectory(Path.GetDirectoryName(path));
using (var response = await _httpClient.Get(new HttpRequestOptions
{
@@ -416,17 +285,17 @@ namespace MediaBrowser.Providers.Movies
}).ConfigureAwait(false))
{
- using (var xmlFileStream = _fileSystem.GetFileStream(xmlPath, FileMode.Create, FileAccess.Write, FileShare.Read, true))
+ using (var fileStream = _fileSystem.GetFileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, true))
{
- await response.CopyToAsync(xmlFileStream).ConfigureAwait(false);
+ await response.CopyToAsync(fileStream).ConfigureAwait(false);
}
}
}
private readonly Task _cachedTask = Task.FromResult(true);
- internal Task EnsureMovieXml(string tmdbId, CancellationToken cancellationToken)
+ internal Task EnsureMovieJson(string id, CancellationToken cancellationToken)
{
- var path = GetFanartXmlPath(tmdbId);
+ var path = GetFanartJsonPath(id);
var fileInfo = _fileSystem.GetFileSystemInfo(path);
@@ -438,7 +307,31 @@ namespace MediaBrowser.Providers.Movies
}
}
- return DownloadMovieXml(tmdbId, cancellationToken);
+ return DownloadMovieJson(id, cancellationToken);
+ }
+
+ public class Image
+ {
+ public string id { get; set; }
+ public string url { get; set; }
+ public string lang { get; set; }
+ public string likes { get; set; }
+ }
+
+ public class RootObject
+ {
+ public string name { get; set; }
+ public string tmdb_id { get; set; }
+ public string imdb_id { get; set; }
+ public List hdmovielogo { get; set; }
+ public List moviedisc { get; set; }
+ public List movielogo { get; set; }
+ public List movieposter { get; set; }
+ public List hdmovieclearart { get; set; }
+ public List movieart { get; set; }
+ public List moviebackground { get; set; }
+ public List moviebanner { get; set; }
+ public List moviethumb { get; set; }
}
}
}
diff --git a/MediaBrowser.Providers/TV/FanArtSeasonProvider.cs b/MediaBrowser.Providers/TV/FanArtSeasonProvider.cs
index 5bc58af915..47c73abbbe 100644
--- a/MediaBrowser.Providers/TV/FanArtSeasonProvider.cs
+++ b/MediaBrowser.Providers/TV/FanArtSeasonProvider.cs
@@ -7,16 +7,15 @@ using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Providers;
+using MediaBrowser.Model.Serialization;
using MediaBrowser.Providers.Music;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
-using System.Text;
using System.Threading;
using System.Threading.Tasks;
-using System.Xml;
namespace MediaBrowser.Providers.TV
{
@@ -26,12 +25,14 @@ namespace MediaBrowser.Providers.TV
private readonly IServerConfigurationManager _config;
private readonly IHttpClient _httpClient;
private readonly IFileSystem _fileSystem;
+ private readonly IJsonSerializer _json;
- public FanArtSeasonProvider(IServerConfigurationManager config, IHttpClient httpClient, IFileSystem fileSystem)
+ public FanArtSeasonProvider(IServerConfigurationManager config, IHttpClient httpClient, IFileSystem fileSystem, IJsonSerializer json)
{
_config = config;
_httpClient = httpClient;
_fileSystem = fileSystem;
+ _json = json;
}
public string Name
@@ -71,14 +72,14 @@ namespace MediaBrowser.Providers.TV
if (!string.IsNullOrEmpty(id) && season.IndexNumber.HasValue)
{
- await FanartSeriesProvider.Current.EnsureSeriesXml(id, cancellationToken).ConfigureAwait(false);
+ await FanartSeriesProvider.Current.EnsureSeriesJson(id, cancellationToken).ConfigureAwait(false);
- var xmlPath = FanartSeriesProvider.Current.GetFanartXmlPath(id);
+ var path = FanartSeriesProvider.Current.GetFanartJsonPath(id);
try
{
int seasonNumber = AdjustForSeriesOffset(series, season.IndexNumber.Value);
- AddImages(list, seasonNumber, xmlPath, cancellationToken);
+ AddImages(list, seasonNumber, path, cancellationToken);
}
catch (FileNotFoundException)
{
@@ -125,142 +126,67 @@ namespace MediaBrowser.Providers.TV
return seasonNumber;
}
- private void AddImages(List list, int seasonNumber, string xmlPath, CancellationToken cancellationToken)
+ private void AddImages(List list, int seasonNumber, string path, CancellationToken cancellationToken)
{
- using (var streamReader = new StreamReader(xmlPath, Encoding.UTF8))
- {
- // Use XmlReader for best performance
- using (var reader = XmlReader.Create(streamReader, new XmlReaderSettings
- {
- CheckCharacters = false,
- IgnoreProcessingInstructions = true,
- IgnoreComments = true,
- ValidationType = ValidationType.None
- }))
- {
- reader.MoveToContent();
+ var root = _json.DeserializeFromFile(path);
- // Loop through each element
- while (reader.Read())
- {
- cancellationToken.ThrowIfCancellationRequested();
-
- if (reader.NodeType == XmlNodeType.Element)
- {
- switch (reader.Name)
- {
- case "series":
- {
- using (var subReader = reader.ReadSubtree())
- {
- AddImages(list, subReader, seasonNumber, cancellationToken);
- }
- break;
- }
-
- default:
- reader.Skip();
- break;
- }
- }
- }
- }
- }
+ AddImages(list, root, seasonNumber, cancellationToken);
}
- private void AddImages(List list, XmlReader reader, int seasonNumber, CancellationToken cancellationToken)
+ private void AddImages(List list, FanartSeriesProvider.RootObject obj, int seasonNumber, CancellationToken cancellationToken)
{
- reader.MoveToContent();
-
- while (reader.Read())
- {
- if (reader.NodeType == XmlNodeType.Element)
- {
- switch (reader.Name)
- {
- case "seasonthumbs":
- {
- using (var subReader = reader.ReadSubtree())
- {
- PopulateImageCategory(list, subReader, cancellationToken, ImageType.Thumb, 500, 281, seasonNumber);
- }
- break;
- }
- case "showbackgrounds":
- {
- using (var subReader = reader.ReadSubtree())
- {
- PopulateImageCategory(list, subReader, cancellationToken, ImageType.Backdrop, 1920, 1080, seasonNumber);
- }
- break;
- }
- default:
- {
- using (reader.ReadSubtree())
- {
- }
- break;
- }
- }
- }
- }
+ PopulateImages(list, obj.seasonthumb, ImageType.Thumb, 500, 281, seasonNumber);
+ PopulateImages(list, obj.showbackground, ImageType.Backdrop, 1920, 1080, seasonNumber);
}
- private void PopulateImageCategory(List list, XmlReader reader, CancellationToken cancellationToken, ImageType type, int width, int height, int seasonNumber)
+ private void PopulateImages(List list,
+ List images,
+ ImageType type,
+ int width,
+ int height,
+ int seasonNumber)
{
- reader.MoveToContent();
+ if (images == null)
+ {
+ return;
+ }
- while (reader.Read())
+ list.AddRange(images.Select(i =>
{
- cancellationToken.ThrowIfCancellationRequested();
+ var url = i.url;
+ var season = i.season;
- if (reader.NodeType == XmlNodeType.Element)
+ int imageSeasonNumber;
+
+ if (!string.IsNullOrEmpty(url) &&
+ !string.IsNullOrEmpty(season) &&
+ int.TryParse(season, NumberStyles.Any, _usCulture, out imageSeasonNumber) &&
+ seasonNumber == imageSeasonNumber)
{
- switch (reader.Name)
+ var likesString = i.likes;
+ int likes;
+
+ var info = new RemoteImageInfo
+ {
+ RatingType = RatingType.Likes,
+ Type = type,
+ Width = width,
+ Height = height,
+ ProviderName = Name,
+ Url = url,
+ Language = i.lang
+ };
+
+ if (!string.IsNullOrEmpty(likesString) && int.TryParse(likesString, NumberStyles.Any, _usCulture, out likes))
{
- case "seasonthumb":
- case "showbackground":
- {
- var url = reader.GetAttribute("url");
- var season = reader.GetAttribute("season");
-
- int imageSeasonNumber;
-
- if (!string.IsNullOrEmpty(url) &&
- !string.IsNullOrEmpty(season) &&
- int.TryParse(season, NumberStyles.Any, _usCulture, out imageSeasonNumber) &&
- seasonNumber == imageSeasonNumber)
- {
- var likesString = reader.GetAttribute("likes");
- int likes;
-
- var info = new RemoteImageInfo
- {
- RatingType = RatingType.Likes,
- Type = type,
- Width = width,
- Height = height,
- ProviderName = Name,
- Url = url,
- Language = reader.GetAttribute("lang")
- };
-
- if (!string.IsNullOrEmpty(likesString) && int.TryParse(likesString, NumberStyles.Any, _usCulture, out likes))
- {
- info.CommunityRating = likes;
- }
-
- list.Add(info);
- }
-
- break;
- }
- default:
- reader.Skip();
- break;
+ info.CommunityRating = likes;
}
+
+ return info;
}
- }
+
+ return null;
+ }).Where(i => i != null));
}
public int Order
@@ -298,9 +224,9 @@ namespace MediaBrowser.Providers.TV
if (!String.IsNullOrEmpty(tvdbId))
{
// Process images
- var imagesXmlPath = FanartSeriesProvider.Current.GetFanartXmlPath(tvdbId);
+ var imagesFilePath = FanartSeriesProvider.Current.GetFanartJsonPath(tvdbId);
- var fileInfo = new FileInfo(imagesXmlPath);
+ var fileInfo = new FileInfo(imagesFilePath);
return !fileInfo.Exists || _fileSystem.GetLastWriteTimeUtc(fileInfo) > date;
}
diff --git a/MediaBrowser.Providers/TV/FanArtTvUpdatesPostScanTask.cs b/MediaBrowser.Providers/TV/FanArtTvUpdatesPostScanTask.cs
index 33100db730..13920d942d 100644
--- a/MediaBrowser.Providers/TV/FanArtTvUpdatesPostScanTask.cs
+++ b/MediaBrowser.Providers/TV/FanArtTvUpdatesPostScanTask.cs
@@ -18,7 +18,7 @@ namespace MediaBrowser.Providers.TV
{
class FanArtTvUpdatesPostScanTask : ILibraryPostScanTask
{
- private const string UpdatesUrl = "http://api.fanart.tv/webservice/newtv/{0}/{1}/";
+ private const string UpdatesUrl = "http://webservice.fanart.tv/v3/tv/latest?api_key={0}&date={1}";
///
/// The _HTTP client
@@ -150,7 +150,7 @@ namespace MediaBrowser.Providers.TV
{
_logger.Info("Updating series " + id);
- await FanartSeriesProvider.Current.DownloadSeriesXml(id, cancellationToken).ConfigureAwait(false);
+ await FanartSeriesProvider.Current.DownloadSeriesJson(id, cancellationToken).ConfigureAwait(false);
numComplete++;
double percent = numComplete;
diff --git a/MediaBrowser.Providers/TV/FanartSeriesProvider.cs b/MediaBrowser.Providers/TV/FanartSeriesProvider.cs
index 57427ece7c..56945106ad 100644
--- a/MediaBrowser.Providers/TV/FanartSeriesProvider.cs
+++ b/MediaBrowser.Providers/TV/FanartSeriesProvider.cs
@@ -8,16 +8,15 @@ using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Providers;
+using MediaBrowser.Model.Serialization;
using MediaBrowser.Providers.Music;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
-using System.Text;
using System.Threading;
using System.Threading.Tasks;
-using System.Xml;
namespace MediaBrowser.Providers.TV
{
@@ -27,16 +26,19 @@ namespace MediaBrowser.Providers.TV
private readonly IServerConfigurationManager _config;
private readonly IHttpClient _httpClient;
private readonly IFileSystem _fileSystem;
+ private readonly IJsonSerializer _json;
- protected string FanArtBaseUrl = "http://api.fanart.tv/webservice/series/{0}/{1}/xml/all/1/1";
+ private const string FanArtBaseUrl = "http://webservice.fanart.tv/v3/tv/{1}?api_key={0}";
+ // &client_key=52c813aa7b8c8b3bb87f4797532a2f8c
internal static FanartSeriesProvider Current { get; private set; }
- public FanartSeriesProvider(IServerConfigurationManager config, IHttpClient httpClient, IFileSystem fileSystem)
+ public FanartSeriesProvider(IServerConfigurationManager config, IHttpClient httpClient, IFileSystem fileSystem, IJsonSerializer json)
{
_config = config;
_httpClient = httpClient;
_fileSystem = fileSystem;
+ _json = json;
Current = this;
}
@@ -79,13 +81,13 @@ namespace MediaBrowser.Providers.TV
if (!string.IsNullOrEmpty(id))
{
- await EnsureSeriesXml(id, cancellationToken).ConfigureAwait(false);
+ await EnsureSeriesJson(id, cancellationToken).ConfigureAwait(false);
- var xmlPath = GetFanartXmlPath(id);
+ var path = GetFanartJsonPath(id);
try
{
- AddImages(list, xmlPath, cancellationToken);
+ AddImages(list, path, cancellationToken);
}
catch (FileNotFoundException)
{
@@ -122,203 +124,72 @@ namespace MediaBrowser.Providers.TV
.ThenByDescending(i => i.VoteCount ?? 0);
}
- private void AddImages(List list, string xmlPath, CancellationToken cancellationToken)
+ private void AddImages(List list, string path, CancellationToken cancellationToken)
{
- using (var streamReader = new StreamReader(xmlPath, Encoding.UTF8))
- {
- // Use XmlReader for best performance
- using (var reader = XmlReader.Create(streamReader, new XmlReaderSettings
- {
- CheckCharacters = false,
- IgnoreProcessingInstructions = true,
- IgnoreComments = true,
- ValidationType = ValidationType.None
- }))
- {
- reader.MoveToContent();
-
- // Loop through each element
- while (reader.Read())
- {
- cancellationToken.ThrowIfCancellationRequested();
+ var root = _json.DeserializeFromFile(path);
- if (reader.NodeType == XmlNodeType.Element)
- {
- switch (reader.Name)
- {
- case "series":
- {
- using (var subReader = reader.ReadSubtree())
- {
- AddImages(list, subReader, cancellationToken);
- }
- break;
- }
-
- default:
- reader.Skip();
- break;
- }
- }
- }
- }
- }
+ AddImages(list, root, cancellationToken);
}
- private void AddImages(List list, XmlReader reader, CancellationToken cancellationToken)
+ private void AddImages(List list, RootObject obj, CancellationToken cancellationToken)
{
- reader.MoveToContent();
-
- while (reader.Read())
- {
- if (reader.NodeType == XmlNodeType.Element)
- {
- switch (reader.Name)
- {
- case "hdtvlogos":
- {
- using (var subReader = reader.ReadSubtree())
- {
- PopulateImageCategory(list, subReader, cancellationToken, ImageType.Logo, 800, 310);
- }
- break;
- }
- case "hdcleararts":
- {
- using (var subReader = reader.ReadSubtree())
- {
- PopulateImageCategory(list, subReader, cancellationToken, ImageType.Art, 1000, 562);
- }
- break;
- }
- case "clearlogos":
- {
- using (var subReader = reader.ReadSubtree())
- {
- PopulateImageCategory(list, subReader, cancellationToken, ImageType.Logo, 400, 155);
- }
- break;
- }
- case "cleararts":
- {
- using (var subReader = reader.ReadSubtree())
- {
- PopulateImageCategory(list, subReader, cancellationToken, ImageType.Art, 500, 281);
- }
- break;
- }
- case "showbackgrounds":
- {
- using (var subReader = reader.ReadSubtree())
- {
- PopulateImageCategory(list, subReader, cancellationToken, ImageType.Backdrop, 1920, 1080, true);
- }
- break;
- }
- case "seasonthumbs":
- {
- using (var subReader = reader.ReadSubtree())
- {
- PopulateImageCategory(list, subReader, cancellationToken, ImageType.Thumb, 500, 281);
- }
- break;
- }
- case "tvthumbs":
- {
- using (var subReader = reader.ReadSubtree())
- {
- PopulateImageCategory(list, subReader, cancellationToken, ImageType.Thumb, 500, 281);
- }
- break;
- }
- case "tvbanners":
- {
- using (var subReader = reader.ReadSubtree())
- {
- PopulateImageCategory(list, subReader, cancellationToken, ImageType.Banner, 1000, 185);
- }
- break;
- }
- case "tvposters":
- {
- using (var subReader = reader.ReadSubtree())
- {
- PopulateImageCategory(list, subReader, cancellationToken, ImageType.Primary, 1000, 1426);
- }
- break;
- }
- default:
- {
- using (reader.ReadSubtree())
- {
- }
- break;
- }
- }
- }
- }
+ PopulateImages(list, obj.hdtvlogo, ImageType.Logo, 800, 310);
+ PopulateImages(list, obj.hdclearart, ImageType.Art, 1000, 562);
+ PopulateImages(list, obj.clearlogo, ImageType.Logo, 400, 155);
+ PopulateImages(list, obj.clearart, ImageType.Art, 500, 281);
+ PopulateImages(list, obj.showbackground, ImageType.Backdrop, 1920, 1080, true);
+ PopulateImages(list, obj.seasonthumb, ImageType.Thumb, 500, 281);
+ PopulateImages(list, obj.tvthumb, ImageType.Thumb, 500, 281);
+ PopulateImages(list, obj.tvbanner, ImageType.Banner, 1000, 185);
+ PopulateImages(list, obj.tvposter, ImageType.Primary, 1000, 1426);
}
- private void PopulateImageCategory(List list, XmlReader reader, CancellationToken cancellationToken, ImageType type, int width, int height, bool allowSeasonAll = false)
+ private void PopulateImages(List list,
+ List images,
+ ImageType type,
+ int width,
+ int height,
+ bool allowSeasonAll = false)
{
- reader.MoveToContent();
+ if (images == null)
+ {
+ return;
+ }
- while (reader.Read())
+ list.AddRange(images.Select(i =>
{
- cancellationToken.ThrowIfCancellationRequested();
+ var url = i.url;
+ var season = i.season;
+
+ var isSeasonValid = string.IsNullOrEmpty(season) ||
+ (allowSeasonAll && string.Equals(season, "all", StringComparison.OrdinalIgnoreCase));
- if (reader.NodeType == XmlNodeType.Element)
+ if (!string.IsNullOrEmpty(url) && isSeasonValid)
{
- switch (reader.Name)
+ var likesString = i.likes;
+ int likes;
+
+ var info = new RemoteImageInfo
+ {
+ RatingType = RatingType.Likes,
+ Type = type,
+ Width = width,
+ Height = height,
+ ProviderName = Name,
+ Url = url,
+ Language = i.lang
+ };
+
+ if (!string.IsNullOrEmpty(likesString) && int.TryParse(likesString, NumberStyles.Any, _usCulture, out likes))
{
- case "hdtvlogo":
- case "hdclearart":
- case "clearlogo":
- case "clearart":
- case "showbackground":
- case "seasonthumb":
- case "tvthumb":
- case "tvbanner":
- case "tvposter":
- {
- var url = reader.GetAttribute("url");
- var season = reader.GetAttribute("season");
-
- var isSeasonValid = string.IsNullOrEmpty(season) ||
- (allowSeasonAll && string.Equals(season, "all", StringComparison.OrdinalIgnoreCase));
-
- if (!string.IsNullOrEmpty(url) && isSeasonValid)
- {
- var likesString = reader.GetAttribute("likes");
- int likes;
-
- var info = new RemoteImageInfo
- {
- RatingType = RatingType.Likes,
- Type = type,
- Width = width,
- Height = height,
- ProviderName = Name,
- Url = url,
- Language = reader.GetAttribute("lang")
- };
-
- if (!string.IsNullOrEmpty(likesString) && int.TryParse(likesString, NumberStyles.Any, _usCulture, out likes))
- {
- info.CommunityRating = likes;
- }
-
- list.Add(info);
- }
-
- break;
- }
- default:
- reader.Skip();
- break;
+ info.CommunityRating = likes;
}
+
+ return info;
}
- }
+
+ return null;
+ }).Where(i => i != null));
}
public int Order
@@ -361,23 +232,23 @@ namespace MediaBrowser.Providers.TV
return dataPath;
}
- public string GetFanartXmlPath(string tvdbId)
+ public string GetFanartJsonPath(string tvdbId)
{
var dataPath = GetSeriesDataPath(_config.ApplicationPaths, tvdbId);
- return Path.Combine(dataPath, "fanart.xml");
+ return Path.Combine(dataPath, "fanart.json");
}
private readonly SemaphoreSlim _ensureSemaphore = new SemaphoreSlim(1, 1);
- internal async Task EnsureSeriesXml(string tvdbId, CancellationToken cancellationToken)
+ internal async Task EnsureSeriesJson(string tvdbId, CancellationToken cancellationToken)
{
- var xmlPath = GetFanartXmlPath(tvdbId);
+ var path = GetFanartJsonPath(tvdbId);
// Only allow one thread in here at a time since every season will be calling this method, possibly concurrently
await _ensureSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
try
{
- var fileInfo = _fileSystem.GetFileSystemInfo(xmlPath);
+ var fileInfo = _fileSystem.GetFileSystemInfo(path);
if (fileInfo.Exists)
{
@@ -387,7 +258,7 @@ namespace MediaBrowser.Providers.TV
}
}
- await DownloadSeriesXml(tvdbId, cancellationToken).ConfigureAwait(false);
+ await DownloadSeriesJson(tvdbId, cancellationToken).ConfigureAwait(false);
}
finally
{
@@ -396,20 +267,20 @@ namespace MediaBrowser.Providers.TV
}
///
- /// Downloads the series XML.
+ /// Downloads the series json.
///
- /// The TVDB id.
+ /// The TVDB identifier.
/// The cancellation token.
/// Task.
- internal async Task DownloadSeriesXml(string tvdbId, CancellationToken cancellationToken)
+ internal async Task DownloadSeriesJson(string tvdbId, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
var url = string.Format(FanArtBaseUrl, FanartArtistProvider.ApiKey, tvdbId);
- var xmlPath = GetFanartXmlPath(tvdbId);
+ var path = GetFanartJsonPath(tvdbId);
- Directory.CreateDirectory(Path.GetDirectoryName(xmlPath));
+ Directory.CreateDirectory(Path.GetDirectoryName(path));
using (var response = await _httpClient.Get(new HttpRequestOptions
{
@@ -419,9 +290,9 @@ namespace MediaBrowser.Providers.TV
}).ConfigureAwait(false))
{
- using (var xmlFileStream = _fileSystem.GetFileStream(xmlPath, FileMode.Create, FileAccess.Write, FileShare.Read, true))
+ using (var fileStream = _fileSystem.GetFileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, true))
{
- await response.CopyToAsync(xmlFileStream).ConfigureAwait(false);
+ await response.CopyToAsync(fileStream).ConfigureAwait(false);
}
}
}
@@ -438,14 +309,41 @@ namespace MediaBrowser.Providers.TV
if (!String.IsNullOrEmpty(tvdbId))
{
// Process images
- var imagesXmlPath = GetFanartXmlPath(tvdbId);
+ var imagesFilePath = GetFanartJsonPath(tvdbId);
- var fileInfo = new FileInfo(imagesXmlPath);
+ var fileInfo = new FileInfo(imagesFilePath);
return !fileInfo.Exists || _fileSystem.GetLastWriteTimeUtc(fileInfo) > date;
}
return false;
}
+
+ public class Image
+ {
+ public string id { get; set; }
+ public string url { get; set; }
+ public string lang { get; set; }
+ public string likes { get; set; }
+ public string season { get; set; }
+ }
+
+ public class RootObject
+ {
+ public string name { get; set; }
+ public string thetvdb_id { get; set; }
+ public List clearlogo { get; set; }
+ public List hdtvlogo { get; set; }
+ public List clearart { get; set; }
+ public List showbackground { get; set; }
+ public List tvthumb { get; set; }
+ public List seasonposter { get; set; }
+ public List seasonthumb { get; set; }
+ public List hdclearart { get; set; }
+ public List tvbanner { get; set; }
+ public List characterart { get; set; }
+ public List tvposter { get; set; }
+ public List seasonbanner { get; set; }
+ }
}
}
diff --git a/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs b/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs
index 1370b2bf29..4abe56acae 100644
--- a/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs
+++ b/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs
@@ -3,6 +3,8 @@ using MediaBrowser.Common.Events;
using MediaBrowser.Common.Implementations.Configuration;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Model.Configuration;
@@ -214,6 +216,11 @@ namespace MediaBrowser.Server.Implementations.Configuration
DisableMetadataService(typeof(Movie), Configuration, service);
DisableMetadataService(typeof(Episode), Configuration, service);
DisableMetadataService(typeof(Series), Configuration, service);
+ DisableMetadataService(typeof(Season), Configuration, service);
+ DisableMetadataService(typeof(MusicArtist), Configuration, service);
+ DisableMetadataService(typeof(MusicAlbum), Configuration, service);
+ DisableMetadataService(typeof(MusicVideo), Configuration, service);
+ DisableMetadataService(typeof(Video), Configuration, service);
}
private void DisableMetadataService(Type type, ServerConfiguration config, string service)
diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs
index 88f934d25f..f468606ed0 100644
--- a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs
+++ b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs
@@ -141,6 +141,8 @@ namespace MediaBrowser.Server.Implementations.Connect
try
{
+ var localAddress = _appHost.GetSystemInfo().LocalAddress;
+
var hasExistingRecord = !string.IsNullOrWhiteSpace(ConnectServerId) &&
!string.IsNullOrWhiteSpace(ConnectAccessKey);
@@ -150,11 +152,12 @@ namespace MediaBrowser.Server.Implementations.Connect
{
try
{
- await UpdateServerRegistration(wanApiAddress).ConfigureAwait(false);
+ await UpdateServerRegistration(wanApiAddress, localAddress).ConfigureAwait(false);
}
catch (HttpException ex)
{
- if (!ex.StatusCode.HasValue || !new[] { HttpStatusCode.NotFound, HttpStatusCode.Unauthorized }.Contains(ex.StatusCode.Value))
+ if (!ex.StatusCode.HasValue ||
+ !new[] { HttpStatusCode.NotFound, HttpStatusCode.Unauthorized }.Contains(ex.StatusCode.Value))
{
throw;
}
@@ -165,7 +168,7 @@ namespace MediaBrowser.Server.Implementations.Connect
if (createNewRegistration)
{
- await CreateServerRegistration(wanApiAddress).ConfigureAwait(false);
+ await CreateServerRegistration(wanApiAddress, localAddress).ConfigureAwait(false);
}
await RefreshAuthorizationsInternal(true, CancellationToken.None).ConfigureAwait(false);
@@ -176,7 +179,7 @@ namespace MediaBrowser.Server.Implementations.Connect
}
}
- private async Task CreateServerRegistration(string wanApiAddress)
+ private async Task CreateServerRegistration(string wanApiAddress, string localAddress)
{
var url = "Servers";
url = GetConnectUrl(url);
@@ -188,6 +191,11 @@ namespace MediaBrowser.Server.Implementations.Connect
{"systemId", _appHost.SystemId}
};
+ if (!string.IsNullOrWhiteSpace(localAddress))
+ {
+ postData["localAddress"] = localAddress;
+ }
+
using (var stream = await _httpClient.Post(url, postData, CancellationToken.None).ConfigureAwait(false))
{
var data = _json.DeserializeFromStream(stream);
@@ -199,24 +207,31 @@ namespace MediaBrowser.Server.Implementations.Connect
}
}
- private async Task UpdateServerRegistration(string wanApiAddress)
+ private async Task UpdateServerRegistration(string wanApiAddress, string localAddress)
{
var url = "Servers";
url = GetConnectUrl(url);
url += "?id=" + ConnectServerId;
+ var postData = new Dictionary
+ {
+ {"name", _appHost.FriendlyName},
+ {"url", wanApiAddress},
+ {"systemId", _appHost.SystemId}
+ };
+
+ if (!string.IsNullOrWhiteSpace(localAddress))
+ {
+ postData["localAddress"] = localAddress;
+ }
+
var options = new HttpRequestOptions
{
Url = url,
CancellationToken = CancellationToken.None
};
- options.SetPostData(new Dictionary
- {
- {"name", _appHost.FriendlyName},
- {"url", wanApiAddress},
- {"systemId", _appHost.SystemId}
- });
+ options.SetPostData(postData);
SetServerAccessToken(options);
@@ -405,15 +420,46 @@ namespace MediaBrowser.Server.Implementations.Connect
throw new ArgumentNullException("connectUsername");
}
- var connectUser = await GetConnectUser(new ConnectUserQuery
+ string connectUserId = null;
+ var result = new UserLinkResult();
+
+ try
{
- Name = connectUsername
+ var connectUser = await GetConnectUser(new ConnectUserQuery
+ {
+ Name = connectUsername
- }, CancellationToken.None).ConfigureAwait(false);
+ }, CancellationToken.None).ConfigureAwait(false);
- if (!connectUser.IsActive)
+ if (!connectUser.IsActive)
+ {
+ throw new ArgumentException("The Media Browser account has been disabled.");
+ }
+
+ connectUserId = connectUser.Id;
+ result.GuestDisplayName = connectUser.Name;
+ }
+ catch (HttpException ex)
{
- throw new ArgumentException("The Media Browser account has been disabled.");
+ if (!ex.StatusCode.HasValue ||
+ ex.StatusCode.Value != HttpStatusCode.NotFound ||
+ !Validator.EmailIsValid(connectUsername))
+ {
+ throw;
+ }
+ }
+
+ var sendingUser = GetUser(sendingUserId);
+ var requesterUserName = sendingUser.ConnectUserName;
+
+ if (string.IsNullOrWhiteSpace(requesterUserName))
+ {
+ requesterUserName = sendingUser.Name;
+ }
+
+ if (string.IsNullOrWhiteSpace(connectUserId))
+ {
+ return await SendNewUserInvitation(requesterUserName, connectUsername).ConfigureAwait(false);
}
var url = GetConnectUrl("ServerAuthorizations");
@@ -425,18 +471,11 @@ namespace MediaBrowser.Server.Implementations.Connect
};
var accessToken = Guid.NewGuid().ToString("N");
- var sendingUser = GetUser(sendingUserId);
-
- var requesterUserName = sendingUser.ConnectUserName;
- if (string.IsNullOrWhiteSpace(requesterUserName))
- {
- requesterUserName = sendingUser.Name;
- }
var postData = new Dictionary
{
{"serverId", ConnectServerId},
- {"userId", connectUser.Id},
+ {"userId", connectUserId},
{"userType", "Guest"},
{"accessToken", accessToken},
{"requesterUserName", requesterUserName}
@@ -446,8 +485,6 @@ namespace MediaBrowser.Server.Implementations.Connect
SetServerAccessToken(options);
- var result = new UserLinkResult();
-
// No need to examine the response
using (var stream = (await _httpClient.Post(options).ConfigureAwait(false)).Content)
{
@@ -461,6 +498,36 @@ namespace MediaBrowser.Server.Implementations.Connect
return result;
}
+ private async Task SendNewUserInvitation(string fromName, string email)
+ {
+ var url = GetConnectUrl("users/invite");
+
+ var options = new HttpRequestOptions
+ {
+ Url = url,
+ CancellationToken = CancellationToken.None
+ };
+
+ var postData = new Dictionary
+ {
+ {"email", email},
+ {"requesterUserName", fromName}
+ };
+
+ options.SetPostData(postData);
+
+ // No need to examine the response
+ using (var stream = (await _httpClient.Post(options).ConfigureAwait(false)).Content)
+ {
+ }
+
+ return new UserLinkResult
+ {
+ IsNewUserInvitation = true,
+ GuestDisplayName = email
+ };
+ }
+
public Task RemoveConnect(string userId)
{
var user = GetUser(userId);
@@ -586,6 +653,9 @@ namespace MediaBrowser.Server.Implementations.Connect
if (connectEntry == null)
{
+ var deleteUser = user.ConnectLinkType.HasValue &&
+ user.ConnectLinkType.Value == UserLinkType.Guest;
+
user.ConnectUserId = null;
user.ConnectAccessKey = null;
user.ConnectUserName = null;
@@ -593,7 +663,7 @@ namespace MediaBrowser.Server.Implementations.Connect
await _userManager.UpdateUser(user).ConfigureAwait(false);
- if (user.ConnectLinkType.HasValue && user.ConnectLinkType.Value == UserLinkType.Guest)
+ if (deleteUser)
{
_logger.Debug("Deleting guest user {0}", user.Name);
await _userManager.DeleteUser(user).ConfigureAwait(false);
diff --git a/MediaBrowser.Server.Implementations/Connect/Validator.cs b/MediaBrowser.Server.Implementations/Connect/Validator.cs
new file mode 100644
index 0000000000..b217da32ac
--- /dev/null
+++ b/MediaBrowser.Server.Implementations/Connect/Validator.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Server.Implementations.Connect
+{
+ public static class Validator
+ {
+ static Regex ValidEmailRegex = CreateValidEmailRegex();
+
+ ///
+ /// Taken from http://haacked.com/archive/2007/08/21/i-knew-how-to-validate-an-email-address-until-i.aspx
+ ///
+ ///
+ private static Regex CreateValidEmailRegex()
+ {
+ string validEmailPattern = @"^(?!\.)(""([^""\r\\]|\\[""\r\\])*""|"
+ + @"([-a-z0-9!#$%&'*+/=?^_`{|}~]|(?
- /// Resolves a path into a BaseItem
- ///
- /// The file info.
- /// The directory service.
- /// The parent.
- /// BaseItem.
- /// fileInfo
- public BaseItem ResolvePath(FileSystemInfo fileInfo, IDirectoryService directoryService, Folder parent = null)
+ public BaseItem ResolvePath(FileSystemInfo fileInfo, IDirectoryService directoryService, Folder parent = null, string collectionType = null)
{
if (fileInfo == null)
{
@@ -554,7 +546,8 @@ namespace MediaBrowser.Server.Implementations.Library
{
Parent = parent,
Path = fileInfo.FullName,
- FileInfo = fileInfo
+ FileInfo = fileInfo,
+ CollectionType = collectionType
};
// Return null if ignore rules deem that we should do so
@@ -622,15 +615,7 @@ namespace MediaBrowser.Server.Implementations.Library
return !args.ContainsFileSystemEntryByName(".ignore");
}
- ///
- /// Resolves a set of files into a list of BaseItem
- ///
- ///
- /// The files.
- /// The directory service.
- /// The parent.
- /// List{``0}.
- public List ResolvePaths(IEnumerable files, IDirectoryService directoryService, Folder parent)
+ public List ResolvePaths(IEnumerable files, IDirectoryService directoryService, Folder parent, string collectionType = null)
where T : BaseItem
{
var list = new List();
@@ -639,7 +624,7 @@ namespace MediaBrowser.Server.Implementations.Library
{
try
{
- var item = ResolvePath(f, directoryService, parent) as T;
+ var item = ResolvePath(f, directoryService, parent, collectionType) as T;
if (item != null)
{
@@ -1190,6 +1175,20 @@ namespace MediaBrowser.Server.Implementations.Library
return item;
}
+ public BaseItem GetMemoryItemById(Guid id)
+ {
+ if (id == Guid.Empty)
+ {
+ throw new ArgumentNullException("id");
+ }
+
+ BaseItem item;
+
+ LibraryItemsCache.TryGetValue(id, out item);
+
+ return item;
+ }
+
///
/// Gets the intros.
///
@@ -1497,14 +1496,10 @@ namespace MediaBrowser.Server.Implementations.Library
return null;
}
- var collectionTypes = _userManager.Users
- .Select(i => i.RootFolder)
- .Distinct()
- .SelectMany(i => i.Children)
+ var collectionTypes = GetUserRootFolder().Children
.OfType()
- .Where(i => string.Equals(i.Path, item.Path, StringComparison.OrdinalIgnoreCase) || i.PhysicalLocations.Contains(item.Path))
+ .Where(i => !string.IsNullOrEmpty(i.CollectionType) && (string.Equals(i.Path, item.Path, StringComparison.OrdinalIgnoreCase) || i.PhysicalLocations.Contains(item.Path)))
.Select(i => i.CollectionType)
- .Where(i => !string.IsNullOrEmpty(i))
.Distinct()
.ToList();
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
index 7f15dce2d1..231b807d8e 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
@@ -82,29 +82,29 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
{
if (string.Equals(collectionType, CollectionType.Trailers, StringComparison.OrdinalIgnoreCase))
{
- return FindMovie(args.Path, args.Parent, args.FileSystemChildren.ToList(), args.DirectoryService, false, false);
+ return FindMovie(args.Path, args.Parent, args.FileSystemChildren.ToList(), args.DirectoryService, false, false, collectionType);
}
if (string.Equals(collectionType, CollectionType.MusicVideos, StringComparison.OrdinalIgnoreCase))
{
- return FindMovie(args.Path, args.Parent, args.FileSystemChildren.ToList(), args.DirectoryService, false, false);
+ return FindMovie(args.Path, args.Parent, args.FileSystemChildren.ToList(), args.DirectoryService, false, false, collectionType);
}
if (string.Equals(collectionType, CollectionType.AdultVideos, StringComparison.OrdinalIgnoreCase))
{
- return FindMovie