浏览代码

update item list page

Luke Pulverenti 9 年之前
父节点
当前提交
9ae7625d13

+ 3 - 1
MediaBrowser.Controller/Entities/InternalItemsQuery.cs

@@ -98,7 +98,9 @@ namespace MediaBrowser.Controller.Entities
 
         public bool? IsCurrentSchema { get; set; }
         public bool? HasDeadParentId { get; set; }
-    
+        public bool? IsOffline { get; set; }
+        public LocationType? LocationType { get; set; }
+
         public InternalItemsQuery()
         {
             Tags = new string[] { };

+ 7 - 0
MediaBrowser.Controller/Persistence/IItemRepository.cs

@@ -169,6 +169,13 @@ namespace MediaBrowser.Controller.Persistence
         /// <param name="query">The query.</param>
         /// <returns>List&lt;System.String&gt;.</returns>
         List<string> GetPeopleNames(InternalPeopleQuery query);
+
+        /// <summary>
+        /// Gets the item ids with path.
+        /// </summary>
+        /// <param name="query">The query.</param>
+        /// <returns>QueryResult&lt;Tuple&lt;Guid, System.String&gt;&gt;.</returns>
+        QueryResult<Tuple<Guid, string>> GetItemIdsWithPath(InternalItemsQuery query);
     }
 }
 

+ 63 - 6
MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs

@@ -1,15 +1,18 @@
-using MediaBrowser.Common.Progress;
+using MediaBrowser.Common.IO;
+using MediaBrowser.Common.Progress;
 using MediaBrowser.Common.ScheduledTasks;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.LiveTv;
 using MediaBrowser.Controller.Persistence;
+using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Logging;
 using System;
 using System.Collections.Generic;
 using System.Threading;
 using System.Threading.Tasks;
+using MediaBrowser.Controller.Entities.Audio;
 
 namespace MediaBrowser.Server.Implementations.Persistence
 {
@@ -19,13 +22,15 @@ namespace MediaBrowser.Server.Implementations.Persistence
         private readonly IItemRepository _itemRepo;
         private readonly ILogger _logger;
         private readonly IServerConfigurationManager _config;
+        private readonly IFileSystem _fileSystem;
 
-        public CleanDatabaseScheduledTask(ILibraryManager libraryManager, IItemRepository itemRepo, ILogger logger, IServerConfigurationManager config)
+        public CleanDatabaseScheduledTask(ILibraryManager libraryManager, IItemRepository itemRepo, ILogger logger, IServerConfigurationManager config, IFileSystem fileSystem)
         {
             _libraryManager = libraryManager;
             _itemRepo = itemRepo;
             _logger = logger;
             _config = config;
+            _fileSystem = fileSystem;
         }
 
         public string Name
@@ -46,15 +51,18 @@ namespace MediaBrowser.Server.Implementations.Persistence
         public async Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
         {
             var innerProgress = new ActionableProgress<double>();
-            innerProgress.RegisterAction(p => progress.Report(.95 * p));
+            innerProgress.RegisterAction(p => progress.Report(.4 * p));
 
             await UpdateToLatestSchema(cancellationToken, innerProgress).ConfigureAwait(false);
 
             innerProgress = new ActionableProgress<double>();
-            innerProgress.RegisterAction(p => progress.Report(95 + (.05 * p)));
-
+            innerProgress.RegisterAction(p => progress.Report(40 + (.05 * p)));
             await CleanDeadItems(cancellationToken, innerProgress).ConfigureAwait(false);
+            progress.Report(45);
 
+            innerProgress = new ActionableProgress<double>();
+            innerProgress.RegisterAction(p => progress.Report(45 + (.55 * p)));
+            await CleanDeletedItems(cancellationToken, innerProgress).ConfigureAwait(false);
             progress.Report(100);
         }
 
@@ -153,11 +161,60 @@ namespace MediaBrowser.Server.Implementations.Persistence
             progress.Report(100);
         }
 
+        private async Task CleanDeletedItems(CancellationToken cancellationToken, IProgress<double> progress)
+        {
+            var result = _itemRepo.GetItemIdsWithPath(new InternalItemsQuery
+            {
+                IsOffline = false,
+                LocationType = LocationType.FileSystem,
+                //Limit = limit,
+
+                // These have their own cleanup routines
+                ExcludeItemTypes = new[] { typeof(Person).Name, typeof(Genre).Name, typeof(MusicGenre).Name, typeof(GameGenre).Name, typeof(Studio).Name, typeof(Year).Name }
+            });
+
+            var numComplete = 0;
+            var numItems = result.Items.Length;
+
+            foreach (var item in result.Items)
+            {
+                cancellationToken.ThrowIfCancellationRequested();
+
+                var path = item.Item2;
+
+                try
+                {
+                    if (!_fileSystem.FileExists(path) && !_fileSystem.DirectoryExists(path))
+                    {
+                        var libraryItem = _libraryManager.GetItemById(item.Item1);
+
+                        await _libraryManager.DeleteItem(libraryItem, new DeleteOptions
+                        {
+                            DeleteFileLocation = false
+                        });
+                    }
+                }
+                catch (OperationCanceledException)
+                {
+                    throw;
+                }
+                catch (Exception ex)
+                {
+                    _logger.ErrorException("Error in CleanDeletedItems. File {0}", ex, path);
+                }
+
+                numComplete++;
+                double percent = numComplete;
+                percent /= numItems;
+                progress.Report(percent * 100);
+            }
+        }
+
         public IEnumerable<ITaskTrigger> GetDefaultTriggers()
         {
             return new ITaskTrigger[] 
             { 
-                new IntervalTrigger{ Interval = TimeSpan.FromDays(1)}
+                new IntervalTrigger{ Interval = TimeSpan.FromDays(7)}
             };
         }
     }

