aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2014-11-10 22:41:55 -0500
committerLuke Pulverenti <luke.pulverenti@gmail.com>2014-11-10 22:41:55 -0500
commit1fea9ad926801c85f436e34a8756bfdc41a43a0d (patch)
treec7c9487320cfdccbf210d9d01b28685d9bf110db
parent4d0a47e5555e4b04967c679dd4e54e937a0bd7ca (diff)
fixes #945 - Add genre views to dlna
-rw-r--r--MediaBrowser.Api/ConfigurationService.cs2
-rw-r--r--MediaBrowser.Api/Playback/BaseStreamingService.cs4
-rw-r--r--MediaBrowser.Api/Playback/StreamState.cs7
-rw-r--r--MediaBrowser.Controller/Entities/UserView.cs2
-rw-r--r--MediaBrowser.Controller/Entities/UserViewBuilder.cs240
-rw-r--r--MediaBrowser.Controller/Library/IUserViewManager.cs3
-rw-r--r--MediaBrowser.LocalMetadata/BaseXmlProvider.cs11
-rw-r--r--MediaBrowser.LocalMetadata/Savers/BoxSetXmlSaver.cs2
-rw-r--r--MediaBrowser.LocalMetadata/Savers/ChannelXmlSaver.cs2
-rw-r--r--MediaBrowser.LocalMetadata/Savers/EpisodeXmlSaver.cs2
-rw-r--r--MediaBrowser.LocalMetadata/Savers/FolderXmlSaver.cs2
-rw-r--r--MediaBrowser.LocalMetadata/Savers/GameSystemXmlSaver.cs2
-rw-r--r--MediaBrowser.LocalMetadata/Savers/GameXmlSaver.cs2
-rw-r--r--MediaBrowser.LocalMetadata/Savers/MovieXmlSaver.cs2
-rw-r--r--MediaBrowser.LocalMetadata/Savers/PersonXmlSaver.cs2
-rw-r--r--MediaBrowser.LocalMetadata/Savers/PlaylistXmlSaver.cs2
-rw-r--r--MediaBrowser.LocalMetadata/Savers/SeasonXmlSaver.cs2
-rw-r--r--MediaBrowser.LocalMetadata/Savers/SeriesXmlSaver.cs2
-rw-r--r--MediaBrowser.Model/ApiClient/IApiClient.cs10
-rw-r--r--MediaBrowser.Model/ApiClient/IConnectionManager.cs8
-rw-r--r--MediaBrowser.Model/Entities/CollectionType.cs4
-rw-r--r--MediaBrowser.Server.Implementations/Library/UserViewManager.cs7
-rw-r--r--MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json2
-rw-r--r--MediaBrowser.Server.Implementations/Localization/Server/server.json6
-rw-r--r--MediaBrowser.Server.Implementations/Music/MusicDynamicImageProvider.cs43
-rw-r--r--MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj3
-rw-r--r--MediaBrowser.Server.Mono/mediabrowser.sh2
-rw-r--r--MediaBrowser.Server.Startup.Common/ApplicationHost.cs83
-rw-r--r--MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj5
-rw-r--r--MediaBrowser.Server.Startup.Common/Migrations/IVersionMigration.cs8
-rw-r--r--MediaBrowser.Server.Startup.Common/Migrations/MigrateUserFolders.cs36
-rw-r--r--MediaBrowser.Server.Startup.Common/Migrations/PlaylistImages.cs55
-rw-r--r--MediaBrowser.Server.Startup.Common/Migrations/RenameXbmcOptions.cs56
-rw-r--r--MediaBrowser.Server.Startup.Common/Migrations/RenameXmlOptions.cs56
-rw-r--r--MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs29
-rw-r--r--MediaBrowser.XbmcMetadata/Parsers/MovieNfoParser.cs8
-rw-r--r--MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs2
-rw-r--r--Nuget/MediaBrowser.Common.Internal.nuspec4
-rw-r--r--Nuget/MediaBrowser.Common.nuspec2
-rw-r--r--Nuget/MediaBrowser.Model.Signed.nuspec2
-rw-r--r--Nuget/MediaBrowser.Server.Core.nuspec4
41 files changed, 554 insertions, 172 deletions
diff --git a/MediaBrowser.Api/ConfigurationService.cs b/MediaBrowser.Api/ConfigurationService.cs
index ce6ca015d..f6edea86e 100644
--- a/MediaBrowser.Api/ConfigurationService.cs
+++ b/MediaBrowser.Api/ConfigurationService.cs
@@ -124,7 +124,7 @@ namespace MediaBrowser.Api
public void Post(AutoSetMetadataOptions request)
{
- _configurationManager.DisableMetadataService("Media Browser Xml");
+ _configurationManager.DisableMetadataService("Media Browser Legacy Xml");
_configurationManager.SaveConfiguration();
}
diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs
index 9c8075bfb..c716ee150 100644
--- a/MediaBrowser.Api/Playback/BaseStreamingService.cs
+++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs
@@ -995,7 +995,7 @@ namespace MediaBrowser.Api.Playback
if (state.ReadInputAtNativeFramerate)
{
- await Task.Delay(1000, cancellationTokenSource.Token).ConfigureAwait(false);
+ await Task.Delay(1500, cancellationTokenSource.Token).ConfigureAwait(false);
}
}
@@ -1619,8 +1619,6 @@ namespace MediaBrowser.Api.Playback
AttachMediaStreamInfo(state, mediaStreams, videoRequest, url);
- state.SegmentLength = 6;
-
var container = Path.GetExtension(state.RequestedUrl);
if (string.IsNullOrEmpty(container))
diff --git a/MediaBrowser.Api/Playback/StreamState.cs b/MediaBrowser.Api/Playback/StreamState.cs
index b6423ed2f..d26259a3a 100644
--- a/MediaBrowser.Api/Playback/StreamState.cs
+++ b/MediaBrowser.Api/Playback/StreamState.cs
@@ -63,11 +63,14 @@ namespace MediaBrowser.Api.Playback
public string LiveTvStreamId { get; set; }
- public int SegmentLength = 10;
+ public int SegmentLength = 6;
public int HlsListSize
{
- get { return ReadInputAtNativeFramerate ? 100 : 1440; }
+ get
+ {
+ return ReadInputAtNativeFramerate ? 1000 : 0;
+ }
}
public long? RunTimeTicks;
diff --git a/MediaBrowser.Controller/Entities/UserView.cs b/MediaBrowser.Controller/Entities/UserView.cs
index c313966a5..4b29f49d8 100644
--- a/MediaBrowser.Controller/Entities/UserView.cs
+++ b/MediaBrowser.Controller/Entities/UserView.cs
@@ -26,7 +26,7 @@ namespace MediaBrowser.Controller.Entities
}
return new UserViewBuilder(UserViewManager, LiveTvManager, ChannelManager, LibraryManager, Logger, UserDataManager, TVSeriesManager, CollectionManager)
- .GetUserItems(parent, ViewType, query);
+ .GetUserItems(parent, this, ViewType, query);
}
public override IEnumerable<BaseItem> GetChildren(User user, bool includeLinkedChildren)
diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
index cd579f7ad..a76a28469 100644
--- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs
+++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
@@ -44,7 +44,7 @@ namespace MediaBrowser.Controller.Entities
_collectionManager = collectionManager;
}
- public async Task<QueryResult<BaseItem>> GetUserItems(Folder parent, string viewType, InternalItemsQuery query)
+ public async Task<QueryResult<BaseItem>> GetUserItems(Folder queryParent, Folder displayParent, string viewType, InternalItemsQuery query)
{
var user = query.User;
@@ -107,110 +107,125 @@ namespace MediaBrowser.Controller.Entities
{
var result = await GetLiveTvFolders(user).ConfigureAwait(false);
- return GetResult(result, parent, query);
+ return GetResult(result, queryParent, query);
}
case CollectionType.Folders:
- return GetResult(user.RootFolder.GetChildren(user, true), parent, query);
+ return GetResult(user.RootFolder.GetChildren(user, true), queryParent, query);
case CollectionType.Games:
- return await GetGameView(user, parent, query).ConfigureAwait(false);
+ return await GetGameView(user, queryParent, query).ConfigureAwait(false);
case CollectionType.BoxSets:
- return GetResult(GetMediaFolders(user).SelectMany(i => i.GetRecursiveChildren(user)).OfType<BoxSet>(), parent, query);
+ return GetResult(GetMediaFolders(user).SelectMany(i => i.GetRecursiveChildren(user)).OfType<BoxSet>(), queryParent, query);
case CollectionType.TvShows:
- return await GetTvView(parent, user, query).ConfigureAwait(false);
+ return await GetTvView(queryParent, user, query).ConfigureAwait(false);
case CollectionType.Music:
- return await GetMusicFolders(parent, user, query).ConfigureAwait(false);
+ return await GetMusicFolders(queryParent, user, query).ConfigureAwait(false);
case CollectionType.Movies:
- return await GetMovieFolders(parent, user, query).ConfigureAwait(false);
+ return await GetMovieFolders(queryParent, user, query).ConfigureAwait(false);
+
+ case SpecialFolder.MusicGenres:
+ return await GetMusicGenres(queryParent, user, query).ConfigureAwait(false);
+
+ case SpecialFolder.MusicGenre:
+ return await GetMusicGenreItems(queryParent, displayParent, user, query).ConfigureAwait(false);
case SpecialFolder.GameGenres:
- return GetGameGenres(parent, user, query);
+ return await GetGameGenres(queryParent, user, query).ConfigureAwait(false);
+
+ case SpecialFolder.GameGenre:
+ return await GetGameGenreItems(queryParent, displayParent, user, query).ConfigureAwait(false);
case SpecialFolder.GameSystems:
- return GetGameSystems(parent, user, query);
+ return GetGameSystems(queryParent, user, query);
case SpecialFolder.LatestGames:
- return GetLatestGames(parent, user, query);
+ return GetLatestGames(queryParent, user, query);
case SpecialFolder.RecentlyPlayedGames:
- return GetRecentlyPlayedGames(parent, user, query);
+ return GetRecentlyPlayedGames(queryParent, user, query);
case SpecialFolder.GameFavorites:
- return GetFavoriteGames(parent, user, query);
+ return GetFavoriteGames(queryParent, user, query);
case SpecialFolder.TvShowSeries:
- return GetTvSeries(parent, user, query);
+ return GetTvSeries(queryParent, user, query);
case SpecialFolder.TvGenres:
- return GetTvGenres(parent, user, query);
+ return await GetTvGenres(queryParent, user, query).ConfigureAwait(false);
+
+ case SpecialFolder.TvGenre:
+ return await GetTvGenreItems(queryParent, displayParent, user, query).ConfigureAwait(false);
case SpecialFolder.TvResume:
- return GetTvResume(parent, user, query);
+ return GetTvResume(queryParent, user, query);
case SpecialFolder.TvNextUp:
- return GetTvNextUp(parent, query);
+ return GetTvNextUp(queryParent, query);
case SpecialFolder.TvLatest:
- return GetTvLatest(parent, user, query);
+ return GetTvLatest(queryParent, user, query);
case SpecialFolder.MovieFavorites:
- return GetFavoriteMovies(parent, user, query);
+ return GetFavoriteMovies(queryParent, user, query);
case SpecialFolder.MovieLatest:
- return GetMovieLatest(parent, user, query);
+ return GetMovieLatest(queryParent, user, query);
case SpecialFolder.MovieGenres:
- return GetMovieGenres(parent, user, query);
+ return await GetMovieGenres(queryParent, user, query).ConfigureAwait(false);
+
+ case SpecialFolder.MovieGenre:
+ return await GetMovieGenreItems(queryParent, displayParent, user, query).ConfigureAwait(false);
case SpecialFolder.MovieResume:
- return GetMovieResume(parent, user, query);
+ return GetMovieResume(queryParent, user, query);
case SpecialFolder.MovieMovies:
- return GetMovieMovies(parent, user, query);
+ return GetMovieMovies(queryParent, user, query);
case SpecialFolder.MovieCollections:
- return GetMovieCollections(parent, user, query);
+ return GetMovieCollections(queryParent, user, query);
case SpecialFolder.MusicLatest:
- return GetMusicLatest(parent, user, query);
+ return GetMusicLatest(queryParent, user, query);
case SpecialFolder.MusicAlbums:
- return GetMusicAlbums(parent, user, query);
+ return GetMusicAlbums(queryParent, user, query);
case SpecialFolder.MusicAlbumArtists:
- return GetMusicAlbumArtists(parent, user, query);
+ return GetMusicAlbumArtists(queryParent, user, query);
case SpecialFolder.MusicArtists:
- return GetMusicArtists(parent, user, query);
+ return GetMusicArtists(queryParent, user, query);
case SpecialFolder.MusicSongs:
- return GetMusicSongs(parent, user, query);
+ return GetMusicSongs(queryParent, user, query);
case SpecialFolder.TvFavoriteEpisodes:
- return GetFavoriteEpisodes(parent, user, query);
+ return GetFavoriteEpisodes(queryParent, user, query);
case SpecialFolder.TvFavoriteSeries:
- return GetFavoriteSeries(parent, user, query);
+ return GetFavoriteSeries(queryParent, user, query);
case SpecialFolder.MusicFavorites:
- return await GetMusicFavorites(parent, user, query).ConfigureAwait(false);
+ return await GetMusicFavorites(queryParent, user, query).ConfigureAwait(false);
case SpecialFolder.MusicFavoriteAlbums:
- return GetFavoriteAlbums(parent, user, query);
+ return GetFavoriteAlbums(queryParent, user, query);
case SpecialFolder.MusicFavoriteArtists:
- return GetFavoriteArtists(parent, user, query);
+ return GetFavoriteArtists(queryParent, user, query);
case SpecialFolder.MusicFavoriteSongs:
- return GetFavoriteSongs(parent, user, query);
+ return GetFavoriteSongs(queryParent, user, query);
default:
- return GetResult(GetMediaFolders(user).SelectMany(i => i.GetChildren(user, true)), parent, query);
+ return GetResult(GetMediaFolders(user).SelectMany(i => i.GetChildren(user, true)), queryParent, query);
}
}
@@ -231,9 +246,9 @@ namespace MediaBrowser.Controller.Entities
list.Add(await GetUserView(SpecialFolder.MusicLatest, user, "0", parent).ConfigureAwait(false));
list.Add(await GetUserView(SpecialFolder.MusicAlbums, user, "1", parent).ConfigureAwait(false));
list.Add(await GetUserView(SpecialFolder.MusicAlbumArtists, user, "2", parent).ConfigureAwait(false));
- list.Add(await GetUserView(SpecialFolder.MusicSongs, user, "3", parent).ConfigureAwait(false));
- //list.Add(await GetUserView(SpecialFolder.MusicArtists, user, "3", parent).ConfigureAwait(false));
- //list.Add(await GetUserView(SpecialFolder.MusicGenres, user, "5", parent).ConfigureAwait(false));
+ list.Add(await GetUserView(SpecialFolder.MusicArtists, user, "3", parent).ConfigureAwait(false));
+ list.Add(await GetUserView(SpecialFolder.MusicSongs, user, "4", parent).ConfigureAwait(false));
+ list.Add(await GetUserView(SpecialFolder.MusicGenres, user, "5", parent).ConfigureAwait(false));
list.Add(await GetUserView(SpecialFolder.MusicFavorites, user, "6", parent).ConfigureAwait(false));
return GetResult(list, parent, query);
@@ -250,6 +265,59 @@ namespace MediaBrowser.Controller.Entities
return GetResult(list, parent, query);
}
+ private async Task<QueryResult<BaseItem>> GetMusicGenres(Folder parent, User user, InternalItemsQuery query)
+ {
+ var tasks = GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos })
+ .Where(i => !i.IsFolder)
+ .SelectMany(i => i.Genres)
+ .Distinct(StringComparer.OrdinalIgnoreCase)
+ .Select(i =>
+ {
+ try
+ {
+ return _libraryManager.GetMusicGenre(i);
+ }
+ catch
+ {
+ // Full exception logged at lower levels
+ _logger.Error("Error getting genre");
+ return null;
+ }
+
+ })
+ .Where(i => i != null)
+ .Select(i => GetUserView(i.Name, SpecialFolder.MusicGenre, user, i.SortName, parent));
+
+ var genres = await Task.WhenAll(tasks).ConfigureAwait(false);
+
+ return GetResult(genres, parent, query);
+ }
+
+ private async Task<QueryResult<BaseItem>> GetMusicGenreItems(Folder queryParent, Folder displayParent, User user, InternalItemsQuery query)
+ {
+ var items = GetRecursiveChildren(queryParent, user, new[] { CollectionType.Music, CollectionType.MusicVideos })
+ .Where(i => !i.IsFolder)
+ .Where(i => i.Genres.Contains(displayParent.Name, StringComparer.OrdinalIgnoreCase))
+ .OfType<IHasAlbumArtist>()
+ .SelectMany(i => i.AlbumArtists)
+ .Distinct(StringComparer.OrdinalIgnoreCase)
+ .Select(i =>
+ {
+ try
+ {
+ return _libraryManager.GetArtist(i);
+ }
+ catch
+ {
+ // Already logged at lower levels
+ return null;
+ }
+ })
+ .Where(i => i != null);
+
+ return GetResult(items, queryParent, query);
+ }
+
private QueryResult<BaseItem> GetMusicAlbumArtists(Folder parent, User user, InternalItemsQuery query)
{
var artists = GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos })
@@ -354,7 +422,7 @@ namespace MediaBrowser.Controller.Entities
list.Add(await GetUserView(SpecialFolder.MovieMovies, user, "2", parent).ConfigureAwait(false));
list.Add(await GetUserView(SpecialFolder.MovieCollections, user, "3", parent).ConfigureAwait(false));
list.Add(await GetUserView(SpecialFolder.MovieFavorites, user, "4", parent).ConfigureAwait(false));
- //list.Add(await GetUserView(CollectionType.MovieGenres, user, "5", parent).ConfigureAwait(false));
+ list.Add(await GetUserView(SpecialFolder.MovieGenres, user, "5", parent).ConfigureAwait(false));
return GetResult(list, parent, query);
}
@@ -421,9 +489,9 @@ namespace MediaBrowser.Controller.Entities
return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Movies, CollectionType.BoxSets, string.Empty }).Where(i => i is Movie), parent, GetSpecialItemsLimit(), query);
}
- private QueryResult<BaseItem> GetMovieGenres(Folder parent, User user, InternalItemsQuery query)
+ private async Task<QueryResult<BaseItem>> GetMovieGenres(Folder parent, User user, InternalItemsQuery query)
{
- var genres = GetRecursiveChildren(parent, user, new[] { CollectionType.Movies, CollectionType.BoxSets, string.Empty })
+ var tasks = GetRecursiveChildren(parent, user, new[] { CollectionType.Movies, CollectionType.BoxSets, string.Empty })
.Where(i => i is Movie)
.SelectMany(i => i.Genres)
.Distinct(StringComparer.OrdinalIgnoreCase)
@@ -441,11 +509,23 @@ namespace MediaBrowser.Controller.Entities
}
})
- .Where(i => i != null);
+ .Where(i => i != null)
+ .Select(i => GetUserView(i.Name, SpecialFolder.MovieGenre, user, i.SortName, parent));
+
+ var genres = await Task.WhenAll(tasks).ConfigureAwait(false);
return GetResult(genres, parent, query);
}
+ private async Task<QueryResult<BaseItem>> GetMovieGenreItems(Folder queryParent, Folder displayParent, User user, InternalItemsQuery query)
+ {
+ var items = GetRecursiveChildren(queryParent, user, new[] { CollectionType.Movies, CollectionType.BoxSets, string.Empty })
+ .Where(i => i is Movie)
+ .Where(i => i.Genres.Contains(displayParent.Name, StringComparer.OrdinalIgnoreCase));
+
+ return GetResult(items, queryParent, query);
+ }
+
private async Task<QueryResult<BaseItem>> GetTvView(Folder parent, User user, InternalItemsQuery query)
{
if (query.Recursive)
@@ -461,7 +541,7 @@ namespace MediaBrowser.Controller.Entities
list.Add(await GetUserView(SpecialFolder.TvShowSeries, user, "3", parent).ConfigureAwait(false));
list.Add(await GetUserView(SpecialFolder.TvFavoriteSeries, user, "4", parent).ConfigureAwait(false));
list.Add(await GetUserView(SpecialFolder.TvFavoriteEpisodes, user, "5", parent).ConfigureAwait(false));
- //list.Add(await GetUserView(SpecialFolder.TvGenres, user, "5", parent).ConfigureAwait(false));
+ list.Add(await GetUserView(SpecialFolder.TvGenres, user, "6", parent).ConfigureAwait(false));
return GetResult(list, parent, query);
}
@@ -479,7 +559,7 @@ namespace MediaBrowser.Controller.Entities
list.Add(await GetUserView(SpecialFolder.RecentlyPlayedGames, user, "1", parent).ConfigureAwait(false));
list.Add(await GetUserView(SpecialFolder.GameFavorites, user, "2", parent).ConfigureAwait(false));
list.Add(await GetUserView(SpecialFolder.GameSystems, user, "3", parent).ConfigureAwait(false));
- //list.Add(await GetUserView(SpecialFolder.GameGenres, user, "4", parent).ConfigureAwait(false));
+ list.Add(await GetUserView(SpecialFolder.GameGenres, user, "4", parent).ConfigureAwait(false));
return GetResult(list, parent, query);
}
@@ -545,9 +625,9 @@ namespace MediaBrowser.Controller.Entities
return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.TvShows, string.Empty }).OfType<Series>(), parent, query);
}
- private QueryResult<BaseItem> GetTvGenres(Folder parent, User user, InternalItemsQuery query)
+ private async Task<QueryResult<BaseItem>> GetTvGenres(Folder parent, User user, InternalItemsQuery query)
{
- var genres = GetRecursiveChildren(parent, user, new[] { CollectionType.TvShows, string.Empty })
+ var tasks = GetRecursiveChildren(parent, user, new[] { CollectionType.TvShows, string.Empty })
.OfType<Series>()
.SelectMany(i => i.Genres)
.Distinct(StringComparer.OrdinalIgnoreCase)
@@ -565,19 +645,40 @@ namespace MediaBrowser.Controller.Entities
}
})
- .Where(i => i != null);
+ .Where(i => i != null)
+ .Select(i => GetUserView(i.Name, SpecialFolder.TvGenre, user, i.SortName, parent));
+
+ var genres = await Task.WhenAll(tasks).ConfigureAwait(false);
return GetResult(genres, parent, query);
}
+ private async Task<QueryResult<BaseItem>> GetTvGenreItems(Folder queryParent, Folder displayParent, User user, InternalItemsQuery query)
+ {
+ var items = GetRecursiveChildren(queryParent, user, new[] { CollectionType.TvShows, string.Empty })
+ .Where(i => i is Series)
+ .Where(i => i.Genres.Contains(displayParent.Name, StringComparer.OrdinalIgnoreCase));
+
+ return GetResult(items, queryParent, query);
+ }
+
private QueryResult<BaseItem> GetGameSystems(Folder parent, User user, InternalItemsQuery query)
{
return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Games }).OfType<GameSystem>(), parent, query);
}
- private QueryResult<BaseItem> GetGameGenres(Folder parent, User user, InternalItemsQuery query)
+ private async Task<QueryResult<BaseItem>> GetGameGenreItems(Folder queryParent, Folder displayParent, User user, InternalItemsQuery query)
+ {
+ var items = GetRecursiveChildren(queryParent, user, new[] { CollectionType.Games })
+ .OfType<Game>()
+ .Where(i => i.Genres.Contains(displayParent.Name, StringComparer.OrdinalIgnoreCase));
+
+ return GetResult(items, queryParent, query);
+ }
+
+ private async Task<QueryResult<BaseItem>> GetGameGenres(Folder parent, User user, InternalItemsQuery query)
{
- var genres = GetRecursiveChildren(parent, user, new[] { CollectionType.Games })
+ var tasks = GetRecursiveChildren(parent, user, new[] { CollectionType.Games })
.OfType<Game>()
.SelectMany(i => i.Genres)
.Distinct(StringComparer.OrdinalIgnoreCase)
@@ -595,7 +696,10 @@ namespace MediaBrowser.Controller.Entities
}
})
- .Where(i => i != null);
+ .Where(i => i != null)
+ .Select(i => GetUserView(i.Name, SpecialFolder.GameGenre, user, i.SortName, parent));
+
+ var genres = await Task.WhenAll(tasks).ConfigureAwait(false);
return GetResult(genres, parent, query);
}
@@ -611,24 +715,24 @@ namespace MediaBrowser.Controller.Entities
}
private QueryResult<BaseItem> GetResult<T>(IEnumerable<T> items,
- BaseItem parentItem,
+ BaseItem queryParent,
InternalItemsQuery query)
where T : BaseItem
{
- return GetResult(items, parentItem, null, query);
+ return GetResult(items, queryParent, null, query);
}
private QueryResult<BaseItem> GetResult<T>(IEnumerable<T> items,
- BaseItem parentItem,
+ BaseItem queryParent,
int? totalRecordLimit,
InternalItemsQuery query)
where T : BaseItem
{
- return SortAndFilter(items, parentItem, totalRecordLimit, query, _libraryManager, _userDataManager);
+ return SortAndFilter(items, queryParent, totalRecordLimit, query, _libraryManager, _userDataManager);
}
public static QueryResult<BaseItem> SortAndFilter(IEnumerable<BaseItem> items,
- BaseItem parentItem,
+ BaseItem queryParent,
int? totalRecordLimit,
InternalItemsQuery query,
ILibraryManager libraryManager,
@@ -643,7 +747,7 @@ namespace MediaBrowser.Controller.Entities
query.IsVirtualUnaired,
query.IsUnaired);
- items = CollapseBoxSetItemsIfNeeded(items, query, parentItem, user);
+ items = CollapseBoxSetItemsIfNeeded(items, query, queryParent, user);
// This must be the last filter
if (!string.IsNullOrEmpty(query.AdjacentTo))
@@ -656,10 +760,10 @@ namespace MediaBrowser.Controller.Entities
public static IEnumerable<BaseItem> CollapseBoxSetItemsIfNeeded(IEnumerable<BaseItem> items,
InternalItemsQuery query,
- BaseItem parentItem,
+ BaseItem queryParent,
User user)
{
- if (CollapseBoxSetItems(query, parentItem, user))
+ if (CollapseBoxSetItems(query, queryParent, user))
{
items = BaseItem.CollectionManager.CollapseItemsWithinBoxSets(items, user);
}
@@ -691,11 +795,11 @@ namespace MediaBrowser.Controller.Entities
}
private static bool CollapseBoxSetItems(InternalItemsQuery query,
- BaseItem parentItem,
+ BaseItem queryParent,
User user)
{
// Could end up stuck in a loop like this
- if (parentItem is BoxSet)
+ if (queryParent is BoxSet)
{
return false;
}
@@ -1488,7 +1592,7 @@ namespace MediaBrowser.Controller.Entities
});
}
- private IEnumerable<Folder> GetMediaFolders(Folder parent, User user, string[] viewTypes)
+ private IEnumerable<Folder> GetMediaFolders(Folder parent, User user, IEnumerable<string> viewTypes)
{
if (parent == null || parent is UserView)
{
@@ -1498,7 +1602,7 @@ namespace MediaBrowser.Controller.Entities
return new[] { parent };
}
- private IEnumerable<BaseItem> GetRecursiveChildren(Folder parent, User user, string[] viewTypes)
+ private IEnumerable<BaseItem> GetRecursiveChildren(Folder parent, User user, IEnumerable<string> viewTypes)
{
if (parent == null || parent is UserView)
{
@@ -1521,7 +1625,15 @@ namespace MediaBrowser.Controller.Entities
return list;
}
- private async Task<UserView> GetUserView(string type, User user, string sortName, Folder parent)
+ private async Task<UserView> GetUserView(string name, string type, User user, string sortName, BaseItem parent)
+ {
+ var view = await _userViewManager.GetUserView(name, parent.Id.ToString("N"), type, user, sortName, CancellationToken.None)
+ .ConfigureAwait(false);
+
+ return view;
+ }
+
+ private async Task<UserView> GetUserView(string type, User user, string sortName, BaseItem parent)
{
var view = await _userViewManager.GetUserView(parent.Id.ToString("N"), type, user, sortName, CancellationToken.None)
.ConfigureAwait(false);
diff --git a/MediaBrowser.Controller/Library/IUserViewManager.cs b/MediaBrowser.Controller/Library/IUserViewManager.cs
index 12dc9c0b2..727ccd00a 100644
--- a/MediaBrowser.Controller/Library/IUserViewManager.cs
+++ b/MediaBrowser.Controller/Library/IUserViewManager.cs
@@ -10,6 +10,9 @@ namespace MediaBrowser.Controller.Library
{
Task<IEnumerable<Folder>> GetUserViews(UserViewQuery query, CancellationToken cancellationToken);
+ Task<UserView> GetUserView(string name, string parentId, string type, User user, string sortName,
+ CancellationToken cancellationToken);
+
Task<UserView> GetUserView(string type, string sortName, CancellationToken cancellationToken);
Task<UserView> GetUserView(string category, string type, User user, string sortName, CancellationToken cancellationToken);
diff --git a/MediaBrowser.LocalMetadata/BaseXmlProvider.cs b/MediaBrowser.LocalMetadata/BaseXmlProvider.cs
index 5eb067dcd..6f8047e4c 100644
--- a/MediaBrowser.LocalMetadata/BaseXmlProvider.cs
+++ b/MediaBrowser.LocalMetadata/BaseXmlProvider.cs
@@ -78,13 +78,22 @@ namespace MediaBrowser.LocalMetadata
{
get
{
- return "Media Browser Xml";
+ return XmlProviderUtils.Name;
}
}
+
}
static class XmlProviderUtils
{
+ public static string Name
+ {
+ get
+ {
+ return "Media Browser Legacy Xml";
+ }
+ }
+
internal static readonly SemaphoreSlim XmlParsingResourcePool = new SemaphoreSlim(4, 4);
}
}
diff --git a/MediaBrowser.LocalMetadata/Savers/BoxSetXmlSaver.cs b/MediaBrowser.LocalMetadata/Savers/BoxSetXmlSaver.cs
index 8cbe69551..f04175654 100644
--- a/MediaBrowser.LocalMetadata/Savers/BoxSetXmlSaver.cs
+++ b/MediaBrowser.LocalMetadata/Savers/BoxSetXmlSaver.cs
@@ -15,7 +15,7 @@ namespace MediaBrowser.LocalMetadata.Savers
{
get
{
- return "Media Browser Xml";
+ return XmlProviderUtils.Name;
}
}
diff --git a/MediaBrowser.LocalMetadata/Savers/ChannelXmlSaver.cs b/MediaBrowser.LocalMetadata/Savers/ChannelXmlSaver.cs
index b111f6d15..03fdf2bc8 100644
--- a/MediaBrowser.LocalMetadata/Savers/ChannelXmlSaver.cs
+++ b/MediaBrowser.LocalMetadata/Savers/ChannelXmlSaver.cs
@@ -41,7 +41,7 @@ namespace MediaBrowser.LocalMetadata.Savers
{
get
{
- return "Media Browser Xml";
+ return XmlProviderUtils.Name;
}
}
diff --git a/MediaBrowser.LocalMetadata/Savers/EpisodeXmlSaver.cs b/MediaBrowser.LocalMetadata/Savers/EpisodeXmlSaver.cs
index 06c13eb8b..673d8bc41 100644
--- a/MediaBrowser.LocalMetadata/Savers/EpisodeXmlSaver.cs
+++ b/MediaBrowser.LocalMetadata/Savers/EpisodeXmlSaver.cs
@@ -45,7 +45,7 @@ namespace MediaBrowser.LocalMetadata.Savers
{
get
{
- return "Media Browser Xml";
+ return XmlProviderUtils.Name;
}
}
diff --git a/MediaBrowser.LocalMetadata/Savers/FolderXmlSaver.cs b/MediaBrowser.LocalMetadata/Savers/FolderXmlSaver.cs
index 7efa55420..fa3d7d87d 100644
--- a/MediaBrowser.LocalMetadata/Savers/FolderXmlSaver.cs
+++ b/MediaBrowser.LocalMetadata/Savers/FolderXmlSaver.cs
@@ -18,7 +18,7 @@ namespace MediaBrowser.LocalMetadata.Savers
{
get
{
- return "Media Browser Xml";
+ return XmlProviderUtils.Name;
}
}
diff --git a/MediaBrowser.LocalMetadata/Savers/GameSystemXmlSaver.cs b/MediaBrowser.LocalMetadata/Savers/GameSystemXmlSaver.cs
index e1fc3b8cc..ebb401f54 100644
--- a/MediaBrowser.LocalMetadata/Savers/GameSystemXmlSaver.cs
+++ b/MediaBrowser.LocalMetadata/Savers/GameSystemXmlSaver.cs
@@ -15,7 +15,7 @@ namespace MediaBrowser.LocalMetadata.Savers
{
get
{
- return "Media Browser Xml";
+ return XmlProviderUtils.Name;
}
}
diff --git a/MediaBrowser.LocalMetadata/Savers/GameXmlSaver.cs b/MediaBrowser.LocalMetadata/Savers/GameXmlSaver.cs
index 11f6db77c..108c6a9e2 100644
--- a/MediaBrowser.LocalMetadata/Savers/GameXmlSaver.cs
+++ b/MediaBrowser.LocalMetadata/Savers/GameXmlSaver.cs
@@ -20,7 +20,7 @@ namespace MediaBrowser.LocalMetadata.Savers
{
get
{
- return "Media Browser Xml";
+ return XmlProviderUtils.Name;
}
}
diff --git a/MediaBrowser.LocalMetadata/Savers/MovieXmlSaver.cs b/MediaBrowser.LocalMetadata/Savers/MovieXmlSaver.cs
index 84d41c8e2..6fe9f88f0 100644
--- a/MediaBrowser.LocalMetadata/Savers/MovieXmlSaver.cs
+++ b/MediaBrowser.LocalMetadata/Savers/MovieXmlSaver.cs
@@ -30,7 +30,7 @@ namespace MediaBrowser.LocalMetadata.Savers
{
get
{
- return "Media Browser Xml";
+ return XmlProviderUtils.Name;
}
}
diff --git a/MediaBrowser.LocalMetadata/Savers/PersonXmlSaver.cs b/MediaBrowser.LocalMetadata/Savers/PersonXmlSaver.cs
index 835256ca7..9c6fb39bd 100644
--- a/MediaBrowser.LocalMetadata/Savers/PersonXmlSaver.cs
+++ b/MediaBrowser.LocalMetadata/Savers/PersonXmlSaver.cs
@@ -18,7 +18,7 @@ namespace MediaBrowser.LocalMetadata.Savers
{
get
{
- return "Media Browser Xml";
+ return XmlProviderUtils.Name;
}
}
diff --git a/MediaBrowser.LocalMetadata/Savers/PlaylistXmlSaver.cs b/MediaBrowser.LocalMetadata/Savers/PlaylistXmlSaver.cs
index 169f0b6ee..16c437381 100644
--- a/MediaBrowser.LocalMetadata/Savers/PlaylistXmlSaver.cs
+++ b/MediaBrowser.LocalMetadata/Savers/PlaylistXmlSaver.cs
@@ -16,7 +16,7 @@ namespace MediaBrowser.LocalMetadata.Savers
{
get
{
- return "Media Browser Xml";
+ return XmlProviderUtils.Name;
}
}
diff --git a/MediaBrowser.LocalMetadata/Savers/SeasonXmlSaver.cs b/MediaBrowser.LocalMetadata/Savers/SeasonXmlSaver.cs
index 610652c6b..a112f22fa 100644
--- a/MediaBrowser.LocalMetadata/Savers/SeasonXmlSaver.cs
+++ b/MediaBrowser.LocalMetadata/Savers/SeasonXmlSaver.cs
@@ -17,7 +17,7 @@ namespace MediaBrowser.LocalMetadata.Savers
{
get
{
- return "Media Browser Xml";
+ return XmlProviderUtils.Name;
}
}
diff --git a/MediaBrowser.LocalMetadata/Savers/SeriesXmlSaver.cs b/MediaBrowser.LocalMetadata/Savers/SeriesXmlSaver.cs
index 885dccdb6..c94770bdb 100644
--- a/MediaBrowser.LocalMetadata/Savers/SeriesXmlSaver.cs
+++ b/MediaBrowser.LocalMetadata/Savers/SeriesXmlSaver.cs
@@ -25,7 +25,7 @@ namespace MediaBrowser.LocalMetadata.Savers
{
get
{
- return "Media Browser Xml";
+ return XmlProviderUtils.Name;
}
}
diff --git a/MediaBrowser.Model/ApiClient/IApiClient.cs b/MediaBrowser.Model/ApiClient/IApiClient.cs
index 89c731223..114dd3095 100644
--- a/MediaBrowser.Model/ApiClient/IApiClient.cs
+++ b/MediaBrowser.Model/ApiClient/IApiClient.cs
@@ -122,6 +122,16 @@ namespace MediaBrowser.Model.ApiClient
Task<SearchHintResult> GetSearchHintsAsync(SearchQuery query);
/// <summary>
+ /// Gets the filters.
+ /// </summary>
+ /// <param name="userId">The user identifier.</param>
+ /// <param name="parentId">The parent identifier.</param>
+ /// <param name="mediaTypes">The media types.</param>
+ /// <param name="itemTypes">The item types.</param>
+ /// <returns>Task&lt;QueryFilters&gt;.</returns>
+ Task<QueryFilters> GetFilters(string userId, string parentId, string[] mediaTypes, string[] itemTypes);
+
+ /// <summary>
/// Gets the theme videos async.
/// </summary>
/// <param name="userId">The user id.</param>
diff --git a/MediaBrowser.Model/ApiClient/IConnectionManager.cs b/MediaBrowser.Model/ApiClient/IConnectionManager.cs
index f234bb714..bf7ef7185 100644
--- a/MediaBrowser.Model/ApiClient/IConnectionManager.cs
+++ b/MediaBrowser.Model/ApiClient/IConnectionManager.cs
@@ -60,6 +60,14 @@ namespace MediaBrowser.Model.ApiClient
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task&lt;ConnectionResult&gt;.</returns>
Task<ConnectionResult> Connect(CancellationToken cancellationToken);
+
+ /// <summary>
+ /// Connects the specified API client.
+ /// </summary>
+ /// <param name="apiClient">The API client.</param>
+ /// <param name="cancellationToken">The cancellation token.</param>
+ /// <returns>Task&lt;ConnectionResult&gt;.</returns>
+ Task<ConnectionResult> Connect(IApiClient apiClient, CancellationToken cancellationToken);
/// <summary>
/// Connects the specified server.
diff --git a/MediaBrowser.Model/Entities/CollectionType.cs b/MediaBrowser.Model/Entities/CollectionType.cs
index 9cd7999b0..a4413f67a 100644
--- a/MediaBrowser.Model/Entities/CollectionType.cs
+++ b/MediaBrowser.Model/Entities/CollectionType.cs
@@ -35,6 +35,7 @@
public const string TvShowSeries = "TvShowSeries";
public const string TvGenres = "TvGenres";
+ public const string TvGenre = "TvGenre";
public const string TvLatest = "TvLatest";
public const string TvNextUp = "TvNextUp";
public const string TvResume = "TvResume";
@@ -47,17 +48,20 @@
public const string MovieCollections = "MovieCollections";
public const string MovieFavorites = "MovieFavorites";
public const string MovieGenres = "MovieGenres";
+ public const string MovieGenre = "MovieGenre";
public const string LatestGames = "LatestGames";
public const string RecentlyPlayedGames = "RecentlyPlayedGames";
public const string GameSystems = "GameSystems";
public const string GameGenres = "GameGenres";
public const string GameFavorites = "GameFavorites";
+ public const string GameGenre = "GameGenre";
public const string MusicArtists = "MusicArtists";
public const string MusicAlbumArtists = "MusicAlbumArtists";
public const string MusicAlbums = "MusicAlbums";
public const string MusicGenres = "MusicGenres";
+ public const string MusicGenre = "MusicGenre";
public const string MusicLatest = "MusicLatest";
public const string MusicSongs = "MusicSongs";
public const string MusicFavorites = "MusicFavorites";
diff --git a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs
index d2d435414..46c32cc56 100644
--- a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs
@@ -148,11 +148,16 @@ namespace MediaBrowser.Server.Implementations.Library
.ThenBy(i => i.SortName);
}
+ public Task<UserView> GetUserView(string name, string parentId, string type, User user, string sortName, CancellationToken cancellationToken)
+ {
+ return _libraryManager.GetSpecialFolder(user, name, parentId, type, sortName, cancellationToken);
+ }
+
public Task<UserView> GetUserView(string parentId, string type, User user, string sortName, CancellationToken cancellationToken)
{
var name = _localizationManager.GetLocalizedString("ViewType" + type);
- return _libraryManager.GetSpecialFolder(user, name, parentId, type, sortName, cancellationToken);
+ return GetUserView(name, parentId, type, user, sortName, cancellationToken);
}
public Task<UserView> GetUserView(string type, string sortName, CancellationToken cancellationToken)
diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json
index a484cbbb8..21658f3ff 100644
--- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json
+++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json
@@ -288,7 +288,7 @@
"LabelPremiereProgram": "PREMIERE",
"LabelHDProgram": "HD",
"HeaderChangeFolderType": "Change Folder Type",
- "HeaderChangeFolderTypeHelp": "To change the folder type, please remove and rebuild the collection with the new type.",
+ "HeaderChangeFolderTypeHelp": "To change the type, please remove and rebuild the folder with the new type.",
"HeaderAlert": "Alert",
"MessagePleaseRestart": "Please restart to finish updating.",
"ButtonRestart": "Restart",
diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json
index 1d52a42ae..a1591156c 100644
--- a/MediaBrowser.Server.Implementations/Localization/Server/server.json
+++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json
@@ -145,9 +145,11 @@
"OptionBudget": "Budget",
"OptionRevenue": "Revenue",
"OptionPoster": "Poster",
+ "OptionPosterCard": "Poster card",
"OptionBackdrop": "Backdrop",
"OptionTimeline": "Timeline",
"OptionThumb": "Thumb",
+ "OptionThumbCard": "Thumb card",
"OptionBanner": "Banner",
"OptionCriticRating": "Critic Rating",
"OptionVideoBitrate": "Video Bitrate",
@@ -455,7 +457,7 @@
"LinkApiDocumentation": "Api Documentation",
"LabelFriendlyServerName": "Friendly server name:",
"LabelFriendlyServerNameHelp": "This name will be used to identify this server. If left blank, the computer name will be used.",
- "LabelPreferredDisplayLanguage": "Preferred display language",
+ "LabelPreferredDisplayLanguage": "Preferred display language:",
"LabelPreferredDisplayLanguageHelp": "Translating Media Browser is an ongoing project and is not yet complete.",
"LabelReadHowYouCanContribute": "Read about how you can contribute.",
"HeaderNewCollection": "New Collection",
@@ -847,6 +849,8 @@
"ViewTypeTvShows": "TV",
"ViewTypeGames": "Games",
"ViewTypeMusic": "Music",
+ "ViewTypeMusicGenres": "Genres",
+ "ViewTypeMusicArtists": "Artists",
"ViewTypeBoxSets": "Collections",
"ViewTypeChannels": "Channels",
"ViewTypeLiveTV": "Live TV",
diff --git a/MediaBrowser.Server.Implementations/Music/MusicDynamicImageProvider.cs b/MediaBrowser.Server.Implementations/Music/MusicDynamicImageProvider.cs
index 846357529..a26e3819e 100644
--- a/MediaBrowser.Server.Implementations/Music/MusicDynamicImageProvider.cs
+++ b/MediaBrowser.Server.Implementations/Music/MusicDynamicImageProvider.cs
@@ -1,5 +1,6 @@
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
@@ -8,6 +9,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
+using MoreLinq;
namespace MediaBrowser.Server.Implementations.Music
{
@@ -36,7 +38,42 @@ namespace MediaBrowser.Server.Implementations.Music
}).ConfigureAwait(false);
- return GetFinalItems(result.Items.Where(i => i.HasImage(ImageType.Primary)).ToList());
+ var items = result.Items.Select(i =>
+ {
+ var episode = i as Episode;
+ if (episode != null)
+ {
+ var series = episode.Series;
+ if (series != null)
+ {
+ return series;
+ }
+ var episodeSeason = episode.Season;
+ if (episodeSeason != null)
+ {
+ return episodeSeason;
+ }
+
+ return episode;
+ }
+
+ var season = i as Season;
+ if (season != null)
+ {
+ var series = season.Series;
+ if (series != null)
+ {
+ return series;
+ }
+
+ return season;
+ }
+
+ return i;
+
+ }).DistinctBy(i => i.Id);
+
+ return GetFinalItems(items.Where(i => i.HasImage(ImageType.Primary)).ToList());
}
protected override bool Supports(IHasImages item)
@@ -50,6 +87,7 @@ namespace MediaBrowser.Server.Implementations.Music
SpecialFolder.TvFavoriteEpisodes,
SpecialFolder.TvFavoriteSeries,
SpecialFolder.TvGenres,
+ SpecialFolder.TvGenre,
SpecialFolder.TvLatest,
SpecialFolder.TvNextUp,
SpecialFolder.TvResume,
@@ -58,12 +96,14 @@ namespace MediaBrowser.Server.Implementations.Music
SpecialFolder.MovieCollections,
SpecialFolder.MovieFavorites,
SpecialFolder.MovieGenres,
+ SpecialFolder.MovieGenre,
SpecialFolder.MovieLatest,
SpecialFolder.MovieMovies,
SpecialFolder.MovieResume,
SpecialFolder.GameFavorites,
SpecialFolder.GameGenres,
+ SpecialFolder.GameGenre,
SpecialFolder.GameSystems,
SpecialFolder.LatestGames,
SpecialFolder.RecentlyPlayedGames,
@@ -72,6 +112,7 @@ namespace MediaBrowser.Server.Implementations.Music
SpecialFolder.MusicAlbumArtists,
SpecialFolder.MusicAlbums,
SpecialFolder.MusicGenres,
+ SpecialFolder.MusicGenre,
SpecialFolder.MusicLatest,
SpecialFolder.MusicSongs,
SpecialFolder.MusicFavorites,
diff --git a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj
index a0c8336f3..6aed66744 100644
--- a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj
+++ b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj
@@ -173,6 +173,9 @@
<None Include="MediaBrowser.MediaInfo.dll.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
+ <None Include="mediabrowser.sh">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </None>
<None Include="packages.config" />
<None Include="System.Data.SQLite.dll.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
diff --git a/MediaBrowser.Server.Mono/mediabrowser.sh b/MediaBrowser.Server.Mono/mediabrowser.sh
new file mode 100644
index 000000000..45884de3e
--- /dev/null
+++ b/MediaBrowser.Server.Mono/mediabrowser.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+mono MediaBrowser.Server.Mono.exe \ No newline at end of file
diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
index c321b4c09..d8358909e 100644
--- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
+++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
@@ -82,6 +82,7 @@ using MediaBrowser.Server.Implementations.Sync;
using MediaBrowser.Server.Implementations.Themes;
using MediaBrowser.Server.Implementations.TV;
using MediaBrowser.Server.Startup.Common.FFMpeg;
+using MediaBrowser.Server.Startup.Common.Migrations;
using MediaBrowser.WebDashboard.Api;
using MediaBrowser.XbmcMetadata.Providers;
using System;
@@ -322,84 +323,10 @@ namespace MediaBrowser.Server.Startup.Common
private void PerformVersionMigration()
{
- DeleteDeprecatedModules();
-
- if (!ServerConfigurationManager.Configuration.PlaylistImagesDeleted)
- {
- DeletePlaylistImages();
- ServerConfigurationManager.Configuration.PlaylistImagesDeleted = true;
- ServerConfigurationManager.SaveConfiguration();
- }
- }
-
- private void DeletePlaylistImages()
- {
- try
- {
- var path = Path.Combine(ApplicationPaths.DataPath, "playlists");
-
- var files = Directory.GetFiles(path, "*", SearchOption.AllDirectories)
- .Where(i => BaseItem.SupportedImageExtensions.Contains(Path.GetExtension(i) ?? string.Empty))
- .ToList();
-
- foreach (var file in files)
- {
- try
- {
- File.Delete(file);
- }
- catch (IOException)
- {
-
- }
- }
- }
- catch (IOException)
- {
-
- }
- }
-
- private void DeleteDeprecatedModules()
- {
- try
- {
- MigrateUserFolders();
- }
- catch (IOException)
- {
- }
-
- try
- {
- File.Delete(Path.Combine(ApplicationPaths.PluginsPath, "MBPhoto.dll"));
- }
- catch (IOException)
- {
- // Not there, no big deal
- }
-
- try
- {
- File.Delete(Path.Combine(ApplicationPaths.PluginsPath, "MediaBrowser.Plugins.XbmcMetadata.dll"));
- }
- catch (IOException)
- {
- // Not there, no big deal
- }
- }
-
- private void MigrateUserFolders()
- {
- var rootPath = ApplicationPaths.RootFolderPath;
-
- var folders = new DirectoryInfo(rootPath).EnumerateDirectories("*", SearchOption.TopDirectoryOnly).Where(i => !string.Equals(i.Name, "default", StringComparison.OrdinalIgnoreCase))
- .ToList();
-
- foreach (var folder in folders)
- {
- Directory.Delete(folder.FullName, true);
- }
+ new MigrateUserFolders(ApplicationPaths).Run();
+ new PlaylistImages(ServerConfigurationManager).Run();
+ new RenameXbmcOptions(ServerConfigurationManager).Run();
+ new RenameXmlOptions(ServerConfigurationManager).Run();
}
/// <summary>
diff --git a/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj b/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj
index 3f04694b9..da0e896e6 100644
--- a/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj
+++ b/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj
@@ -60,6 +60,11 @@
<Compile Include="FFMpeg\FFMpegDownloadInfo.cs" />
<Compile Include="FFMpeg\FFMpegInfo.cs" />
<Compile Include="INativeApp.cs" />
+ <Compile Include="Migrations\IVersionMigration.cs" />
+ <Compile Include="Migrations\MigrateUserFolders.cs" />
+ <Compile Include="Migrations\PlaylistImages.cs" />
+ <Compile Include="Migrations\RenameXbmcOptions.cs" />
+ <Compile Include="Migrations\RenameXmlOptions.cs" />
<Compile Include="NativeEnvironment.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="StartupOptions.cs" />
diff --git a/MediaBrowser.Server.Startup.Common/Migrations/IVersionMigration.cs b/MediaBrowser.Server.Startup.Common/Migrations/IVersionMigration.cs
new file mode 100644
index 000000000..a6a8c1a35
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/Migrations/IVersionMigration.cs
@@ -0,0 +1,8 @@
+
+namespace MediaBrowser.Server.Startup.Common.Migrations
+{
+ public interface IVersionMigration
+ {
+ void Run();
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/Migrations/MigrateUserFolders.cs b/MediaBrowser.Server.Startup.Common/Migrations/MigrateUserFolders.cs
new file mode 100644
index 000000000..5e3df5701
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/Migrations/MigrateUserFolders.cs
@@ -0,0 +1,36 @@
+using MediaBrowser.Controller;
+using System;
+using System.IO;
+using System.Linq;
+
+namespace MediaBrowser.Server.Startup.Common.Migrations
+{
+ public class MigrateUserFolders : IVersionMigration
+ {
+ private readonly IServerApplicationPaths _appPaths;
+
+ public MigrateUserFolders(IServerApplicationPaths appPaths)
+ {
+ _appPaths = appPaths;
+ }
+
+ public void Run()
+ {
+ try
+ {
+ var rootPath = _appPaths.RootFolderPath;
+
+ var folders = new DirectoryInfo(rootPath).EnumerateDirectories("*", SearchOption.TopDirectoryOnly).Where(i => !string.Equals(i.Name, "default", StringComparison.OrdinalIgnoreCase))
+ .ToList();
+
+ foreach (var folder in folders)
+ {
+ Directory.Delete(folder.FullName, true);
+ }
+ }
+ catch (IOException)
+ {
+ }
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/Migrations/PlaylistImages.cs b/MediaBrowser.Server.Startup.Common/Migrations/PlaylistImages.cs
new file mode 100644
index 000000000..f6ddf5847
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/Migrations/PlaylistImages.cs
@@ -0,0 +1,55 @@
+using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Entities;
+using System.IO;
+using System.Linq;
+
+namespace MediaBrowser.Server.Startup.Common.Migrations
+{
+ public class PlaylistImages : IVersionMigration
+ {
+ private readonly IServerConfigurationManager _config;
+
+ public PlaylistImages(IServerConfigurationManager config)
+ {
+ _config = config;
+ }
+
+ public void Run()
+ {
+ if (!_config.Configuration.PlaylistImagesDeleted)
+ {
+ DeletePlaylistImages();
+ _config.Configuration.PlaylistImagesDeleted = true;
+ _config.SaveConfiguration();
+ }
+ }
+
+ private void DeletePlaylistImages()
+ {
+ try
+ {
+ var path = Path.Combine(_config.ApplicationPaths.DataPath, "playlists");
+
+ var files = Directory.GetFiles(path, "*", SearchOption.AllDirectories)
+ .Where(i => BaseItem.SupportedImageExtensions.Contains(Path.GetExtension(i) ?? string.Empty))
+ .ToList();
+
+ foreach (var file in files)
+ {
+ try
+ {
+ File.Delete(file);
+ }
+ catch (IOException)
+ {
+
+ }
+ }
+ }
+ catch (IOException)
+ {
+
+ }
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/Migrations/RenameXbmcOptions.cs b/MediaBrowser.Server.Startup.Common/Migrations/RenameXbmcOptions.cs
new file mode 100644
index 000000000..efc34c1d8
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/Migrations/RenameXbmcOptions.cs
@@ -0,0 +1,56 @@
+using MediaBrowser.Controller.Configuration;
+using System;
+
+namespace MediaBrowser.Server.Startup.Common.Migrations
+{
+ public class RenameXbmcOptions
+ {
+ private readonly IServerConfigurationManager _config;
+
+ public RenameXbmcOptions(IServerConfigurationManager config)
+ {
+ _config = config;
+ }
+
+ public void Run()
+ {
+ var changed = false;
+
+ foreach (var option in _config.Configuration.MetadataOptions)
+ {
+ if (Migrate(option.DisabledMetadataSavers))
+ {
+ changed = true;
+ }
+ if (Migrate(option.LocalMetadataReaderOrder))
+ {
+ changed = true;
+ }
+ }
+
+ if (changed)
+ {
+ _config.SaveConfiguration();
+ }
+ }
+
+ private bool Migrate(string[] options)
+ {
+ var changed = false;
+
+ if (options != null)
+ {
+ for (var i = 0; i < options.Length; i++)
+ {
+ if (string.Equals(options[i], "Xbmc Nfo", StringComparison.OrdinalIgnoreCase))
+ {
+ options[i] = "Nfo";
+ changed = true;
+ }
+ }
+ }
+
+ return changed;
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/Migrations/RenameXmlOptions.cs b/MediaBrowser.Server.Startup.Common/Migrations/RenameXmlOptions.cs
new file mode 100644
index 000000000..3034fad31
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/Migrations/RenameXmlOptions.cs
@@ -0,0 +1,56 @@
+using MediaBrowser.Controller.Configuration;
+using System;
+
+namespace MediaBrowser.Server.Startup.Common.Migrations
+{
+ public class RenameXmlOptions
+ {
+ private readonly IServerConfigurationManager _config;
+
+ public RenameXmlOptions(IServerConfigurationManager config)
+ {
+ _config = config;
+ }
+
+ public void Run()
+ {
+ var changed = false;
+
+ foreach (var option in _config.Configuration.MetadataOptions)
+ {
+ if (Migrate(option.DisabledMetadataSavers))
+ {
+ changed = true;
+ }
+ if (Migrate(option.LocalMetadataReaderOrder))
+ {
+ changed = true;
+ }
+ }
+
+ if (changed)
+ {
+ _config.SaveConfiguration();
+ }
+ }
+
+ private bool Migrate(string[] options)
+ {
+ var changed = false;
+
+ if (options != null)
+ {
+ for (var i = 0; i < options.Length; i++)
+ {
+ if (string.Equals(options[i], "Media Browser Xml", StringComparison.OrdinalIgnoreCase))
+ {
+ options[i] = "Media Browser Legacy Xml";
+ changed = true;
+ }
+ }
+ }
+
+ return changed;
+ }
+ }
+}
diff --git a/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs b/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs
index 8b73107bf..b5c4bef90 100644
--- a/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs
+++ b/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs
@@ -69,6 +69,11 @@ namespace MediaBrowser.XbmcMetadata.Parsers
Fetch(item, userDataList, metadataFile, settings, cancellationToken);
}
+ protected virtual bool SupportsUrlAfterClosingXmlTag
+ {
+ get { return false; }
+ }
+
/// <summary>
/// Fetches the specified item.
/// </summary>
@@ -79,6 +84,30 @@ namespace MediaBrowser.XbmcMetadata.Parsers
/// <param name="cancellationToken">The cancellation token.</param>
private void Fetch(T item, List<UserItemData> userDataList, string metadataFile, XmlReaderSettings settings, CancellationToken cancellationToken)
{
+ if (!SupportsUrlAfterClosingXmlTag)
+ {
+ using (var streamReader = BaseNfoSaver.GetStreamReader(metadataFile))
+ {
+ // Use XmlReader for best performance
+ using (var reader = XmlReader.Create(streamReader, settings))
+ {
+ reader.MoveToContent();
+
+ // Loop through each element
+ while (reader.Read())
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+
+ if (reader.NodeType == XmlNodeType.Element)
+ {
+ FetchDataFromXmlNode(reader, item, userDataList);
+ }
+ }
+ }
+ }
+ return;
+ }
+
using (var streamReader = BaseNfoSaver.GetStreamReader(metadataFile))
{
// Need to handle a url after the xml data
diff --git a/MediaBrowser.XbmcMetadata/Parsers/MovieNfoParser.cs b/MediaBrowser.XbmcMetadata/Parsers/MovieNfoParser.cs
index 7cf987f9c..2a275320f 100644
--- a/MediaBrowser.XbmcMetadata/Parsers/MovieNfoParser.cs
+++ b/MediaBrowser.XbmcMetadata/Parsers/MovieNfoParser.cs
@@ -28,6 +28,14 @@ namespace MediaBrowser.XbmcMetadata.Parsers
Fetch(item, userDataList, metadataFile, cancellationToken);
}
+ protected override bool SupportsUrlAfterClosingXmlTag
+ {
+ get
+ {
+ return true;
+ }
+ }
+
/// <summary>
/// Fetches the data from XML node.
/// </summary>
diff --git a/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs b/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs
index 73358cb21..86e92530f 100644
--- a/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs
+++ b/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs
@@ -131,7 +131,7 @@ namespace MediaBrowser.XbmcMetadata.Savers
{
get
{
- return "Xbmc Nfo";
+ return "Nfo";
}
}
diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec
index 4b95fcf59..dd529093f 100644
--- a/Nuget/MediaBrowser.Common.Internal.nuspec
+++ b/Nuget/MediaBrowser.Common.Internal.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaBrowser.Common.Internal</id>
- <version>3.0.506</version>
+ <version>3.0.507</version>
<title>MediaBrowser.Common.Internal</title>
<authors>Luke</authors>
<owners>ebr,Luke,scottisafool</owners>
@@ -12,7 +12,7 @@
<description>Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption.</description>
<copyright>Copyright © Media Browser 2013</copyright>
<dependencies>
- <dependency id="MediaBrowser.Common" version="3.0.506" />
+ <dependency id="MediaBrowser.Common" version="3.0.507" />
<dependency id="NLog" version="3.1.0.0" />
<dependency id="SimpleInjector" version="2.6.1" />
<dependency id="sharpcompress" version="0.10.2" />
diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec
index a5dfc5850..dac65b65b 100644
--- a/Nuget/MediaBrowser.Common.nuspec
+++ b/Nuget/MediaBrowser.Common.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaBrowser.Common</id>
- <version>3.0.506</version>
+ <version>3.0.507</version>
<title>MediaBrowser.Common</title>
<authors>Media Browser Team</authors>
<owners>ebr,Luke,scottisafool</owners>
diff --git a/Nuget/MediaBrowser.Model.Signed.nuspec b/Nuget/MediaBrowser.Model.Signed.nuspec
index 4b7462151..6517c99a0 100644
--- a/Nuget/MediaBrowser.Model.Signed.nuspec
+++ b/Nuget/MediaBrowser.Model.Signed.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaBrowser.Model.Signed</id>
- <version>3.0.506</version>
+ <version>3.0.507</version>
<title>MediaBrowser.Model - Signed Edition</title>
<authors>Media Browser Team</authors>
<owners>ebr,Luke,scottisafool</owners>
diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec
index a5e6f216c..0d017c293 100644
--- a/Nuget/MediaBrowser.Server.Core.nuspec
+++ b/Nuget/MediaBrowser.Server.Core.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>MediaBrowser.Server.Core</id>
- <version>3.0.506</version>
+ <version>3.0.507</version>
<title>Media Browser.Server.Core</title>
<authors>Media Browser Team</authors>
<owners>ebr,Luke,scottisafool</owners>
@@ -12,7 +12,7 @@
<description>Contains core components required to build plugins for Media Browser Server.</description>
<copyright>Copyright © Media Browser 2013</copyright>
<dependencies>
- <dependency id="MediaBrowser.Common" version="3.0.506" />
+ <dependency id="MediaBrowser.Common" version="3.0.507" />
</dependencies>
</metadata>
<files>