Browse Source

Merge pull request #2144 from MediaBrowser/dev

Dev
Luke 8 years ago
parent
commit
5c021eb7d9

+ 82 - 1
MediaBrowser.Api/LiveTv/LiveTvService.cs

@@ -157,6 +157,8 @@ namespace MediaBrowser.Api.LiveTv
 
         public bool? IsMovie { get; set; }
         public bool? IsSeries { get; set; }
+        public bool? IsKids { get; set; }
+        public bool? IsSports { get; set; }
 
         public GetRecordings()
         {
@@ -164,6 +166,61 @@ namespace MediaBrowser.Api.LiveTv
         }
     }
 
+    [Route("/LiveTv/Recordings/Series", "GET", Summary = "Gets live tv recordings")]
+    [Authenticated]
+    public class GetRecordingSeries : IReturn<QueryResult<BaseItemDto>>, IHasDtoOptions
+    {
+        [ApiMember(Name = "ChannelId", Description = "Optional filter by channel id.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
+        public string ChannelId { get; set; }
+
+        [ApiMember(Name = "UserId", Description = "Optional filter by user and attach user data.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
+        public string UserId { get; set; }
+
+        [ApiMember(Name = "GroupId", Description = "Optional filter by recording group.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
+        public string GroupId { get; set; }
+
+        [ApiMember(Name = "StartIndex", Description = "Optional. The record index to start at. All items with a lower index will be dropped from the results.", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
+        public int? StartIndex { get; set; }
+
+        [ApiMember(Name = "Limit", Description = "Optional. The maximum number of records to return", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
+        public int? Limit { get; set; }
+
+        [ApiMember(Name = "Status", Description = "Optional filter by recording status.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
+        public RecordingStatus? Status { get; set; }
+
+        [ApiMember(Name = "Status", Description = "Optional filter by recordings that are in progress, or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
+        public bool? IsInProgress { get; set; }
+
+        [ApiMember(Name = "SeriesTimerId", Description = "Optional filter by recordings belonging to a series timer", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
+        public string SeriesTimerId { get; set; }
+
+        [ApiMember(Name = "EnableImages", Description = "Optional, include image information in output", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")]
+        public bool? EnableImages { get; set; }
+
+        [ApiMember(Name = "ImageTypeLimit", Description = "Optional, the max number of images to return, per image type", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
+        public int? ImageTypeLimit { get; set; }
+
+        [ApiMember(Name = "EnableImageTypes", Description = "Optional. The image types to include in the output.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
+        public string EnableImageTypes { get; set; }
+
+        /// <summary>
+        /// Fields to return within the items, in addition to basic information
+        /// </summary>
+        /// <value>The fields.</value>
+        [ApiMember(Name = "Fields", Description = "Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: Budget, Chapters, CriticRatingSummary, DateCreated, Genres, HomePageUrl, IndexOptions, MediaStreams, Overview, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
+        public string Fields { get; set; }
+
+        public bool EnableTotalRecordCount { get; set; }
+
+        [ApiMember(Name = "EnableUserData", Description = "Optional, include user data", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")]
+        public bool? EnableUserData { get; set; }
+
+        public GetRecordingSeries()
+        {
+            EnableTotalRecordCount = true;
+        }
+    }
+
     [Route("/LiveTv/Recordings/Groups", "GET", Summary = "Gets live tv recording groups")]
     [Authenticated]
     public class GetRecordingGroups : IReturn<QueryResult<BaseItemDto>>
@@ -862,7 +919,31 @@ namespace MediaBrowser.Api.LiveTv
                 IsInProgress = request.IsInProgress,
                 EnableTotalRecordCount = request.EnableTotalRecordCount,
                 IsMovie = request.IsMovie,
-                IsSeries = request.IsSeries
+                IsSeries = request.IsSeries,
+                IsKids = request.IsKids,
+                IsSports = request.IsSports
+
+            }, options, CancellationToken.None).ConfigureAwait(false);
+
+            return ToOptimizedResult(result);
+        }
+
+        public async Task<object> Get(GetRecordingSeries request)
+        {
+            var options = GetDtoOptions(request);
+            options.DeviceId = AuthorizationContext.GetAuthorizationInfo(Request).DeviceId;
+
+            var result = await _liveTvManager.GetRecordingSeries(new RecordingQuery
+            {
+                ChannelId = request.ChannelId,
+                UserId = request.UserId,
+                GroupId = request.GroupId,
+                StartIndex = request.StartIndex,
+                Limit = request.Limit,
+                Status = request.Status,
+                SeriesTimerId = request.SeriesTimerId,
+                IsInProgress = request.IsInProgress,
+                EnableTotalRecordCount = request.EnableTotalRecordCount
 
             }, options, CancellationToken.None).ConfigureAwait(false);
 

+ 3 - 0
MediaBrowser.Controller/Library/ILibraryManager.cs

@@ -566,5 +566,8 @@ namespace MediaBrowser.Controller.Library
         QueryResult<Tuple<BaseItem, ItemCounts>> GetArtists(InternalItemsQuery query);
         QueryResult<Tuple<BaseItem, ItemCounts>> GetAlbumArtists(InternalItemsQuery query);
         QueryResult<Tuple<BaseItem, ItemCounts>> GetAllArtists(InternalItemsQuery query);
+
+        void RegisterIgnoredPath(string path);
+        void UnRegisterIgnoredPath(string path);
     }
 }

+ 1 - 0
MediaBrowser.Controller/LiveTv/ILiveTvManager.cs

@@ -108,6 +108,7 @@ namespace MediaBrowser.Controller.LiveTv
         /// <param name="cancellationToken">The cancellation token.</param>
         /// <returns>QueryResult{RecordingInfoDto}.</returns>
         Task<QueryResult<BaseItemDto>> GetRecordings(RecordingQuery query, DtoOptions options, CancellationToken cancellationToken);
+        Task<QueryResult<BaseItemDto>> GetRecordingSeries(RecordingQuery query, DtoOptions options, CancellationToken cancellationToken);
 
         /// <summary>
         /// Gets the timers.

+ 2 - 0
MediaBrowser.Model/LiveTv/RecordingQuery.cs

@@ -70,6 +70,8 @@ namespace MediaBrowser.Model.LiveTv
         public bool? EnableImages { get; set; }
         public bool? IsMovie { get; set; }
         public bool? IsSeries { get; set; }
+        public bool? IsKids { get; set; }
+        public bool? IsSports { get; set; }
         public int? ImageTypeLimit { get; set; }
         public ImageType[] EnableImageTypes { get; set; }
 

+ 1 - 5
MediaBrowser.Server.Implementations/EntryPoints/UsageEntryPoint.cs

@@ -92,11 +92,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
                 DeviceId = session.DeviceId
             };
 
-            // Report usage to remote server, except for web client, since we already have data on that
-            if (!string.Equals(info.AppName, "Dashboard", StringComparison.OrdinalIgnoreCase))
-            {
-                ReportNewSession(info);
-            }
+            ReportNewSession(info);
 
             return info;
         }

+ 11 - 2
MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs

@@ -46,6 +46,14 @@ namespace MediaBrowser.Server.Implementations.IO
             "TempSBE"
         };
 
+        private readonly IReadOnlyList<string> _alwaysIgnoreSubstrings = new List<string>
+        {
+            // Synology
+            "@eaDir",
+            ".wd_tv",
+            ".actors"
+        };
+
         private readonly IReadOnlyList<string> _alwaysIgnoreExtensions = new List<string>
         {
             // thumbs.db
@@ -421,10 +429,11 @@ namespace MediaBrowser.Server.Implementations.IO
             }
 
             var filename = Path.GetFileName(path);
-
+            
             var monitorPath = !string.IsNullOrEmpty(filename) &&
                 !_alwaysIgnoreFiles.Contains(filename, StringComparer.OrdinalIgnoreCase) &&
-                !_alwaysIgnoreExtensions.Contains(Path.GetExtension(path) ?? string.Empty, StringComparer.OrdinalIgnoreCase);
+                !_alwaysIgnoreExtensions.Contains(Path.GetExtension(path) ?? string.Empty, StringComparer.OrdinalIgnoreCase) &&
+                _alwaysIgnoreSubstrings.All(i => path.IndexOf(i, StringComparison.OrdinalIgnoreCase) == -1);
 
             // Ignore certain files
             var tempIgnorePaths = _tempIgnoredPaths.Keys.ToList();

+ 30 - 1
MediaBrowser.Server.Implementations/Library/LibraryManager.cs

@@ -621,9 +621,38 @@ namespace MediaBrowser.Server.Implementations.Library
             return ResolveItem(args, resolvers);
         }
 
+        private readonly List<string> _ignoredPaths = new List<string>();
+
+        public void RegisterIgnoredPath(string path)
+        {
+            lock (_ignoredPaths)
+            {
+                _ignoredPaths.Add(path);
+            }
+        }
+        public void UnRegisterIgnoredPath(string path)
+        {
+            lock (_ignoredPaths)
+            {
+                _ignoredPaths.Remove(path);
+            }
+        }
+
         public bool IgnoreFile(FileSystemMetadata file, BaseItem parent)
         {
-            return EntityResolutionIgnoreRules.Any(r => r.ShouldIgnore(file, parent));
+            if (EntityResolutionIgnoreRules.Any(r => r.ShouldIgnore(file, parent)))
+            {
+                return true;
+            }
+
+            //lock (_ignoredPaths)
+            {
+                if (_ignoredPaths.Contains(file.FullName, StringComparer.OrdinalIgnoreCase))
+                {
+                    return true;
+                }
+            }
+            return false;
         }
 
         public IEnumerable<FileSystemMetadata> NormalizeRootPathList(IEnumerable<FileSystemMetadata> paths)

+ 2 - 0
MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs

@@ -993,6 +993,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
                 recordPath = recorder.GetOutputPath(mediaStreamInfo, recordPath);
                 recordPath = EnsureFileUnique(recordPath, timer.Id);
 
+                _libraryManager.RegisterIgnoredPath(recordPath);
                 _libraryMonitor.ReportFileSystemChangeBeginning(recordPath);
                 _fileSystem.CreateDirectory(Path.GetDirectoryName(recordPath));
                 activeRecordingInfo.Path = recordPath;
@@ -1044,6 +1045,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
                     semaphore.Release();
                 }
 
+                _libraryManager.UnRegisterIgnoredPath(recordPath);
                 _libraryMonitor.ReportFileSystemChangeComplete(recordPath, true);
 
                 ActiveRecordingInfo removed;

+ 90 - 1
MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs

@@ -1430,6 +1430,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
 
             var includeItemTypes = new List<string>();
             var excludeItemTypes = new List<string>();
+            var genres = new List<string>();
 
             if (query.IsMovie.HasValue)
             {
@@ -1453,6 +1454,22 @@ namespace MediaBrowser.Server.Implementations.LiveTv
                     excludeItemTypes.Add(typeof(Episode).Name);
                 }
             }
+            if (query.IsSports.HasValue)
+            {
+                if (query.IsSports.Value)
+                {
+                    genres.Add("Sports");
+                }
+            }
+            if (query.IsKids.HasValue)
+            {
+                if (query.IsKids.Value)
+                {
+                    genres.Add("Kids");
+                    genres.Add("Children");
+                    genres.Add("Family");
+                }
+            }
 
             return _libraryManager.GetItemsResult(new InternalItemsQuery(user)
             {
@@ -1461,13 +1478,73 @@ namespace MediaBrowser.Server.Implementations.LiveTv
                 AncestorIds = folders.Select(i => i.Id.ToString("N")).ToArray(),
                 IsFolder = false,
                 ExcludeLocationTypes = new[] { LocationType.Virtual },
-                Limit = Math.Min(200, query.Limit ?? int.MaxValue),
+                Limit = query.Limit,
+                SortBy = new[] { ItemSortBy.DateCreated },
+                SortOrder = SortOrder.Descending,
+                EnableTotalRecordCount = query.EnableTotalRecordCount,
+                IncludeItemTypes = includeItemTypes.ToArray(),
+                ExcludeItemTypes = excludeItemTypes.ToArray(),
+                Genres = genres.ToArray()
+            });
+        }
+
+        public async Task<QueryResult<BaseItemDto>> GetRecordingSeries(RecordingQuery query, DtoOptions options, CancellationToken cancellationToken)
+        {
+            var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId);
+            if (user != null && !IsLiveTvEnabled(user))
+            {
+                return new QueryResult<BaseItemDto>();
+            }
+
+            if (_services.Count > 1)
+            {
+                return new QueryResult<BaseItemDto>();
+            }
+
+            if (user == null || (query.IsInProgress ?? false))
+            {
+                return new QueryResult<BaseItemDto>();
+            }
+
+            var folders = EmbyTV.EmbyTV.Current.GetRecordingFolders()
+                .SelectMany(i => i.Locations)
+                .Distinct(StringComparer.OrdinalIgnoreCase)
+                .Select(i => _libraryManager.FindByPath(i, true))
+                .Where(i => i != null)
+                .Where(i => i.IsVisibleStandalone(user))
+                .ToList();
+
+            if (folders.Count == 0)
+            {
+                return new QueryResult<BaseItemDto>();
+            }
+
+            var includeItemTypes = new List<string>();
+            var excludeItemTypes = new List<string>();
+
+            includeItemTypes.Add(typeof(Series).Name);
+
+            var internalResult = _libraryManager.GetItemsResult(new InternalItemsQuery(user)
+            {
+                Recursive = true,
+                AncestorIds = folders.Select(i => i.Id.ToString("N")).ToArray(),
+                Limit = query.Limit,
                 SortBy = new[] { ItemSortBy.DateCreated },
                 SortOrder = SortOrder.Descending,
                 EnableTotalRecordCount = query.EnableTotalRecordCount,
                 IncludeItemTypes = includeItemTypes.ToArray(),
                 ExcludeItemTypes = excludeItemTypes.ToArray()
             });
+
+            RemoveFields(options);
+
+            var returnArray = (await _dtoService.GetBaseItemDtos(internalResult.Items, options, user).ConfigureAwait(false)).ToArray();
+
+            return new QueryResult<BaseItemDto>
+            {
+                Items = returnArray,
+                TotalRecordCount = internalResult.TotalRecordCount
+            };
         }
 
         public async Task<QueryResult<BaseItem>> GetInternalRecordings(RecordingQuery query, CancellationToken cancellationToken)
@@ -1537,6 +1614,18 @@ namespace MediaBrowser.Server.Implementations.LiveTv
                 recordings = recordings.Where(i => i.IsSeries == val);
             }
 
+            if (query.IsKids.HasValue)
+            {
+                var val = query.IsKids.Value;
+                recordings = recordings.Where(i => i.IsKids == val);
+            }
+
+            if (query.IsSports.HasValue)
+            {
+                var val = query.IsSports.Value;
+                recordings = recordings.Where(i => i.IsSports == val);
+            }
+
             if (!string.IsNullOrEmpty(query.SeriesTimerId))
             {
                 var guid = new Guid(query.SeriesTimerId);

+ 0 - 6
MediaBrowser.Server.Startup.Common/Migrations/UpdateLevelMigration.cs

@@ -42,12 +42,6 @@ namespace MediaBrowser.Server.Startup.Common.Migrations
             {
                 var updateLevel = _config.Configuration.SystemUpdateLevel;
 
-                if (updateLevel == PackageVersionClass.Dev)
-                {
-                    // It's already dev, there's nothing to check
-                    return;
-                }
-
                 await CheckVersion(currentVersion, updateLevel, CancellationToken.None).ConfigureAwait(false);
             }
             catch

+ 1 - 1
MediaBrowser.ServerApplication/Native/WindowsApp.cs

@@ -240,9 +240,9 @@ namespace MediaBrowser.ServerApplication.Native
                 {
                     var data = process.StandardOutput.ReadToEnd() ?? string.Empty;
 
-                    //_logger.Debug("Found windows firewall rule: " + data);
                     if (data.IndexOf("Block", StringComparison.OrdinalIgnoreCase) != -1)
                     {
+                        _logger.Info("Found windows firewall rule: " + data);
                         return Confirm();
                     }