update series queries

pull/702/head
Luke Pulverenti 8 years ago
parent bff0cd4447
commit e1b880a5a0

@ -84,9 +84,6 @@ namespace Emby.Server.Implementations.Activity
{ {
using (var connection = CreateConnection(true)) using (var connection = CreateConnection(true))
{ {
var list = new List<ActivityLogEntry>();
var result = new QueryResult<ActivityLogEntry>();
var commandText = BaseActivitySelectText; var commandText = BaseActivitySelectText;
var whereClauses = new List<string>(); var whereClauses = new List<string>();
@ -127,8 +124,11 @@ namespace Emby.Server.Implementations.Activity
statementTexts.Add(commandText); statementTexts.Add(commandText);
statementTexts.Add("select count (Id) from ActivityLogEntries" + whereTextWithoutPaging); statementTexts.Add("select count (Id) from ActivityLogEntries" + whereTextWithoutPaging);
connection.RunInTransaction(db => return connection.RunInTransaction(db =>
{ {
var list = new List<ActivityLogEntry>();
var result = new QueryResult<ActivityLogEntry>();
var statements = PrepareAllSafe(db, string.Join(";", statementTexts.ToArray())).ToList(); var statements = PrepareAllSafe(db, string.Join(";", statementTexts.ToArray())).ToList();
using (var statement = statements[0]) using (var statement = statements[0])
@ -153,10 +153,11 @@ namespace Emby.Server.Implementations.Activity
result.TotalRecordCount = statement.ExecuteQuery().SelectScalarInt().First(); result.TotalRecordCount = statement.ExecuteQuery().SelectScalarInt().First();
} }
}, ReadTransactionMode);
result.Items = list.ToArray(); result.Items = list.ToArray();
return result; return result;
}, ReadTransactionMode);
} }
} }
} }

@ -43,6 +43,7 @@ namespace Emby.Server.Implementations.Data
//CheckOk(rc); //CheckOk(rc);
rc = raw.sqlite3_config(raw.SQLITE_CONFIG_MULTITHREAD, 1); rc = raw.sqlite3_config(raw.SQLITE_CONFIG_MULTITHREAD, 1);
//rc = raw.sqlite3_config(raw.SQLITE_CONFIG_SERIALIZED, 1);
//CheckOk(rc); //CheckOk(rc);
rc = raw.sqlite3_enable_shared_cache(1); rc = raw.sqlite3_enable_shared_cache(1);
@ -94,6 +95,7 @@ namespace Emby.Server.Implementations.Data
var queries = new List<string> var queries = new List<string>
{ {
//"PRAGMA cache size=-10000" //"PRAGMA cache size=-10000"
//"PRAGMA read_uncommitted = true"
}; };
if (EnableTempStoreMemory) if (EnableTempStoreMemory)

