update series queries
This commit is contained in:
parent
bff0cd4447
commit
e1b880a5a0
|
@ -84,9 +84,6 @@ namespace Emby.Server.Implementations.Activity
|
|||
{
|
||||
using (var connection = CreateConnection(true))
|
||||
{
|
||||
var list = new List<ActivityLogEntry>();
|
||||
var result = new QueryResult<ActivityLogEntry>();
|
||||
|
||||
var commandText = BaseActivitySelectText;
|
||||
var whereClauses = new List<string>();
|
||||
|
||||
|
@ -127,8 +124,11 @@ namespace Emby.Server.Implementations.Activity
|
|||
statementTexts.Add(commandText);
|
||||
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();
|
||||
|
||||
using (var statement = statements[0])
|
||||
|
@ -153,10 +153,11 @@ namespace Emby.Server.Implementations.Activity
|
|||
|
||||
result.TotalRecordCount = statement.ExecuteQuery().SelectScalarInt().First();
|
||||
}
|
||||
}, ReadTransactionMode);
|
||||
|
||||
result.Items = list.ToArray();
|
||||
return result;
|
||||
result.Items = list.ToArray();
|
||||
return result;
|
||||
|
||||
}, ReadTransactionMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ namespace Emby.Server.Implementations.Data
|
|||
//CheckOk(rc);
|
||||
|
||||
rc = raw.sqlite3_config(raw.SQLITE_CONFIG_MULTITHREAD, 1);
|
||||
//rc = raw.sqlite3_config(raw.SQLITE_CONFIG_SERIALIZED, 1);
|
||||
//CheckOk(rc);
|
||||
|
||||
rc = raw.sqlite3_enable_shared_cache(1);
|
||||
|
@ -94,6 +95,7 @@ namespace Emby.Server.Implementations.Data
|
|||
var queries = new List<string>
|
||||
{
|
||||
//"PRAGMA cache size=-10000"
|
||||
//"PRAGMA read_uncommitted = true"
|
||||
};
|
||||
|
||||
if (EnableTempStoreMemory)
|
||||
|
|
|
@ -328,6 +328,8 @@ namespace Emby.Server.Implementations.Data
|
|||
"drop table if exists Images",
|
||||
"drop index if exists idx_Images",
|
||||
"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_ParentIdTypedBaseItems on TypedBaseItems(ParentId)",
|
||||
|
@ -343,8 +345,9 @@ namespace Emby.Server.Implementations.Data
|
|||
// series
|
||||
"create index if not exists idx_TypeSeriesPresentationUniqueKey1 on TypedBaseItems(Type,SeriesPresentationUniqueKey,PresentationUniqueKey,SortName)",
|
||||
|
||||
// series next up
|
||||
"create index if not exists idx_SeriesPresentationUniqueKey on TypedBaseItems(SeriesPresentationUniqueKey)",
|
||||
// series counts
|
||||
// seriesdateplayed sort order
|
||||
"create index if not exists idx_TypeSeriesPresentationUniqueKey3 on TypedBaseItems(SeriesPresentationUniqueKey,Type,IsFolder,IsVirtualItem)",
|
||||
|
||||
// live tv programs
|
||||
"create index if not exists idx_TypeTopParentIdStartDate on TypedBaseItems(Type,TopParentId,StartDate)",
|
||||
|
@ -2079,25 +2082,29 @@ namespace Emby.Server.Implementations.Data
|
|||
throw new ArgumentNullException("id");
|
||||
}
|
||||
|
||||
var list = new List<ChapterInfo>();
|
||||
|
||||
using (WriteLock.Read())
|
||||
{
|
||||
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 =>
|
||||
{
|
||||
statement.TryBind("@ItemId", id);
|
||||
var list = new List<ChapterInfo>();
|
||||
|
||||
foreach (var row in statement.ExecuteQuery())
|
||||
using (var statement = PrepareStatementSafe(db, "select StartPositionTicks,Name,ImagePath,ImageDateModified from " + ChaptersTableName + " where ItemId = @ItemId order by ChapterIndex asc"))
|
||||
{
|
||||
list.Add(GetChapter(row));
|
||||
statement.TryBind("@ItemId", id);
|
||||
|
||||
foreach (var row in statement.ExecuteQuery())
|
||||
{
|
||||
list.Add(GetChapter(row));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
|
||||
}, ReadTransactionMode);
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -2470,32 +2477,33 @@ namespace Emby.Server.Implementations.Data
|
|||
|
||||
//commandText += GetGroupBy(query);
|
||||
|
||||
int count = 0;
|
||||
|
||||
using (WriteLock.Read())
|
||||
{
|
||||
using (var connection = CreateConnection(true))
|
||||
{
|
||||
using (var statement = PrepareStatementSafe(connection, commandText))
|
||||
return connection.RunInTransaction(db =>
|
||||
{
|
||||
if (EnableJoinUserData(query))
|
||||
using (var statement = PrepareStatementSafe(db, commandText))
|
||||
{
|
||||
statement.TryBind("@UserId", query.User.Id);
|
||||
if (EnableJoinUserData(query))
|
||||
{
|
||||
statement.TryBind("@UserId", query.User.Id);
|
||||
}
|
||||
|
||||
BindSimilarParams(query, statement);
|
||||
|
||||
// Running this again will bind the params
|
||||
GetWhereClauses(query, statement);
|
||||
|
||||
var count = statement.ExecuteQuery().SelectScalarInt().First();
|
||||
LogQueryTime("GetCount", commandText, now);
|
||||
return count;
|
||||
}
|
||||
|
||||
BindSimilarParams(query, statement);
|
||||
|
||||
// Running this again will bind the params
|
||||
GetWhereClauses(query, statement);
|
||||
|
||||
count = statement.ExecuteQuery().SelectScalarInt().First();
|
||||
}
|
||||
}, ReadTransactionMode);
|
||||
}
|
||||
|
||||
LogQueryTime("GetCount", commandText, now);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
public List<BaseItem> GetItemList(InternalItemsQuery query)
|
||||
|
@ -2511,8 +2519,6 @@ namespace Emby.Server.Implementations.Data
|
|||
|
||||
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
|
||||
if (query.Limit.HasValue && query.EnableGroupByMetadataKey)
|
||||
{
|
||||
|
@ -2553,53 +2559,59 @@ namespace Emby.Server.Implementations.Data
|
|||
{
|
||||
using (var connection = CreateConnection(true))
|
||||
{
|
||||
using (var statement = PrepareStatementSafe(connection, commandText))
|
||||
return connection.RunInTransaction(db =>
|
||||
{
|
||||
if (EnableJoinUserData(query))
|
||||
var list = new List<BaseItem>();
|
||||
|
||||
using (var statement = PrepareStatementSafe(db, commandText))
|
||||
{
|
||||
statement.TryBind("@UserId", query.User.Id);
|
||||
}
|
||||
|
||||
BindSimilarParams(query, statement);
|
||||
|
||||
// Running this again will bind the params
|
||||
GetWhereClauses(query, statement);
|
||||
|
||||
foreach (var row in statement.ExecuteQuery())
|
||||
{
|
||||
var item = GetItem(row, query);
|
||||
if (item != null)
|
||||
if (EnableJoinUserData(query))
|
||||
{
|
||||
list.Add(item);
|
||||
statement.TryBind("@UserId", query.User.Id);
|
||||
}
|
||||
|
||||
BindSimilarParams(query, statement);
|
||||
|
||||
// Running this again will bind the params
|
||||
GetWhereClauses(query, statement);
|
||||
|
||||
foreach (var row in statement.ExecuteQuery())
|
||||
{
|
||||
var item = GetItem(row, query);
|
||||
if (item != null)
|
||||
{
|
||||
list.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Hack for right now since we currently don't support filtering out these duplicates within a query
|
||||
if (query.EnableGroupByMetadataKey)
|
||||
{
|
||||
var limit = query.Limit ?? int.MaxValue;
|
||||
limit -= 4;
|
||||
var newList = new List<BaseItem>();
|
||||
|
||||
foreach (var item in list)
|
||||
{
|
||||
AddItem(newList, item);
|
||||
|
||||
if (newList.Count >= limit)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
list = newList;
|
||||
}
|
||||
|
||||
LogQueryTime("GetItemList", commandText, now);
|
||||
|
||||
return list;
|
||||
|
||||
}, ReadTransactionMode);
|
||||
}
|
||||
|
||||
LogQueryTime("GetItemList", commandText, now);
|
||||
}
|
||||
|
||||
// Hack for right now since we currently don't support filtering out these duplicates within a query
|
||||
if (query.EnableGroupByMetadataKey)
|
||||
{
|
||||
var limit = query.Limit ?? int.MaxValue;
|
||||
limit -= 4;
|
||||
var newList = new List<BaseItem>();
|
||||
|
||||
foreach (var item in list)
|
||||
{
|
||||
AddItem(newList, item);
|
||||
|
||||
if (newList.Count >= limit)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
list = newList;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private void AddItem(List<BaseItem> items, BaseItem newItem)
|
||||
|
@ -2637,7 +2649,7 @@ namespace Emby.Server.Implementations.Data
|
|||
var slowThreshold = 1000;
|
||||
|
||||
#if DEBUG
|
||||
slowThreshold = 50;
|
||||
slowThreshold = 2;
|
||||
#endif
|
||||
|
||||
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 statementTexts = new List<string>();
|
||||
|
@ -2748,8 +2759,9 @@ namespace Emby.Server.Implementations.Data
|
|||
{
|
||||
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()))
|
||||
.ToList();
|
||||
|
||||
|
@ -2796,12 +2808,12 @@ namespace Emby.Server.Implementations.Data
|
|||
}
|
||||
}
|
||||
|
||||
LogQueryTime("GetItems", commandText, now);
|
||||
|
||||
result.Items = list.ToArray();
|
||||
return result;
|
||||
|
||||
}, ReadTransactionMode);
|
||||
|
||||
LogQueryTime("GetItems", commandText, now);
|
||||
|
||||
result.Items = list.ToArray();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2962,34 +2974,38 @@ namespace Emby.Server.Implementations.Data
|
|||
}
|
||||
}
|
||||
|
||||
var list = new List<Guid>();
|
||||
|
||||
using (WriteLock.Read())
|
||||
{
|
||||
using (var connection = CreateConnection(true))
|
||||
{
|
||||
using (var statement = PrepareStatementSafe(connection, commandText))
|
||||
return connection.RunInTransaction(db =>
|
||||
{
|
||||
if (EnableJoinUserData(query))
|
||||
var list = new List<Guid>();
|
||||
|
||||
using (var statement = PrepareStatementSafe(db, commandText))
|
||||
{
|
||||
statement.TryBind("@UserId", query.User.Id);
|
||||
if (EnableJoinUserData(query))
|
||||
{
|
||||
statement.TryBind("@UserId", query.User.Id);
|
||||
}
|
||||
|
||||
BindSimilarParams(query, statement);
|
||||
|
||||
// Running this again will bind the params
|
||||
GetWhereClauses(query, statement);
|
||||
|
||||
foreach (var row in statement.ExecuteQuery())
|
||||
{
|
||||
list.Add(row[0].ReadGuid());
|
||||
}
|
||||
}
|
||||
|
||||
BindSimilarParams(query, statement);
|
||||
LogQueryTime("GetItemList", commandText, now);
|
||||
|
||||
// Running this again will bind the params
|
||||
GetWhereClauses(query, statement);
|
||||
return list;
|
||||
|
||||
foreach (var row in statement.ExecuteQuery())
|
||||
{
|
||||
list.Add(row[0].ReadGuid());
|
||||
}
|
||||
}
|
||||
}, ReadTransactionMode);
|
||||
}
|
||||
|
||||
LogQueryTime("GetItemList", commandText, now);
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3153,10 +3169,10 @@ namespace Emby.Server.Implementations.Data
|
|||
{
|
||||
using (var connection = CreateConnection(true))
|
||||
{
|
||||
var result = new QueryResult<Guid>();
|
||||
|
||||
connection.RunInTransaction(db =>
|
||||
return connection.RunInTransaction(db =>
|
||||
{
|
||||
var result = new QueryResult<Guid>();
|
||||
|
||||
var statements = PrepareAllSafe(db, string.Join(";", statementTexts.ToArray()))
|
||||
.ToList();
|
||||
|
||||
|
@ -3199,12 +3215,12 @@ namespace Emby.Server.Implementations.Data
|
|||
}
|
||||
}
|
||||
|
||||
LogQueryTime("GetItemIds", commandText, now);
|
||||
|
||||
result.Items = list.ToArray();
|
||||
return result;
|
||||
|
||||
}, ReadTransactionMode);
|
||||
|
||||
LogQueryTime("GetItemIds", commandText, now);
|
||||
|
||||
result.Items = list.ToArray();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4653,13 +4669,13 @@ namespace Emby.Server.Implementations.Data
|
|||
|
||||
commandText += " order by ListOrder";
|
||||
|
||||
var list = new List<string>();
|
||||
using (WriteLock.Read())
|
||||
{
|
||||
using (var connection = CreateConnection(true))
|
||||
{
|
||||
connection.RunInTransaction(db =>
|
||||
return connection.RunInTransaction(db =>
|
||||
{
|
||||
var list = new List<string>();
|
||||
using (var statement = PrepareStatementSafe(db, commandText))
|
||||
{
|
||||
// Run this again to bind the params
|
||||
|
@ -4670,9 +4686,9 @@ namespace Emby.Server.Implementations.Data
|
|||
list.Add(row.GetString(0));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}, ReadTransactionMode);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4696,14 +4712,14 @@ namespace Emby.Server.Implementations.Data
|
|||
|
||||
commandText += " order by ListOrder";
|
||||
|
||||
var list = new List<PersonInfo>();
|
||||
|
||||
using (WriteLock.Read())
|
||||
{
|
||||
using (var connection = CreateConnection(true))
|
||||
{
|
||||
connection.RunInTransaction(db =>
|
||||
return connection.RunInTransaction(db =>
|
||||
{
|
||||
var list = new List<PersonInfo>();
|
||||
|
||||
using (var statement = PrepareStatementSafe(db, commandText))
|
||||
{
|
||||
// Run this again to bind the params
|
||||
|
@ -4714,11 +4730,11 @@ namespace Emby.Server.Implementations.Data
|
|||
list.Add(GetPerson(row));
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}, ReadTransactionMode);
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private List<string> GetPeopleWhereClauses(InternalPeopleQuery query, IStatement statement)
|
||||
|
@ -4899,8 +4915,6 @@ namespace Emby.Server.Implementations.Data
|
|||
("Type=" + itemValueTypes[0].ToString(CultureInfo.InvariantCulture)) :
|
||||
("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;
|
||||
|
||||
if (withItemTypes.Count > 0)
|
||||
|
@ -4920,8 +4934,10 @@ namespace Emby.Server.Implementations.Data
|
|||
{
|
||||
using (var connection = CreateConnection(true))
|
||||
{
|
||||
connection.RunInTransaction(db =>
|
||||
return connection.RunInTransaction(db =>
|
||||
{
|
||||
var list = new List<string>();
|
||||
|
||||
using (var statement = PrepareStatementSafe(db, commandText))
|
||||
{
|
||||
foreach (var row in statement.ExecuteQuery())
|
||||
|
@ -4932,12 +4948,13 @@ namespace Emby.Server.Implementations.Data
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
LogQueryTime("GetItemValueNames", commandText, now);
|
||||
|
||||
return list;
|
||||
}, ReadTransactionMode);
|
||||
}
|
||||
}
|
||||
LogQueryTime("GetItemValueNames", commandText, now);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
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 list = new List<Tuple<BaseItem, ItemCounts>>();
|
||||
var result = new QueryResult<Tuple<BaseItem, ItemCounts>>();
|
||||
|
||||
var statementTexts = new List<string>();
|
||||
if (!isReturningZeroItems)
|
||||
{
|
||||
|
@ -5102,8 +5116,11 @@ namespace Emby.Server.Implementations.Data
|
|||
{
|
||||
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();
|
||||
|
||||
if (!isReturningZeroItems)
|
||||
|
@ -5167,17 +5184,18 @@ namespace Emby.Server.Implementations.Data
|
|||
LogQueryTime("GetItemValues", commandText, now);
|
||||
}
|
||||
}
|
||||
|
||||
if (result.TotalRecordCount == 0)
|
||||
{
|
||||
result.TotalRecordCount = list.Count;
|
||||
}
|
||||
result.Items = list.ToArray();
|
||||
|
||||
return result;
|
||||
|
||||
}, ReadTransactionMode);
|
||||
}
|
||||
}
|
||||
|
||||
if (result.TotalRecordCount == 0)
|
||||
{
|
||||
result.TotalRecordCount = list.Count;
|
||||
}
|
||||
result.Items = list.ToArray();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private ItemCounts GetItemCounts(IReadOnlyList<IResultSetValue> reader, int countStartColumn, List<string> typesToCount)
|
||||
|
@ -5390,8 +5408,6 @@ namespace Emby.Server.Implementations.Data
|
|||
throw new ArgumentNullException("query");
|
||||
}
|
||||
|
||||
var list = new List<MediaStream>();
|
||||
|
||||
var cmdText = "select " + string.Join(",", _mediaStreamSaveColumns) + " from mediastreams where";
|
||||
|
||||
cmdText += " ItemId=@ItemId";
|
||||
|
@ -5412,8 +5428,10 @@ namespace Emby.Server.Implementations.Data
|
|||
{
|
||||
using (var connection = CreateConnection(true))
|
||||
{
|
||||
connection.RunInTransaction(db =>
|
||||
return connection.RunInTransaction(db =>
|
||||
{
|
||||
var list = new List<MediaStream>();
|
||||
|
||||
using (var statement = PrepareStatementSafe(db, cmdText))
|
||||
{
|
||||
statement.TryBind("@ItemId", query.ItemId.ToGuidParamValue());
|
||||
|
@ -5433,11 +5451,12 @@ namespace Emby.Server.Implementations.Data
|
|||
list.Add(GetMediaStream(row));
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
|
||||
}, ReadTransactionMode);
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
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))
|
||||
{
|
||||
UserItemData result = null;
|
||||
|
||||
connection.RunInTransaction(db =>
|
||||
return 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"))
|
||||
{
|
||||
|
@ -311,13 +309,13 @@ namespace Emby.Server.Implementations.Data
|
|||
|
||||
foreach (var row in statement.ExecuteQuery())
|
||||
{
|
||||
result = ReadRow(row);
|
||||
break;
|
||||
return ReadRow(row);
|
||||
}
|
||||
}
|
||||
}, ReadTransactionMode);
|
||||
|
||||
return result;
|
||||
return null;
|
||||
|
||||
}, ReadTransactionMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -459,12 +459,21 @@ namespace Emby.Server.Implementations.Dto
|
|||
|
||||
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)
|
||||
{
|
||||
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))
|
||||
|
@ -1151,28 +1160,29 @@ namespace Emby.Server.Implementations.Dto
|
|||
{
|
||||
dto.Artists = hasArtist.Artists;
|
||||
|
||||
var artistItems = _libraryManager.GetArtists(new InternalItemsQuery
|
||||
{
|
||||
EnableTotalRecordCount = false,
|
||||
ItemIds = new[] { item.Id.ToString("N") }
|
||||
});
|
||||
//var artistItems = _libraryManager.GetArtists(new InternalItemsQuery
|
||||
//{
|
||||
// EnableTotalRecordCount = false,
|
||||
// ItemIds = new[] { item.Id.ToString("N") }
|
||||
//});
|
||||
|
||||
dto.ArtistItems = artistItems.Items
|
||||
.Select(i =>
|
||||
{
|
||||
var artist = i.Item1;
|
||||
return new NameIdPair
|
||||
{
|
||||
Name = artist.Name,
|
||||
Id = artist.Id.ToString("N")
|
||||
};
|
||||
})
|
||||
.ToList();
|
||||
//dto.ArtistItems = artistItems.Items
|
||||
// .Select(i =>
|
||||
// {
|
||||
// var artist = i.Item1;
|
||||
// return new NameIdPair
|
||||
// {
|
||||
// Name = artist.Name,
|
||||
// Id = artist.Id.ToString("N")
|
||||
// };
|
||||
// })
|
||||
// .ToList();
|
||||
|
||||
// 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
|
||||
.Except(foundArtists, new DistinctNameComparer())
|
||||
//.Except(foundArtists, new DistinctNameComparer())
|
||||
.Select(i =>
|
||||
{
|
||||
// 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();
|
||||
|
||||
var artistItems = _libraryManager.GetAlbumArtists(new InternalItemsQuery
|
||||
{
|
||||
EnableTotalRecordCount = false,
|
||||
ItemIds = new[] { item.Id.ToString("N") }
|
||||
});
|
||||
//var artistItems = _libraryManager.GetAlbumArtists(new InternalItemsQuery
|
||||
//{
|
||||
// EnableTotalRecordCount = false,
|
||||
// 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 =>
|
||||
{
|
||||
var artist = i.Item1;
|
||||
return new NameIdPair
|
||||
// This should not be necessary but we're seeing some cases of it
|
||||
if (string.IsNullOrWhiteSpace(i))
|
||||
{
|
||||
Name = artist.Name,
|
||||
Id = artist.Id.ToString("N")
|
||||
};
|
||||
})
|
||||
.ToList();
|
||||
return null;
|
||||
}
|
||||
|
||||
var artist = _libraryManager.GetArtist(i);
|
||||
if (artist != null)
|
||||
{
|
||||
return new NameIdPair
|
||||
{
|
||||
Name = artist.Name,
|
||||
Id = artist.Id.ToString("N")
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}).Where(i => i != null));
|
||||
}
|
||||
|
||||
// Add video info
|
||||
|
|
|
@ -519,6 +519,12 @@ namespace Emby.Server.Implementations.FileOrganization
|
|||
|
||||
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);
|
||||
|
||||
_fileSystem.CreateDirectory(Path.GetDirectoryName(result.TargetPath));
|
||||
|
|
|
@ -76,7 +76,8 @@ namespace Emby.Server.Implementations.HttpServer.SocketSharp
|
|||
|
||||
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)
|
||||
|
|
|
@ -817,7 +817,31 @@ namespace Emby.Server.Implementations.Library
|
|||
|
||||
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)
|
||||
{
|
||||
// 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
|
||||
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[] { };
|
||||
}
|
||||
}
|
||||
|
@ -1489,7 +1513,7 @@ namespace Emby.Server.Implementations.Library
|
|||
}))
|
||||
{
|
||||
// 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
|
||||
{
|
||||
|
@ -1515,11 +1539,11 @@ namespace Emby.Server.Implementations.Library
|
|||
|
||||
}, 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;
|
||||
|
||||
|
@ -1527,7 +1551,7 @@ namespace Emby.Server.Implementations.Library
|
|||
{
|
||||
if (string.Equals(view.ViewType, CollectionType.LiveTv))
|
||||
{
|
||||
return new[] { view };
|
||||
return new[] { view.Id };
|
||||
}
|
||||
if (string.Equals(view.ViewType, CollectionType.Channels))
|
||||
{
|
||||
|
@ -1537,7 +1561,7 @@ namespace Emby.Server.Implementations.Library
|
|||
|
||||
}, CancellationToken.None).Result;
|
||||
|
||||
return channelResult.Items;
|
||||
return channelResult.Items.Select(i => i.Id);
|
||||
}
|
||||
|
||||
// Translate view into folders
|
||||
|
@ -1546,18 +1570,18 @@ namespace Emby.Server.Implementations.Library
|
|||
var displayParent = GetItemById(view.DisplayParentId);
|
||||
if (displayParent != null)
|
||||
{
|
||||
return GetTopParentsForQuery(displayParent, user);
|
||||
return GetTopParentIdsForQuery(displayParent, user);
|
||||
}
|
||||
return new BaseItem[] { };
|
||||
return new Guid[] { };
|
||||
}
|
||||
if (view.ParentId != Guid.Empty)
|
||||
{
|
||||
var displayParent = GetItemById(view.ParentId);
|
||||
if (displayParent != null)
|
||||
{
|
||||
return GetTopParentsForQuery(displayParent, user);
|
||||
return GetTopParentIdsForQuery(displayParent, user);
|
||||
}
|
||||
return new BaseItem[] { };
|
||||
return new Guid[] { };
|
||||
}
|
||||
|
||||
// Handle grouping
|
||||
|
@ -1568,23 +1592,23 @@ namespace Emby.Server.Implementations.Library
|
|||
.OfType<CollectionFolder>()
|
||||
.Where(i => string.IsNullOrWhiteSpace(i.CollectionType) || string.Equals(i.CollectionType, view.ViewType, StringComparison.OrdinalIgnoreCase))
|
||||
.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;
|
||||
if (collectionFolder != null)
|
||||
{
|
||||
return collectionFolder.GetPhysicalParents();
|
||||
return collectionFolder.PhysicalFolderIds;
|
||||
}
|
||||
|
||||
|
||||
var topParent = item.GetTopParent();
|
||||
if (topParent != null)
|
||||
{
|
||||
return new[] { topParent };
|
||||
return new[] { topParent.Id };
|
||||
}
|
||||
return new BaseItem[] { };
|
||||
return new Guid[] { };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -12,6 +12,7 @@ using System.Collections.Concurrent;
|
|||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Querying;
|
||||
|
||||
namespace Emby.Server.Implementations.Library
|
||||
{
|
||||
|
@ -186,16 +187,16 @@ namespace Emby.Server.Implementations.Library
|
|||
var userData = GetUserData(user.Id, item);
|
||||
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;
|
||||
}
|
||||
|
||||
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 dto = GetUserItemDataDto(userData);
|
||||
|
||||
await item.FillUserDataDtoValues(dto, userData, itemDto, user).ConfigureAwait(false);
|
||||
await item.FillUserDataDtoValues(dto, userData, itemDto, user, fields).ConfigureAwait(false);
|
||||
return dto;
|
||||
}
|
||||
|
||||
|
|
|
@ -65,9 +65,9 @@ namespace Emby.Server.Implementations.Notifications
|
|||
|
||||
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();
|
||||
|
||||
|
@ -106,9 +106,9 @@ namespace Emby.Server.Implementations.Notifications
|
|||
{
|
||||
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"))
|
||||
{
|
||||
|
@ -223,9 +223,9 @@ namespace Emby.Server.Implementations.Notifications
|
|||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
using (var connection = CreateConnection())
|
||||
lock (WriteLock)
|
||||
{
|
||||
lock (WriteLock)
|
||||
using (var connection = CreateConnection())
|
||||
{
|
||||
connection.RunInTransaction(conn =>
|
||||
{
|
||||
|
@ -286,9 +286,9 @@ namespace Emby.Server.Implementations.Notifications
|
|||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
using (var connection = CreateConnection())
|
||||
using (WriteLock.Write())
|
||||
{
|
||||
lock (WriteLock)
|
||||
using (var connection = CreateConnection())
|
||||
{
|
||||
connection.RunInTransaction(conn =>
|
||||
{
|
||||
|
@ -308,9 +308,9 @@ namespace Emby.Server.Implementations.Notifications
|
|||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
using (var connection = CreateConnection())
|
||||
using (WriteLock.Write())
|
||||
{
|
||||
lock (WriteLock)
|
||||
using (var connection = CreateConnection())
|
||||
{
|
||||
connection.RunInTransaction(conn =>
|
||||
{
|
||||
|
|
|
@ -206,10 +206,10 @@ namespace Emby.Server.Implementations.Security
|
|||
{
|
||||
using (var connection = CreateConnection(true))
|
||||
{
|
||||
var result = new QueryResult<AuthenticationInfo>();
|
||||
|
||||
connection.RunInTransaction(db =>
|
||||
return connection.RunInTransaction(db =>
|
||||
{
|
||||
var result = new QueryResult<AuthenticationInfo>();
|
||||
|
||||
var statementTexts = new List<string>();
|
||||
statementTexts.Add(commandText);
|
||||
statementTexts.Add("select count (Id) from AccessTokens" + whereTextWithoutPaging);
|
||||
|
@ -236,10 +236,10 @@ namespace Emby.Server.Implementations.Security
|
|||
}
|
||||
}
|
||||
|
||||
}, ReadTransactionMode);
|
||||
result.Items = list.ToArray();
|
||||
return result;
|
||||
|
||||
result.Items = list.ToArray();
|
||||
return result;
|
||||
}, ReadTransactionMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -121,7 +121,9 @@ namespace MediaBrowser.Api
|
|||
{
|
||||
var options = new DtoOptions();
|
||||
|
||||
options.DeviceId = authContext.GetAuthorizationInfo(Request).DeviceId;
|
||||
var authInfo = authContext.GetAuthorizationInfo(Request);
|
||||
|
||||
options.DeviceId = authInfo.DeviceId;
|
||||
|
||||
var hasFields = request as IHasItemFields;
|
||||
if (hasFields != null)
|
||||
|
@ -129,6 +131,34 @@ namespace MediaBrowser.Api
|
|||
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;
|
||||
if (hasDtoOptions != null)
|
||||
{
|
||||
|
|
|
@ -14,8 +14,6 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.IO;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
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")]
|
||||
public class GetRemoteSearchImage
|
||||
{
|
||||
|
@ -147,6 +151,13 @@ namespace MediaBrowser.Api
|
|||
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)
|
||||
{
|
||||
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.LiveTv;
|
||||
using MediaBrowser.Model.Providers;
|
||||
using MediaBrowser.Model.Querying;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
|
@ -2191,7 +2192,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
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)
|
||||
{
|
||||
|
|
|
@ -27,6 +27,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
public CollectionFolder()
|
||||
{
|
||||
PhysicalLocationsList = new List<string>();
|
||||
PhysicalFolderIds = new List<Guid>();
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
|
@ -153,6 +154,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
}
|
||||
|
||||
public List<string> PhysicalLocationsList { get; set; }
|
||||
public List<Guid> PhysicalFolderIds { get; set; }
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -186,6 +200,31 @@ namespace MediaBrowser.Controller.Entities
|
|||
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)
|
||||
{
|
||||
var newCollectionFolder = newItem as CollectionFolder;
|
||||
|
@ -260,26 +299,6 @@ namespace MediaBrowser.Controller.Entities
|
|||
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>
|
||||
/// Our children are actually just references to the ones in the physical root...
|
||||
/// </summary>
|
||||
|
@ -292,11 +311,16 @@ namespace MediaBrowser.Controller.Entities
|
|||
|
||||
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
|
||||
.OfType<Folder>()
|
||||
.ToList();
|
||||
|
|
|
@ -1222,7 +1222,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
/// Refreshes the linked children.
|
||||
/// </summary>
|
||||
/// <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 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)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var recursiveItemCount = GetRecursiveChildCount(user);
|
||||
|
||||
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,
|
||||
IsFolder = false,
|
||||
|
@ -1435,21 +1436,24 @@ namespace MediaBrowser.Controller.Entities
|
|||
Limit = 0,
|
||||
IsPlayed = false
|
||||
|
||||
}).ConfigureAwait(false) : new QueryResult<BaseItem>();
|
||||
}).ConfigureAwait(false);
|
||||
|
||||
double unplayedCount = unplayedQueryResult.TotalRecordCount;
|
||||
|
||||
var unplayedPercentage = (unplayedCount / recursiveItemCount) * 100;
|
||||
dto.PlayedPercentage = 100 - unplayedPercentage;
|
||||
dto.Played = dto.PlayedPercentage.Value >= 100;
|
||||
dto.UnplayedItemCount = unplayedQueryResult.TotalRecordCount;
|
||||
}
|
||||
|
||||
if (itemDto != null)
|
||||
{
|
||||
if (this is Season || this is MusicAlbum)
|
||||
if (itemDto != null && itemDto.RecursiveItemCount.HasValue)
|
||||
{
|
||||
itemDto.ChildCount = recursiveItemCount;
|
||||
if (itemDto.RecursiveItemCount.Value > 0)
|
||||
{
|
||||
var unplayedPercentage = (unplayedCount/itemDto.RecursiveItemCount.Value)*100;
|
||||
dto.PlayedPercentage = 100 - unplayedPercentage;
|
||||
dto.Played = dto.PlayedPercentage.Value >= 100;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dto.Played = (dto.UnplayedItemCount ?? 0) == 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Querying;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
|
@ -14,10 +15,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
/// <summary>
|
||||
/// Fills the user data dto values.
|
||||
/// </summary>
|
||||
/// <param name="dto">The dto.</param>
|
||||
/// <param name="userData">The user data.</param>
|
||||
/// <param name="user">The user.</param>
|
||||
Task FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, BaseItemDto itemDto, User user);
|
||||
Task FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, BaseItemDto itemDto, User user, List<ItemFields> fields);
|
||||
|
||||
bool EnableRememberingTrackSelections { get; }
|
||||
|
||||
|
|
|
@ -62,6 +62,8 @@ namespace MediaBrowser.Controller.Library
|
|||
/// <returns>BaseItem.</returns>
|
||||
BaseItem FindByPath(string path, bool? isFolder);
|
||||
|
||||
Guid? FindIdByPath(string path, bool? isFolder);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the artist.
|
||||
/// </summary>
|
||||
|
|
|
@ -5,6 +5,7 @@ using MediaBrowser.Model.Entities;
|
|||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Querying;
|
||||
|
||||
namespace MediaBrowser.Controller.Library
|
||||
{
|
||||
|
@ -37,12 +38,9 @@ namespace MediaBrowser.Controller.Library
|
|||
/// <summary>
|
||||
/// Gets the user data dto.
|
||||
/// </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, BaseItemDto itemDto, User user);
|
||||
Task<UserItemDataDto> GetUserDataDto(IHasUserData item, BaseItemDto itemDto, User user, List<ItemFields> fields);
|
||||
|
||||
/// <summary>
|
||||
/// Get all user data for the given user
|
||||
|
|
|
@ -171,6 +171,8 @@
|
|||
/// </summary>
|
||||
PrimaryImageAspectRatio,
|
||||
|
||||
RecursiveItemCount,
|
||||
|
||||
/// <summary>
|
||||
/// The revenue
|
||||
/// </summary>
|
||||
|
|
|
@ -291,7 +291,7 @@ namespace Rssdp.Infrastructure
|
|||
if (devices != null)
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
@ -300,7 +300,7 @@ namespace Rssdp.Infrastructure
|
|||
}
|
||||
else
|
||||
{
|
||||
WriteTrace(String.Format("Sending 0 search responses."));
|
||||
//WriteTrace(String.Format("Sending 0 search responses."));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -413,7 +413,7 @@ namespace Rssdp.Infrastructure
|
|||
|
||||
//DisposeRebroadcastTimer();
|
||||
|
||||
WriteTrace("Begin Sending Alive Notifications For All Devices");
|
||||
//WriteTrace("Begin Sending Alive Notifications For All Devices");
|
||||
|
||||
_LastNotificationTime = DateTime.Now;
|
||||
|
||||
|
@ -430,7 +430,7 @@ namespace Rssdp.Infrastructure
|
|||
SendAliveNotifications(device, true);
|
||||
}
|
||||
|
||||
WriteTrace("Completed Sending Alive Notifications For All Devices");
|
||||
//WriteTrace("Completed Sending Alive Notifications For All Devices");
|
||||
}
|
||||
catch (ObjectDisposedException ex)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue
Block a user