Merge branch 'dev' into Video-Playlist-Controls

This commit is contained in:
T. Adams 2015-03-13 21:57:10 -07:00
commit eff23da373
121 changed files with 1525 additions and 930 deletions

View File

@ -53,7 +53,7 @@ namespace MediaBrowser.Api
var albums = _libraryManager.RootFolder var albums = _libraryManager.RootFolder
.GetRecursiveChildren() .GetRecursiveChildren()
.OfType<MusicAlbum>() .OfType<MusicAlbum>()
.Where(i => i.HasArtist(item.Name)) .Where(i => i.HasAnyArtist(item.Name))
.ToList(); .ToList();
var musicArtists = albums var musicArtists = albums

View File

@ -389,20 +389,33 @@ namespace MediaBrowser.Api
game.PlayersSupported = request.Players; game.PlayersSupported = request.Players;
} }
var song = item as Audio; var hasAlbumArtists = item as IHasAlbumArtist;
if (hasAlbumArtists != null)
{
hasAlbumArtists.AlbumArtists = request
.AlbumArtists
.Select(i => i.Name)
.ToList();
}
var hasArtists = item as IHasArtist;
if (hasArtists != null)
{
hasArtists.Artists = request
.ArtistItems
.Select(i => i.Name)
.ToList();
}
var song = item as Audio;
if (song != null) if (song != null)
{ {
song.Album = request.Album; song.Album = request.Album;
song.AlbumArtists = string.IsNullOrWhiteSpace(request.AlbumArtist) ? new List<string>() : new List<string> { request.AlbumArtist };
song.Artists = request.Artists.ToList();
} }
var musicVideo = item as MusicVideo; var musicVideo = item as MusicVideo;
if (musicVideo != null) if (musicVideo != null)
{ {
musicVideo.Artists = request.Artists.ToList();
musicVideo.Album = request.Album; musicVideo.Album = request.Album;
} }

View File

@ -77,15 +77,13 @@ namespace MediaBrowser.Api.Music
var album1 = (MusicAlbum)item1; var album1 = (MusicAlbum)item1;
var album2 = (MusicAlbum)item2; var album2 = (MusicAlbum)item2;
var artists1 = album1.GetRecursiveChildren(i => i is IHasArtist) var artists1 = album1
.Cast<IHasArtist>() .AllArtists
.SelectMany(i => i.AllArtists)
.Distinct(StringComparer.OrdinalIgnoreCase) .Distinct(StringComparer.OrdinalIgnoreCase)
.ToList(); .ToList();
var artists2 = album2.GetRecursiveChildren(i => i is IHasArtist) var artists2 = album2
.Cast<IHasArtist>() .AllArtists
.SelectMany(i => i.AllArtists)
.Distinct(StringComparer.OrdinalIgnoreCase) .Distinct(StringComparer.OrdinalIgnoreCase)
.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase); .ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);

View File

@ -25,10 +25,7 @@ namespace MediaBrowser.Api.Playback
public void Start() public void Start()
{ {
if (_processManager.SupportsSuspension) _timer = new Timer(TimerCallback, null, 5000, 5000);
{
//_timer = new Timer(TimerCallback, null, 5000, 5000);
}
} }
private void TimerCallback(object state) private void TimerCallback(object state)
@ -58,8 +55,7 @@ namespace MediaBrowser.Api.Playback
try try
{ {
//_job.Process.StandardInput.WriteLine("p"); _job.Process.StandardInput.WriteLine("p");
_processManager.SuspendProcess(_job.Process);
_isPaused = true; _isPaused = true;
} }
catch (Exception ex) catch (Exception ex)
@ -77,8 +73,7 @@ namespace MediaBrowser.Api.Playback
try try
{ {
//_job.Process.StandardInput.WriteLine("u"); _job.Process.StandardInput.WriteLine("u");
_processManager.ResumeProcess(_job.Process);
_isPaused = false; _isPaused = false;
} }
catch (Exception ex) catch (Exception ex)

View File

@ -211,7 +211,7 @@ namespace MediaBrowser.Api
result.SongCount = album.Tracks.Count(); result.SongCount = album.Tracks.Count();
result.Artists = album.Artists.ToArray(); result.Artists = album.Artists.ToArray();
result.AlbumArtist = album.AlbumArtists.FirstOrDefault(); result.AlbumArtist = album.AlbumArtist;
} }
var song = item as Audio; var song = item as Audio;

View File

@ -65,6 +65,7 @@ namespace MediaBrowser.Api
_config.Configuration.MergeMetadataAndImagesByName = true; _config.Configuration.MergeMetadataAndImagesByName = true;
_config.Configuration.EnableStandaloneMetadata = true; _config.Configuration.EnableStandaloneMetadata = true;
_config.Configuration.EnableLibraryMetadataSubFolder = true; _config.Configuration.EnableLibraryMetadataSubFolder = true;
_config.Configuration.EnableUserSpecificUserViews = true;
_config.SaveConfiguration(); _config.SaveConfiguration();
} }

View File

