Merge pull request #2796 from MediaBrowser/dev

Dev
This commit is contained in:
Luke 2017-08-06 19:01:30 -04:00 committed by GitHub
commit e9bf2e4132
28 changed files with 113 additions and 285 deletions

View File

@ -410,7 +410,7 @@ namespace Emby.Server.Core
{ {
Logger.ErrorException("Error in {0}", ex, name); Logger.ErrorException("Error in {0}", ex, name);
} }
Logger.Info("Entry point completed: {0}. Duration: {1} seconds", name, (DateTime.UtcNow - now).TotalSeconds.ToString(CultureInfo.InvariantCulture)); Logger.Info("Entry point completed: {0}. Duration: {1} seconds", name, (DateTime.UtcNow - now).TotalSeconds.ToString(CultureInfo.InvariantCulture), "ImageInfos");
} }
Logger.Info("All entry points have started"); Logger.Info("All entry points have started");
@ -431,41 +431,41 @@ namespace Emby.Server.Core
var result = new JsonSerializer(FileSystemManager, LogManager.GetLogger("JsonSerializer")); var result = new JsonSerializer(FileSystemManager, LogManager.GetLogger("JsonSerializer"));
ServiceStack.Text.JsConfig<LiveTvProgram>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "ExtraType" }; ServiceStack.Text.JsConfig<LiveTvProgram>.ExcludePropertyNames = new[] { "ProviderIds" };
ServiceStack.Text.JsConfig<LiveTvChannel>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "ExtraType" }; ServiceStack.Text.JsConfig<LiveTvChannel>.ExcludePropertyNames = new[] { "ProviderIds" };
ServiceStack.Text.JsConfig<LiveTvVideoRecording>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "ExtraType" }; ServiceStack.Text.JsConfig<LiveTvVideoRecording>.ExcludePropertyNames = new[] { "ProviderIds" };
ServiceStack.Text.JsConfig<LiveTvAudioRecording>.ExcludePropertyNames = new[] { "Artists", "AlbumArtists", "ChannelMediaSources", "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "ExtraType" }; ServiceStack.Text.JsConfig<LiveTvAudioRecording>.ExcludePropertyNames = new[] { "ProviderIds" };
ServiceStack.Text.JsConfig<Series>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "ExtraType" }; ServiceStack.Text.JsConfig<Series>.ExcludePropertyNames = new[] { "ProviderIds" };
ServiceStack.Text.JsConfig<Audio>.ExcludePropertyNames = new[] { "Artists", "AlbumArtists", "ChannelMediaSources", "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "ExtraType" }; ServiceStack.Text.JsConfig<Audio>.ExcludePropertyNames = new[] { "ProviderIds" };
ServiceStack.Text.JsConfig<MusicAlbum>.ExcludePropertyNames = new[] { "Artists", "AlbumArtists", "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "ExtraType" }; ServiceStack.Text.JsConfig<MusicAlbum>.ExcludePropertyNames = new[] { "ProviderIds" };
ServiceStack.Text.JsConfig<MusicArtist>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "ExtraType" }; ServiceStack.Text.JsConfig<MusicArtist>.ExcludePropertyNames = new[] { "ProviderIds" };
ServiceStack.Text.JsConfig<MusicGenre>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "ExtraType" }; ServiceStack.Text.JsConfig<MusicGenre>.ExcludePropertyNames = new[] { "ProviderIds" };
ServiceStack.Text.JsConfig<MusicVideo>.ExcludePropertyNames = new[] { "Artists", "AlbumArtists", "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "ExtraType" }; ServiceStack.Text.JsConfig<MusicVideo>.ExcludePropertyNames = new[] { "ProviderIds" };
ServiceStack.Text.JsConfig<Movie>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "ExtraType" }; ServiceStack.Text.JsConfig<Movie>.ExcludePropertyNames = new[] { "ProviderIds" };
ServiceStack.Text.JsConfig<Playlist>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "ExtraType" }; ServiceStack.Text.JsConfig<Playlist>.ExcludePropertyNames = new[] { "ProviderIds" };
ServiceStack.Text.JsConfig<AudioPodcast>.ExcludePropertyNames = new[] { "Artists", "AlbumArtists", "ChannelMediaSources", "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "ExtraType" }; ServiceStack.Text.JsConfig<AudioPodcast>.ExcludePropertyNames = new[] { "ProviderIds" };
ServiceStack.Text.JsConfig<AudioBook>.ExcludePropertyNames = new[] { "Artists", "AlbumArtists", "ChannelMediaSources", "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "ExtraType" }; ServiceStack.Text.JsConfig<AudioBook>.ExcludePropertyNames = new[] { "ProviderIds" };
ServiceStack.Text.JsConfig<Trailer>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "ExtraType" }; ServiceStack.Text.JsConfig<Trailer>.ExcludePropertyNames = new[] { "ProviderIds" };
ServiceStack.Text.JsConfig<BoxSet>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "ExtraType" }; ServiceStack.Text.JsConfig<BoxSet>.ExcludePropertyNames = new[] { "ProviderIds" };
ServiceStack.Text.JsConfig<Episode>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "ExtraType" }; ServiceStack.Text.JsConfig<Episode>.ExcludePropertyNames = new[] { "ProviderIds" };
ServiceStack.Text.JsConfig<Season>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "ExtraType" }; ServiceStack.Text.JsConfig<Season>.ExcludePropertyNames = new[] { "ProviderIds" };
ServiceStack.Text.JsConfig<Book>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "ExtraType" }; ServiceStack.Text.JsConfig<Book>.ExcludePropertyNames = new[] { "ProviderIds" };
ServiceStack.Text.JsConfig<CollectionFolder>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "ExtraType" }; ServiceStack.Text.JsConfig<CollectionFolder>.ExcludePropertyNames = new[] { "ProviderIds" };
ServiceStack.Text.JsConfig<Folder>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "ExtraType" }; ServiceStack.Text.JsConfig<Folder>.ExcludePropertyNames = new[] { "ProviderIds" };
ServiceStack.Text.JsConfig<Game>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "ExtraType" }; ServiceStack.Text.JsConfig<Game>.ExcludePropertyNames = new[] { "ProviderIds" };
ServiceStack.Text.JsConfig<GameGenre>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "ExtraType" }; ServiceStack.Text.JsConfig<GameGenre>.ExcludePropertyNames = new[] { "ProviderIds" };
ServiceStack.Text.JsConfig<GameSystem>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "ExtraType" }; ServiceStack.Text.JsConfig<GameSystem>.ExcludePropertyNames = new[] { "ProviderIds" };
ServiceStack.Text.JsConfig<Genre>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "ExtraType" }; ServiceStack.Text.JsConfig<Genre>.ExcludePropertyNames = new[] { "ProviderIds" };
ServiceStack.Text.JsConfig<Person>.ExcludePropertyNames = new[] { "PlaceOfBirth", "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "ExtraType" }; ServiceStack.Text.JsConfig<Person>.ExcludePropertyNames = new[] { "ProviderIds" };
ServiceStack.Text.JsConfig<Photo>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "ExtraType" }; ServiceStack.Text.JsConfig<Photo>.ExcludePropertyNames = new[] { "ProviderIds" };
ServiceStack.Text.JsConfig<PhotoAlbum>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "ExtraType" }; ServiceStack.Text.JsConfig<PhotoAlbum>.ExcludePropertyNames = new[] { "ProviderIds" };
ServiceStack.Text.JsConfig<Studio>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "ExtraType" }; ServiceStack.Text.JsConfig<Studio>.ExcludePropertyNames = new[] { "ProviderIds" };
ServiceStack.Text.JsConfig<UserRootFolder>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "ExtraType" }; ServiceStack.Text.JsConfig<UserRootFolder>.ExcludePropertyNames = new[] { "ProviderIds" };
ServiceStack.Text.JsConfig<UserView>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "ExtraType" }; ServiceStack.Text.JsConfig<UserView>.ExcludePropertyNames = new[] { "ProviderIds" };
ServiceStack.Text.JsConfig<Video>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "ExtraType" }; ServiceStack.Text.JsConfig<Video>.ExcludePropertyNames = new[] { "ProviderIds" };
ServiceStack.Text.JsConfig<Year>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "ExtraType" }; ServiceStack.Text.JsConfig<Year>.ExcludePropertyNames = new[] { "ProviderIds" };
ServiceStack.Text.JsConfig<Channel>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "ExtraType" }; ServiceStack.Text.JsConfig<Channel>.ExcludePropertyNames = new[] { "ProviderIds" };
ServiceStack.Text.JsConfig<AggregateFolder>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "ExtraType" }; ServiceStack.Text.JsConfig<AggregateFolder>.ExcludePropertyNames = new[] { "ProviderIds" };
return result; return result;
} }

