using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Logging; using System; using System.Threading; using System.Threading.Tasks; namespace MediaBrowser.Controller.Providers { /// /// Class BaseMetadataProvider /// public abstract class BaseMetadataProvider { /// /// Gets the logger. /// /// The logger. protected ILogger Logger { get; set; } protected ILogManager LogManager { get; set; } /// /// Gets the configuration manager. /// /// The configuration manager. protected IServerConfigurationManager ConfigurationManager { get; private set; } /// /// The _id /// public readonly Guid Id; /// /// The true task result /// protected static readonly Task TrueTaskResult = Task.FromResult(true); protected static readonly Task FalseTaskResult = Task.FromResult(false); protected static readonly SemaphoreSlim XmlParsingResourcePool = new SemaphoreSlim(4, 4); /// /// Supportses the specified item. /// /// The item. /// true if XXXX, false otherwise public abstract bool Supports(BaseItem item); /// /// Gets a value indicating whether [requires internet]. /// /// true if [requires internet]; otherwise, false. public virtual bool RequiresInternet { get { return false; } } /// /// Gets the provider version. /// /// The provider version. protected virtual string ProviderVersion { get { return null; } } public virtual ItemUpdateType ItemUpdateType { get { return RequiresInternet ? ItemUpdateType.MetadataDownload : ItemUpdateType.MetadataImport; } } /// /// Gets a value indicating whether [refresh on version change]. /// /// true if [refresh on version change]; otherwise, false. protected virtual bool RefreshOnVersionChange { get { return false; } } /// /// Determines if this provider is relatively slow and, therefore, should be skipped /// in certain instances. Default is whether or not it requires internet. Can be overridden /// for explicit designation. /// /// true if this instance is slow; otherwise, false. public virtual bool IsSlow { get { return RequiresInternet; } } /// /// Initializes a new instance of the class. /// protected BaseMetadataProvider(ILogManager logManager, IServerConfigurationManager configurationManager) { Logger = logManager.GetLogger(GetType().Name); LogManager = logManager; ConfigurationManager = configurationManager; Id = GetType().FullName.GetMD5(); Initialize(); } /// /// Initializes this instance. /// protected virtual void Initialize() { } /// /// Sets the persisted last refresh date on the item for this provider. /// /// The item. /// The value. /// The provider version. /// The provider information. /// The status. /// item public virtual void SetLastRefreshed(BaseItem item, DateTime value, string providerVersion, BaseProviderInfo providerInfo, ProviderRefreshStatus status = ProviderRefreshStatus.Success) { if (item == null) { throw new ArgumentNullException("item"); } providerInfo.LastRefreshed = value; providerInfo.LastRefreshStatus = status; providerInfo.ProviderVersion = providerVersion; } /// /// Sets the last refreshed. /// /// The item. /// The value. /// The provider information. /// The status. public void SetLastRefreshed(BaseItem item, DateTime value, BaseProviderInfo providerInfo, ProviderRefreshStatus status = ProviderRefreshStatus.Success) { SetLastRefreshed(item, value, ProviderVersion, providerInfo, status); } /// /// Returns whether or not this provider should be re-fetched. Default functionality can /// compare a provided date with a last refresh time. This can be overridden for more complex /// determinations. /// /// The item. /// true if XXXX, false otherwise /// public bool NeedsRefresh(BaseItem item, BaseProviderInfo data) { if (item == null) { throw new ArgumentNullException(); } return NeedsRefreshInternal(item, data); } /// /// Gets a value indicating whether [enforce dont fetch metadata]. /// /// true if [enforce dont fetch metadata]; otherwise, false. public virtual bool EnforceDontFetchMetadata { get { return true; } } /// /// Needses the refresh internal. /// /// The item. /// The provider info. /// true if XXXX, false otherwise /// protected virtual bool NeedsRefreshInternal(BaseItem item, BaseProviderInfo providerInfo) { if (item == null) { throw new ArgumentNullException("item"); } if (providerInfo == null) { throw new ArgumentNullException("providerInfo"); } if (providerInfo.LastRefreshed == default(DateTime)) { return true; } if (NeedsRefreshBasedOnCompareDate(item, providerInfo)) { return true; } if (RefreshOnVersionChange && !String.Equals(ProviderVersion, providerInfo.ProviderVersion)) { return true; } if (providerInfo.LastRefreshStatus != ProviderRefreshStatus.Success) { return true; } return false; } /// /// Needses the refresh based on compare date. /// /// The item. /// The provider info. /// true if XXXX, false otherwise protected virtual bool NeedsRefreshBasedOnCompareDate(BaseItem item, BaseProviderInfo providerInfo) { return CompareDate(item) > providerInfo.LastRefreshed; } /// /// Override this to return the date that should be compared to the last refresh date /// to determine if this provider should be re-fetched. /// /// The item. /// DateTime. protected virtual DateTime CompareDate(BaseItem item) { return DateTime.MinValue.AddMinutes(1); // want this to be greater than mindate so new items will refresh } /// /// Fetches metadata and returns true or false indicating if any work that requires persistence was done /// /// The item. /// if set to true [force]. /// The provider information. /// The cancellation token. /// Task{System.Boolean}. /// public abstract Task FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken); /// /// Gets the priority. /// /// The priority. public abstract MetadataProviderPriority Priority { get; } } }