@ -125,13 +125,15 @@ namespace MediaBrowser.Api.Subtitles
private readonly ISubtitleManager _subtitleManager; private readonly ISubtitleManager _subtitleManager;
private readonly ISubtitleEncoder _subtitleEncoder; private readonly ISubtitleEncoder _subtitleEncoder;
private readonly IMediaSourceManager _mediaSourceManager; private readonly IMediaSourceManager _mediaSourceManager;
private readonly IProviderManager _providerManager;
public SubtitleService(ILibraryManager libraryManager, ISubtitleManager subtitleManager, ISubtitleEncoder subtitleEncoder, IMediaSourceManager mediaSourceManager) public SubtitleService(ILibraryManager libraryManager, ISubtitleManager subtitleManager, ISubtitleEncoder subtitleEncoder, IMediaSourceManager mediaSourceManager, IProviderManager providerManager)
{ {
_libraryManager = libraryManager; _libraryManager = libraryManager;
_subtitleManager = subtitleManager; _subtitleManager = subtitleManager;
_subtitleEncoder = subtitleEncoder; _subtitleEncoder = subtitleEncoder;
_mediaSourceManager = mediaSourceManager; _mediaSourceManager = mediaSourceManager;
_providerManager = providerManager;
} }
public object Get(GetSubtitlePlaylist request) public object Get(GetSubtitlePlaylist request)
@ -256,7 +258,7 @@ namespace MediaBrowser.Api.Subtitles
await _subtitleManager.DownloadSubtitles(video, request.SubtitleId, CancellationToken.None) await _subtitleManager.DownloadSubtitles(video, request.SubtitleId, CancellationToken.None)
.ConfigureAwait(false); .ConfigureAwait(false);
await video.RefreshMetadata(new MetadataRefreshOptions(new DirectoryService()), CancellationToken.None).ConfigureAwait(false); _providerManager.QueueRefresh(video.Id, new MetadataRefreshOptions());
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@ -46,9 +46,6 @@ namespace MediaBrowser.Api.UserLibrary
[ApiMember(Name = "PersonTypes", Description = "Optional. If specified, along with Person, results will be filtered to include only those containing the specified person and PersonType. Allows multiple, comma-delimited", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] [ApiMember(Name = "PersonTypes", Description = "Optional. If specified, along with Person, results will be filtered to include only those containing the specified person and PersonType. Allows multiple, comma-delimited", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public string PersonTypes { get; set; } public string PersonTypes { get; set; }
[ApiMember(Name = "AllGenres", Description = "Optional. If specified, results will be filtered based on genre. This allows multiple, pipe delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
public string AllGenres { get; set; }
/// <summary> /// <summary>
/// Limit results to items containing specific studios /// Limit results to items containing specific studios
/// </summary> /// </summary>
@ -56,6 +53,9 @@ namespace MediaBrowser.Api.UserLibrary
[ApiMember(Name = "Studios", Description = "Optional. If specified, results will be filtered based on studio. This allows multiple, pipe delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] [ApiMember(Name = "Studios", Description = "Optional. If specified, results will be filtered based on studio. This allows multiple, pipe delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
public string Studios { get; set; } public string Studios { get; set; }
[ApiMember(Name = "StudioIds", Description = "Optional. If specified, results will be filtered based on studio. This allows multiple, pipe delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
public string StudioIds { get; set; }
/// <summary> /// <summary>
/// Gets or sets the studios. /// Gets or sets the studios.
/// </summary> /// </summary>
@ -63,6 +63,9 @@ namespace MediaBrowser.Api.UserLibrary
[ApiMember(Name = "Artists", Description = "Optional. If specified, results will be filtered based on artist. This allows multiple, pipe delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] [ApiMember(Name = "Artists", Description = "Optional. If specified, results will be filtered based on artist. This allows multiple, pipe delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
public string Artists { get; set; } public string Artists { get; set; }
[ApiMember(Name = "ArtistIds", Description = "Optional. If specified, results will be filtered based on artist. This allows multiple, pipe delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
public string ArtistIds { get; set; }
[ApiMember(Name = "Albums", Description = "Optional. If specified, results will be filtered based on album. This allows multiple, pipe delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] [ApiMember(Name = "Albums", Description = "Optional. If specified, results will be filtered based on album. This allows multiple, pipe delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
public string Albums { get; set; } public string Albums { get; set; }
@ -226,22 +229,22 @@ namespace MediaBrowser.Api.UserLibrary
[ApiMember(Name = "CollapseBoxSetItems", Description = "Whether or not to hide items behind their boxsets.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")] [ApiMember(Name = "CollapseBoxSetItems", Description = "Whether or not to hide items behind their boxsets.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
public bool? CollapseBoxSetItems { get; set; } public bool? CollapseBoxSetItems { get; set; }
public string[] GetAllGenres()
{
return (AllGenres ?? string.Empty).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
}
public string[] GetStudios() public string[] GetStudios()
{ {
return (Studios ?? string.Empty).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries); return (Studios ?? string.Empty).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
} }
public string[] GetStudioIds()
{
return (StudioIds ?? string.Empty).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
}
public string[] GetPersonTypes() public string[] GetPersonTypes()
{ {
return (PersonTypes ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); return (PersonTypes ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
} }
public IEnumerable<VideoType> GetVideoTypes() public VideoType[] GetVideoTypes()
{ {
var val = VideoTypes; var val = VideoTypes;
@ -250,7 +253,7 @@ namespace MediaBrowser.Api.UserLibrary
return new VideoType[] { }; return new VideoType[] { };
} }
return val.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(v => (VideoType)Enum.Parse(typeof(VideoType), v, true)); return val.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(v => (VideoType)Enum.Parse(typeof(VideoType), v, true)).ToArray();
} }
} }
@ -471,8 +474,8 @@ namespace MediaBrowser.Api.UserLibrary
Tags = request.GetTags(), Tags = request.GetTags(),
OfficialRatings = request.GetOfficialRatings(), OfficialRatings = request.GetOfficialRatings(),
Genres = request.GetGenres(), Genres = request.GetGenres(),
AllGenres = request.GetAllGenres(),
Studios = request.GetStudios(), Studios = request.GetStudios(),
StudioIds = request.GetStudioIds(),
Person = request.Person, Person = request.Person,
PersonTypes = request.GetPersonTypes(), PersonTypes = request.GetPersonTypes(),
Years = request.GetYears(), Years = request.GetYears(),
@ -609,6 +612,8 @@ namespace MediaBrowser.Api.UserLibrary
private bool ApplyAdditionalFilters(GetItems request, BaseItem i, User user, bool isPreFiltered, ILibraryManager libraryManager) private bool ApplyAdditionalFilters(GetItems request, BaseItem i, User user, bool isPreFiltered, ILibraryManager libraryManager)
{ {
var video = i as Video;
if (!isPreFiltered) if (!isPreFiltered)
{ {
var mediaTypes = request.GetMediaTypes(); var mediaTypes = request.GetMediaTypes();
@ -656,7 +661,6 @@ namespace MediaBrowser.Api.UserLibrary
if (request.Is3D.HasValue) if (request.Is3D.HasValue)
{ {
var val = request.Is3D.Value; var val = request.Is3D.Value;
var video = i as Video;
if (video == null || val != video.Video3DFormat.HasValue) if (video == null || val != video.Video3DFormat.HasValue)
{ {
@ -667,7 +671,6 @@ namespace MediaBrowser.Api.UserLibrary
if (request.IsHD.HasValue) if (request.IsHD.HasValue)
{ {
var val = request.IsHD.Value; var val = request.IsHD.Value;
var video = i as Video;
if (video == null || val != video.IsHD) if (video == null || val != video.IsHD)
{ {
@ -809,8 +812,6 @@ namespace MediaBrowser.Api.UserLibrary
{ {
var val = request.HasSubtitles.Value; var val = request.HasSubtitles.Value;
var video = i as Video;
if (video == null || val != video.HasSubtitles) if (video == null || val != video.HasSubtitles)
{ {
return false; return false;
@ -930,25 +931,13 @@ namespace MediaBrowser.Api.UserLibrary
return false; return false;
} }
// Apply genre filter // Filter by VideoType
var allGenres = request.GetAllGenres(); var videoTypes = request.GetVideoTypes();
if (allGenres.Length > 0 && !allGenres.All(v => i.Genres.Contains(v, StringComparer.OrdinalIgnoreCase))) if (videoTypes.Length > 0 && (video == null || !videoTypes.Contains(video.VideoType)))
{ {
return false; return false;
} }
// Filter by VideoType
if (!string.IsNullOrEmpty(request.VideoTypes))
{
var types = request.VideoTypes.Split(',');
var video = i as Video;
if (video == null || !types.Contains(video.VideoType.ToString(), StringComparer.OrdinalIgnoreCase))
{
return false;
}
}
var imageTypes = request.GetImageTypes().ToList(); var imageTypes = request.GetImageTypes().ToList();
if (imageTypes.Count > 0) if (imageTypes.Count > 0)
{ {
@ -965,6 +954,17 @@ namespace MediaBrowser.Api.UserLibrary
return false; return false;
} }
// Apply studio filter
var studioIds = request.GetStudioIds();
if (studioIds.Length > 0 && !studioIds.Any(id =>
{
var studioItem = libraryManager.GetItemById(id);
return studioItem != null && i.Studios.Contains(studioItem.Name, StringComparer.OrdinalIgnoreCase);
}))
{
return false;
}
// Apply year filter // Apply year filter
var years = request.GetYears(); var years = request.GetYears();
if (years.Length > 0 && !(i.ProductionYear.HasValue && years.Contains(i.ProductionYear.Value))) if (years.Length > 0 && !(i.ProductionYear.HasValue && years.Contains(i.ProductionYear.Value)))
@ -1030,6 +1030,23 @@ namespace MediaBrowser.Api.UserLibrary
} }
} }
// Artists
if (!string.IsNullOrEmpty(request.ArtistIds))
{
var artistIds = request.ArtistIds.Split('|');
var audio = i as IHasArtist;
if (!(audio != null && artistIds.Any(id =>
{
var artistItem = libraryManager.GetItemById(id);
return artistItem != null && audio.HasAnyArtist(artistItem.Name);
})))
{
return false;
}
}
// Artists // Artists
if (!string.IsNullOrEmpty(request.Artists)) if (!string.IsNullOrEmpty(request.Artists))
{ {
@ -1037,7 +1054,7 @@ namespace MediaBrowser.Api.UserLibrary
var audio = i as IHasArtist; var audio = i as IHasArtist;
if (!(audio != null && artists.Any(audio.HasArtist))) if (!(audio != null && artists.Any(audio.HasAnyArtist)))
{ {
return false; return false;
} }

View File

@ -171,16 +171,6 @@ namespace MediaBrowser.Controller.Entities.Audio
+ (IndexNumber != null ? IndexNumber.Value.ToString("0000 - ") : "") + Name; + (IndexNumber != null ? IndexNumber.Value.ToString("0000 - ") : "") + Name;
} }
/// <summary>
/// Determines whether the specified name has artist.
/// </summary>
/// <param name="name">The name.</param>
/// <returns><c>true</c> if the specified name has artist; otherwise, <c>false</c>.</returns>
public bool HasArtist(string name)
{
return AllArtists.Contains(name, StringComparer.OrdinalIgnoreCase);
}
/// <summary> /// <summary>
/// Gets the user data key. /// Gets the user data key.
/// </summary> /// </summary>

View File

@ -1,4 +1,6 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Linq;
namespace MediaBrowser.Controller.Entities.Audio namespace MediaBrowser.Controller.Entities.Audio
{ {
@ -9,10 +11,20 @@ namespace MediaBrowser.Controller.Entities.Audio
public interface IHasArtist public interface IHasArtist
{ {
bool HasArtist(string name);
List<string> AllArtists { get; } List<string> AllArtists { get; }
List<string> Artists { get; } List<string> Artists { get; set; }
}
public static class HasArtistExtensions
{
public static bool HasArtist(this IHasArtist hasArtist, string artist)
{
return hasArtist.Artists.Contains(artist, StringComparer.OrdinalIgnoreCase);
}
public static bool HasAnyArtist(this IHasArtist hasArtist, string artist)
{
return hasArtist.AllArtists.Contains(artist, StringComparer.OrdinalIgnoreCase);
}
} }
} }

View File

@ -120,16 +120,6 @@ namespace MediaBrowser.Controller.Entities.Audio
get { return Parent as MusicArtist ?? UnknwonArtist; } get { return Parent as MusicArtist ?? UnknwonArtist; }
} }
/// <summary>
/// Determines whether the specified artist has artist.
/// </summary>
/// <param name="artist">The artist.</param>
/// <returns><c>true</c> if the specified artist has artist; otherwise, <c>false</c>.</returns>
public bool HasArtist(string artist)
{
return AllArtists.Contains(artist, StringComparer.OrdinalIgnoreCase);
}
public List<string> Artists { get; set; } public List<string> Artists { get; set; }
/// <summary> /// <summary>

View File

@ -213,7 +213,7 @@ namespace MediaBrowser.Controller.Entities.Audio
return i => return i =>
{ {
var hasArtist = i as IHasArtist; var hasArtist = i as IHasArtist;
return hasArtist != null && hasArtist.HasArtist(Name); return hasArtist != null && hasArtist.HasAnyArtist(Name);
}; };
} }
} }

View File

@ -1455,7 +1455,8 @@ namespace MediaBrowser.Controller.Entities
/// <returns>Task.</returns> /// <returns>Task.</returns>
public virtual Task ChangedExternally() public virtual Task ChangedExternally()
{ {
return RefreshMetadata(CancellationToken.None); ProviderManager.QueueRefresh(Id, new MetadataRefreshOptions());
return Task.FromResult(true);
} }
/// <summary> /// <summary>

View File

@ -30,7 +30,6 @@ namespace MediaBrowser.Controller.Entities
public string[] IncludeItemTypes { get; set; } public string[] IncludeItemTypes { get; set; }
public string[] ExcludeItemTypes { get; set; } public string[] ExcludeItemTypes { get; set; }
public string[] Genres { get; set; } public string[] Genres { get; set; }
public string[] AllGenres { get; set; }
public bool? IsMissing { get; set; } public bool? IsMissing { get; set; }
public bool? IsUnaired { get; set; } public bool? IsUnaired { get; set; }
@ -66,6 +65,7 @@ namespace MediaBrowser.Controller.Entities
public bool? HasParentalRating { get; set; } public bool? HasParentalRating { get; set; }
public string[] Studios { get; set; } public string[] Studios { get; set; }
public string[] StudioIds { get; set; }
public ImageType[] ImageTypes { get; set; } public ImageType[] ImageTypes { get; set; }
public VideoType[] VideoTypes { get; set; } public VideoType[] VideoTypes { get; set; }
public int[] Years { get; set; } public int[] Years { get; set; }
@ -80,9 +80,9 @@ namespace MediaBrowser.Controller.Entities
MediaTypes = new string[] { }; MediaTypes = new string[] { };
IncludeItemTypes = new string[] { }; IncludeItemTypes = new string[] { };
ExcludeItemTypes = new string[] { }; ExcludeItemTypes = new string[] { };
AllGenres = new string[] { };
Genres = new string[] { }; Genres = new string[] { };
Studios = new string[] { }; Studios = new string[] { };
StudioIds = new string[] { };
ImageTypes = new ImageType[] { }; ImageTypes = new ImageType[] { };
VideoTypes = new VideoType[] { }; VideoTypes = new VideoType[] { };
Years = new int[] { }; Years = new int[] { };

View File

@ -47,16 +47,6 @@ namespace MediaBrowser.Controller.Entities
} }
} }
/// <summary>
/// Determines whether the specified name has artist.
/// </summary>
/// <param name="name">The name.</param>
/// <returns><c>true</c> if the specified name has artist; otherwise, <c>false</c>.</returns>
public bool HasArtist(string name)
{
return AllArtists.Contains(name, StringComparer.OrdinalIgnoreCase);
}
/// <summary> /// <summary>
/// Gets the user data key. /// Gets the user data key.
/// </summary> /// </summary>

View File

@ -1,4 +1,5 @@
using MediaBrowser.Controller.TV; using MediaBrowser.Controller.Playlists;
using MediaBrowser.Controller.TV;
using MediaBrowser.Model.Entities; using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Querying; using MediaBrowser.Model.Querying;
using System; using System;
@ -15,6 +16,7 @@ namespace MediaBrowser.Controller.Entities
public Guid? UserId { get; set; } public Guid? UserId { get; set; }
public static ITVSeriesManager TVSeriesManager; public static ITVSeriesManager TVSeriesManager;
public static IPlaylistManager PlaylistManager;
public bool ContainsDynamicCategories(User user) public bool ContainsDynamicCategories(User user)
{ {
@ -30,7 +32,7 @@ namespace MediaBrowser.Controller.Entities
parent = LibraryManager.GetItemById(ParentId) as Folder ?? parent; parent = LibraryManager.GetItemById(ParentId) as Folder ?? parent;
} }
return new UserViewBuilder(UserViewManager, LiveTvManager, ChannelManager, LibraryManager, Logger, UserDataManager, TVSeriesManager, CollectionManager) return new UserViewBuilder(UserViewManager, LiveTvManager, ChannelManager, LibraryManager, Logger, UserDataManager, TVSeriesManager, CollectionManager, PlaylistManager)
.GetUserItems(parent, this, ViewType, query); .GetUserItems(parent, this, ViewType, query);
} }

View File

@ -5,6 +5,7 @@ using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.Playlists;
using MediaBrowser.Controller.TV; using MediaBrowser.Controller.TV;
using MediaBrowser.Model.Channels; using MediaBrowser.Model.Channels;
using MediaBrowser.Model.Entities; using MediaBrowser.Model.Entities;
@ -30,8 +31,9 @@ namespace MediaBrowser.Controller.Entities
private readonly IUserDataManager _userDataManager; private readonly IUserDataManager _userDataManager;
private readonly ITVSeriesManager _tvSeriesManager; private readonly ITVSeriesManager _tvSeriesManager;
private readonly ICollectionManager _collectionManager; private readonly ICollectionManager _collectionManager;
private readonly IPlaylistManager _playlistManager;
public UserViewBuilder(IUserViewManager userViewManager, ILiveTvManager liveTvManager, IChannelManager channelManager, ILibraryManager libraryManager, ILogger logger, IUserDataManager userDataManager, ITVSeriesManager tvSeriesManager, ICollectionManager collectionManager) public UserViewBuilder(IUserViewManager userViewManager, ILiveTvManager liveTvManager, IChannelManager channelManager, ILibraryManager libraryManager, ILogger logger, IUserDataManager userDataManager, ITVSeriesManager tvSeriesManager, ICollectionManager collectionManager, IPlaylistManager playlistManager)
{ {
_userViewManager = userViewManager; _userViewManager = userViewManager;
_liveTvManager = liveTvManager; _liveTvManager = liveTvManager;
@ -41,6 +43,7 @@ namespace MediaBrowser.Controller.Entities
_userDataManager = userDataManager; _userDataManager = userDataManager;
_tvSeriesManager = tvSeriesManager; _tvSeriesManager = tvSeriesManager;
_collectionManager = collectionManager; _collectionManager = collectionManager;
_playlistManager = playlistManager;
} }
public async Task<QueryResult<BaseItem>> GetUserItems(Folder queryParent, Folder displayParent, string viewType, InternalItemsQuery query) public async Task<QueryResult<BaseItem>> GetUserItems(Folder queryParent, Folder displayParent, string viewType, InternalItemsQuery query)
@ -115,6 +118,9 @@ namespace MediaBrowser.Controller.Entities
case CollectionType.Games: case CollectionType.Games:
return await GetGameView(user, queryParent, query).ConfigureAwait(false); return await GetGameView(user, queryParent, query).ConfigureAwait(false);
case CollectionType.Playlists:
return await GetPlaylistsView(queryParent, user, query).ConfigureAwait(false);
case CollectionType.BoxSets: case CollectionType.BoxSets:
return await GetBoxsetView(queryParent, user, query).ConfigureAwait(false); return await GetBoxsetView(queryParent, user, query).ConfigureAwait(false);
@ -572,6 +578,11 @@ namespace MediaBrowser.Controller.Entities
return GetResult(items, queryParent, query); return GetResult(items, queryParent, query);
} }
private async Task<QueryResult<BaseItem>> GetPlaylistsView(Folder parent, User user, InternalItemsQuery query)
{
return GetResult(_playlistManager.GetPlaylists(user.Id.ToString("N")), parent, query);
}
private async Task<QueryResult<BaseItem>> GetBoxsetView(Folder parent, User user, InternalItemsQuery query) private async Task<QueryResult<BaseItem>> GetBoxsetView(Folder parent, User user, InternalItemsQuery query)
{ {
return GetResult(GetMediaFolders(user).SelectMany(i => return GetResult(GetMediaFolders(user).SelectMany(i =>
@ -935,11 +946,6 @@ namespace MediaBrowser.Controller.Entities
return false; return false;
} }
if (request.AllGenres.Length > 0)
{
return false;
}
if (request.Genres.Length > 0) if (request.Genres.Length > 0)
{ {
return false; return false;
@ -1050,6 +1056,11 @@ namespace MediaBrowser.Controller.Entities
return false; return false;
} }
if (request.StudioIds.Length > 0)
{
return false;
}
if (request.VideoTypes.Length > 0) if (request.VideoTypes.Length > 0)
{ {
return false; return false;
@ -1569,12 +1580,6 @@ namespace MediaBrowser.Controller.Entities
return false; return false;
} }
// Apply genre filter
if (query.AllGenres.Length > 0 && !query.AllGenres.All(v => item.Genres.Contains(v, StringComparer.OrdinalIgnoreCase)))
{
return false;
}
// Filter by VideoType // Filter by VideoType
if (query.VideoTypes.Length > 0) if (query.VideoTypes.Length > 0)
{ {
@ -1596,6 +1601,16 @@ namespace MediaBrowser.Controller.Entities
return false; return false;
} }
// Apply studio filter
if (query.StudioIds.Length > 0 && !query.StudioIds.Any(id =>
{
var studioItem = libraryManager.GetItemById(id);
return studioItem != null && item.Studios.Contains(studioItem.Name, StringComparer.OrdinalIgnoreCase);
}))
{
return false;
}
// Apply year filter // Apply year filter
if (query.Years.Length > 0) if (query.Years.Length > 0)
{ {
@ -1714,7 +1729,7 @@ namespace MediaBrowser.Controller.Entities
var parent = user.RootFolder; var parent = user.RootFolder;
//list.Add(await GetUserView(SpecialFolder.LiveTvNowPlaying, user, "0", parent).ConfigureAwait(false)); //list.Add(await GetUserSubView(SpecialFolder.LiveTvNowPlaying, user, "0", parent).ConfigureAwait(false));
list.Add(await GetUserView(SpecialFolder.LiveTvChannels, user, string.Empty, parent).ConfigureAwait(false)); list.Add(await GetUserView(SpecialFolder.LiveTvChannels, user, string.Empty, parent).ConfigureAwait(false));
list.Add(await GetUserView(SpecialFolder.LiveTvRecordingGroups, user, string.Empty, parent).ConfigureAwait(false)); list.Add(await GetUserView(SpecialFolder.LiveTvRecordingGroups, user, string.Empty, parent).ConfigureAwait(false));
@ -1723,7 +1738,7 @@ namespace MediaBrowser.Controller.Entities
private async Task<UserView> GetUserView(string name, string type, User user, string sortName, BaseItem 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) var view = await _userViewManager.GetUserSubView(name, parent.Id.ToString("N"), type, user, sortName, CancellationToken.None)
.ConfigureAwait(false); .ConfigureAwait(false);
return view; return view;
@ -1731,7 +1746,7 @@ namespace MediaBrowser.Controller.Entities
private async Task<UserView> GetUserView(string type, User user, string sortName, BaseItem parent) 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) var view = await _userViewManager.GetUserSubView(parent.Id.ToString("N"), type, user, sortName, CancellationToken.None)
.ConfigureAwait(false); .ConfigureAwait(false);
return view; return view;

View File

@ -302,7 +302,7 @@ namespace MediaBrowser.Controller.Library
IEnumerable<BaseItem> ReplaceVideosWithPrimaryVersions(IEnumerable<BaseItem> items); IEnumerable<BaseItem> ReplaceVideosWithPrimaryVersions(IEnumerable<BaseItem> items);
/// <summary> /// <summary>
/// Gets the special folder. /// Gets the named view.
/// </summary> /// </summary>
/// <param name="user">The user.</param> /// <param name="user">The user.</param>
/// <param name="name">The name.</param> /// <param name="name">The name.</param>
@ -311,7 +311,7 @@ namespace MediaBrowser.Controller.Library
/// <param name="sortName">Name of the sort.</param> /// <param name="sortName">Name of the sort.</param>
/// <param name="cancellationToken">The cancellation token.</param> /// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task&lt;UserView&gt;.</returns> /// <returns>Task&lt;UserView&gt;.</returns>
Task<UserView> GetSpecialFolder(User user, Task<UserView> GetNamedView(User user,
string name, string name,
string parentId, string parentId,
string viewType, string viewType,
@ -321,12 +321,14 @@ namespace MediaBrowser.Controller.Library
/// <summary> /// <summary>
/// Gets the named view. /// Gets the named view.
/// </summary> /// </summary>
/// <param name="user">The user.</param>
/// <param name="name">The name.</param> /// <param name="name">The name.</param>
/// <param name="viewType">Type of the view.</param> /// <param name="viewType">Type of the view.</param>
/// <param name="sortName">Name of the sort.</param> /// <param name="sortName">Name of the sort.</param>
/// <param name="cancellationToken">The cancellation token.</param> /// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task&lt;UserView&gt;.</returns> /// <returns>Task&lt;UserView&gt;.</returns>
Task<UserView> GetNamedView(string name, Task<UserView> GetNamedView(User user,
string name,
string viewType, string viewType,
string sortName, string sortName,
CancellationToken cancellationToken); CancellationToken cancellationToken);

View File

@ -12,12 +12,10 @@ namespace MediaBrowser.Controller.Library
{ {
Task<IEnumerable<Folder>> GetUserViews(UserViewQuery query, CancellationToken cancellationToken); Task<IEnumerable<Folder>> GetUserViews(UserViewQuery query, CancellationToken cancellationToken);
Task<UserView> GetUserView(string name, string parentId, string type, User user, string sortName, Task<UserView> GetUserSubView(string name, string parentId, string type, User user, string sortName,
CancellationToken cancellationToken); CancellationToken cancellationToken);
Task<UserView> GetUserView(string type, string sortName, CancellationToken cancellationToken); Task<UserView> GetUserSubView(string category, string type, User user, string sortName, CancellationToken cancellationToken);
Task<UserView> GetUserView(string category, string type, User user, string sortName, CancellationToken cancellationToken);
List<Tuple<BaseItem, List<BaseItem>>> GetLatestItems(LatestItemsQuery request); List<Tuple<BaseItem, List<BaseItem>>> GetLatestItems(LatestItemsQuery request);
} }

View File

@ -247,22 +247,67 @@
<Compile Include="Persistence\MediaStreamQuery.cs" /> <Compile Include="Persistence\MediaStreamQuery.cs" />
<Compile Include="Playlists\IPlaylistManager.cs" /> <Compile Include="Playlists\IPlaylistManager.cs" />
<Compile Include="Playlists\Playlist.cs" /> <Compile Include="Playlists\Playlist.cs" />
<Compile Include="Providers\AlbumInfo.cs" />
<Compile Include="Providers\ArtistInfo.cs" />
<Compile Include="Providers\BookInfo.cs" />
<Compile Include="Providers\BoxSetInfo.cs" />
<Compile Include="Providers\ChannelItemLookupInfo.cs" />
<Compile Include="Providers\DirectoryService.cs" /> <Compile Include="Providers\DirectoryService.cs" />
<Compile Include="Providers\DynamicImageInfo.cs" />
<Compile Include="Providers\DynamicImageResponse.cs" />
<Compile Include="Providers\EpisodeIdentity.cs" />
<Compile Include="Providers\EpisodeInfo.cs" />
<Compile Include="Providers\ExtraInfo.cs" />
<Compile Include="Providers\ExtraSource.cs" />
<Compile Include="Providers\GameInfo.cs" />
<Compile Include="Providers\GameSystemInfo.cs" />
<Compile Include="Providers\ICustomMetadataProvider.cs" /> <Compile Include="Providers\ICustomMetadataProvider.cs" />
<Compile Include="Providers\IDirectoryService.cs" />
<Compile Include="Providers\IDynamicImageProvider.cs" />
<Compile Include="Providers\IExternalId.cs" /> <Compile Include="Providers\IExternalId.cs" />
<Compile Include="Providers\IExtrasProvider.cs" /> <Compile Include="Providers\IExtrasProvider.cs" />
<Compile Include="Providers\IForcedProvider.cs" /> <Compile Include="Providers\IForcedProvider.cs" />
<Compile Include="Providers\IHasChangeMonitor.cs" /> <Compile Include="Providers\IHasChangeMonitor.cs" />
<Compile Include="Entities\IHasMetadata.cs" /> <Compile Include="Entities\IHasMetadata.cs" />
<Compile Include="Providers\IHasIdentities.cs" />
<Compile Include="Providers\IHasItemChangeMonitor.cs" />
<Compile Include="Providers\IHasLookupInfo.cs" />
<Compile Include="Providers\IHasOrder.cs" />
<Compile Include="Providers\IImageFileSaver.cs" />
<Compile Include="Providers\IImageProvider.cs" /> <Compile Include="Providers\IImageProvider.cs" />
<Compile Include="Providers\IImageSaver.cs" /> <Compile Include="Providers\IImageSaver.cs" />
<Compile Include="Providers\IItemIdentity.cs" />
<Compile Include="Providers\IItemIdentityConverter.cs" />
<Compile Include="Providers\IItemIdentityProvider.cs" />
<Compile Include="Providers\ILocalImageFileProvider.cs" />
<Compile Include="Providers\ILocalMetadataProvider.cs" /> <Compile Include="Providers\ILocalMetadataProvider.cs" />
<Compile Include="Providers\ImageRefreshMode.cs" />
<Compile Include="Providers\ImageRefreshOptions.cs" />
<Compile Include="Providers\IPreRefreshProvider.cs" />
<Compile Include="Providers\IProviderRepository.cs" /> <Compile Include="Providers\IProviderRepository.cs" />
<Compile Include="Providers\IRemoteImageProvider.cs" /> <Compile Include="Providers\IRemoteImageProvider.cs" />
<Compile Include="Providers\ILocalImageProvider.cs" /> <Compile Include="Providers\ILocalImageProvider.cs" />
<Compile Include="Providers\IMetadataProvider.cs" /> <Compile Include="Providers\IMetadataProvider.cs" />
<Compile Include="Providers\IMetadataService.cs" /> <Compile Include="Providers\IMetadataService.cs" />
<Compile Include="Providers\IRemoteMetadataProvider.cs" /> <Compile Include="Providers\IRemoteMetadataProvider.cs" />
<Compile Include="Providers\IRemoteSearchProvider.cs" />
<Compile Include="Providers\ISeriesOrderProvider.cs" />
<Compile Include="Providers\ItemInfo.cs" />
<Compile Include="Providers\LocalImageInfo.cs" />
<Compile Include="Providers\LocalMetadataResult.cs" />
<Compile Include="Providers\MetadataRefreshMode.cs" />
<Compile Include="Providers\MetadataResult.cs" />
<Compile Include="Providers\MovieInfo.cs" />
<Compile Include="Providers\MusicVideoInfo.cs" />
<Compile Include="Providers\PersonLookupInfo.cs" />
<Compile Include="Providers\RemoteSearchQuery.cs" />
<Compile Include="Providers\SeasonIdentity.cs" />
<Compile Include="Providers\SeasonInfo.cs" />
<Compile Include="Providers\SeriesIdentity.cs" />
<Compile Include="Providers\SeriesInfo.cs" />
<Compile Include="Providers\SeriesOrderTypes.cs" />
<Compile Include="Providers\SongInfo.cs" />
<Compile Include="Providers\TrailerInfo.cs" />
<Compile Include="Providers\VideoContentType.cs" /> <Compile Include="Providers\VideoContentType.cs" />
<Compile Include="RelatedMedia\IRelatedMediaProvider.cs" /> <Compile Include="RelatedMedia\IRelatedMediaProvider.cs" />
<Compile Include="Security\AuthenticationInfo.cs" /> <Compile Include="Security\AuthenticationInfo.cs" />
@ -350,6 +395,7 @@
<Compile Include="Sync\ISyncManager.cs" /> <Compile Include="Sync\ISyncManager.cs" />
<Compile Include="Sync\ISyncProvider.cs" /> <Compile Include="Sync\ISyncProvider.cs" />
<Compile Include="Sync\ISyncRepository.cs" /> <Compile Include="Sync\ISyncRepository.cs" />
<Compile Include="Sync\SendFileResult.cs" />
<Compile Include="Themes\IAppThemeManager.cs" /> <Compile Include="Themes\IAppThemeManager.cs" />
<Compile Include="Themes\InternalThemeImage.cs" /> <Compile Include="Themes\InternalThemeImage.cs" />
<Compile Include="TV\ITVSeriesManager.cs" /> <Compile Include="TV\ITVSeriesManager.cs" />

View File

@ -106,7 +106,7 @@ namespace MediaBrowser.Controller.Playlists
Func<BaseItem, bool> filter = i => Func<BaseItem, bool> filter = i =>
{ {
var audio = i as Audio; var audio = i as Audio;
return audio != null && audio.HasArtist(musicArtist.Name); return audio != null && audio.HasAnyArtist(musicArtist.Name);
}; };
var items = user == null var items = user == null

View File

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
namespace MediaBrowser.Controller.Providers
{
public class AlbumInfo : ItemLookupInfo
{
/// <summary>
/// Gets or sets the album artist.
/// </summary>
/// <value>The album artist.</value>
public List<string> AlbumArtists { get; set; }
/// <summary>
/// Gets or sets the artist provider ids.
/// </summary>
/// <value>The artist provider ids.</value>
public Dictionary<string, string> ArtistProviderIds { get; set; }
public List<SongInfo> SongInfos { get; set; }
public AlbumInfo()
{
ArtistProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
SongInfos = new List<SongInfo>();
AlbumArtists = new List<string>();
}
}
}

View File

@ -0,0 +1,14 @@
using System.Collections.Generic;
namespace MediaBrowser.Controller.Providers
{
public class ArtistInfo : ItemLookupInfo
{
public List<SongInfo> SongInfos { get; set; }
public ArtistInfo()
{
SongInfos = new List<SongInfo>();
}
}
}

View File

@ -0,0 +1,7 @@
namespace MediaBrowser.Controller.Providers
{
public class BookInfo : ItemLookupInfo
{
public string SeriesName { get; set; }
}
}

View File

@ -0,0 +1,7 @@
namespace MediaBrowser.Controller.Providers
{
public class BoxSetInfo : ItemLookupInfo
{
}
}

View File

@ -0,0 +1,11 @@
using MediaBrowser.Model.Channels;
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Controller.Providers
{
public class ChannelItemLookupInfo : ItemLookupInfo
{
public ChannelMediaContentType ContentType { get; set; }
public ExtraType ExtraType { get; set; }
}
}

View File

@ -7,16 +7,6 @@ using System.Linq;
namespace MediaBrowser.Controller.Providers namespace MediaBrowser.Controller.Providers
{ {
public interface IDirectoryService
{
IEnumerable<FileSystemInfo> GetFileSystemEntries(string path);
IEnumerable<FileSystemInfo> GetFiles(string path);
IEnumerable<FileSystemInfo> GetDirectories(string path);
IEnumerable<FileSystemInfo> GetFiles(string path, bool clearCache);
FileSystemInfo GetFile(string path);
Dictionary<string, FileSystemInfo> GetFileSystemDictionary(string path);
}
public class DirectoryService : IDirectoryService public class DirectoryService : IDirectoryService
{ {
private readonly ILogger _logger; private readonly ILogger _logger;

View File

@ -0,0 +1,10 @@
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Controller.Providers
{
public class DynamicImageInfo
{
public string ImageId { get; set; }
public ImageType Type { get; set; }
}
}

View File

@ -0,0 +1,35 @@
using System;
using System.IO;
using MediaBrowser.Model.Drawing;
namespace MediaBrowser.Controller.Providers
{
public class DynamicImageResponse
{
public string Path { get; set; }
public Stream Stream { get; set; }
public ImageFormat Format { get; set; }
public bool HasImage { get; set; }
public string InternalCacheKey { get; set; }
public void SetFormatFromMimeType(string mimeType)
{
if (mimeType.EndsWith("gif", StringComparison.OrdinalIgnoreCase))
{
Format = ImageFormat.Gif;
}
else if (mimeType.EndsWith("bmp", StringComparison.OrdinalIgnoreCase))
{
Format = ImageFormat.Bmp;
}
else if (mimeType.EndsWith("png", StringComparison.OrdinalIgnoreCase))
{
Format = ImageFormat.Png;
}
else
{
Format = ImageFormat.Jpg;
}
}
}
}

View File

@ -0,0 +1,12 @@
namespace MediaBrowser.Controller.Providers
{
public class EpisodeIdentity : IItemIdentity
{
public string Type { get; set; }
public string SeriesId { get; set; }
public int? SeasonIndex { get; set; }
public int IndexNumber { get; set; }
public int? IndexNumberEnd { get; set; }
}
}

View File

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace MediaBrowser.Controller.Providers
{
public class EpisodeInfo : ItemLookupInfo, IHasIdentities<EpisodeIdentity>
{
private List<EpisodeIdentity> _identities = new List<EpisodeIdentity>();
public Dictionary<string, string> SeriesProviderIds { get; set; }
public int? IndexNumberEnd { get; set; }
public int? AnimeSeriesIndex { get; set; }
public EpisodeInfo()
{
SeriesProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
}
public IEnumerable<EpisodeIdentity> Identities
{
get { return _identities; }
}
public async Task FindIdentities(IProviderManager providerManager, CancellationToken cancellationToken)
{
var identifier = new ItemIdentifier<EpisodeInfo, EpisodeIdentity>();
_identities = (await identifier.FindIdentities(this, providerManager, cancellationToken)).ToList();
}
}
}

View File

@ -0,0 +1,15 @@
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Controller.Providers
{
public class ExtraInfo
{
public string Path { get; set; }
public LocationType LocationType { get; set; }
public bool IsDownloadable { get; set; }
public ExtraType ExtraType { get; set; }
}
}

View File

@ -0,0 +1,9 @@
namespace MediaBrowser.Controller.Providers
{
public enum ExtraSource
{
Local = 1,
Metadata = 2,
Remote = 3
}
}

View File

@ -0,0 +1,11 @@
namespace MediaBrowser.Controller.Providers
{
public class GameInfo : ItemLookupInfo
{
/// <summary>
/// Gets or sets the game system.
/// </summary>
/// <value>The game system.</value>
public string GameSystem { get; set; }
}
}

View File

@ -0,0 +1,11 @@
namespace MediaBrowser.Controller.Providers
{
public class GameSystemInfo : ItemLookupInfo
{
/// <summary>
/// Gets or sets the path.
/// </summary>
/// <value>The path.</value>
public string Path { get; set; }
}
}

View File

@ -21,9 +21,4 @@ namespace MediaBrowser.Controller.Providers
/// <returns>Task{ItemUpdateType}.</returns> /// <returns>Task{ItemUpdateType}.</returns>
Task<ItemUpdateType> FetchAsync(TItemType item, MetadataRefreshOptions options, CancellationToken cancellationToken); Task<ItemUpdateType> FetchAsync(TItemType item, MetadataRefreshOptions options, CancellationToken cancellationToken);
} }
public interface IPreRefreshProvider : ICustomMetadataProvider
{
}
} }

View File

@ -0,0 +1,15 @@
using System.Collections.Generic;
using System.IO;
namespace MediaBrowser.Controller.Providers
{
public interface IDirectoryService
{
IEnumerable<FileSystemInfo> GetFileSystemEntries(string path);
IEnumerable<FileSystemInfo> GetFiles(string path);
IEnumerable<FileSystemInfo> GetDirectories(string path);
IEnumerable<FileSystemInfo> GetFiles(string path, bool clearCache);
FileSystemInfo GetFile(string path);
Dictionary<string, FileSystemInfo> GetFileSystemDictionary(string path);
}
}

View File

@ -0,0 +1,27 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Controller.Providers
{
public interface IDynamicImageProvider : IImageProvider
{
/// <summary>
/// Gets the supported images.
/// </summary>
/// <param name="item">The item.</param>
/// <returns>IEnumerable{ImageType}.</returns>
IEnumerable<ImageType> GetSupportedImages(IHasImages item);
/// <summary>
/// Gets the image.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="type">The type.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{DynamicImageResponse}.</returns>
Task<DynamicImageResponse> GetImage(IHasImages item, ImageType type, CancellationToken cancellationToken);
}
}

View File

@ -1,5 +1,4 @@
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities;
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Controller.Providers namespace MediaBrowser.Controller.Providers
{ {
@ -18,22 +17,4 @@ namespace MediaBrowser.Controller.Providers
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns> /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
bool Supports(IHasMetadata item); bool Supports(IHasMetadata item);
} }
public enum ExtraSource
{
Local = 1,
Metadata = 2,
Remote = 3
}
public class ExtraInfo
{
public string Path { get; set; }
public LocationType LocationType { get; set; }
public bool IsDownloadable { get; set; }
public ExtraType ExtraType { get; set; }
}
} }

View File

@ -14,16 +14,4 @@ namespace MediaBrowser.Controller.Providers
/// <returns><c>true</c> if the specified item has changed; otherwise, <c>false</c>.</returns> /// <returns><c>true</c> if the specified item has changed; otherwise, <c>false</c>.</returns>
bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date); bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date);
} }
public interface IHasItemChangeMonitor
{
/// <summary>
/// Determines whether the specified item has changed.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="status">The status.</param>
/// <param name="directoryService">The directory service.</param>
/// <returns><c>true</c> if the specified item has changed; otherwise, <c>false</c>.</returns>
bool HasChanged(IHasMetadata item, MetadataStatus status, IDirectoryService directoryService);
}
} }

View File

@ -0,0 +1,14 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace MediaBrowser.Controller.Providers
{
public interface IHasIdentities<out TIdentity>
where TIdentity : IItemIdentity
{
IEnumerable<TIdentity> Identities { get; }
Task FindIdentities(IProviderManager providerManager, CancellationToken cancellationToken);
}
}

View File

@ -0,0 +1,16 @@
using MediaBrowser.Controller.Entities;
namespace MediaBrowser.Controller.Providers
{
public interface IHasItemChangeMonitor
{
/// <summary>
/// Determines whether the specified item has changed.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="status">The status.</param>
/// <param name="directoryService">The directory service.</param>
/// <returns><c>true</c> if the specified item has changed; otherwise, <c>false</c>.</returns>
bool HasChanged(IHasMetadata item, MetadataStatus status, IDirectoryService directoryService);
}
}

View File

@ -0,0 +1,8 @@
namespace MediaBrowser.Controller.Providers
{
public interface IHasLookupInfo<out TLookupInfoType>
where TLookupInfoType : ItemLookupInfo, new()
{
TLookupInfoType GetLookupInfo();
}
}

View File

@ -0,0 +1,7 @@
namespace MediaBrowser.Controller.Providers
{
public interface IHasOrder
{
int Order { get; }
}
}

View File

@ -0,0 +1,20 @@
using System.Collections.Generic;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Model.Drawing;
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Controller.Providers
{
public interface IImageFileSaver : IImageSaver
{
/// <summary>
/// Gets the save paths.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="type">The type.</param>
/// <param name="format">The format.</param>
/// <param name="index">The index.</param>
/// <returns>IEnumerable{System.String}.</returns>
IEnumerable<string> GetSavePaths(IHasImages item, ImageType type, ImageFormat format, int index);
}
}

View File

@ -1,9 +1,4 @@
using MediaBrowser.Controller.Entities; namespace MediaBrowser.Controller.Providers
using MediaBrowser.Model.Drawing;
using MediaBrowser.Model.Entities;
using System.Collections.Generic;
namespace MediaBrowser.Controller.Providers
{ {
public interface IImageSaver public interface IImageSaver
{ {
@ -13,17 +8,4 @@ namespace MediaBrowser.Controller.Providers
/// <value>The name.</value> /// <value>The name.</value>
string Name { get; } string Name { get; }
} }
public interface IImageFileSaver : IImageSaver
{
/// <summary>
/// Gets the save paths.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="type">The type.</param>
/// <param name="format">The format.</param>
/// <param name="index">The index.</param>
/// <returns>IEnumerable{System.String}.</returns>
IEnumerable<string> GetSavePaths(IHasImages item, ImageType type, ImageFormat format, int index);
}
} }

View File

@ -0,0 +1,7 @@
namespace MediaBrowser.Controller.Providers
{
public interface IItemIdentity
{
string Type { get; }
}
}

View File

@ -0,0 +1,4 @@
namespace MediaBrowser.Controller.Providers
{
public interface IItemIdentityConverter : IHasOrder { }
}

View File

@ -0,0 +1,4 @@
namespace MediaBrowser.Controller.Providers
{
public interface IItemIdentityProvider : IHasOrder { }
}

View File

@ -0,0 +1,10 @@
using System.Collections.Generic;
using MediaBrowser.Controller.Entities;
namespace MediaBrowser.Controller.Providers
{
public interface ILocalImageFileProvider : ILocalImageProvider
{
List<LocalImageInfo> GetImages(IHasImages item, IDirectoryService directoryService);
}
}

View File

@ -1,13 +1,4 @@
using MediaBrowser.Controller.Entities; namespace MediaBrowser.Controller.Providers
using MediaBrowser.Model.Drawing;
using MediaBrowser.Model.Entities;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace MediaBrowser.Controller.Providers
{ {
/// <summary> /// <summary>
/// This is just a marker interface /// This is just a marker interface
@ -15,68 +6,4 @@ namespace MediaBrowser.Controller.Providers
public interface ILocalImageProvider : IImageProvider public interface ILocalImageProvider : IImageProvider
{ {
} }
public interface ILocalImageFileProvider : ILocalImageProvider
{
List<LocalImageInfo> GetImages(IHasImages item, IDirectoryService directoryService);
}
public class LocalImageInfo
{
public FileSystemInfo FileInfo { get; set; }
public ImageType Type { get; set; }
}
public interface IDynamicImageProvider : IImageProvider
{
/// <summary>
/// Gets the supported images.
/// </summary>
/// <param name="item">The item.</param>
/// <returns>IEnumerable{ImageType}.</returns>
IEnumerable<ImageType> GetSupportedImages(IHasImages item);
/// <summary>
/// Gets the image.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="type">The type.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{DynamicImageResponse}.</returns>
Task<DynamicImageResponse> GetImage(IHasImages item, ImageType type, CancellationToken cancellationToken);
}
public class DynamicImageInfo
{
public string ImageId { get; set; }
public ImageType Type { get; set; }
}
public class DynamicImageResponse
{
public string Path { get; set; }
public Stream Stream { get; set; }
public ImageFormat Format { get; set; }
public bool HasImage { get; set; }
public void SetFormatFromMimeType(string mimeType)
{
if (mimeType.EndsWith("gif", StringComparison.OrdinalIgnoreCase))
{
Format = ImageFormat.Gif;
}
else if (mimeType.EndsWith("bmp", StringComparison.OrdinalIgnoreCase))
{
Format = ImageFormat.Bmp;
}
else if (mimeType.EndsWith("png", StringComparison.OrdinalIgnoreCase))
{
Format = ImageFormat.Png;
}
else
{
Format = ImageFormat.Jpg;
}
}
}
} }

View File

@ -1,6 +1,4 @@
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities;
using MediaBrowser.Model.Entities;
using System.Collections.Generic;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -24,29 +22,4 @@ namespace MediaBrowser.Controller.Providers
IDirectoryService directoryService, IDirectoryService directoryService,
CancellationToken cancellationToken); CancellationToken cancellationToken);
} }
public class ItemInfo
{
public string Path { get; set; }
public bool IsInMixedFolder { get; set; }
}
public class LocalMetadataResult<T>
where T : IHasMetadata
{
public bool HasMetadata { get; set; }
public T Item { get; set; }
public List<LocalImageInfo> Images { get; set; }
public List<ChapterInfo> Chapters { get; set; }
public List<UserItemData> UserDataLIst { get; set; }
public LocalMetadataResult()
{
Images = new List<LocalImageInfo>();
Chapters = new List<ChapterInfo>();
UserDataLIst = new List<UserItemData>();
}
}
} }

View File

@ -19,15 +19,4 @@ namespace MediaBrowser.Controller.Providers
where TItemType : IHasMetadata where TItemType : IHasMetadata
{ {
} }
public interface IHasOrder
{
int Order { get; }
}
public class MetadataResult<T>
{
public bool HasMetadata { get; set; }
public T Item { get; set; }
}
} }