View File

@ -228,7 +228,6 @@ namespace Emby.Server.Implementations.Data
AddColumn(db, "TypedBaseItems", "TopParentId", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "TopParentId", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "TrailerTypes", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "TrailerTypes", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "CriticRating", "Float", existingColumnNames); AddColumn(db, "TypedBaseItems", "CriticRating", "Float", existingColumnNames);
AddColumn(db, "TypedBaseItems", "InheritedTags", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "CleanName", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "CleanName", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "PresentationUniqueKey", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "PresentationUniqueKey", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "OriginalTitle", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "OriginalTitle", "Text", existingColumnNames);
@ -442,7 +441,6 @@ namespace Emby.Server.Implementations.Data
"SeriesId", "SeriesId",
"PresentationUniqueKey", "PresentationUniqueKey",
"InheritedParentalRatingValue", "InheritedParentalRatingValue",
"InheritedTags",
"ExternalSeriesId", "ExternalSeriesId",
"Tagline", "Tagline",
"ProviderIds", "ProviderIds",
@ -552,7 +550,6 @@ namespace Emby.Server.Implementations.Data
"TopParentId", "TopParentId",
"TrailerTypes", "TrailerTypes",
"CriticRating", "CriticRating",
"InheritedTags",
"CleanName", "CleanName",
"PresentationUniqueKey", "PresentationUniqueKey",
"OriginalTitle", "OriginalTitle",
@ -633,7 +630,7 @@ namespace Emby.Server.Implementations.Data
CheckDisposed(); CheckDisposed();
var tuples = new List<Tuple<BaseItem, List<Guid>, BaseItem, string>>(); var tuples = new List<Tuple<BaseItem, List<Guid>, BaseItem, string, List<string>>>();
foreach (var item in items) foreach (var item in items)
{ {
var ancestorIds = item.SupportsAncestors ? var ancestorIds = item.SupportsAncestors ?
@ -643,8 +640,9 @@ namespace Emby.Server.Implementations.Data
var topParent = item.GetTopParent(); var topParent = item.GetTopParent();
var userdataKey = item.GetUserDataKeys().FirstOrDefault(); var userdataKey = item.GetUserDataKeys().FirstOrDefault();
var inheritedTags = item.GetInheritedTags();
tuples.Add(new Tuple<BaseItem, List<Guid>, BaseItem, string>(item, ancestorIds, topParent, userdataKey)); tuples.Add(new Tuple<BaseItem, List<Guid>, BaseItem, string, List<string>>(item, ancestorIds, topParent, userdataKey, inheritedTags));
} }
using (WriteLock.Write()) using (WriteLock.Write())
@ -654,12 +652,13 @@ namespace Emby.Server.Implementations.Data
connection.RunInTransaction(db => connection.RunInTransaction(db =>
{ {
SaveItemsInTranscation(db, tuples); SaveItemsInTranscation(db, tuples);
}, TransactionMode); }, TransactionMode);
} }
} }
} }
private void SaveItemsInTranscation(IDatabaseConnection db, List<Tuple<BaseItem, List<Guid>, BaseItem, string>> tuples) private void SaveItemsInTranscation(IDatabaseConnection db, List<Tuple<BaseItem, List<Guid>, BaseItem, string, List<string>>> tuples)
{ {
var requiresReset = false; var requiresReset = false;
@ -690,12 +689,14 @@ namespace Emby.Server.Implementations.Data
SaveItem(item, topParent, userDataKey, saveItemStatement); SaveItem(item, topParent, userDataKey, saveItemStatement);
//Logger.Debug(_saveItemCommand.CommandText); //Logger.Debug(_saveItemCommand.CommandText);
var inheritedTags = tuple.Item5;
if (item.SupportsAncestors) if (item.SupportsAncestors)
{ {
UpdateAncestors(item.Id, tuple.Item2, db, deleteAncestorsStatement, updateAncestorsStatement); UpdateAncestors(item.Id, tuple.Item2, db, deleteAncestorsStatement, updateAncestorsStatement);
} }
UpdateItemValues(item.Id, GetItemValuesToSave(item), db); UpdateItemValues(item.Id, GetItemValuesToSave(item, inheritedTags), db);
requiresReset = true; requiresReset = true;
} }
@ -806,7 +807,7 @@ namespace Emby.Server.Implementations.Data
saveItemStatement.TryBind("@RunTimeTicks", item.RunTimeTicks); saveItemStatement.TryBind("@RunTimeTicks", item.RunTimeTicks);
saveItemStatement.TryBind("@HomePageUrl", item.HomePageUrl); saveItemStatement.TryBind("@HomePageUrl", item.HomePageUrl);
saveItemStatement.TryBind("@DisplayMediaType", item.DisplayMediaType); saveItemStatement.TryBindNull("@DisplayMediaType");
saveItemStatement.TryBind("@DateCreated", item.DateCreated); saveItemStatement.TryBind("@DateCreated", item.DateCreated);
saveItemStatement.TryBind("@DateModified", item.DateModified); saveItemStatement.TryBind("@DateModified", item.DateModified);
@ -900,16 +901,6 @@ namespace Emby.Server.Implementations.Data
saveItemStatement.TryBind("@CriticRating", item.CriticRating); saveItemStatement.TryBind("@CriticRating", item.CriticRating);
var inheritedTags = item.InheritedTags;
if (inheritedTags.Count > 0)
{
saveItemStatement.TryBind("@InheritedTags", string.Join("|", inheritedTags.ToArray()));
}
else
{
saveItemStatement.TryBindNull("@InheritedTags");
}
if (string.IsNullOrWhiteSpace(item.Name)) if (string.IsNullOrWhiteSpace(item.Name))
{ {
saveItemStatement.TryBindNull("@CleanName"); saveItemStatement.TryBindNull("@CleanName");
@ -1579,11 +1570,15 @@ namespace Emby.Server.Implementations.Data
index++; index++;
} }
var video = item as Video;
if (HasField(query, ItemFields.DisplayMediaType)) if (HasField(query, ItemFields.DisplayMediaType))
{
if (video != null)
{ {
if (!reader.IsDBNull(index)) if (!reader.IsDBNull(index))
{ {
item.DisplayMediaType = reader.GetString(index); video.DisplayMediaType = reader.GetString(index);
}
} }
index++; index++;
} }
@ -1739,7 +1734,6 @@ namespace Emby.Server.Implementations.Data
index++; index++;
} }
var video = item as Video;
if (video != null) if (video != null)
{ {
if (!reader.IsDBNull(index)) if (!reader.IsDBNull(index))
@ -1842,15 +1836,6 @@ namespace Emby.Server.Implementations.Data
index++; index++;
} }
if (HasField(query, ItemFields.Tags))
{
if (!reader.IsDBNull(index))
{
item.InheritedTags = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).ToList();
}
index++;
}
if (HasField(query, ItemFields.ExternalSeriesId)) if (HasField(query, ItemFields.ExternalSeriesId))
{ {
if (!reader.IsDBNull(index)) if (!reader.IsDBNull(index))
@ -2245,7 +2230,7 @@ namespace Emby.Server.Implementations.Data
} }
if (field == ItemFields.Tags) if (field == ItemFields.Tags)
{ {
return new[] { "Tags", "InheritedTags" }; return new[] { "Tags" };
} }
return new[] { field.ToString() }; return new[] { field.ToString() };
@ -2258,8 +2243,8 @@ namespace Emby.Server.Implementations.Data
switch (name) switch (name)
{ {
case ItemFields.HomePageUrl: case ItemFields.HomePageUrl:
case ItemFields.DisplayMediaType:
case ItemFields.CustomRating: case ItemFields.CustomRating:
case ItemFields.DisplayMediaType:
case ItemFields.ProductionLocations: case ItemFields.ProductionLocations:
case ItemFields.Settings: case ItemFields.Settings:
case ItemFields.OriginalTitle: case ItemFields.OriginalTitle:
@ -4555,26 +4540,12 @@ namespace Emby.Server.Implementations.Data
whereClauses.Add(string.Format("(InheritedParentalRatingValue > 0 or UnratedType not in ({0}))", inClause)); whereClauses.Add(string.Format("(InheritedParentalRatingValue > 0 or UnratedType not in ({0}))", inClause));
} }
var excludeTagIndex = 0; if (query.ExcludeInheritedTags.Length > 0)
foreach (var excludeTag in query.ExcludeTags)
{ {
whereClauses.Add("(Tags is null OR Tags not like @excludeTag" + excludeTagIndex + ")"); var tagValues = query.ExcludeInheritedTags.Select(i => "'" + GetCleanValue(i) + "'").ToArray();
if (statement != null) var tagValuesList = string.Join(",", tagValues);
{
statement.TryBind("@excludeTag" + excludeTagIndex, "%" + excludeTag + "%");
}
excludeTagIndex++;
}
excludeTagIndex = 0; whereClauses.Add("((select CleanValue from itemvalues where ItemId=Guid and Type=6 and cleanvalue in (" + tagValuesList + ")) is null)");
foreach (var excludeTag in query.ExcludeInheritedTags)
{
whereClauses.Add("(InheritedTags is null OR InheritedTags not like @excludeInheritedTag" + excludeTagIndex + ")");
if (statement != null)
{
statement.TryBind("@excludeInheritedTag" + excludeTagIndex, "%" + excludeTag + "%");
}
excludeTagIndex++;
} }
return whereClauses; return whereClauses;
@ -4724,7 +4695,7 @@ namespace Emby.Server.Implementations.Data
{ {
var newValues = new List<Tuple<Guid, string>>(); var newValues = new List<Tuple<Guid, string>>();
var commandText = "select Guid,InheritedTags,(select group_concat(Tags, '|') from TypedBaseItems where (guid=outer.guid) OR (guid in (Select AncestorId from AncestorIds where ItemId=Outer.guid))) as NewInheritedTags from typedbaseitems as Outer where NewInheritedTags <> InheritedTags"; var commandText = "select Guid,(select group_concat(Tags, '|') from TypedBaseItems where (guid=outer.guid) OR (guid in (Select AncestorId from AncestorIds where ItemId=Outer.guid))) as NewInheritedTags from typedbaseitems as Outer";
using (WriteLock.Write()) using (WriteLock.Write())
{ {
@ -5445,7 +5416,7 @@ namespace Emby.Server.Implementations.Data
return counts; return counts;
} }
private List<Tuple<int, string>> GetItemValuesToSave(BaseItem item) private List<Tuple<int, string>> GetItemValuesToSave(BaseItem item, List<string> inheritedTags)
{ {
var list = new List<Tuple<int, string>>(); var list = new List<Tuple<int, string>>();
@ -5465,6 +5436,10 @@ namespace Emby.Server.Implementations.Data
list.AddRange(item.Studios.Select(i => new Tuple<int, string>(3, i))); list.AddRange(item.Studios.Select(i => new Tuple<int, string>(3, i)));
list.AddRange(item.Tags.Select(i => new Tuple<int, string>(4, i))); list.AddRange(item.Tags.Select(i => new Tuple<int, string>(4, i)));
// keywords was 5
list.AddRange(inheritedTags.Select(i => new Tuple<int, string>(6, i)));
return list; return list;
} }

View File

@ -517,7 +517,7 @@ namespace Emby.Server.Implementations.Dto
} }
} }
if (!(item is LiveTvProgram) || fields.Contains(ItemFields.PlayAccess)) if (/*!(item is LiveTvProgram) ||*/ fields.Contains(ItemFields.PlayAccess))
{ {
dto.PlayAccess = item.GetPlayAccess(user); dto.PlayAccess = item.GetPlayAccess(user);
} }
@ -864,11 +864,6 @@ namespace Emby.Server.Implementations.Dto
dto.DateCreated = item.DateCreated; dto.DateCreated = item.DateCreated;
} }
if (fields.Contains(ItemFields.DisplayMediaType))
{
dto.DisplayMediaType = item.DisplayMediaType;
}
if (fields.Contains(ItemFields.Settings)) if (fields.Contains(ItemFields.Settings))
{ {
dto.LockedFields = item.LockedFields; dto.LockedFields = item.LockedFields;

View File

@ -130,14 +130,6 @@ namespace Emby.Server.Implementations.IO
paths = _affectedPaths.ToList(); paths = _affectedPaths.ToList();
} }
// Extend the timer as long as any of the paths are still being written to.
if (paths.Any(IsFileLocked))
{
Logger.Info("Timer extended.");
RestartTimer();
return;
}
Logger.Debug("Timer stopped."); Logger.Debug("Timer stopped.");
DisposeTimer(); DisposeTimer();
@ -229,90 +221,6 @@ namespace Emby.Server.Implementations.IO
return item; return item;
} }
private bool IsFileLocked(string path)
{
if (_environmentInfo.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.Windows)
{
// Causing lockups on linux
return false;
}
// Only try to open video files
if (!_libraryManager.IsVideoFile(path))
{
return false;
}
try
{
var data = _fileSystem.GetFileSystemInfo(path);
if (!data.Exists
|| data.IsDirectory
// Opening a writable stream will fail with readonly files
|| data.IsReadOnly)
{
return false;
}
}
catch (IOException)
{
return false;
}
catch (Exception ex)
{
Logger.ErrorException("Error getting file system info for: {0}", ex, path);
return false;
}
// In order to determine if the file is being written to, we have to request write access
// But if the server only has readonly access, this is going to cause this entire algorithm to fail
// So we'll take a best guess about our access level
//var requestedFileAccess = ConfigurationManager.Configuration.SaveLocalMeta
// ? FileAccessMode.ReadWrite
// : FileAccessMode.Read;
var requestedFileAccess = FileAccessMode.Read;
try
{
using (_fileSystem.GetFileStream(path, FileOpenMode.Open, requestedFileAccess, FileShareMode.ReadWrite))
{
//file is not locked
return false;
}
}
catch (DirectoryNotFoundException)
{
// File may have been deleted
return false;
}
catch (FileNotFoundException)
{
// File may have been deleted
return false;
}
catch (UnauthorizedAccessException)
{
Logger.Debug("No write permission for: {0}.", path);
return false;
}
catch (IOException)
{
//the file is unavailable because it is:
//still being written to
//or being processed by another thread
//or does not exist (has already been processed)
Logger.Debug("{0} is locked.", path);
return true;
}
catch (Exception ex)
{
Logger.ErrorException("Error determining if file is locked: {0}", ex, path);
return false;
}
}
private void DisposeTimer() private void DisposeTimer()
{ {
lock (_timerLock) lock (_timerLock)

View File

@ -2350,6 +2350,7 @@ namespace Emby.Server.Implementations.LiveTv
var addCurrentProgram = options.AddCurrentProgram; var addCurrentProgram = options.AddCurrentProgram;
var addMediaSources = options.Fields.Contains(ItemFields.MediaSources); var addMediaSources = options.Fields.Contains(ItemFields.MediaSources);
var addServiceName = options.Fields.Contains(ItemFields.ServiceName);
foreach (var tuple in tuples) foreach (var tuple in tuples)
{ {
@ -2359,7 +2360,11 @@ namespace Emby.Server.Implementations.LiveTv
dto.Number = channel.Number; dto.Number = channel.Number;
dto.ChannelNumber = channel.Number; dto.ChannelNumber = channel.Number;
dto.ChannelType = channel.ChannelType; dto.ChannelType = channel.ChannelType;
if (addServiceName)
{
dto.ServiceName = channel.ServiceName; dto.ServiceName = channel.ServiceName;
}
currentChannelsDict[dto.Id] = dto; currentChannelsDict[dto.Id] = dto;

View File

@ -122,17 +122,11 @@ namespace Emby.Server.Implementations.MediaEncoder
continue; continue;
} }
List<string> playableStreamFileNames = null;
if (video.VideoType == VideoType.BluRay || video.VideoType == VideoType.Dvd) if (video.VideoType == VideoType.BluRay || video.VideoType == VideoType.Dvd)
{ {
continue; continue;
} }
if (playableStreamFileNames == null)
{
playableStreamFileNames = new List<string>();
}
try try
{ {
// Add some time for the first chapter to make sure we don't end up with a black image // Add some time for the first chapter to make sure we don't end up with a black image
@ -140,7 +134,7 @@ namespace Emby.Server.Implementations.MediaEncoder
var protocol = MediaProtocol.File; var protocol = MediaProtocol.File;
var inputPath = MediaEncoderHelpers.GetInputArgument(_fileSystem, video.Path, protocol, null, playableStreamFileNames); var inputPath = MediaEncoderHelpers.GetInputArgument(_fileSystem, video.Path, protocol, null, new List<string>());
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(path)); _fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(path));

View File

@ -438,7 +438,7 @@ namespace MediaBrowser.Api.Playback
if (mediaSource.SupportsDirectStream) if (mediaSource.SupportsDirectStream)
{ {
options.MaxBitrate = GetMaxBitrate(maxBitrate); options.MaxBitrate = GetMaxBitrate(maxBitrate, user);
if (item is Audio) if (item is Audio)
{ {
@ -473,7 +473,7 @@ namespace MediaBrowser.Api.Playback
if (mediaSource.SupportsTranscoding) if (mediaSource.SupportsTranscoding)
{ {
options.MaxBitrate = GetMaxBitrate(maxBitrate); options.MaxBitrate = GetMaxBitrate(maxBitrate, user);
// The MediaSource supports direct stream, now test to see if the client supports it // The MediaSource supports direct stream, now test to see if the client supports it
var streamInfo = string.Equals(item.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase) ? var streamInfo = string.Equals(item.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase) ?
@ -507,10 +507,15 @@ namespace MediaBrowser.Api.Playback
} }
} }
private long? GetMaxBitrate(long? clientMaxBitrate) private long? GetMaxBitrate(long? clientMaxBitrate, User user)
{ {
var maxBitrate = clientMaxBitrate; var maxBitrate = clientMaxBitrate;
var remoteClientMaxBitrate = _config.Configuration.RemoteClientBitrateLimit; var remoteClientMaxBitrate = user == null ? 0 : user.Policy.RemoteClientBitrateLimit;
if (remoteClientMaxBitrate <= 0)
{
remoteClientMaxBitrate = _config.Configuration.RemoteClientBitrateLimit;
}
if (remoteClientMaxBitrate > 0) if (remoteClientMaxBitrate > 0)
{ {

View File

@ -198,7 +198,6 @@ namespace MediaBrowser.Api
Type = item.GetClientTypeName(), Type = item.GetClientTypeName(),
MediaType = item.MediaType, MediaType = item.MediaType,
MatchedTerm = hintInfo.MatchedTerm, MatchedTerm = hintInfo.MatchedTerm,
DisplayMediaType = item.DisplayMediaType,
RunTimeTicks = item.RunTimeTicks, RunTimeTicks = item.RunTimeTicks,
ProductionYear = item.ProductionYear, ProductionYear = item.ProductionYear,
ChannelId = item.ChannelId, ChannelId = item.ChannelId,

View File

@ -8,7 +8,6 @@ namespace MediaBrowser.Controller.Collections
public ManualCollectionsFolder() public ManualCollectionsFolder()
{ {
Name = "Collections"; Name = "Collections";
DisplayMediaType = "CollectionFolder";
} }
public override bool IsHidden public override bool IsHidden

View File

@ -28,8 +28,10 @@ namespace MediaBrowser.Controller.Entities.Audio
/// Gets or sets the artist. /// Gets or sets the artist.
/// </summary> /// </summary>
/// <value>The artist.</value> /// <value>The artist.</value>
[IgnoreDataMember]
public List<string> Artists { get; set; } public List<string> Artists { get; set; }
[IgnoreDataMember]
public List<string> AlbumArtists { get; set; } public List<string> AlbumArtists { get; set; }
[IgnoreDataMember] [IgnoreDataMember]

View File

@ -51,7 +51,6 @@ namespace MediaBrowser.Controller.Entities
ProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); ProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
LockedFields = new List<MetadataFields>(); LockedFields = new List<MetadataFields>();
ImageInfos = new List<ItemImageInfo>(); ImageInfos = new List<ItemImageInfo>();
InheritedTags = new List<string>();
ProductionLocations = new List<string>(); ProductionLocations = new List<string>();
} }
@ -73,7 +72,9 @@ namespace MediaBrowser.Controller.Entities
public static string ThemeSongFilename = "theme"; public static string ThemeSongFilename = "theme";
public static string ThemeVideosFolderName = "backdrops"; public static string ThemeVideosFolderName = "backdrops";
[IgnoreDataMember]
public List<Guid> ThemeSongIds { get; set; } public List<Guid> ThemeSongIds { get; set; }
[IgnoreDataMember]
public List<Guid> ThemeVideoIds { get; set; } public List<Guid> ThemeVideoIds { get; set; }
[IgnoreDataMember] [IgnoreDataMember]
@ -87,6 +88,7 @@ namespace MediaBrowser.Controller.Entities
[IgnoreDataMember] [IgnoreDataMember]
public string Tagline { get; set; } public string Tagline { get; set; }
[IgnoreDataMember]
public List<ItemImageInfo> ImageInfos { get; set; } public List<ItemImageInfo> ImageInfos { get; set; }
[IgnoreDataMember] [IgnoreDataMember]
@ -197,7 +199,9 @@ namespace MediaBrowser.Controller.Entities
get { return PremiereDate.HasValue && PremiereDate.Value.ToLocalTime().Date >= DateTime.Now.Date; } get { return PremiereDate.HasValue && PremiereDate.Value.ToLocalTime().Date >= DateTime.Now.Date; }
} }
[IgnoreDataMember]
public int? TotalBitrate { get; set; } public int? TotalBitrate { get; set; }
[IgnoreDataMember]
public ExtraType? ExtraType { get; set; } public ExtraType? ExtraType { get; set; }
[IgnoreDataMember] [IgnoreDataMember]
@ -802,13 +806,6 @@ namespace MediaBrowser.Controller.Entities
[IgnoreDataMember] [IgnoreDataMember]
public DateTime? EndDate { get; set; } public DateTime? EndDate { get; set; }
/// <summary>
/// Gets or sets the display type of the media.
/// </summary>
/// <value>The display type of the media.</value>
[IgnoreDataMember]
public string DisplayMediaType { get; set; }
/// <summary> /// <summary>
/// Gets or sets the official rating. /// Gets or sets the official rating.
/// </summary> /// </summary>
@ -819,9 +816,6 @@ namespace MediaBrowser.Controller.Entities
[IgnoreDataMember] [IgnoreDataMember]
public int InheritedParentalRatingValue { get; set; } public int InheritedParentalRatingValue { get; set; }
[IgnoreDataMember]
public List<string> InheritedTags { get; set; }
/// <summary> /// <summary>
/// Gets or sets the critic rating. /// Gets or sets the critic rating.
/// </summary> /// </summary>
@ -864,6 +858,7 @@ namespace MediaBrowser.Controller.Entities
[IgnoreDataMember] [IgnoreDataMember]
public List<string> Tags { get; set; } public List<string> Tags { get; set; }
[IgnoreDataMember]
public List<string> ProductionLocations { get; set; } public List<string> ProductionLocations { get; set; }
/// <summary> /// <summary>

View File

@ -97,12 +97,6 @@ namespace MediaBrowser.Controller.Entities
/// <returns>Task.</returns> /// <returns>Task.</returns>
Task SwapImages(ImageType type, int index1, int index2); Task SwapImages(ImageType type, int index1, int index2);
/// <summary>
/// Gets the display type of the media.
/// </summary>
/// <value>The display type of the media.</value>
string DisplayMediaType { get; set; }
/// <summary> /// <summary>
/// Gets or sets the primary image path. /// Gets or sets the primary image path.
/// </summary> /// </summary>
@ -208,6 +202,8 @@ namespace MediaBrowser.Controller.Entities
double? GetDefaultPrimaryImageAspectRatio(); double? GetDefaultPrimaryImageAspectRatio();
int? ProductionYear { get; set; } int? ProductionYear { get; set; }
List<string> Tags { get; set; }
} }
public static class HasImagesExtensions public static class HasImagesExtensions

View File

@ -64,7 +64,6 @@ namespace MediaBrowser.Controller.Entities
int? GetInheritedParentalRatingValue(); int? GetInheritedParentalRatingValue();
int InheritedParentalRatingValue { get; set; } int InheritedParentalRatingValue { get; set; }
List<string> GetInheritedTags(); List<string> GetInheritedTags();
List<string> InheritedTags { get; set; }
long? RunTimeTicks { get; set; } long? RunTimeTicks { get; set; }
} }
} }