+ 85 - 3
MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs

@@ -72,7 +72,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
         private IDbCommand _deletePeopleCommand;
         private IDbCommand _savePersonCommand;
 
-        private const int LatestSchemaVersion = 6;
+        private const int LatestSchemaVersion = 7;
 
         /// <summary>
         /// Initializes a new instance of the <see cref="SqliteItemRepository"/> class.
@@ -175,6 +175,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
 
             _connection.AddColumn(_logger, "TypedBaseItems", "ForcedSortName", "Text");
             _connection.AddColumn(_logger, "TypedBaseItems", "IsOffline", "BIT");
+            _connection.AddColumn(_logger, "TypedBaseItems", "LocationType", "Text");
 
             PrepareStatements();
 
@@ -245,7 +246,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
                 "DateCreated",
                 "DateModified",
                 "ForcedSortName",
-                "IsOffline"
+                "IsOffline",
+                "LocationType"
             };
             _saveItemCommand = _connection.CreateCommand();
             _saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values (";
@@ -415,6 +417,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
 
                     _saveItemCommand.GetParameter(index++).Value = item.ForcedSortName;
                     _saveItemCommand.GetParameter(index++).Value = item.IsOffline;
+                    _saveItemCommand.GetParameter(index++).Value = item.LocationType.ToString();
 
                     _saveItemCommand.Transaction = transaction;
 
@@ -617,7 +620,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
         /// <returns>Task.</returns>
         public Task SaveCriticReviews(Guid itemId, IEnumerable<ItemReview> criticReviews)
         {
-			Directory.CreateDirectory(_criticReviewsPath);
+            Directory.CreateDirectory(_criticReviewsPath);
 
             var path = Path.Combine(_criticReviewsPath, itemId + ".json");
 
@@ -950,6 +953,75 @@ namespace MediaBrowser.Server.Implementations.Persistence
             }
         }
 
+        public QueryResult<Tuple<Guid, string>> GetItemIdsWithPath(InternalItemsQuery query)
+        {
+            if (query == null)
+            {
+                throw new ArgumentNullException("query");
+            }
+
+            CheckDisposed();
+
+            using (var cmd = _connection.CreateCommand())
+            {
+                cmd.CommandText = "select guid,path from TypedBaseItems";
+
+                var whereClauses = GetWhereClauses(query, cmd, false);
+
+                var whereTextWithoutPaging = whereClauses.Count == 0 ?
+                    string.Empty :
+                    " where " + string.Join(" AND ", whereClauses.ToArray());
+
+                whereClauses = GetWhereClauses(query, cmd, true);
+
+                var whereText = whereClauses.Count == 0 ?
+                    string.Empty :
+                    " where " + string.Join(" AND ", whereClauses.ToArray());
+
+                cmd.CommandText += whereText;
+
+                cmd.CommandText += GetOrderByText(query);
+
+                if (query.Limit.HasValue)
+                {
+                    cmd.CommandText += " LIMIT " + query.Limit.Value.ToString(CultureInfo.InvariantCulture);
+                }
+
+                cmd.CommandText += "; select count (guid) from TypedBaseItems" + whereTextWithoutPaging;
+
+                var list = new List<Tuple<Guid, string>>();
+                var count = 0;
+
+                _logger.Debug(cmd.CommandText);
+
+                using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess))
+                {
+                    while (reader.Read())
+                    {
+                        var id = reader.GetGuid(0);
+                        string path = null;
+
+                        if (!reader.IsDBNull(1))
+                        {
+                            path = reader.GetString(1);
+                        }
+                        list.Add(new Tuple<Guid, string>(id, path));
+                    }
+
+                    if (reader.NextResult() && reader.Read())
+                    {
+                        count = reader.GetInt32(0);
+                    }
+                }
+
+                return new QueryResult<Tuple<Guid, string>>()
+                {
+                    Items = list.ToArray(),
+                    TotalRecordCount = count
+                };
+            }
+        }
+
         public QueryResult<Guid> GetItemIds(InternalItemsQuery query)
         {
             if (query == null)
@@ -1028,6 +1100,16 @@ namespace MediaBrowser.Server.Implementations.Persistence
                 }
                 cmd.Parameters.Add(cmd, "@SchemaVersion", DbType.Int32).Value = LatestSchemaVersion;
             }
+            if (query.IsOffline.HasValue)
+            {
+                whereClauses.Add("IsOffline=@IsOffline");
+                cmd.Parameters.Add(cmd, "@IsOffline", DbType.Boolean).Value = query.IsOffline;
+            }
+            if (query.LocationType.HasValue)
+            {
+                whereClauses.Add("LocationType=@LocationType");
+                cmd.Parameters.Add(cmd, "@LocationType", DbType.String).Value = query.LocationType.Value;
+            }
             if (query.IsMovie.HasValue)
             {
                 whereClauses.Add("IsMovie=@IsMovie");