View File

@ -0,0 +1,7 @@
namespace MediaBrowser.Controller.Providers
{
public interface IPreRefreshProvider : ICustomMetadataProvider
{
}
}

View File

@ -4,6 +4,7 @@ using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities; using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Providers; using MediaBrowser.Model.Providers;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Threading; using System.Threading;
@ -16,6 +17,13 @@ namespace MediaBrowser.Controller.Providers
/// </summary> /// </summary>
public interface IProviderManager public interface IProviderManager
{ {
/// <summary>
/// Queues the refresh.
/// </summary>
/// <param name="itemId">The item identifier.</param>
/// <param name="options">The options.</param>
void QueueRefresh(Guid itemId, MetadataRefreshOptions options);
/// <summary> /// <summary>
/// Refreshes the metadata. /// Refreshes the metadata.
/// </summary> /// </summary>

View File

@ -1,5 +1,4 @@
using MediaBrowser.Common.Net; using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Model.Providers; using MediaBrowser.Model.Providers;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading; using System.Threading;
@ -18,37 +17,9 @@ namespace MediaBrowser.Controller.Providers
Task<MetadataResult<TItemType>> GetMetadata(TLookupInfoType info, CancellationToken cancellationToken); Task<MetadataResult<TItemType>> GetMetadata(TLookupInfoType info, CancellationToken cancellationToken);
} }
public interface IRemoteSearchProvider : IMetadataProvider
{
/// <summary>
/// Gets the image response.
/// </summary>
/// <param name="url">The URL.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{HttpResponseInfo}.</returns>
Task<HttpResponseInfo> GetImageResponse(string url, CancellationToken cancellationToken);
}
public interface IRemoteSearchProvider<in TLookupInfoType> : IRemoteSearchProvider public interface IRemoteSearchProvider<in TLookupInfoType> : IRemoteSearchProvider
where TLookupInfoType : ItemLookupInfo where TLookupInfoType : ItemLookupInfo
{ {
Task<IEnumerable<RemoteSearchResult>> GetSearchResults(TLookupInfoType searchInfo, CancellationToken cancellationToken); Task<IEnumerable<RemoteSearchResult>> GetSearchResults(TLookupInfoType searchInfo, CancellationToken cancellationToken);
} }
public class RemoteSearchQuery<T>
where T : ItemLookupInfo
{
public T SearchInfo { get; set; }
/// <summary>
/// If set will only search within the given provider
/// </summary>
public string SearchProviderName { get; set; }
/// <summary>
/// Gets or sets a value indicating whether [include disabled providers].
/// </summary>
/// <value><c>true</c> if [include disabled providers]; otherwise, <c>false</c>.</value>
public bool IncludeDisabledProviders { get; set; }
}
} }