View File

@ -8,6 +8,7 @@ namespace MediaBrowser.Controller.Entities
{ {
public class MusicVideo : Video, IHasArtist, IHasMusicGenres, IHasLookupInfo<MusicVideoInfo> public class MusicVideo : Video, IHasArtist, IHasMusicGenres, IHasLookupInfo<MusicVideoInfo>
{ {
[IgnoreDataMember]
public List<string> Artists { get; set; } public List<string> Artists { get; set; }
public MusicVideo() public MusicVideo()

View File

@ -52,6 +52,12 @@ namespace MediaBrowser.Controller.Entities
} }
} }
/// <summary>
/// Gets or sets the display type of the media.
/// </summary>
/// <value>The display type of the media.</value>
public string DisplayMediaType { get; set; }
[IgnoreDataMember] [IgnoreDataMember]
public override bool SupportsPositionTicksResume public override bool SupportsPositionTicksResume
{ {

View File

@ -179,18 +179,6 @@ namespace MediaBrowser.LocalMetadata.Parsers
item.Name = reader.ReadElementContentAsString(); item.Name = reader.ReadElementContentAsString();
break; break;
case "Type":
{
var type = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(type) && !type.Equals("none", StringComparison.OrdinalIgnoreCase))
{
item.DisplayMediaType = type;
}
break;
}
case "CriticRating": case "CriticRating":
{ {
var text = reader.ReadElementContentAsString(); var text = reader.ReadElementContentAsString();

View File

@ -106,7 +106,6 @@ namespace MediaBrowser.LocalMetadata.Savers
"Trailers", "Trailers",
"TVcomId", "TVcomId",
"TvDbId", "TvDbId",
"Type",
"TVRageId", "TVRageId",
"Website", "Website",
"Zap2ItId", "Zap2ItId",
@ -308,11 +307,6 @@ namespace MediaBrowser.LocalMetadata.Savers
writer.WriteElementString("LockedFields", string.Join("|", item.LockedFields.Select(i => i.ToString()).ToArray())); writer.WriteElementString("LockedFields", string.Join("|", item.LockedFields.Select(i => i.ToString()).ToArray()));
} }
if (!string.IsNullOrEmpty(item.DisplayMediaType))
{
writer.WriteElementString("Type", item.DisplayMediaType);
}
if (item.CriticRating.HasValue) if (item.CriticRating.HasValue)
{ {
writer.WriteElementString("CriticRating", item.CriticRating.Value.ToString(UsCulture)); writer.WriteElementString("CriticRating", item.CriticRating.Value.ToString(UsCulture));

View File

@ -523,12 +523,6 @@ namespace MediaBrowser.Model.Dto
/// <value>The type of the video.</value> /// <value>The type of the video.</value>
public VideoType? VideoType { get; set; } public VideoType? VideoType { get; set; }
/// <summary>
/// Gets or sets the display type of the media.
/// </summary>
/// <value>The display type of the media.</value>
public string DisplayMediaType { get; set; }
/// <summary> /// <summary>
/// Gets or sets the part count. /// Gets or sets the part count.
/// </summary> /// </summary>

View File

@ -91,12 +91,6 @@ namespace MediaBrowser.Model.Search
/// <value>The type of the media.</value> /// <value>The type of the media.</value>
public string MediaType { get; set; } public string MediaType { get; set; }
/// <summary>
/// Gets or sets the display type of the media.
/// </summary>
/// <value>The display type of the media.</value>
public string DisplayMediaType { get; set; }
public DateTime? StartDate { get; set; } public DateTime? StartDate { get; set; }
public DateTime? EndDate { get; set; } public DateTime? EndDate { get; set; }

View File

@ -68,6 +68,8 @@ namespace MediaBrowser.Model.Users
public string[] BlockedMediaFolders { get; set; } public string[] BlockedMediaFolders { get; set; }
public string[] BlockedChannels { get; set; } public string[] BlockedChannels { get; set; }
public int RemoteClientBitrateLimit { get; set; }
public UserPolicy() public UserPolicy()
{ {
EnableContentDeletion = true; EnableContentDeletion = true;

View File

@ -302,13 +302,6 @@ namespace MediaBrowser.Providers.Manager
updateType |= ItemUpdateType.MetadataImport; updateType |= ItemUpdateType.MetadataImport;
} }
var inheritedTags = item.GetInheritedTags();
if (!inheritedTags.SequenceEqual(item.InheritedTags, StringComparer.Ordinal))
{
item.InheritedTags = inheritedTags;
updateType |= ItemUpdateType.MetadataImport;
}
return updateType; return updateType;
} }

View File

@ -204,12 +204,17 @@ namespace MediaBrowser.Providers.Manager
//if (!lockedFields.Contains(MetadataFields.DisplayMediaType)) //if (!lockedFields.Contains(MetadataFields.DisplayMediaType))
{ {
if (replaceData || string.IsNullOrEmpty(target.DisplayMediaType)) var targetVideo = target as Video;
var sourceVideo = source as Video;
if (sourceVideo != null && targetVideo != null)
{
if (replaceData || string.IsNullOrEmpty(targetVideo.DisplayMediaType))
{ {
// Safeguard against incoming data having an emtpy name // Safeguard against incoming data having an emtpy name
if (!string.IsNullOrWhiteSpace(source.DisplayMediaType)) if (!string.IsNullOrWhiteSpace(sourceVideo.DisplayMediaType))
{ {
target.DisplayMediaType = source.DisplayMediaType; targetVideo.DisplayMediaType = sourceVideo.DisplayMediaType;
}
} }
} }
} }

View File

@ -45,7 +45,7 @@ namespace MediaBrowser.Providers.MediaInfo
} }
// No support for this // No support for this
if (video.VideoType == VideoType.Iso) if (video.VideoType == VideoType.Iso || video.VideoType == VideoType.Dvd || video.VideoType == VideoType.BluRay)
{ {
return Task.FromResult(new DynamicImageResponse { HasImage = false }); return Task.FromResult(new DynamicImageResponse { HasImage = false });
} }