@ -328,6 +328,8 @@ namespace Emby.Server.Implementations.Data
"drop table if exists Images", "drop table if exists Images",
"drop index if exists idx_Images", "drop index if exists idx_Images",
"drop index if exists idx_TypeSeriesPresentationUniqueKey", "drop index if exists idx_TypeSeriesPresentationUniqueKey",
"drop index if exists idx_SeriesPresentationUniqueKey",
"drop index if exists idx_TypeSeriesPresentationUniqueKey2",
"create index if not exists idx_PathTypedBaseItems on TypedBaseItems(Path)", "create index if not exists idx_PathTypedBaseItems on TypedBaseItems(Path)",
"create index if not exists idx_ParentIdTypedBaseItems on TypedBaseItems(ParentId)", "create index if not exists idx_ParentIdTypedBaseItems on TypedBaseItems(ParentId)",
@ -343,8 +345,9 @@ namespace Emby.Server.Implementations.Data
// series // series
"create index if not exists idx_TypeSeriesPresentationUniqueKey1 on TypedBaseItems(Type,SeriesPresentationUniqueKey,PresentationUniqueKey,SortName)", "create index if not exists idx_TypeSeriesPresentationUniqueKey1 on TypedBaseItems(Type,SeriesPresentationUniqueKey,PresentationUniqueKey,SortName)",
// series next up // series counts
"create index if not exists idx_SeriesPresentationUniqueKey on TypedBaseItems(SeriesPresentationUniqueKey)", // seriesdateplayed sort order
"create index if not exists idx_TypeSeriesPresentationUniqueKey3 on TypedBaseItems(SeriesPresentationUniqueKey,Type,IsFolder,IsVirtualItem)",
// live tv programs // live tv programs
"create index if not exists idx_TypeTopParentIdStartDate on TypedBaseItems(Type,TopParentId,StartDate)", "create index if not exists idx_TypeTopParentIdStartDate on TypedBaseItems(Type,TopParentId,StartDate)",
@ -2079,13 +2082,15 @@ namespace Emby.Server.Implementations.Data
throw new ArgumentNullException("id"); throw new ArgumentNullException("id");
} }
var list = new List<ChapterInfo>();
using (WriteLock.Read()) using (WriteLock.Read())
{ {
using (var connection = CreateConnection(true)) using (var connection = CreateConnection(true))
{ {
using (var statement = PrepareStatementSafe(connection, "select StartPositionTicks,Name,ImagePath,ImageDateModified from " + ChaptersTableName + " where ItemId = @ItemId order by ChapterIndex asc")) return connection.RunInTransaction(db =>
{
var list = new List<ChapterInfo>();
using (var statement = PrepareStatementSafe(db, "select StartPositionTicks,Name,ImagePath,ImageDateModified from " + ChaptersTableName + " where ItemId = @ItemId order by ChapterIndex asc"))
{ {
statement.TryBind("@ItemId", id); statement.TryBind("@ItemId", id);
@ -2094,10 +2099,12 @@ namespace Emby.Server.Implementations.Data
list.Add(GetChapter(row)); list.Add(GetChapter(row));
} }
} }
}
}
return list; return list;
}, ReadTransactionMode);
}
}
} }
/// <summary> /// <summary>
@ -2470,13 +2477,13 @@ namespace Emby.Server.Implementations.Data
//commandText += GetGroupBy(query); //commandText += GetGroupBy(query);
int count = 0;
using (WriteLock.Read()) using (WriteLock.Read())
{ {
using (var connection = CreateConnection(true)) using (var connection = CreateConnection(true))
{ {
using (var statement = PrepareStatementSafe(connection, commandText)) return connection.RunInTransaction(db =>
{
using (var statement = PrepareStatementSafe(db, commandText))
{ {
if (EnableJoinUserData(query)) if (EnableJoinUserData(query))
{ {
@ -2488,14 +2495,15 @@ namespace Emby.Server.Implementations.Data
// Running this again will bind the params // Running this again will bind the params
GetWhereClauses(query, statement); GetWhereClauses(query, statement);
count = statement.ExecuteQuery().SelectScalarInt().First(); var count = statement.ExecuteQuery().SelectScalarInt().First();
} LogQueryTime("GetCount", commandText, now);
return count;
} }
LogQueryTime("GetCount", commandText, now); }, ReadTransactionMode);
} }
return count; }
} }
public List<BaseItem> GetItemList(InternalItemsQuery query) public List<BaseItem> GetItemList(InternalItemsQuery query)
@ -2511,8 +2519,6 @@ namespace Emby.Server.Implementations.Data
var now = DateTime.UtcNow; var now = DateTime.UtcNow;
var list = new List<BaseItem>();
// Hack for right now since we currently don't support filtering out these duplicates within a query // Hack for right now since we currently don't support filtering out these duplicates within a query
if (query.Limit.HasValue && query.EnableGroupByMetadataKey) if (query.Limit.HasValue && query.EnableGroupByMetadataKey)
{ {
@ -2553,7 +2559,11 @@ namespace Emby.Server.Implementations.Data
{ {
using (var connection = CreateConnection(true)) using (var connection = CreateConnection(true))
{ {
using (var statement = PrepareStatementSafe(connection, commandText)) return connection.RunInTransaction(db =>
{
var list = new List<BaseItem>();
using (var statement = PrepareStatementSafe(db, commandText))
{ {
if (EnableJoinUserData(query)) if (EnableJoinUserData(query))
{ {
@ -2574,10 +2584,6 @@ namespace Emby.Server.Implementations.Data
} }
} }
} }
}
LogQueryTime("GetItemList", commandText, now);
}
// Hack for right now since we currently don't support filtering out these duplicates within a query // Hack for right now since we currently don't support filtering out these duplicates within a query
if (query.EnableGroupByMetadataKey) if (query.EnableGroupByMetadataKey)
@ -2599,7 +2605,13 @@ namespace Emby.Server.Implementations.Data
list = newList; list = newList;
} }
LogQueryTime("GetItemList", commandText, now);
return list; return list;
}, ReadTransactionMode);
}
}
} }
private void AddItem(List<BaseItem> items, BaseItem newItem) private void AddItem(List<BaseItem> items, BaseItem newItem)
@ -2637,7 +2649,7 @@ namespace Emby.Server.Implementations.Data
var slowThreshold = 1000; var slowThreshold = 1000;
#if DEBUG #if DEBUG
slowThreshold = 50; slowThreshold = 2;
#endif #endif
if (elapsed >= slowThreshold) if (elapsed >= slowThreshold)
@ -2718,7 +2730,6 @@ namespace Emby.Server.Implementations.Data
} }
} }
var result = new QueryResult<BaseItem>();
var isReturningZeroItems = query.Limit.HasValue && query.Limit <= 0; var isReturningZeroItems = query.Limit.HasValue && query.Limit <= 0;
var statementTexts = new List<string>(); var statementTexts = new List<string>();
@ -2748,8 +2759,9 @@ namespace Emby.Server.Implementations.Data
{ {
using (var connection = CreateConnection(true)) using (var connection = CreateConnection(true))
{ {
connection.RunInTransaction(db => return connection.RunInTransaction(db =>
{ {
var result = new QueryResult<BaseItem>();
var statements = PrepareAllSafe(db, string.Join(";", statementTexts.ToArray())) var statements = PrepareAllSafe(db, string.Join(";", statementTexts.ToArray()))
.ToList(); .ToList();
@ -2796,12 +2808,12 @@ namespace Emby.Server.Implementations.Data
} }
} }
}, ReadTransactionMode);
LogQueryTime("GetItems", commandText, now); LogQueryTime("GetItems", commandText, now);
result.Items = list.ToArray(); result.Items = list.ToArray();
return result; return result;
}, ReadTransactionMode);
} }
} }
} }
@ -2962,13 +2974,15 @@ namespace Emby.Server.Implementations.Data
} }
} }
var list = new List<Guid>();
using (WriteLock.Read()) using (WriteLock.Read())
{ {
using (var connection = CreateConnection(true)) using (var connection = CreateConnection(true))
{ {
using (var statement = PrepareStatementSafe(connection, commandText)) return connection.RunInTransaction(db =>
{
var list = new List<Guid>();
using (var statement = PrepareStatementSafe(db, commandText))
{ {
if (EnableJoinUserData(query)) if (EnableJoinUserData(query))
{ {
@ -2985,11 +2999,13 @@ namespace Emby.Server.Implementations.Data
list.Add(row[0].ReadGuid()); list.Add(row[0].ReadGuid());
} }
} }
}
LogQueryTime("GetItemList", commandText, now); LogQueryTime("GetItemList", commandText, now);
return list; return list;
}, ReadTransactionMode);
}
} }
} }
@ -3152,11 +3168,11 @@ namespace Emby.Server.Implementations.Data
using (WriteLock.Read()) using (WriteLock.Read())
{ {
using (var connection = CreateConnection(true)) using (var connection = CreateConnection(true))
{
return connection.RunInTransaction(db =>
{ {
var result = new QueryResult<Guid>(); var result = new QueryResult<Guid>();
connection.RunInTransaction(db =>
{
var statements = PrepareAllSafe(db, string.Join(";", statementTexts.ToArray())) var statements = PrepareAllSafe(db, string.Join(";", statementTexts.ToArray()))
.ToList(); .ToList();
@ -3199,12 +3215,12 @@ namespace Emby.Server.Implementations.Data
} }
} }
}, ReadTransactionMode);
LogQueryTime("GetItemIds", commandText, now); LogQueryTime("GetItemIds", commandText, now);
result.Items = list.ToArray(); result.Items = list.ToArray();
return result; return result;
}, ReadTransactionMode);
} }
} }
} }
@ -4653,13 +4669,13 @@ namespace Emby.Server.Implementations.Data
commandText += " order by ListOrder"; commandText += " order by ListOrder";
var list = new List<string>();
using (WriteLock.Read()) using (WriteLock.Read())
{ {
using (var connection = CreateConnection(true)) using (var connection = CreateConnection(true))
{ {
connection.RunInTransaction(db => return connection.RunInTransaction(db =>
{ {
var list = new List<string>();
using (var statement = PrepareStatementSafe(db, commandText)) using (var statement = PrepareStatementSafe(db, commandText))
{ {
// Run this again to bind the params // Run this again to bind the params
@ -4670,9 +4686,9 @@ namespace Emby.Server.Implementations.Data
list.Add(row.GetString(0)); list.Add(row.GetString(0));
} }
} }
return list;
}, ReadTransactionMode); }, ReadTransactionMode);
} }
return list;
} }
} }
@ -4696,14 +4712,14 @@ namespace Emby.Server.Implementations.Data
commandText += " order by ListOrder"; commandText += " order by ListOrder";
var list = new List<PersonInfo>();
using (WriteLock.Read()) using (WriteLock.Read())
{ {
using (var connection = CreateConnection(true)) using (var connection = CreateConnection(true))
{ {
connection.RunInTransaction(db => return connection.RunInTransaction(db =>
{ {
var list = new List<PersonInfo>();
using (var statement = PrepareStatementSafe(db, commandText)) using (var statement = PrepareStatementSafe(db, commandText))
{ {
// Run this again to bind the params // Run this again to bind the params
@ -4714,11 +4730,11 @@ namespace Emby.Server.Implementations.Data
list.Add(GetPerson(row)); list.Add(GetPerson(row));
} }
} }
return list;
}, ReadTransactionMode); }, ReadTransactionMode);
} }
} }
return list;
} }
private List<string> GetPeopleWhereClauses(InternalPeopleQuery query, IStatement statement) private List<string> GetPeopleWhereClauses(InternalPeopleQuery query, IStatement statement)
@ -4899,8 +4915,6 @@ namespace Emby.Server.Implementations.Data
("Type=" + itemValueTypes[0].ToString(CultureInfo.InvariantCulture)) : ("Type=" + itemValueTypes[0].ToString(CultureInfo.InvariantCulture)) :
("Type in (" + string.Join(",", itemValueTypes.Select(i => i.ToString(CultureInfo.InvariantCulture)).ToArray()) + ")"); ("Type in (" + string.Join(",", itemValueTypes.Select(i => i.ToString(CultureInfo.InvariantCulture)).ToArray()) + ")");
var list = new List<string>();
var commandText = "Select Value From ItemValues where " + typeClause; var commandText = "Select Value From ItemValues where " + typeClause;
if (withItemTypes.Count > 0) if (withItemTypes.Count > 0)
@ -4920,8 +4934,10 @@ namespace Emby.Server.Implementations.Data
{ {
using (var connection = CreateConnection(true)) using (var connection = CreateConnection(true))
{ {
connection.RunInTransaction(db => return connection.RunInTransaction(db =>
{ {
var list = new List<string>();
using (var statement = PrepareStatementSafe(db, commandText)) using (var statement = PrepareStatementSafe(db, commandText))
{ {
foreach (var row in statement.ExecuteQuery()) foreach (var row in statement.ExecuteQuery())
@ -4932,12 +4948,13 @@ namespace Emby.Server.Implementations.Data
} }
} }
} }
}, ReadTransactionMode);
}
}
LogQueryTime("GetItemValueNames", commandText, now); LogQueryTime("GetItemValueNames", commandText, now);
return list; return list;
}, ReadTransactionMode);
}
}
} }
private QueryResult<Tuple<BaseItem, ItemCounts>> GetItemValues(InternalItemsQuery query, int[] itemValueTypes, string returnType) private QueryResult<Tuple<BaseItem, ItemCounts>> GetItemValues(InternalItemsQuery query, int[] itemValueTypes, string returnType)
@ -5081,9 +5098,6 @@ namespace Emby.Server.Implementations.Data
var isReturningZeroItems = query.Limit.HasValue && query.Limit <= 0; var isReturningZeroItems = query.Limit.HasValue && query.Limit <= 0;
var list = new List<Tuple<BaseItem, ItemCounts>>();
var result = new QueryResult<Tuple<BaseItem, ItemCounts>>();
var statementTexts = new List<string>(); var statementTexts = new List<string>();
if (!isReturningZeroItems) if (!isReturningZeroItems)
{ {
@ -5102,8 +5116,11 @@ namespace Emby.Server.Implementations.Data
{ {
using (var connection = CreateConnection(true)) using (var connection = CreateConnection(true))
{ {
connection.RunInTransaction(db => return connection.RunInTransaction(db =>
{ {
var list = new List<Tuple<BaseItem, ItemCounts>>();
var result = new QueryResult<Tuple<BaseItem, ItemCounts>>();
var statements = PrepareAllSafe(db, string.Join(";", statementTexts.ToArray())).ToList(); var statements = PrepareAllSafe(db, string.Join(";", statementTexts.ToArray())).ToList();
if (!isReturningZeroItems) if (!isReturningZeroItems)
@ -5167,9 +5184,6 @@ namespace Emby.Server.Implementations.Data
LogQueryTime("GetItemValues", commandText, now); LogQueryTime("GetItemValues", commandText, now);
} }
} }
}, ReadTransactionMode);
}
}
if (result.TotalRecordCount == 0) if (result.TotalRecordCount == 0)
{ {
@ -5178,6 +5192,10 @@ namespace Emby.Server.Implementations.Data
result.Items = list.ToArray(); result.Items = list.ToArray();
return result; return result;
}, ReadTransactionMode);
}
}
} }
private ItemCounts GetItemCounts(IReadOnlyList<IResultSetValue> reader, int countStartColumn, List<string> typesToCount) private ItemCounts GetItemCounts(IReadOnlyList<IResultSetValue> reader, int countStartColumn, List<string> typesToCount)
@ -5390,8 +5408,6 @@ namespace Emby.Server.Implementations.Data
throw new ArgumentNullException("query"); throw new ArgumentNullException("query");
} }
var list = new List<MediaStream>();
var cmdText = "select " + string.Join(",", _mediaStreamSaveColumns) + " from mediastreams where"; var cmdText = "select " + string.Join(",", _mediaStreamSaveColumns) + " from mediastreams where";
cmdText += " ItemId=@ItemId"; cmdText += " ItemId=@ItemId";
@ -5412,8 +5428,10 @@ namespace Emby.Server.Implementations.Data
{ {
using (var connection = CreateConnection(true)) using (var connection = CreateConnection(true))
{ {
connection.RunInTransaction(db => return connection.RunInTransaction(db =>
{ {
var list = new List<MediaStream>();
using (var statement = PrepareStatementSafe(db, cmdText)) using (var statement = PrepareStatementSafe(db, cmdText))
{ {
statement.TryBind("@ItemId", query.ItemId.ToGuidParamValue()); statement.TryBind("@ItemId", query.ItemId.ToGuidParamValue());
@ -5433,11 +5451,12 @@ namespace Emby.Server.Implementations.Data
list.Add(GetMediaStream(row)); list.Add(GetMediaStream(row));
} }
} }
return list;
}, ReadTransactionMode); }, ReadTransactionMode);
} }
} }
return list;
} }
public async Task SaveMediaStreams(Guid id, List<MediaStream> streams, CancellationToken cancellationToken) public async Task SaveMediaStreams(Guid id, List<MediaStream> streams, CancellationToken cancellationToken)