View File

@ -0,0 +1,17 @@
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common.Net;
namespace MediaBrowser.Controller.Providers
{
public interface IRemoteSearchProvider : IMetadataProvider
{
/// <summary>
/// Gets the image response.
/// </summary>
/// <param name="url">The URL.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{HttpResponseInfo}.</returns>
Task<HttpResponseInfo> GetImageResponse(string url, CancellationToken cancellationToken);
}
}

View File

@ -7,17 +7,6 @@ using MediaBrowser.Common;
namespace MediaBrowser.Controller.Providers namespace MediaBrowser.Controller.Providers
{ {
public interface ISeriesOrderProvider
{
string OrderType { get; }
Task<int?> FindSeriesIndex(string seriesName);
}
public static class SeriesOrderTypes
{
public const string Anime = "Anime";
}
public interface ISeriesOrderManager public interface ISeriesOrderManager
{ {
Task<int?> FindSeriesIndex(string orderType, string seriesName); Task<int?> FindSeriesIndex(string orderType, string seriesName);

View File

@ -0,0 +1,10 @@
using System.Threading.Tasks;
namespace MediaBrowser.Controller.Providers
{
public interface ISeriesOrderProvider
{
string OrderType { get; }
Task<int?> FindSeriesIndex(string seriesName);
}
}

View File

@ -0,0 +1,25 @@
namespace MediaBrowser.Controller.Providers
{
public enum ImageRefreshMode
{
/// <summary>
/// The none
/// </summary>
None = 0,
/// <summary>
/// The default
/// </summary>
Default = 1,
/// <summary>
/// Existing images will be validated
/// </summary>
ValidationOnly = 2,
/// <summary>
/// All providers will be executed to search for new metadata
/// </summary>
FullRefresh = 3
}
}

View File

@ -0,0 +1,29 @@
using System.Collections.Generic;
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Controller.Providers
{
public class ImageRefreshOptions
{
public ImageRefreshMode ImageRefreshMode { get; set; }
public IDirectoryService DirectoryService { get; private set; }
public bool ReplaceAllImages { get; set; }
public List<ImageType> ReplaceImages { get; set; }
public ImageRefreshOptions(IDirectoryService directoryService)
{
ImageRefreshMode = ImageRefreshMode.Default;
DirectoryService = directoryService;
ReplaceImages = new List<ImageType>();
}
public bool IsReplacingImage(ImageType type)
{
return ImageRefreshMode == ImageRefreshMode.FullRefresh &&
(ReplaceAllImages || ReplaceImages.Contains(type));
}
}
}

View File

@ -1,24 +1,7 @@
using System.Collections.Generic; using System.Threading.Tasks;
using System.Threading;
using System.Threading.Tasks;
namespace MediaBrowser.Controller.Providers namespace MediaBrowser.Controller.Providers
{ {
public interface IItemIdentity
{
string Type { get; }
}
public interface IHasIdentities<out TIdentity>
where TIdentity : IItemIdentity
{
IEnumerable<TIdentity> Identities { get; }
Task FindIdentities(IProviderManager providerManager, CancellationToken cancellationToken);
}
public interface IItemIdentityProvider : IHasOrder { }
public interface IItemIdentityProvider<in TLookupInfo, TIdentity> : IItemIdentityProvider public interface IItemIdentityProvider<in TLookupInfo, TIdentity> : IItemIdentityProvider
where TLookupInfo : ItemLookupInfo where TLookupInfo : ItemLookupInfo
where TIdentity : IItemIdentity where TIdentity : IItemIdentity
@ -26,8 +9,6 @@ namespace MediaBrowser.Controller.Providers
Task<TIdentity> FindIdentity(TLookupInfo info); Task<TIdentity> FindIdentity(TLookupInfo info);
} }
public interface IItemIdentityConverter : IHasOrder { }
public interface IItemIdentityConverter<TIdentity> : IItemIdentityConverter public interface IItemIdentityConverter<TIdentity> : IItemIdentityConverter
where TIdentity : IItemIdentity where TIdentity : IItemIdentity
{ {

View File

@ -0,0 +1,9 @@
namespace MediaBrowser.Controller.Providers
{
public class ItemInfo
{
public string Path { get; set; }
public bool IsInMixedFolder { get; set; }
}
}

View File

@ -1,8 +1,4 @@
using System.Linq; using MediaBrowser.Model.Entities;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Model.Channels;
using MediaBrowser.Model.Entities;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -43,204 +39,4 @@ namespace MediaBrowser.Controller.Providers
ProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); ProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
} }
} }
public interface IHasLookupInfo<out TLookupInfoType>
where TLookupInfoType : ItemLookupInfo, new()
{
TLookupInfoType GetLookupInfo();
}
public class ArtistInfo : ItemLookupInfo
{
public List<SongInfo> SongInfos { get; set; }
public ArtistInfo()
{
SongInfos = new List<SongInfo>();
}
}
public class AlbumInfo : ItemLookupInfo
{
/// <summary>
/// Gets or sets the album artist.
/// </summary>
/// <value>The album artist.</value>
public List<string> AlbumArtists { get; set; }
/// <summary>
/// Gets or sets the artist provider ids.
/// </summary>
/// <value>The artist provider ids.</value>
public Dictionary<string, string> ArtistProviderIds { get; set; }
public List<SongInfo> SongInfos { get; set; }
public AlbumInfo()
{
ArtistProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
SongInfos = new List<SongInfo>();
AlbumArtists = new List<string>();
}
}
public class GameInfo : ItemLookupInfo
{
/// <summary>
/// Gets or sets the game system.
/// </summary>
/// <value>The game system.</value>
public string GameSystem { get; set; }
}
public class GameSystemInfo : ItemLookupInfo
{
/// <summary>
/// Gets or sets the path.
/// </summary>
/// <value>The path.</value>
public string Path { get; set; }
}
public class EpisodeInfo : ItemLookupInfo, IHasIdentities<EpisodeIdentity>
{
private List<EpisodeIdentity> _identities = new List<EpisodeIdentity>();
public Dictionary<string, string> SeriesProviderIds { get; set; }
public int? IndexNumberEnd { get; set; }
public int? AnimeSeriesIndex { get; set; }
public EpisodeInfo()
{
SeriesProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
}
public IEnumerable<EpisodeIdentity> Identities
{
get { return _identities; }
}
public async Task FindIdentities(IProviderManager providerManager, CancellationToken cancellationToken)
{
var identifier = new ItemIdentifier<EpisodeInfo, EpisodeIdentity>();
_identities = (await identifier.FindIdentities(this, providerManager, cancellationToken)).ToList();
}
}
public class EpisodeIdentity : IItemIdentity
{
public string Type { get; set; }
public string SeriesId { get; set; }
public int? SeasonIndex { get; set; }
public int IndexNumber { get; set; }
public int? IndexNumberEnd { get; set; }
}
public class SongInfo : ItemLookupInfo
{
public List<string> AlbumArtists { get; set; }
public string Album { get; set; }
public List<string> Artists { get; set; }
public SongInfo()
{
Artists = new List<string>();
AlbumArtists = new List<string>();
}
}
public class SeriesInfo : ItemLookupInfo, IHasIdentities<SeriesIdentity>
{
private List<SeriesIdentity> _identities = new List<SeriesIdentity>();
public int? AnimeSeriesIndex { get; set; }
public IEnumerable<SeriesIdentity> Identities
{
get { return _identities; }
}
public async Task FindIdentities(IProviderManager providerManager, CancellationToken cancellationToken)
{
var identifier = new ItemIdentifier<SeriesInfo, SeriesIdentity>();
_identities = (await identifier.FindIdentities(this, providerManager, cancellationToken)).ToList();
}
}
public class SeriesIdentity : IItemIdentity
{
public string Type { get; set; }
public string Id { get; set; }
}
public class PersonLookupInfo : ItemLookupInfo
{
}
public class MovieInfo : ItemLookupInfo
{
}
public class BoxSetInfo : ItemLookupInfo
{
}
public class MusicVideoInfo : ItemLookupInfo
{
}
public class TrailerInfo : ItemLookupInfo
{
public bool IsLocalTrailer { get; set; }
}
public class BookInfo : ItemLookupInfo
{
public string SeriesName { get; set; }
}
public class SeasonInfo : ItemLookupInfo, IHasIdentities<SeasonIdentity>
{
private List<SeasonIdentity> _identities = new List<SeasonIdentity>();
public Dictionary<string, string> SeriesProviderIds { get; set; }
public int? AnimeSeriesIndex { get; set; }
public SeasonInfo()
{
SeriesProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
}
public IEnumerable<SeasonIdentity> Identities
{
get { return _identities; }
}
public async Task FindIdentities(IProviderManager providerManager, CancellationToken cancellationToken)
{
var identifier = new ItemIdentifier<SeasonInfo, SeasonIdentity>();
_identities = (await identifier.FindIdentities(this, providerManager, cancellationToken)).ToList();
}
}
public class SeasonIdentity : IItemIdentity
{
public string Type { get; set; }
public string SeriesId { get; set; }
public int SeasonIndex { get; set; }
}
public class ChannelItemLookupInfo : ItemLookupInfo
{
public ChannelMediaContentType ContentType { get; set; }
public ExtraType ExtraType { get; set; }
}
} }

