commit
a4260a2cbc
|
@ -159,6 +159,7 @@ namespace MediaBrowser.Api.Subtitles
|
|||
builder.AppendLine("#EXT-X-TARGETDURATION:" + request.SegmentLength.ToString(CultureInfo.InvariantCulture));
|
||||
builder.AppendLine("#EXT-X-VERSION:3");
|
||||
builder.AppendLine("#EXT-X-MEDIA-SEQUENCE:0");
|
||||
builder.AppendLine("#EXT-X-PLAYLIST-TYPE:VOD");
|
||||
|
||||
long positionTicks = 0;
|
||||
var segmentLengthTicks = TimeSpan.FromSeconds(request.SegmentLength).Ticks;
|
||||
|
@ -170,7 +171,7 @@ namespace MediaBrowser.Api.Subtitles
|
|||
var remaining = runtime - positionTicks;
|
||||
var lengthTicks = Math.Min(remaining, segmentLengthTicks);
|
||||
|
||||
builder.AppendLine("#EXTINF:" + TimeSpan.FromTicks(lengthTicks).TotalSeconds.ToString(CultureInfo.InvariantCulture));
|
||||
builder.AppendLine("#EXTINF:" + TimeSpan.FromTicks(lengthTicks).TotalSeconds.ToString(CultureInfo.InvariantCulture) + ",");
|
||||
|
||||
var endPositionTicks = Math.Min(runtime, positionTicks + segmentLengthTicks);
|
||||
|
||||
|
|
|
@ -456,7 +456,16 @@ namespace MediaBrowser.Api
|
|||
throw new ResourceNotFoundException("No series exists with Id " + request.Id);
|
||||
}
|
||||
|
||||
episodes = series.GetEpisodes(user, request.Season.Value);
|
||||
var season = series.GetSeasons(user).FirstOrDefault(i => i.IndexNumber == request.Season.Value);
|
||||
|
||||
if (season == null)
|
||||
{
|
||||
episodes = new List<Episode>();
|
||||
}
|
||||
else
|
||||
{
|
||||
episodes = series.GetEpisodes(user, season);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1031,9 +1031,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
}
|
||||
: options;
|
||||
|
||||
var result = await ProviderManager.RefreshSingleItem(this, refreshOptions, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
return result;
|
||||
return await ProviderManager.RefreshSingleItem(this, refreshOptions, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
|
|
|
@ -461,17 +461,15 @@ namespace MediaBrowser.Controller.Entities
|
|||
|
||||
foreach (var item in itemsRemoved)
|
||||
{
|
||||
if (item.LocationType == LocationType.Virtual ||
|
||||
item.LocationType == LocationType.Remote)
|
||||
var itemLocationType = item.LocationType;
|
||||
if (itemLocationType == LocationType.Virtual ||
|
||||
itemLocationType == LocationType.Remote)
|
||||
{
|
||||
// Don't remove these because there's no way to accurately validate them.
|
||||
validChildren.Add(item);
|
||||
}
|
||||
|
||||
else if (!string.IsNullOrEmpty(item.Path) && IsPathOffline(item.Path))
|
||||
{
|
||||
await UpdateIsOffline(item, true).ConfigureAwait(false);
|
||||
validChildren.Add(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -205,7 +205,7 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
|
||||
if (IndexNumber.HasValue && series != null)
|
||||
{
|
||||
return series.GetEpisodes(user, IndexNumber.Value, includeMissingEpisodes, includeVirtualUnairedEpisodes);
|
||||
return series.GetEpisodes(user, this, includeMissingEpisodes, includeVirtualUnairedEpisodes);
|
||||
}
|
||||
|
||||
var episodes = GetRecursiveChildren(user)
|
||||
|
|
|
@ -338,11 +338,11 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
progress.Report(100);
|
||||
}
|
||||
|
||||
public IEnumerable<Episode> GetEpisodes(User user, int seasonNumber)
|
||||
public IEnumerable<Episode> GetEpisodes(User user, Season season)
|
||||
{
|
||||
var config = user.Configuration;
|
||||
|
||||
return GetEpisodes(user, seasonNumber, config.DisplayMissingEpisodes, config.DisplayUnairedEpisodes);
|
||||
return GetEpisodes(user, season, config.DisplayMissingEpisodes, config.DisplayUnairedEpisodes);
|
||||
}
|
||||
|
||||
private bool EnablePooling()
|
||||
|
@ -350,7 +350,7 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
return false;
|
||||
}
|
||||
|
||||
public IEnumerable<Episode> GetEpisodes(User user, int seasonNumber, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes)
|
||||
public IEnumerable<Episode> GetEpisodes(User user, Season parentSeason, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes)
|
||||
{
|
||||
IEnumerable<Episode> episodes;
|
||||
|
||||
|
@ -388,7 +388,7 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
}).Cast<Episode>();
|
||||
}
|
||||
|
||||
episodes = FilterEpisodesBySeason(episodes, seasonNumber, DisplaySpecialsWithSeasons);
|
||||
episodes = FilterEpisodesBySeason(episodes, parentSeason, DisplaySpecialsWithSeasons);
|
||||
|
||||
if (!includeMissingEpisodes)
|
||||
{
|
||||
|
@ -399,7 +399,7 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
episodes = episodes.Where(i => !i.IsVirtualUnaired);
|
||||
}
|
||||
|
||||
var sortBy = seasonNumber == 0 ? ItemSortBy.SortName : ItemSortBy.AiredEpisodeOrder;
|
||||
var sortBy = (parentSeason.IndexNumber ?? -1) == 0 ? ItemSortBy.SortName : ItemSortBy.AiredEpisodeOrder;
|
||||
|
||||
return LibraryManager.Sort(episodes, user, new[] { sortBy }, SortOrder.Ascending)
|
||||
.Cast<Episode>();
|
||||
|
@ -408,10 +408,6 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
/// <summary>
|
||||
/// Filters the episodes by season.
|
||||
/// </summary>
|
||||
/// <param name="episodes">The episodes.</param>
|
||||
/// <param name="seasonNumber">The season number.</param>
|
||||
/// <param name="includeSpecials">if set to <c>true</c> [include specials].</param>
|
||||
/// <returns>IEnumerable{Episode}.</returns>
|
||||
public static IEnumerable<Episode> FilterEpisodesBySeason(IEnumerable<Episode> episodes, int seasonNumber, bool includeSpecials)
|
||||
{
|
||||
if (!includeSpecials || seasonNumber < 1)
|
||||
|
@ -434,6 +430,55 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filters the episodes by season.
|
||||
/// </summary>
|
||||
public static IEnumerable<Episode> FilterEpisodesBySeason(IEnumerable<Episode> episodes, Season parentSeason, bool includeSpecials)
|
||||
{
|
||||
var seasonNumber = parentSeason.IndexNumber;
|
||||
if (!includeSpecials || (seasonNumber.HasValue && seasonNumber.Value == 0))
|
||||
{
|
||||
var seasonPresentationKey = parentSeason.PresentationUniqueKey;
|
||||
|
||||
return episodes.Where(i =>
|
||||
{
|
||||
if ((i.ParentIndexNumber ?? -1) == seasonNumber)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (!i.ParentIndexNumber.HasValue)
|
||||
{
|
||||
var season = i.Season;
|
||||
return season != null && string.Equals(season.PresentationUniqueKey, seasonPresentationKey, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
var seasonPresentationKey = parentSeason.PresentationUniqueKey;
|
||||
|
||||
return episodes.Where(episode =>
|
||||
{
|
||||
var currentSeasonNumber = episode.AiredSeasonNumber;
|
||||
|
||||
if (currentSeasonNumber.HasValue && seasonNumber.HasValue && currentSeasonNumber.Value == seasonNumber.Value)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!episode.ParentIndexNumber.HasValue)
|
||||
{
|
||||
var season = episode.Season;
|
||||
return season != null && string.Equals(season.PresentationUniqueKey, seasonPresentationKey, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool GetBlockUnratedValue(UserPolicy config)
|
||||
{
|
||||
return config.BlockUnratedItems.Contains(UnratedItem.Series);
|
||||
|
|
|
@ -230,12 +230,6 @@
|
|||
<Compile Include="..\MediaBrowser.Model\Configuration\SubtitlePlaybackMode.cs">
|
||||
<Link>Configuration\SubtitlePlaybackMode.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\MediaBrowser.Model\Configuration\TheMovieDbOptions.cs">
|
||||
<Link>Configuration\TheMovieDbOptions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\MediaBrowser.Model\Configuration\TvdbOptions.cs">
|
||||
<Link>Configuration\TvdbOptions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\MediaBrowser.Model\Configuration\UnratedItem.cs">
|
||||
<Link>Configuration\UnratedItem.cs</Link>
|
||||
</Compile>
|
||||
|
|
|
@ -204,12 +204,6 @@
|
|||
<Compile Include="..\MediaBrowser.Model\Configuration\SubtitlePlaybackMode.cs">
|
||||
<Link>Configuration\SubtitlePlaybackMode.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\MediaBrowser.Model\Configuration\TheMovieDbOptions.cs">
|
||||
<Link>Configuration\TheMovieDbOptions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\MediaBrowser.Model\Configuration\TvdbOptions.cs">
|
||||
<Link>Configuration\TvdbOptions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\MediaBrowser.Model\Configuration\UnratedItem.cs">
|
||||
<Link>Configuration\UnratedItem.cs</Link>
|
||||
</Compile>
|
||||
|
|
|
@ -3,11 +3,6 @@ namespace MediaBrowser.Model.Configuration
|
|||
{
|
||||
public class FanartOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether [enable automatic updates].
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if [enable automatic updates]; otherwise, <c>false</c>.</value>
|
||||
public bool EnableAutomaticUpdates { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the user API key.
|
||||
/// </summary>
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
|
||||
namespace MediaBrowser.Model.Configuration
|
||||
{
|
||||
public class TheMovieDbOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether [enable automatic updates].
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if [enable automatic updates]; otherwise, <c>false</c>.</value>
|
||||
public bool EnableAutomaticUpdates { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
|
||||
namespace MediaBrowser.Model.Configuration
|
||||
{
|
||||
public class TvdbOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether [enable automatic updates].
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if [enable automatic updates]; otherwise, <c>false</c>.</value>
|
||||
public bool EnableAutomaticUpdates { get; set; }
|
||||
}
|
||||
}
|
|
@ -97,8 +97,6 @@
|
|||
<Compile Include="Configuration\FanartOptions.cs" />
|
||||
<Compile Include="Configuration\MetadataConfiguration.cs" />
|
||||
<Compile Include="Configuration\PeopleMetadataOptions.cs" />
|
||||
<Compile Include="Configuration\TheMovieDbOptions.cs" />
|
||||
<Compile Include="Configuration\TvdbOptions.cs" />
|
||||
<Compile Include="Configuration\XbmcMetadataOptions.cs" />
|
||||
<Compile Include="Configuration\SubtitlePlaybackMode.cs" />
|
||||
<Compile Include="Connect\ConnectAuthenticationExchangeResult.cs" />
|
||||
|
|
|
@ -1,165 +0,0 @@
|
|||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Providers;
|
||||
using MediaBrowser.Providers.Genres;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.Providers.Folders
|
||||
{
|
||||
public class DefaultImageProvider : IRemoteImageProvider, IHasItemChangeMonitor
|
||||
{
|
||||
private readonly IHttpClient _httpClient;
|
||||
|
||||
public DefaultImageProvider(IHttpClient httpClient)
|
||||
{
|
||||
_httpClient = httpClient;
|
||||
}
|
||||
|
||||
public IEnumerable<ImageType> GetSupportedImages(IHasImages item)
|
||||
{
|
||||
return new List<ImageType>
|
||||
{
|
||||
ImageType.Primary
|
||||
};
|
||||
}
|
||||
|
||||
public Task<IEnumerable<RemoteImageInfo>> GetImages(IHasImages item, CancellationToken cancellationToken)
|
||||
{
|
||||
var view = item as UserView;
|
||||
|
||||
if (view != null)
|
||||
{
|
||||
return GetImages(view.ViewType, cancellationToken);
|
||||
}
|
||||
|
||||
var folder = (ICollectionFolder)item;
|
||||
return GetImages(folder.CollectionType, cancellationToken);
|
||||
}
|
||||
|
||||
private Task<IEnumerable<RemoteImageInfo>> GetImages(string viewType, CancellationToken cancellationToken)
|
||||
{
|
||||
var url = GetImageUrl(viewType);
|
||||
|
||||
var list = new List<RemoteImageInfo>();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(url))
|
||||
{
|
||||
list.AddRange(new List<RemoteImageInfo>{
|
||||
new RemoteImageInfo
|
||||
{
|
||||
ProviderName = Name,
|
||||
Url = url,
|
||||
Type = ImageType.Primary
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return Task.FromResult<IEnumerable<RemoteImageInfo>>(list);
|
||||
}
|
||||
|
||||
private string GetImageUrl(string viewType)
|
||||
{
|
||||
const string urlPrefix = "https://raw.githubusercontent.com/MediaBrowser/Emby.Resources/master/images/folders/";
|
||||
|
||||
if (string.Equals(viewType, CollectionType.Books, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return urlPrefix + "books.jpg";
|
||||
}
|
||||
if (string.Equals(viewType, CollectionType.Games, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return urlPrefix + "games.jpg";
|
||||
}
|
||||
if (string.Equals(viewType, CollectionType.Music, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
//return urlPrefix + "music.jpg";
|
||||
}
|
||||
if (string.Equals(viewType, CollectionType.Photos, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
//return urlPrefix + "photos.png";
|
||||
}
|
||||
if (string.Equals(viewType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
//return urlPrefix + "tv.jpg";
|
||||
}
|
||||
if (string.Equals(viewType, CollectionType.Channels, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return urlPrefix + "channels.jpg";
|
||||
}
|
||||
if (string.Equals(viewType, CollectionType.LiveTv, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return urlPrefix + "livetv.png";
|
||||
}
|
||||
if (string.Equals(viewType, CollectionType.Movies, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
//return urlPrefix + "movies.jpg";
|
||||
}
|
||||
if (string.Equals(viewType, CollectionType.Playlists, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return urlPrefix + "playlists.jpg";
|
||||
}
|
||||
if (string.Equals(viewType, CollectionType.HomeVideos, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
//return urlPrefix + "homevideos.jpg";
|
||||
}
|
||||
if (string.Equals(viewType, CollectionType.MusicVideos, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return urlPrefix + "musicvideos.jpg";
|
||||
}
|
||||
if (string.Equals(viewType, CollectionType.BoxSets, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
//return urlPrefix + "collections.jpg";
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(viewType))
|
||||
{
|
||||
//return urlPrefix + "generic.jpg";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "Default Image Provider"; }
|
||||
}
|
||||
|
||||
public bool Supports(IHasImages item)
|
||||
{
|
||||
var view = item as UserView;
|
||||
|
||||
if (view != null)
|
||||
{
|
||||
return !string.IsNullOrWhiteSpace(GetImageUrl(view.ViewType));
|
||||
}
|
||||
|
||||
var folder = item as ICollectionFolder;
|
||||
|
||||
if (folder != null)
|
||||
{
|
||||
return !string.IsNullOrWhiteSpace(GetImageUrl(folder.CollectionType));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public Task<HttpResponseInfo> GetImageResponse(string url, CancellationToken cancellationToken)
|
||||
{
|
||||
return _httpClient.GetResponse(new HttpRequestOptions
|
||||
{
|
||||
CancellationToken = cancellationToken,
|
||||
Url = url,
|
||||
ResourcePool = GenreImageProvider.ImageDownloadResourcePool
|
||||
});
|
||||
}
|
||||
|
||||
public bool HasChanged(IHasMetadata item, IDirectoryService directoryService)
|
||||
{
|
||||
return GetSupportedImages(item).Any(i => !item.HasImage(i));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -422,12 +422,6 @@ namespace MediaBrowser.Providers.Manager
|
|||
providers = providers
|
||||
.Where(i =>
|
||||
{
|
||||
var hasChangeMonitor = i as IHasChangeMonitor;
|
||||
if (hasChangeMonitor != null)
|
||||
{
|
||||
return HasChanged(item, hasChangeMonitor, dateLastImageRefresh, options.DirectoryService);
|
||||
}
|
||||
|
||||
var hasFileChangeMonitor = i as IHasItemChangeMonitor;
|
||||
if (hasFileChangeMonitor != null)
|
||||
{
|
||||
|
|
|
@ -89,7 +89,6 @@
|
|||
<Compile Include="Channels\ChannelMetadataService.cs" />
|
||||
<Compile Include="Chapters\ChapterManager.cs" />
|
||||
<Compile Include="Folders\CollectionFolderMetadataService.cs" />
|
||||
<Compile Include="Folders\DefaultImageProvider.cs" />
|
||||
<Compile Include="Folders\FolderMetadataService.cs" />
|
||||
<Compile Include="Folders\UserViewMetadataService.cs" />
|
||||
<Compile Include="GameGenres\GameGenreMetadataService.cs" />
|
||||
|
@ -145,10 +144,7 @@
|
|||
<Compile Include="Omdb\OmdbProvider.cs" />
|
||||
<Compile Include="Omdb\OmdbItemProvider.cs" />
|
||||
<Compile Include="People\MovieDbPersonImageProvider.cs" />
|
||||
<Compile Include="Movies\MovieUpdatesPrescanTask.cs" />
|
||||
<Compile Include="Movies\FanArtMovieUpdatesPostScanTask.cs" />
|
||||
<Compile Include="Movies\MovieDbProvider.cs" />
|
||||
<Compile Include="Music\FanArtUpdatesPostScanTask.cs" />
|
||||
<Compile Include="Music\FanArtAlbumProvider.cs" />
|
||||
<Compile Include="Music\FanArtArtistProvider.cs" />
|
||||
<Compile Include="Music\MusicBrainzAlbumProvider.cs" />
|
||||
|
@ -168,7 +164,6 @@
|
|||
<Compile Include="Subtitles\SubtitleManager.cs" />
|
||||
<Compile Include="TV\DummySeasonProvider.cs" />
|
||||
<Compile Include="TV\EpisodeMetadataService.cs" />
|
||||
<Compile Include="TV\FanArt\FanArtTvUpdatesPostScanTask.cs" />
|
||||
<Compile Include="TV\FanArt\FanArtSeasonProvider.cs" />
|
||||
<Compile Include="TV\FanArt\FanartSeriesProvider.cs" />
|
||||
<Compile Include="TV\MissingEpisodeProvider.cs" />
|
||||
|
|
|
@ -1,196 +0,0 @@
|
|||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
using MediaBrowser.Providers.Music;
|
||||
using MediaBrowser.Providers.TV;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using CommonIO;
|
||||
|
||||
namespace MediaBrowser.Providers.Movies
|
||||
{
|
||||
class FanartMovieUpdatesPostScanTask : ILibraryPostScanTask
|
||||
{
|
||||
private const string UpdatesUrl = "https://webservice.fanart.tv/v3/movies/latest?api_key={0}&date={1}";
|
||||
|
||||
/// <summary>
|
||||
/// The _HTTP client
|
||||
/// </summary>
|
||||
private readonly IHttpClient _httpClient;
|
||||
/// <summary>
|
||||
/// The _logger
|
||||
/// </summary>
|
||||
private readonly ILogger _logger;
|
||||
/// <summary>
|
||||
/// The _config
|
||||
/// </summary>
|
||||
private readonly IServerConfigurationManager _config;
|
||||
private readonly IJsonSerializer _jsonSerializer;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
|
||||
|
||||
public FanartMovieUpdatesPostScanTask(IJsonSerializer jsonSerializer, IServerConfigurationManager config, ILogger logger, IHttpClient httpClient, IFileSystem fileSystem)
|
||||
{
|
||||
_jsonSerializer = jsonSerializer;
|
||||
_config = config;
|
||||
_logger = logger;
|
||||
_httpClient = httpClient;
|
||||
_fileSystem = fileSystem;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs the specified progress.
|
||||
/// </summary>
|
||||
/// <param name="progress">The progress.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
|
||||
{
|
||||
var options = FanartSeriesProvider.Current.GetFanartOptions();
|
||||
|
||||
if (!options.EnableAutomaticUpdates)
|
||||
{
|
||||
progress.Report(100);
|
||||
return;
|
||||
}
|
||||
|
||||
var path = FanartMovieImageProvider.GetMoviesDataPath(_config.CommonApplicationPaths);
|
||||
|
||||
_fileSystem.CreateDirectory(path);
|
||||
|
||||
var timestampFile = Path.Combine(path, "time.txt");
|
||||
|
||||
var timestampFileInfo = _fileSystem.GetFileInfo(timestampFile);
|
||||
|
||||
// Don't check for updates every single time
|
||||
if (timestampFileInfo.Exists && (DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(timestampFileInfo)).TotalDays < 3)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Find out the last time we queried for updates
|
||||
var lastUpdateTime = timestampFileInfo.Exists ? _fileSystem.ReadAllText(timestampFile, Encoding.UTF8) : string.Empty;
|
||||
|
||||
var existingDirectories = Directory.EnumerateDirectories(path).Select(Path.GetFileName).ToList();
|
||||
|
||||
// If this is our first time, don't do any updates and just record the timestamp
|
||||
if (!string.IsNullOrEmpty(lastUpdateTime))
|
||||
{
|
||||
var moviesToUpdate = await GetMovieIdsToUpdate(existingDirectories, lastUpdateTime, options, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
progress.Report(5);
|
||||
|
||||
await UpdateMovies(moviesToUpdate, progress, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
var newUpdateTime = Convert.ToInt64(DateTimeToUnixTimestamp(DateTime.UtcNow)).ToString(UsCulture);
|
||||
|
||||
_fileSystem.WriteAllText(timestampFile, newUpdateTime, Encoding.UTF8);
|
||||
|
||||
progress.Report(100);
|
||||
}
|
||||
|
||||
private async Task<IEnumerable<string>> GetMovieIdsToUpdate(IEnumerable<string> existingIds, string lastUpdateTime, FanartOptions options, CancellationToken cancellationToken)
|
||||
{
|
||||
var url = string.Format(UpdatesUrl, FanartArtistProvider.ApiKey, lastUpdateTime);
|
||||
|
||||
var clientKey = options.UserApiKey;
|
||||
if (!string.IsNullOrWhiteSpace(clientKey))
|
||||
{
|
||||
url += "&client_key=" + clientKey;
|
||||
}
|
||||
|
||||
// First get last time
|
||||
using (var stream = await _httpClient.Get(new HttpRequestOptions
|
||||
{
|
||||
Url = url,
|
||||
CancellationToken = cancellationToken,
|
||||
EnableHttpCompression = true,
|
||||
ResourcePool = FanartArtistProvider.Current.FanArtResourcePool
|
||||
|
||||
}).ConfigureAwait(false))
|
||||
{
|
||||
using (var reader = new StreamReader(stream))
|
||||
{
|
||||
var json = await reader.ReadToEndAsync().ConfigureAwait(false);
|
||||
|
||||
// If empty fanart will return a string of "null", rather than an empty list
|
||||
if (string.Equals(json, "null", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return new List<string>();
|
||||
}
|
||||
|
||||
var updates = _jsonSerializer.DeserializeFromString<List<RootObject>>(json);
|
||||
|
||||
var existingDictionary = existingIds.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
return updates.SelectMany(i =>
|
||||
{
|
||||
var list = new List<string>();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(i.imdb_id))
|
||||
{
|
||||
list.Add(i.imdb_id);
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(i.tmdb_id))
|
||||
{
|
||||
list.Add(i.tmdb_id);
|
||||
}
|
||||
|
||||
return list;
|
||||
|
||||
}).Where(existingDictionary.ContainsKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task UpdateMovies(IEnumerable<string> idList, IProgress<double> progress, CancellationToken cancellationToken)
|
||||
{
|
||||
var list = idList.ToList();
|
||||
var numComplete = 0;
|
||||
|
||||
foreach (var id in list)
|
||||
{
|
||||
_logger.Info("Updating movie " + id);
|
||||
|
||||
await FanartMovieImageProvider.Current.DownloadMovieJson(id, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
numComplete++;
|
||||
double percent = numComplete;
|
||||
percent /= list.Count;
|
||||
percent *= 95;
|
||||
|
||||
progress.Report(percent + 5);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dates the time to unix timestamp.
|
||||
/// </summary>
|
||||
/// <param name="dateTime">The date time.</param>
|
||||
/// <returns>System.Double.</returns>
|
||||
private static double DateTimeToUnixTimestamp(DateTime dateTime)
|
||||
{
|
||||
return (dateTime - new DateTime(1970, 1, 1).ToUniversalTime()).TotalSeconds;
|
||||
}
|
||||
|
||||
public class RootObject
|
||||
{
|
||||
public string tmdb_id { get; set; }
|
||||
public string imdb_id { get; set; }
|
||||
public string name { get; set; }
|
||||
public string new_images { get; set; }
|
||||
public string total_images { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -24,7 +24,7 @@ using MediaBrowser.Providers.TV;
|
|||
|
||||
namespace MediaBrowser.Providers.Movies
|
||||
{
|
||||
public class FanartMovieImageProvider : IRemoteImageProvider, IHasItemChangeMonitor, IHasOrder
|
||||
public class FanartMovieImageProvider : IRemoteImageProvider, IHasOrder
|
||||
{
|
||||
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
|
||||
private readonly IServerConfigurationManager _config;
|
||||
|
@ -241,33 +241,6 @@ namespace MediaBrowser.Providers.Movies
|
|||
});
|
||||
}
|
||||
|
||||
public bool HasChanged(IHasMetadata item, IDirectoryService directoryService)
|
||||
{
|
||||
var options = FanartSeriesProvider.Current.GetFanartOptions();
|
||||
if (!options.EnableAutomaticUpdates)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var id = item.GetProviderId(MetadataProviders.Tmdb);
|
||||
if (string.IsNullOrEmpty(id))
|
||||
{
|
||||
id = item.GetProviderId(MetadataProviders.Imdb);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(id))
|
||||
{
|
||||
// Process images
|
||||
var path = GetFanartJsonPath(id);
|
||||
|
||||
var fileInfo = _fileSystem.GetFileInfo(path);
|
||||
|
||||
return !fileInfo.Exists || _fileSystem.GetLastWriteTimeUtc(fileInfo) > item.DateLastRefreshed;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the movie data path.
|
||||
/// </summary>
|
||||
|
|
|
@ -17,7 +17,7 @@ using System.Threading.Tasks;
|
|||
|
||||
namespace MediaBrowser.Providers.Movies
|
||||
{
|
||||
class MovieDbImageProvider : IRemoteImageProvider, IHasOrder, IHasItemChangeMonitor
|
||||
class MovieDbImageProvider : IRemoteImageProvider, IHasOrder
|
||||
{
|
||||
private readonly IJsonSerializer _jsonSerializer;
|
||||
private readonly IHttpClient _httpClient;
|
||||
|
@ -221,10 +221,5 @@ namespace MediaBrowser.Providers.Movies
|
|||
ResourcePool = MovieDbProvider.Current.MovieDbResourcePool
|
||||
});
|
||||
}
|
||||
|
||||
public bool HasChanged(IHasMetadata item, IDirectoryService directoryService)
|
||||
{
|
||||
return MovieDbProvider.Current.HasChanged(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -409,33 +409,6 @@ namespace MediaBrowser.Providers.Movies
|
|||
return await _httpClient.Get(options).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public TheMovieDbOptions GetTheMovieDbOptions()
|
||||
{
|
||||
return _configurationManager.GetConfiguration<TheMovieDbOptions>("themoviedb");
|
||||
}
|
||||
|
||||
public bool HasChanged(IHasMetadata item)
|
||||
{
|
||||
if (!GetTheMovieDbOptions().EnableAutomaticUpdates)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var tmdbId = item.GetProviderId(MetadataProviders.Tmdb);
|
||||
|
||||
if (!String.IsNullOrEmpty(tmdbId))
|
||||
{
|
||||
// Process images
|
||||
var dataFilePath = GetDataFilePath(tmdbId, item.GetPreferredMetadataLanguage());
|
||||
|
||||
var fileInfo = _fileSystem.GetFileInfo(dataFilePath);
|
||||
|
||||
return !fileInfo.Exists || _fileSystem.GetLastWriteTimeUtc(fileInfo) > item.DateLastRefreshed;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
|
@ -659,19 +632,4 @@ namespace MediaBrowser.Providers.Movies
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
public class TmdbConfigStore : IConfigurationFactory
|
||||
{
|
||||
public IEnumerable<ConfigurationStore> GetConfigurations()
|
||||
{
|
||||
return new List<ConfigurationStore>
|
||||
{
|
||||
new ConfigurationStore
|
||||
{
|
||||
Key = "themoviedb",
|
||||
ConfigurationType = typeof(TheMovieDbOptions)
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,11 +33,6 @@ namespace MediaBrowser.Providers.Movies
|
|||
get { return MovieDbProvider.Current.Name; }
|
||||
}
|
||||
|
||||
public bool HasChanged(IHasMetadata item, IDirectoryService directoryService)
|
||||
{
|
||||
return MovieDbProvider.Current.HasChanged(item);
|
||||
}
|
||||
|
||||
public int Order
|
||||
{
|
||||
get
|
||||
|
|
|
@ -1,249 +0,0 @@
|
|||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using CommonIO;
|
||||
|
||||
namespace MediaBrowser.Providers.Movies
|
||||
{
|
||||
public class MovieUpdatesPreScanTask : ILibraryPostScanTask
|
||||
{
|
||||
/// <summary>
|
||||
/// The updates URL
|
||||
/// </summary>
|
||||
private const string UpdatesUrl = "https://api.themoviedb.org/3/movie/changes?start_date={0}&api_key={1}&page={2}";
|
||||
|
||||
/// <summary>
|
||||
/// The _HTTP client
|
||||
/// </summary>
|
||||
private readonly IHttpClient _httpClient;
|
||||
/// <summary>
|
||||
/// The _logger
|
||||
/// </summary>
|
||||
private readonly ILogger _logger;
|
||||
/// <summary>
|
||||
/// The _config
|
||||
/// </summary>
|
||||
private readonly IServerConfigurationManager _config;
|
||||
private readonly IJsonSerializer _json;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MovieUpdatesPreScanTask"/> class.
|
||||
/// </summary>
|
||||
/// <param name="logger">The logger.</param>
|
||||
/// <param name="httpClient">The HTTP client.</param>
|
||||
/// <param name="config">The config.</param>
|
||||
/// <param name="json">The json.</param>
|
||||
public MovieUpdatesPreScanTask(ILogger logger, IHttpClient httpClient, IServerConfigurationManager config, IJsonSerializer json, IFileSystem fileSystem, ILibraryManager libraryManager)
|
||||
{
|
||||
_logger = logger;
|
||||
_httpClient = httpClient;
|
||||
_config = config;
|
||||
_json = json;
|
||||
_fileSystem = fileSystem;
|
||||
_libraryManager = libraryManager;
|
||||
}
|
||||
|
||||
protected readonly CultureInfo UsCulture = new CultureInfo("en-US");
|
||||
|
||||
/// <summary>
|
||||
/// Runs the specified progress.
|
||||
/// </summary>
|
||||
/// <param name="progress">The progress.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
|
||||
{
|
||||
if (!MovieDbProvider.Current.GetTheMovieDbOptions().EnableAutomaticUpdates)
|
||||
{
|
||||
progress.Report(100);
|
||||
return;
|
||||
}
|
||||
|
||||
var path = MovieDbProvider.GetMoviesDataPath(_config.CommonApplicationPaths);
|
||||
|
||||
_fileSystem.CreateDirectory(path);
|
||||
|
||||
var timestampFile = Path.Combine(path, "time.txt");
|
||||
|
||||
var timestampFileInfo = _fileSystem.GetFileInfo(timestampFile);
|
||||
|
||||
// Don't check for updates every single time
|
||||
if (timestampFileInfo.Exists && (DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(timestampFileInfo)).TotalDays < 7)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Find out the last time we queried tvdb for updates
|
||||
var lastUpdateTime = timestampFileInfo.Exists ? _fileSystem.ReadAllText(timestampFile, Encoding.UTF8) : string.Empty;
|
||||
|
||||
var existingDirectories = Directory.EnumerateDirectories(path).Select(Path.GetFileName).ToList();
|
||||
|
||||
if (!string.IsNullOrEmpty(lastUpdateTime))
|
||||
{
|
||||
long lastUpdateTicks;
|
||||
|
||||
if (long.TryParse(lastUpdateTime, NumberStyles.Any, UsCulture, out lastUpdateTicks))
|
||||
{
|
||||
var lastUpdateDate = new DateTime(lastUpdateTicks, DateTimeKind.Utc);
|
||||
|
||||
// They only allow up to 14 days of updates
|
||||
if ((DateTime.UtcNow - lastUpdateDate).TotalDays > 13)
|
||||
{
|
||||
lastUpdateDate = DateTime.UtcNow.AddDays(-13);
|
||||
}
|
||||
|
||||
var updatedIds = await GetIdsToUpdate(lastUpdateDate, 1, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
var existingDictionary = existingDirectories.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
var idsToUpdate = updatedIds.Where(i => !string.IsNullOrWhiteSpace(i) && existingDictionary.ContainsKey(i));
|
||||
|
||||
await UpdateMovies(idsToUpdate, progress, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
_fileSystem.WriteAllText(timestampFile, DateTime.UtcNow.Ticks.ToString(UsCulture), Encoding.UTF8);
|
||||
progress.Report(100);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ids to update.
|
||||
/// </summary>
|
||||
/// <param name="lastUpdateTime">The last update time.</param>
|
||||
/// <param name="page">The page.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task{IEnumerable{System.String}}.</returns>
|
||||
private async Task<IEnumerable<string>> GetIdsToUpdate(DateTime lastUpdateTime, int page, CancellationToken cancellationToken)
|
||||
{
|
||||
bool hasMorePages;
|
||||
var list = new List<string>();
|
||||
|
||||
// First get last time
|
||||
using (var stream = await _httpClient.Get(new HttpRequestOptions
|
||||
{
|
||||
Url = string.Format(UpdatesUrl, lastUpdateTime.ToString("yyyy-MM-dd"), MovieDbProvider.ApiKey, page),
|
||||
CancellationToken = cancellationToken,
|
||||
EnableHttpCompression = true,
|
||||
ResourcePool = MovieDbProvider.Current.MovieDbResourcePool,
|
||||
AcceptHeader = MovieDbProvider.AcceptHeader
|
||||
|
||||
}).ConfigureAwait(false))
|
||||
{
|
||||
var obj = _json.DeserializeFromStream<RootObject>(stream);
|
||||
|
||||
var data = obj.results.Select(i => i.id.ToString(UsCulture));
|
||||
|
||||
list.AddRange(data);
|
||||
|
||||
hasMorePages = page < obj.total_pages;
|
||||
}
|
||||
|
||||
if (hasMorePages)
|
||||
{
|
||||
var more = await GetIdsToUpdate(lastUpdateTime, page + 1, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
list.AddRange(more);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the movies.
|
||||
/// </summary>
|
||||
/// <param name="ids">The ids.</param>
|
||||
/// <param name="progress">The progress.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
private async Task UpdateMovies(IEnumerable<string> ids, IProgress<double> progress, CancellationToken cancellationToken)
|
||||
{
|
||||
var list = ids.ToList();
|
||||
var numComplete = 0;
|
||||
|
||||
// Gather all movies into a lookup by tmdb id
|
||||
var allMovies = _libraryManager.GetItemList(new Controller.Entities.InternalItemsQuery
|
||||
{
|
||||
IncludeItemTypes = new[] {typeof (Movie).Name},
|
||||
Recursive = true
|
||||
|
||||
}).Where(i => !string.IsNullOrEmpty(i.GetProviderId(MetadataProviders.Tmdb)))
|
||||
.ToLookup(i => i.GetProviderId(MetadataProviders.Tmdb));
|
||||
|
||||
foreach (var id in list)
|
||||
{
|
||||
// Find the preferred language(s) for the movie in the library
|
||||
var languages = allMovies[id]
|
||||
.Select(i => i.GetPreferredMetadataLanguage())
|
||||
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||
.ToList();
|
||||
|
||||
foreach (var language in languages)
|
||||
{
|
||||
try
|
||||
{
|
||||
await UpdateMovie(id, language, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error updating tmdb movie id {0}, language {1}", ex, id, language);
|
||||
}
|
||||
}
|
||||
|
||||
numComplete++;
|
||||
double percent = numComplete;
|
||||
percent /= list.Count;
|
||||
percent *= 100;
|
||||
|
||||
progress.Report(percent);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the movie.
|
||||
/// </summary>
|
||||
/// <param name="id">The id.</param>
|
||||
/// <param name="preferredMetadataLanguage">The preferred metadata language.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
private Task UpdateMovie(string id, string preferredMetadataLanguage, CancellationToken cancellationToken)
|
||||
{
|
||||
_logger.Info("Updating movie from tmdb " + id + ", language " + preferredMetadataLanguage);
|
||||
|
||||
return MovieDbProvider.Current.DownloadMovieInfo(id, preferredMetadataLanguage, cancellationToken);
|
||||
}
|
||||
|
||||
class Result
|
||||
{
|
||||
public int id { get; set; }
|
||||
public bool? adult { get; set; }
|
||||
}
|
||||
|
||||
class RootObject
|
||||
{
|
||||
public List<Result> results { get; set; }
|
||||
public int page { get; set; }
|
||||
public int total_pages { get; set; }
|
||||
public int total_results { get; set; }
|
||||
|
||||
public RootObject()
|
||||
{
|
||||
results = new List<Result>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,7 +19,7 @@ using MediaBrowser.Model.Serialization;
|
|||
|
||||
namespace MediaBrowser.Providers.Music
|
||||
{
|
||||
public class FanartAlbumProvider : IRemoteImageProvider, IHasItemChangeMonitor, IHasOrder
|
||||
public class FanartAlbumProvider : IRemoteImageProvider, IHasOrder
|
||||
{
|
||||
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
|
||||
private readonly IServerConfigurationManager _config;
|
||||
|
@ -212,34 +212,5 @@ namespace MediaBrowser.Providers.Music
|
|||
ResourcePool = FanartArtistProvider.Current.FanArtResourcePool
|
||||
});
|
||||
}
|
||||
|
||||
public bool HasChanged(IHasMetadata item, IDirectoryService directoryService)
|
||||
{
|
||||
var options = FanartSeriesProvider.Current.GetFanartOptions();
|
||||
if (!options.EnableAutomaticUpdates)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var album = (MusicAlbum)item;
|
||||
var artist = album.MusicArtist;
|
||||
|
||||
if (artist != null)
|
||||
{
|
||||
var artistMusicBrainzId = artist.GetProviderId(MetadataProviders.MusicBrainzArtist);
|
||||
|
||||
if (!String.IsNullOrEmpty(artistMusicBrainzId))
|
||||
{
|
||||
// Process images
|
||||
var artistJsonPath = FanartArtistProvider.GetArtistJsonPath(_config.CommonApplicationPaths, artistMusicBrainzId);
|
||||
|
||||
var fileInfo = _fileSystem.GetFileInfo(artistJsonPath);
|
||||
|
||||
return !fileInfo.Exists || _fileSystem.GetLastWriteTimeUtc(fileInfo) > item.DateLastRefreshed;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ using MediaBrowser.Model.Serialization;
|
|||
|
||||
namespace MediaBrowser.Providers.Music
|
||||
{
|
||||
public class FanartArtistProvider : IRemoteImageProvider, IHasItemChangeMonitor, IHasOrder
|
||||
public class FanartArtistProvider : IRemoteImageProvider, IHasOrder
|
||||
{
|
||||
internal readonly SemaphoreSlim FanArtResourcePool = new SemaphoreSlim(3, 3);
|
||||
internal const string ApiKey = "5c6b04c68e904cfed1e6cbc9a9e683d4";
|
||||
|
@ -207,29 +207,6 @@ namespace MediaBrowser.Providers.Music
|
|||
});
|
||||
}
|
||||
|
||||
public bool HasChanged(IHasMetadata item, IDirectoryService directoryService)
|
||||
{
|
||||
var options = FanartSeriesProvider.Current.GetFanartOptions();
|
||||
if (!options.EnableAutomaticUpdates)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var id = item.GetProviderId(MetadataProviders.MusicBrainzArtist);
|
||||
|
||||
if (!String.IsNullOrEmpty(id))
|
||||
{
|
||||
// Process images
|
||||
var artistJsonPath = GetArtistJsonPath(_config.CommonApplicationPaths, id);
|
||||
|
||||
var fileInfo = _fileSystem.GetFileInfo(artistJsonPath);
|
||||
|
||||
return !fileInfo.Exists || _fileSystem.GetLastWriteTimeUtc(fileInfo) > item.DateLastRefreshed;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private readonly Task _cachedTask = Task.FromResult(true);
|
||||
internal Task EnsureArtistJson(string musicBrainzId, CancellationToken cancellationToken)
|
||||
{
|
||||
|
|
|
@ -1,203 +0,0 @@
|
|||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using CommonIO;
|
||||
using MediaBrowser.Providers.TV;
|
||||
|
||||
namespace MediaBrowser.Providers.Music
|
||||
{
|
||||
class FanartUpdatesPostScanTask : ILibraryPostScanTask
|
||||
{
|
||||
private const string UpdatesUrl = "https://api.fanart.tv/webservice/newmusic/{0}/{1}/";
|
||||
|
||||
/// <summary>
|
||||
/// The _HTTP client
|
||||
/// </summary>
|
||||
private readonly IHttpClient _httpClient;
|
||||
/// <summary>
|
||||
/// The _logger
|
||||
/// </summary>
|
||||
private readonly ILogger _logger;
|
||||
/// <summary>
|
||||
/// The _config
|
||||
/// </summary>
|
||||
private readonly IServerConfigurationManager _config;
|
||||
private readonly IJsonSerializer _jsonSerializer;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
|
||||
|
||||
public FanartUpdatesPostScanTask(IJsonSerializer jsonSerializer, IServerConfigurationManager config, ILogger logger, IHttpClient httpClient, IFileSystem fileSystem)
|
||||
{
|
||||
_jsonSerializer = jsonSerializer;
|
||||
_config = config;
|
||||
_logger = logger;
|
||||
_httpClient = httpClient;
|
||||
_fileSystem = fileSystem;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs the specified progress.
|
||||
/// </summary>
|
||||
/// <param name="progress">The progress.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
|
||||
{
|
||||
var options = FanartSeriesProvider.Current.GetFanartOptions();
|
||||
|
||||
if (!options.EnableAutomaticUpdates)
|
||||
{
|
||||
progress.Report(100);
|
||||
return;
|
||||
}
|
||||
|
||||
var path = FanartArtistProvider.GetArtistDataPath(_config.CommonApplicationPaths);
|
||||
|
||||
_fileSystem.CreateDirectory(path);
|
||||
|
||||
var timestampFile = Path.Combine(path, "time.txt");
|
||||
|
||||
var timestampFileInfo = _fileSystem.GetFileInfo(timestampFile);
|
||||
|
||||
// Don't check for updates every single time
|
||||
if (timestampFileInfo.Exists && (DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(timestampFileInfo)).TotalDays < 3)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Find out the last time we queried for updates
|
||||
var lastUpdateTime = timestampFileInfo.Exists ? _fileSystem.ReadAllText(timestampFile, Encoding.UTF8) : string.Empty;
|
||||
|
||||
var existingDirectories = Directory.EnumerateDirectories(path).Select(Path.GetFileName).ToList();
|
||||
|
||||
// If this is our first time, don't do any updates and just record the timestamp
|
||||
if (!string.IsNullOrEmpty(lastUpdateTime))
|
||||
{
|
||||
var artistsToUpdate = await GetArtistIdsToUpdate(existingDirectories, lastUpdateTime, options, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
progress.Report(5);
|
||||
|
||||
await UpdateArtists(artistsToUpdate, progress, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
var newUpdateTime = Convert.ToInt64(DateTimeToUnixTimestamp(DateTime.UtcNow)).ToString(UsCulture);
|
||||
|
||||
_fileSystem.WriteAllText(timestampFile, newUpdateTime, Encoding.UTF8);
|
||||
|
||||
progress.Report(100);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the artist ids to update.
|
||||
/// </summary>
|
||||
/// <param name="existingArtistIds">The existing series ids.</param>
|
||||
/// <param name="lastUpdateTime">The last update time.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task{IEnumerable{System.String}}.</returns>
|
||||
private async Task<IEnumerable<string>> GetArtistIdsToUpdate(IEnumerable<string> existingArtistIds, string lastUpdateTime, FanartOptions options, CancellationToken cancellationToken)
|
||||
{
|
||||
var url = string.Format(UpdatesUrl, FanartArtistProvider.ApiKey, lastUpdateTime);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(options.UserApiKey))
|
||||
{
|
||||
url += "&client_key=" + options.UserApiKey;
|
||||
}
|
||||
|
||||
// First get last time
|
||||
using (var stream = await _httpClient.Get(new HttpRequestOptions
|
||||
{
|
||||
Url = url,
|
||||
CancellationToken = cancellationToken,
|
||||
EnableHttpCompression = true,
|
||||
ResourcePool = FanartArtistProvider.Current.FanArtResourcePool
|
||||
|
||||
}).ConfigureAwait(false))
|
||||
{
|
||||
// If empty fanart will return a string of "null", rather than an empty list
|
||||
using (var reader = new StreamReader(stream))
|
||||
{
|
||||
var json = await reader.ReadToEndAsync().ConfigureAwait(false);
|
||||
|
||||
if (string.Equals(json, "null", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return new List<string>();
|
||||
}
|
||||
|
||||
var existingDictionary = existingArtistIds.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
var updates = _jsonSerializer.DeserializeFromString<List<FanArtUpdate>>(json);
|
||||
|
||||
return updates.Select(i => i.id).Where(existingDictionary.ContainsKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the artists.
|
||||
/// </summary>
|
||||
/// <param name="idList">The id list.</param>
|
||||
/// <param name="progress">The progress.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
private async Task UpdateArtists(IEnumerable<string> idList, IProgress<double> progress, CancellationToken cancellationToken)
|
||||
{
|
||||
var list = idList.ToList();
|
||||
var numComplete = 0;
|
||||
|
||||
foreach (var id in list)
|
||||
{
|
||||
await UpdateArtist(id, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
numComplete++;
|
||||
double percent = numComplete;
|
||||
percent /= list.Count;
|
||||
percent *= 95;
|
||||
|
||||
progress.Report(percent + 5);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the artist.
|
||||
/// </summary>
|
||||
/// <param name="musicBrainzId">The musicBrainzId.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
private Task UpdateArtist(string musicBrainzId, CancellationToken cancellationToken)
|
||||
{
|
||||
_logger.Info("Updating artist " + musicBrainzId);
|
||||
|
||||
return FanartArtistProvider.Current.DownloadArtistJson(musicBrainzId, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dates the time to unix timestamp.
|
||||
/// </summary>
|
||||
/// <param name="dateTime">The date time.</param>
|
||||
/// <returns>System.Double.</returns>
|
||||
private static double DateTimeToUnixTimestamp(DateTime dateTime)
|
||||
{
|
||||
return (dateTime - new DateTime(1970, 1, 1).ToUniversalTime()).TotalSeconds;
|
||||
}
|
||||
|
||||
public class FanArtUpdate
|
||||
{
|
||||
public string id { get; set; }
|
||||
public string name { get; set; }
|
||||
public string new_images { get; set; }
|
||||
public string total_images { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -27,11 +27,6 @@ namespace MediaBrowser.Providers.Music
|
|||
get { return MovieDbProvider.Current.Name; }
|
||||
}
|
||||
|
||||
public bool HasChanged(IHasMetadata item, IDirectoryService directoryService)
|
||||
{
|
||||
return MovieDbProvider.Current.HasChanged(item);
|
||||
}
|
||||
|
||||
public Task<HttpResponseInfo> GetImageResponse(string url, CancellationToken cancellationToken)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
|
|
|
@ -21,7 +21,7 @@ using CommonIO;
|
|||
|
||||
namespace MediaBrowser.Providers.TV
|
||||
{
|
||||
public class FanArtSeasonProvider : IRemoteImageProvider, IHasOrder, IHasItemChangeMonitor
|
||||
public class FanArtSeasonProvider : IRemoteImageProvider, IHasOrder
|
||||
{
|
||||
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
|
||||
private readonly IServerConfigurationManager _config;
|
||||
|
@ -224,36 +224,5 @@ namespace MediaBrowser.Providers.TV
|
|||
ResourcePool = FanartArtistProvider.Current.FanArtResourcePool
|
||||
});
|
||||
}
|
||||
|
||||
public bool HasChanged(IHasMetadata item, IDirectoryService directoryService)
|
||||
{
|
||||
var options = FanartSeriesProvider.Current.GetFanartOptions();
|
||||
if (!options.EnableAutomaticUpdates)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var season = (Season)item;
|
||||
var series = season.Series;
|
||||
|
||||
if (series == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var tvdbId = series.GetProviderId(MetadataProviders.Tvdb);
|
||||
|
||||
if (!String.IsNullOrEmpty(tvdbId))
|
||||
{
|
||||
// Process images
|
||||
var imagesFilePath = FanartSeriesProvider.Current.GetFanartJsonPath(tvdbId);
|
||||
|
||||
var fileInfo = _fileSystem.GetFileInfo(imagesFilePath);
|
||||
|
||||
return !fileInfo.Exists || _fileSystem.GetLastWriteTimeUtc(fileInfo) > item.DateLastRefreshed;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,192 +0,0 @@
|
|||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
using MediaBrowser.Providers.Music;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using CommonIO;
|
||||
|
||||
namespace MediaBrowser.Providers.TV
|
||||
{
|
||||
class FanArtTvUpdatesPostScanTask : ILibraryPostScanTask
|
||||
{
|
||||
private const string UpdatesUrl = "https://webservice.fanart.tv/v3/tv/latest?api_key={0}&date={1}";
|
||||
|
||||
/// <summary>
|
||||
/// The _HTTP client
|
||||
/// </summary>
|
||||
private readonly IHttpClient _httpClient;
|
||||
/// <summary>
|
||||
/// The _logger
|
||||
/// </summary>
|
||||
private readonly ILogger _logger;
|
||||
/// <summary>
|
||||
/// The _config
|
||||
/// </summary>
|
||||
private readonly IServerConfigurationManager _config;
|
||||
private readonly IJsonSerializer _jsonSerializer;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
|
||||
|
||||
public FanArtTvUpdatesPostScanTask(IJsonSerializer jsonSerializer, IServerConfigurationManager config, ILogger logger, IHttpClient httpClient, IFileSystem fileSystem)
|
||||
{
|
||||
_jsonSerializer = jsonSerializer;
|
||||
_config = config;
|
||||
_logger = logger;
|
||||
_httpClient = httpClient;
|
||||
_fileSystem = fileSystem;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs the specified progress.
|
||||
/// </summary>
|
||||
/// <param name="progress">The progress.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
|
||||
{
|
||||
var options = FanartSeriesProvider.Current.GetFanartOptions();
|
||||
|
||||
if (!options.EnableAutomaticUpdates)
|
||||
{
|
||||
progress.Report(100);
|
||||
return;
|
||||
}
|
||||
|
||||
var path = FanartSeriesProvider.GetSeriesDataPath(_config.CommonApplicationPaths);
|
||||
|
||||
_fileSystem.CreateDirectory(path);
|
||||
|
||||
var timestampFile = Path.Combine(path, "time.txt");
|
||||
|
||||
var timestampFileInfo = _fileSystem.GetFileInfo(timestampFile);
|
||||
|
||||
// Don't check for updates every single time
|
||||
if (timestampFileInfo.Exists && (DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(timestampFileInfo)).TotalDays < 3)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Find out the last time we queried for updates
|
||||
var lastUpdateTime = timestampFileInfo.Exists ? _fileSystem.ReadAllText(timestampFile, Encoding.UTF8) : string.Empty;
|
||||
|
||||
var existingDirectories = Directory.EnumerateDirectories(path).Select(Path.GetFileName).ToList();
|
||||
|
||||
// If this is our first time, don't do any updates and just record the timestamp
|
||||
if (!string.IsNullOrEmpty(lastUpdateTime))
|
||||
{
|
||||
var seriesToUpdate = await GetSeriesIdsToUpdate(existingDirectories, lastUpdateTime, options, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
progress.Report(5);
|
||||
|
||||
await UpdateSeries(seriesToUpdate, progress, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
var newUpdateTime = Convert.ToInt64(DateTimeToUnixTimestamp(DateTime.UtcNow)).ToString(UsCulture);
|
||||
|
||||
_fileSystem.WriteAllText(timestampFile, newUpdateTime, Encoding.UTF8);
|
||||
|
||||
progress.Report(100);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the series ids to update.
|
||||
/// </summary>
|
||||
/// <param name="existingSeriesIds">The existing series ids.</param>
|
||||
/// <param name="lastUpdateTime">The last update time.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task{IEnumerable{System.String}}.</returns>
|
||||
private async Task<IEnumerable<string>> GetSeriesIdsToUpdate(IEnumerable<string> existingSeriesIds, string lastUpdateTime, FanartOptions options, CancellationToken cancellationToken)
|
||||
{
|
||||
var url = string.Format(UpdatesUrl, FanartArtistProvider.ApiKey, lastUpdateTime);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(options.UserApiKey))
|
||||
{
|
||||
url += "&client_key=" + options.UserApiKey;
|
||||
}
|
||||
|
||||
// First get last time
|
||||
using (var stream = await _httpClient.Get(new HttpRequestOptions
|
||||
{
|
||||
Url = url,
|
||||
CancellationToken = cancellationToken,
|
||||
EnableHttpCompression = true,
|
||||
ResourcePool = FanartArtistProvider.Current.FanArtResourcePool
|
||||
|
||||
}).ConfigureAwait(false))
|
||||
{
|
||||
// If empty fanart will return a string of "null", rather than an empty list
|
||||
using (var reader = new StreamReader(stream))
|
||||
{
|
||||
var json = await reader.ReadToEndAsync().ConfigureAwait(false);
|
||||
|
||||
if (string.Equals(json, "null", StringComparison.OrdinalIgnoreCase) || string.IsNullOrWhiteSpace(json))
|
||||
{
|
||||
return new List<string>();
|
||||
}
|
||||
|
||||
var existingDictionary = existingSeriesIds.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
var updates = _jsonSerializer.DeserializeFromString<List<FanartUpdatesPostScanTask.FanArtUpdate>>(json);
|
||||
|
||||
return updates.Select(i => i.id).Where(existingDictionary.ContainsKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the series.
|
||||
/// </summary>
|
||||
/// <param name="idList">The id list.</param>
|
||||
/// <param name="progress">The progress.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
private async Task UpdateSeries(IEnumerable<string> idList, IProgress<double> progress, CancellationToken cancellationToken)
|
||||
{
|
||||
var list = idList.ToList();
|
||||
var numComplete = 0;
|
||||
|
||||
foreach (var id in list)
|
||||
{
|
||||
_logger.Info("Updating series " + id);
|
||||
|
||||
await FanartSeriesProvider.Current.DownloadSeriesJson(id, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
numComplete++;
|
||||
double percent = numComplete;
|
||||
percent /= list.Count;
|
||||
percent *= 95;
|
||||
|
||||
progress.Report(percent + 5);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dates the time to unix timestamp.
|
||||
/// </summary>
|
||||
/// <param name="dateTime">The date time.</param>
|
||||
/// <returns>System.Double.</returns>
|
||||
private static double DateTimeToUnixTimestamp(DateTime dateTime)
|
||||
{
|
||||
return (dateTime - new DateTime(1970, 1, 1).ToUniversalTime()).TotalSeconds;
|
||||
}
|
||||
|
||||
public class FanArtUpdate
|
||||
{
|
||||
public string id { get; set; }
|
||||
public string name { get; set; }
|
||||
public string new_images { get; set; }
|
||||
public string total_images { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -23,7 +23,7 @@ using CommonIO;
|
|||
|
||||
namespace MediaBrowser.Providers.TV
|
||||
{
|
||||
public class FanartSeriesProvider : IRemoteImageProvider, IHasOrder, IHasItemChangeMonitor
|
||||
public class FanartSeriesProvider : IRemoteImageProvider, IHasOrder
|
||||
{
|
||||
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
|
||||
private readonly IServerConfigurationManager _config;
|
||||
|
@ -341,29 +341,6 @@ namespace MediaBrowser.Providers.TV
|
|||
}
|
||||
}
|
||||
|
||||
public bool HasChanged(IHasMetadata item, IDirectoryService directoryService)
|
||||
{
|
||||
var options = GetFanartOptions();
|
||||
if (!options.EnableAutomaticUpdates)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var tvdbId = item.GetProviderId(MetadataProviders.Tvdb);
|
||||
|
||||
if (!String.IsNullOrEmpty(tvdbId))
|
||||
{
|
||||
// Process images
|
||||
var imagesFilePath = GetFanartJsonPath(tvdbId);
|
||||
|
||||
var fileInfo = _fileSystem.GetFileInfo(imagesFilePath);
|
||||
|
||||
return !fileInfo.Exists || _fileSystem.GetLastWriteTimeUtc(fileInfo) > item.DateLastRefreshed;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public class Image
|
||||
{
|
||||
public string id { get; set; }
|
||||
|
|
|
@ -16,7 +16,7 @@ using System.Threading.Tasks;
|
|||
|
||||
namespace MediaBrowser.Providers.TV
|
||||
{
|
||||
public class MovieDbSeriesImageProvider : IRemoteImageProvider, IHasOrder, IHasItemChangeMonitor
|
||||
public class MovieDbSeriesImageProvider : IRemoteImageProvider, IHasOrder
|
||||
{
|
||||
private readonly IJsonSerializer _jsonSerializer;
|
||||
private readonly IHttpClient _httpClient;
|
||||
|
@ -195,10 +195,5 @@ namespace MediaBrowser.Providers.TV
|
|||
ResourcePool = MovieDbProvider.Current.MovieDbResourcePool
|
||||
});
|
||||
}
|
||||
|
||||
public bool HasChanged(IHasMetadata item, IDirectoryService directoryService)
|
||||
{
|
||||
return MovieDbSeriesProvider.Current.HasChanged(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -414,28 +414,6 @@ namespace MediaBrowser.Providers.TV
|
|||
return Path.Combine(path, filename);
|
||||
}
|
||||
|
||||
public bool HasChanged(IHasMetadata item)
|
||||
{
|
||||
if (!MovieDbProvider.Current.GetTheMovieDbOptions().EnableAutomaticUpdates)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var tmdbId = item.GetProviderId(MetadataProviders.Tmdb);
|
||||
|
||||
if (!String.IsNullOrEmpty(tmdbId))
|
||||
{
|
||||
// Process images
|
||||
var dataFilePath = GetDataFilePath(tmdbId, item.GetPreferredMetadataLanguage());
|
||||
|
||||
var fileInfo = _fileSystem.GetFileInfo(dataFilePath);
|
||||
|
||||
return !fileInfo.Exists || _fileSystem.GetLastWriteTimeUtc(fileInfo) > item.DateLastRefreshed;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private async Task<RemoteSearchResult> FindByExternalId(string id, string externalSource, CancellationToken cancellationToken)
|
||||
{
|
||||
var url = string.Format("https://api.themoviedb.org/3/tv/find/{0}?api_key={1}&external_source={2}",
|
||||
|
|
|
@ -17,7 +17,7 @@ using CommonIO;
|
|||
|
||||
namespace MediaBrowser.Providers.TV
|
||||
{
|
||||
public class TvdbEpisodeImageProvider : IRemoteImageProvider, IHasItemChangeMonitor
|
||||
public class TvdbEpisodeImageProvider : IRemoteImageProvider
|
||||
{
|
||||
private readonly IServerConfigurationManager _config;
|
||||
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
|
||||
|
@ -173,31 +173,5 @@ namespace MediaBrowser.Providers.TV
|
|||
ResourcePool = TvdbSeriesProvider.Current.TvDbResourcePool
|
||||
});
|
||||
}
|
||||
|
||||
public bool HasChanged(IHasMetadata item, IDirectoryService directoryService)
|
||||
{
|
||||
// For non-unaired items, only enable if configured
|
||||
if (!TvdbSeriesProvider.Current.GetTvDbOptions().EnableAutomaticUpdates)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!item.HasImage(ImageType.Primary))
|
||||
{
|
||||
var episode = (Episode)item;
|
||||
|
||||
var series = episode.Series;
|
||||
|
||||
if (series != null && TvdbSeriesProvider.IsValidSeries(series.ProviderIds))
|
||||
{
|
||||
// Process images
|
||||
var seriesXmlPath = TvdbSeriesProvider.Current.GetSeriesXmlPath(series.ProviderIds, series.GetPreferredMetadataLanguage());
|
||||
|
||||
return _fileSystem.GetLastWriteTimeUtc(seriesXmlPath) > item.DateLastRefreshed;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ namespace MediaBrowser.Providers.TV
|
|||
/// <summary>
|
||||
/// Class RemoteEpisodeProvider
|
||||
/// </summary>
|
||||
class TvdbEpisodeProvider : IRemoteMetadataProvider<Episode, EpisodeInfo>, IItemIdentityProvider<EpisodeInfo>, IHasItemChangeMonitor
|
||||
class TvdbEpisodeProvider : IRemoteMetadataProvider<Episode, EpisodeInfo>, IItemIdentityProvider<EpisodeInfo>
|
||||
{
|
||||
private static readonly string FullIdKey = MetadataProviders.Tvdb + "-Full";
|
||||
|
||||
|
@ -144,27 +144,6 @@ namespace MediaBrowser.Providers.TV
|
|||
return result;
|
||||
}
|
||||
|
||||
public bool HasChanged(IHasMetadata item, IDirectoryService directoryService)
|
||||
{
|
||||
if (!TvdbSeriesProvider.Current.GetTvDbOptions().EnableAutomaticUpdates)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var episode = (Episode)item;
|
||||
var series = episode.Series;
|
||||
|
||||
if (series != null && TvdbSeriesProvider.IsValidSeries(series.ProviderIds))
|
||||
{
|
||||
// Process images
|
||||
var seriesXmlPath = TvdbSeriesProvider.Current.GetSeriesXmlPath(series.ProviderIds, series.GetPreferredMetadataLanguage());
|
||||
|
||||
return _fileSystem.GetLastWriteTimeUtc(seriesXmlPath) > item.DateLastRefreshed;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the episode XML files.
|
||||
/// </summary>
|
||||
|
|
|
@ -20,7 +20,7 @@ using CommonIO;
|
|||
|
||||
namespace MediaBrowser.Providers.TV
|
||||
{
|
||||
public class TvdbSeasonImageProvider : IRemoteImageProvider, IHasOrder, IHasItemChangeMonitor
|
||||
public class TvdbSeasonImageProvider : IRemoteImageProvider, IHasOrder
|
||||
{
|
||||
private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
|
||||
|
||||
|
@ -362,28 +362,5 @@ namespace MediaBrowser.Providers.TV
|
|||
ResourcePool = TvdbSeriesProvider.Current.TvDbResourcePool
|
||||
});
|
||||
}
|
||||
|
||||
public bool HasChanged(IHasMetadata item, IDirectoryService directoryService)
|
||||
{
|
||||
if (!TvdbSeriesProvider.Current.GetTvDbOptions().EnableAutomaticUpdates)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var season = (Season)item;
|
||||
var series = season.Series;
|
||||
|
||||
if (series != null && TvdbSeriesProvider.IsValidSeries(series.ProviderIds))
|
||||
{
|
||||
// Process images
|
||||
var imagesXmlPath = Path.Combine(TvdbSeriesProvider.GetSeriesDataPath(_config.ApplicationPaths, series.ProviderIds), "banners.xml");
|
||||
|
||||
var fileInfo = _fileSystem.GetFileInfo(imagesXmlPath);
|
||||
|
||||
return fileInfo.Exists && _fileSystem.GetLastWriteTimeUtc(fileInfo) > item.DateLastRefreshed;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ using CommonIO;
|
|||
|
||||
namespace MediaBrowser.Providers.TV
|
||||
{
|
||||
public class TvdbSeriesImageProvider : IRemoteImageProvider, IHasOrder, IHasItemChangeMonitor
|
||||
public class TvdbSeriesImageProvider : IRemoteImageProvider, IHasOrder
|
||||
{
|
||||
private readonly IServerConfigurationManager _config;
|
||||
private readonly IHttpClient _httpClient;
|
||||
|
@ -331,25 +331,5 @@ namespace MediaBrowser.Providers.TV
|
|||
ResourcePool = TvdbSeriesProvider.Current.TvDbResourcePool
|
||||
});
|
||||
}
|
||||
|
||||
public bool HasChanged(IHasMetadata item, IDirectoryService directoryService)
|
||||
{
|
||||
if (!TvdbSeriesProvider.Current.GetTvDbOptions().EnableAutomaticUpdates)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (TvdbSeriesProvider.IsValidSeries(item.ProviderIds))
|
||||
{
|
||||
// Process images
|
||||
var imagesXmlPath = Path.Combine(TvdbSeriesProvider.GetSeriesDataPath(_config.ApplicationPaths, item.ProviderIds), "banners.xml");
|
||||
|
||||
var fileInfo = _fileSystem.GetFileInfo(imagesXmlPath);
|
||||
|
||||
return fileInfo.Exists && _fileSystem.GetLastWriteTimeUtc(fileInfo) > item.DateLastRefreshed;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -311,11 +311,6 @@ namespace MediaBrowser.Providers.TV
|
|||
return null;
|
||||
}
|
||||
|
||||
public TvdbOptions GetTvDbOptions()
|
||||
{
|
||||
return _config.GetConfiguration<TvdbOptions>("tvdb");
|
||||
}
|
||||
|
||||
internal static bool IsValidSeries(Dictionary<string, string> seriesProviderIds)
|
||||
{
|
||||
string id;
|
||||
|
@ -392,27 +387,25 @@ namespace MediaBrowser.Providers.TV
|
|||
|
||||
var seriesXmlFilename = preferredMetadataLanguage + ".xml";
|
||||
|
||||
var automaticUpdatesEnabled = GetTvDbOptions().EnableAutomaticUpdates;
|
||||
|
||||
const int cacheDays = 1;
|
||||
|
||||
var seriesFile = files.FirstOrDefault(i => string.Equals(seriesXmlFilename, i.Name, StringComparison.OrdinalIgnoreCase));
|
||||
// No need to check age if automatic updates are enabled
|
||||
if (seriesFile == null || !seriesFile.Exists || (!automaticUpdatesEnabled && (DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(seriesFile)).TotalDays > cacheDays))
|
||||
if (seriesFile == null || !seriesFile.Exists || (DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(seriesFile)).TotalDays > cacheDays)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var actorsXml = files.FirstOrDefault(i => string.Equals("actors.xml", i.Name, StringComparison.OrdinalIgnoreCase));
|
||||
// No need to check age if automatic updates are enabled
|
||||
if (actorsXml == null || !actorsXml.Exists || (!automaticUpdatesEnabled && (DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(actorsXml)).TotalDays > cacheDays))
|
||||
if (actorsXml == null || !actorsXml.Exists || (DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(actorsXml)).TotalDays > cacheDays)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var bannersXml = files.FirstOrDefault(i => string.Equals("banners.xml", i.Name, StringComparison.OrdinalIgnoreCase));
|
||||
// No need to check age if automatic updates are enabled
|
||||
if (bannersXml == null || !bannersXml.Exists || (!automaticUpdatesEnabled && (DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(bannersXml)).TotalDays > cacheDays))
|
||||
if (bannersXml == null || !bannersXml.Exists || (DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(bannersXml)).TotalDays > cacheDays)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -1450,19 +1443,4 @@ namespace MediaBrowser.Providers.TV
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
public class TvdbConfigStore : IConfigurationFactory
|
||||
{
|
||||
public IEnumerable<ConfigurationStore> GetConfigurations()
|
||||
{
|
||||
return new List<ConfigurationStore>
|
||||
{
|
||||
new ConfigurationStore
|
||||
{
|
||||
Key = "tvdb",
|
||||
ConfigurationType = typeof(TvdbOptions)
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ namespace MediaBrowser.Server.Implementations.Devices
|
|||
return base.IsVisible(user) && HasChildren();
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override string CollectionType
|
||||
{
|
||||
get { return Model.Entities.CollectionType.Photos; }
|
||||
|
|
|
@ -1670,7 +1670,13 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
{
|
||||
var elapsed = (DateTime.UtcNow - startDate).TotalMilliseconds;
|
||||
|
||||
if (elapsed >= 400)
|
||||
var slowThreshold = 1000;
|
||||
|
||||
#if DEBUG
|
||||
slowThreshold = 200;
|
||||
#endif
|
||||
|
||||
if (elapsed >= slowThreshold)
|
||||
{
|
||||
Logger.Debug("{2} query time (slow): {0}ms. Query: {1}",
|
||||
Convert.ToInt32(elapsed),
|
||||
|
|
Loading…
Reference in New Issue
Block a user