@ -300,9 +300,7 @@ namespace Emby.Server.Implementations.Data
{ {
using (var connection = CreateConnection(true)) using (var connection = CreateConnection(true))
{ {
UserItemData result = null; return connection.RunInTransaction(db =>
connection.RunInTransaction(db =>
{ {
using (var statement = db.PrepareStatement("select key,userid,rating,played,playCount,isFavorite,playbackPositionTicks,lastPlayedDate,AudioStreamIndex,SubtitleStreamIndex from userdata where key =@Key and userId=@UserId")) using (var statement = db.PrepareStatement("select key,userid,rating,played,playCount,isFavorite,playbackPositionTicks,lastPlayedDate,AudioStreamIndex,SubtitleStreamIndex from userdata where key =@Key and userId=@UserId"))
{ {
@ -311,13 +309,13 @@ namespace Emby.Server.Implementations.Data
foreach (var row in statement.ExecuteQuery()) foreach (var row in statement.ExecuteQuery())
{ {
result = ReadRow(row); return ReadRow(row);
break;
} }
} }
}, ReadTransactionMode);
return result; return null;
}, ReadTransactionMode);
} }
} }
} }

@ -459,12 +459,21 @@ namespace Emby.Server.Implementations.Dto
if (dtoOptions.EnableUserData) if (dtoOptions.EnableUserData)
{ {
dto.UserData = await _userDataRepository.GetUserDataDto(item, dto, user).ConfigureAwait(false); dto.UserData = await _userDataRepository.GetUserDataDto(item, dto, user, dtoOptions.Fields).ConfigureAwait(false);
} }
if (!dto.ChildCount.HasValue && item.SourceType == SourceType.Library) if (!dto.ChildCount.HasValue && item.SourceType == SourceType.Library)
{ {
dto.ChildCount = GetChildCount(folder, user); // For these types we can try to optimize and assume these values will be equal
if (item is MusicAlbum || item is Season)
{
dto.ChildCount = dto.RecursiveItemCount;
}
if (dtoOptions.Fields.Contains(ItemFields.ChildCount))
{
dto.ChildCount = dto.ChildCount ?? GetChildCount(folder, user);
}
} }
if (fields.Contains(ItemFields.CumulativeRunTimeTicks)) if (fields.Contains(ItemFields.CumulativeRunTimeTicks))
@ -1151,28 +1160,29 @@ namespace Emby.Server.Implementations.Dto
{ {
dto.Artists = hasArtist.Artists; dto.Artists = hasArtist.Artists;
var artistItems = _libraryManager.GetArtists(new InternalItemsQuery //var artistItems = _libraryManager.GetArtists(new InternalItemsQuery
{ //{
EnableTotalRecordCount = false, // EnableTotalRecordCount = false,
ItemIds = new[] { item.Id.ToString("N") } // ItemIds = new[] { item.Id.ToString("N") }
}); //});
dto.ArtistItems = artistItems.Items //dto.ArtistItems = artistItems.Items
.Select(i => // .Select(i =>
{ // {
var artist = i.Item1; // var artist = i.Item1;
return new NameIdPair // return new NameIdPair
{ // {
Name = artist.Name, // Name = artist.Name,
Id = artist.Id.ToString("N") // Id = artist.Id.ToString("N")
}; // };
}) // })
.ToList(); // .ToList();
// Include artists that are not in the database yet, e.g., just added via metadata editor // Include artists that are not in the database yet, e.g., just added via metadata editor
var foundArtists = artistItems.Items.Select(i => i.Item1.Name).ToList(); //var foundArtists = artistItems.Items.Select(i => i.Item1.Name).ToList();
dto.ArtistItems = new List<NameIdPair>();
dto.ArtistItems.AddRange(hasArtist.Artists dto.ArtistItems.AddRange(hasArtist.Artists
.Except(foundArtists, new DistinctNameComparer()) //.Except(foundArtists, new DistinctNameComparer())
.Select(i => .Select(i =>
{ {
// This should not be necessary but we're seeing some cases of it // This should not be necessary but we're seeing some cases of it
@ -1201,23 +1211,48 @@ namespace Emby.Server.Implementations.Dto
{ {
dto.AlbumArtist = hasAlbumArtist.AlbumArtists.FirstOrDefault(); dto.AlbumArtist = hasAlbumArtist.AlbumArtists.FirstOrDefault();
var artistItems = _libraryManager.GetAlbumArtists(new InternalItemsQuery //var artistItems = _libraryManager.GetAlbumArtists(new InternalItemsQuery
{ //{
EnableTotalRecordCount = false, // EnableTotalRecordCount = false,
ItemIds = new[] { item.Id.ToString("N") } // ItemIds = new[] { item.Id.ToString("N") }
}); //});
dto.AlbumArtists = artistItems.Items //dto.AlbumArtists = artistItems.Items
// .Select(i =>
// {
// var artist = i.Item1;
// return new NameIdPair
// {
// Name = artist.Name,
// Id = artist.Id.ToString("N")
// };
// })
// .ToList();
dto.AlbumArtists = new List<NameIdPair>();
dto.AlbumArtists.AddRange(hasAlbumArtist.AlbumArtists
//.Except(foundArtists, new DistinctNameComparer())
.Select(i => .Select(i =>
{ {
var artist = i.Item1; // This should not be necessary but we're seeing some cases of it
if (string.IsNullOrWhiteSpace(i))
{
return null;
}
var artist = _libraryManager.GetArtist(i);
if (artist != null)
{
return new NameIdPair return new NameIdPair
{ {
Name = artist.Name, Name = artist.Name,
Id = artist.Id.ToString("N") Id = artist.Id.ToString("N")
}; };
}) }
.ToList();
return null;
}).Where(i => i != null));
} }
// Add video info // Add video info

@ -519,6 +519,12 @@ namespace Emby.Server.Implementations.FileOrganization
private void PerformFileSorting(TvFileOrganizationOptions options, FileOrganizationResult result) private void PerformFileSorting(TvFileOrganizationOptions options, FileOrganizationResult result)
{ {
// We should probably handle this earlier so that we never even make it this far
if (string.Equals(result.OriginalPath, result.TargetPath, StringComparison.OrdinalIgnoreCase))
{
return;
}
_libraryMonitor.ReportFileSystemChangeBeginning(result.TargetPath); _libraryMonitor.ReportFileSystemChangeBeginning(result.TargetPath);
_fileSystem.CreateDirectory(Path.GetDirectoryName(result.TargetPath)); _fileSystem.CreateDirectory(Path.GetDirectoryName(result.TargetPath));

@ -76,7 +76,8 @@ namespace Emby.Server.Implementations.HttpServer.SocketSharp
private void ProcessContext(HttpListenerContext context) private void ProcessContext(HttpListenerContext context)
{ {
Task.Factory.StartNew(() => InitTask(context)); //Task.Factory.StartNew(() => InitTask(context), TaskCreationOptions.DenyChildAttach | TaskCreationOptions.PreferFairness);
Task.Run(() => InitTask(context));
} }
private Task InitTask(HttpListenerContext context) private Task InitTask(HttpListenerContext context)

@ -818,6 +818,30 @@ namespace Emby.Server.Implementations.Library
return _userRootFolder; return _userRootFolder;
} }
public Guid? FindIdByPath(string path, bool? isFolder)
{
// If this returns multiple items it could be tricky figuring out which one is correct.
// In most cases, the newest one will be and the others obsolete but not yet cleaned up
var query = new InternalItemsQuery
{
Path = path,
IsFolder = isFolder,
SortBy = new[] { ItemSortBy.DateCreated },
SortOrder = SortOrder.Descending,
Limit = 1
};
var id = GetItemIds(query);
if (id.Count == 0)
{
return null;
}
return id[0];
}
public BaseItem FindByPath(string path, bool? isFolder) public BaseItem FindByPath(string path, bool? isFolder)
{ {
// If this returns multiple items it could be tricky figuring out which one is correct. // If this returns multiple items it could be tricky figuring out which one is correct.
@ -1430,7 +1454,7 @@ namespace Emby.Server.Implementations.Library
})) }))
{ {
// Optimize by querying against top level views // Optimize by querying against top level views
query.TopParentIds = parents.SelectMany(i => GetTopParentsForQuery(i, query.User)).Select(i => i.Id.ToString("N")).ToArray(); query.TopParentIds = parents.SelectMany(i => GetTopParentIdsForQuery(i, query.User)).Select(i => i.ToString("N")).ToArray();
query.AncestorIds = new string[] { }; query.AncestorIds = new string[] { };
} }
} }
@ -1489,7 +1513,7 @@ namespace Emby.Server.Implementations.Library
})) }))
{ {
// Optimize by querying against top level views // Optimize by querying against top level views
query.TopParentIds = parents.SelectMany(i => GetTopParentsForQuery(i, query.User)).Select(i => i.Id.ToString("N")).ToArray(); query.TopParentIds = parents.SelectMany(i => GetTopParentIdsForQuery(i, query.User)).Select(i => i.ToString("N")).ToArray();
} }
else else
{ {
@ -1515,11 +1539,11 @@ namespace Emby.Server.Implementations.Library
}, CancellationToken.None).Result.ToList(); }, CancellationToken.None).Result.ToList();
query.TopParentIds = userViews.SelectMany(i => GetTopParentsForQuery(i, user)).Select(i => i.Id.ToString("N")).ToArray(); query.TopParentIds = userViews.SelectMany(i => GetTopParentIdsForQuery(i, user)).Select(i => i.ToString("N")).ToArray();
} }
} }
private IEnumerable<BaseItem> GetTopParentsForQuery(BaseItem item, User user) private IEnumerable<Guid> GetTopParentIdsForQuery(BaseItem item, User user)
{ {
var view = item as UserView; var view = item as UserView;
@ -1527,7 +1551,7 @@ namespace Emby.Server.Implementations.Library
{ {
if (string.Equals(view.ViewType, CollectionType.LiveTv)) if (string.Equals(view.ViewType, CollectionType.LiveTv))
{ {
return new[] { view }; return new[] { view.Id };
} }
if (string.Equals(view.ViewType, CollectionType.Channels)) if (string.Equals(view.ViewType, CollectionType.Channels))
{ {
@ -1537,7 +1561,7 @@ namespace Emby.Server.Implementations.Library
}, CancellationToken.None).Result; }, CancellationToken.None).Result;
return channelResult.Items; return channelResult.Items.Select(i => i.Id);
} }
// Translate view into folders // Translate view into folders
@ -1546,18 +1570,18 @@ namespace Emby.Server.Implementations.Library
var displayParent = GetItemById(view.DisplayParentId); var displayParent = GetItemById(view.DisplayParentId);
if (displayParent != null) if (displayParent != null)
{ {
return GetTopParentsForQuery(displayParent, user); return GetTopParentIdsForQuery(displayParent, user);
} }
return new BaseItem[] { }; return new Guid[] { };
} }
if (view.ParentId != Guid.Empty) if (view.ParentId != Guid.Empty)
{ {
var displayParent = GetItemById(view.ParentId); var displayParent = GetItemById(view.ParentId);
if (displayParent != null) if (displayParent != null)
{ {
return GetTopParentsForQuery(displayParent, user); return GetTopParentIdsForQuery(displayParent, user);
} }
return new BaseItem[] { }; return new Guid[] { };
} }
// Handle grouping // Handle grouping
@ -1568,23 +1592,23 @@ namespace Emby.Server.Implementations.Library
.OfType<CollectionFolder>() .OfType<CollectionFolder>()
.Where(i => string.IsNullOrWhiteSpace(i.CollectionType) || string.Equals(i.CollectionType, view.ViewType, StringComparison.OrdinalIgnoreCase)) .Where(i => string.IsNullOrWhiteSpace(i.CollectionType) || string.Equals(i.CollectionType, view.ViewType, StringComparison.OrdinalIgnoreCase))
.Where(i => user.IsFolderGrouped(i.Id)) .Where(i => user.IsFolderGrouped(i.Id))
.SelectMany(i => GetTopParentsForQuery(i, user)); .SelectMany(i => GetTopParentIdsForQuery(i, user));
} }
return new BaseItem[] { }; return new Guid[] { };
} }
var collectionFolder = item as CollectionFolder; var collectionFolder = item as CollectionFolder;
if (collectionFolder != null) if (collectionFolder != null)
{ {
return collectionFolder.GetPhysicalParents(); return collectionFolder.PhysicalFolderIds;
} }
var topParent = item.GetTopParent(); var topParent = item.GetTopParent();
if (topParent != null) if (topParent != null)
{ {
return new[] { topParent }; return new[] { topParent.Id };
} }
return new BaseItem[] { }; return new Guid[] { };
} }
/// <summary> /// <summary>