View File

@ -0,0 +1,11 @@
using System.IO;
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Controller.Providers
{
public class LocalImageInfo
{
public FileSystemInfo FileInfo { get; set; }
public ImageType Type { get; set; }
}
}

View File

@ -0,0 +1,24 @@
using System.Collections.Generic;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Controller.Providers
{
public class LocalMetadataResult<T>
where T : IHasMetadata
{
public bool HasMetadata { get; set; }
public T Item { get; set; }
public List<LocalImageInfo> Images { get; set; }
public List<ChapterInfo> Chapters { get; set; }
public List<UserItemData> UserDataLIst { get; set; }
public LocalMetadataResult()
{
Images = new List<LocalImageInfo>();
Chapters = new List<ChapterInfo>();
UserDataLIst = new List<UserItemData>();
}
}
}

View File

@ -0,0 +1,25 @@
namespace MediaBrowser.Controller.Providers
{
public enum MetadataRefreshMode
{
/// <summary>
/// The none
/// </summary>
None = 0,
/// <summary>
/// The validation only
/// </summary>
ValidationOnly = 1,
/// <summary>
/// Providers will be executed based on default rules
/// </summary>
Default = 2,
/// <summary>
/// All providers will be executed to search for new metadata
/// </summary>
FullRefresh = 3
}
}

View File

@ -1,6 +1,4 @@
using MediaBrowser.Model.Entities; using System.Linq;
using System.Collections.Generic;
using System.Linq;
namespace MediaBrowser.Controller.Providers namespace MediaBrowser.Controller.Providers
{ {
@ -40,74 +38,4 @@ namespace MediaBrowser.Controller.Providers
ReplaceImages = copy.ReplaceImages.ToList(); ReplaceImages = copy.ReplaceImages.ToList();
} }
} }
public class ImageRefreshOptions
{
public ImageRefreshMode ImageRefreshMode { get; set; }
public IDirectoryService DirectoryService { get; private set; }
public bool ReplaceAllImages { get; set; }
public List<ImageType> ReplaceImages { get; set; }
public ImageRefreshOptions(IDirectoryService directoryService)
{
ImageRefreshMode = ImageRefreshMode.Default;
DirectoryService = directoryService;
ReplaceImages = new List<ImageType>();
}
public bool IsReplacingImage(ImageType type)
{
return ImageRefreshMode == ImageRefreshMode.FullRefresh &&
(ReplaceAllImages || ReplaceImages.Contains(type));
}
}
public enum MetadataRefreshMode
{
/// <summary>
/// The none
/// </summary>
None = 0,
/// <summary>
/// The validation only
/// </summary>
ValidationOnly = 1,
/// <summary>
/// Providers will be executed based on default rules
/// </summary>
Default = 2,
/// <summary>
/// All providers will be executed to search for new metadata
/// </summary>
FullRefresh = 3
}
public enum ImageRefreshMode
{
/// <summary>
/// The none
/// </summary>
None = 0,
/// <summary>
/// The default
/// </summary>
Default = 1,
/// <summary>
/// Existing images will be validated
/// </summary>
ValidationOnly = 2,
/// <summary>
/// All providers will be executed to search for new metadata
/// </summary>
FullRefresh = 3
}
} }

View File

@ -0,0 +1,8 @@
namespace MediaBrowser.Controller.Providers
{
public class MetadataResult<T>
{
public bool HasMetadata { get; set; }
public T Item { get; set; }
}
}

View File

@ -0,0 +1,7 @@
namespace MediaBrowser.Controller.Providers
{
public class MovieInfo : ItemLookupInfo
{
}
}

View File

