aboutsummaryrefslogtreecommitdiff
path: root/Emby.Server.Implementations
diff options
context:
space:
mode:
authorLuke <luke.pulverenti@gmail.com>2017-08-27 13:34:55 -0400
committerGitHub <noreply@github.com>2017-08-27 13:34:55 -0400
commitf3ee129bd9e88e8768221ba176bc8356f9b240e3 (patch)
tree72dc082f77629e8d70f764d175433b40ac4c02d0 /Emby.Server.Implementations
parent4f8684a16b1102056bd2b527dcbd585b78dd8000 (diff)
parentfa6bec94b59cf850246c5d0757b9279d080643d7 (diff)
Merge pull request #2847 from MediaBrowser/beta
Beta
Diffstat (limited to 'Emby.Server.Implementations')
-rw-r--r--Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs12
-rw-r--r--Emby.Server.Implementations/Activity/ActivityManager.cs6
-rw-r--r--Emby.Server.Implementations/Activity/ActivityRepository.cs7
-rw-r--r--Emby.Server.Implementations/ApplicationHost.cs33
-rw-r--r--Emby.Server.Implementations/Channels/ChannelManager.cs40
-rw-r--r--Emby.Server.Implementations/Collections/CollectionManager.cs35
-rw-r--r--Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs9
-rw-r--r--Emby.Server.Implementations/Data/SqliteItemRepository.cs40
-rw-r--r--Emby.Server.Implementations/Data/SqliteUserDataRepository.cs15
-rw-r--r--Emby.Server.Implementations/Data/SqliteUserRepository.cs5
-rw-r--r--Emby.Server.Implementations/Devices/DeviceRepository.cs6
-rw-r--r--Emby.Server.Implementations/Dto/DtoService.cs115
-rw-r--r--Emby.Server.Implementations/Emby.Server.Implementations.csproj7
-rw-r--r--Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs10
-rw-r--r--Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs2
-rw-r--r--Emby.Server.Implementations/HttpServer/HttpListenerHost.cs2
-rw-r--r--Emby.Server.Implementations/IO/LibraryMonitor.cs8
-rw-r--r--Emby.Server.Implementations/IO/LnkShortcutHandler.cs332
-rw-r--r--Emby.Server.Implementations/Library/LibraryManager.cs57
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs2
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs17
-rw-r--r--Emby.Server.Implementations/Library/SearchEngine.cs2
-rw-r--r--Emby.Server.Implementations/Library/UserDataManager.cs14
-rw-r--r--Emby.Server.Implementations/Library/UserManager.cs68
-rw-r--r--Emby.Server.Implementations/Library/UserViewManager.cs21
-rw-r--r--Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs165
-rw-r--r--Emby.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs4
-rw-r--r--Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs31
-rw-r--r--Emby.Server.Implementations/LiveTv/LiveTvDtoService.cs51
-rw-r--r--Emby.Server.Implementations/LiveTv/LiveTvManager.cs228
-rw-r--r--Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs22
-rw-r--r--Emby.Server.Implementations/LiveTv/RefreshChannelsScheduledTask.cs2
-rw-r--r--Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs128
-rw-r--r--Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs18
-rw-r--r--Emby.Server.Implementations/LiveTv/TunerHosts/MulticastStream.cs50
-rw-r--r--Emby.Server.Implementations/LiveTv/TunerHosts/QueueStream.cs82
-rw-r--r--Emby.Server.Implementations/Localization/Core/core.json179
-rw-r--r--Emby.Server.Implementations/Localization/Core/en-US.json14
-rw-r--r--Emby.Server.Implementations/Localization/LocalizationManager.cs20
-rw-r--r--Emby.Server.Implementations/Logging/SimpleLogManager.cs13
-rw-r--r--Emby.Server.Implementations/MediaEncoder/EncodingManager.cs9
-rw-r--r--Emby.Server.Implementations/Notifications/CoreNotificationTypes.cs32
-rw-r--r--Emby.Server.Implementations/Notifications/NotificationManager.cs2
-rw-r--r--Emby.Server.Implementations/Notifications/Notifications.cs4
-rw-r--r--Emby.Server.Implementations/Playlists/PlaylistManager.cs4
-rw-r--r--Emby.Server.Implementations/Security/AuthenticationRepository.cs7
-rw-r--r--Emby.Server.Implementations/Services/ServiceController.cs40
-rw-r--r--Emby.Server.Implementations/Services/ServiceHandler.cs8
-rw-r--r--Emby.Server.Implementations/Session/SessionManager.cs123
-rw-r--r--Emby.Server.Implementations/Social/SharingManager.cs8
-rw-r--r--Emby.Server.Implementations/Social/SharingRepository.cs6
-rw-r--r--Emby.Server.Implementations/Sorting/ArtistComparer.cs2
-rw-r--r--Emby.Server.Implementations/TV/TVSeriesManager.cs6
-rw-r--r--Emby.Server.Implementations/Updates/InstallationManager.cs130
-rw-r--r--Emby.Server.Implementations/packages.config2
55 files changed, 903 insertions, 1352 deletions
diff --git a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs
index 702917832..1b6daca73 100644
--- a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs
+++ b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs
@@ -128,7 +128,7 @@ namespace Emby.Server.Implementations.Activity
{
// Don't report theme song or local trailer playback
return;
- }
+ }
if (e.Users.Count == 0)
{
@@ -160,8 +160,8 @@ namespace Emby.Server.Implementations.Activity
{
// Don't report theme song or local trailer playback
return;
- }
-
+ }
+
if (e.Users.Count == 0)
{
return;
@@ -416,7 +416,7 @@ namespace Emby.Server.Implementations.Activity
{
return;
}
-
+
var time = result.EndTimeUtc - result.StartTimeUtc;
var runningTime = string.Format(_localization.GetLocalizedString("LabelRunningTimeValue"), ToUserFriendlyString(time));
@@ -444,11 +444,11 @@ namespace Emby.Server.Implementations.Activity
}
}
- private async void CreateLogEntry(ActivityLogEntry entry)
+ private void CreateLogEntry(ActivityLogEntry entry)
{
try
{
- await _activityManager.Create(entry).ConfigureAwait(false);
+ _activityManager.Create(entry);
}
catch
{
diff --git a/Emby.Server.Implementations/Activity/ActivityManager.cs b/Emby.Server.Implementations/Activity/ActivityManager.cs
index b6095f082..9a3f1ae47 100644
--- a/Emby.Server.Implementations/Activity/ActivityManager.cs
+++ b/Emby.Server.Implementations/Activity/ActivityManager.cs
@@ -13,7 +13,7 @@ namespace Emby.Server.Implementations.Activity
public class ActivityManager : IActivityManager
{
public event EventHandler<GenericEventArgs<ActivityLogEntry>> EntryCreated;
-
+
private readonly IActivityRepository _repo;
private readonly ILogger _logger;
private readonly IUserManager _userManager;
@@ -25,12 +25,12 @@ namespace Emby.Server.Implementations.Activity
_userManager = userManager;
}
- public async Task Create(ActivityLogEntry entry)
+ public void Create(ActivityLogEntry entry)
{
entry.Id = Guid.NewGuid().ToString("N");
entry.Date = DateTime.UtcNow;
- await _repo.Create(entry).ConfigureAwait(false);
+ _repo.Create(entry);
EventHelper.FireEventIfNotNull(EntryCreated, this, new GenericEventArgs<ActivityLogEntry>(entry), _logger);
}
diff --git a/Emby.Server.Implementations/Activity/ActivityRepository.cs b/Emby.Server.Implementations/Activity/ActivityRepository.cs
index 7720f8f2f..3dcc50ba3 100644
--- a/Emby.Server.Implementations/Activity/ActivityRepository.cs
+++ b/Emby.Server.Implementations/Activity/ActivityRepository.cs
@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
-using System.Threading.Tasks;
using Emby.Server.Implementations.Data;
using MediaBrowser.Controller;
using MediaBrowser.Model.Activity;
@@ -41,12 +40,12 @@ namespace Emby.Server.Implementations.Activity
private const string BaseActivitySelectText = "select Id, Name, Overview, ShortOverview, Type, ItemId, UserId, DateCreated, LogSeverity from ActivityLogEntries";
- public Task Create(ActivityLogEntry entry)
+ public void Create(ActivityLogEntry entry)
{
- return Update(entry);
+ Update(entry);
}
- public async Task Update(ActivityLogEntry entry)
+ public void Update(ActivityLogEntry entry)
{
if (entry == null)
{
diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs
index bc88d652c..70ec37a3b 100644
--- a/Emby.Server.Implementations/ApplicationHost.cs
+++ b/Emby.Server.Implementations/ApplicationHost.cs
@@ -227,6 +227,8 @@ namespace Emby.Server.Implementations
protected IEnvironmentInfo EnvironmentInfo { get; set; }
+ private IBlurayExaminer BlurayExaminer { get; set; }
+
public PackageVersionClass SystemUpdateLevel
{
get
@@ -424,11 +426,6 @@ namespace Emby.Server.Implementations
SetBaseExceptionMessage();
- if (environmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Windows)
- {
- fileSystem.AddShortcutHandler(new LnkShortcutHandler());
- }
-
fileSystem.AddShortcutHandler(new MbLinkShortcutHandler(fileSystem));
}
@@ -866,7 +863,7 @@ namespace Emby.Server.Implementations
SecurityManager = new PluginSecurityManager(this, HttpClient, JsonSerializer, ApplicationPaths, LogManager, FileSystemManager, CryptographyProvider);
RegisterSingleInstance(SecurityManager);
- InstallationManager = new InstallationManager(LogManager.GetLogger("InstallationManager"), this, ApplicationPaths, HttpClient, JsonSerializer, SecurityManager, ConfigurationManager, FileSystemManager, CryptographyProvider);
+ InstallationManager = new InstallationManager(LogManager.GetLogger("InstallationManager"), this, ApplicationPaths, HttpClient, JsonSerializer, SecurityManager, ConfigurationManager, FileSystemManager, CryptographyProvider, PackageRuntime);
RegisterSingleInstance(InstallationManager);
ZipClient = new ZipClient(FileSystemManager);
@@ -889,7 +886,8 @@ namespace Emby.Server.Implementations
ITextEncoding textEncoding = new TextEncoding.TextEncoding(FileSystemManager, LogManager.GetLogger("TextEncoding"), JsonSerializer);
RegisterSingleInstance(textEncoding);
Utilities.EncodingHelper = textEncoding;
- RegisterSingleInstance<IBlurayExaminer>(() => new BdInfoExaminer(FileSystemManager, textEncoding));
+ BlurayExaminer = new BdInfoExaminer(FileSystemManager, textEncoding);
+ RegisterSingleInstance(BlurayExaminer);
RegisterSingleInstance<IXmlReaderSettingsFactory>(new XmlReaderSettingsFactory());
@@ -1050,7 +1048,15 @@ namespace Emby.Server.Implementations
SetStaticProperties();
- await ((UserManager)UserManager).Initialize().ConfigureAwait(false);
+ ((UserManager)UserManager).Initialize();
+ }
+
+ protected virtual string PackageRuntime
+ {
+ get
+ {
+ return "netframework";
+ }
}
public static void LogEnvironmentInfo(ILogger logger, IApplicationPaths appPaths, bool isStartup)
@@ -1199,7 +1205,7 @@ namespace Emby.Server.Implementations
private IImageProcessor GetImageProcessor()
{
- return new ImageProcessor(LogManager.GetLogger("ImageProcessor"), ServerConfigurationManager.ApplicationPaths, FileSystemManager, JsonSerializer, ImageEncoder, () => LibraryManager, TimerFactory);
+ return new ImageProcessor(LogManager.GetLogger("ImageProcessor"), ServerConfigurationManager.ApplicationPaths, FileSystemManager, JsonSerializer, ImageEncoder, () => LibraryManager, TimerFactory, () => MediaEncoder);
}
protected virtual FFMpegInstallInfo GetFfmpegInstallInfo()
@@ -1332,7 +1338,8 @@ namespace Emby.Server.Implementations
ProcessFactory,
(Environment.ProcessorCount > 2 ? 14000 : 40000),
EnvironmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Windows,
- EnvironmentInfo);
+ EnvironmentInfo,
+ BlurayExaminer);
MediaEncoder = mediaEncoder;
RegisterSingleInstance(MediaEncoder);
@@ -1858,9 +1865,9 @@ namespace Emby.Server.Implementations
HasPendingRestart = HasPendingRestart,
Version = ApplicationVersion.ToString(),
WebSocketPortNumber = HttpPort,
- FailedPluginAssemblies = FailedAssemblies.ToList(),
- InProgressInstallations = InstallationManager.CurrentInstallations.Select(i => i.Item1).ToList(),
- CompletedInstallations = InstallationManager.CompletedInstallations.ToList(),
+ FailedPluginAssemblies = FailedAssemblies.ToArray(),
+ InProgressInstallations = InstallationManager.CurrentInstallations.Select(i => i.Item1).ToArray(),
+ CompletedInstallations = InstallationManager.CompletedInstallations.ToArray(),
Id = SystemId,
ProgramDataPath = ApplicationPaths.ProgramDataPath,
LogPath = ApplicationPaths.LogDirectoryPath,
diff --git a/Emby.Server.Implementations/Channels/ChannelManager.cs b/Emby.Server.Implementations/Channels/ChannelManager.cs
index e41e0ea87..fcc637b25 100644
--- a/Emby.Server.Implementations/Channels/ChannelManager.cs
+++ b/Emby.Server.Implementations/Channels/ChannelManager.cs
@@ -182,10 +182,8 @@ namespace Emby.Server.Implementations.Channels
{
};
- var returnList = (await _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user)
+ var returnItems = (await _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user)
.ConfigureAwait(false));
- var returnItems = returnList
- .ToArray(returnList.Count);
var result = new QueryResult<BaseItemDto>
{
@@ -431,7 +429,7 @@ namespace Emby.Server.Implementations.Channels
if (isNew)
{
- await _libraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false);
+ _libraryManager.CreateItem(item, cancellationToken);
}
else if (forceUpdate)
{
@@ -464,14 +462,14 @@ namespace Emby.Server.Implementations.Channels
return _libraryManager.GetItemById(id) as Channel;
}
- public IEnumerable<ChannelFeatures> GetAllChannelFeatures()
+ public ChannelFeatures[] GetAllChannelFeatures()
{
return _libraryManager.GetItemIds(new InternalItemsQuery
{
IncludeItemTypes = new[] { typeof(Channel).Name },
SortBy = new[] { ItemSortBy.SortName }
- }).Select(i => GetChannelFeatures(i.ToString("N")));
+ }).Select(i => GetChannelFeatures(i.ToString("N"))).ToArray();
}
public ChannelFeatures GetChannelFeatures(string id)
@@ -511,10 +509,10 @@ namespace Emby.Server.Implementations.Channels
{
CanFilter = !features.MaxPageSize.HasValue,
CanSearch = provider is ISearchableChannel,
- ContentTypes = features.ContentTypes,
- DefaultSortFields = features.DefaultSortFields,
+ ContentTypes = features.ContentTypes.ToArray(),
+ DefaultSortFields = features.DefaultSortFields.ToArray(),
MaxPageSize = features.MaxPageSize,
- MediaTypes = features.MediaTypes,
+ MediaTypes = features.MediaTypes.ToArray(),
SupportsSortOrderToggle = features.SupportsSortOrderToggle,
SupportsLatestMedia = supportsLatest,
Name = channel.Name,
@@ -566,12 +564,10 @@ namespace Emby.Server.Implementations.Channels
var dtoOptions = new DtoOptions()
{
- Fields = query.Fields.ToList()
+ Fields = query.Fields
};
- var returnList = (await _dtoService.GetBaseItemDtos(items, dtoOptions, user).ConfigureAwait(false));
- var returnItems = returnList
- .ToArray(returnList.Count);
+ var returnItems = (await _dtoService.GetBaseItemDtos(items, dtoOptions, user).ConfigureAwait(false));
var result = new QueryResult<BaseItemDto>
{
@@ -833,13 +829,11 @@ namespace Emby.Server.Implementations.Channels
var dtoOptions = new DtoOptions()
{
- Fields = query.Fields.ToList()
+ Fields = query.Fields
};
- var returnList = (await _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user)
+ var returnItems = (await _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user)
.ConfigureAwait(false));
- var returnItems = returnList
- .ToArray(returnList.Count);
var result = new QueryResult<BaseItemDto>
{
@@ -987,13 +981,11 @@ namespace Emby.Server.Implementations.Channels
var dtoOptions = new DtoOptions()
{
- Fields = query.Fields.ToList()
+ Fields = query.Fields
};
- var returnList = (await _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user)
+ var returnItems = (await _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user)
.ConfigureAwait(false));
- var returnItems = returnList
- .ToArray(returnList.Count);
var result = new QueryResult<BaseItemDto>
{
@@ -1338,7 +1330,7 @@ namespace Emby.Server.Implementations.Channels
var hasArtists = item as IHasArtist;
if (hasArtists != null)
{
- hasArtists.Artists = info.Artists;
+ hasArtists.Artists = info.Artists.ToArray();
}
var hasAlbumArtists = item as IHasAlbumArtist;
@@ -1396,11 +1388,11 @@ namespace Emby.Server.Implementations.Channels
if (isNew)
{
- await _libraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false);
+ _libraryManager.CreateItem(item, cancellationToken);
if (info.People != null && info.People.Count > 0)
{
- await _libraryManager.UpdatePeople(item, info.People ?? new List<PersonInfo>()).ConfigureAwait(false);
+ _libraryManager.UpdatePeople(item, info.People ?? new List<PersonInfo>());
}
}
else if (forceUpdate)
diff --git a/Emby.Server.Implementations/Collections/CollectionManager.cs b/Emby.Server.Implementations/Collections/CollectionManager.cs
index 5b168f6cc..2e884e729 100644
--- a/Emby.Server.Implementations/Collections/CollectionManager.cs
+++ b/Emby.Server.Implementations/Collections/CollectionManager.cs
@@ -84,15 +84,15 @@ namespace Emby.Server.Implementations.Collections
ProviderIds = options.ProviderIds,
Shares = options.UserIds.Select(i => new Share
{
- UserId = i.ToString("N"),
+ UserId = i,
CanEdit = true
}).ToList()
};
- await parentFolder.AddChild(collection, CancellationToken.None).ConfigureAwait(false);
+ parentFolder.AddChild(collection, CancellationToken.None);
- if (options.ItemIdList.Count > 0)
+ if (options.ItemIdList.Length > 0)
{
await AddToCollection(collection.Id, options.ItemIdList, false, new MetadataRefreshOptions(_fileSystem)
{
@@ -149,12 +149,17 @@ namespace Emby.Server.Implementations.Collections
return GetCollectionsFolder(string.Empty);
}
- public Task AddToCollection(Guid collectionId, IEnumerable<Guid> ids)
+ public Task AddToCollection(Guid collectionId, IEnumerable<string> ids)
{
return AddToCollection(collectionId, ids, true, new MetadataRefreshOptions(_fileSystem));
}
- private async Task AddToCollection(Guid collectionId, IEnumerable<Guid> ids, bool fireEvent, MetadataRefreshOptions refreshOptions)
+ public Task AddToCollection(Guid collectionId, IEnumerable<Guid> ids)
+ {
+ return AddToCollection(collectionId, ids.Select(i => i.ToString("N")), true, new MetadataRefreshOptions(_fileSystem));
+ }
+
+ private async Task AddToCollection(Guid collectionId, IEnumerable<string> ids, bool fireEvent, MetadataRefreshOptions refreshOptions)
{
var collection = _libraryManager.GetItemById(collectionId) as BoxSet;
@@ -165,11 +170,12 @@ namespace Emby.Server.Implementations.Collections
var list = new List<LinkedChild>();
var itemList = new List<BaseItem>();
- var currentLinkedChildren = collection.GetLinkedChildren().ToList();
+ var currentLinkedChildrenIds = collection.GetLinkedChildren().Select(i => i.Id).ToList();
- foreach (var itemId in ids)
+ foreach (var id in ids)
{
- var item = _libraryManager.GetItemById(itemId);
+ var guidId = new Guid(id);
+ var item = _libraryManager.GetItemById(guidId);
if (string.IsNullOrWhiteSpace(item.Path))
{
@@ -183,7 +189,7 @@ namespace Emby.Server.Implementations.Collections
itemList.Add(item);
- if (currentLinkedChildren.All(i => i.Id != itemId))
+ if (!currentLinkedChildrenIds.Contains(guidId))
{
list.Add(LinkedChild.Create(item));
}
@@ -213,6 +219,11 @@ namespace Emby.Server.Implementations.Collections
}
}
+ public Task RemoveFromCollection(Guid collectionId, IEnumerable<string> itemIds)
+ {
+ return RemoveFromCollection(collectionId, itemIds.Select(i => new Guid(i)));
+ }
+
public async Task RemoveFromCollection(Guid collectionId, IEnumerable<Guid> itemIds)
{
var collection = _libraryManager.GetItemById(collectionId) as BoxSet;
@@ -225,11 +236,11 @@ namespace Emby.Server.Implementations.Collections
var list = new List<LinkedChild>();
var itemList = new List<BaseItem>();
- foreach (var itemId in itemIds)
+ foreach (var guidId in itemIds)
{
- var childItem = _libraryManager.GetItemById(itemId);
+ var childItem = _libraryManager.GetItemById(guidId);
- var child = collection.LinkedChildren.FirstOrDefault(i => (i.ItemId.HasValue && i.ItemId.Value == itemId) || (childItem != null && string.Equals(childItem.Path, i.Path, StringComparison.OrdinalIgnoreCase)));
+ var child = collection.LinkedChildren.FirstOrDefault(i => (i.ItemId.HasValue && i.ItemId.Value == guidId) || (childItem != null && string.Equals(childItem.Path, i.Path, StringComparison.OrdinalIgnoreCase)));
if (child == null)
{
diff --git a/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs b/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs
index 4118bd1b2..89664d158 100644
--- a/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs
+++ b/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs
@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.IO;
using System.Threading;
-using System.Threading.Tasks;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Persistence;
@@ -75,7 +74,7 @@ namespace Emby.Server.Implementations.Data
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
/// <exception cref="System.ArgumentNullException">item</exception>
- public async Task SaveDisplayPreferences(DisplayPreferences displayPreferences, Guid userId, string client, CancellationToken cancellationToken)
+ public void SaveDisplayPreferences(DisplayPreferences displayPreferences, Guid userId, string client, CancellationToken cancellationToken)
{
if (displayPreferences == null)
{
@@ -123,7 +122,7 @@ namespace Emby.Server.Implementations.Data
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
/// <exception cref="System.ArgumentNullException">item</exception>
- public async Task SaveAllDisplayPreferences(IEnumerable<DisplayPreferences> displayPreferences, Guid userId, CancellationToken cancellationToken)
+ public void SaveAllDisplayPreferences(IEnumerable<DisplayPreferences> displayPreferences, Guid userId, CancellationToken cancellationToken)
{
if (displayPreferences == null)
{
@@ -226,9 +225,9 @@ namespace Emby.Server.Implementations.Data
}
}
- public Task SaveDisplayPreferences(DisplayPreferences displayPreferences, string userId, string client, CancellationToken cancellationToken)
+ public void SaveDisplayPreferences(DisplayPreferences displayPreferences, string userId, string client, CancellationToken cancellationToken)
{
- return SaveDisplayPreferences(displayPreferences, new Guid(userId), client, cancellationToken);
+ SaveDisplayPreferences(displayPreferences, new Guid(userId), client, cancellationToken);
}
public DisplayPreferences GetDisplayPreferences(string displayPreferencesId, string userId, string client)
diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
index 6743e96fd..74e009bd9 100644
--- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs
+++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
@@ -132,8 +132,7 @@ namespace Emby.Server.Implementations.Data
/// <summary>
/// Opens the connection to the database
/// </summary>
- /// <returns>Task.</returns>
- public async Task Initialize(SqliteUserDataRepository userDataRepo)
+ public void Initialize(SqliteUserDataRepository userDataRepo)
{
using (var connection = CreateConnection())
{
@@ -149,7 +148,7 @@ namespace Emby.Server.Implementations.Data
"create table if not exists AncestorIds (ItemId GUID, AncestorId GUID, AncestorIdText TEXT, PRIMARY KEY (ItemId, AncestorId))",
"create index if not exists idx_AncestorIds1 on AncestorIds(AncestorId)",
- "create index if not exists idx_AncestorIds2 on AncestorIds(AncestorIdText)",
+ "create index if not exists idx_AncestorIds5 on AncestorIds(AncestorIdText,ItemId)",
"create table if not exists ItemValues (ItemId GUID, Type INT, Value TEXT, CleanValue TEXT)",
@@ -308,6 +307,7 @@ namespace Emby.Server.Implementations.Data
"drop index if exists idx_TypeSeriesPresentationUniqueKey2",
"drop index if exists idx_AncestorIds3",
"drop index if exists idx_AncestorIds4",
+ "drop index if exists idx_AncestorIds2",
"create index if not exists idx_PathTypedBaseItems on TypedBaseItems(Path)",
"create index if not exists idx_ParentIdTypedBaseItems on TypedBaseItems(ParentId)",
@@ -599,16 +599,15 @@ namespace Emby.Server.Implementations.Data
/// </summary>
/// <param name="item">The item.</param>
/// <param name="cancellationToken">The cancellation token.</param>
- /// <returns>Task.</returns>
/// <exception cref="System.ArgumentNullException">item</exception>
- public Task SaveItem(BaseItem item, CancellationToken cancellationToken)
+ public void SaveItem(BaseItem item, CancellationToken cancellationToken)
{
if (item == null)
{
throw new ArgumentNullException("item");
}
- return SaveItems(new List<BaseItem> { item }, cancellationToken);
+ SaveItems(new List<BaseItem> { item }, cancellationToken);
}
/// <summary>
@@ -616,13 +615,12 @@ namespace Emby.Server.Implementations.Data
/// </summary>
/// <param name="items">The items.</param>
/// <param name="cancellationToken">The cancellation token.</param>
- /// <returns>Task.</returns>
/// <exception cref="System.ArgumentNullException">
/// items
/// or
/// cancellationToken
/// </exception>
- public async Task SaveItems(List<BaseItem> items, CancellationToken cancellationToken)
+ public void SaveItems(List<BaseItem> items, CancellationToken cancellationToken)
{
if (items == null)
{
@@ -1027,9 +1025,9 @@ namespace Emby.Server.Implementations.Data
var hasArtists = item as IHasArtist;
if (hasArtists != null)
{
- if (hasArtists.Artists.Count > 0)
+ if (hasArtists.Artists.Length > 0)
{
- artists = string.Join("|", hasArtists.Artists.ToArray());
+ artists = string.Join("|", hasArtists.Artists);
}
}
saveItemStatement.TryBind("@Artists", artists);
@@ -1907,7 +1905,7 @@ namespace Emby.Server.Implementations.Data
var hasArtists = item as IHasArtist;
if (hasArtists != null && !reader.IsDBNull(index))
{
- hasArtists.Artists = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).ToList();
+ hasArtists.Artists = reader.GetString(index).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
}
index++;
@@ -1958,22 +1956,18 @@ namespace Emby.Server.Implementations.Data
/// Gets the critic reviews.
/// </summary>
/// <param name="itemId">The item id.</param>
- /// <returns>Task{IEnumerable{ItemReview}}.</returns>
public List<ItemReview> GetCriticReviews(Guid itemId)
{
return new List<ItemReview>();
}
- private readonly Task _cachedTask = Task.FromResult(true);
/// <summary>
/// Saves the critic reviews.
/// </summary>
/// <param name="itemId">The item id.</param>
/// <param name="criticReviews">The critic reviews.</param>
- /// <returns>Task.</returns>
- public Task SaveCriticReviews(Guid itemId, IEnumerable<ItemReview> criticReviews)
+ public void SaveCriticReviews(Guid itemId, IEnumerable<ItemReview> criticReviews)
{
- return _cachedTask;
}
/// <summary>
@@ -2078,7 +2072,7 @@ namespace Emby.Server.Implementations.Data
/// <summary>
/// Saves the chapters.
/// </summary>
- public async Task SaveChapters(Guid id, List<ChapterInfo> chapters)
+ public void SaveChapters(Guid id, List<ChapterInfo> chapters)
{
CheckDisposed();
@@ -4653,12 +4647,12 @@ namespace Emby.Server.Implementations.Data
typeof(AggregateFolder)
};
- public async Task UpdateInheritedValues(CancellationToken cancellationToken)
+ public void UpdateInheritedValues(CancellationToken cancellationToken)
{
- await UpdateInheritedTags(cancellationToken).ConfigureAwait(false);
+ UpdateInheritedTags(cancellationToken);
}
- private async Task UpdateInheritedTags(CancellationToken cancellationToken)
+ private void UpdateInheritedTags(CancellationToken cancellationToken)
{
var newValues = new List<Tuple<Guid, string[]>>();
@@ -4753,7 +4747,7 @@ limit 100";
return new[] { value }.Where(IsValidType);
}
- public async Task DeleteItem(Guid id, CancellationToken cancellationToken)
+ public void DeleteItem(Guid id, CancellationToken cancellationToken)
{
if (id == Guid.Empty)
{
@@ -5484,7 +5478,7 @@ limit 100";
}
}
- public async Task UpdatePeople(Guid itemId, List<PersonInfo> people)
+ public void UpdatePeople(Guid itemId, List<PersonInfo> people)
{
if (itemId == Guid.Empty)
{
@@ -5614,7 +5608,7 @@ limit 100";
}
}
- public async Task SaveMediaStreams(Guid id, List<MediaStream> streams, CancellationToken cancellationToken)
+ public void SaveMediaStreams(Guid id, List<MediaStream> streams, CancellationToken cancellationToken)
{
CheckDisposed();
diff --git a/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs b/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs
index bf6388f5d..ef1d7ba44 100644
--- a/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs
+++ b/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs
@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
-using System.Threading.Tasks;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Persistence;
@@ -153,7 +152,7 @@ namespace Emby.Server.Implementations.Data
/// userId
/// or
/// userDataId</exception>
- public Task SaveUserData(Guid userId, string key, UserItemData userData, CancellationToken cancellationToken)
+ public void SaveUserData(Guid userId, string key, UserItemData userData, CancellationToken cancellationToken)
{
if (userData == null)
{
@@ -168,10 +167,10 @@ namespace Emby.Server.Implementations.Data
throw new ArgumentNullException("key");
}
- return PersistUserData(userId, key, userData, cancellationToken);
+ PersistUserData(userId, key, userData, cancellationToken);
}
- public Task SaveAllUserData(Guid userId, IEnumerable<UserItemData> userData, CancellationToken cancellationToken)
+ public void SaveAllUserData(Guid userId, UserItemData[] userData, CancellationToken cancellationToken)
{
if (userData == null)
{
@@ -182,7 +181,7 @@ namespace Emby.Server.Implementations.Data
throw new ArgumentNullException("userId");
}
- return PersistAllUserData(userId, userData.ToList(), cancellationToken);
+ PersistAllUserData(userId, userData, cancellationToken);
}
/// <summary>
@@ -193,7 +192,7 @@ namespace Emby.Server.Implementations.Data
/// <param name="userData">The user data.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
- public async Task PersistUserData(Guid userId, string key, UserItemData userData, CancellationToken cancellationToken)
+ public void PersistUserData(Guid userId, string key, UserItemData userData, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
@@ -264,7 +263,7 @@ namespace Emby.Server.Implementations.Data
/// <summary>
/// Persist all user data for the specified user
/// </summary>
- private async Task PersistAllUserData(Guid userId, List<UserItemData> userDataList, CancellationToken cancellationToken)
+ private void PersistAllUserData(Guid userId, UserItemData[] userDataList, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
@@ -349,7 +348,7 @@ namespace Emby.Server.Implementations.Data
/// </summary>
/// <param name="userId"></param>
/// <returns></returns>
- public IEnumerable<UserItemData> GetAllUserData(Guid userId)
+ public List<UserItemData> GetAllUserData(Guid userId)
{
if (userId == Guid.Empty)
{
diff --git a/Emby.Server.Implementations/Data/SqliteUserRepository.cs b/Emby.Server.Implementations/Data/SqliteUserRepository.cs
index 29959bcab..b65996e40 100644
--- a/Emby.Server.Implementations/Data/SqliteUserRepository.cs
+++ b/Emby.Server.Implementations/Data/SqliteUserRepository.cs
@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.IO;
using System.Threading;
-using System.Threading.Tasks;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Persistence;
@@ -72,7 +71,7 @@ namespace Emby.Server.Implementations.Data
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
/// <exception cref="System.ArgumentNullException">user</exception>
- public async Task SaveUser(User user, CancellationToken cancellationToken)
+ public void SaveUser(User user, CancellationToken cancellationToken)
{
if (user == null)
{
@@ -139,7 +138,7 @@ namespace Emby.Server.Implementations.Data
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
/// <exception cref="System.ArgumentNullException">user</exception>
- public async Task DeleteUser(User user, CancellationToken cancellationToken)
+ public void DeleteUser(User user, CancellationToken cancellationToken)
{
if (user == null)
{
diff --git a/Emby.Server.Implementations/Devices/DeviceRepository.cs b/Emby.Server.Implementations/Devices/DeviceRepository.cs
index de0dfda2e..b286a3bb0 100644
--- a/Emby.Server.Implementations/Devices/DeviceRepository.cs
+++ b/Emby.Server.Implementations/Devices/DeviceRepository.cs
@@ -11,6 +11,7 @@ using MediaBrowser.Model.IO;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Session;
+using MediaBrowser.Model.Extensions;
namespace Emby.Server.Implementations.Devices
{
@@ -199,7 +200,10 @@ namespace Emby.Server.Implementations.Devices
}
history.DeviceId = deviceId;
- history.FilesUploaded.Add(file);
+
+ var list = history.FilesUploaded.ToList();
+ list.Add(file);
+ history.FilesUploaded = list.ToArray(list.Count);
_json.SerializeToFile(history, path);
}
diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs
index c49c318ee..a0e994d88 100644
--- a/Emby.Server.Implementations/Dto/DtoService.cs
+++ b/Emby.Server.Implementations/Dto/DtoService.cs
@@ -77,7 +77,7 @@ namespace Emby.Server.Implementations.Dto
/// <param name="owner">The owner.</param>
/// <returns>Task{DtoBaseItem}.</returns>
/// <exception cref="System.ArgumentNullException">item</exception>
- public BaseItemDto GetBaseItemDto(BaseItem item, List<ItemFields> fields, User user = null, BaseItem owner = null)
+ public BaseItemDto GetBaseItemDto(BaseItem item, ItemFields[] fields, User user = null, BaseItem owner = null)
{
var options = new DtoOptions
{
@@ -87,7 +87,17 @@ namespace Emby.Server.Implementations.Dto
return GetBaseItemDto(item, options, user, owner);
}
- public async Task<List<BaseItemDto>> GetBaseItemDtos(IEnumerable<BaseItem> items, DtoOptions options, User user = null, BaseItem owner = null)
+ public Task<BaseItemDto[]> GetBaseItemDtos(List<BaseItem> items, DtoOptions options, User user = null, BaseItem owner = null)
+ {
+ return GetBaseItemDtos(items, items.Count, options, user, owner);
+ }
+
+ public Task<BaseItemDto[]> GetBaseItemDtos(BaseItem[] items, DtoOptions options, User user = null, BaseItem owner = null)
+ {
+ return GetBaseItemDtos(items, items.Length, options, user, owner);
+ }
+
+ public async Task<BaseItemDto[]> GetBaseItemDtos(IEnumerable<BaseItem> items, int itemCount, DtoOptions options, User user = null, BaseItem owner = null)
{
if (items == null)
{
@@ -101,17 +111,14 @@ namespace Emby.Server.Implementations.Dto
var syncDictionary = GetSyncedItemProgress(options);
- var list = new List<BaseItemDto>();
+ var returnItems = new BaseItemDto[itemCount];
var programTuples = new List<Tuple<BaseItem, BaseItemDto>>();
var channelTuples = new List<Tuple<BaseItemDto, LiveTvChannel>>();
- var refreshQueue = options.Fields.Contains(ItemFields.RefreshState)
- ? _providerManager.GetRefreshQueue()
- : null;
-
+ var index = 0;
foreach (var item in items)
{
- var dto = GetBaseItemDtoInternal(item, options, refreshQueue, user, owner);
+ var dto = GetBaseItemDtoInternal(item, options, user, owner);
var tvChannel = item as LiveTvChannel;
if (tvChannel != null)
@@ -144,7 +151,8 @@ namespace Emby.Server.Implementations.Dto
FillSyncInfo(dto, item, options, user, syncDictionary);
- list.Add(dto);
+ returnItems[index] = dto;
+ index++;
}
if (programTuples.Count > 0)
@@ -157,18 +165,14 @@ namespace Emby.Server.Implementations.Dto
await _livetvManager().AddChannelInfo(channelTuples, options, user).ConfigureAwait(false);
}
- return list;
+ return returnItems;
}
public BaseItemDto GetBaseItemDto(BaseItem item, DtoOptions options, User user = null, BaseItem owner = null)
{
var syncDictionary = GetSyncedItemProgress(options);
- var refreshQueue = options.Fields.Contains(ItemFields.RefreshState)
- ? _providerManager.GetRefreshQueue()
- : null;
-
- var dto = GetBaseItemDtoInternal(item, options, refreshQueue, user, owner);
+ var dto = GetBaseItemDtoInternal(item, options, user, owner);
var tvChannel = item as LiveTvChannel;
if (tvChannel != null)
{
@@ -300,7 +304,7 @@ namespace Emby.Server.Implementations.Dto
}
}
- private BaseItemDto GetBaseItemDtoInternal(BaseItem item, DtoOptions options, Dictionary<Guid, Guid> currentRefreshQueue, User user = null, BaseItem owner = null)
+ private BaseItemDto GetBaseItemDtoInternal(BaseItem item, DtoOptions options, User user = null, BaseItem owner = null)
{
var fields = options.Fields;
@@ -365,6 +369,8 @@ namespace Emby.Server.Implementations.Dto
{
dto.MediaSources = _mediaSourceManager().GetStaticMediaSources(hasMediaSources, true, user);
}
+
+ NormalizeMediaSourceContainers(dto);
}
}
@@ -400,25 +406,72 @@ namespace Emby.Server.Implementations.Dto
dto.Etag = item.GetEtag(user);
}
- if (currentRefreshQueue != null)
+ var liveTvManager = _livetvManager();
+ if (item is ILiveTvRecording)
{
- //dto.RefreshState = item.GetRefreshState(currentRefreshQueue);
+ liveTvManager.AddInfoToRecordingDto(item, dto, user);
}
-
- if (item is ILiveTvRecording)
+ else
{
- _livetvManager().AddInfoToRecordingDto(item, dto, user);
+ var activeRecording = liveTvManager.GetActiveRecordingInfo(item.Path);
+ if (activeRecording != null)
+ {
+ dto.Type = "Recording";
+ dto.CanDownload = false;
+ if (!string.IsNullOrWhiteSpace(dto.SeriesName))
+ {
+ dto.EpisodeTitle = dto.Name;
+ dto.Name = dto.SeriesName;
+ }
+ liveTvManager.AddInfoToRecordingDto(item, dto, activeRecording, user);
+ }
}
return dto;
}
+ private void NormalizeMediaSourceContainers(BaseItemDto dto)
+ {
+ foreach (var mediaSource in dto.MediaSources)
+ {
+ var container = mediaSource.Container;
+ if (string.IsNullOrWhiteSpace(container))
+ {
+ continue;
+ }
+ var containers = container.Split(new[] { ',' });
+ if (containers.Length < 2)
+ {
+ continue;
+ }
+
+ var path = mediaSource.Path;
+ string fileExtensionContainer = null;
+
+ if (!string.IsNullOrWhiteSpace(path))
+ {
+ path = Path.GetExtension(path);
+ if (!string.IsNullOrWhiteSpace(path))
+ {
+ path = Path.GetExtension(path);
+ if (!string.IsNullOrWhiteSpace(path))
+ {
+ path = path.TrimStart('.');
+ }
+ if (!string.IsNullOrWhiteSpace(path) && containers.Contains(path, StringComparer.OrdinalIgnoreCase))
+ {
+ fileExtensionContainer = path;
+ }
+ }
+ }
+
+ mediaSource.Container = fileExtensionContainer ?? containers[0];
+ }
+ }
+
public BaseItemDto GetItemByNameDto(BaseItem item, DtoOptions options, List<BaseItem> taggedItems, Dictionary<string, SyncedItemProgress> syncProgress, User user = null)
{
- var refreshQueue = options.Fields.Contains(ItemFields.RefreshState)
- ? _providerManager.GetRefreshQueue()
- : null;
- var dto = GetBaseItemDtoInternal(item, options, refreshQueue, user);
+ var dto = GetBaseItemDtoInternal(item, options, user);
if (taggedItems != null && options.Fields.Contains(ItemFields.ItemCounts))
{
@@ -992,7 +1045,7 @@ namespace Emby.Server.Implementations.Dto
{
dto.RemoteTrailers = hasTrailers != null ?
hasTrailers.RemoteTrailers :
- new MediaUrl[] {};
+ new MediaUrl[] { };
}
dto.Name = item.Name;
@@ -1053,7 +1106,7 @@ namespace Emby.Server.Implementations.Dto
if (dto.Taglines == null)
{
- dto.Taglines = new string[]{};
+ dto.Taglines = new string[] { };
}
}
@@ -1243,17 +1296,17 @@ namespace Emby.Server.Implementations.Dto
if (iHasMediaSources != null)
{
- List<MediaStream> mediaStreams;
+ MediaStream[] mediaStreams;
if (dto.MediaSources != null && dto.MediaSources.Count > 0)
{
mediaStreams = dto.MediaSources.Where(i => new Guid(i.Id) == item.Id)
.SelectMany(i => i.MediaStreams)
- .ToList();
+ .ToArray();
}
else
{
- mediaStreams = _mediaSourceManager().GetStaticMediaSources(iHasMediaSources, true).First().MediaStreams;
+ mediaStreams = _mediaSourceManager().GetStaticMediaSources(iHasMediaSources, true).First().MediaStreams.ToArray();
}
dto.MediaStreams = mediaStreams;
@@ -1564,7 +1617,7 @@ namespace Emby.Server.Implementations.Dto
return null;
}
- var supportedEnhancers = _imageProcessor.GetSupportedEnhancers(item, ImageType.Primary).ToList();
+ var supportedEnhancers = _imageProcessor.GetSupportedEnhancers(item, ImageType.Primary);
ImageSize size;
diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj
index 1e897016e..84ec214c9 100644
--- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj
+++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj
@@ -133,7 +133,6 @@
<Compile Include="IO\FileRefresher.cs" />
<Compile Include="IO\IsoManager.cs" />
<Compile Include="IO\LibraryMonitor.cs" />
- <Compile Include="IO\LnkShortcutHandler.cs" />
<Compile Include="IO\ManagedFileSystem.cs" />
<Compile Include="IO\MbLinkShortcutHandler.cs" />
<Compile Include="IO\MemoryStreamProvider.cs" />
@@ -662,8 +661,9 @@
<Reference Include="Emby.XmlTv, Version=1.0.6387.29335, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Emby.XmlTv.1.0.10\lib\portable-net45+netstandard2.0+win8\Emby.XmlTv.dll</HintPath>
</Reference>
- <Reference Include="MediaBrowser.Naming, Version=1.0.6437.24226, Culture=neutral, processorArchitecture=MSIL">
- <HintPath>..\packages\MediaBrowser.Naming.1.0.6\lib\portable-net45+netstandard2.0+win8\MediaBrowser.Naming.dll</HintPath>
+ <Reference Include="MediaBrowser.Naming, Version=1.0.6447.2217, Culture=neutral, processorArchitecture=MSIL">
+ <HintPath>..\packages\MediaBrowser.Naming.1.0.7\lib\portable-net45+netstandard2.0+win8\MediaBrowser.Naming.dll</HintPath>
+ <Private>True</Private>
</Reference>
<Reference Include="ServiceStack.Text, Version=4.5.8.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ServiceStack.Text.4.5.8\lib\net45\ServiceStack.Text.dll</HintPath>
@@ -699,7 +699,6 @@
<EmbeddedResource Include="Localization\Core\ar.json" />
<EmbeddedResource Include="Localization\Core\bg-BG.json" />
<EmbeddedResource Include="Localization\Core\ca.json" />
- <EmbeddedResource Include="Localization\Core\core.json" />
<EmbeddedResource Include="Localization\Core\cs.json" />
<EmbeddedResource Include="Localization\Core\da.json" />
<EmbeddedResource Include="Localization\Core\de.json" />
diff --git a/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs b/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs
index 69a205dda..80a188bc0 100644
--- a/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs
+++ b/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs
@@ -367,15 +367,15 @@ namespace Emby.Server.Implementations.EntryPoints
return new LibraryUpdateInfo
{
- ItemsAdded = itemsAdded.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToList(),
+ ItemsAdded = itemsAdded.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToArray(),
- ItemsUpdated = itemsUpdated.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToList(),
+ ItemsUpdated = itemsUpdated.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToArray(),
- ItemsRemoved = itemsRemoved.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user, true)).Select(i => i.Id.ToString("N")).Distinct().ToList(),
+ ItemsRemoved = itemsRemoved.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user, true)).Select(i => i.Id.ToString("N")).Distinct().ToArray(),
- FoldersAddedTo = foldersAddedTo.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToList(),
+ FoldersAddedTo = foldersAddedTo.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToArray(),
- FoldersRemovedFrom = foldersRemovedFrom.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToList()
+ FoldersRemovedFrom = foldersRemovedFrom.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToArray()
};
}
diff --git a/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs b/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs
index 71e31d4d4..accdc5e9d 100644
--- a/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs
+++ b/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs
@@ -126,7 +126,7 @@ namespace Emby.Server.Implementations.EntryPoints
dto.ItemId = i.Id.ToString("N");
return dto;
})
- .ToList();
+ .ToArray();
var info = new UserDataChangeInfo
{
diff --git a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
index f150e4785..f1fea2085 100644
--- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
+++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
@@ -162,7 +162,7 @@ namespace Emby.Server.Implementations.HttpServer
return serviceType;
}
- public void AddServiceInfo(Type serviceType, Type requestType, Type responseType)
+ public void AddServiceInfo(Type serviceType, Type requestType)
{
ServiceOperationsMap[requestType] = serviceType;
}
diff --git a/Emby.Server.Implementations/IO/LibraryMonitor.cs b/Emby.Server.Implementations/IO/LibraryMonitor.cs
index c452c01be..3994e2b00 100644
--- a/Emby.Server.Implementations/IO/LibraryMonitor.cs
+++ b/Emby.Server.Implementations/IO/LibraryMonitor.cs
@@ -35,7 +35,7 @@ namespace Emby.Server.Implementations.IO
/// <summary>
/// Any file name ending in any of these will be ignored by the watchers
/// </summary>
- private readonly IReadOnlyList<string> _alwaysIgnoreFiles = new List<string>
+ private readonly string[] _alwaysIgnoreFiles = new string[]
{
"small.jpg",
"albumart.jpg",
@@ -45,7 +45,7 @@ namespace Emby.Server.Implementations.IO
"TempSBE"
};
- private readonly IReadOnlyList<string> _alwaysIgnoreSubstrings = new List<string>
+ private readonly string[] _alwaysIgnoreSubstrings = new string[]
{
// Synology
"eaDir",
@@ -54,7 +54,7 @@ namespace Emby.Server.Implementations.IO
".actors"
};
- private readonly IReadOnlyList<string> _alwaysIgnoreExtensions = new List<string>
+ private readonly string[] _alwaysIgnoreExtensions = new string[]
{
// thumbs.db
".db",
@@ -85,6 +85,8 @@ namespace Emby.Server.Implementations.IO
public bool IsPathLocked(string path)
{
+ // This method is not used by the core but it used by auto-organize
+
var lockedPaths = _tempIgnoredPaths.Keys.ToList();
return lockedPaths.Any(i => _fileSystem.AreEqual(i, path) || _fileSystem.ContainsSubPath(i, path));
}
diff --git a/Emby.Server.Implementations/IO/LnkShortcutHandler.cs b/Emby.Server.Implementations/IO/LnkShortcutHandler.cs
deleted file mode 100644
index 093d57aa4..000000000
--- a/Emby.Server.Implementations/IO/LnkShortcutHandler.cs
+++ /dev/null
@@ -1,332 +0,0 @@
-using System;
-using System.IO;
-using System.Runtime.InteropServices;
-using System.Runtime.InteropServices.ComTypes;
-using System.Text;
-using MediaBrowser.Model.IO;
-
-namespace Emby.Server.Implementations.IO
-{
- public class LnkShortcutHandler :IShortcutHandler
- {
- public string Extension
- {
- get { return ".lnk"; }
- }
-
- public string Resolve(string shortcutPath)
- {
- var link = new ShellLink();
- ((IPersistFile)link).Load(shortcutPath, NativeMethods.STGM_READ);
- // ((IShellLinkW)link).Resolve(hwnd, 0)
- var sb = new StringBuilder(NativeMethods.MAX_PATH);
- WIN32_FIND_DATA data;
- ((IShellLinkW)link).GetPath(sb, sb.Capacity, out data, 0);
- return sb.ToString();
- }
-
- public void Create(string shortcutPath, string targetPath)
- {
- throw new NotImplementedException();
- }
- }
-
- /// <summary>
- /// Class NativeMethods
- /// </summary>
- public static class NativeMethods
- {
- /// <summary>
- /// The MA x_ PATH
- /// </summary>
- public const int MAX_PATH = 260;
- /// <summary>
- /// The MA x_ ALTERNATE
- /// </summary>
- public const int MAX_ALTERNATE = 14;
- /// <summary>
- /// The INVALI d_ HANDL e_ VALUE
- /// </summary>
- public static IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
- /// <summary>
- /// The STG m_ READ
- /// </summary>
- public const int STGM_READ = 0;
- }
-
- /// <summary>
- /// Struct FILETIME
- /// </summary>
- [StructLayout(LayoutKind.Sequential)]
- public struct FILETIME
- {
- /// <summary>
- /// The dw low date time
- /// </summary>
- public uint dwLowDateTime;
- /// <summary>
- /// The dw high date time
- /// </summary>
- public uint dwHighDateTime;
- }
-
- /// <summary>
- /// Struct WIN32_FIND_DATA
- /// </summary>
- [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
- public struct WIN32_FIND_DATA
- {
- /// <summary>
- /// The dw file attributes
- /// </summary>
- public FileAttributes dwFileAttributes;
- /// <summary>
- /// The ft creation time
- /// </summary>
- public FILETIME ftCreationTime;
- /// <summary>
- /// The ft last access time
- /// </summary>
- public FILETIME ftLastAccessTime;
- /// <summary>
- /// The ft last write time
- /// </summary>
- public FILETIME ftLastWriteTime;
- /// <summary>
- /// The n file size high
- /// </summary>
- public int nFileSizeHigh;
- /// <summary>
- /// The n file size low
- /// </summary>
- public int nFileSizeLow;
- /// <summary>
- /// The dw reserved0
- /// </summary>
- public int dwReserved0;
- /// <summary>
- /// The dw reserved1
- /// </summary>
- public int dwReserved1;
-
- /// <summary>
- /// The c file name
- /// </summary>
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = NativeMethods.MAX_PATH)]
- public string cFileName;
-
- /// <summary>
- /// This will always be null when FINDEX_INFO_LEVELS = basic
- /// </summary>
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = NativeMethods.MAX_ALTERNATE)]
- public string cAlternate;
-
- /// <summary>
- /// Gets or sets the path.
- /// </summary>
- /// <value>The path.</value>
- public string Path { get; set; }
-
- /// <summary>
- /// Returns a <see cref="System.String" /> that represents this instance.
- /// </summary>
- /// <returns>A <see cref="System.String" /> that represents this instance.</returns>
- public override string ToString()
- {
- return Path ?? string.Empty;
- }
- }
-
- /// <summary>
- /// Enum SLGP_FLAGS
- /// </summary>
- [Flags]
- public enum SLGP_FLAGS
- {
- /// <summary>
- /// Retrieves the standard short (8.3 format) file name
- /// </summary>
- SLGP_SHORTPATH = 0x1,
- /// <summary>
- /// Retrieves the Universal Naming Convention (UNC) path name of the file
- /// </summary>
- SLGP_UNCPRIORITY = 0x2,
- /// <summary>
- /// Retrieves the raw path name. A raw path is something that might not exist and may include environment variables that need to be expanded
- /// </summary>
- SLGP_RAWPATH = 0x4
- }
- /// <summary>
- /// Enum SLR_FLAGS
- /// </summary>
- [Flags]
- public enum SLR_FLAGS
- {
- /// <summary>
- /// Do not display a dialog box if the link cannot be resolved. When SLR_NO_UI is set,
- /// the high-order word of fFlags can be set to a time-out value that specifies the
- /// maximum amount of time to be spent resolving the link. The function returns if the
- /// link cannot be resolved within the time-out duration. If the high-order word is set
- /// to zero, the time-out duration will be set to the default value of 3,000 milliseconds
- /// (3 seconds). To specify a value, set the high word of fFlags to the desired time-out
- /// duration, in milliseconds.
- /// </summary>
- SLR_NO_UI = 0x1,
- /// <summary>
- /// Obsolete and no longer used
- /// </summary>
- SLR_ANY_MATCH = 0x2,
- /// <summary>
- /// If the link object has changed, update its path and list of identifiers.
- /// If SLR_UPDATE is set, you do not need to call IPersistFile::IsDirty to determine
- /// whether or not the link object has changed.
- /// </summary>
- SLR_UPDATE = 0x4,
- /// <summary>
- /// Do not update the link information
- /// </summary>
- SLR_NOUPDATE = 0x8,
- /// <summary>
- /// Do not execute the search heuristics
- /// </summary>
- SLR_NOSEARCH = 0x10,
- /// <summary>
- /// Do not use distributed link tracking
- /// </summary>
- SLR_NOTRACK = 0x20,
- /// <summary>
- /// Disable distributed link tracking. By default, distributed link tracking tracks
- /// removable media across multiple devices based on the volume name. It also uses the
- /// Universal Naming Convention (UNC) path to track remote file systems whose drive letter
- /// has changed. Setting SLR_NOLINKINFO disables both types of tracking.
- /// </summary>
- SLR_NOLINKINFO = 0x40,
- /// <summary>
- /// Call the Microsoft Windows Installer
- /// </summary>
- SLR_INVOKE_MSI = 0x80
- }
-
- /// <summary>
- /// The IShellLink interface allows Shell links to be created, modified, and resolved
- /// </summary>
- [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("000214F9-0000-0000-C000-000000000046")]
- public interface IShellLinkW
- {
- /// <summary>
- /// Retrieves the path and file name of a Shell link object
- /// </summary>
- /// <param name="pszFile">The PSZ file.</param>
- /// <param name="cchMaxPath">The CCH max path.</param>
- /// <param name="pfd">The PFD.</param>
- /// <param name="fFlags">The f flags.</param>
- void GetPath([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, int cchMaxPath, out WIN32_FIND_DATA pfd, SLGP_FLAGS fFlags);
- /// <summary>
- /// Retrieves the list of item identifiers for a Shell link object
- /// </summary>
- /// <param name="ppidl">The ppidl.</param>
- void GetIDList(out IntPtr ppidl);
- /// <summary>
- /// Sets the pointer to an item identifier list (PIDL) for a Shell link object.
- /// </summary>
- /// <param name="pidl">The pidl.</param>
- void SetIDList(IntPtr pidl);
- /// <summary>
- /// Retrieves the description string for a Shell link object
- /// </summary>
- /// <param name="pszName">Name of the PSZ.</param>
- /// <param name="cchMaxName">Name of the CCH max.</param>
- void GetDescription([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszName, int cchMaxName);
- /// <summary>
- /// Sets the description for a Shell link object. The description can be any application-defined string
- /// </summary>
- /// <param name="pszName">Name of the PSZ.</param>
- void SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName);
- /// <summary>
- /// Retrieves the name of the working directory for a Shell link object
- /// </summary>
- /// <param name="pszDir">The PSZ dir.</param>
- /// <param name="cchMaxPath">The CCH max path.</param>
- void GetWorkingDirectory([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir, int cchMaxPath);
- /// <summary>
- /// Sets the name of the working directory for a Shell link object
- /// </summary>
- /// <param name="pszDir">The PSZ dir.</param>
- void SetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] string pszDir);
- /// <summary>
- /// Retrieves the command-line arguments associated with a Shell link object
- /// </summary>
- /// <param name="pszArgs">The PSZ args.</param>
- /// <param name="cchMaxPath">The CCH max path.</param>
- void GetArguments([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs, int cchMaxPath);
- /// <summary>
- /// Sets the command-line arguments for a Shell link object
- /// </summary>
- /// <param name="pszArgs">The PSZ args.</param>
- void SetArguments([MarshalAs(UnmanagedType.LPWStr)] string pszArgs);
- /// <summary>
- /// Retrieves the hot key for a Shell link object
- /// </summary>
- /// <param name="pwHotkey">The pw hotkey.</param>
- void GetHotkey(out short pwHotkey);
- /// <summary>
- /// Sets a hot key for a Shell link object
- /// </summary>
- /// <param name="wHotkey">The w hotkey.</param>
- void SetHotkey(short wHotkey);
- /// <summary>
- /// Retrieves the show command for a Shell link object
- /// </summary>
- /// <param name="piShowCmd">The pi show CMD.</param>
- void GetShowCmd(out int piShowCmd);
- /// <summary>
- /// Sets the show command for a Shell link object. The show command sets the initial show state of the window.
- /// </summary>
- /// <param name="iShowCmd">The i show CMD.</param>
- void SetShowCmd(int iShowCmd);
- /// <summary>
- /// Retrieves the location (path and index) of the icon for a Shell link object
- /// </summary>
- /// <param name="pszIconPath">The PSZ icon path.</param>
- /// <param name="cchIconPath">The CCH icon path.</param>
- /// <param name="piIcon">The pi icon.</param>
- void GetIconLocation([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath,
- int cchIconPath, out int piIcon);
- /// <summary>
- /// Sets the location (path and index) of the icon for a Shell link object
- /// </summary>
- /// <param name="pszIconPath">The PSZ icon path.</param>
- /// <param name="iIcon">The i icon.</param>
- void SetIconLocation([MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, int iIcon);
- /// <summary>
- /// Sets the relative path to the Shell link object
- /// </summary>
- /// <param name="pszPathRel">The PSZ path rel.</param>
- /// <param name="dwReserved">The dw reserved.</param>
- void SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] string pszPathRel, int dwReserved);
- /// <summary>
- /// Attempts to find the target of a Shell link, even if it has been moved or renamed
- /// </summary>
- /// <param name="hwnd">The HWND.</param>
- /// <param name="fFlags">The f flags.</param>
- void Resolve(IntPtr hwnd, SLR_FLAGS fFlags);
- /// <summary>
- /// Sets the path and file name of a Shell link object
- /// </summary>
- /// <param name="pszFile">The PSZ file.</param>
- void SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile);
-
- }
-
- // CLSID_ShellLink from ShlGuid.h
- /// <summary>
- /// Class ShellLink
- /// </summary>
- [
- ComImport,
- Guid("00021401-0000-0000-C000-000000000046")
- ]
- public class ShellLink
- {
- }
-}
diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs
index 40dccf9ba..57e42985d 100644
--- a/Emby.Server.Implementations/Library/LibraryManager.cs
+++ b/Emby.Server.Implementations/Library/LibraryManager.cs
@@ -353,7 +353,7 @@ namespace Emby.Server.Implementations.Library
}
else
{
- if (item is Photo)
+ if (!(item is Video))
{
return;
}
@@ -461,10 +461,10 @@ namespace Emby.Server.Implementations.Library
parent.RemoveChild(item);
}
- await ItemRepository.DeleteItem(item.Id, CancellationToken.None).ConfigureAwait(false);
+ ItemRepository.DeleteItem(item.Id, CancellationToken.None);
foreach (var child in children)
{
- await ItemRepository.DeleteItem(child.Id, CancellationToken.None).ConfigureAwait(false);
+ ItemRepository.DeleteItem(child.Id, CancellationToken.None);
}
BaseItem removed;
@@ -599,18 +599,16 @@ namespace Emby.Server.Implementations.Library
// When resolving the root, we need it's grandchildren (children of user views)
var flattenFolderDepth = isPhysicalRoot ? 2 : 0;
- var fileSystemDictionary = FileData.GetFilteredFileSystemEntries(directoryService, args.Path, _fileSystem, _logger, args, flattenFolderDepth: flattenFolderDepth, resolveShortcuts: isPhysicalRoot || args.IsVf);
+ var files = FileData.GetFilteredFileSystemEntries(directoryService, args.Path, _fileSystem, _logger, args, flattenFolderDepth: flattenFolderDepth, resolveShortcuts: isPhysicalRoot || args.IsVf);
// Need to remove subpaths that may have been resolved from shortcuts
// Example: if \\server\movies exists, then strip out \\server\movies\action
if (isPhysicalRoot)
{
- var paths = NormalizeRootPathList(fileSystemDictionary.Values);
-
- fileSystemDictionary = paths.ToDictionary(i => i.FullName);
+ files = NormalizeRootPathList(files).ToArray();
}
- args.FileSystemDictionary = fileSystemDictionary;
+ args.FileSystemChildren = files;
}
// Check to see if we should resolve based on our contents
@@ -656,7 +654,7 @@ namespace Emby.Server.Implementations.Library
return false;
}
- public IEnumerable<FileSystemMetadata> NormalizeRootPathList(IEnumerable<FileSystemMetadata> paths)
+ public List<FileSystemMetadata> NormalizeRootPathList(IEnumerable<FileSystemMetadata> paths)
{
var originalList = paths.ToList();
@@ -999,8 +997,7 @@ namespace Emby.Server.Implementations.Library
Path = path
};
- var task = CreateItem(item, CancellationToken.None);
- Task.WaitAll(task);
+ CreateItem(item, CancellationToken.None);
}
return item;
@@ -1172,7 +1169,7 @@ namespace Emby.Server.Implementations.Library
progress.Report(percent * 100);
}
- await ItemRepository.UpdateInheritedValues(cancellationToken).ConfigureAwait(false);
+ ItemRepository.UpdateInheritedValues(cancellationToken);
progress.Report(100);
}
@@ -1208,7 +1205,7 @@ namespace Emby.Server.Implementations.Library
.Where(i => string.Equals(ShortcutFileExtension, Path.GetExtension(i), StringComparison.OrdinalIgnoreCase))
.Select(_fileSystem.ResolveShortcut)
.OrderBy(i => i)
- .ToList(),
+ .ToArray(),
CollectionType = GetCollectionType(dir)
};
@@ -1554,7 +1551,7 @@ namespace Emby.Server.Implementations.Library
IncludeHidden = true,
IncludeExternalContent = allowExternalContent
- }, CancellationToken.None).Result.ToList();
+ }, CancellationToken.None).Result;
query.TopParentIds = userViews.SelectMany(i => GetTopParentIdsForQuery(i, user)).Select(i => i.ToString("N")).ToArray();
}
@@ -1814,9 +1811,9 @@ namespace Emby.Server.Implementations.Library
/// <param name="item">The item.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
- public Task CreateItem(BaseItem item, CancellationToken cancellationToken)
+ public void CreateItem(BaseItem item, CancellationToken cancellationToken)
{
- return CreateItems(new[] { item }, cancellationToken);
+ CreateItems(new[] { item }, cancellationToken);
}
/// <summary>
@@ -1825,11 +1822,11 @@ namespace Emby.Server.Implementations.Library
/// <param name="items">The items.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
- public async Task CreateItems(IEnumerable<BaseItem> items, CancellationToken cancellationToken)
+ public void CreateItems(IEnumerable<BaseItem> items, CancellationToken cancellationToken)
{
var list = items.ToList();
- await ItemRepository.SaveItems(list, cancellationToken).ConfigureAwait(false);
+ ItemRepository.SaveItems(list, cancellationToken);
foreach (var item in list)
{
@@ -1872,7 +1869,7 @@ namespace Emby.Server.Implementations.Library
var logName = item.LocationType == LocationType.Remote ? item.Name ?? item.Path : item.Path ?? item.Name;
_logger.Debug("Saving {0} to database.", logName);
- await ItemRepository.SaveItem(item, cancellationToken).ConfigureAwait(false);
+ ItemRepository.SaveItem(item, cancellationToken);
RegisterItem(item);
@@ -2069,7 +2066,7 @@ namespace Emby.Server.Implementations.Library
private readonly TimeSpan _viewRefreshInterval = TimeSpan.FromHours(24);
//private readonly TimeSpan _viewRefreshInterval = TimeSpan.FromMinutes(1);
- public Task<UserView> GetNamedView(User user,
+ public UserView GetNamedView(User user,
string name,
string viewType,
string sortName,
@@ -2107,7 +2104,7 @@ namespace Emby.Server.Implementations.Library
ForcedSortName = sortName
};
- await CreateItem(item, cancellationToken).ConfigureAwait(false);
+ CreateItem(item, cancellationToken);
refresh = true;
}
@@ -2138,7 +2135,7 @@ namespace Emby.Server.Implementations.Library
return item;
}
- public async Task<UserView> GetNamedView(User user,
+ public UserView GetNamedView(User user,
string name,
string parentId,
string viewType,
@@ -2175,7 +2172,7 @@ namespace Emby.Server.Implementations.Library
item.DisplayParentId = new Guid(parentId);
}
- await CreateItem(item, cancellationToken).ConfigureAwait(false);
+ CreateItem(item, cancellationToken);
isNew = true;
}
@@ -2201,7 +2198,7 @@ namespace Emby.Server.Implementations.Library
return item;
}
- public async Task<UserView> GetShadowView(BaseItem parent,
+ public UserView GetShadowView(BaseItem parent,
string viewType,
string sortName,
CancellationToken cancellationToken)
@@ -2240,7 +2237,7 @@ namespace Emby.Server.Implementations.Library
item.DisplayParentId = parentId;
- await CreateItem(item, cancellationToken).ConfigureAwait(false);
+ CreateItem(item, cancellationToken);
isNew = true;
}
@@ -2311,7 +2308,7 @@ namespace Emby.Server.Implementations.Library
item.DisplayParentId = new Guid(parentId);
}
- await CreateItem(item, cancellationToken).ConfigureAwait(false);
+ CreateItem(item, cancellationToken);
isNew = true;
}
@@ -2825,14 +2822,14 @@ namespace Emby.Server.Implementations.Library
return ItemRepository.GetPeopleNames(query);
}
- public Task UpdatePeople(BaseItem item, List<PersonInfo> people)
+ public void UpdatePeople(BaseItem item, List<PersonInfo> people)
{
if (!item.SupportsPeople)
{
- return Task.FromResult(true);
+ return;
}
- return ItemRepository.UpdatePeople(item.Id, people);
+ ItemRepository.UpdatePeople(item.Id, people);
}
public async Task<ItemImageInfo> ConvertImageToLocal(IHasMetadata item, ItemImageInfo image, int imageIndex)
@@ -3061,7 +3058,7 @@ namespace Emby.Server.Implementations.Library
var topLibraryFolders = GetUserRootFolder().Children.ToList();
var info = GetVirtualFolderInfo(virtualFolderPath, topLibraryFolders, null);
- if (info.Locations.Count > 0 && info.Locations.Count != options.PathInfos.Length)
+ if (info.Locations.Length > 0 && info.Locations.Length != options.PathInfos.Length)
{
var list = options.PathInfos.ToList();
diff --git a/Emby.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs b/Emby.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs
index 6c7c1f052..6a1f8ec6f 100644
--- a/Emby.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs
@@ -53,7 +53,7 @@ namespace Emby.Server.Implementations.Library.Resolvers
return new CollectionFolder
{
CollectionType = GetCollectionType(args),
- PhysicalLocationsList = args.PhysicalLocations.ToList()
+ PhysicalLocationsList = args.PhysicalLocations
};
}
}
diff --git a/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs b/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs
index 84ceac65e..830bd9d85 100644
--- a/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs
@@ -1,6 +1,8 @@
-using MediaBrowser.Controller.Configuration;
+using System.Globalization;
+using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
+using MediaBrowser.Model.Globalization;
using MediaBrowser.Naming.Common;
using MediaBrowser.Naming.TV;
@@ -17,15 +19,18 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV
private readonly IServerConfigurationManager _config;
private readonly ILibraryManager _libraryManager;
+ private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
+ private readonly ILocalizationManager _localization;
/// <summary>
/// Initializes a new instance of the <see cref="SeasonResolver"/> class.
/// </summary>
/// <param name="config">The config.</param>
- public SeasonResolver(IServerConfigurationManager config, ILibraryManager libraryManager)
+ public SeasonResolver(IServerConfigurationManager config, ILibraryManager libraryManager, ILocalizationManager localization)
{
_config = config;
_libraryManager = libraryManager;
+ _localization = localization;
}
/// <summary>
@@ -47,9 +52,13 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV
SeriesName = series.Name
};
- if (season.IndexNumber.HasValue && season.IndexNumber.Value == 0)
+ if (season.IndexNumber.HasValue)
{
- season.Name = _config.Configuration.SeasonZeroDisplayName;
+ var seasonNumber = season.IndexNumber.Value;
+
+ season.Name = seasonNumber == 0 ?
+ _config.Configuration.SeasonZeroDisplayName :
+ string.Format(_localization.GetLocalizedString("NameSeasonNumber"), seasonNumber.ToString(UsCulture));
}
return season;
diff --git a/Emby.Server.Implementations/Library/SearchEngine.cs b/Emby.Server.Implementations/Library/SearchEngine.cs
index 658558ec0..d4c4f2794 100644
--- a/Emby.Server.Implementations/Library/SearchEngine.cs
+++ b/Emby.Server.Implementations/Library/SearchEngine.cs
@@ -181,7 +181,7 @@ namespace Emby.Server.Implementations.Library
DtoOptions = new DtoOptions
{
- Fields = new List<ItemFields>
+ Fields = new ItemFields[]
{
ItemFields.AirTime,
ItemFields.DateCreated,
diff --git a/Emby.Server.Implementations/Library/UserDataManager.cs b/Emby.Server.Implementations/Library/UserDataManager.cs
index e066ab61b..7ef5ca35e 100644
--- a/Emby.Server.Implementations/Library/UserDataManager.cs
+++ b/Emby.Server.Implementations/Library/UserDataManager.cs
@@ -41,7 +41,7 @@ namespace Emby.Server.Implementations.Library
/// <value>The repository.</value>
public IUserDataRepository Repository { get; set; }
- public async Task SaveUserData(Guid userId, IHasUserData item, UserItemData userData, UserDataSaveReason reason, CancellationToken cancellationToken)
+ public void SaveUserData(Guid userId, IHasUserData item, UserItemData userData, UserDataSaveReason reason, CancellationToken cancellationToken)
{
if (userData == null)
{
@@ -62,7 +62,7 @@ namespace Emby.Server.Implementations.Library
foreach (var key in keys)
{
- await Repository.SaveUserData(userId, key, userData, cancellationToken).ConfigureAwait(false);
+ Repository.SaveUserData(userId, key, userData, cancellationToken);
}
var cacheKey = GetCacheKey(userId, item.Id);
@@ -86,7 +86,7 @@ namespace Emby.Server.Implementations.Library
/// <param name="userData"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
- public async Task SaveAllUserData(Guid userId, IEnumerable<UserItemData> userData, CancellationToken cancellationToken)
+ public void SaveAllUserData(Guid userId, UserItemData[] userData, CancellationToken cancellationToken)
{
if (userData == null)
{
@@ -99,7 +99,7 @@ namespace Emby.Server.Implementations.Library
cancellationToken.ThrowIfCancellationRequested();
- await Repository.SaveAllUserData(userId, userData, cancellationToken).ConfigureAwait(false);
+ Repository.SaveAllUserData(userId, userData, cancellationToken);
}
/// <summary>
@@ -107,7 +107,7 @@ namespace Emby.Server.Implementations.Library
/// </summary>
/// <param name="userId"></param>
/// <returns></returns>
- public IEnumerable<UserItemData> GetAllUserData(Guid userId)
+ public List<UserItemData> GetAllUserData(Guid userId)
{
if (userId == Guid.Empty)
{
@@ -187,11 +187,11 @@ namespace Emby.Server.Implementations.Library
var userData = GetUserData(user.Id, item);
var dto = GetUserItemDataDto(userData);
- item.FillUserDataDtoValues(dto, userData, null, user, new List<ItemFields>());
+ item.FillUserDataDtoValues(dto, userData, null, user, new ItemFields[] { });
return dto;
}
- public UserItemDataDto GetUserDataDto(IHasUserData item, BaseItemDto itemDto, User user, List<ItemFields> fields)
+ public UserItemDataDto GetUserDataDto(IHasUserData item, BaseItemDto itemDto, User user, ItemFields[] fields)
{
var userData = GetUserData(user.Id, item);
var dto = GetUserItemDataDto(userData);
diff --git a/Emby.Server.Implementations/Library/UserManager.cs b/Emby.Server.Implementations/Library/UserManager.cs
index 211c54cee..e5fe2969f 100644
--- a/Emby.Server.Implementations/Library/UserManager.cs
+++ b/Emby.Server.Implementations/Library/UserManager.cs
@@ -160,9 +160,9 @@ namespace Emby.Server.Implementations.Library
return Users.FirstOrDefault(u => string.Equals(u.Name, name, StringComparison.OrdinalIgnoreCase));
}
- public async Task Initialize()
+ public void Initialize()
{
- Users = await LoadUsers().ConfigureAwait(false);
+ Users = LoadUsers();
var users = Users.ToList();
@@ -174,7 +174,7 @@ namespace Emby.Server.Implementations.Library
if (!user.ConnectLinkType.HasValue || user.ConnectLinkType.Value == UserLinkType.LinkedUser)
{
user.Policy.IsAdministrator = true;
- await UpdateUserPolicy(user, user.Policy, false).ConfigureAwait(false);
+ UpdateUserPolicy(user, user.Policy, false);
}
}
}
@@ -294,12 +294,12 @@ namespace Emby.Server.Implementations.Library
if (success)
{
user.LastActivityDate = user.LastLoginDate = DateTime.UtcNow;
- await UpdateUser(user).ConfigureAwait(false);
- await UpdateInvalidLoginAttemptCount(user, 0).ConfigureAwait(false);
+ UpdateUser(user);
+ UpdateInvalidLoginAttemptCount(user, 0);
}
else
{
- await UpdateInvalidLoginAttemptCount(user, user.Policy.InvalidLoginAttemptCount + 1).ConfigureAwait(false);
+ UpdateInvalidLoginAttemptCount(user, user.Policy.InvalidLoginAttemptCount + 1);
}
_logger.Info("Authentication request for {0} {1}.", user.Name, success ? "has succeeded" : "has been denied");
@@ -307,7 +307,7 @@ namespace Emby.Server.Implementations.Library
return success ? user : null;
}
- private async Task UpdateInvalidLoginAttemptCount(User user, int newValue)
+ private void UpdateInvalidLoginAttemptCount(User user, int newValue)
{
if (user.Policy.InvalidLoginAttemptCount != newValue || newValue > 0)
{
@@ -327,7 +327,7 @@ namespace Emby.Server.Implementations.Library
//fireLockout = true;
}
- await UpdateUserPolicy(user, user.Policy, false).ConfigureAwait(false);
+ UpdateUserPolicy(user, user.Policy, false);
if (fireLockout)
{
@@ -372,7 +372,7 @@ namespace Emby.Server.Implementations.Library
/// Loads the users from the repository
/// </summary>
/// <returns>IEnumerable{User}.</returns>
- private async Task<IEnumerable<User>> LoadUsers()
+ private List<User> LoadUsers()
{
var users = UserRepository.RetrieveAllUsers().ToList();
@@ -385,14 +385,14 @@ namespace Emby.Server.Implementations.Library
user.DateLastSaved = DateTime.UtcNow;
- await UserRepository.SaveUser(user, CancellationToken.None).ConfigureAwait(false);
+ UserRepository.SaveUser(user, CancellationToken.None);
users.Add(user);
user.Policy.IsAdministrator = true;
user.Policy.EnableContentDeletion = true;
user.Policy.EnableRemoteControlOfOtherUsers = true;
- await UpdateUserPolicy(user, user.Policy, false).ConfigureAwait(false);
+ UpdateUserPolicy(user, user.Policy, false);
}
return users;
@@ -539,7 +539,7 @@ namespace Emby.Server.Implementations.Library
/// <param name="user">The user.</param>
/// <exception cref="System.ArgumentNullException">user</exception>
/// <exception cref="System.ArgumentException"></exception>
- public async Task UpdateUser(User user)
+ public void UpdateUser(User user)
{
if (user == null)
{
@@ -554,7 +554,7 @@ namespace Emby.Server.Implementations.Library
user.DateModified = DateTime.UtcNow;
user.DateLastSaved = DateTime.UtcNow;
- await UserRepository.SaveUser(user, CancellationToken.None).ConfigureAwait(false);
+ UserRepository.SaveUser(user, CancellationToken.None);
OnUserUpdated(user);
}
@@ -599,7 +599,7 @@ namespace Emby.Server.Implementations.Library
user.DateLastSaved = DateTime.UtcNow;
- await UserRepository.SaveUser(user, CancellationToken.None).ConfigureAwait(false);
+ UserRepository.SaveUser(user, CancellationToken.None);
EventHelper.QueueEventIfNotNull(UserCreated, this, new GenericEventArgs<User> { Argument = user }, _logger);
@@ -653,7 +653,7 @@ namespace Emby.Server.Implementations.Library
{
var configPath = GetConfigurationFilePath(user);
- await UserRepository.DeleteUser(user, CancellationToken.None).ConfigureAwait(false);
+ UserRepository.DeleteUser(user, CancellationToken.None);
try
{
@@ -667,7 +667,7 @@ namespace Emby.Server.Implementations.Library
DeleteUserPolicy(user);
// Force this to be lazy loaded again
- Users = await LoadUsers().ConfigureAwait(false);
+ Users = LoadUsers();
OnUserDeleted(user);
}
@@ -681,17 +681,17 @@ namespace Emby.Server.Implementations.Library
/// Resets the password by clearing it.
/// </summary>
/// <returns>Task.</returns>
- public Task ResetPassword(User user)
+ public void ResetPassword(User user)
{
- return ChangePassword(user, GetSha1String(string.Empty));
+ ChangePassword(user, GetSha1String(string.Empty));
}
- public Task ResetEasyPassword(User user)
+ public void ResetEasyPassword(User user)
{
- return ChangeEasyPassword(user, GetSha1String(string.Empty));
+ ChangeEasyPassword(user, GetSha1String(string.Empty));
}
- public async Task ChangePassword(User user, string newPasswordSha1)
+ public void ChangePassword(User user, string newPasswordSha1)
{
if (user == null)
{
@@ -709,12 +709,12 @@ namespace Emby.Server.Implementations.Library
user.Password = newPasswordSha1;
- await UpdateUser(user).ConfigureAwait(false);
+ UpdateUser(user);
EventHelper.FireEventIfNotNull(UserPasswordChanged, this, new GenericEventArgs<User>(user), _logger);
}
- public async Task ChangeEasyPassword(User user, string newPasswordSha1)
+ public void ChangeEasyPassword(User user, string newPasswordSha1)
{
if (user == null)
{
@@ -727,7 +727,7 @@ namespace Emby.Server.Implementations.Library
user.EasyPassword = newPasswordSha1;
- await UpdateUser(user).ConfigureAwait(false);
+ UpdateUser(user);
EventHelper.FireEventIfNotNull(UserPasswordChanged, this, new GenericEventArgs<User>(user), _logger);
}
@@ -842,7 +842,7 @@ namespace Emby.Server.Implementations.Library
};
}
- public async Task<PinRedeemResult> RedeemPasswordResetPin(string pin)
+ public PinRedeemResult RedeemPasswordResetPin(string pin)
{
DeletePinFile();
@@ -863,12 +863,12 @@ namespace Emby.Server.Implementations.Library
foreach (var user in users)
{
- await ResetPassword(user).ConfigureAwait(false);
+ ResetPassword(user);
if (user.Policy.IsDisabled)
{
user.Policy.IsDisabled = false;
- await UpdateUserPolicy(user, user.Policy, true).ConfigureAwait(false);
+ UpdateUserPolicy(user, user.Policy, true);
}
usersReset.Add(user.Name);
}
@@ -945,13 +945,13 @@ namespace Emby.Server.Implementations.Library
}
private readonly object _policySyncLock = new object();
- public Task UpdateUserPolicy(string userId, UserPolicy userPolicy)
+ public void UpdateUserPolicy(string userId, UserPolicy userPolicy)
{
var user = GetUserById(userId);
- return UpdateUserPolicy(user, userPolicy, true);
+ UpdateUserPolicy(user, userPolicy, true);
}
- private async Task UpdateUserPolicy(User user, UserPolicy userPolicy, bool fireEvent)
+ private void UpdateUserPolicy(User user, UserPolicy userPolicy, bool fireEvent)
{
// The xml serializer will output differently if the type is not exact
if (userPolicy.GetType() != typeof(UserPolicy))
@@ -970,7 +970,7 @@ namespace Emby.Server.Implementations.Library
user.Policy = userPolicy;
}
- await UpdateConfiguration(user, user.Configuration, true).ConfigureAwait(false);
+ UpdateConfiguration(user, user.Configuration, true);
}
private void DeleteUserPolicy(User user)
@@ -1032,13 +1032,13 @@ namespace Emby.Server.Implementations.Library
}
private readonly object _configSyncLock = new object();
- public Task UpdateConfiguration(string userId, UserConfiguration config)
+ public void UpdateConfiguration(string userId, UserConfiguration config)
{
var user = GetUserById(userId);
- return UpdateConfiguration(user, config, true);
+ UpdateConfiguration(user, config, true);
}
- private async Task UpdateConfiguration(User user, UserConfiguration config, bool fireEvent)
+ private void UpdateConfiguration(User user, UserConfiguration config, bool fireEvent)
{
var path = GetConfigurationFilePath(user);
diff --git a/Emby.Server.Implementations/Library/UserViewManager.cs b/Emby.Server.Implementations/Library/UserViewManager.cs
index 0d4303b16..b02c114bb 100644
--- a/Emby.Server.Implementations/Library/UserViewManager.cs
+++ b/Emby.Server.Implementations/Library/UserViewManager.cs
@@ -39,7 +39,7 @@ namespace Emby.Server.Implementations.Library
_config = config;
}
- public async Task<IEnumerable<Folder>> GetUserViews(UserViewQuery query, CancellationToken cancellationToken)
+ public async Task<Folder[]> GetUserViews(UserViewQuery query, CancellationToken cancellationToken)
{
var user = _userManager.GetUserById(query.UserId);
@@ -68,7 +68,7 @@ namespace Emby.Server.Implementations.Library
if (UserView.IsUserSpecific(folder))
{
- list.Add(await _libraryManager.GetNamedView(user, folder.Name, folder.Id.ToString("N"), folderViewType, null, cancellationToken).ConfigureAwait(false));
+ list.Add(_libraryManager.GetNamedView(user, folder.Name, folder.Id.ToString("N"), folderViewType, null, cancellationToken));
continue;
}
@@ -80,7 +80,7 @@ namespace Emby.Server.Implementations.Library
if (query.PresetViews.Contains(folderViewType ?? string.Empty, StringComparer.OrdinalIgnoreCase))
{
- list.Add(await GetUserView(folder, folderViewType, string.Empty, cancellationToken).ConfigureAwait(false));
+ list.Add(GetUserView(folder, folderViewType, string.Empty, cancellationToken));
}
else
{
@@ -95,7 +95,7 @@ namespace Emby.Server.Implementations.Library
if (parents.Count > 0)
{
- list.Add(await GetUserView(parents, viewType, string.Empty, user, query.PresetViews, cancellationToken).ConfigureAwait(false));
+ list.Add(GetUserView(parents, viewType, string.Empty, user, query.PresetViews, cancellationToken));
}
}
@@ -114,7 +114,7 @@ namespace Emby.Server.Implementations.Library
}, cancellationToken).ConfigureAwait(false);
var channels = channelResult.Items;
-
+
if (_config.Configuration.EnableChannelView && channels.Length > 0)
{
list.Add(await _channelManager.GetInternalChannelFolder(cancellationToken).ConfigureAwait(false));
@@ -154,7 +154,8 @@ namespace Emby.Server.Implementations.Library
return index == -1 ? int.MaxValue : index;
})
.ThenBy(sorted.IndexOf)
- .ThenBy(i => i.SortName);
+ .ThenBy(i => i.SortName)
+ .ToArray();
}
public Task<UserView> GetUserSubView(string name, string parentId, string type, string sortName, CancellationToken cancellationToken)
@@ -171,7 +172,7 @@ namespace Emby.Server.Implementations.Library
return GetUserSubView(name, parentId, type, sortName, cancellationToken);
}
- private async Task<Folder> GetUserView(List<ICollectionFolder> parents, string viewType, string sortName, User user, string[] presetViews, CancellationToken cancellationToken)
+ private Folder GetUserView(List<ICollectionFolder> parents, string viewType, string sortName, User user, string[] presetViews, CancellationToken cancellationToken)
{
if (parents.Count == 1 && parents.All(i => string.Equals(i.CollectionType, viewType, StringComparison.OrdinalIgnoreCase)))
{
@@ -180,14 +181,14 @@ namespace Emby.Server.Implementations.Library
return (Folder)parents[0];
}
- return await GetUserView((Folder)parents[0], viewType, string.Empty, cancellationToken).ConfigureAwait(false);
+ return GetUserView((Folder)parents[0], viewType, string.Empty, cancellationToken);
}
var name = _localizationManager.GetLocalizedString("ViewType" + viewType);
- return await _libraryManager.GetNamedView(user, name, viewType, sortName, cancellationToken).ConfigureAwait(false);
+ return _libraryManager.GetNamedView(user, name, viewType, sortName, cancellationToken);
}
- public Task<UserView> GetUserView(Folder parent, string viewType, string sortName, CancellationToken cancellationToken)
+ public UserView GetUserView(Folder parent, string viewType, string sortName, CancellationToken cancellationToken)
{
return _libraryManager.GetShadowView(parent, viewType, sortName, cancellationToken);
}
diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
index 99b5558a2..2e12f46bf 100644
--- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
+++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
@@ -208,7 +208,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
continue;
}
- if (virtualFolder.Locations.Count == 1)
+ if (virtualFolder.Locations.Length == 1)
{
// remove entire virtual folder
try
@@ -458,7 +458,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
return GetEpgChannelFromTunerChannel(info, tunerChannel, epgChannels);
}
- private string GetMappedChannel(string channelId, List<NameValuePair> mappings)
+ private string GetMappedChannel(string channelId, NameValuePair[] mappings)
{
foreach (NameValuePair mapping in mappings)
{
@@ -472,10 +472,10 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
private ChannelInfo GetEpgChannelFromTunerChannel(ListingsProviderInfo info, ChannelInfo tunerChannel, List<ChannelInfo> epgChannels)
{
- return GetEpgChannelFromTunerChannel(info.ChannelMappings.ToList(), tunerChannel, epgChannels);
+ return GetEpgChannelFromTunerChannel(info.ChannelMappings, tunerChannel, epgChannels);
}
- public ChannelInfo GetEpgChannelFromTunerChannel(List<NameValuePair> mappings, ChannelInfo tunerChannel, List<ChannelInfo> epgChannels)
+ public ChannelInfo GetEpgChannelFromTunerChannel(NameValuePair[] mappings, ChannelInfo tunerChannel, List<ChannelInfo> epgChannels)
{
if (!string.IsNullOrWhiteSpace(tunerChannel.Id))
{
@@ -607,20 +607,22 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
var timer = _timerProvider.GetTimer(timerId);
if (timer != null)
{
+ timer.Status = RecordingStatus.Cancelled;
+
if (string.IsNullOrWhiteSpace(timer.SeriesTimerId) || isSeriesCancelled)
{
_timerProvider.Delete(timer);
}
else
{
- timer.Status = RecordingStatus.Cancelled;
_timerProvider.AddOrUpdate(timer, false);
}
}
ActiveRecordingInfo activeRecordingInfo;
if (_activeRecordings.TryGetValue(timerId, out activeRecordingInfo))
- {
+ {
+ activeRecordingInfo.Timer = timer;
activeRecordingInfo.CancellationTokenSource.Cancel();
}
}
@@ -830,6 +832,9 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
existingTimer.IsKids = updatedTimer.IsKids;
existingTimer.IsNews = updatedTimer.IsNews;
existingTimer.IsMovie = updatedTimer.IsMovie;
+ existingTimer.IsSeries = updatedTimer.IsSeries;
+ existingTimer.IsLive = updatedTimer.IsLive;
+ existingTimer.IsPremiere = updatedTimer.IsPremiere;
existingTimer.IsProgramSeries = updatedTimer.IsProgramSeries;
existingTimer.IsRepeat = updatedTimer.IsRepeat;
existingTimer.IsSports = updatedTimer.IsSports;
@@ -861,7 +866,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
public async Task<IEnumerable<RecordingInfo>> GetRecordingsAsync(CancellationToken cancellationToken)
{
- return _activeRecordings.Values.ToList().Select(GetRecordingInfo).ToList();
+ return new List<RecordingInfo>();
}
public string GetActiveRecordingPath(string id)
@@ -875,49 +880,31 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
return null;
}
- private RecordingInfo GetRecordingInfo(ActiveRecordingInfo info)
- {
- var timer = info.Timer;
- var program = info.Program;
-
- var result = new RecordingInfo
- {
- ChannelId = timer.ChannelId,
- CommunityRating = timer.CommunityRating,
- DateLastUpdated = DateTime.UtcNow,
- EndDate = timer.EndDate,
- EpisodeTitle = timer.EpisodeTitle,
- Genres = timer.Genres,
- Id = "recording" + timer.Id,
- IsKids = timer.IsKids,
- IsMovie = timer.IsMovie,
- IsNews = timer.IsNews,
- IsRepeat = timer.IsRepeat,
- IsSeries = timer.IsProgramSeries,
- IsSports = timer.IsSports,
- Name = timer.Name,
- OfficialRating = timer.OfficialRating,
- OriginalAirDate = timer.OriginalAirDate,
- Overview = timer.Overview,
- ProgramId = timer.ProgramId,
- SeriesTimerId = timer.SeriesTimerId,
- StartDate = timer.StartDate,
- Status = RecordingStatus.InProgress,
- TimerId = timer.Id
- };
+ public IEnumerable<ActiveRecordingInfo> GetAllActiveRecordings()
+ {
+ return _activeRecordings.Values.Where(i => i.Timer.Status == RecordingStatus.InProgress && !i.CancellationTokenSource.IsCancellationRequested);
+ }
- if (program != null)
+ public ActiveRecordingInfo GetActiveRecordingInfo(string path)
+ {
+ if (string.IsNullOrWhiteSpace(path))
{
- result.Audio = program.Audio;
- result.ImagePath = program.ImagePath;
- result.ImageUrl = program.ImageUrl;
- result.IsHD = program.IsHD;
- result.IsLive = program.IsLive;
- result.IsPremiere = program.IsPremiere;
- result.ShowId = program.ShowId;
+ return null;
}
- return result;
+ foreach (var recording in _activeRecordings.Values)
+ {
+ if (string.Equals(recording.Path, path, StringComparison.Ordinal) && !recording.CancellationTokenSource.IsCancellationRequested)
+ {
+ var timer = recording.Timer;
+ if (timer.Status != RecordingStatus.InProgress)
+ {
+ return null;
+ }
+ return recording;
+ }
+ }
+ return null;
}
public Task<IEnumerable<TimerInfo>> GetTimersAsync(CancellationToken cancellationToken)
@@ -1245,6 +1232,33 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
throw new FileNotFoundException();
}
+ public async Task<List<MediaSourceInfo>> GetRecordingStreamMediaSources(ActiveRecordingInfo info, CancellationToken cancellationToken)
+ {
+ var stream = new MediaSourceInfo
+ {
+ Path = _appHost.GetLocalApiUrl("127.0.0.1") + "/LiveTv/LiveRecordings/" + info.Id + "/stream",
+ Id = info.Id,
+ SupportsDirectPlay = false,
+ SupportsDirectStream = true,
+ SupportsTranscoding = true,
+ IsInfiniteStream = true,
+ RequiresOpening = false,
+ RequiresClosing = false,
+ Protocol = MediaBrowser.Model.MediaInfo.MediaProtocol.Http,
+ BufferMs = 0,
+ IgnoreDts = true,
+ IgnoreIndex = true
+ };
+
+ var isAudio = false;
+ await new LiveStreamHelper(_mediaEncoder, _logger).AddMediaInfoWithProbe(stream, isAudio, cancellationToken).ConfigureAwait(false);
+
+ return new List<MediaSourceInfo>
+ {
+ stream
+ };
+ }
+
public async Task CloseLiveStream(string id, CancellationToken cancellationToken)
{
// Ignore the consumer id
@@ -1327,7 +1341,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
var activeRecordingInfo = new ActiveRecordingInfo
{
CancellationTokenSource = new CancellationTokenSource(),
- Timer = timer
+ Timer = timer,
+ Id = timer.Id
};
if (_activeRecordings.TryAdd(timer.Id, activeRecordingInfo))
@@ -1493,7 +1508,6 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
recordPath = recorder.GetOutputPath(mediaStreamInfo, recordPath);
recordPath = EnsureFileUnique(recordPath, timer.Id);
- _libraryManager.RegisterIgnoredPath(recordPath);
_libraryMonitor.ReportFileSystemChangeBeginning(recordPath);
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(recordPath));
activeRecordingInfo.Path = recordPath;
@@ -1512,6 +1526,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
_timerProvider.AddOrUpdate(timer, false);
SaveRecordingMetadata(timer, recordPath, seriesPath);
+ TriggerRefresh(recordPath);
EnforceKeepUpTo(timer, seriesPath);
};
@@ -1543,7 +1558,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
}
}
- _libraryManager.UnRegisterIgnoredPath(recordPath);
+ TriggerRefresh(recordPath);
_libraryMonitor.ReportFileSystemChangeComplete(recordPath, true);
ActiveRecordingInfo removed;
@@ -1574,6 +1589,44 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
OnRecordingStatusChanged();
}
+ private void TriggerRefresh(string path)
+ {
+ var item = GetAffectedBaseItem(_fileSystem.GetDirectoryName(path));
+
+ if (item != null)
+ {
+ item.ChangedExternally();
+ }
+ }
+
+ private BaseItem GetAffectedBaseItem(string path)
+ {
+ BaseItem item = null;
+
+ while (item == null && !string.IsNullOrEmpty(path))
+ {
+ item = _libraryManager.FindByPath(path, null);
+
+ path = _fileSystem.GetDirectoryName(path);
+ }
+
+ if (item != null)
+ {
+ // If the item has been deleted find the first valid parent that still exists
+ while (!_fileSystem.DirectoryExists(item.Path) && !_fileSystem.FileExists(item.Path))
+ {
+ item = item.GetParent();
+
+ if (item == null)
+ {
+ break;
+ }
+ }
+ }
+
+ return item;
+ }
+
private void OnRecordingStatusChanged()
{
EventHelper.FireEventIfNotNull(RecordingStatusChanged, this, new RecordingStatusChangedEventArgs
@@ -2591,7 +2644,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
{
list.Add(new VirtualFolderInfo
{
- Locations = new List<string> { defaultFolder },
+ Locations = new string[] { defaultFolder },
Name = defaultName
});
}
@@ -2601,7 +2654,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
{
list.Add(new VirtualFolderInfo
{
- Locations = new List<string> { customPath },
+ Locations = new string[] { customPath },
Name = "Recorded Movies",
CollectionType = CollectionType.Movies
});
@@ -2612,7 +2665,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
{
list.Add(new VirtualFolderInfo
{
- Locations = new List<string> { customPath },
+ Locations = new string[] { customPath },
Name = "Recorded Shows",
CollectionType = CollectionType.TvShows
});
@@ -2621,14 +2674,6 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
return list;
}
- class ActiveRecordingInfo
- {
- public string Path { get; set; }
- public TimerInfo Timer { get; set; }
- public ProgramInfo Program { get; set; }
- public CancellationTokenSource CancellationTokenSource { get; set; }
- }
-
private const int TunerDiscoveryDurationMs = 3000;
public async Task<List<TunerHostInfo>> DiscoverTuners(bool newDevicesOnly, CancellationToken cancellationToken)
diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs
index 94be4a02e..b5de6ef01 100644
--- a/Emby.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs
+++ b/Emby.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs
@@ -58,6 +58,10 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
timerInfo.OriginalAirDate = programInfo.OriginalAirDate;
timerInfo.IsProgramSeries = programInfo.IsSeries;
+ timerInfo.IsSeries = programInfo.IsSeries;
+ timerInfo.IsLive = programInfo.IsLive;
+ timerInfo.IsPremiere = programInfo.IsPremiere;
+
timerInfo.HomePageUrl = programInfo.HomePageUrl;
timerInfo.CommunityRating = programInfo.CommunityRating;
timerInfo.Overview = programInfo.Overview;
diff --git a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs
index e12acf140..b7cfdea1b 100644
--- a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs
+++ b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs
@@ -247,7 +247,10 @@ namespace Emby.Server.Implementations.LiveTv.Listings
ProgramAudio audioType = ProgramAudio.Stereo;
bool repeat = programInfo.@new == null;
- string newID = programInfo.programID + "T" + startAt.Ticks + "C" + channelId;
+
+ var programId = programInfo.programID ?? string.Empty;
+
+ string newID = programId + "T" + startAt.Ticks + "C" + channelId;
if (programInfo.audioProperties != null)
{
@@ -300,7 +303,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
Etag = programInfo.md5
};
- var showId = programInfo.programID ?? string.Empty;
+ var showId = programId;
if (!info.IsSeries)
{
@@ -339,11 +342,11 @@ namespace Emby.Server.Implementations.LiveTv.Listings
if (details.descriptions != null)
{
- if (details.descriptions.description1000 != null)
+ if (details.descriptions.description1000 != null && details.descriptions.description1000.Count > 0)
{
info.Overview = details.descriptions.description1000[0].description;
}
- else if (details.descriptions.description100 != null)
+ else if (details.descriptions.description100 != null && details.descriptions.description100.Count > 0)
{
info.Overview = details.descriptions.description100[0].description;
}
@@ -351,16 +354,24 @@ namespace Emby.Server.Implementations.LiveTv.Listings
if (info.IsSeries)
{
- info.SeriesId = programInfo.programID.Substring(0, 10);
+ info.SeriesId = programId.Substring(0, 10);
if (details.metadata != null)
{
- var gracenote = details.metadata.Find(x => x.Gracenote != null).Gracenote;
- info.SeasonNumber = gracenote.season;
-
- if (gracenote.episode > 0)
+ foreach (var metadataProgram in details.metadata)
{
- info.EpisodeNumber = gracenote.episode;
+ var gracenote = metadataProgram.Gracenote;
+ if (gracenote != null)
+ {
+ info.SeasonNumber = gracenote.season;
+
+ if (gracenote.episode > 0)
+ {
+ info.EpisodeNumber = gracenote.episode;
+ }
+
+ break;
+ }
}
}
}
diff --git a/Emby.Server.Implementations/LiveTv/LiveTvDtoService.cs b/Emby.Server.Implementations/LiveTv/LiveTvDtoService.cs
index 619d2378d..eff2909fd 100644
--- a/Emby.Server.Implementations/LiveTv/LiveTvDtoService.cs
+++ b/Emby.Server.Implementations/LiveTv/LiveTvDtoService.cs
@@ -15,6 +15,8 @@ using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Model.Dto;
+using MediaBrowser.Model.Extensions;
+using MediaBrowser.Model.Querying;
namespace Emby.Server.Implementations.LiveTv
{
@@ -110,7 +112,7 @@ namespace Emby.Server.Implementations.LiveTv
PostPaddingSeconds = info.PostPaddingSeconds,
IsPostPaddingRequired = info.IsPostPaddingRequired,
IsPrePaddingRequired = info.IsPrePaddingRequired,
- Days = info.Days,
+ Days = info.Days.ToArray(),
Priority = info.Priority,
RecordAnyChannel = info.RecordAnyChannel,
RecordAnyTime = info.RecordAnyTime,
@@ -135,7 +137,7 @@ namespace Emby.Server.Implementations.LiveTv
dto.ProgramId = GetInternalProgramId(service.Name, info.ProgramId).ToString("N");
}
- dto.DayPattern = info.Days == null ? null : GetDayPattern(info.Days);
+ dto.DayPattern = info.Days == null ? null : GetDayPattern(info.Days.ToArray(info.Days.Count));
FillImages(dto, info.Name, info.SeriesId);
@@ -150,10 +152,7 @@ namespace Emby.Server.Implementations.LiveTv
Name = seriesName,
Limit = 1,
ImageTypes = new ImageType[] { ImageType.Thumb },
- DtoOptions = new DtoOptions
- {
- Fields = new List<MediaBrowser.Model.Querying.ItemFields>()
- }
+ DtoOptions = new DtoOptions(false)
}).FirstOrDefault();
@@ -196,10 +195,7 @@ namespace Emby.Server.Implementations.LiveTv
ExternalSeriesId = programSeriesId,
Limit = 1,
ImageTypes = new ImageType[] { ImageType.Primary },
- DtoOptions = new DtoOptions
- {
- Fields = new List<MediaBrowser.Model.Querying.ItemFields>()
- }
+ DtoOptions = new DtoOptions(false)
}).FirstOrDefault();
@@ -248,10 +244,7 @@ namespace Emby.Server.Implementations.LiveTv
Name = seriesName,
Limit = 1,
ImageTypes = new ImageType[] { ImageType.Thumb },
- DtoOptions = new DtoOptions
- {
- Fields = new List<MediaBrowser.Model.Querying.ItemFields>()
- }
+ DtoOptions = new DtoOptions(false)
}).FirstOrDefault();
@@ -274,7 +267,7 @@ namespace Emby.Server.Implementations.LiveTv
{
try
{
- dto.ParentBackdropImageTags = new List<string>
+ dto.ParentBackdropImageTags = new string[]
{
_imageProcessor.GetImageCacheTag(librarySeries, image)
};
@@ -294,10 +287,7 @@ namespace Emby.Server.Implementations.LiveTv
Name = seriesName,
Limit = 1,
ImageTypes = new ImageType[] { ImageType.Primary },
- DtoOptions = new DtoOptions
- {
- Fields = new List<MediaBrowser.Model.Querying.ItemFields>()
- }
+ DtoOptions = new DtoOptions(false)
}).FirstOrDefault() ?? _libraryManager.GetItemList(new InternalItemsQuery
{
@@ -305,10 +295,7 @@ namespace Emby.Server.Implementations.LiveTv
ExternalSeriesId = programSeriesId,
Limit = 1,
ImageTypes = new ImageType[] { ImageType.Primary },
- DtoOptions = new DtoOptions
- {
- Fields = new List<MediaBrowser.Model.Querying.ItemFields>()
- }
+ DtoOptions = new DtoOptions(false)
}).FirstOrDefault();
@@ -327,14 +314,14 @@ namespace Emby.Server.Implementations.LiveTv
}
}
- if (dto.ParentBackdropImageTags == null || dto.ParentBackdropImageTags.Count == 0)
+ if (dto.ParentBackdropImageTags == null || dto.ParentBackdropImageTags.Length == 0)
{
image = program.GetImageInfo(ImageType.Backdrop, 0);
if (image != null)
{
try
{
- dto.ParentBackdropImageTags = new List<string>
+ dto.ParentBackdropImageTags = new string[]
{
_imageProcessor.GetImageCacheTag(program, image)
};
@@ -349,24 +336,24 @@ namespace Emby.Server.Implementations.LiveTv
}
}
- public DayPattern? GetDayPattern(List<DayOfWeek> days)
+ public DayPattern? GetDayPattern(DayOfWeek[] days)
{
DayPattern? pattern = null;
- if (days.Count > 0)
+ if (days.Length > 0)
{
- if (days.Count == 7)
+ if (days.Length == 7)
{
pattern = DayPattern.Daily;
}
- else if (days.Count == 2)
+ else if (days.Length == 2)
{
if (days.Contains(DayOfWeek.Saturday) && days.Contains(DayOfWeek.Sunday))
{
pattern = DayPattern.Weekends;
}
}
- else if (days.Count == 5)
+ else if (days.Length == 5)
{
if (days.Contains(DayOfWeek.Monday) && days.Contains(DayOfWeek.Tuesday) && days.Contains(DayOfWeek.Wednesday) && days.Contains(DayOfWeek.Thursday) && days.Contains(DayOfWeek.Friday))
{
@@ -384,7 +371,7 @@ namespace Emby.Server.Implementations.LiveTv
{
Name = info.Name,
Id = info.Id,
- Clients = info.Clients,
+ Clients = info.Clients.ToArray(),
ProgramName = info.ProgramName,
SourceType = info.SourceType,
Status = info.Status,
@@ -543,7 +530,7 @@ namespace Emby.Server.Implementations.LiveTv
PostPaddingSeconds = dto.PostPaddingSeconds,
IsPostPaddingRequired = dto.IsPostPaddingRequired,
IsPrePaddingRequired = dto.IsPrePaddingRequired,
- Days = dto.Days,
+ Days = dto.Days.ToList(),
Priority = dto.Priority,
RecordAnyChannel = dto.RecordAnyChannel,
RecordAnyTime = dto.RecordAnyTime,
diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
index 3fbbc8390..ac98d1043 100644
--- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
+++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
@@ -60,7 +60,7 @@ namespace Emby.Server.Implementations.LiveTv
private readonly LiveTvDtoService _tvDtoService;
- private readonly List<ILiveTvService> _services = new List<ILiveTvService>();
+ private ILiveTvService[] _services = new ILiveTvService[] { };
private readonly SemaphoreSlim _refreshRecordingsLock = new SemaphoreSlim(1, 1);
@@ -124,7 +124,7 @@ namespace Emby.Server.Implementations.LiveTv
/// <param name="listingProviders">The listing providers.</param>
public void AddParts(IEnumerable<ILiveTvService> services, IEnumerable<ITunerHost> tunerHosts, IEnumerable<IListingsProvider> listingProviders)
{
- _services.AddRange(services);
+ _services = services.ToArray();
_tunerHosts.AddRange(tunerHosts);
_listingProviders.AddRange(listingProviders);
@@ -558,7 +558,7 @@ namespace Emby.Server.Implementations.LiveTv
if (isNew)
{
- await _libraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false);
+ _libraryManager.CreateItem(item, cancellationToken);
}
else if (forceUpdate)
{
@@ -875,7 +875,7 @@ namespace Emby.Server.Implementations.LiveTv
if (isNew)
{
- await _libraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false);
+ _libraryManager.CreateItem(item, cancellationToken);
}
else if (dataChanged || info.DateLastUpdated > recording.DateLastSaved || statusChanged)
{
@@ -985,9 +985,8 @@ namespace Emby.Server.Implementations.LiveTv
var queryResult = _libraryManager.QueryItems(internalQuery);
- var returnList = (await _dtoService.GetBaseItemDtos(queryResult.Items, options, user)
+ var returnArray = (await _dtoService.GetBaseItemDtos(queryResult.Items, options, user)
.ConfigureAwait(false));
- var returnArray = returnList.ToArray(returnList.Count);
var result = new QueryResult<BaseItemDto>
{
@@ -998,7 +997,7 @@ namespace Emby.Server.Implementations.LiveTv
return result;
}
- public async Task<QueryResult<LiveTvProgram>> GetRecommendedProgramsInternal(RecommendedProgramQuery query, DtoOptions options, CancellationToken cancellationToken)
+ public async Task<QueryResult<BaseItem>> GetRecommendedProgramsInternal(RecommendedProgramQuery query, DtoOptions options, CancellationToken cancellationToken)
{
var user = _userManager.GetUserById(query.UserId);
@@ -1036,10 +1035,10 @@ namespace Emby.Server.Implementations.LiveTv
}
}
- var programList = _libraryManager.QueryItems(internalQuery).Items.Cast<LiveTvProgram>().ToList();
- var totalCount = programList.Count;
+ var programList = _libraryManager.QueryItems(internalQuery).Items;
+ var totalCount = programList.Length;
- IOrderedEnumerable<LiveTvProgram> orderedPrograms = programList.OrderBy(i => i.StartDate.Date);
+ IOrderedEnumerable<LiveTvProgram> orderedPrograms = programList.Cast<LiveTvProgram>().OrderBy(i => i.StartDate.Date);
if (query.IsAiring ?? false)
{
@@ -1047,14 +1046,14 @@ namespace Emby.Server.Implementations.LiveTv
.ThenByDescending(i => GetRecommendationScore(i, user.Id, true));
}
- IEnumerable<LiveTvProgram> programs = orderedPrograms;
+ IEnumerable<BaseItem> programs = orderedPrograms;
if (query.Limit.HasValue)
{
programs = programs.Take(query.Limit.Value);
}
- var result = new QueryResult<LiveTvProgram>
+ var result = new QueryResult<BaseItem>
{
Items = programs.ToArray(),
TotalRecordCount = totalCount
@@ -1071,9 +1070,8 @@ namespace Emby.Server.Implementations.LiveTv
var user = _userManager.GetUserById(query.UserId);
- var returnList = (await _dtoService.GetBaseItemDtos(internalResult.Items, options, user)
+ var returnArray = (await _dtoService.GetBaseItemDtos(internalResult.Items, options, user)
.ConfigureAwait(false));
- var returnArray = returnList.ToArray(returnList.Count);
var result = new QueryResult<BaseItemDto>
{
@@ -1223,9 +1221,9 @@ namespace Emby.Server.Implementations.LiveTv
await EmbyTV.EmbyTV.Current.ScanForTunerDeviceChanges(cancellationToken).ConfigureAwait(false);
var numComplete = 0;
- double progressPerService = _services.Count == 0
+ double progressPerService = _services.Length == 0
? 0
- : 1 / _services.Count;
+ : 1 / _services.Length;
var newChannelIdList = new List<Guid>();
var newProgramIdList = new List<Guid>();
@@ -1257,13 +1255,13 @@ namespace Emby.Server.Implementations.LiveTv
numComplete++;
double percent = numComplete;
- percent /= _services.Count;
+ percent /= _services.Length;
progress.Report(100 * percent);
}
- await CleanDatabaseInternal(newChannelIdList, new[] { typeof(LiveTvChannel).Name }, progress, cancellationToken).ConfigureAwait(false);
- await CleanDatabaseInternal(newProgramIdList, new[] { typeof(LiveTvProgram).Name }, progress, cancellationToken).ConfigureAwait(false);
+ await CleanDatabaseInternal(newChannelIdList.ToArray(), new[] { typeof(LiveTvChannel).Name }, progress, cancellationToken).ConfigureAwait(false);
+ await CleanDatabaseInternal(newProgramIdList.ToArray(), new[] { typeof(LiveTvProgram).Name }, progress, cancellationToken).ConfigureAwait(false);
var coreService = _services.OfType<EmbyTV.EmbyTV>().FirstOrDefault();
@@ -1275,8 +1273,11 @@ namespace Emby.Server.Implementations.LiveTv
// Load these now which will prefetch metadata
var dtoOptions = new DtoOptions();
- dtoOptions.Fields.Remove(ItemFields.SyncInfo);
- dtoOptions.Fields.Remove(ItemFields.BasicSyncInfo);
+ var fields = dtoOptions.Fields.ToList();
+ fields.Remove(ItemFields.SyncInfo);
+ fields.Remove(ItemFields.BasicSyncInfo);
+ dtoOptions.Fields = fields.ToArray(fields.Count);
+
await GetRecordings(new RecordingQuery(), dtoOptions, cancellationToken).ConfigureAwait(false);
progress.Report(100);
@@ -1409,7 +1410,7 @@ namespace Emby.Server.Implementations.LiveTv
if (newPrograms.Count > 0)
{
- await _libraryManager.CreateItems(newPrograms, cancellationToken).ConfigureAwait(false);
+ _libraryManager.CreateItems(newPrograms, cancellationToken);
}
// TODO: Do this in bulk
@@ -1446,14 +1447,14 @@ namespace Emby.Server.Implementations.LiveTv
return new Tuple<List<Guid>, List<Guid>>(channels, programs);
}
- private async Task CleanDatabaseInternal(List<Guid> currentIdList, string[] validTypes, IProgress<double> progress, CancellationToken cancellationToken)
+ private async Task CleanDatabaseInternal(Guid[] currentIdList, string[] validTypes, IProgress<double> progress, CancellationToken cancellationToken)
{
var list = _itemRepo.GetItemIdsList(new InternalItemsQuery
{
IncludeItemTypes = validTypes,
DtoOptions = new DtoOptions(false)
- }).ToList();
+ });
var numComplete = 0;
@@ -1543,7 +1544,7 @@ namespace Emby.Server.Implementations.LiveTv
var idList = await Task.WhenAll(recordingTasks).ConfigureAwait(false);
- await CleanDatabaseInternal(idList.ToList(), new[] { typeof(LiveTvVideoRecording).Name, typeof(LiveTvAudioRecording).Name }, new SimpleProgress<double>(), cancellationToken).ConfigureAwait(false);
+ await CleanDatabaseInternal(idList, new[] { typeof(LiveTvVideoRecording).Name, typeof(LiveTvAudioRecording).Name }, new SimpleProgress<double>(), cancellationToken).ConfigureAwait(false);
_lastRecordingRefreshTime = DateTime.UtcNow;
}
@@ -1560,11 +1561,6 @@ namespace Emby.Server.Implementations.LiveTv
return new QueryResult<BaseItem>();
}
- if ((query.IsInProgress ?? false))
- {
- return new QueryResult<BaseItem>();
- }
-
var folderIds = EmbyTV.EmbyTV.Current.GetRecordingFolders()
.SelectMany(i => i.Locations)
.Distinct(StringComparer.OrdinalIgnoreCase)
@@ -1576,13 +1572,10 @@ namespace Emby.Server.Implementations.LiveTv
var excludeItemTypes = new List<string>();
- if (!query.IsInProgress.HasValue)
- {
- folderIds.Add(internalLiveTvFolderId);
+ folderIds.Add(internalLiveTvFolderId);
- excludeItemTypes.Add(typeof(LiveTvChannel).Name);
- excludeItemTypes.Add(typeof(LiveTvProgram).Name);
- }
+ excludeItemTypes.Add(typeof(LiveTvChannel).Name);
+ excludeItemTypes.Add(typeof(LiveTvProgram).Name);
if (folderIds.Count == 0)
{
@@ -1631,6 +1624,19 @@ namespace Emby.Server.Implementations.LiveTv
}
}
+ if ((query.IsInProgress ?? false))
+ {
+ // TODO: filter
+ var allActivePaths = EmbyTV.EmbyTV.Current.GetAllActiveRecordings().Select(i => i.Path).ToArray();
+ var items = allActivePaths.Select(i => _libraryManager.FindByPath(i, false)).Where(i => i != null).ToArray();
+
+ return new QueryResult<BaseItem>
+ {
+ Items = items,
+ TotalRecordCount = items.Length
+ };
+ }
+
return _libraryManager.GetItemsResult(new InternalItemsQuery(user)
{
MediaTypes = new[] { MediaType.Video },
@@ -1658,11 +1664,6 @@ namespace Emby.Server.Implementations.LiveTv
return new QueryResult<BaseItemDto>();
}
- if (_services.Count > 1)
- {
- return new QueryResult<BaseItemDto>();
- }
-
if (user == null || (query.IsInProgress ?? false))
{
return new QueryResult<BaseItemDto>();
@@ -1701,11 +1702,9 @@ namespace Emby.Server.Implementations.LiveTv
DtoOptions = options
});
- var returnList = (await _dtoService.GetBaseItemDtos(internalResult.Items, options, user)
+ var returnArray = (await _dtoService.GetBaseItemDtos(internalResult.Items, options, user)
.ConfigureAwait(false));
- var returnArray = returnList.ToArray(returnList.Count);
-
return new QueryResult<BaseItemDto>
{
Items = returnArray,
@@ -1723,13 +1722,9 @@ namespace Emby.Server.Implementations.LiveTv
var folder = await GetInternalLiveTvFolder(cancellationToken).ConfigureAwait(false);
- if (_services.Count == 1 && (!query.IsInProgress.HasValue || !query.IsInProgress.Value) && (!query.IsLibraryItem.HasValue || query.IsLibraryItem.Value))
+ // TODO: Figure out how to merge emby recordings + service recordings
+ if (_services.Length == 1)
{
- if (!query.IsInProgress.HasValue)
- {
- await RefreshRecordings(folder.Id, cancellationToken).ConfigureAwait(false);
- }
-
return GetEmbyRecordings(query, options, folder.Id, user);
}
@@ -1841,7 +1836,7 @@ namespace Emby.Server.Implementations.LiveTv
};
}
- public async Task AddInfoToProgramDto(List<Tuple<BaseItem, BaseItemDto>> tuples, List<ItemFields> fields, User user = null)
+ public async Task AddInfoToProgramDto(List<Tuple<BaseItem, BaseItemDto>> tuples, ItemFields[] fields, User user = null)
{
var programTuples = new List<Tuple<BaseItemDto, string, string, string>>();
var hasChannelImage = fields.Contains(ItemFields.ChannelImage);
@@ -1921,6 +1916,11 @@ namespace Emby.Server.Implementations.LiveTv
await AddRecordingInfo(programTuples, CancellationToken.None).ConfigureAwait(false);
}
+ public ActiveRecordingInfo GetActiveRecordingInfo(string path)
+ {
+ return EmbyTV.EmbyTV.Current.GetActiveRecordingInfo(path);
+ }
+
public void AddInfoToRecordingDto(BaseItem item, BaseItemDto dto, User user = null)
{
var recording = (ILiveTvRecording)item;
@@ -1950,27 +1950,72 @@ namespace Emby.Server.Implementations.LiveTv
dto.IsKids = info.IsKids;
dto.IsPremiere = info.IsPremiere;
- dto.CanDelete = user == null
- ? recording.CanDelete()
- : recording.CanDelete(user);
-
- if (dto.MediaSources == null)
+ if (info.Status == RecordingStatus.InProgress && info.EndDate.HasValue)
{
- dto.MediaSources = recording.GetMediaSources(true);
+ var now = DateTime.UtcNow.Ticks;
+ var start = info.StartDate.Ticks;
+ var end = info.EndDate.Value.Ticks;
+
+ var pct = now - start;
+ pct /= end;
+ pct *= 100;
+ dto.CompletionPercentage = pct;
}
- if (dto.MediaStreams == null)
+ if (channel != null)
{
- dto.MediaStreams = dto.MediaSources.SelectMany(i => i.MediaStreams).ToList();
+ dto.ChannelName = channel.Name;
+
+ if (channel.HasImage(ImageType.Primary))
+ {
+ dto.ChannelPrimaryImageTag = _tvDtoService.GetImageTag(channel);
+ }
}
+ }
- if (info.Status == RecordingStatus.InProgress && info.EndDate.HasValue)
+ public void AddInfoToRecordingDto(BaseItem item, BaseItemDto dto, ActiveRecordingInfo activeRecordingInfo, User user = null)
+ {
+ var service = EmbyTV.EmbyTV.Current;
+
+ var info = activeRecordingInfo.Timer;
+
+ var channel = string.IsNullOrWhiteSpace(info.ChannelId) ? null : GetInternalChannel(_tvDtoService.GetInternalChannelId(service.Name, info.ChannelId));
+
+ dto.SeriesTimerId = string.IsNullOrEmpty(info.SeriesTimerId)
+ ? null
+ : _tvDtoService.GetInternalSeriesTimerId(service.Name, info.SeriesTimerId).ToString("N");
+
+ dto.TimerId = string.IsNullOrEmpty(info.Id)
+ ? null
+ : _tvDtoService.GetInternalTimerId(service.Name, info.Id).ToString("N");
+
+ var startDate = info.StartDate;
+ var endDate = info.EndDate;
+
+ dto.StartDate = startDate;
+ dto.EndDate = endDate;
+ dto.Status = info.Status.ToString();
+ dto.IsRepeat = info.IsRepeat;
+ dto.EpisodeTitle = info.EpisodeTitle;
+ dto.IsMovie = info.IsMovie;
+ dto.IsSeries = info.IsSeries;
+ dto.IsSports = info.IsSports;
+ dto.IsLive = info.IsLive;
+ dto.IsNews = info.IsNews;
+ dto.IsKids = info.IsKids;
+ dto.IsPremiere = info.IsPremiere;
+
+ if (info.Status == RecordingStatus.InProgress)
{
+ startDate = info.StartDate.AddSeconds(0 - info.PrePaddingSeconds);
+ endDate = info.EndDate.AddSeconds(info.PostPaddingSeconds);
+
var now = DateTime.UtcNow.Ticks;
- var start = info.StartDate.Ticks;
- var end = info.EndDate.Value.Ticks;
+ var start = startDate.Ticks;
+ var end = endDate.Ticks;
var pct = now - start;
+
pct /= end;
pct *= 100;
dto.CompletionPercentage = pct;
@@ -1995,9 +2040,8 @@ namespace Emby.Server.Implementations.LiveTv
var internalResult = await GetInternalRecordings(query, options, cancellationToken).ConfigureAwait(false);
- var returnList = (await _dtoService.GetBaseItemDtos(internalResult.Items, options, user)
+ var returnArray = (await _dtoService.GetBaseItemDtos(internalResult.Items, options, user)
.ConfigureAwait(false));
- var returnArray = returnList.ToArray(returnList.Count);
return new QueryResult<BaseItemDto>
{
@@ -2100,7 +2144,6 @@ namespace Emby.Server.Implementations.LiveTv
if (service is EmbyTV.EmbyTV)
{
- // We can't trust that we'll be able to direct stream it through emby server, no matter what the provider says
return service.DeleteRecordingAsync(GetItemExternalId(recording), CancellationToken.None);
}
@@ -2350,7 +2393,6 @@ namespace Emby.Server.Implementations.LiveTv
var currentChannelsDict = new Dictionary<string, BaseItemDto>();
var addCurrentProgram = options.AddCurrentProgram;
- var addMediaSources = options.Fields.Contains(ItemFields.MediaSources);
var addServiceName = options.Fields.Contains(ItemFields.ServiceName);
foreach (var tuple in tuples)
@@ -2369,11 +2411,6 @@ namespace Emby.Server.Implementations.LiveTv
currentChannelsDict[dto.Id] = dto;
- if (addMediaSources)
- {
- dto.MediaSources = channel.GetMediaSources(true);
- }
-
if (addCurrentProgram)
{
var channelIdString = channel.Id.ToString("N");
@@ -2479,7 +2516,7 @@ namespace Emby.Server.Implementations.LiveTv
var defaults = await GetNewTimerDefaultsInternal(cancellationToken, program).ConfigureAwait(false);
var info = _tvDtoService.GetSeriesTimerInfoDto(defaults.Item1, defaults.Item2, null);
- info.Days = defaults.Item1.Days;
+ info.Days = defaults.Item1.Days.ToArray();
info.DayPattern = _tvDtoService.GetDayPattern(info.Days);
@@ -2656,8 +2693,7 @@ namespace Emby.Server.Implementations.LiveTv
var series = recordings
.Where(i => i.IsSeries)
- .ToLookup(i => i.Name, StringComparer.OrdinalIgnoreCase)
- .ToList();
+ .ToLookup(i => i.Name, StringComparer.OrdinalIgnoreCase);
groups.AddRange(series.OrderByString(i => i.Key).Select(i => new BaseItemDto
{
@@ -2762,7 +2798,7 @@ namespace Emby.Server.Implementations.LiveTv
}
}
- private async Task<IEnumerable<LiveTvServiceInfo>> GetServiceInfos(CancellationToken cancellationToken)
+ private async Task<LiveTvServiceInfo[]> GetServiceInfos(CancellationToken cancellationToken)
{
var tasks = Services.Select(i => GetServiceInfo(i, cancellationToken));
@@ -2806,7 +2842,7 @@ namespace Emby.Server.Implementations.LiveTv
return dto;
- }).ToList();
+ }).ToArray();
}
catch (Exception ex)
{
@@ -2822,25 +2858,24 @@ namespace Emby.Server.Implementations.LiveTv
public async Task<LiveTvInfo> GetLiveTvInfo(CancellationToken cancellationToken)
{
var services = await GetServiceInfos(CancellationToken.None).ConfigureAwait(false);
- var servicesList = services.ToList();
var info = new LiveTvInfo
{
- Services = servicesList.ToList(),
- IsEnabled = servicesList.Count > 0
+ Services = services,
+ IsEnabled = services.Length > 0
};
info.EnabledUsers = _userManager.Users
.Where(IsLiveTvEnabled)
.Select(i => i.Id.ToString("N"))
- .ToList();
+ .ToArray();
return info;
}
private bool IsLiveTvEnabled(User user)
{
- return user.Policy.EnableLiveTvAccess && (Services.Count > 1 || GetConfiguration().TunerHosts.Count > 0);
+ return user.Policy.EnableLiveTvAccess && (Services.Count > 1 || GetConfiguration().TunerHosts.Length > 0);
}
public IEnumerable<User> GetEnabledUsers()
@@ -2880,10 +2915,13 @@ namespace Emby.Server.Implementations.LiveTv
private void RemoveFields(DtoOptions options)
{
- options.Fields.Remove(ItemFields.CanDelete);
- options.Fields.Remove(ItemFields.CanDownload);
- options.Fields.Remove(ItemFields.DisplayPreferencesId);
- options.Fields.Remove(ItemFields.Etag);
+ var fields = options.Fields.ToList();
+
+ fields.Remove(ItemFields.CanDelete);
+ fields.Remove(ItemFields.CanDownload);
+ fields.Remove(ItemFields.DisplayPreferencesId);
+ fields.Remove(ItemFields.Etag);
+ options.Fields = fields.ToArray(fields.Count);
}
public async Task<Folder> GetInternalLiveTvFolder(CancellationToken cancellationToken)
@@ -2911,12 +2949,14 @@ namespace Emby.Server.Implementations.LiveTv
var config = GetConfiguration();
- var index = config.TunerHosts.FindIndex(i => string.Equals(i.Id, info.Id, StringComparison.OrdinalIgnoreCase));
+ var list = config.TunerHosts.ToList();
+ var index = list.FindIndex(i => string.Equals(i.Id, info.Id, StringComparison.OrdinalIgnoreCase));
if (index == -1 || string.IsNullOrWhiteSpace(info.Id))
{
info.Id = Guid.NewGuid().ToString("N");
- config.TunerHosts.Add(info);
+ list.Add(info);
+ config.TunerHosts = list.ToArray(list.Count);
}
else
{
@@ -2948,12 +2988,14 @@ namespace Emby.Server.Implementations.LiveTv
var config = GetConfiguration();
- var index = config.ListingProviders.FindIndex(i => string.Equals(i.Id, info.Id, StringComparison.OrdinalIgnoreCase));
+ var list = config.ListingProviders.ToList();
+ var index = list.FindIndex(i => string.Equals(i.Id, info.Id, StringComparison.OrdinalIgnoreCase));
if (index == -1 || string.IsNullOrWhiteSpace(info.Id))
{
info.Id = Guid.NewGuid().ToString("N");
- config.ListingProviders.Add(info);
+ list.Add(info);
+ config.ListingProviders = list.ToArray(list.Count);
info.EnableNewProgramIds = true;
}
else
@@ -2972,7 +3014,7 @@ namespace Emby.Server.Implementations.LiveTv
{
var config = GetConfiguration();
- config.ListingProviders = config.ListingProviders.Where(i => !string.Equals(id, i.Id, StringComparison.OrdinalIgnoreCase)).ToList();
+ config.ListingProviders = config.ListingProviders.Where(i => !string.Equals(id, i.Id, StringComparison.OrdinalIgnoreCase)).ToArray();
_config.SaveConfiguration("livetv", config);
_taskManager.CancelIfRunningAndQueue<RefreshChannelsScheduledTask>();
@@ -3004,7 +3046,7 @@ namespace Emby.Server.Implementations.LiveTv
var providerChannels = await GetChannelsFromListingsProviderData(providerId, CancellationToken.None)
.ConfigureAwait(false);
- var mappings = listingsProviderInfo.ChannelMappings.ToList();
+ var mappings = listingsProviderInfo.ChannelMappings;
var tunerChannelMappings =
tunerChannels.Select(i => GetTunerChannelMapping(i, mappings, providerChannels)).ToList();
@@ -3014,7 +3056,7 @@ namespace Emby.Server.Implementations.LiveTv
return tunerChannelMappings.First(i => string.Equals(i.Id, tunerChannelId, StringComparison.OrdinalIgnoreCase));
}
- public TunerChannelMapping GetTunerChannelMapping(ChannelInfo tunerChannel, List<NameValuePair> mappings, List<ChannelInfo> epgChannels)
+ public TunerChannelMapping GetTunerChannelMapping(ChannelInfo tunerChannel, NameValuePair[] mappings, List<ChannelInfo> epgChannels)
{
var result = new TunerChannelMapping
{
@@ -3078,7 +3120,7 @@ namespace Emby.Server.Implementations.LiveTv
if (string.Equals(feature, "dvr-l", StringComparison.OrdinalIgnoreCase))
{
var config = GetConfiguration();
- if (config.TunerHosts.Count > 0 &&
+ if (config.TunerHosts.Length > 0 &&
config.ListingProviders.Count(i => (i.EnableAllTuners || i.EnabledTuners.Length > 0) && string.Equals(i.Type, SchedulesDirect.TypeName, StringComparison.OrdinalIgnoreCase)) > 0)
{
return Task.FromResult(new MBRegistrationRecord
diff --git a/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs b/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs
index 5436a12b8..0e52f874d 100644
--- a/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs
+++ b/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs
@@ -43,9 +43,11 @@ namespace Emby.Server.Implementations.LiveTv
if (baseItem.SourceType == SourceType.LiveTV)
{
- if (string.IsNullOrWhiteSpace(baseItem.Path))
+ var activeRecordingInfo = _liveTvManager.GetActiveRecordingInfo(item.Path);
+
+ if (string.IsNullOrWhiteSpace(baseItem.Path) || activeRecordingInfo != null)
{
- return GetMediaSourcesInternal(item, cancellationToken);
+ return GetMediaSourcesInternal(item, activeRecordingInfo, cancellationToken);
}
}
@@ -56,7 +58,7 @@ namespace Emby.Server.Implementations.LiveTv
private const char StreamIdDelimeter = '_';
private const string StreamIdDelimeterString = "_";
- private async Task<IEnumerable<MediaSourceInfo>> GetMediaSourcesInternal(IHasMediaSources item, CancellationToken cancellationToken)
+ private async Task<IEnumerable<MediaSourceInfo>> GetMediaSourcesInternal(IHasMediaSources item, ActiveRecordingInfo activeRecordingInfo, CancellationToken cancellationToken)
{
IEnumerable<MediaSourceInfo> sources;
@@ -67,12 +69,20 @@ namespace Emby.Server.Implementations.LiveTv
if (item is ILiveTvRecording)
{
sources = await _liveTvManager.GetRecordingMediaSources(item, cancellationToken)
- .ConfigureAwait(false);
+ .ConfigureAwait(false);
}
else
{
- sources = await _liveTvManager.GetChannelMediaSources(item, cancellationToken)
- .ConfigureAwait(false);
+ if (activeRecordingInfo != null)
+ {
+ sources = await EmbyTV.EmbyTV.Current.GetRecordingStreamMediaSources(activeRecordingInfo, cancellationToken)
+ .ConfigureAwait(false);
+ }
+ else
+ {
+ sources = await _liveTvManager.GetChannelMediaSources(item, cancellationToken)
+ .ConfigureAwait(false);
+ }
}
}
catch (NotImplementedException)
diff --git a/Emby.Server.Implementations/LiveTv/RefreshChannelsScheduledTask.cs b/Emby.Server.Implementations/LiveTv/RefreshChannelsScheduledTask.cs
index 5582d8f35..cad28c809 100644
--- a/Emby.Server.Implementations/LiveTv/RefreshChannelsScheduledTask.cs
+++ b/Emby.Server.Implementations/LiveTv/RefreshChannelsScheduledTask.cs
@@ -62,7 +62,7 @@ namespace Emby.Server.Implementations.LiveTv
public bool IsHidden
{
- get { return _liveTvManager.Services.Count == 1 && GetConfiguration().TunerHosts.Count == 0; }
+ get { return _liveTvManager.Services.Count == 1 && GetConfiguration().TunerHosts.Length == 0; }
}
public bool IsEnabled
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
index 2c12f4ca1..eac845579 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
@@ -25,12 +25,14 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
private readonly IHttpClient _httpClient;
private readonly IServerApplicationHost _appHost;
private readonly IEnvironmentInfo _environment;
+ private readonly INetworkManager _networkManager;
- public M3UTunerHost(IServerConfigurationManager config, ILogger logger, IJsonSerializer jsonSerializer, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IHttpClient httpClient, IServerApplicationHost appHost, IEnvironmentInfo environment) : base(config, logger, jsonSerializer, mediaEncoder, fileSystem)
+ public M3UTunerHost(IServerConfigurationManager config, ILogger logger, IJsonSerializer jsonSerializer, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IHttpClient httpClient, IServerApplicationHost appHost, IEnvironmentInfo environment, INetworkManager networkManager) : base(config, logger, jsonSerializer, mediaEncoder, fileSystem)
{
_httpClient = httpClient;
_appHost = appHost;
_environment = environment;
+ _networkManager = networkManager;
}
public override string Type
@@ -38,7 +40,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
get { return "m3u"; }
}
- public string Name
+ public virtual string Name
{
get { return "M3U Tuner"; }
}
@@ -99,72 +101,84 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
}
var channels = await GetChannels(info, true, cancellationToken).ConfigureAwait(false);
- var m3uchannels = channels.Cast<M3UChannel>();
- var channel = m3uchannels.FirstOrDefault(c => string.Equals(c.Id, channelId, StringComparison.OrdinalIgnoreCase));
+ var channel = channels.FirstOrDefault(c => string.Equals(c.Id, channelId, StringComparison.OrdinalIgnoreCase));
if (channel != null)
{
- var path = channel.Path;
- MediaProtocol protocol = MediaProtocol.File;
- if (path.StartsWith("http", StringComparison.OrdinalIgnoreCase))
- {
- protocol = MediaProtocol.Http;
- }
- else if (path.StartsWith("rtmp", StringComparison.OrdinalIgnoreCase))
- {
- protocol = MediaProtocol.Rtmp;
- }
- else if (path.StartsWith("rtsp", StringComparison.OrdinalIgnoreCase))
- {
- protocol = MediaProtocol.Rtsp;
- }
- else if (path.StartsWith("udp", StringComparison.OrdinalIgnoreCase))
- {
- protocol = MediaProtocol.Udp;
- }
- else if (path.StartsWith("rtp", StringComparison.OrdinalIgnoreCase))
- {
- protocol = MediaProtocol.Rtmp;
- }
+ return new List<MediaSourceInfo> { CreateMediaSourceInfo(info, channel) };
+ }
+ return new List<MediaSourceInfo>();
+ }
+
+ protected virtual MediaSourceInfo CreateMediaSourceInfo(TunerHostInfo info, ChannelInfo channel)
+ {
+ var path = channel.Path;
+ MediaProtocol protocol = MediaProtocol.File;
+ if (path.StartsWith("http", StringComparison.OrdinalIgnoreCase))
+ {
+ protocol = MediaProtocol.Http;
+ }
+ else if (path.StartsWith("rtmp", StringComparison.OrdinalIgnoreCase))
+ {
+ protocol = MediaProtocol.Rtmp;
+ }
+ else if (path.StartsWith("rtsp", StringComparison.OrdinalIgnoreCase))
+ {
+ protocol = MediaProtocol.Rtsp;
+ }
+ else if (path.StartsWith("udp", StringComparison.OrdinalIgnoreCase))
+ {
+ protocol = MediaProtocol.Udp;
+ }
+ else if (path.StartsWith("rtp", StringComparison.OrdinalIgnoreCase))
+ {
+ protocol = MediaProtocol.Rtmp;
+ }
+
+ Uri uri;
+ var isRemote = true;
+ if (Uri.TryCreate(path, UriKind.Absolute, out uri))
+ {
+ isRemote = !_networkManager.IsInLocalNetwork(uri.Host);
+ }
- var mediaSource = new MediaSourceInfo
+ var mediaSource = new MediaSourceInfo
+ {
+ Path = path,
+ Protocol = protocol,
+ MediaStreams = new List<MediaStream>
{
- Path = channel.Path,
- Protocol = protocol,
- MediaStreams = new List<MediaStream>
+ new MediaStream
{
- new MediaStream
- {
- Type = MediaStreamType.Video,
- // Set the index to -1 because we don't know the exact index of the video stream within the container
- Index = -1,
- IsInterlaced = true
- },
- new MediaStream
- {
- Type = MediaStreamType.Audio,
- // Set the index to -1 because we don't know the exact index of the audio stream within the container
- Index = -1
-
- }
+ Type = MediaStreamType.Video,
+ // Set the index to -1 because we don't know the exact index of the video stream within the container
+ Index = -1,
+ IsInterlaced = true
},
- RequiresOpening = true,
- RequiresClosing = true,
- RequiresLooping = info.EnableStreamLooping,
+ new MediaStream
+ {
+ Type = MediaStreamType.Audio,
+ // Set the index to -1 because we don't know the exact index of the audio stream within the container
+ Index = -1
- ReadAtNativeFramerate = false,
+ }
+ },
+ RequiresOpening = true,
+ RequiresClosing = true,
+ RequiresLooping = info.EnableStreamLooping,
+ EnableMpDecimate = info.EnableMpDecimate,
- Id = channel.Path.GetMD5().ToString("N"),
- IsInfiniteStream = true,
- IsRemote = true,
+ ReadAtNativeFramerate = false,
- IgnoreDts = true
- };
+ Id = channel.Path.GetMD5().ToString("N"),
+ IsInfiniteStream = true,
+ IsRemote = isRemote,
- mediaSource.InferTotalBitrate();
+ IgnoreDts = true
+ };
- return new List<MediaSourceInfo> { mediaSource };
- }
- return new List<MediaSourceInfo>();
+ mediaSource.InferTotalBitrate();
+
+ return mediaSource;
}
protected override Task<bool> IsAvailableInternal(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken)
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs
index 113e691b6..ca744b615 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs
@@ -32,7 +32,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
_appHost = appHost;
}
- public async Task<List<M3UChannel>> Parse(string url, string channelIdPrefix, string tunerHostId, CancellationToken cancellationToken)
+ public async Task<List<ChannelInfo>> Parse(string url, string channelIdPrefix, string tunerHostId, CancellationToken cancellationToken)
{
// Read the file and display it line by line.
using (var reader = new StreamReader(await GetListingsStream(url, cancellationToken).ConfigureAwait(false)))
@@ -41,7 +41,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
}
}
- public List<M3UChannel> ParseString(string text, string channelIdPrefix, string tunerHostId)
+ public List<ChannelInfo> ParseString(string text, string channelIdPrefix, string tunerHostId)
{
// Read the file and display it line by line.
using (var reader = new StringReader(text))
@@ -66,9 +66,9 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
}
const string ExtInfPrefix = "#EXTINF:";
- private List<M3UChannel> GetChannels(TextReader reader, string channelIdPrefix, string tunerHostId)
+ private List<ChannelInfo> GetChannels(TextReader reader, string channelIdPrefix, string tunerHostId)
{
- var channels = new List<M3UChannel>();
+ var channels = new List<ChannelInfo>();
string line;
string extInf = "";
@@ -111,9 +111,9 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
return channels;
}
- private M3UChannel GetChannelnfo(string extInf, string tunerHostId, string mediaUrl)
+ private ChannelInfo GetChannelnfo(string extInf, string tunerHostId, string mediaUrl)
{
- var channel = new M3UChannel();
+ var channel = new ChannelInfo();
channel.TunerHostId = tunerHostId;
extInf = extInf.Trim();
@@ -335,10 +335,4 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
return dict;
}
}
-
-
- public class M3UChannel : ChannelInfo
- {
- public string Path { get; set; }
- }
} \ No newline at end of file
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/MulticastStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/MulticastStream.cs
index cf50e6092..45a0c348e 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/MulticastStream.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/MulticastStream.cs
@@ -24,8 +24,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
public async Task CopyUntilCancelled(Stream source, Action onStarted, CancellationToken cancellationToken)
{
- byte[] buffer = new byte[BufferSize];
-
if (source == null)
{
throw new ArgumentNullException("source");
@@ -35,25 +33,15 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
{
cancellationToken.ThrowIfCancellationRequested();
+ byte[] buffer = new byte[BufferSize];
+
var bytesRead = source.Read(buffer, 0, buffer.Length);
if (bytesRead > 0)
{
- var allStreams = _outputStreams.ToList();
-
- //if (allStreams.Count == 1)
- //{
- // allStreams[0].Value.Write(buffer, 0, bytesRead);
- //}
- //else
+ foreach (var stream in _outputStreams)
{
- byte[] copy = new byte[bytesRead];
- Buffer.BlockCopy(buffer, 0, copy, 0, bytesRead);
-
- foreach (var stream in allStreams)
- {
- stream.Value.Queue(copy, 0, copy.Length);
- }
+ stream.Value.Queue(buffer, 0, bytesRead);
}
if (onStarted != null)
@@ -73,27 +61,21 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
public Task CopyToAsync(Stream stream, CancellationToken cancellationToken)
{
- var result = new QueueStream(stream, _logger)
- {
- OnFinished = OnFinished
- };
-
- _outputStreams.TryAdd(result.Id, result);
+ var queueStream = new QueueStream(stream, _logger);
- result.Start(cancellationToken);
-
- return result.TaskCompletion.Task;
- }
+ _outputStreams.TryAdd(queueStream.Id, queueStream);
- public void RemoveOutputStream(QueueStream stream)
- {
- QueueStream removed;
- _outputStreams.TryRemove(stream.Id, out removed);
- }
+ try
+ {
+ queueStream.Start(cancellationToken);
+ }
+ finally
+ {
+ _outputStreams.TryRemove(queueStream.Id, out queueStream);
+ GC.Collect();
+ }
- private void OnFinished(QueueStream queueStream)
- {
- RemoveOutputStream(queueStream);
+ return Task.FromResult(true);
}
}
}
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/QueueStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/QueueStream.cs
index 61bc390b4..07a4daa87 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/QueueStream.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/QueueStream.cs
@@ -13,10 +13,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
public class QueueStream
{
private readonly Stream _outputStream;
- private readonly ConcurrentQueue<Tuple<byte[], int, int>> _queue = new ConcurrentQueue<Tuple<byte[], int, int>>();
- public TaskCompletionSource<bool> TaskCompletion { get; private set; }
+ private readonly BlockingCollection<Tuple<byte[], int, int>> _queue = new BlockingCollection<Tuple<byte[], int, int>>();
- public Action<QueueStream> OnFinished { get; set; }
private readonly ILogger _logger;
public Guid Id = Guid.NewGuid();
@@ -24,94 +22,24 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
{
_outputStream = outputStream;
_logger = logger;
- TaskCompletion = new TaskCompletionSource<bool>();
}
public void Queue(byte[] bytes, int offset, int count)
{
- _queue.Enqueue(new Tuple<byte[], int, int>(bytes, offset, count));
+ _queue.Add(new Tuple<byte[], int, int>(bytes, offset, count));
}
public void Start(CancellationToken cancellationToken)
{
- Task.Run(() => StartInternal(cancellationToken));
- }
-
- private Tuple<byte[], int, int> Dequeue()
- {
- Tuple<byte[], int, int> result;
- if (_queue.TryDequeue(out result))
- {
- return result;
- }
-
- return null;
- }
-
- private void OnClosed()
- {
- GC.Collect();
- if (OnFinished != null)
- {
- OnFinished(this);
- }
- }
-
- public void Write(byte[] bytes, int offset, int count)
- {
- //return _outputStream.WriteAsync(bytes, offset, count, cancellationToken);
-
- try
+ while (true)
{
- _outputStream.Write(bytes, offset, count);
- }
- catch (OperationCanceledException)
- {
- _logger.Debug("QueueStream cancelled");
- TaskCompletion.TrySetCanceled();
- OnClosed();
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error in QueueStream", ex);
- TaskCompletion.TrySetException(ex);
- OnClosed();
- }
- }
-
- private async Task StartInternal(CancellationToken cancellationToken)
- {
- try
- {
- while (true)
+ foreach (var result in _queue.GetConsumingEnumerable())
{
cancellationToken.ThrowIfCancellationRequested();
- var result = Dequeue();
- if (result != null)
- {
- _outputStream.Write(result.Item1, result.Item2, result.Item3);
- }
- else
- {
- await Task.Delay(50, cancellationToken).ConfigureAwait(false);
- }
+ _outputStream.Write(result.Item1, result.Item2, result.Item3);
}
}
- catch (OperationCanceledException)
- {
- _logger.Debug("QueueStream cancelled");
- TaskCompletion.TrySetCanceled();
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error in QueueStream", ex);
- TaskCompletion.TrySetException(ex);
- }
- finally
- {
- OnClosed();
- }
}
}
}
diff --git a/Emby.Server.Implementations/Localization/Core/core.json b/Emby.Server.Implementations/Localization/Core/core.json
deleted file mode 100644
index 976faa8cb..000000000
--- a/Emby.Server.Implementations/Localization/Core/core.json
+++ /dev/null
@@ -1,179 +0,0 @@
-{
- "AppDeviceValues": "App: {0}, Device: {1}",
- "UserDownloadingItemWithValues": "{0} is downloading {1}",
- "FolderTypeMixed": "Mixed content",
- "FolderTypeMovies": "Movies",
- "FolderTypeMusic": "Music",
- "FolderTypeAdultVideos": "Adult videos",
- "FolderTypePhotos": "Photos",
- "FolderTypeMusicVideos": "Music videos",
- "FolderTypeHomeVideos": "Home videos",
- "FolderTypeGames": "Games",
- "FolderTypeBooks": "Books",
- "FolderTypeTvShows": "TV",
- "FolderTypeInherit": "Inherit",
- "HeaderCastCrew": "Cast & Crew",
- "HeaderPeople": "People",
- "ValueSpecialEpisodeName": "Special - {0}",
- "LabelChapterName": "Chapter {0}",
- "NameSeasonNumber": "Season {0}",
- "LabelExit": "Exit",
- "LabelVisitCommunity": "Visit Community",
- "LabelGithub": "Github",
- "LabelApiDocumentation": "Api Documentation",
- "LabelDeveloperResources": "Developer Resources",
- "LabelBrowseLibrary": "Browse Library",
- "LabelConfigureServer": "Configure Emby",
- "LabelRestartServer": "Restart Server",
- "CategorySync": "Sync",
- "CategoryUser": "User",
- "CategorySystem": "System",
- "CategoryApplication": "Application",
- "CategoryPlugin": "Plugin",
- "NotificationOptionPluginError": "Plugin failure",
- "NotificationOptionApplicationUpdateAvailable": "Application update available",
- "NotificationOptionApplicationUpdateInstalled": "Application update installed",
- "NotificationOptionPluginUpdateInstalled": "Plugin update installed",
- "NotificationOptionPluginInstalled": "Plugin installed",
- "NotificationOptionPluginUninstalled": "Plugin uninstalled",
- "NotificationOptionVideoPlayback": "Video playback started",
- "NotificationOptionAudioPlayback": "Audio playback started",
- "NotificationOptionGamePlayback": "Game playback started",
- "NotificationOptionVideoPlaybackStopped": "Video playback stopped",
- "NotificationOptionAudioPlaybackStopped": "Audio playback stopped",
- "NotificationOptionGamePlaybackStopped": "Game playback stopped",
- "NotificationOptionTaskFailed": "Scheduled task failure",
- "NotificationOptionInstallationFailed": "Installation failure",
- "NotificationOptionNewLibraryContent": "New content added",
- "NotificationOptionNewLibraryContentMultiple": "New content added (multiple)",
- "NotificationOptionCameraImageUploaded": "Camera image uploaded",
- "NotificationOptionUserLockedOut": "User locked out",
- "NotificationOptionServerRestartRequired": "Server restart required",
- "ViewTypePlaylists": "Playlists",
- "ViewTypeMovies": "Movies",
- "ViewTypeTvShows": "TV",
- "ViewTypeGames": "Games",
- "ViewTypeMusic": "Music",
- "ViewTypeMusicGenres": "Genres",
- "ViewTypeMusicArtists": "Artists",
- "ViewTypeBoxSets": "Collections",
- "ViewTypeChannels": "Channels",
- "ViewTypeLiveTV": "Live TV",
- "ViewTypeLiveTvNowPlaying": "Now Airing",
- "ViewTypeLatestGames": "Latest Games",
- "ViewTypeRecentlyPlayedGames": "Recently Played",
- "ViewTypeGameFavorites": "Favorites",
- "ViewTypeGameSystems": "Game Systems",
- "ViewTypeGameGenres": "Genres",
- "ViewTypeTvResume": "Resume",
- "ViewTypeTvNextUp": "Next Up",
- "ViewTypeTvLatest": "Latest",
- "ViewTypeTvShowSeries": "Series",
- "ViewTypeTvGenres": "Genres",
- "ViewTypeTvFavoriteSeries": "Favorite Series",
- "ViewTypeTvFavoriteEpisodes": "Favorite Episodes",
- "ViewTypeMovieResume": "Resume",
- "ViewTypeMovieLatest": "Latest",
- "ViewTypeMovieMovies": "Movies",
- "ViewTypeMovieCollections": "Collections",
- "ViewTypeMovieFavorites": "Favorites",
- "ViewTypeMovieGenres": "Genres",
- "ViewTypeMusicLatest": "Latest",
- "ViewTypeMusicPlaylists": "Playlists",
- "ViewTypeMusicAlbums": "Albums",
- "ViewTypeMusicAlbumArtists": "Album Artists",
- "HeaderOtherDisplaySettings": "Display Settings",
- "ViewTypeMusicSongs": "Songs",
- "ViewTypeMusicFavorites": "Favorites",
- "ViewTypeMusicFavoriteAlbums": "Favorite Albums",
- "ViewTypeMusicFavoriteArtists": "Favorite Artists",
- "ViewTypeMusicFavoriteSongs": "Favorite Songs",
- "ViewTypeFolders": "Folders",
- "ViewTypeLiveTvRecordingGroups": "Recordings",
- "ViewTypeLiveTvChannels": "Channels",
- "ScheduledTaskFailedWithName": "{0} failed",
- "LabelRunningTimeValue": "Running time: {0}",
- "ScheduledTaskStartedWithName": "{0} started",
- "VersionNumber": "Version {0}",
- "PluginInstalledWithName": "{0} was installed",
- "PluginUpdatedWithName": "{0} was updated",
- "PluginUninstalledWithName": "{0} was uninstalled",
- "ItemAddedWithName": "{0} was added to the library",
- "ItemRemovedWithName": "{0} was removed from the library",
- "LabelIpAddressValue": "Ip address: {0}",
- "DeviceOnlineWithName": "{0} is connected",
- "UserOnlineFromDevice": "{0} is online from {1}",
- "ProviderValue": "Provider: {0}",
- "SubtitlesDownloadedForItem": "Subtitles downloaded for {0}",
- "UserConfigurationUpdatedWithName": "User configuration has been updated for {0}",
- "UserCreatedWithName": "User {0} has been created",
- "UserPasswordChangedWithName": "Password has been changed for user {0}",
- "UserDeletedWithName": "User {0} has been deleted",
- "MessageServerConfigurationUpdated": "Server configuration has been updated",
- "MessageNamedServerConfigurationUpdatedWithValue": "Server configuration section {0} has been updated",
- "MessageApplicationUpdated": "Emby Server has been updated",
- "FailedLoginAttemptWithUserName": "Failed login attempt from {0}",
- "AuthenticationSucceededWithUserName": "{0} successfully authenticated",
- "DeviceOfflineWithName": "{0} has disconnected",
- "UserLockedOutWithName": "User {0} has been locked out",
- "UserOfflineFromDevice": "{0} has disconnected from {1}",
- "UserStartedPlayingItemWithValues": "{0} has started playing {1}",
- "UserStoppedPlayingItemWithValues": "{0} has stopped playing {1}",
- "SubtitlesDownloadedForItem": "Subtitles downloaded for {0}",
- "SubtitleDownloadFailureForItem": "Subtitles failed to download for {0}",
- "HeaderUnidentified": "Unidentified",
- "HeaderImagePrimary": "Primary",
- "HeaderImageBackdrop": "Backdrop",
- "HeaderImageLogo": "Logo",
- "HeaderUserPrimaryImage": "User Image",
- "HeaderOverview": "Overview",
- "HeaderShortOverview": "Short Overview",
- "HeaderType": "Type",
- "HeaderSeverity": "Severity",
- "HeaderUser": "User",
- "HeaderName": "Name",
- "HeaderDate": "Date",
- "HeaderPremiereDate": "Premiere Date",
- "HeaderDateAdded": "Date Added",
- "HeaderReleaseDate": "Release date",
- "HeaderRuntime": "Runtime",
- "HeaderPlayCount": "Play Count",
- "HeaderSeason": "Season",
- "HeaderSeasonNumber": "Season number",
- "HeaderSeries": "Series:",
- "HeaderNetwork": "Network",
- "HeaderYear": "Year:",
- "HeaderYears": "Years:",
- "HeaderParentalRating": "Parental Rating",
- "HeaderCommunityRating": "Community rating",
- "HeaderTrailers": "Trailers",
- "HeaderSpecials": "Specials",
- "HeaderGameSystems": "Game Systems",
- "HeaderPlayers": "Players:",
- "HeaderAlbumArtists": "Album Artists",
- "HeaderAlbums": "Albums",
- "HeaderDisc": "Disc",
- "HeaderTrack": "Track",
- "HeaderAudio": "Audio",
- "HeaderVideo": "Video",
- "HeaderEmbeddedImage": "Embedded image",
- "HeaderResolution": "Resolution",
- "HeaderSubtitles": "Subtitles",
- "HeaderGenres": "Genres",
- "HeaderCountries": "Countries",
- "HeaderStatus": "Status",
- "HeaderTracks": "Tracks",
- "HeaderMusicArtist": "Music artist",
- "HeaderLocked": "Locked",
- "HeaderStudios": "Studios",
- "HeaderActor": "Actors",
- "HeaderComposer": "Composers",
- "HeaderDirector": "Directors",
- "HeaderGuestStar": "Guest star",
- "HeaderProducer": "Producers",
- "HeaderWriter": "Writers",
- "HeaderParentalRatings": "Parental Ratings",
- "HeaderCommunityRatings": "Community ratings",
- "StartupEmbyServerIsLoading": "Emby Server is loading. Please try again shortly.",
- "DbUpgradeMessage": "Please wait while your Emby Server database is upgraded. {0}% complete."
-}
diff --git a/Emby.Server.Implementations/Localization/Core/en-US.json b/Emby.Server.Implementations/Localization/Core/en-US.json
index 133644ff7..c7f865233 100644
--- a/Emby.Server.Implementations/Localization/Core/en-US.json
+++ b/Emby.Server.Implementations/Localization/Core/en-US.json
@@ -1,5 +1,4 @@
{
- "DbUpgradeMessage": "Please wait while your Emby Server database is upgraded. {0}% complete.",
"AppDeviceValues": "App: {0}, Device: {1}",
"UserDownloadingItemWithValues": "{0} is downloading {1}",
"FolderTypeMixed": "Mixed content",
@@ -13,15 +12,12 @@
"FolderTypeBooks": "Books",
"FolderTypeTvShows": "TV",
"FolderTypeInherit": "Inherit",
- "HeaderCastCrew": "Cast & Crew",
- "HeaderPeople": "People",
"ValueSpecialEpisodeName": "Special - {0}",
"LabelChapterName": "Chapter {0}",
"NameSeasonUnknown": "Season Unknown",
"NameSeasonNumber": "Season {0}",
"LabelExit": "Exit",
"LabelVisitCommunity": "Visit Community",
- "LabelGithub": "Github",
"LabelApiDocumentation": "Api Documentation",
"LabelDeveloperResources": "Developer Resources",
"LabelBrowseLibrary": "Browse Library",
@@ -164,15 +160,5 @@
"HeaderStatus": "Status",
"HeaderTracks": "Tracks",
"HeaderMusicArtist": "Music artist",
- "HeaderLocked": "Locked",
- "HeaderStudios": "Studios",
- "HeaderActor": "Actors",
- "HeaderComposer": "Composers",
- "HeaderDirector": "Directors",
- "HeaderGuestStar": "Guest star",
- "HeaderProducer": "Producers",
- "HeaderWriter": "Writers",
- "HeaderParentalRatings": "Parental Ratings",
- "HeaderCommunityRatings": "Community ratings",
"StartupEmbyServerIsLoading": "Emby Server is loading. Please try again shortly."
} \ No newline at end of file
diff --git a/Emby.Server.Implementations/Localization/LocalizationManager.cs b/Emby.Server.Implementations/Localization/LocalizationManager.cs
index 8d3051a89..278a39cd1 100644
--- a/Emby.Server.Implementations/Localization/LocalizationManager.cs
+++ b/Emby.Server.Implementations/Localization/LocalizationManager.cs
@@ -132,7 +132,7 @@ namespace Emby.Server.Implementations.Localization
/// Gets the cultures.
/// </summary>
/// <returns>IEnumerable{CultureDto}.</returns>
- public List<CultureDto> GetCultures()
+ public CultureDto[] GetCultures()
{
var type = GetType();
var path = type.Namespace + ".iso6392.txt";
@@ -169,21 +169,21 @@ namespace Emby.Server.Implementations.Localization
return list.Where(i => !string.IsNullOrWhiteSpace(i.Name) &&
!string.IsNullOrWhiteSpace(i.DisplayName) &&
!string.IsNullOrWhiteSpace(i.ThreeLetterISOLanguageName) &&
- !string.IsNullOrWhiteSpace(i.TwoLetterISOLanguageName)).ToList();
+ !string.IsNullOrWhiteSpace(i.TwoLetterISOLanguageName)).ToArray();
}
/// <summary>
/// Gets the countries.
/// </summary>
/// <returns>IEnumerable{CountryInfo}.</returns>
- public List<CountryInfo> GetCountries()
+ public CountryInfo[] GetCountries()
{
var type = GetType();
var path = type.Namespace + ".countries.json";
using (var stream = _assemblyInfo.GetManifestResourceStream(type, path))
{
- return _jsonSerializer.DeserializeFromStream<List<CountryInfo>>(stream);
+ return _jsonSerializer.DeserializeFromStream<CountryInfo[]>(stream);
}
}
@@ -191,9 +191,9 @@ namespace Emby.Server.Implementations.Localization
/// Gets the parental ratings.
/// </summary>
/// <returns>IEnumerable{ParentalRating}.</returns>
- public IEnumerable<ParentalRating> GetParentalRatings()
+ public ParentalRating[] GetParentalRatings()
{
- return GetParentalRatingsDictionary().Values.ToList();
+ return GetParentalRatingsDictionary().Values.ToArray();
}
/// <summary>
@@ -335,7 +335,7 @@ namespace Emby.Server.Implementations.Localization
const string prefix = "Core";
var key = prefix + culture;
- return _dictionaries.GetOrAdd(key, k => GetDictionary(prefix, culture, "core.json"));
+ return _dictionaries.GetOrAdd(key, k => GetDictionary(prefix, culture, "en-US.json"));
}
private Dictionary<string, string> GetDictionary(string prefix, string culture, string baseFilename)
@@ -382,9 +382,9 @@ namespace Emby.Server.Implementations.Localization
return culture + ".json";
}
- public IEnumerable<LocalizatonOption> GetLocalizationOptions()
+ public LocalizatonOption[] GetLocalizationOptions()
{
- return new List<LocalizatonOption>
+ return new LocalizatonOption[]
{
new LocalizatonOption{ Name="Arabic", Value="ar"},
new LocalizatonOption{ Name="Bulgarian (Bulgaria)", Value="bg-BG"},
@@ -421,7 +421,7 @@ namespace Emby.Server.Implementations.Localization
new LocalizatonOption{ Name="Ukrainian", Value="uk"},
new LocalizatonOption{ Name="Vietnamese", Value="vi"}
- }.OrderBy(i => i.Name);
+ };
}
}
diff --git a/Emby.Server.Implementations/Logging/SimpleLogManager.cs b/Emby.Server.Implementations/Logging/SimpleLogManager.cs
index 5c83766fe..3a6992657 100644
--- a/Emby.Server.Implementations/Logging/SimpleLogManager.cs
+++ b/Emby.Server.Implementations/Logging/SimpleLogManager.cs
@@ -112,7 +112,7 @@ namespace Emby.Server.Implementations.Logging
public class FileLogger : IDisposable
{
- private readonly Stream _fileStream;
+ private readonly FileStream _fileStream;
private bool _disposed;
private readonly CancellationTokenSource _cancellationTokenSource;
@@ -122,7 +122,7 @@ namespace Emby.Server.Implementations.Logging
{
Directory.CreateDirectory(Path.GetDirectoryName(path));
- _fileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read);
+ _fileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, 32768);
_cancellationTokenSource = new CancellationTokenSource();
Task.Factory.StartNew(LogInternal, _cancellationTokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default);
@@ -134,19 +134,12 @@ namespace Emby.Server.Implementations.Logging
{
try
{
- var any = false;
-
foreach (var message in _queue.GetConsumingEnumerable())
{
var bytes = Encoding.UTF8.GetBytes(message + Environment.NewLine);
_fileStream.Write(bytes, 0, bytes.Length);
- any = true;
- }
-
- if (any)
- {
- _fileStream.Flush();
+ _fileStream.Flush(true);
}
}
catch
diff --git a/Emby.Server.Implementations/MediaEncoder/EncodingManager.cs b/Emby.Server.Implementations/MediaEncoder/EncodingManager.cs
index 7ee6e9e38..9a9e619a6 100644
--- a/Emby.Server.Implementations/MediaEncoder/EncodingManager.cs
+++ b/Emby.Server.Implementations/MediaEncoder/EncodingManager.cs
@@ -75,6 +75,11 @@ namespace Emby.Server.Implementations.MediaEncoder
return false;
}
+ if (!video.IsCompleteMedia)
+ {
+ return false;
+ }
+
// Can't extract images if there are no video streams
return video.DefaultVideoStreamIndex.HasValue;
}
@@ -129,7 +134,7 @@ namespace Emby.Server.Implementations.MediaEncoder
var protocol = MediaProtocol.File;
- var inputPath = MediaEncoderHelpers.GetInputArgument(_fileSystem, video.Path, protocol, null, new List<string>());
+ var inputPath = MediaEncoderHelpers.GetInputArgument(_fileSystem, video.Path, protocol, null, new string[] { });
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(path));
@@ -174,7 +179,7 @@ namespace Emby.Server.Implementations.MediaEncoder
if (saveChapters && changesMade)
{
- await _chapterManager.SaveChapters(video.Id.ToString(), chapters).ConfigureAwait(false);
+ _chapterManager.SaveChapters(video.Id.ToString(), chapters);
}
DeleteDeadImages(currentImages, chapters);
diff --git a/Emby.Server.Implementations/Notifications/CoreNotificationTypes.cs b/Emby.Server.Implementations/Notifications/CoreNotificationTypes.cs
index f9fb98f85..849e02d81 100644
--- a/Emby.Server.Implementations/Notifications/CoreNotificationTypes.cs
+++ b/Emby.Server.Implementations/Notifications/CoreNotificationTypes.cs
@@ -28,21 +28,21 @@ namespace Emby.Server.Implementations.Notifications
Type = NotificationType.ApplicationUpdateInstalled.ToString(),
DefaultDescription = "{ReleaseNotes}",
DefaultTitle = "A new version of Emby Server has been installed.",
- Variables = new List<string>{"Version"}
+ Variables = new string[]{"Version"}
},
new NotificationTypeInfo
{
Type = NotificationType.InstallationFailed.ToString(),
DefaultTitle = "{Name} installation failed.",
- Variables = new List<string>{"Name", "Version"}
+ Variables = new string[]{"Name", "Version"}
},
new NotificationTypeInfo
{
Type = NotificationType.PluginInstalled.ToString(),
DefaultTitle = "{Name} was installed.",
- Variables = new List<string>{"Name", "Version"}
+ Variables = new string[]{"Name", "Version"}
},
new NotificationTypeInfo
@@ -50,14 +50,14 @@ namespace Emby.Server.Implementations.Notifications
Type = NotificationType.PluginError.ToString(),
DefaultTitle = "{Name} has encountered an error.",
DefaultDescription = "{ErrorMessage}",
- Variables = new List<string>{"Name", "ErrorMessage"}
+ Variables = new string[]{"Name", "ErrorMessage"}
},
new NotificationTypeInfo
{
Type = NotificationType.PluginUninstalled.ToString(),
DefaultTitle = "{Name} was uninstalled.",
- Variables = new List<string>{"Name", "Version"}
+ Variables = new string[]{"Name", "Version"}
},
new NotificationTypeInfo
@@ -65,7 +65,7 @@ namespace Emby.Server.Implementations.Notifications
Type = NotificationType.PluginUpdateInstalled.ToString(),
DefaultTitle = "{Name} was updated.",
DefaultDescription = "{ReleaseNotes}",
- Variables = new List<string>{"Name", "ReleaseNotes", "Version"}
+ Variables = new string[]{"Name", "ReleaseNotes", "Version"}
},
new NotificationTypeInfo
@@ -79,70 +79,70 @@ namespace Emby.Server.Implementations.Notifications
Type = NotificationType.TaskFailed.ToString(),
DefaultTitle = "{Name} failed.",
DefaultDescription = "{ErrorMessage}",
- Variables = new List<string>{"Name", "ErrorMessage"}
+ Variables = new string[]{"Name", "ErrorMessage"}
},
new NotificationTypeInfo
{
Type = NotificationType.NewLibraryContent.ToString(),
DefaultTitle = "{Name} has been added to your media library.",
- Variables = new List<string>{"Name"}
+ Variables = new string[]{"Name"}
},
new NotificationTypeInfo
{
Type = NotificationType.AudioPlayback.ToString(),
DefaultTitle = "{UserName} is playing {ItemName} on {DeviceName}.",
- Variables = new List<string>{"UserName", "ItemName", "DeviceName", "AppName"}
+ Variables = new string[]{"UserName", "ItemName", "DeviceName", "AppName"}
},
new NotificationTypeInfo
{
Type = NotificationType.GamePlayback.ToString(),
DefaultTitle = "{UserName} is playing {ItemName} on {DeviceName}.",
- Variables = new List<string>{"UserName", "ItemName", "DeviceName", "AppName"}
+ Variables = new string[]{"UserName", "ItemName", "DeviceName", "AppName"}
},
new NotificationTypeInfo
{
Type = NotificationType.VideoPlayback.ToString(),
DefaultTitle = "{UserName} is playing {ItemName} on {DeviceName}.",
- Variables = new List<string>{"UserName", "ItemName", "DeviceName", "AppName"}
+ Variables = new string[]{"UserName", "ItemName", "DeviceName", "AppName"}
},
new NotificationTypeInfo
{
Type = NotificationType.AudioPlaybackStopped.ToString(),
DefaultTitle = "{UserName} has finished playing {ItemName} on {DeviceName}.",
- Variables = new List<string>{"UserName", "ItemName", "DeviceName", "AppName"}
+ Variables = new string[]{"UserName", "ItemName", "DeviceName", "AppName"}
},
new NotificationTypeInfo
{
Type = NotificationType.GamePlaybackStopped.ToString(),
DefaultTitle = "{UserName} has finished playing {ItemName} on {DeviceName}.",
- Variables = new List<string>{"UserName", "ItemName", "DeviceName", "AppName"}
+ Variables = new string[]{"UserName", "ItemName", "DeviceName", "AppName"}
},
new NotificationTypeInfo
{
Type = NotificationType.VideoPlaybackStopped.ToString(),
DefaultTitle = "{UserName} has finished playing {ItemName} on {DeviceName}.",
- Variables = new List<string>{"UserName", "ItemName", "DeviceName", "AppName"}
+ Variables = new string[]{"UserName", "ItemName", "DeviceName", "AppName"}
},
new NotificationTypeInfo
{
Type = NotificationType.CameraImageUploaded.ToString(),
DefaultTitle = "A new camera image has been uploaded from {DeviceName}.",
- Variables = new List<string>{"DeviceName"}
+ Variables = new string[]{"DeviceName"}
},
new NotificationTypeInfo
{
Type = NotificationType.UserLockedOut.ToString(),
DefaultTitle = "{UserName} has been locked out.",
- Variables = new List<string>{"UserName"}
+ Variables = new string[]{"UserName"}
}
};
diff --git a/Emby.Server.Implementations/Notifications/NotificationManager.cs b/Emby.Server.Implementations/Notifications/NotificationManager.cs
index db7980497..f49d5a1d1 100644
--- a/Emby.Server.Implementations/Notifications/NotificationManager.cs
+++ b/Emby.Server.Implementations/Notifications/NotificationManager.cs
@@ -251,7 +251,7 @@ namespace Emby.Server.Implementations.Notifications
_typeFactories = notificationTypeFactories.ToArray();
}
- public IEnumerable<NotificationTypeInfo> GetNotificationTypes()
+ public List<NotificationTypeInfo> GetNotificationTypes()
{
var list = _typeFactories.Select(i =>
{
diff --git a/Emby.Server.Implementations/Notifications/Notifications.cs b/Emby.Server.Implementations/Notifications/Notifications.cs
index f95b3f701..ac3cc7564 100644
--- a/Emby.Server.Implementations/Notifications/Notifications.cs
+++ b/Emby.Server.Implementations/Notifications/Notifications.cs
@@ -422,7 +422,7 @@ namespace Emby.Server.Implementations.Notifications
{
var artists = hasArtist.AllArtists;
- if (artists.Count > 0)
+ if (artists.Length > 0)
{
name = hasArtist.AllArtists[0] + " - " + name;
}
@@ -440,7 +440,7 @@ namespace Emby.Server.Implementations.Notifications
name = item.SeriesName + " - " + name;
}
- if (item.Artists != null && item.Artists.Count > 0)
+ if (item.Artists != null && item.Artists.Length > 0)
{
name = item.Artists[0] + " - " + name;
}
diff --git a/Emby.Server.Implementations/Playlists/PlaylistManager.cs b/Emby.Server.Implementations/Playlists/PlaylistManager.cs
index 578a2321c..87832e7dd 100644
--- a/Emby.Server.Implementations/Playlists/PlaylistManager.cs
+++ b/Emby.Server.Implementations/Playlists/PlaylistManager.cs
@@ -128,12 +128,12 @@ namespace Emby.Server.Implementations.Playlists
playlist.SetMediaType(options.MediaType);
- await parentFolder.AddChild(playlist, CancellationToken.None).ConfigureAwait(false);
+ parentFolder.AddChild(playlist, CancellationToken.None);
await playlist.RefreshMetadata(new MetadataRefreshOptions(_fileSystem) { ForceSave = true }, CancellationToken.None)
.ConfigureAwait(false);
- if (options.ItemIdList.Count > 0)
+ if (options.ItemIdList.Length > 0)
{
await AddToPlaylistInternal(playlist.Id.ToString("N"), options.ItemIdList, user, new DtoOptions(false)
{
diff --git a/Emby.Server.Implementations/Security/AuthenticationRepository.cs b/Emby.Server.Implementations/Security/AuthenticationRepository.cs
index d512ff4fb..f5b847ccf 100644
--- a/Emby.Server.Implementations/Security/AuthenticationRepository.cs
+++ b/Emby.Server.Implementations/Security/AuthenticationRepository.cs
@@ -4,7 +4,6 @@ using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading;
-using System.Threading.Tasks;
using Emby.Server.Implementations.Data;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Security;
@@ -51,14 +50,14 @@ namespace Emby.Server.Implementations.Security
}
}
- public Task Create(AuthenticationInfo info, CancellationToken cancellationToken)
+ public void Create(AuthenticationInfo info, CancellationToken cancellationToken)
{
info.Id = Guid.NewGuid().ToString("N");
- return Update(info, cancellationToken);
+ Update(info, cancellationToken);
}
- public async Task Update(AuthenticationInfo info, CancellationToken cancellationToken)
+ public void Update(AuthenticationInfo info, CancellationToken cancellationToken)
{
if (info == null)
{
diff --git a/Emby.Server.Implementations/Services/ServiceController.cs b/Emby.Server.Implementations/Services/ServiceController.cs
index 4ad56411a..c3970b22f 100644
--- a/Emby.Server.Implementations/Services/ServiceController.cs
+++ b/Emby.Server.Implementations/Services/ServiceController.cs
@@ -29,13 +29,6 @@ namespace Emby.Server.Implementations.Services
}
}
- private Type[] GetGenericArguments(Type type)
- {
- return type.GetTypeInfo().IsGenericTypeDefinition
- ? type.GetTypeInfo().GenericTypeParameters
- : type.GetTypeInfo().GenericTypeArguments;
- }
-
public void RegisterService(HttpListenerHost appHost, Type serviceType)
{
var processedReqs = new HashSet<Type>();
@@ -50,38 +43,19 @@ namespace Emby.Server.Implementations.Services
ServiceExecGeneral.CreateServiceRunnersFor(requestType, actions);
- var returnMarker = GetTypeWithGenericTypeDefinitionOf(requestType, typeof(IReturn<>));
- var responseType = returnMarker != null ?
- GetGenericArguments(returnMarker)[0]
- : mi.ReturnType != typeof(object) && mi.ReturnType != typeof(void) ?
- mi.ReturnType
- : Type.GetType(requestType.FullName + "Response");
+ //var returnMarker = GetTypeWithGenericTypeDefinitionOf(requestType, typeof(IReturn<>));
+ //var responseType = returnMarker != null ?
+ // GetGenericArguments(returnMarker)[0]
+ // : mi.ReturnType != typeof(object) && mi.ReturnType != typeof(void) ?
+ // mi.ReturnType
+ // : Type.GetType(requestType.FullName + "Response");
RegisterRestPaths(appHost, requestType);
- appHost.AddServiceInfo(serviceType, requestType, responseType);
+ appHost.AddServiceInfo(serviceType, requestType);
}
}
- private static Type GetTypeWithGenericTypeDefinitionOf(Type type, Type genericTypeDefinition)
- {
- foreach (var t in type.GetTypeInfo().ImplementedInterfaces)
- {
- if (t.GetTypeInfo().IsGenericType && t.GetGenericTypeDefinition() == genericTypeDefinition)
- {
- return t;
- }
- }
-
- var genericType = FirstGenericType(type);
- if (genericType != null && genericType.GetGenericTypeDefinition() == genericTypeDefinition)
- {
- return genericType;
- }
-
- return null;
- }
-
public static Type FirstGenericType(Type type)
{
while (type != null)
diff --git a/Emby.Server.Implementations/Services/ServiceHandler.cs b/Emby.Server.Implementations/Services/ServiceHandler.cs
index 526e62d39..f9fcfdbab 100644
--- a/Emby.Server.Implementations/Services/ServiceHandler.cs
+++ b/Emby.Server.Implementations/Services/ServiceHandler.cs
@@ -215,13 +215,13 @@ namespace Emby.Server.Implementations.Services
if (name == null) continue; //thank you ASP.NET
var values = request.QueryString.GetValues(name);
- if (values.Length == 1)
+ if (values.Count == 1)
{
map[name] = values[0];
}
else
{
- for (var i = 0; i < values.Length; i++)
+ for (var i = 0; i < values.Count; i++)
{
map[name + (i == 0 ? "" : "#" + i)] = values[i];
}
@@ -235,13 +235,13 @@ namespace Emby.Server.Implementations.Services
if (name == null) continue; //thank you ASP.NET
var values = request.FormData.GetValues(name);
- if (values.Length == 1)
+ if (values.Count == 1)
{
map[name] = values[0];
}
else
{
- for (var i = 0; i < values.Length; i++)
+ for (var i = 0; i < values.Count; i++)
{
map[name + (i == 0 ? "" : "#" + i)] = values[i];
}
diff --git a/Emby.Server.Implementations/Session/SessionManager.cs b/Emby.Server.Implementations/Session/SessionManager.cs
index dc7e83992..0692a0ba5 100644
--- a/Emby.Server.Implementations/Session/SessionManager.cs
+++ b/Emby.Server.Implementations/Session/SessionManager.cs
@@ -6,11 +6,8 @@ using MediaBrowser.Controller.Devices;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.LiveTv;
-using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Security;
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Devices;
@@ -253,7 +250,7 @@ namespace Emby.Server.Implementations.Session
{
try
{
- await _userManager.UpdateUser(user).ConfigureAwait(false);
+ _userManager.UpdateUser(user);
}
catch (Exception ex)
{
@@ -468,7 +465,7 @@ namespace Emby.Server.Implementations.Session
if (!userId.HasValue)
{
- sessionInfo.AdditionalUsers.Clear();
+ sessionInfo.AdditionalUsers = new SessionUserInfo[] { };
}
if (sessionInfo.SessionController == null)
@@ -622,7 +619,7 @@ namespace Emby.Server.Implementations.Session
{
foreach (var user in users)
{
- await OnPlaybackStart(user.Id, libraryItem).ConfigureAwait(false);
+ OnPlaybackStart(user.Id, libraryItem);
}
}
@@ -650,8 +647,7 @@ namespace Emby.Server.Implementations.Session
/// </summary>
/// <param name="userId">The user identifier.</param>
/// <param name="item">The item.</param>
- /// <returns>Task.</returns>
- private async Task OnPlaybackStart(Guid userId, IHasUserData item)
+ private void OnPlaybackStart(Guid userId, IHasUserData item)
{
var data = _userDataManager.GetUserData(userId, item);
@@ -670,7 +666,7 @@ namespace Emby.Server.Implementations.Session
data.Played = false;
}
- await _userDataManager.SaveUserData(userId, item, data, UserDataSaveReason.PlaybackStart, CancellationToken.None).ConfigureAwait(false);
+ _userDataManager.SaveUserData(userId, item, data, UserDataSaveReason.PlaybackStart, CancellationToken.None);
}
public Task OnPlaybackProgress(PlaybackProgressInfo info)
@@ -702,7 +698,7 @@ namespace Emby.Server.Implementations.Session
{
foreach (var user in users)
{
- await OnPlaybackProgress(user, libraryItem, info).ConfigureAwait(false);
+ OnPlaybackProgress(user, libraryItem, info);
}
}
@@ -730,7 +726,7 @@ namespace Emby.Server.Implementations.Session
StartIdleCheckTimer();
}
- private async Task OnPlaybackProgress(User user, BaseItem item, PlaybackProgressInfo info)
+ private void OnPlaybackProgress(User user, BaseItem item, PlaybackProgressInfo info)
{
var data = _userDataManager.GetUserData(user.Id, item);
@@ -742,7 +738,7 @@ namespace Emby.Server.Implementations.Session
UpdatePlaybackSettings(user, info, data);
- await _userDataManager.SaveUserData(user.Id, item, data, UserDataSaveReason.PlaybackProgress, CancellationToken.None).ConfigureAwait(false);
+ _userDataManager.SaveUserData(user.Id, item, data, UserDataSaveReason.PlaybackProgress, CancellationToken.None);
}
}
@@ -842,7 +838,7 @@ namespace Emby.Server.Implementations.Session
{
foreach (var user in users)
{
- playedToCompletion = await OnPlaybackStopped(user.Id, libraryItem, info.PositionTicks, info.Failed).ConfigureAwait(false);
+ playedToCompletion = OnPlaybackStopped(user.Id, libraryItem, info.PositionTicks, info.Failed);
}
}
@@ -875,7 +871,7 @@ namespace Emby.Server.Implementations.Session
await SendPlaybackStoppedNotification(session, CancellationToken.None).ConfigureAwait(false);
}
- private async Task<bool> OnPlaybackStopped(Guid userId, BaseItem item, long? positionTicks, bool playbackFailed)
+ private bool OnPlaybackStopped(Guid userId, BaseItem item, long? positionTicks, bool playbackFailed)
{
bool playedToCompletion = false;
@@ -896,7 +892,7 @@ namespace Emby.Server.Implementations.Session
playedToCompletion = true;
}
- await _userDataManager.SaveUserData(userId, item, data, UserDataSaveReason.PlaybackFinished, CancellationToken.None).ConfigureAwait(false);
+ _userDataManager.SaveUserData(userId, item, data, UserDataSaveReason.PlaybackFinished, CancellationToken.None);
}
return playedToCompletion;
@@ -1074,7 +1070,7 @@ namespace Emby.Server.Implementations.Session
DtoOptions = new DtoOptions(false)
{
EnableImages = false,
- Fields = new List<ItemFields>
+ Fields = new ItemFields[]
{
ItemFields.SortName
}
@@ -1097,7 +1093,7 @@ namespace Emby.Server.Implementations.Session
DtoOptions = new DtoOptions(false)
{
EnableImages = false,
- Fields = new List<ItemFields>
+ Fields = new ItemFields[]
{
ItemFields.SortName
}
@@ -1340,11 +1336,15 @@ namespace Emby.Server.Implementations.Session
{
var user = _userManager.GetUserById(userId);
- session.AdditionalUsers.Add(new SessionUserInfo
+ var list = session.AdditionalUsers.ToList();
+
+ list.Add(new SessionUserInfo
{
UserId = userId,
UserName = user.Name
});
+
+ session.AdditionalUsers = list.ToArray(list.Count);
}
}
@@ -1368,7 +1368,10 @@ namespace Emby.Server.Implementations.Session
if (user != null)
{
- session.AdditionalUsers.Remove(user);
+ var list = session.AdditionalUsers.ToList();
+ list.Remove(user);
+
+ session.AdditionalUsers = list.ToArray(list.Count);
}
}
@@ -1425,7 +1428,7 @@ namespace Emby.Server.Implementations.Session
user = result;
}
- var token = await GetAuthorizationToken(user.Id.ToString("N"), request.DeviceId, request.App, request.AppVersion, request.DeviceName).ConfigureAwait(false);
+ var token = GetAuthorizationToken(user.Id.ToString("N"), request.DeviceId, request.App, request.AppVersion, request.DeviceName);
EventHelper.FireEventIfNotNull(AuthenticationSucceeded, this, new GenericEventArgs<AuthenticationRequest>(request), _logger);
@@ -1447,7 +1450,7 @@ namespace Emby.Server.Implementations.Session
}
- private async Task<string> GetAuthorizationToken(string userId, string deviceId, string app, string appVersion, string deviceName)
+ private string GetAuthorizationToken(string userId, string deviceId, string app, string appVersion, string deviceName)
{
var existing = _authRepo.Get(new AuthenticationInfoQuery
{
@@ -1477,12 +1480,12 @@ namespace Emby.Server.Implementations.Session
};
_logger.Info("Creating new access token for user {0}", userId);
- await _authRepo.Create(newToken, CancellationToken.None).ConfigureAwait(false);
+ _authRepo.Create(newToken, CancellationToken.None);
return newToken.AccessToken;
}
- public async Task Logout(string accessToken)
+ public void Logout(string accessToken)
{
if (string.IsNullOrWhiteSpace(accessToken))
{
@@ -1502,7 +1505,7 @@ namespace Emby.Server.Implementations.Session
{
existing.IsActive = false;
- await _authRepo.Update(existing, CancellationToken.None).ConfigureAwait(false);
+ _authRepo.Update(existing, CancellationToken.None);
var sessions = Sessions
.Where(i => string.Equals(i.DeviceId, existing.DeviceId, StringComparison.OrdinalIgnoreCase))
@@ -1522,7 +1525,7 @@ namespace Emby.Server.Implementations.Session
}
}
- public async Task RevokeUserTokens(string userId, string currentAccessToken)
+ public void RevokeUserTokens(string userId, string currentAccessToken)
{
var existing = _authRepo.Get(new AuthenticationInfoQuery
{
@@ -1534,14 +1537,14 @@ namespace Emby.Server.Implementations.Session
{
if (!string.Equals(currentAccessToken, info.AccessToken, StringComparison.OrdinalIgnoreCase))
{
- await Logout(info.AccessToken).ConfigureAwait(false);
+ Logout(info.AccessToken);
}
}
}
- public Task RevokeToken(string token)
+ public void RevokeToken(string token)
{
- return Logout(token);
+ Logout(token);
}
/// <summary>
@@ -1661,35 +1664,39 @@ namespace Emby.Server.Implementations.Session
AddProgramRecordingInfo = false
};
- dtoOptions.Fields.Remove(ItemFields.BasicSyncInfo);
- dtoOptions.Fields.Remove(ItemFields.SyncInfo);
- dtoOptions.Fields.Remove(ItemFields.CanDelete);
- dtoOptions.Fields.Remove(ItemFields.CanDownload);
- dtoOptions.Fields.Remove(ItemFields.ChildCount);
- dtoOptions.Fields.Remove(ItemFields.CustomRating);
- dtoOptions.Fields.Remove(ItemFields.DateLastMediaAdded);
- dtoOptions.Fields.Remove(ItemFields.DateLastRefreshed);
- dtoOptions.Fields.Remove(ItemFields.DateLastSaved);
- dtoOptions.Fields.Remove(ItemFields.DisplayPreferencesId);
- dtoOptions.Fields.Remove(ItemFields.Etag);
- dtoOptions.Fields.Remove(ItemFields.ExternalEtag);
- dtoOptions.Fields.Remove(ItemFields.InheritedParentalRatingValue);
- dtoOptions.Fields.Remove(ItemFields.ItemCounts);
- dtoOptions.Fields.Remove(ItemFields.MediaSourceCount);
- dtoOptions.Fields.Remove(ItemFields.MediaStreams);
- dtoOptions.Fields.Remove(ItemFields.MediaSources);
- dtoOptions.Fields.Remove(ItemFields.People);
- dtoOptions.Fields.Remove(ItemFields.PlayAccess);
- dtoOptions.Fields.Remove(ItemFields.People);
- dtoOptions.Fields.Remove(ItemFields.ProductionLocations);
- dtoOptions.Fields.Remove(ItemFields.RecursiveItemCount);
- dtoOptions.Fields.Remove(ItemFields.RemoteTrailers);
- dtoOptions.Fields.Remove(ItemFields.SeasonUserData);
- dtoOptions.Fields.Remove(ItemFields.Settings);
- dtoOptions.Fields.Remove(ItemFields.SortName);
- dtoOptions.Fields.Remove(ItemFields.Tags);
- dtoOptions.Fields.Remove(ItemFields.ThemeSongIds);
- dtoOptions.Fields.Remove(ItemFields.ThemeVideoIds);
+ var fields = dtoOptions.Fields.ToList();
+
+ fields.Remove(ItemFields.BasicSyncInfo);
+ fields.Remove(ItemFields.SyncInfo);
+ fields.Remove(ItemFields.CanDelete);
+ fields.Remove(ItemFields.CanDownload);
+ fields.Remove(ItemFields.ChildCount);
+ fields.Remove(ItemFields.CustomRating);
+ fields.Remove(ItemFields.DateLastMediaAdded);
+ fields.Remove(ItemFields.DateLastRefreshed);
+ fields.Remove(ItemFields.DateLastSaved);
+ fields.Remove(ItemFields.DisplayPreferencesId);
+ fields.Remove(ItemFields.Etag);
+ fields.Remove(ItemFields.ExternalEtag);
+ fields.Remove(ItemFields.InheritedParentalRatingValue);
+ fields.Remove(ItemFields.ItemCounts);
+ fields.Remove(ItemFields.MediaSourceCount);
+ fields.Remove(ItemFields.MediaStreams);
+ fields.Remove(ItemFields.MediaSources);
+ fields.Remove(ItemFields.People);
+ fields.Remove(ItemFields.PlayAccess);
+ fields.Remove(ItemFields.People);
+ fields.Remove(ItemFields.ProductionLocations);
+ fields.Remove(ItemFields.RecursiveItemCount);
+ fields.Remove(ItemFields.RemoteTrailers);
+ fields.Remove(ItemFields.SeasonUserData);
+ fields.Remove(ItemFields.Settings);
+ fields.Remove(ItemFields.SortName);
+ fields.Remove(ItemFields.Tags);
+ fields.Remove(ItemFields.ThemeSongIds);
+ fields.Remove(ItemFields.ThemeVideoIds);
+
+ dtoOptions.Fields = fields.ToArray(fields.Count);
_itemInfoDtoOptions = dtoOptions;
}
@@ -1698,7 +1705,7 @@ namespace Emby.Server.Implementations.Session
if (mediaSource != null)
{
- info.MediaStreams = mediaSource.MediaStreams;
+ info.MediaStreams = mediaSource.MediaStreams.ToArray();
}
return info;
diff --git a/Emby.Server.Implementations/Social/SharingManager.cs b/Emby.Server.Implementations/Social/SharingManager.cs
index 54614c879..57cf93948 100644
--- a/Emby.Server.Implementations/Social/SharingManager.cs
+++ b/Emby.Server.Implementations/Social/SharingManager.cs
@@ -58,8 +58,8 @@ namespace Emby.Server.Implementations.Social
};
AddShareInfo(info, externalUrl);
-
- await _repository.CreateShare(info).ConfigureAwait(false);
+
+ _repository.CreateShare(info);
return info;
}
@@ -92,9 +92,9 @@ namespace Emby.Server.Implementations.Social
}
}
- public Task DeleteShare(string id)
+ public void DeleteShare(string id)
{
- return _repository.DeleteShare(id);
+ _repository.DeleteShare(id);
}
}
}
diff --git a/Emby.Server.Implementations/Social/SharingRepository.cs b/Emby.Server.Implementations/Social/SharingRepository.cs
index a2a1f879a..f306e76c4 100644
--- a/Emby.Server.Implementations/Social/SharingRepository.cs
+++ b/Emby.Server.Implementations/Social/SharingRepository.cs
@@ -1,8 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
-using System.Threading;
-using System.Threading.Tasks;
using Emby.Server.Implementations.Data;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Model.Logging;
@@ -42,7 +40,7 @@ namespace Emby.Server.Implementations.Social
}
}
- public async Task CreateShare(SocialShareInfo info)
+ public void CreateShare(SocialShareInfo info)
{
if (info == null)
{
@@ -109,7 +107,7 @@ namespace Emby.Server.Implementations.Social
return info;
}
- public async Task DeleteShare(string id)
+ public void DeleteShare(string id)
{
}
diff --git a/Emby.Server.Implementations/Sorting/ArtistComparer.cs b/Emby.Server.Implementations/Sorting/ArtistComparer.cs
index edb195820..616aff673 100644
--- a/Emby.Server.Implementations/Sorting/ArtistComparer.cs
+++ b/Emby.Server.Implementations/Sorting/ArtistComparer.cs
@@ -36,7 +36,7 @@ namespace Emby.Server.Implementations.Sorting
return string.Empty;
}
- return audio.Artists.Count == 0 ? null : audio.Artists[0];
+ return audio.Artists.Length == 0 ? null : audio.Artists[0];
}
/// <summary>
diff --git a/Emby.Server.Implementations/TV/TVSeriesManager.cs b/Emby.Server.Implementations/TV/TVSeriesManager.cs
index 03283031e..018e452be 100644
--- a/Emby.Server.Implementations/TV/TVSeriesManager.cs
+++ b/Emby.Server.Implementations/TV/TVSeriesManager.cs
@@ -72,7 +72,7 @@ namespace Emby.Server.Implementations.TV
Recursive = true,
DtoOptions = new MediaBrowser.Controller.Dto.DtoOptions
{
- Fields = new List<ItemFields>
+ Fields = new ItemFields[]
{
ItemFields.SeriesPresentationUniqueKey
}
@@ -128,7 +128,7 @@ namespace Emby.Server.Implementations.TV
Limit = limit,
DtoOptions = new MediaBrowser.Controller.Dto.DtoOptions
{
- Fields = new List<ItemFields>
+ Fields = new ItemFields[]
{
ItemFields.SeriesPresentationUniqueKey
},
@@ -207,7 +207,7 @@ namespace Emby.Server.Implementations.TV
ParentIndexNumberNotEquals = 0,
DtoOptions = new MediaBrowser.Controller.Dto.DtoOptions
{
- Fields = new List<ItemFields>
+ Fields = new ItemFields[]
{
ItemFields.SortName
},
diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs
index 6e37c1dc1..75328a39a 100644
--- a/Emby.Server.Implementations/Updates/InstallationManager.cs
+++ b/Emby.Server.Implementations/Updates/InstallationManager.cs
@@ -122,7 +122,10 @@ namespace Emby.Server.Implementations.Updates
private readonly ICryptoProvider _cryptographyProvider;
- public InstallationManager(ILogger logger, IApplicationHost appHost, IApplicationPaths appPaths, IHttpClient httpClient, IJsonSerializer jsonSerializer, ISecurityManager securityManager, IConfigurationManager config, IFileSystem fileSystem, ICryptoProvider cryptographyProvider)
+ // netframework or netcore
+ private readonly string _packageRuntime;
+
+ public InstallationManager(ILogger logger, IApplicationHost appHost, IApplicationPaths appPaths, IHttpClient httpClient, IJsonSerializer jsonSerializer, ISecurityManager securityManager, IConfigurationManager config, IFileSystem fileSystem, ICryptoProvider cryptographyProvider, string packageRuntime)
{
if (logger == null)
{
@@ -140,6 +143,7 @@ namespace Emby.Server.Implementations.Updates
_config = config;
_fileSystem = fileSystem;
_cryptographyProvider = cryptographyProvider;
+ _packageRuntime = packageRuntime;
_logger = logger;
}
@@ -157,7 +161,7 @@ namespace Emby.Server.Implementations.Updates
/// Gets all available packages.
/// </summary>
/// <returns>Task{List{PackageInfo}}.</returns>
- public async Task<IEnumerable<PackageInfo>> GetAvailablePackages(CancellationToken cancellationToken,
+ public async Task<List<PackageInfo>> GetAvailablePackages(CancellationToken cancellationToken,
bool withRegistration = true,
string packageType = null,
Version applicationVersion = null)
@@ -171,11 +175,11 @@ namespace Emby.Server.Implementations.Updates
{ "systemid", _applicationHost.SystemId }
};
- using (var json = await _httpClient.Post("https://www.mb3admin.com/admin/service/package/retrieveall", data, cancellationToken).ConfigureAwait(false))
+ using (var json = await _httpClient.Post("https://www.mb3admin.com/admin/service/package/retrieveall?includeAllRuntimes=true", data, cancellationToken).ConfigureAwait(false))
{
cancellationToken.ThrowIfCancellationRequested();
- var packages = _jsonSerializer.DeserializeFromStream<List<PackageInfo>>(json).ToList();
+ var packages = _jsonSerializer.DeserializeFromStream<PackageInfo[]>(json);
return FilterPackages(packages, packageType, applicationVersion);
}
@@ -184,7 +188,7 @@ namespace Emby.Server.Implementations.Updates
{
var packages = await GetAvailablePackagesWithoutRegistrationInfo(cancellationToken).ConfigureAwait(false);
- return FilterPackages(packages.ToList(), packageType, applicationVersion);
+ return FilterPackages(packages, packageType, applicationVersion);
}
}
@@ -195,21 +199,21 @@ namespace Emby.Server.Implementations.Updates
/// </summary>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{List{PackageInfo}}.</returns>
- public async Task<IEnumerable<PackageInfo>> GetAvailablePackagesWithoutRegistrationInfo(CancellationToken cancellationToken)
+ public async Task<List<PackageInfo>> GetAvailablePackagesWithoutRegistrationInfo(CancellationToken cancellationToken)
{
_logger.Info("Opening {0}", PackageCachePath);
try
{
using (var stream = _fileSystem.OpenRead(PackageCachePath))
{
- var packages = _jsonSerializer.DeserializeFromStream<List<PackageInfo>>(stream).ToList();
+ var packages = _jsonSerializer.DeserializeFromStream<PackageInfo[]>(stream);
if (DateTime.UtcNow - _lastPackageUpdateTime > GetCacheLength())
{
UpdateCachedPackages(CancellationToken.None, false);
}
- return packages;
+ return FilterPackages(packages);
}
}
catch (Exception)
@@ -221,7 +225,7 @@ namespace Emby.Server.Implementations.Updates
await UpdateCachedPackages(cancellationToken, true).ConfigureAwait(false);
using (var stream = _fileSystem.OpenRead(PackageCachePath))
{
- return _jsonSerializer.DeserializeFromStream<List<PackageInfo>>(stream).ToList();
+ return FilterPackages(_jsonSerializer.DeserializeFromStream<PackageInfo[]>(stream));
}
}
@@ -244,7 +248,7 @@ namespace Emby.Server.Implementations.Updates
var tempFile = await _httpClient.GetTempFile(new HttpRequestOptions
{
- Url = "https://www.mb3admin.com/admin/service/MB3Packages.json",
+ Url = "https://www.mb3admin.com/admin/service/EmbyPackages.json",
CancellationToken = cancellationToken,
Progress = new SimpleProgress<Double>()
@@ -277,57 +281,77 @@ namespace Emby.Server.Implementations.Updates
private TimeSpan GetCacheLength()
{
- switch (GetSystemUpdateLevel())
- {
- case PackageVersionClass.Beta:
- return TimeSpan.FromMinutes(30);
- case PackageVersionClass.Dev:
- return TimeSpan.FromMinutes(3);
- default:
- return TimeSpan.FromHours(24);
- }
+ return TimeSpan.FromMinutes(3);
}
- protected IEnumerable<PackageInfo> FilterPackages(List<PackageInfo> packages)
+ protected List<PackageInfo> FilterPackages(IEnumerable<PackageInfo> packages)
{
+ var list = new List<PackageInfo>();
+
foreach (var package in packages)
{
- package.versions = package.versions.Where(v => !string.IsNullOrWhiteSpace(v.sourceUrl))
- .OrderByDescending(GetPackageVersion).ToList();
+ var versions = new List<PackageVersionInfo>();
+ foreach (var version in package.versions)
+ {
+ if (string.IsNullOrWhiteSpace(version.sourceUrl))
+ {
+ continue;
+ }
+
+ if (string.IsNullOrWhiteSpace(version.runtimes) || version.runtimes.IndexOf(_packageRuntime, StringComparison.OrdinalIgnoreCase) == -1)
+ {
+ continue;
+ }
+
+ versions.Add(version);
+ }
+
+ package.versions = versions
+ .OrderByDescending(GetPackageVersion)
+ .ToArray();
+
+ if (package.versions.Length == 0)
+ {
+ continue;
+ }
+
+ list.Add(package);
}
// Remove packages with no versions
- packages = packages.Where(p => p.versions.Any()).ToList();
-
- return packages;
+ return list;
}
- protected IEnumerable<PackageInfo> FilterPackages(List<PackageInfo> packages, string packageType, Version applicationVersion)
+ protected List<PackageInfo> FilterPackages(IEnumerable<PackageInfo> packages, string packageType, Version applicationVersion)
{
- foreach (var package in packages)
- {
- package.versions = package.versions.Where(v => !string.IsNullOrWhiteSpace(v.sourceUrl))
- .OrderByDescending(GetPackageVersion).ToList();
- }
+ var packagesList = FilterPackages(packages);
- if (!string.IsNullOrWhiteSpace(packageType))
- {
- packages = packages.Where(p => string.Equals(p.type, packageType, StringComparison.OrdinalIgnoreCase)).ToList();
- }
+ var returnList = new List<PackageInfo>();
- // If an app version was supplied, filter the versions for each package to only include supported versions
- if (applicationVersion != null)
+ var filterOnPackageType = !string.IsNullOrWhiteSpace(packageType);
+
+ foreach (var p in packagesList)
{
- foreach (var package in packages)
+ if (filterOnPackageType && !string.Equals(p.type, packageType, StringComparison.OrdinalIgnoreCase))
{
- package.versions = package.versions.Where(v => IsPackageVersionUpToDate(v, applicationVersion)).ToList();
+ continue;
}
- }
- // Remove packages with no versions
- packages = packages.Where(p => p.versions.Any()).ToList();
+ // If an app version was supplied, filter the versions for each package to only include supported versions
+ if (applicationVersion != null)
+ {
+ p.versions = p.versions.Where(v => IsPackageVersionUpToDate(v, applicationVersion)).ToArray();
+ }
- return packages;
+ if (p.versions.Length == 0)
+ {
+ continue;
+ }
+
+ returnList.Add(p);
+ }
+
+ return returnList;
}
/// <summary>
@@ -418,30 +442,24 @@ namespace Emby.Server.Implementations.Updates
/// <returns>Task{IEnumerable{PackageVersionInfo}}.</returns>
public async Task<IEnumerable<PackageVersionInfo>> GetAvailablePluginUpdates(Version applicationVersion, bool withAutoUpdateEnabled, CancellationToken cancellationToken)
{
- var catalog = await GetAvailablePackagesWithoutRegistrationInfo(cancellationToken).ConfigureAwait(false);
-
- var plugins = _applicationHost.Plugins.ToList();
-
- if (withAutoUpdateEnabled)
+ if (!_config.CommonConfiguration.EnableAutoUpdate)
{
- plugins = plugins
- .Where(p => _config.CommonConfiguration.EnableAutoUpdate)
- .ToList();
+ return new PackageVersionInfo[] { };
}
+ var catalog = await GetAvailablePackagesWithoutRegistrationInfo(cancellationToken).ConfigureAwait(false);
+
var systemUpdateLevel = GetSystemUpdateLevel();
// Figure out what needs to be installed
- var packages = plugins.Select(p =>
+ return _applicationHost.Plugins.Select(p =>
{
var latestPluginInfo = GetLatestCompatibleVersion(catalog, p.Name, p.Id.ToString(), applicationVersion, systemUpdateLevel);
return latestPluginInfo != null && GetPackageVersion(latestPluginInfo) > p.Version ? latestPluginInfo : null;
- }).Where(i => i != null).ToList();
-
- return packages
- .Where(p => !string.IsNullOrWhiteSpace(p.sourceUrl) && !CompletedInstallations.Any(i => string.Equals(i.AssemblyGuid, p.guid, StringComparison.OrdinalIgnoreCase)));
+ }).Where(i => i != null)
+ .Where(p => !string.IsNullOrWhiteSpace(p.sourceUrl) && !CompletedInstallations.Any(i => string.Equals(i.AssemblyGuid, p.guid, StringComparison.OrdinalIgnoreCase)));
}
/// <summary>
diff --git a/Emby.Server.Implementations/packages.config b/Emby.Server.Implementations/packages.config
index 8d4d24995..5b869221a 100644
--- a/Emby.Server.Implementations/packages.config
+++ b/Emby.Server.Implementations/packages.config
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Emby.XmlTv" version="1.0.10" targetFramework="net46" />
- <package id="MediaBrowser.Naming" version="1.0.6" targetFramework="net46" />
+ <package id="MediaBrowser.Naming" version="1.0.7" targetFramework="net46" />
<package id="ServiceStack.Text" version="4.5.8" targetFramework="net46" />
<package id="SharpCompress" version="0.14.0" targetFramework="net46" />
<package id="SimpleInjector" version="4.0.8" targetFramework="net46" />