update item list page

This commit is contained in:
Luke Pulverenti 2015-09-16 13:16:39 -04:00
parent a2c371ec60
commit 9ae7625d13
4 changed files with 158 additions and 10 deletions

View File

@ -98,6 +98,8 @@ namespace MediaBrowser.Controller.Entities
public bool? IsCurrentSchema { get; set; } public bool? IsCurrentSchema { get; set; }
public bool? HasDeadParentId { get; set; } public bool? HasDeadParentId { get; set; }
public bool? IsOffline { get; set; }
public LocationType? LocationType { get; set; }
public InternalItemsQuery() public InternalItemsQuery()
{ {

View File

@ -169,6 +169,13 @@ namespace MediaBrowser.Controller.Persistence
/// <param name="query">The query.</param> /// <param name="query">The query.</param>
/// <returns>List&lt;System.String&gt;.</returns> /// <returns>List&lt;System.String&gt;.</returns>
List<string> GetPeopleNames(InternalPeopleQuery query); 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);
} }
} }

View File

@ -1,15 +1,18 @@
using MediaBrowser.Common.Progress; using MediaBrowser.Common.IO;
using MediaBrowser.Common.Progress;
using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Common.ScheduledTasks;
using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.Persistence; using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging; using MediaBrowser.Model.Logging;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using MediaBrowser.Controller.Entities.Audio;
namespace MediaBrowser.Server.Implementations.Persistence namespace MediaBrowser.Server.Implementations.Persistence
{ {
@ -19,13 +22,15 @@ namespace MediaBrowser.Server.Implementations.Persistence
private readonly IItemRepository _itemRepo; private readonly IItemRepository _itemRepo;
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IServerConfigurationManager _config; 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; _libraryManager = libraryManager;
_itemRepo = itemRepo; _itemRepo = itemRepo;
_logger = logger; _logger = logger;
_config = config; _config = config;
_fileSystem = fileSystem;
} }
public string Name public string Name
@ -46,15 +51,18 @@ namespace MediaBrowser.Server.Implementations.Persistence
public async Task Execute(CancellationToken cancellationToken, IProgress<double> progress) public async Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
{ {
var innerProgress = new ActionableProgress<double>(); 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); await UpdateToLatestSchema(cancellationToken, innerProgress).ConfigureAwait(false);
innerProgress = new ActionableProgress<double>(); 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); 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); progress.Report(100);
} }
@ -153,11 +161,60 @@ namespace MediaBrowser.Server.Implementations.Persistence
progress.Report(100); 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() public IEnumerable<ITaskTrigger> GetDefaultTriggers()
{ {
return new ITaskTrigger[] return new ITaskTrigger[]
{ {
new IntervalTrigger{ Interval = TimeSpan.FromDays(1)} new IntervalTrigger{ Interval = TimeSpan.FromDays(7)}
}; };
} }
} }

View File

@ -72,7 +72,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
private IDbCommand _deletePeopleCommand; private IDbCommand _deletePeopleCommand;
private IDbCommand _savePersonCommand; private IDbCommand _savePersonCommand;
private const int LatestSchemaVersion = 6; private const int LatestSchemaVersion = 7;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="SqliteItemRepository"/> class. /// 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", "ForcedSortName", "Text");
_connection.AddColumn(_logger, "TypedBaseItems", "IsOffline", "BIT"); _connection.AddColumn(_logger, "TypedBaseItems", "IsOffline", "BIT");
_connection.AddColumn(_logger, "TypedBaseItems", "LocationType", "Text");
PrepareStatements(); PrepareStatements();
@ -245,7 +246,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
"DateCreated", "DateCreated",
"DateModified", "DateModified",
"ForcedSortName", "ForcedSortName",
"IsOffline" "IsOffline",
"LocationType"
}; };
_saveItemCommand = _connection.CreateCommand(); _saveItemCommand = _connection.CreateCommand();
_saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values ("; _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.ForcedSortName;
_saveItemCommand.GetParameter(index++).Value = item.IsOffline; _saveItemCommand.GetParameter(index++).Value = item.IsOffline;
_saveItemCommand.GetParameter(index++).Value = item.LocationType.ToString();
_saveItemCommand.Transaction = transaction; _saveItemCommand.Transaction = transaction;
@ -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) public QueryResult<Guid> GetItemIds(InternalItemsQuery query)
{ {
if (query == null) if (query == null)
@ -1028,6 +1100,16 @@ namespace MediaBrowser.Server.Implementations.Persistence
} }
cmd.Parameters.Add(cmd, "@SchemaVersion", DbType.Int32).Value = LatestSchemaVersion; 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) if (query.IsMovie.HasValue)
{ {
whereClauses.Add("IsMovie=@IsMovie"); whereClauses.Add("IsMovie=@IsMovie");