@ -0,0 +1,7 @@
namespace MediaBrowser.Controller.Providers
{
public class MusicVideoInfo : ItemLookupInfo
{
}
}

View File

@ -0,0 +1,7 @@
namespace MediaBrowser.Controller.Providers
{
public class PersonLookupInfo : ItemLookupInfo
{
}
}

View File

@ -0,0 +1,19 @@
namespace MediaBrowser.Controller.Providers
{
public class RemoteSearchQuery<T>
where T : ItemLookupInfo
{
public T SearchInfo { get; set; }
/// <summary>
/// If set will only search within the given provider
/// </summary>
public string SearchProviderName { get; set; }
/// <summary>
/// Gets or sets a value indicating whether [include disabled providers].
/// </summary>
/// <value><c>true</c> if [include disabled providers]; otherwise, <c>false</c>.</value>
public bool IncludeDisabledProviders { get; set; }
}
}

View File

@ -0,0 +1,11 @@
namespace MediaBrowser.Controller.Providers
{
public class SeasonIdentity : IItemIdentity
{
public string Type { get; set; }
public string SeriesId { get; set; }
public int SeasonIndex { get; set; }
}
}

View File

@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace MediaBrowser.Controller.Providers
{
public class SeasonInfo : ItemLookupInfo, IHasIdentities<SeasonIdentity>
{
private List<SeasonIdentity> _identities = new List<SeasonIdentity>();
public Dictionary<string, string> SeriesProviderIds { get; set; }
public int? AnimeSeriesIndex { get; set; }
public SeasonInfo()
{
SeriesProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
}
public IEnumerable<SeasonIdentity> Identities
{
get { return _identities; }
}
public async Task FindIdentities(IProviderManager providerManager, CancellationToken cancellationToken)
{
var identifier = new ItemIdentifier<SeasonInfo, SeasonIdentity>();
_identities = (await identifier.FindIdentities(this, providerManager, cancellationToken)).ToList();
}
}
}

View File

@ -0,0 +1,9 @@
namespace MediaBrowser.Controller.Providers
{
public class SeriesIdentity : IItemIdentity
{
public string Type { get; set; }
public string Id { get; set; }
}
}

View File

@ -0,0 +1,25 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace MediaBrowser.Controller.Providers
{
public class SeriesInfo : ItemLookupInfo, IHasIdentities<SeriesIdentity>
{
private List<SeriesIdentity> _identities = new List<SeriesIdentity>();
public int? AnimeSeriesIndex { get; set; }
public IEnumerable<SeriesIdentity> Identities
{
get { return _identities; }
}
public async Task FindIdentities(IProviderManager providerManager, CancellationToken cancellationToken)
{
var identifier = new ItemIdentifier<SeriesInfo, SeriesIdentity>();
_identities = (await identifier.FindIdentities(this, providerManager, cancellationToken)).ToList();
}
}
}

View File

@ -0,0 +1,7 @@
namespace MediaBrowser.Controller.Providers
{
public static class SeriesOrderTypes
{
public const string Anime = "Anime";
}
}

View File

@ -0,0 +1,17 @@
using System.Collections.Generic;
namespace MediaBrowser.Controller.Providers
{
public class SongInfo : ItemLookupInfo
{
public List<string> AlbumArtists { get; set; }
public string Album { get; set; }
public List<string> Artists { get; set; }
public SongInfo()
{
Artists = new List<string>();
AlbumArtists = new List<string>();
}
}
}

View File

@ -0,0 +1,7 @@
namespace MediaBrowser.Controller.Providers
{
public class TrailerInfo : ItemLookupInfo
{
public bool IsLocalTrailer { get; set; }
}
}

View File

@ -18,7 +18,7 @@ namespace MediaBrowser.Controller.Sync
/// <param name="progress">The progress.</param> /// <param name="progress">The progress.</param>
/// <param name="cancellationToken">The cancellation token.</param> /// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns> /// <returns>Task.</returns>
Task SendFile(Stream stream, string remotePath, SyncTarget target, IProgress<double> progress, CancellationToken cancellationToken); Task<SendFileResult> SendFile(Stream stream, string remotePath, SyncTarget target, IProgress<double> progress, CancellationToken cancellationToken);
/// <summary> /// <summary>
/// Deletes the file. /// Deletes the file.

View File

@ -0,0 +1,18 @@
using MediaBrowser.Model.MediaInfo;
namespace MediaBrowser.Controller.Sync
{
public class SendFileResult
{
/// <summary>
/// Gets or sets the path.
/// </summary>
/// <value>The path.</value>
public string Path { get; set; }
/// <summary>
/// Gets or sets the protocol.
/// </summary>
/// <value>The protocol.</value>
public MediaProtocol Protocol { get; set; }
}
}

View File

@ -491,6 +491,9 @@
<Compile Include="..\MediaBrowser.Model\Dto\MetadataEditorInfo.cs"> <Compile Include="..\MediaBrowser.Model\Dto\MetadataEditorInfo.cs">
<Link>Dto\MetadataEditorInfo.cs</Link> <Link>Dto\MetadataEditorInfo.cs</Link>
</Compile> </Compile>
<Compile Include="..\MediaBrowser.Model\Dto\NameIdPair.cs">
<Link>Dto\NameIdPair.cs</Link>
</Compile>
<Compile Include="..\MediaBrowser.Model\Dto\NameValuePair.cs"> <Compile Include="..\MediaBrowser.Model\Dto\NameValuePair.cs">
<Link>Dto\NameValuePair.cs</Link> <Link>Dto\NameValuePair.cs</Link>
</Compile> </Compile>
@ -977,9 +980,6 @@
<Compile Include="..\MediaBrowser.Model\Querying\SessionQuery.cs"> <Compile Include="..\MediaBrowser.Model\Querying\SessionQuery.cs">
<Link>Querying\SessionQuery.cs</Link> <Link>Querying\SessionQuery.cs</Link>
</Compile> </Compile>
<Compile Include="..\MediaBrowser.Model\Querying\SimilarItemsByNameQuery.cs">
<Link>Querying\SimilarItemsByNameQuery.cs</Link>
</Compile>
<Compile Include="..\MediaBrowser.Model\Querying\SimilarItemsQuery.cs"> <Compile Include="..\MediaBrowser.Model\Querying\SimilarItemsQuery.cs">
<Link>Querying\SimilarItemsQuery.cs</Link> <Link>Querying\SimilarItemsQuery.cs</Link>
</Compile> </Compile>

View File

@ -459,6 +459,9 @@
<Compile Include="..\MediaBrowser.Model\Dto\MetadataEditorInfo.cs"> <Compile Include="..\MediaBrowser.Model\Dto\MetadataEditorInfo.cs">
<Link>Dto\MetadataEditorInfo.cs</Link> <Link>Dto\MetadataEditorInfo.cs</Link>
</Compile> </Compile>
<Compile Include="..\MediaBrowser.Model\Dto\NameIdPair.cs">
<Link>Dto\NameIdPair.cs</Link>
</Compile>
<Compile Include="..\MediaBrowser.Model\Dto\NameValuePair.cs"> <Compile Include="..\MediaBrowser.Model\Dto\NameValuePair.cs">
<Link>Dto\NameValuePair.cs</Link> <Link>Dto\NameValuePair.cs</Link>
</Compile> </Compile>
@ -939,9 +942,6 @@
<Compile Include="..\MediaBrowser.Model\Querying\SessionQuery.cs"> <Compile Include="..\MediaBrowser.Model\Querying\SessionQuery.cs">
<Link>Querying\SessionQuery.cs</Link> <Link>Querying\SessionQuery.cs</Link>
</Compile> </Compile>
<Compile Include="..\MediaBrowser.Model\Querying\SimilarItemsByNameQuery.cs">
<Link>Querying\SimilarItemsByNameQuery.cs</Link>
</Compile>
<Compile Include="..\MediaBrowser.Model\Querying\SimilarItemsQuery.cs"> <Compile Include="..\MediaBrowser.Model\Querying\SimilarItemsQuery.cs">
<Link>Querying\SimilarItemsQuery.cs</Link> <Link>Querying\SimilarItemsQuery.cs</Link>
</Compile> </Compile>

View File

@ -251,12 +251,12 @@ namespace MediaBrowser.Model.ApiClient
Task<ItemsResult> GetAdditionalParts(string itemId, string userId); Task<ItemsResult> GetAdditionalParts(string itemId, string userId);
/// <summary> /// <summary>
/// Gets the live media information. /// Gets the playback information.
/// </summary> /// </summary>
/// <param name="itemId">The item identifier.</param> /// <param name="itemId">The item identifier.</param>
/// <param name="userId">The user identifier.</param> /// <param name="userId">The user identifier.</param>
/// <returns>Task&lt;LiveMediaInfoResult&gt;.</returns> /// <returns>Task&lt;LiveMediaInfoResult&gt;.</returns>
Task<LiveMediaInfoResult> GetLiveMediaInfo(string itemId, string userId); Task<LiveMediaInfoResult> GetPlaybackInfo(string itemId, string userId);
/// <summary> /// <summary>
/// Gets the users async. /// Gets the users async.
@ -344,14 +344,14 @@ namespace MediaBrowser.Model.ApiClient
/// </summary> /// </summary>
/// <param name="query">The query.</param> /// <param name="query">The query.</param>
/// <returns>Task{ItemsResult}.</returns> /// <returns>Task{ItemsResult}.</returns>
Task<ItemsResult> GetInstantMixFromArtistAsync(SimilarItemsByNameQuery query); Task<ItemsResult> GetInstantMixFromArtistAsync(SimilarItemsQuery query);
/// <summary> /// <summary>
/// Gets the instant mix from music genre async. /// Gets the instant mix from music genre async.
/// </summary> /// </summary>
/// <param name="query">The query.</param> /// <param name="query">The query.</param>
/// <returns>Task{ItemsResult}.</returns> /// <returns>Task{ItemsResult}.</returns>
Task<ItemsResult> GetInstantMixFromMusicGenreAsync(SimilarItemsByNameQuery query); Task<ItemsResult> GetInstantMixFromMusicGenreAsync(SimilarItemsQuery query);
/// <summary> /// <summary>
/// Gets the similar movies async. /// Gets the similar movies async.
@ -417,15 +417,6 @@ namespace MediaBrowser.Model.ApiClient
/// <returns>Task{ItemsResult}.</returns> /// <returns>Task{ItemsResult}.</returns>
Task<ItemsResult> GetAlbumArtistsAsync(ArtistsQuery query); Task<ItemsResult> GetAlbumArtistsAsync(ArtistsQuery query);
/// <summary>
/// Gets a studio
/// </summary>
/// <param name="name">The name.</param>
/// <param name="userId">The user id.</param>
/// <returns>Task{BaseItemDto}.</returns>
/// <exception cref="ArgumentNullException">userId</exception>
Task<BaseItemDto> GetStudioAsync(string name, string userId);
/// <summary> /// <summary>
/// Gets the next up async. /// Gets the next up async.
/// </summary> /// </summary>
@ -494,15 +485,6 @@ namespace MediaBrowser.Model.ApiClient
/// <returns>Task{BaseItemDto}.</returns> /// <returns>Task{BaseItemDto}.</returns>
Task<BaseItemDto> GetGameGenreAsync(string name, string userId); Task<BaseItemDto> GetGameGenreAsync(string name, string userId);
/// <summary>
/// Gets the artist async.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="userId">The user id.</param>
/// <returns>Task{BaseItemDto}.</returns>
/// <exception cref="ArgumentNullException">name</exception>
Task<BaseItemDto> GetArtistAsync(string name, string userId);
/// <summary> /// <summary>
/// Restarts the server. /// Restarts the server.
/// </summary> /// </summary>
@ -1011,14 +993,6 @@ namespace MediaBrowser.Model.ApiClient
/// <exception cref="ArgumentNullException">item</exception> /// <exception cref="ArgumentNullException">item</exception>
string GetPersonImageUrl(BaseItemPerson item, ImageOptions options); string GetPersonImageUrl(BaseItemPerson item, ImageOptions options);
/// <summary>
/// Gets an image url that can be used to download an image from the api
/// </summary>
/// <param name="year">The year.</param>
/// <param name="options">The options.</param>
/// <returns>System.String.</returns>
string GetYearImageUrl(int year, ImageOptions options);
/// <summary> /// <summary>
/// Gets an image url that can be used to download an image from the api /// Gets an image url that can be used to download an image from the api
/// </summary> /// </summary>
@ -1044,24 +1018,6 @@ namespace MediaBrowser.Model.ApiClient
/// <returns>System.String.</returns> /// <returns>System.String.</returns>
string GetGameGenreImageUrl(string name, ImageOptions options); string GetGameGenreImageUrl(string name, ImageOptions options);
/// <summary>
/// Gets an image url that can be used to download an image from the api
/// </summary>
/// <param name="name">The name.</param>
/// <param name="options">The options.</param>
/// <returns>System.String.</returns>
/// <exception cref="ArgumentNullException">name</exception>
string GetStudioImageUrl(string name, ImageOptions options);
/// <summary>
/// Gets the artist image URL.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="options">The options.</param>
/// <returns>System.String.</returns>
/// <exception cref="ArgumentNullException">name</exception>
string GetArtistImageUrl(string name, ImageOptions options);
/// <summary> /// <summary>
/// This is a helper to get a list of backdrop url's from a given ApiBaseItemWrapper. If the actual item does not have any backdrops it will return backdrops from the first parent that does. /// This is a helper to get a list of backdrop url's from a given ApiBaseItemWrapper. If the actual item does not have any backdrops it will return backdrops from the first parent that does.
/// </summary> /// </summary>

View File