View File

@ -316,10 +316,6 @@ namespace MediaBrowser.XbmcMetadata.Parsers
break; break;
} }
case "type":
item.DisplayMediaType = reader.ReadElementContentAsString();
break;
case "title": case "title":
case "localtitle": case "localtitle":
item.Name = reader.ReadElementContentAsString(); item.Name = reader.ReadElementContentAsString();
@ -926,17 +922,6 @@ namespace MediaBrowser.XbmcMetadata.Parsers
name = reader.ReadElementContentAsString() ?? string.Empty; name = reader.ReadElementContentAsString() ?? string.Empty;
break; break;
case "type":
{
var val = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(val))
{
type = val;
}
break;
}
case "role": case "role":
{ {
var val = reader.ReadElementContentAsString(); var val = reader.ReadElementContentAsString();

View File

@ -35,7 +35,6 @@ namespace MediaBrowser.XbmcMetadata.Savers
"plot", "plot",
"customrating", "customrating",
"lockdata", "lockdata",
"type",
"dateadded", "dateadded",
"title", "title",
"rating", "rating",
@ -491,11 +490,6 @@ namespace MediaBrowser.XbmcMetadata.Savers
writer.WriteElementString("lockedfields", string.Join("|", item.LockedFields.Select(i => i.ToString()).ToArray())); writer.WriteElementString("lockedfields", string.Join("|", item.LockedFields.Select(i => i.ToString()).ToArray()));
} }
if (!string.IsNullOrEmpty(item.DisplayMediaType))
{
writer.WriteElementString("type", item.DisplayMediaType);
}
writer.WriteElementString("dateadded", item.DateCreated.ToLocalTime().ToString(DateAddedFormat)); writer.WriteElementString("dateadded", item.DateCreated.ToLocalTime().ToString(DateAddedFormat));
writer.WriteElementString("title", item.Name ?? string.Empty); writer.WriteElementString("title", item.Name ?? string.Empty);