@ -12,6 +12,7 @@ using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using MediaBrowser.Model.Querying;
namespace Emby.Server.Implementations.Library namespace Emby.Server.Implementations.Library
{ {
@ -186,16 +187,16 @@ namespace Emby.Server.Implementations.Library
var userData = GetUserData(user.Id, item); var userData = GetUserData(user.Id, item);
var dto = GetUserItemDataDto(userData); var dto = GetUserItemDataDto(userData);
await item.FillUserDataDtoValues(dto, userData, null, user).ConfigureAwait(false); await item.FillUserDataDtoValues(dto, userData, null, user, new List<ItemFields>()).ConfigureAwait(false);
return dto; return dto;
} }
public async Task<UserItemDataDto> GetUserDataDto(IHasUserData item, BaseItemDto itemDto, User user) public async Task<UserItemDataDto> GetUserDataDto(IHasUserData item, BaseItemDto itemDto, User user, List<ItemFields> fields)
{ {
var userData = GetUserData(user.Id, item); var userData = GetUserData(user.Id, item);
var dto = GetUserItemDataDto(userData); var dto = GetUserItemDataDto(userData);
await item.FillUserDataDtoValues(dto, userData, itemDto, user).ConfigureAwait(false); await item.FillUserDataDtoValues(dto, userData, itemDto, user, fields).ConfigureAwait(false);
return dto; return dto;
} }