@ -44,6 +44,12 @@ namespace MediaBrowser.Model.Configuration
/// <value><c>true</c> if [use HTTPS]; otherwise, <c>false</c>.</value> /// <value><c>true</c> if [use HTTPS]; otherwise, <c>false</c>.</value>
public bool EnableHttps { get; set; } public bool EnableHttps { get; set; }
/// <summary>
/// Gets or sets a value indicating whether [enable user specific user views].
/// </summary>
/// <value><c>true</c> if [enable user specific user views]; otherwise, <c>false</c>.</value>
public bool EnableUserSpecificUserViews { get; set; }
/// <summary> /// <summary>
/// Gets or sets the value pointing to the file system where the ssl certiifcate is located.. /// Gets or sets the value pointing to the file system where the ssl certiifcate is located..
/// </summary> /// </summary>

View File

@ -466,6 +466,12 @@ namespace MediaBrowser.Model.Dto
/// <value>The artists.</value> /// <value>The artists.</value>
public List<string> Artists { get; set; } public List<string> Artists { get; set; }
/// <summary>
/// Gets or sets the artist items.
/// </summary>
/// <value>The artist items.</value>
public List<NameIdPair> ArtistItems { get; set; }
/// <summary> /// <summary>
/// Gets or sets the album. /// Gets or sets the album.
/// </summary> /// </summary>
@ -507,6 +513,12 @@ namespace MediaBrowser.Model.Dto
/// <value>The album artist.</value> /// <value>The album artist.</value>
public string AlbumArtist { get; set; } public string AlbumArtist { get; set; }
/// <summary>
/// Gets or sets the album artists.
/// </summary>
/// <value>The album artists.</value>
public List<NameIdPair> AlbumArtists { get; set; }
/// <summary> /// <summary>
/// Gets or sets the name of the season. /// Gets or sets the name of the season.
/// </summary> /// </summary>

View File

@ -0,0 +1,17 @@

namespace MediaBrowser.Model.Dto
{
public class NameIdPair
{
/// <summary>
/// Gets or sets the name.
/// </summary>
/// <value>The name.</value>
public string Name { get; set; }
/// <summary>
/// Gets or sets the identifier.
/// </summary>
/// <value>The identifier.</value>
public string Id { get; set; }
}
}

View File

@ -273,6 +273,10 @@ namespace MediaBrowser.Model.LiveTv
/// <value>The type.</value> /// <value>The type.</value>
public string Type { get; set; } public string Type { get; set; }
/// <summary>
/// Gets or sets the media sources.
/// </summary>
/// <value>The media sources.</value>
public List<MediaSourceInfo> MediaSources { get; set; } public List<MediaSourceInfo> MediaSources { get; set; }
public RecordingInfoDto() public RecordingInfoDto()

View File

@ -139,6 +139,7 @@
<Compile Include="Drawing\ImageOrientation.cs" /> <Compile Include="Drawing\ImageOrientation.cs" />
<Compile Include="Dto\IHasServerId.cs" /> <Compile Include="Dto\IHasServerId.cs" />
<Compile Include="Dto\MetadataEditorInfo.cs" /> <Compile Include="Dto\MetadataEditorInfo.cs" />
<Compile Include="Dto\NameIdPair.cs" />
<Compile Include="Dto\NameValuePair.cs" /> <Compile Include="Dto\NameValuePair.cs" />
<Compile Include="MediaInfo\LiveMediaInfoResult.cs" /> <Compile Include="MediaInfo\LiveMediaInfoResult.cs" />
<Compile Include="Dto\MediaSourceType.cs" /> <Compile Include="Dto\MediaSourceType.cs" />
@ -321,7 +322,6 @@
<Compile Include="Querying\QueryResult.cs" /> <Compile Include="Querying\QueryResult.cs" />
<Compile Include="Querying\SeasonQuery.cs" /> <Compile Include="Querying\SeasonQuery.cs" />
<Compile Include="Querying\SessionQuery.cs" /> <Compile Include="Querying\SessionQuery.cs" />
<Compile Include="Querying\SimilarItemsByNameQuery.cs" />
<Compile Include="Querying\SimilarItemsQuery.cs" /> <Compile Include="Querying\SimilarItemsQuery.cs" />
<Compile Include="Querying\UpcomingEpisodesQuery.cs" /> <Compile Include="Querying\UpcomingEpisodesQuery.cs" />
<Compile Include="Querying\UserQuery.cs" /> <Compile Include="Querying\UserQuery.cs" />

View File

@ -39,11 +39,11 @@ namespace MediaBrowser.Model.Querying
public string[] SortBy { get; set; } public string[] SortBy { get; set; }
/// <summary> /// <summary>
/// Filter by artists /// Gets or sets the artist ids.
/// </summary> /// </summary>
/// <value>The artists.</value> /// <value>The artist ids.</value>
public string[] Artists { get; set; } public string[] ArtistIds { get; set; }
/// <summary> /// <summary>
/// The sort order to return results with /// The sort order to return results with
/// </summary> /// </summary>
@ -93,16 +93,10 @@ namespace MediaBrowser.Model.Querying
public string[] Genres { get; set; } public string[] Genres { get; set; }
/// <summary> /// <summary>
/// Limit results to items containing specific genres /// Gets or sets the studio ids.
/// </summary> /// </summary>
/// <value>The genres.</value> /// <value>The studio ids.</value>
public string[] AllGenres { get; set; } public string[] StudioIds { get; set; }
/// <summary>
/// Limit results to items containing specific studios
/// </summary>
/// <value>The studios.</value>
public string[] Studios { get; set; }
/// <summary> /// <summary>
/// Gets or sets the exclude item types. /// Gets or sets the exclude item types.
@ -306,13 +300,13 @@ namespace MediaBrowser.Model.Querying
VideoTypes = new VideoType[] { }; VideoTypes = new VideoType[] { };
Genres = new string[] { }; Genres = new string[] { };
Studios = new string[] { }; StudioIds = new string[] { };
IncludeItemTypes = new string[] { }; IncludeItemTypes = new string[] { };
ExcludeItemTypes = new string[] { }; ExcludeItemTypes = new string[] { };
Years = new int[] { }; Years = new int[] { };
PersonTypes = new string[] { }; PersonTypes = new string[] { };
Ids = new string[] { }; Ids = new string[] { };
Artists = new string[] { }; ArtistIds = new string[] { };
ImageTypes = new ImageType[] { }; ImageTypes = new ImageType[] { };
AirDays = new DayOfWeek[] { }; AirDays = new DayOfWeek[] { };

View File

@ -1,29 +0,0 @@
namespace MediaBrowser.Model.Querying
{
public class SimilarItemsByNameQuery
{
/// <summary>
/// The user to localize search results for
/// </summary>
/// <value>The user id.</value>
public string UserId { get; set; }
/// <summary>
/// Gets or sets the name.
/// </summary>
/// <value>The name.</value>
public string Name { get; set; }
/// <summary>
/// The maximum number of items to return
/// </summary>
/// <value>The limit.</value>
public int? Limit { get; set; }
/// <summary>
/// Fields to return within the items, in addition to basic information
/// </summary>
/// <value>The fields.</value>
public ItemFields[] Fields { get; set; }
}
}

View File

@ -12,7 +12,7 @@ using System.Threading.Tasks;
namespace MediaBrowser.Providers.FolderImages namespace MediaBrowser.Providers.FolderImages
{ {
public class DefaultImageProvider : IRemoteImageProvider, IHasItemChangeMonitor public class DefaultImageProvider : IRemoteImageProvider, IHasItemChangeMonitor, IHasOrder
{ {
private readonly IHttpClient _httpClient; private readonly IHttpClient _httpClient;
@ -36,36 +36,42 @@ namespace MediaBrowser.Providers.FolderImages
if (view != null) if (view != null)
{ {
return GetImages(view.ViewType, cancellationToken); return GetImages(view.ViewType, view.ParentId != Guid.Empty, cancellationToken);
} }
var folder = (ICollectionFolder)item; var folder = (ICollectionFolder)item;
return GetImages(folder.CollectionType, cancellationToken); return GetImages(folder.CollectionType, false, cancellationToken);
} }
private Task<IEnumerable<RemoteImageInfo>> GetImages(string viewType, CancellationToken cancellationToken) private Task<IEnumerable<RemoteImageInfo>> GetImages(string viewType, bool isSubView, CancellationToken cancellationToken)
{ {
var url = GetImageUrl(viewType); var url = GetImageUrl(viewType, isSubView);
var list = new List<RemoteImageInfo>();
return Task.FromResult<IEnumerable<RemoteImageInfo>>(new List<RemoteImageInfo> if (!string.IsNullOrWhiteSpace(url))
{ {
new RemoteImageInfo list.AddRange(new List<RemoteImageInfo>
{ {
ProviderName = Name, new RemoteImageInfo
Url = url, {
Type = ImageType.Primary ProviderName = Name,
}, Url = url,
Type = ImageType.Primary
},
new RemoteImageInfo new RemoteImageInfo
{ {
ProviderName = Name, ProviderName = Name,
Url = url, Url = url,
Type = ImageType.Thumb Type = ImageType.Thumb
} }
}); });
}
return Task.FromResult<IEnumerable<RemoteImageInfo>>(list);
} }
private string GetImageUrl(string viewType) private string GetImageUrl(string viewType, bool isSubView)
{ {
const string urlPrefix = "https://raw.githubusercontent.com/MediaBrowser/MediaBrowser.Resources/master/images/folders/"; const string urlPrefix = "https://raw.githubusercontent.com/MediaBrowser/MediaBrowser.Resources/master/images/folders/";
@ -102,6 +108,11 @@ namespace MediaBrowser.Providers.FolderImages
return urlPrefix + "movies.png"; return urlPrefix + "movies.png";
} }
if (isSubView)
{
return null;
}
return urlPrefix + "generic.png"; return urlPrefix + "generic.png";
} }
@ -112,14 +123,7 @@ namespace MediaBrowser.Providers.FolderImages
public bool Supports(IHasImages item) public bool Supports(IHasImages item)
{ {
var view = item as UserView; return item is ICollectionFolder || item is UserView;
if (view != null)
{
return !view.UserId.HasValue;
}
return item is ICollectionFolder;
} }
public Task<HttpResponseInfo> GetImageResponse(string url, CancellationToken cancellationToken) public Task<HttpResponseInfo> GetImageResponse(string url, CancellationToken cancellationToken)
@ -136,5 +140,14 @@ namespace MediaBrowser.Providers.FolderImages
{ {
return GetSupportedImages(item).Any(i => !item.HasImage(i)); return GetSupportedImages(item).Any(i => !item.HasImage(i));
} }
public int Order
{
get
{
// Run after the dynamic image provider
return 1;
}
}
} }
} }

View File

@ -135,17 +135,17 @@ namespace MediaBrowser.Providers.Manager
{ {
if (!string.IsNullOrEmpty(response.Path)) if (!string.IsNullOrEmpty(response.Path))
{ {
var mimeType = "image/" + Path.GetExtension(response.Path).TrimStart('.').ToLower(); var mimeType = MimeTypes.GetMimeType(response.Path);
var stream = _fileSystem.GetFileStream(response.Path, FileMode.Open, FileAccess.Read, FileShare.Read, true); var stream = _fileSystem.GetFileStream(response.Path, FileMode.Open, FileAccess.Read, FileShare.Read, true);
await _providerManager.SaveImage(item, stream, mimeType, imageType, null, cancellationToken).ConfigureAwait(false); await _providerManager.SaveImage(item, stream, mimeType, imageType, null, response.InternalCacheKey, cancellationToken).ConfigureAwait(false);
} }
else else
{ {
var mimeType = "image/" + response.Format.ToString().ToLower(); var mimeType = "image/" + response.Format.ToString().ToLower();
await _providerManager.SaveImage(item, response.Stream, mimeType, imageType, null, cancellationToken).ConfigureAwait(false); await _providerManager.SaveImage(item, response.Stream, mimeType, imageType, null, response.InternalCacheKey, cancellationToken).ConfigureAwait(false);
} }
downloadedImages.Add(imageType); downloadedImages.Add(imageType);

View File

@ -26,7 +26,7 @@ namespace MediaBrowser.Providers.Manager
/// <summary> /// <summary>
/// Class ProviderManager /// Class ProviderManager
/// </summary> /// </summary>
public class ProviderManager : IProviderManager public class ProviderManager : IProviderManager, IDisposable
{ {
/// <summary> /// <summary>
/// The _logger /// The _logger
@ -63,6 +63,8 @@ namespace MediaBrowser.Providers.Manager
private IExternalId[] _externalIds; private IExternalId[] _externalIds;
private readonly Func<ILibraryManager> _libraryManagerFactory;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="ProviderManager" /> class. /// Initializes a new instance of the <see cref="ProviderManager" /> class.
/// </summary> /// </summary>
@ -71,7 +73,7 @@ namespace MediaBrowser.Providers.Manager
/// <param name="libraryMonitor">The directory watchers.</param> /// <param name="libraryMonitor">The directory watchers.</param>
/// <param name="logManager">The log manager.</param> /// <param name="logManager">The log manager.</param>
/// <param name="fileSystem">The file system.</param> /// <param name="fileSystem">The file system.</param>
public ProviderManager(IHttpClient httpClient, IServerConfigurationManager configurationManager, ILibraryMonitor libraryMonitor, ILogManager logManager, IFileSystem fileSystem, IServerApplicationPaths appPaths) public ProviderManager(IHttpClient httpClient, IServerConfigurationManager configurationManager, ILibraryMonitor libraryMonitor, ILogManager logManager, IFileSystem fileSystem, IServerApplicationPaths appPaths, Func<ILibraryManager> libraryManagerFactory)
{ {
_logger = logManager.GetLogger("ProviderManager"); _logger = logManager.GetLogger("ProviderManager");
_httpClient = httpClient; _httpClient = httpClient;
@ -79,6 +81,7 @@ namespace MediaBrowser.Providers.Manager
_libraryMonitor = libraryMonitor; _libraryMonitor = libraryMonitor;
_fileSystem = fileSystem; _fileSystem = fileSystem;
_appPaths = appPaths; _appPaths = appPaths;
_libraryManagerFactory = libraryManagerFactory;
} }
/// <summary> /// <summary>
@ -841,5 +844,80 @@ namespace MediaBrowser.Providers.Manager
}); });
} }
private readonly ConcurrentQueue<Tuple<Guid, MetadataRefreshOptions>> _refreshQueue =
new ConcurrentQueue<Tuple<Guid, MetadataRefreshOptions>>();
private readonly object _refreshTimerLock = new object();
private Timer _refreshTimer;
public void QueueRefresh(Guid id, MetadataRefreshOptions options)
{
if (_disposed)
{
return;
}
_refreshQueue.Enqueue(new Tuple<Guid, MetadataRefreshOptions>(id, options));
StartRefreshTimer();
}
private void StartRefreshTimer()
{
lock (_refreshTimerLock)
{
if (_refreshTimer == null)
{
_refreshTimer = new Timer(RefreshTimerCallback, null, 100, Timeout.Infinite);
}
}
}
private void StopRefreshTimer()
{
lock (_refreshTimerLock)
{
if (_refreshTimer != null)
{
_refreshTimer.Dispose();
_refreshTimer = null;
}
}
}
private async void RefreshTimerCallback(object state)
{
Tuple<Guid, MetadataRefreshOptions> refreshItem;
var libraryManager = _libraryManagerFactory();
while (_refreshQueue.TryDequeue(out refreshItem))
{
if (_disposed)
{
return;
}
try
{
var item = libraryManager.GetItemById(refreshItem.Item1);
if (item != null)
{
await item.RefreshMetadata(refreshItem.Item2, CancellationToken.None).ConfigureAwait(false);
}
}
catch (Exception ex)
{
_logger.ErrorException("Error refreshing item", ex);
}
}
StopRefreshTimer();
}
private bool _disposed;
public void Dispose()
{
_disposed = true;
}
} }
} }

