aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2014-01-02 18:07:37 -0500
committerLuke Pulverenti <luke.pulverenti@gmail.com>2014-01-02 18:07:37 -0500
commita5be2523c5d86c077175b2de347b8beb791616c1 (patch)
tree5fbf58f4db3b51328fb55c86b330d01789418366
parentb50fc351a12fa890b2d4ab6e71b7a4b609dd583c (diff)
added music and game genre image downloading
-rw-r--r--MediaBrowser.Api/LiveTv/LiveTvService.cs28
-rw-r--r--MediaBrowser.Api/Playback/BaseStreamingService.cs30
-rw-r--r--MediaBrowser.Controller/LiveTv/ILiveTvManager.cs4
-rw-r--r--MediaBrowser.Controller/LiveTv/ILiveTvService.cs4
-rw-r--r--MediaBrowser.Controller/LiveTv/LiveStreamInfo.cs18
-rw-r--r--MediaBrowser.Controller/MediaBrowser.Controller.csproj1
-rw-r--r--MediaBrowser.Mono.userprefs2
-rw-r--r--MediaBrowser.Providers/ImagesByName/GameGenreImageProvider.cs160
-rw-r--r--MediaBrowser.Providers/ImagesByName/GameGenresManualImageProvider.cs128
-rw-r--r--MediaBrowser.Providers/ImagesByName/MusicGenreImageProvider.cs161
-rw-r--r--MediaBrowser.Providers/ImagesByName/MusicGenresManualImageProvider.cs129
-rw-r--r--MediaBrowser.Providers/MediaBrowser.Providers.csproj4
-rw-r--r--MediaBrowser.Server.Implementations/Library/LuceneSearchEngine.cs3
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs6
-rw-r--r--Nuget/MediaBrowser.Common.Internal.nuspec4
-rw-r--r--Nuget/MediaBrowser.Common.nuspec2
-rw-r--r--Nuget/MediaBrowser.Server.Core.nuspec4
17 files changed, 636 insertions, 52 deletions
diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs
index 84bd291a4..6cec2118b 100644
--- a/MediaBrowser.Api/LiveTv/LiveTvService.cs
+++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs
@@ -194,20 +194,6 @@ namespace MediaBrowser.Api.LiveTv
{
}
- [Route("/LiveTv/Recordings/{Id}/Stream", "GET")]
- public class GetInternalRecordingStream
- {
- [ApiMember(Name = "Id", Description = "Recording Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string Id { get; set; }
- }
-
- [Route("/LiveTv/Channels/{Id}/Stream", "GET")]
- public class GetInternalChannelStream
- {
- [ApiMember(Name = "Id", Description = "Channel Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string Id { get; set; }
- }
-
[Route("/LiveTv/Recordings/Groups/{Id}", "GET")]
[Api(Description = "Gets a recording group")]
public class GetRecordingGroup : IReturn<RecordingGroupDto>
@@ -411,20 +397,6 @@ namespace MediaBrowser.Api.LiveTv
Task.WaitAll(task);
}
- public object Get(GetInternalRecordingStream request)
- {
- var stream = _liveTvManager.GetRecordingStream(request.Id, CancellationToken.None).Result;
-
- return ToStreamResult(stream.Stream, stream.MimeType);
- }
-
- public object Get(GetInternalChannelStream request)
- {
- var stream = _liveTvManager.GetChannelStream(request.Id, CancellationToken.None).Result;
-
- return ToStreamResult(stream.Stream, stream.MimeType);
- }
-
public object Get(GetRecordingGroups request)
{
var result = _liveTvManager.GetRecordingGroups(new RecordingGroupQuery
diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs
index 718c142a4..450c0c681 100644
--- a/MediaBrowser.Api/Playback/BaseStreamingService.cs
+++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs
@@ -888,11 +888,18 @@ namespace MediaBrowser.Api.Playback
}
else
{
- state.MediaPath = string.Format("http://localhost:{0}/mediabrowser/LiveTv/Recordings/{1}/Stream",
- ServerConfigurationManager.Configuration.HttpServerPortNumber,
- request.Id);
+ var streamInfo = await LiveTvManager.GetRecordingStream(request.Id, cancellationToken).ConfigureAwait(false);
- state.IsRemote = true;
+ if (!string.IsNullOrEmpty(streamInfo.Path) && File.Exists(streamInfo.Path))
+ {
+ state.MediaPath = streamInfo.Path;
+ state.IsRemote = false;
+ }
+ else if (!string.IsNullOrEmpty(streamInfo.Url))
+ {
+ state.MediaPath = streamInfo.Url;
+ state.IsRemote = true;
+ }
}
itemId = recording.Id;
@@ -905,11 +912,18 @@ namespace MediaBrowser.Api.Playback
state.IsInputVideo = string.Equals(channel.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase);
state.PlayableStreamFileNames = new List<string>();
- state.MediaPath = string.Format("http://localhost:{0}/mediabrowser/LiveTv/Channels/{1}/Stream",
- ServerConfigurationManager.Configuration.HttpServerPortNumber,
- request.Id);
+ var streamInfo = await LiveTvManager.GetChannelStream(request.Id, cancellationToken).ConfigureAwait(false);
- state.IsRemote = true;
+ if (!string.IsNullOrEmpty(streamInfo.Path) && File.Exists(streamInfo.Path))
+ {
+ state.MediaPath = streamInfo.Path;
+ state.IsRemote = false;
+ }
+ else if (!string.IsNullOrEmpty(streamInfo.Url))
+ {
+ state.MediaPath = streamInfo.Url;
+ state.IsRemote = true;
+ }
itemId = channel.Id;
}
diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs
index 87ac0d4dc..b7acb0735 100644
--- a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs
+++ b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs
@@ -161,7 +161,7 @@ namespace MediaBrowser.Controller.LiveTv
/// <param name="id">The identifier.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{Stream}.</returns>
- Task<StreamResponseInfo> GetRecordingStream(string id, CancellationToken cancellationToken);
+ Task<LiveStreamInfo> GetRecordingStream(string id, CancellationToken cancellationToken);
/// <summary>
/// Gets the channel stream.
@@ -169,7 +169,7 @@ namespace MediaBrowser.Controller.LiveTv
/// <param name="id">The identifier.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{StreamResponseInfo}.</returns>
- Task<StreamResponseInfo> GetChannelStream(string id, CancellationToken cancellationToken);
+ Task<LiveStreamInfo> GetChannelStream(string id, CancellationToken cancellationToken);
/// <summary>
/// Gets the program.
diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvService.cs b/MediaBrowser.Controller/LiveTv/ILiveTvService.cs
index f8efbce63..491e8cbf8 100644
--- a/MediaBrowser.Controller/LiveTv/ILiveTvService.cs
+++ b/MediaBrowser.Controller/LiveTv/ILiveTvService.cs
@@ -145,7 +145,7 @@ namespace MediaBrowser.Controller.LiveTv
/// <param name="recordingId">The recording identifier.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{Stream}.</returns>
- Task<StreamResponseInfo> GetRecordingStream(string recordingId, CancellationToken cancellationToken);
+ Task<LiveStreamInfo> GetRecordingStream(string recordingId, CancellationToken cancellationToken);
/// <summary>
/// Gets the channel stream.
@@ -153,6 +153,6 @@ namespace MediaBrowser.Controller.LiveTv
/// <param name="channelId">The channel identifier.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{Stream}.</returns>
- Task<StreamResponseInfo> GetChannelStream(string channelId, CancellationToken cancellationToken);
+ Task<LiveStreamInfo> GetChannelStream(string channelId, CancellationToken cancellationToken);
}
}
diff --git a/MediaBrowser.Controller/LiveTv/LiveStreamInfo.cs b/MediaBrowser.Controller/LiveTv/LiveStreamInfo.cs
new file mode 100644
index 000000000..ba480f685
--- /dev/null
+++ b/MediaBrowser.Controller/LiveTv/LiveStreamInfo.cs
@@ -0,0 +1,18 @@
+
+namespace MediaBrowser.Controller.LiveTv
+{
+ public class LiveStreamInfo
+ {
+ /// <summary>
+ /// Gets or sets the path.
+ /// </summary>
+ /// <value>The path.</value>
+ public string Path { get; set; }
+
+ /// <summary>
+ /// Gets or sets the URL.
+ /// </summary>
+ /// <value>The URL.</value>
+ public string Url { get; set; }
+ }
+}
diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
index 25ea9979c..e08361812 100644
--- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj
+++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
@@ -109,6 +109,7 @@
<Compile Include="Library\IUserDataManager.cs" />
<Compile Include="Library\UserDataSaveEventArgs.cs" />
<Compile Include="LiveTv\ILiveTvRecording.cs" />
+ <Compile Include="LiveTv\LiveStreamInfo.cs" />
<Compile Include="LiveTv\LiveTvAudioRecording.cs" />
<Compile Include="LiveTv\LiveTvChannel.cs" />
<Compile Include="LiveTv\ChannelInfo.cs" />
diff --git a/MediaBrowser.Mono.userprefs b/MediaBrowser.Mono.userprefs
index 51af96f9f..e5d5fa75e 100644
--- a/MediaBrowser.Mono.userprefs
+++ b/MediaBrowser.Mono.userprefs
@@ -3,7 +3,7 @@
<MonoDevelop.Ide.Workbench ActiveDocument="MediaBrowser.Server.Mono\Networking\NetworkManager.cs">
<Files>
<File FileName="MediaBrowser.Server.Mono\app.config" Line="1" Column="1" />
- <File FileName="MediaBrowser.Server.Mono\Networking\NetworkManager.cs" Line="6" Column="34" />
+ <File FileName="MediaBrowser.Server.Mono\Networking\NetworkManager.cs" Line="7" Column="26" />
</Files>
</MonoDevelop.Ide.Workbench>
<MonoDevelop.Ide.DebuggingService.Breakpoints>
diff --git a/MediaBrowser.Providers/ImagesByName/GameGenreImageProvider.cs b/MediaBrowser.Providers/ImagesByName/GameGenreImageProvider.cs
new file mode 100644
index 000000000..a0dbb83dc
--- /dev/null
+++ b/MediaBrowser.Providers/ImagesByName/GameGenreImageProvider.cs
@@ -0,0 +1,160 @@
+using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Providers;
+using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Net;
+using MediaBrowser.Model.Providers;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Providers.ImagesByName
+{
+ public class GameGenreImageProvider : BaseMetadataProvider
+ {
+ private readonly IProviderManager _providerManager;
+ private readonly SemaphoreSlim _resourcePool = new SemaphoreSlim(5, 5);
+
+ public GameGenreImageProvider(ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager)
+ : base(logManager, configurationManager)
+ {
+ _providerManager = providerManager;
+ }
+
+ public override bool Supports(BaseItem item)
+ {
+ return item is GameGenre;
+ }
+
+ public override bool RequiresInternet
+ {
+ get
+ {
+ return true;
+ }
+ }
+
+ public override ItemUpdateType ItemUpdateType
+ {
+ get
+ {
+ return ItemUpdateType.ImageUpdate;
+ }
+ }
+
+ protected override bool NeedsRefreshInternal(BaseItem item, BaseProviderInfo providerInfo)
+ {
+ if (item.HasImage(ImageType.Primary) && item.HasImage(ImageType.Thumb))
+ {
+ return false;
+ }
+
+ // Try again periodically in case new images were added
+ if ((DateTime.UtcNow - providerInfo.LastRefreshed).TotalDays > 7)
+ {
+ return true;
+ }
+
+ return base.NeedsRefreshInternal(item, providerInfo);
+ }
+
+ protected override bool RefreshOnVersionChange
+ {
+ get
+ {
+ return true;
+ }
+ }
+
+ protected override string ProviderVersion
+ {
+ get
+ {
+ return "8";
+ }
+ }
+
+ public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken)
+ {
+ if (item.HasImage(ImageType.Primary) && item.HasImage(ImageType.Thumb))
+ {
+ SetLastRefreshed(item, DateTime.UtcNow, providerInfo);
+ return true;
+ }
+
+ var images = await _providerManager.GetAvailableRemoteImages(item, cancellationToken, GameGenresManualImageProvider.ProviderName).ConfigureAwait(false);
+
+ await DownloadImages(item, images.ToList(), cancellationToken).ConfigureAwait(false);
+
+ SetLastRefreshed(item, DateTime.UtcNow, providerInfo);
+ return true;
+ }
+
+ private async Task DownloadImages(BaseItem item, List<RemoteImageInfo> images, CancellationToken cancellationToken)
+ {
+ if (!item.LockedFields.Contains(MetadataFields.Images))
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+
+ if (!item.HasImage(ImageType.Primary))
+ {
+ await SaveImage(item, images, ImageType.Primary, cancellationToken).ConfigureAwait(false);
+ }
+ cancellationToken.ThrowIfCancellationRequested();
+
+ if (!item.HasImage(ImageType.Thumb))
+ {
+ await SaveImage(item, images, ImageType.Thumb, cancellationToken).ConfigureAwait(false);
+ }
+ }
+
+ if (!item.LockedFields.Contains(MetadataFields.Backdrops))
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+
+ if (item.BackdropImagePaths.Count == 0)
+ {
+ foreach (var image in images.Where(i => i.Type == ImageType.Backdrop))
+ {
+ await _providerManager.SaveImage(item, image.Url, _resourcePool, ImageType.Backdrop, null, cancellationToken)
+ .ConfigureAwait(false);
+
+ break;
+ }
+ }
+ }
+ }
+
+
+ private async Task SaveImage(BaseItem item, IEnumerable<RemoteImageInfo> images, ImageType type, CancellationToken cancellationToken)
+ {
+ foreach (var image in images.Where(i => i.Type == type))
+ {
+ try
+ {
+ await _providerManager.SaveImage(item, image.Url, _resourcePool, type, null, cancellationToken).ConfigureAwait(false);
+ break;
+ }
+ catch (HttpException ex)
+ {
+ // Sometimes fanart has bad url's in their xml
+ if (ex.StatusCode.HasValue && ex.StatusCode.Value == HttpStatusCode.NotFound)
+ {
+ continue;
+ }
+ break;
+ }
+ }
+ }
+
+ public override MetadataProviderPriority Priority
+ {
+ get { return MetadataProviderPriority.Third; }
+ }
+ }
+}
diff --git a/MediaBrowser.Providers/ImagesByName/GameGenresManualImageProvider.cs b/MediaBrowser.Providers/ImagesByName/GameGenresManualImageProvider.cs
new file mode 100644
index 000000000..8207bb042
--- /dev/null
+++ b/MediaBrowser.Providers/ImagesByName/GameGenresManualImageProvider.cs
@@ -0,0 +1,128 @@
+using MediaBrowser.Common.IO;
+using MediaBrowser.Common.Net;
+using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Providers;
+using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Providers;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Providers.ImagesByName
+{
+ public class GameGenresManualImageProvider : IImageProvider
+ {
+ private readonly IServerConfigurationManager _config;
+ private readonly IHttpClient _httpClient;
+ private readonly IFileSystem _fileSystem;
+
+ private readonly SemaphoreSlim _listResourcePool = new SemaphoreSlim(1, 1);
+
+ public GameGenresManualImageProvider(IServerConfigurationManager config, IHttpClient httpClient, IFileSystem fileSystem)
+ {
+ _config = config;
+ _httpClient = httpClient;
+ _fileSystem = fileSystem;
+ }
+
+ public string Name
+ {
+ get { return ProviderName; }
+ }
+
+ public static string ProviderName
+ {
+ get { return "Media Browser"; }
+ }
+
+ public bool Supports(IHasImages item)
+ {
+ return item is GameGenre;
+ }
+
+ public Task<IEnumerable<RemoteImageInfo>> GetImages(IHasImages item, ImageType imageType, CancellationToken cancellationToken)
+ {
+ return GetImages(item, imageType == ImageType.Primary, imageType == ImageType.Thumb, cancellationToken);
+ }
+
+ public Task<IEnumerable<RemoteImageInfo>> GetAllImages(IHasImages item, CancellationToken cancellationToken)
+ {
+ return GetImages(item, true, true, cancellationToken);
+ }
+
+ private async Task<IEnumerable<RemoteImageInfo>> GetImages(IHasImages item, bool posters, bool thumbs, CancellationToken cancellationToken)
+ {
+ var list = new List<RemoteImageInfo>();
+
+ if (posters)
+ {
+ var posterPath = Path.Combine(_config.ApplicationPaths.CachePath, "imagesbyname", "remotegamegenreposters.txt");
+
+ await EnsurePosterList(posterPath, cancellationToken).ConfigureAwait(false);
+
+ list.Add(GetImage(item, posterPath, ImageType.Primary, "folder"));
+ }
+
+ cancellationToken.ThrowIfCancellationRequested();
+
+ if (thumbs)
+ {
+ var thumbsPath = Path.Combine(_config.ApplicationPaths.CachePath, "imagesbyname", "remotegamegenrethumbs.txt");
+
+ await EnsureThumbsList(thumbsPath, cancellationToken).ConfigureAwait(false);
+
+ list.Add(GetImage(item, thumbsPath, ImageType.Thumb, "thumb"));
+ }
+
+ return list.Where(i => i != null);
+ }
+
+ private RemoteImageInfo GetImage(IHasImages item, string filename, ImageType type, string remoteFilename)
+ {
+ var list = ImageUtils.GetAvailableImages(filename);
+
+ var match = ImageUtils.FindMatch(item, list);
+
+ if (!string.IsNullOrEmpty(match))
+ {
+ var url = GetUrl(match, remoteFilename);
+
+ return new RemoteImageInfo
+ {
+ ProviderName = Name,
+ Type = type,
+ Url = url
+ };
+ }
+
+ return null;
+ }
+
+ private string GetUrl(string image, string filename)
+ {
+ return string.Format("https://raw.github.com/MediaBrowser/MediaBrowser.Resources/master/images/imagesbyname/gamegenres/{0}/{1}.jpg", image, filename);
+ }
+
+ private Task EnsureThumbsList(string file, CancellationToken cancellationToken)
+ {
+ const string url = "https://raw.github.com/MediaBrowser/MediaBrowser.Resources/master/images/imagesbyname/gamegenrethumbs.txt";
+
+ return ImageUtils.EnsureList(url, file, _httpClient, _fileSystem, _listResourcePool, cancellationToken);
+ }
+
+ private Task EnsurePosterList(string file, CancellationToken cancellationToken)
+ {
+ const string url = "https://raw.github.com/MediaBrowser/MediaBrowser.Resources/master/images/imagesbyname/gamegenreposters.txt";
+
+ return ImageUtils.EnsureList(url, file, _httpClient, _fileSystem, _listResourcePool, cancellationToken);
+ }
+
+ public int Priority
+ {
+ get { return 0; }
+ }
+ }
+}
diff --git a/MediaBrowser.Providers/ImagesByName/MusicGenreImageProvider.cs b/MediaBrowser.Providers/ImagesByName/MusicGenreImageProvider.cs
new file mode 100644
index 000000000..5b05a7b63
--- /dev/null
+++ b/MediaBrowser.Providers/ImagesByName/MusicGenreImageProvider.cs
@@ -0,0 +1,161 @@
+using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities.Audio;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Providers;
+using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Net;
+using MediaBrowser.Model.Providers;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Providers.ImagesByName
+{
+ public class MusicGenreImageProvider : BaseMetadataProvider
+ {
+ private readonly IProviderManager _providerManager;
+ private readonly SemaphoreSlim _resourcePool = new SemaphoreSlim(5, 5);
+
+ public MusicGenreImageProvider(ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager)
+ : base(logManager, configurationManager)
+ {
+ _providerManager = providerManager;
+ }
+
+ public override bool Supports(BaseItem item)
+ {
+ return item is MusicGenre;
+ }
+
+ public override bool RequiresInternet
+ {
+ get
+ {
+ return true;
+ }
+ }
+
+ public override ItemUpdateType ItemUpdateType
+ {
+ get
+ {
+ return ItemUpdateType.ImageUpdate;
+ }
+ }
+
+ protected override bool NeedsRefreshInternal(BaseItem item, BaseProviderInfo providerInfo)
+ {
+ if (item.HasImage(ImageType.Primary) && item.HasImage(ImageType.Thumb))
+ {
+ return false;
+ }
+
+ // Try again periodically in case new images were added
+ if ((DateTime.UtcNow - providerInfo.LastRefreshed).TotalDays > 7)
+ {
+ return true;
+ }
+
+ return base.NeedsRefreshInternal(item, providerInfo);
+ }
+
+ protected override bool RefreshOnVersionChange
+ {
+ get
+ {
+ return true;
+ }
+ }
+
+ protected override string ProviderVersion
+ {
+ get
+ {
+ return "8";
+ }
+ }
+
+ public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken)
+ {
+ if (item.HasImage(ImageType.Primary) && item.HasImage(ImageType.Thumb))
+ {
+ SetLastRefreshed(item, DateTime.UtcNow, providerInfo);
+ return true;
+ }
+
+ var images = await _providerManager.GetAvailableRemoteImages(item, cancellationToken, MusicGenresManualImageProvider.ProviderName).ConfigureAwait(false);
+
+ await DownloadImages(item, images.ToList(), cancellationToken).ConfigureAwait(false);
+
+ SetLastRefreshed(item, DateTime.UtcNow, providerInfo);
+ return true;
+ }
+
+ private async Task DownloadImages(BaseItem item, List<RemoteImageInfo> images, CancellationToken cancellationToken)
+ {
+ if (!item.LockedFields.Contains(MetadataFields.Images))
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+
+ if (!item.HasImage(ImageType.Primary))
+ {
+ await SaveImage(item, images, ImageType.Primary, cancellationToken).ConfigureAwait(false);
+ }
+ cancellationToken.ThrowIfCancellationRequested();
+
+ if (!item.HasImage(ImageType.Thumb))
+ {
+ await SaveImage(item, images, ImageType.Thumb, cancellationToken).ConfigureAwait(false);
+ }
+ }
+
+ if (!item.LockedFields.Contains(MetadataFields.Backdrops))
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+
+ if (item.BackdropImagePaths.Count == 0)
+ {
+ foreach (var image in images.Where(i => i.Type == ImageType.Backdrop))
+ {
+ await _providerManager.SaveImage(item, image.Url, _resourcePool, ImageType.Backdrop, null, cancellationToken)
+ .ConfigureAwait(false);
+
+ break;
+ }
+ }
+ }
+ }
+
+
+ private async Task SaveImage(BaseItem item, IEnumerable<RemoteImageInfo> images, ImageType type, CancellationToken cancellationToken)
+ {
+ foreach (var image in images.Where(i => i.Type == type))
+ {
+ try
+ {
+ await _providerManager.SaveImage(item, image.Url, _resourcePool, type, null, cancellationToken).ConfigureAwait(false);
+ break;
+ }
+ catch (HttpException ex)
+ {
+ // Sometimes fanart has bad url's in their xml
+ if (ex.StatusCode.HasValue && ex.StatusCode.Value == HttpStatusCode.NotFound)
+ {
+ continue;
+ }
+ break;
+ }
+ }
+ }
+
+ public override MetadataProviderPriority Priority
+ {
+ get { return MetadataProviderPriority.Third; }
+ }
+ }
+}
diff --git a/MediaBrowser.Providers/ImagesByName/MusicGenresManualImageProvider.cs b/MediaBrowser.Providers/ImagesByName/MusicGenresManualImageProvider.cs
new file mode 100644
index 000000000..f21e867d1
--- /dev/null
+++ b/MediaBrowser.Providers/ImagesByName/MusicGenresManualImageProvider.cs
@@ -0,0 +1,129 @@
+using MediaBrowser.Common.IO;
+using MediaBrowser.Common.Net;
+using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities.Audio;
+using MediaBrowser.Controller.Providers;
+using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Providers;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Providers.ImagesByName
+{
+ public class MusicGenresManualImageProvider : IImageProvider
+ {
+ private readonly IServerConfigurationManager _config;
+ private readonly IHttpClient _httpClient;
+ private readonly IFileSystem _fileSystem;
+
+ private readonly SemaphoreSlim _listResourcePool = new SemaphoreSlim(1, 1);
+
+ public MusicGenresManualImageProvider(IServerConfigurationManager config, IHttpClient httpClient, IFileSystem fileSystem)
+ {
+ _config = config;
+ _httpClient = httpClient;
+ _fileSystem = fileSystem;
+ }
+
+ public string Name
+ {
+ get { return ProviderName; }
+ }
+
+ public static string ProviderName
+ {
+ get { return "Media Browser"; }
+ }
+
+ public bool Supports(IHasImages item)
+ {
+ return item is MusicGenre;
+ }
+
+ public Task<IEnumerable<RemoteImageInfo>> GetImages(IHasImages item, ImageType imageType, CancellationToken cancellationToken)
+ {
+ return GetImages(item, imageType == ImageType.Primary, imageType == ImageType.Thumb, cancellationToken);
+ }
+
+ public Task<IEnumerable<RemoteImageInfo>> GetAllImages(IHasImages item, CancellationToken cancellationToken)
+ {
+ return GetImages(item, true, true, cancellationToken);
+ }
+
+ private async Task<IEnumerable<RemoteImageInfo>> GetImages(IHasImages item, bool posters, bool thumbs, CancellationToken cancellationToken)
+ {
+ var list = new List<RemoteImageInfo>();
+
+ if (posters)
+ {
+ var posterPath = Path.Combine(_config.ApplicationPaths.CachePath, "imagesbyname", "remotemusicgenreposters.txt");
+
+ await EnsurePosterList(posterPath, cancellationToken).ConfigureAwait(false);
+
+ list.Add(GetImage(item, posterPath, ImageType.Primary, "folder"));
+ }
+
+ cancellationToken.ThrowIfCancellationRequested();
+
+ if (thumbs)
+ {
+ var thumbsPath = Path.Combine(_config.ApplicationPaths.CachePath, "imagesbyname", "remotemusicgenrethumbs.txt");
+
+ await EnsureThumbsList(thumbsPath, cancellationToken).ConfigureAwait(false);
+
+ list.Add(GetImage(item, thumbsPath, ImageType.Thumb, "thumb"));
+ }
+
+ return list.Where(i => i != null);
+ }
+
+ private RemoteImageInfo GetImage(IHasImages item, string filename, ImageType type, string remoteFilename)
+ {
+ var list = ImageUtils.GetAvailableImages(filename);
+
+ var match = ImageUtils.FindMatch(item, list);
+
+ if (!string.IsNullOrEmpty(match))
+ {
+ var url = GetUrl(match, remoteFilename);
+
+ return new RemoteImageInfo
+ {
+ ProviderName = Name,
+ Type = type,
+ Url = url
+ };
+ }
+
+ return null;
+ }
+
+ private string GetUrl(string image, string filename)
+ {
+ return string.Format("https://raw.github.com/MediaBrowser/MediaBrowser.Resources/master/images/imagesbyname/musicgenres/{0}/{1}.jpg", image, filename);
+ }
+
+ private Task EnsureThumbsList(string file, CancellationToken cancellationToken)
+ {
+ const string url = "https://raw.github.com/MediaBrowser/MediaBrowser.Resources/master/images/imagesbyname/musicgenrethumbs.txt";
+
+ return ImageUtils.EnsureList(url, file, _httpClient, _fileSystem, _listResourcePool, cancellationToken);
+ }
+
+ private Task EnsurePosterList(string file, CancellationToken cancellationToken)
+ {
+ const string url = "https://raw.github.com/MediaBrowser/MediaBrowser.Resources/master/images/imagesbyname/musicgenreposters.txt";
+
+ return ImageUtils.EnsureList(url, file, _httpClient, _fileSystem, _listResourcePool, cancellationToken);
+ }
+
+ public int Priority
+ {
+ get { return 0; }
+ }
+ }
+}
diff --git a/MediaBrowser.Providers/MediaBrowser.Providers.csproj b/MediaBrowser.Providers/MediaBrowser.Providers.csproj
index b32670a91..6b87f1dfe 100644
--- a/MediaBrowser.Providers/MediaBrowser.Providers.csproj
+++ b/MediaBrowser.Providers/MediaBrowser.Providers.csproj
@@ -66,6 +66,10 @@
<Compile Include="Games\GameSystemProviderFromXml.cs" />
<Compile Include="ImageFromMediaLocationProvider.cs" />
<Compile Include="ImagesByNameProvider.cs" />
+ <Compile Include="ImagesByName\MusicGenreImageProvider.cs" />
+ <Compile Include="ImagesByName\MusicGenresManualImageProvider.cs" />
+ <Compile Include="ImagesByName\GameGenreImageProvider.cs" />
+ <Compile Include="ImagesByName\GameGenresManualImageProvider.cs" />
<Compile Include="ImagesByName\GenreImageProvider.cs" />
<Compile Include="ImagesByName\GenresManualImageProvider.cs" />
<Compile Include="ImagesByName\ImageUtils.cs" />
diff --git a/MediaBrowser.Server.Implementations/Library/LuceneSearchEngine.cs b/MediaBrowser.Server.Implementations/Library/LuceneSearchEngine.cs
index b194b2e94..34156b509 100644
--- a/MediaBrowser.Server.Implementations/Library/LuceneSearchEngine.cs
+++ b/MediaBrowser.Server.Implementations/Library/LuceneSearchEngine.cs
@@ -40,9 +40,6 @@ namespace MediaBrowser.Server.Implementations.Library
public void Dispose()
{
- //BaseItem.LibraryManager.LibraryChanged -= LibraryChanged;
-
- //LuceneSearch.CloseAll();
}
/// <summary>
diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
index b38ef5d55..4b3f33297 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
@@ -153,18 +153,18 @@ namespace MediaBrowser.Server.Implementations.LiveTv
return await GetRecording(recording, service.Name, cancellationToken).ConfigureAwait(false);
}
- public async Task<StreamResponseInfo> GetRecordingStream(string id, CancellationToken cancellationToken)
+ public async Task<LiveStreamInfo> GetRecordingStream(string id, CancellationToken cancellationToken)
{
var service = ActiveService;
var recordings = await service.GetRecordingsAsync(cancellationToken).ConfigureAwait(false);
- var recording = recordings.FirstOrDefault(i => _tvDtoService.GetInternalRecordingId(service.Name, i.Id) == new Guid(id));
+ var recording = recordings.First(i => _tvDtoService.GetInternalRecordingId(service.Name, i.Id) == new Guid(id));
return await service.GetRecordingStream(recording.Id, cancellationToken).ConfigureAwait(false);
}
- public async Task<StreamResponseInfo> GetChannelStream(string id, CancellationToken cancellationToken)
+ public async Task<LiveStreamInfo> GetChannelStream(string id, CancellationToken cancellationToken)
{
var service = ActiveService;
diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec
index 4dd9b22fe..5b8f266bc 100644
--- a/Nuget/MediaBrowser.Common.Internal.nuspec
+++ b/Nuget/MediaBrowser.Common.Internal.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaBrowser.Common.Internal</id>
- <version>3.0.294</version>
+ <version>3.0.295</version>
<title>MediaBrowser.Common.Internal</title>
<authors>Luke</authors>
<owners>ebr,Luke,scottisafool</owners>
@@ -12,7 +12,7 @@
<description>Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption.</description>
<copyright>Copyright © Media Browser 2013</copyright>
<dependencies>
- <dependency id="MediaBrowser.Common" version="3.0.294" />
+ <dependency id="MediaBrowser.Common" version="3.0.295" />
<dependency id="NLog" version="2.1.0" />
<dependency id="SimpleInjector" version="2.4.0" />
<dependency id="sharpcompress" version="0.10.2" />
diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec
index ea68c2c49..334ddc8e9 100644
--- a/Nuget/MediaBrowser.Common.nuspec
+++ b/Nuget/MediaBrowser.Common.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaBrowser.Common</id>
- <version>3.0.294</version>
+ <version>3.0.295</version>
<title>MediaBrowser.Common</title>
<authors>Media Browser Team</authors>
<owners>ebr,Luke,scottisafool</owners>
diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec
index 1e3a24eee..b0d354a91 100644
--- a/Nuget/MediaBrowser.Server.Core.nuspec
+++ b/Nuget/MediaBrowser.Server.Core.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>MediaBrowser.Server.Core</id>
- <version>3.0.294</version>
+ <version>3.0.295</version>
<title>Media Browser.Server.Core</title>
<authors>Media Browser Team</authors>
<owners>ebr,Luke,scottisafool</owners>
@@ -12,7 +12,7 @@
<description>Contains core components required to build plugins for Media Browser Server.</description>
<copyright>Copyright © Media Browser 2013</copyright>
<dependencies>
- <dependency id="MediaBrowser.Common" version="3.0.294" />
+ <dependency id="MediaBrowser.Common" version="3.0.295" />
</dependencies>
</metadata>
<files>