View File

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"> <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata> <metadata>
<id>MediaBrowser.Common</id> <id>MediaBrowser.Common</id>
<version>3.0.710</version> <version>3.0.712</version>
<title>Emby.Common</title> <title>Emby.Common</title>
<authors>Emby Team</authors> <authors>Emby Team</authors>
<owners>ebr,Luke,scottisafool</owners> <owners>ebr,Luke,scottisafool</owners>

View File

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"> <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata> <metadata>
<id>MediaBrowser.Server.Core</id> <id>MediaBrowser.Server.Core</id>
<version>3.0.710</version> <version>3.0.712</version>
<title>Emby.Server.Core</title> <title>Emby.Server.Core</title>
<authors>Emby Team</authors> <authors>Emby Team</authors>
<owners>ebr,Luke,scottisafool</owners> <owners>ebr,Luke,scottisafool</owners>
@ -12,7 +12,7 @@
<description>Contains core components required to build plugins for Emby Server.</description> <description>Contains core components required to build plugins for Emby Server.</description>
<copyright>Copyright © Emby 2013</copyright> <copyright>Copyright © Emby 2013</copyright>
<dependencies> <dependencies>
<dependency id="MediaBrowser.Common" version="3.0.710" /> <dependency id="MediaBrowser.Common" version="3.0.712" />
</dependencies> </dependencies>
</metadata> </metadata>
<files> <files>

View File

@ -1,3 +1,3 @@
using System.Reflection; using System.Reflection;
[assembly: AssemblyVersion("3.2.26.15")] [assembly: AssemblyVersion("3.2.26.16")]