View File

@ -387,7 +387,7 @@ namespace MediaBrowser.Providers.MediaInfo
if (!string.IsNullOrEmpty(val)) if (!string.IsNullOrEmpty(val))
{ {
// Sometimes the artist name is listed here, account for that // Sometimes the artist name is listed here, account for that
var studios = Split(val, true).Where(i => !audio.HasArtist(i)); var studios = Split(val, true).Where(i => !audio.HasAnyArtist(i));
foreach (var studio in studios) foreach (var studio in studios)
{ {

View File

@ -1400,7 +1400,9 @@ namespace MediaBrowser.Server.Implementations.Channels
public async Task<Folder> GetInternalChannelFolder(string userId, CancellationToken cancellationToken) public async Task<Folder> GetInternalChannelFolder(string userId, CancellationToken cancellationToken)
{ {
var name = _localization.GetLocalizedString("ViewTypeChannels"); var name = _localization.GetLocalizedString("ViewTypeChannels");
return await _libraryManager.GetNamedView(name, "channels", "zz_" + name, cancellationToken).ConfigureAwait(false); var user = _userManager.GetUserById(userId);
return await _libraryManager.GetNamedView(user, name, "channels", "zz_" + name, cancellationToken).ConfigureAwait(false);
} }
public async Task DownloadChannelItem(IChannelMediaItem item, string destination, public async Task DownloadChannelItem(IChannelMediaItem item, string destination,

View File

@ -14,7 +14,7 @@ using System.Threading.Tasks;
namespace MediaBrowser.Server.Implementations.Collections namespace MediaBrowser.Server.Implementations.Collections
{ {
public class CollectionImageProvider : BaseDynamicImageProvider<BoxSet>, ICustomMetadataProvider<BoxSet> public class CollectionImageProvider : BaseDynamicImageProvider<BoxSet>
{ {
public CollectionImageProvider(IFileSystem fileSystem, IProviderManager providerManager, IApplicationPaths applicationPaths) : base(fileSystem, providerManager, applicationPaths) public CollectionImageProvider(IFileSystem fileSystem, IProviderManager providerManager, IApplicationPaths applicationPaths) : base(fileSystem, providerManager, applicationPaths)
{ {

View File

@ -504,7 +504,6 @@ namespace MediaBrowser.Server.Implementations.Dto
} }
dto.Album = item.Album; dto.Album = item.Album;
dto.Artists = item.Artists;
} }
private void SetGameProperties(BaseItemDto dto, Game item) private void SetGameProperties(BaseItemDto dto, Game item)
@ -1142,7 +1141,6 @@ namespace MediaBrowser.Server.Implementations.Dto
if (audio != null) if (audio != null)
{ {
dto.Album = audio.Album; dto.Album = audio.Album;
dto.Artists = audio.Artists;
var albumParent = audio.FindParent<MusicAlbum>(); var albumParent = audio.FindParent<MusicAlbum>();
@ -1163,18 +1161,65 @@ namespace MediaBrowser.Server.Implementations.Dto
if (album != null) if (album != null)
{ {
dto.Artists = album.Artists;
dto.SoundtrackIds = album.SoundtrackIds dto.SoundtrackIds = album.SoundtrackIds
.Select(i => i.ToString("N")) .Select(i => i.ToString("N"))
.ToArray(); .ToArray();
} }
var hasAlbumArtist = item as IHasAlbumArtist; var hasArtist = item as IHasArtist;
if (hasArtist != null)
{
dto.Artists = hasArtist.Artists;
dto.ArtistItems = hasArtist
.Artists
.Select(i =>
{
try
{
var artist = _libraryManager.GetArtist(i);
return new NameIdPair
{
Name = artist.Name,
Id = artist.Id.ToString("N")
};
}
catch (Exception ex)
{
_logger.ErrorException("Error getting artist", ex);
return null;
}
})
.Where(i => i != null)
.ToList();
}
var hasAlbumArtist = item as IHasAlbumArtist;
if (hasAlbumArtist != null) if (hasAlbumArtist != null)
{ {
dto.AlbumArtist = hasAlbumArtist.AlbumArtists.FirstOrDefault(); dto.AlbumArtist = hasAlbumArtist.AlbumArtists.FirstOrDefault();
dto.AlbumArtists = hasAlbumArtist
.AlbumArtists
.Select(i =>
{
try
{
var artist = _libraryManager.GetArtist(i);
return new NameIdPair
{
Name = artist.Name,
Id = artist.Id.ToString("N")
};
}
catch (Exception ex)
{
_logger.ErrorException("Error getting album artist", ex);
return null;
}
})
.Where(i => i != null)
.ToList();
} }
// Add video info // Add video info
@ -1231,7 +1276,6 @@ namespace MediaBrowser.Server.Implementations.Dto
// Add MovieInfo // Add MovieInfo
var movie = item as Movie; var movie = item as Movie;
if (movie != null) if (movie != null)
{ {
if (fields.Contains(ItemFields.TmdbCollectionName)) if (fields.Contains(ItemFields.TmdbCollectionName))
@ -1241,7 +1285,6 @@ namespace MediaBrowser.Server.Implementations.Dto
} }
var hasSpecialFeatures = item as IHasSpecialFeatures; var hasSpecialFeatures = item as IHasSpecialFeatures;
if (hasSpecialFeatures != null) if (hasSpecialFeatures != null)
{ {
var specialFeatureCount = hasSpecialFeatures.SpecialFeatureIds.Count; var specialFeatureCount = hasSpecialFeatures.SpecialFeatureIds.Count;
@ -1254,7 +1297,6 @@ namespace MediaBrowser.Server.Implementations.Dto
// Add EpisodeInfo // Add EpisodeInfo
var episode = item as Episode; var episode = item as Episode;
if (episode != null) if (episode != null)
{ {
dto.IndexNumberEnd = episode.IndexNumberEnd; dto.IndexNumberEnd = episode.IndexNumberEnd;
@ -1296,7 +1338,6 @@ namespace MediaBrowser.Server.Implementations.Dto
// Add SeriesInfo // Add SeriesInfo
var series = item as Series; var series = item as Series;
if (series != null) if (series != null)
{ {
dto.AirDays = series.AirDays; dto.AirDays = series.AirDays;
@ -1346,7 +1387,6 @@ namespace MediaBrowser.Server.Implementations.Dto
// Add SeasonInfo // Add SeasonInfo
var season = item as Season; var season = item as Season;
if (season != null) if (season != null)
{ {
series = season.Series; series = season.Series;
@ -1380,7 +1420,6 @@ namespace MediaBrowser.Server.Implementations.Dto
} }
var musicVideo = item as MusicVideo; var musicVideo = item as MusicVideo;
if (musicVideo != null) if (musicVideo != null)
{ {
SetMusicVideoProperties(dto, musicVideo); SetMusicVideoProperties(dto, musicVideo);

View File

@ -1584,15 +1584,22 @@ namespace MediaBrowser.Server.Implementations.Library
.FirstOrDefault(i => !string.IsNullOrWhiteSpace(i)); .FirstOrDefault(i => !string.IsNullOrWhiteSpace(i));
} }
public async Task<UserView> GetNamedView(string name, public async Task<UserView> GetNamedView(User user,
string type, string name,
string viewType,
string sortName, string sortName,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
if (ConfigurationManager.Configuration.EnableUserSpecificUserViews)
{
return await GetNamedViewInternal(user, name, null, viewType, sortName, cancellationToken)
.ConfigureAwait(false);
}
var path = Path.Combine(ConfigurationManager.ApplicationPaths.ItemsByNamePath, var path = Path.Combine(ConfigurationManager.ApplicationPaths.ItemsByNamePath,
"views"); "views");
path = Path.Combine(path, _fileSystem.GetValidFilename(type)); path = Path.Combine(path, _fileSystem.GetValidFilename(viewType));
var id = GetNewItemId(path + "_namedview_" + name, typeof(UserView)); var id = GetNewItemId(path + "_namedview_" + name, typeof(UserView));
@ -1611,7 +1618,7 @@ namespace MediaBrowser.Server.Implementations.Library
Id = id, Id = id,
DateCreated = DateTime.UtcNow, DateCreated = DateTime.UtcNow,
Name = name, Name = name,
ViewType = type, ViewType = viewType,
ForcedSortName = sortName ForcedSortName = sortName
}; };
@ -1627,17 +1634,29 @@ namespace MediaBrowser.Server.Implementations.Library
if (refresh) if (refresh)
{ {
await item.RefreshMetadata(new MetadataRefreshOptions await item.UpdateToRepository(ItemUpdateType.MetadataImport, CancellationToken.None).ConfigureAwait(false);
{ _providerManagerFactory().QueueRefresh(item.Id, new MetadataRefreshOptions());
ForceSave = true
}, cancellationToken).ConfigureAwait(false);
} }
return item; return item;
} }
public async Task<UserView> GetSpecialFolder(User user, public Task<UserView> GetNamedView(User user,
string name,
string parentId,
string viewType,
string sortName,
CancellationToken cancellationToken)
{
if (string.IsNullOrWhiteSpace(parentId))
{
throw new ArgumentNullException("parentId");
}
return GetNamedViewInternal(user, name, parentId, viewType, sortName, cancellationToken);
}
private async Task<UserView> GetNamedViewInternal(User user,
string name, string name,
string parentId, string parentId,
string viewType, string viewType,
@ -1649,19 +1668,14 @@ namespace MediaBrowser.Server.Implementations.Library
throw new ArgumentNullException("name"); throw new ArgumentNullException("name");
} }
if (string.IsNullOrWhiteSpace(parentId))
{
throw new ArgumentNullException("parentId");
}
if (string.IsNullOrWhiteSpace(viewType)) if (string.IsNullOrWhiteSpace(viewType))
{ {
throw new ArgumentNullException("viewType"); throw new ArgumentNullException("viewType");
} }
var id = GetNewItemId("7_namedview_" + name + user.Id.ToString("N") + parentId, typeof(UserView)); var id = GetNewItemId("23_namedview_" + name + user.Id.ToString("N") + (parentId ?? string.Empty), typeof(UserView));
var path = Path.Combine(ConfigurationManager.ApplicationPaths.InternalMetadataPath, "views", "specialviews", id.ToString("N")); var path = Path.Combine(ConfigurationManager.ApplicationPaths.InternalMetadataPath, "views", id.ToString("N"));
var item = GetItemById(id) as UserView; var item = GetItemById(id) as UserView;
@ -1679,27 +1693,28 @@ namespace MediaBrowser.Server.Implementations.Library
Name = name, Name = name,
ViewType = viewType, ViewType = viewType,
ForcedSortName = sortName, ForcedSortName = sortName,
UserId = user.Id, UserId = user.Id
ParentId = new Guid(parentId)
}; };
if (!string.IsNullOrWhiteSpace(parentId))
{
item.ParentId = new Guid(parentId);
}
await CreateItem(item, cancellationToken).ConfigureAwait(false); await CreateItem(item, cancellationToken).ConfigureAwait(false);
refresh = true; refresh = true;
} }
if (!refresh && item != null) if (!refresh)
{ {
refresh = (DateTime.UtcNow - item.DateLastSaved).TotalHours >= 24; refresh = (DateTime.UtcNow - item.DateLastSaved).TotalHours >= 24;
} }
if (refresh) if (refresh)
{ {
await item.RefreshMetadata(new MetadataRefreshOptions await item.UpdateToRepository(ItemUpdateType.MetadataImport, CancellationToken.None).ConfigureAwait(false);
{ _providerManagerFactory().QueueRefresh(item.Id, new MetadataRefreshOptions());
ForceSave = true
}, cancellationToken).ConfigureAwait(false);
} }
return item; return item;
@ -1849,7 +1864,7 @@ namespace MediaBrowser.Server.Implementations.Library
// These cause apps to have problems // These cause apps to have problems
options.AudioFileExtensions.Remove(".m3u"); options.AudioFileExtensions.Remove(".m3u");
options.AudioFileExtensions.Remove(".wpl"); options.AudioFileExtensions.Remove(".wpl");
if (!ConfigurationManager.Configuration.EnableAudioArchiveFiles) if (!ConfigurationManager.Configuration.EnableAudioArchiveFiles)
{ {
options.AudioFileExtensions.Remove(".rar"); options.AudioFileExtensions.Remove(".rar");

Some files were not shown because too many files have changed in this diff Show More