@ -65,9 +65,9 @@ namespace Emby.Server.Implementations.Notifications
var whereClause = " where " + string.Join(" And ", clauses.ToArray()); var whereClause = " where " + string.Join(" And ", clauses.ToArray());
using (var connection = CreateConnection(true)) using (WriteLock.Read())
{ {
lock (WriteLock) using (var connection = CreateConnection(true))
{ {
result.TotalRecordCount = connection.Query("select count(Id) from Notifications" + whereClause, paramList.ToArray()).SelectScalarInt().First(); result.TotalRecordCount = connection.Query("select count(Id) from Notifications" + whereClause, paramList.ToArray()).SelectScalarInt().First();
@ -106,9 +106,9 @@ namespace Emby.Server.Implementations.Notifications
{ {
var result = new NotificationsSummary(); var result = new NotificationsSummary();
using (var connection = CreateConnection(true)) using (WriteLock.Read())
{ {
lock (WriteLock) using (var connection = CreateConnection(true))
{ {
using (var statement = connection.PrepareStatement("select Level from Notifications where UserId=@UserId and IsRead=@IsRead")) using (var statement = connection.PrepareStatement("select Level from Notifications where UserId=@UserId and IsRead=@IsRead"))
{ {
@ -223,9 +223,9 @@ namespace Emby.Server.Implementations.Notifications
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
using (var connection = CreateConnection())
{
lock (WriteLock) lock (WriteLock)
{
using (var connection = CreateConnection())
{ {
connection.RunInTransaction(conn => connection.RunInTransaction(conn =>
{ {
@ -286,9 +286,9 @@ namespace Emby.Server.Implementations.Notifications
{ {
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
using (var connection = CreateConnection()) using (WriteLock.Write())
{ {
lock (WriteLock) using (var connection = CreateConnection())
{ {
connection.RunInTransaction(conn => connection.RunInTransaction(conn =>
{ {
@ -308,9 +308,9 @@ namespace Emby.Server.Implementations.Notifications
{ {
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
using (var connection = CreateConnection()) using (WriteLock.Write())
{ {
lock (WriteLock) using (var connection = CreateConnection())
{ {
connection.RunInTransaction(conn => connection.RunInTransaction(conn =>
{ {

@ -205,11 +205,11 @@ namespace Emby.Server.Implementations.Security
using (WriteLock.Read()) using (WriteLock.Read())
{ {
using (var connection = CreateConnection(true)) using (var connection = CreateConnection(true))
{
return connection.RunInTransaction(db =>
{ {
var result = new QueryResult<AuthenticationInfo>(); var result = new QueryResult<AuthenticationInfo>();
connection.RunInTransaction(db =>
{
var statementTexts = new List<string>(); var statementTexts = new List<string>();
statementTexts.Add(commandText); statementTexts.Add(commandText);
statementTexts.Add("select count (Id) from AccessTokens" + whereTextWithoutPaging); statementTexts.Add("select count (Id) from AccessTokens" + whereTextWithoutPaging);
@ -236,10 +236,10 @@ namespace Emby.Server.Implementations.Security
} }
} }
}, ReadTransactionMode);
result.Items = list.ToArray(); result.Items = list.ToArray();
return result; return result;
}, ReadTransactionMode);
} }
} }
} }

@ -121,7 +121,9 @@ namespace MediaBrowser.Api
{ {
var options = new DtoOptions(); var options = new DtoOptions();
options.DeviceId = authContext.GetAuthorizationInfo(Request).DeviceId; var authInfo = authContext.GetAuthorizationInfo(Request);
options.DeviceId = authInfo.DeviceId;
var hasFields = request as IHasItemFields; var hasFields = request as IHasItemFields;
if (hasFields != null) if (hasFields != null)
@ -129,6 +131,34 @@ namespace MediaBrowser.Api
options.Fields = hasFields.GetItemFields().ToList(); options.Fields = hasFields.GetItemFields().ToList();
} }
var client = authInfo.Client ?? string.Empty;
if (client.IndexOf("kodi", StringComparison.OrdinalIgnoreCase) != -1 ||
client.IndexOf("wmc", StringComparison.OrdinalIgnoreCase) != -1 ||
client.IndexOf("media center", StringComparison.OrdinalIgnoreCase) != -1 ||
client.IndexOf("classic", StringComparison.OrdinalIgnoreCase) != -1)
{
options.Fields.Add(Model.Querying.ItemFields.RecursiveItemCount);
}
if (client.IndexOf("kodi", StringComparison.OrdinalIgnoreCase) != -1 ||
client.IndexOf("wmc", StringComparison.OrdinalIgnoreCase) != -1 ||
client.IndexOf("media center", StringComparison.OrdinalIgnoreCase) != -1 ||
client.IndexOf("classic", StringComparison.OrdinalIgnoreCase) != -1 ||
client.IndexOf("roku", StringComparison.OrdinalIgnoreCase) != -1 ||
client.IndexOf("samsung", StringComparison.OrdinalIgnoreCase) != -1)
{
options.Fields.Add(Model.Querying.ItemFields.ChildCount);
}
if (client.IndexOf("web", StringComparison.OrdinalIgnoreCase) == -1 &&
client.IndexOf("mobile", StringComparison.OrdinalIgnoreCase) == -1 &&
client.IndexOf("ios", StringComparison.OrdinalIgnoreCase) == -1 &&
client.IndexOf("android", StringComparison.OrdinalIgnoreCase) == -1 &&
client.IndexOf("theater", StringComparison.OrdinalIgnoreCase) == -1)
{
options.Fields.Add(Model.Querying.ItemFields.ChildCount);
}
var hasDtoOptions = request as IHasDtoOptions; var hasDtoOptions = request as IHasDtoOptions;
if (hasDtoOptions != null) if (hasDtoOptions != null)
{ {

@ -14,8 +14,6 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.IO;
using MediaBrowser.Model.IO; using MediaBrowser.Model.IO;
using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Services; using MediaBrowser.Model.Services;
@ -88,6 +86,12 @@ namespace MediaBrowser.Api
{ {
} }
[Route("/Items/RemoteSearch/Book", "POST")]
[Authenticated]
public class GetBookRemoteSearchResults : RemoteSearchQuery<BookInfo>, IReturn<List<RemoteSearchResult>>
{
}
[Route("/Items/RemoteSearch/Image", "GET", Summary = "Gets a remote image")] [Route("/Items/RemoteSearch/Image", "GET", Summary = "Gets a remote image")]
public class GetRemoteSearchImage public class GetRemoteSearchImage
{ {
@ -147,6 +151,13 @@ namespace MediaBrowser.Api
return ToOptimizedResult(result); return ToOptimizedResult(result);
} }
public async Task<object> Post(GetBookRemoteSearchResults request)
{
var result = await _providerManager.GetRemoteSearchResults<Book, BookInfo>(request, CancellationToken.None).ConfigureAwait(false);
return ToOptimizedResult(result);
}
public async Task<object> Post(GetMovieRemoteSearchResults request) public async Task<object> Post(GetMovieRemoteSearchResults request)
{ {
var result = await _providerManager.GetRemoteSearchResults<Movie, MovieInfo>(request, CancellationToken.None).ConfigureAwait(false); var result = await _providerManager.GetRemoteSearchResults<Movie, MovieInfo>(request, CancellationToken.None).ConfigureAwait(false);

@ -30,6 +30,7 @@ using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.IO; using MediaBrowser.Model.IO;
using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.LiveTv;
using MediaBrowser.Model.Providers; using MediaBrowser.Model.Providers;
using MediaBrowser.Model.Querying;
using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Serialization;
namespace MediaBrowser.Controller.Entities namespace MediaBrowser.Controller.Entities
@ -2191,7 +2192,7 @@ namespace MediaBrowser.Controller.Entities
return path; return path;
} }
public virtual Task FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, BaseItemDto itemDto, User user) public virtual Task FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, BaseItemDto itemDto, User user, List<ItemFields> itemFields)
{ {
if (RunTimeTicks.HasValue) if (RunTimeTicks.HasValue)
{ {

@ -27,6 +27,7 @@ namespace MediaBrowser.Controller.Entities
public CollectionFolder() public CollectionFolder()
{ {
PhysicalLocationsList = new List<string>(); PhysicalLocationsList = new List<string>();
PhysicalFolderIds = new List<Guid>();
} }
[IgnoreDataMember] [IgnoreDataMember]
@ -153,6 +154,7 @@ namespace MediaBrowser.Controller.Entities
} }
public List<string> PhysicalLocationsList { get; set; } public List<string> PhysicalLocationsList { get; set; }
public List<Guid> PhysicalFolderIds { get; set; }
protected override IEnumerable<FileSystemMetadata> GetFileSystemChildren(IDirectoryService directoryService) protected override IEnumerable<FileSystemMetadata> GetFileSystemChildren(IDirectoryService directoryService)
{ {
@ -176,6 +178,18 @@ namespace MediaBrowser.Controller.Entities
} }
} }
if (!changed)
{
var folderIds = PhysicalFolderIds.ToList();
var newFolderIds = GetPhysicalFolders(false).Select(i => i.Id).ToList();
if (!folderIds.SequenceEqual(newFolderIds))
{
changed = true;
}
}
return changed; return changed;
} }
@ -186,6 +200,31 @@ namespace MediaBrowser.Controller.Entities
return changed; return changed;
} }
protected override bool RefreshLinkedChildren(IEnumerable<FileSystemMetadata> fileSystemChildren)
{
var physicalFolders = GetPhysicalFolders(false)
.ToList();
var linkedChildren = physicalFolders
.SelectMany(c => c.LinkedChildren)
.ToList();
var changed = !linkedChildren.SequenceEqual(LinkedChildren, new LinkedChildComparer());
LinkedChildren = linkedChildren;
var folderIds = PhysicalFolderIds.ToList();
var newFolderIds = physicalFolders.Select(i => i.Id).ToList();
if (!folderIds.SequenceEqual(newFolderIds))
{
changed = true;
PhysicalFolderIds = newFolderIds.ToList();
}
return changed;
}
internal override bool IsValidFromResolver(BaseItem newItem) internal override bool IsValidFromResolver(BaseItem newItem)
{ {
var newCollectionFolder = newItem as CollectionFolder; var newCollectionFolder = newItem as CollectionFolder;
@ -260,26 +299,6 @@ namespace MediaBrowser.Controller.Entities
return Task.FromResult(true); return Task.FromResult(true);
} }
/// <summary>
/// Our children are actually just references to the ones in the physical root...
/// </summary>
/// <value>The linked children.</value>
[IgnoreDataMember]
public override List<LinkedChild> LinkedChildren
{
get { return GetLinkedChildrenInternal(); }
set
{
base.LinkedChildren = value;
}
}
private List<LinkedChild> GetLinkedChildrenInternal()
{
return GetPhysicalParents()
.SelectMany(c => c.LinkedChildren)
.ToList();
}
/// <summary> /// <summary>
/// Our children are actually just references to the ones in the physical root... /// Our children are actually just references to the ones in the physical root...
/// </summary> /// </summary>
@ -292,11 +311,16 @@ namespace MediaBrowser.Controller.Entities
private IEnumerable<BaseItem> GetActualChildren() private IEnumerable<BaseItem> GetActualChildren()
{ {
return GetPhysicalParents().SelectMany(c => c.Children); return GetPhysicalFolders(true).SelectMany(c => c.Children);
} }
public IEnumerable<Folder> GetPhysicalParents() private IEnumerable<Folder> GetPhysicalFolders(bool enableCache)
{
if (enableCache)
{ {
return PhysicalFolderIds.Select(i => LibraryManager.GetItemById(i)).OfType<Folder>();
}
var rootChildren = LibraryManager.RootFolder.Children var rootChildren = LibraryManager.RootFolder.Children
.OfType<Folder>() .OfType<Folder>()
.ToList(); .ToList();

@ -1222,7 +1222,7 @@ namespace MediaBrowser.Controller.Entities
/// Refreshes the linked children. /// Refreshes the linked children.
/// </summary> /// </summary>
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns> /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
private bool RefreshLinkedChildren(IEnumerable<FileSystemMetadata> fileSystemChildren) protected virtual bool RefreshLinkedChildren(IEnumerable<FileSystemMetadata> fileSystemChildren)
{ {
var currentManualLinks = LinkedChildren.Where(i => i.Type == LinkedChildType.Manual).ToList(); var currentManualLinks = LinkedChildren.Where(i => i.Type == LinkedChildType.Manual).ToList();
var currentShortcutLinks = LinkedChildren.Where(i => i.Type == LinkedChildType.Shortcut).ToList(); var currentShortcutLinks = LinkedChildren.Where(i => i.Type == LinkedChildType.Shortcut).ToList();
@ -1410,23 +1410,24 @@ namespace MediaBrowser.Controller.Entities
} }
} }
public override async Task FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, BaseItemDto itemDto, User user) public override async Task FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, BaseItemDto itemDto, User user, List<ItemFields> itemFields)
{ {
if (!SupportsUserDataFromChildren) if (!SupportsUserDataFromChildren)
{ {
return; return;
} }
var recursiveItemCount = GetRecursiveChildCount(user);
if (itemDto != null) if (itemDto != null)
{ {
itemDto.RecursiveItemCount = recursiveItemCount; if (itemFields.Contains(ItemFields.RecursiveItemCount))
{
itemDto.RecursiveItemCount = GetRecursiveChildCount(user);
}
} }
if (recursiveItemCount > 0 && SupportsPlayedStatus) if (SupportsPlayedStatus)
{ {
var unplayedQueryResult = recursiveItemCount > 0 ? await GetItems(new InternalItemsQuery(user) var unplayedQueryResult = await GetItems(new InternalItemsQuery(user)
{ {
Recursive = true, Recursive = true,
IsFolder = false, IsFolder = false,
@ -1435,21 +1436,24 @@ namespace MediaBrowser.Controller.Entities
Limit = 0, Limit = 0,
IsPlayed = false IsPlayed = false
}).ConfigureAwait(false) : new QueryResult<BaseItem>(); }).ConfigureAwait(false);
double unplayedCount = unplayedQueryResult.TotalRecordCount; double unplayedCount = unplayedQueryResult.TotalRecordCount;
var unplayedPercentage = (unplayedCount / recursiveItemCount) * 100;
dto.PlayedPercentage = 100 - unplayedPercentage;
dto.Played = dto.PlayedPercentage.Value >= 100;
dto.UnplayedItemCount = unplayedQueryResult.TotalRecordCount; dto.UnplayedItemCount = unplayedQueryResult.TotalRecordCount;
}
if (itemDto != null) if (itemDto != null && itemDto.RecursiveItemCount.HasValue)
{
if (itemDto.RecursiveItemCount.Value > 0)
{ {
if (this is Season || this is MusicAlbum) var unplayedPercentage = (unplayedCount/itemDto.RecursiveItemCount.Value)*100;
dto.PlayedPercentage = 100 - unplayedPercentage;
dto.Played = dto.PlayedPercentage.Value >= 100;
}
}
else
{ {
itemDto.ChildCount = recursiveItemCount; dto.Played = (dto.UnplayedItemCount ?? 0) == 0;
} }
} }
} }

@ -1,6 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using MediaBrowser.Model.Dto; using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Querying;
namespace MediaBrowser.Controller.Entities namespace MediaBrowser.Controller.Entities
{ {
@ -14,10 +15,7 @@ namespace MediaBrowser.Controller.Entities
/// <summary> /// <summary>
/// Fills the user data dto values. /// Fills the user data dto values.
/// </summary> /// </summary>
/// <param name="dto">The dto.</param> Task FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, BaseItemDto itemDto, User user, List<ItemFields> fields);
/// <param name="userData">The user data.</param>
/// <param name="user">The user.</param>
Task FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, BaseItemDto itemDto, User user);
bool EnableRememberingTrackSelections { get; } bool EnableRememberingTrackSelections { get; }

@ -62,6 +62,8 @@ namespace MediaBrowser.Controller.Library
/// <returns>BaseItem.</returns> /// <returns>BaseItem.</returns>
BaseItem FindByPath(string path, bool? isFolder); BaseItem FindByPath(string path, bool? isFolder);
Guid? FindIdByPath(string path, bool? isFolder);
/// <summary> /// <summary>
/// Gets the artist. /// Gets the artist.
/// </summary> /// </summary>

@ -5,6 +5,7 @@ using MediaBrowser.Model.Entities;
using System; using System;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using MediaBrowser.Model.Querying;
namespace MediaBrowser.Controller.Library namespace MediaBrowser.Controller.Library
{ {
@ -37,12 +38,9 @@ namespace MediaBrowser.Controller.Library
/// <summary> /// <summary>
/// Gets the user data dto. /// Gets the user data dto.
/// </summary> /// </summary>
/// <param name="item">The item.</param>
/// <param name="user">The user.</param>
/// <returns>UserItemDataDto.</returns>
Task<UserItemDataDto> GetUserDataDto(IHasUserData item, User user); Task<UserItemDataDto> GetUserDataDto(IHasUserData item, User user);
Task<UserItemDataDto> GetUserDataDto(IHasUserData item, BaseItemDto itemDto, User user); Task<UserItemDataDto> GetUserDataDto(IHasUserData item, BaseItemDto itemDto, User user, List<ItemFields> fields);
/// <summary> /// <summary>
/// Get all user data for the given user /// Get all user data for the given user

@ -171,6 +171,8 @@
/// </summary> /// </summary>
PrimaryImageAspectRatio, PrimaryImageAspectRatio,
RecursiveItemCount,
/// <summary> /// <summary>
/// The revenue /// The revenue
/// </summary> /// </summary>

@ -291,7 +291,7 @@ namespace Rssdp.Infrastructure
if (devices != null) if (devices != null)
{ {
var deviceList = devices.ToList(); var deviceList = devices.ToList();
WriteTrace(String.Format("Sending {0} search responses", deviceList.Count)); //WriteTrace(String.Format("Sending {0} search responses", deviceList.Count));
foreach (var device in deviceList) foreach (var device in deviceList)
{ {
@ -300,7 +300,7 @@ namespace Rssdp.Infrastructure
} }
else else
{ {
WriteTrace(String.Format("Sending 0 search responses.")); //WriteTrace(String.Format("Sending 0 search responses."));
} }
}); });
} }
@ -413,7 +413,7 @@ namespace Rssdp.Infrastructure
//DisposeRebroadcastTimer(); //DisposeRebroadcastTimer();
WriteTrace("Begin Sending Alive Notifications For All Devices"); //WriteTrace("Begin Sending Alive Notifications For All Devices");
_LastNotificationTime = DateTime.Now; _LastNotificationTime = DateTime.Now;
@ -430,7 +430,7 @@ namespace Rssdp.Infrastructure
SendAliveNotifications(device, true); SendAliveNotifications(device, true);
} }
WriteTrace("Completed Sending Alive Notifications For All Devices"); //WriteTrace("Completed Sending Alive Notifications For All Devices");
} }
catch (ObjectDisposedException ex) catch (ObjectDisposedException ex)
{ {

Loading…
Cancel
Save