mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-04-21 09:34:44 +01:00
move classes to portable server project
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Emby.Server.Implementations.Channels
|
||||
{
|
||||
public static class ChannelConfigurationExtension
|
||||
{
|
||||
public static ChannelOptions GetChannelsConfiguration(this IConfigurationManager manager)
|
||||
{
|
||||
return manager.GetConfiguration<ChannelOptions>("channels");
|
||||
}
|
||||
}
|
||||
|
||||
public class ChannelConfigurationFactory : IConfigurationFactory
|
||||
{
|
||||
public IEnumerable<ConfigurationStore> GetConfigurations()
|
||||
{
|
||||
return new List<ConfigurationStore>
|
||||
{
|
||||
new ConfigurationStore
|
||||
{
|
||||
Key = "channels",
|
||||
ConfigurationType = typeof (ChannelOptions)
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using MediaBrowser.Controller.Channels;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Emby.Server.Implementations.Channels
|
||||
{
|
||||
public class ChannelDynamicMediaSourceProvider : IMediaSourceProvider
|
||||
{
|
||||
private readonly ChannelManager _channelManager;
|
||||
|
||||
public ChannelDynamicMediaSourceProvider(IChannelManager channelManager)
|
||||
{
|
||||
_channelManager = (ChannelManager)channelManager;
|
||||
}
|
||||
|
||||
public Task<IEnumerable<MediaSourceInfo>> GetMediaSources(IHasMediaSources item, CancellationToken cancellationToken)
|
||||
{
|
||||
var baseItem = (BaseItem) item;
|
||||
|
||||
if (baseItem.SourceType == SourceType.Channel)
|
||||
{
|
||||
return _channelManager.GetDynamicMediaSources(baseItem, cancellationToken);
|
||||
}
|
||||
|
||||
return Task.FromResult<IEnumerable<MediaSourceInfo>>(new List<MediaSourceInfo>());
|
||||
}
|
||||
|
||||
public Task<Tuple<MediaSourceInfo, IDirectStreamProvider>> OpenMediaSource(string openToken, CancellationToken cancellationToken)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task CloseMediaSource(string liveStreamId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
55
Emby.Server.Implementations/Channels/ChannelImageProvider.cs
Normal file
55
Emby.Server.Implementations/Channels/ChannelImageProvider.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
using MediaBrowser.Controller.Channels;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Emby.Server.Implementations.Channels
|
||||
{
|
||||
public class ChannelImageProvider : IDynamicImageProvider, IHasItemChangeMonitor
|
||||
{
|
||||
private readonly IChannelManager _channelManager;
|
||||
|
||||
public ChannelImageProvider(IChannelManager channelManager)
|
||||
{
|
||||
_channelManager = channelManager;
|
||||
}
|
||||
|
||||
public IEnumerable<ImageType> GetSupportedImages(IHasImages item)
|
||||
{
|
||||
return GetChannel(item).GetSupportedChannelImages();
|
||||
}
|
||||
|
||||
public Task<DynamicImageResponse> GetImage(IHasImages item, ImageType type, CancellationToken cancellationToken)
|
||||
{
|
||||
var channel = GetChannel(item);
|
||||
|
||||
return channel.GetChannelImage(type, cancellationToken);
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "Channel Image Provider"; }
|
||||
}
|
||||
|
||||
public bool Supports(IHasImages item)
|
||||
{
|
||||
return item is Channel;
|
||||
}
|
||||
|
||||
private IChannel GetChannel(IHasImages item)
|
||||
{
|
||||
var channel = (Channel)item;
|
||||
|
||||
return ((ChannelManager)_channelManager).GetChannelProvider(channel);
|
||||
}
|
||||
|
||||
public bool HasChanged(IHasMetadata item, IDirectoryService directoryService)
|
||||
{
|
||||
return GetSupportedImages(item).Any(i => !item.HasImage(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
1620
Emby.Server.Implementations/Channels/ChannelManager.cs
Normal file
1620
Emby.Server.Implementations/Channels/ChannelManager.cs
Normal file
File diff suppressed because it is too large
Load Diff
257
Emby.Server.Implementations/Channels/ChannelPostScanTask.cs
Normal file
257
Emby.Server.Implementations/Channels/ChannelPostScanTask.cs
Normal file
@@ -0,0 +1,257 @@
|
||||
using MediaBrowser.Common.Progress;
|
||||
using MediaBrowser.Controller.Channels;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Channels;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Extensions;
|
||||
|
||||
namespace Emby.Server.Implementations.Channels
|
||||
{
|
||||
public class ChannelPostScanTask
|
||||
{
|
||||
private readonly IChannelManager _channelManager;
|
||||
private readonly IUserManager _userManager;
|
||||
private readonly ILogger _logger;
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
|
||||
public ChannelPostScanTask(IChannelManager channelManager, IUserManager userManager, ILogger logger, ILibraryManager libraryManager)
|
||||
{
|
||||
_channelManager = channelManager;
|
||||
_userManager = userManager;
|
||||
_logger = logger;
|
||||
_libraryManager = libraryManager;
|
||||
}
|
||||
|
||||
public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
|
||||
{
|
||||
var users = _userManager.Users
|
||||
.DistinctBy(GetUserDistinctValue)
|
||||
.Select(i => i.Id.ToString("N"))
|
||||
.ToList();
|
||||
|
||||
var numComplete = 0;
|
||||
|
||||
foreach (var user in users)
|
||||
{
|
||||
double percentPerUser = 1;
|
||||
percentPerUser /= users.Count;
|
||||
var startingPercent = numComplete * percentPerUser * 100;
|
||||
|
||||
var innerProgress = new ActionableProgress<double>();
|
||||
innerProgress.RegisterAction(p => progress.Report(startingPercent + percentPerUser * p));
|
||||
|
||||
await DownloadContent(user, cancellationToken, innerProgress).ConfigureAwait(false);
|
||||
|
||||
numComplete++;
|
||||
double percent = numComplete;
|
||||
percent /= users.Count;
|
||||
progress.Report(percent * 100);
|
||||
}
|
||||
|
||||
await CleanDatabase(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
progress.Report(100);
|
||||
}
|
||||
|
||||
public static string GetUserDistinctValue(User user)
|
||||
{
|
||||
var channels = user.Policy.EnabledChannels
|
||||
.OrderBy(i => i)
|
||||
.ToList();
|
||||
|
||||
return string.Join("|", channels.ToArray());
|
||||
}
|
||||
|
||||
private async Task DownloadContent(string user, CancellationToken cancellationToken, IProgress<double> progress)
|
||||
{
|
||||
var channels = await _channelManager.GetChannelsInternal(new ChannelQuery
|
||||
{
|
||||
UserId = user
|
||||
|
||||
}, cancellationToken);
|
||||
|
||||
var numComplete = 0;
|
||||
var numItems = channels.Items.Length;
|
||||
|
||||
foreach (var channel in channels.Items)
|
||||
{
|
||||
var channelId = channel.Id.ToString("N");
|
||||
|
||||
var features = _channelManager.GetChannelFeatures(channelId);
|
||||
|
||||
const int currentRefreshLevel = 1;
|
||||
var maxRefreshLevel = features.AutoRefreshLevels ?? 0;
|
||||
maxRefreshLevel = Math.Max(maxRefreshLevel, 2);
|
||||
|
||||
if (maxRefreshLevel > 0)
|
||||
{
|
||||
var innerProgress = new ActionableProgress<double>();
|
||||
|
||||
var startingNumberComplete = numComplete;
|
||||
innerProgress.RegisterAction(p =>
|
||||
{
|
||||
double innerPercent = startingNumberComplete;
|
||||
innerPercent += p / 100;
|
||||
innerPercent /= numItems;
|
||||
progress.Report(innerPercent * 100);
|
||||
});
|
||||
|
||||
try
|
||||
{
|
||||
await GetAllItems(user, channelId, null, currentRefreshLevel, maxRefreshLevel, innerProgress, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error getting channel content", ex);
|
||||
}
|
||||
}
|
||||
|
||||
numComplete++;
|
||||
double percent = numComplete;
|
||||
percent /= numItems;
|
||||
progress.Report(percent * 100);
|
||||
}
|
||||
|
||||
progress.Report(100);
|
||||
}
|
||||
|
||||
private async Task CleanDatabase(CancellationToken cancellationToken)
|
||||
{
|
||||
var installedChannelIds = ((ChannelManager)_channelManager).GetInstalledChannelIds();
|
||||
|
||||
var databaseIds = _libraryManager.GetItemIds(new InternalItemsQuery
|
||||
{
|
||||
IncludeItemTypes = new[] { typeof(Channel).Name }
|
||||
});
|
||||
|
||||
var invalidIds = databaseIds
|
||||
.Except(installedChannelIds)
|
||||
.ToList();
|
||||
|
||||
foreach (var id in invalidIds)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
await CleanChannel(id, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task CleanChannel(Guid id, CancellationToken cancellationToken)
|
||||
{
|
||||
_logger.Info("Cleaning channel {0} from database", id);
|
||||
|
||||
// Delete all channel items
|
||||
var allIds = _libraryManager.GetItemIds(new InternalItemsQuery
|
||||
{
|
||||
ChannelIds = new[] { id.ToString("N") }
|
||||
});
|
||||
|
||||
foreach (var deleteId in allIds)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
await DeleteItem(deleteId).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
// Finally, delete the channel itself
|
||||
await DeleteItem(id).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private Task DeleteItem(Guid id)
|
||||
{
|
||||
var item = _libraryManager.GetItemById(id);
|
||||
|
||||
if (item == null)
|
||||
{
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
return _libraryManager.DeleteItem(item, new DeleteOptions
|
||||
{
|
||||
DeleteFileLocation = false
|
||||
});
|
||||
}
|
||||
|
||||
private async Task GetAllItems(string user, string channelId, string folderId, int currentRefreshLevel, int maxRefreshLevel, IProgress<double> progress, CancellationToken cancellationToken)
|
||||
{
|
||||
var folderItems = new List<string>();
|
||||
|
||||
var innerProgress = new ActionableProgress<double>();
|
||||
innerProgress.RegisterAction(p => progress.Report(p / 2));
|
||||
|
||||
var result = await _channelManager.GetChannelItemsInternal(new ChannelItemQuery
|
||||
{
|
||||
ChannelId = channelId,
|
||||
UserId = user,
|
||||
FolderId = folderId
|
||||
|
||||
}, innerProgress, cancellationToken);
|
||||
|
||||
folderItems.AddRange(result.Items.Where(i => i.IsFolder).Select(i => i.Id.ToString("N")));
|
||||
|
||||
var totalRetrieved = result.Items.Length;
|
||||
var totalCount = result.TotalRecordCount;
|
||||
|
||||
while (totalRetrieved < totalCount)
|
||||
{
|
||||
result = await _channelManager.GetChannelItemsInternal(new ChannelItemQuery
|
||||
{
|
||||
ChannelId = channelId,
|
||||
UserId = user,
|
||||
StartIndex = totalRetrieved,
|
||||
FolderId = folderId
|
||||
|
||||
}, new Progress<double>(), cancellationToken);
|
||||
|
||||
folderItems.AddRange(result.Items.Where(i => i.IsFolder).Select(i => i.Id.ToString("N")));
|
||||
|
||||
totalRetrieved += result.Items.Length;
|
||||
totalCount = result.TotalRecordCount;
|
||||
}
|
||||
|
||||
progress.Report(50);
|
||||
|
||||
if (currentRefreshLevel < maxRefreshLevel)
|
||||
{
|
||||
var numComplete = 0;
|
||||
var numItems = folderItems.Count;
|
||||
|
||||
foreach (var folder in folderItems)
|
||||
{
|
||||
try
|
||||
{
|
||||
innerProgress = new ActionableProgress<double>();
|
||||
|
||||
var startingNumberComplete = numComplete;
|
||||
innerProgress.RegisterAction(p =>
|
||||
{
|
||||
double innerPercent = startingNumberComplete;
|
||||
innerPercent += p / 100;
|
||||
innerPercent /= numItems;
|
||||
progress.Report(innerPercent * 50 + 50);
|
||||
});
|
||||
|
||||
await GetAllItems(user, channelId, folder, currentRefreshLevel + 1, maxRefreshLevel, innerProgress, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error getting channel content", ex);
|
||||
}
|
||||
|
||||
numComplete++;
|
||||
double percent = numComplete;
|
||||
percent /= numItems;
|
||||
progress.Report(percent * 50 + 50);
|
||||
}
|
||||
}
|
||||
|
||||
progress.Report(100);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
using MediaBrowser.Controller.Channels;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Tasks;
|
||||
|
||||
namespace Emby.Server.Implementations.Channels
|
||||
{
|
||||
class RefreshChannelsScheduledTask : IScheduledTask
|
||||
{
|
||||
private readonly IChannelManager _channelManager;
|
||||
private readonly IUserManager _userManager;
|
||||
private readonly ILogger _logger;
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
|
||||
public RefreshChannelsScheduledTask(IChannelManager channelManager, IUserManager userManager, ILogger logger, ILibraryManager libraryManager)
|
||||
{
|
||||
_channelManager = channelManager;
|
||||
_userManager = userManager;
|
||||
_logger = logger;
|
||||
_libraryManager = libraryManager;
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "Refresh Channels"; }
|
||||
}
|
||||
|
||||
public string Description
|
||||
{
|
||||
get { return "Refreshes internet channel information."; }
|
||||
}
|
||||
|
||||
public string Category
|
||||
{
|
||||
get { return "Internet Channels"; }
|
||||
}
|
||||
|
||||
public async Task Execute(System.Threading.CancellationToken cancellationToken, IProgress<double> progress)
|
||||
{
|
||||
var manager = (ChannelManager)_channelManager;
|
||||
|
||||
await manager.RefreshChannels(new Progress<double>(), cancellationToken).ConfigureAwait(false);
|
||||
|
||||
await new ChannelPostScanTask(_channelManager, _userManager, _logger, _libraryManager).Run(progress, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the triggers that define when the task will run
|
||||
/// </summary>
|
||||
public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
|
||||
{
|
||||
return new[] {
|
||||
|
||||
// Every so often
|
||||
new TaskTriggerInfo { Type = TaskTriggerInfo.TriggerInterval, IntervalTicks = TimeSpan.FromHours(24).Ticks}
|
||||
};
|
||||
}
|
||||
|
||||
public string Key
|
||||
{
|
||||
get { return "RefreshInternetChannels"; }
|
||||
}
|
||||
|
||||
public bool IsHidden
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public bool IsEnabled
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user