aboutsummaryrefslogtreecommitdiff
path: root/Emby.Server.Implementations
diff options
context:
space:
mode:
authorLuke <luke.pulverenti@gmail.com>2017-12-05 13:37:55 -0500
committerGitHub <noreply@github.com>2017-12-05 13:37:55 -0500
commitc32d8656382a0eacb301692e0084377fc433ae9b (patch)
tree121dd382bf71a9b5c96e00771c0ba18a7d28ab87 /Emby.Server.Implementations
parente7ffdf3fbdae7d4ec76a0a4e0e37792b079c56e5 (diff)
parentb3fbdde04305a0406b5322ec6947f8a30ddc12af (diff)
Merge pull request #3055 from MediaBrowser/beta
Beta
Diffstat (limited to 'Emby.Server.Implementations')
-rw-r--r--Emby.Server.Implementations/ApplicationHost.cs125
-rw-r--r--Emby.Server.Implementations/Archiving/ZipClient.cs18
-rw-r--r--Emby.Server.Implementations/Browser/BrowserLauncher.cs2
-rw-r--r--Emby.Server.Implementations/Data/SqliteItemRepository.cs10
-rw-r--r--Emby.Server.Implementations/Emby.Server.Implementations.csproj2
-rw-r--r--Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs3
-rw-r--r--Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs36
-rw-r--r--Emby.Server.Implementations/EntryPoints/StartupWizard.cs33
-rw-r--r--Emby.Server.Implementations/IO/LibraryMonitor.cs7
-rw-r--r--Emby.Server.Implementations/IO/ManagedFileSystem.cs15
-rw-r--r--Emby.Server.Implementations/Library/CoreResolutionIgnoreRule.cs11
-rw-r--r--Emby.Server.Implementations/Library/LibraryManager.cs21
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs20
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs27
-rw-r--r--Emby.Server.Implementations/Library/SearchEngine.cs3
-rw-r--r--Emby.Server.Implementations/Library/UserManager.cs11
-rw-r--r--Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs35
-rw-r--r--Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs70
-rw-r--r--Emby.Server.Implementations/LiveTv/LiveTvManager.cs8
-rw-r--r--Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs2
-rw-r--r--Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs8
-rw-r--r--Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs21
-rw-r--r--Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs25
-rw-r--r--Emby.Server.Implementations/Localization/Core/ca.json126
-rw-r--r--Emby.Server.Implementations/Localization/Core/de.json4
-rw-r--r--Emby.Server.Implementations/Localization/Core/el.json91
-rw-r--r--Emby.Server.Implementations/Localization/Core/es-MX.json2
-rw-r--r--Emby.Server.Implementations/Localization/Core/gsw.json91
-rw-r--r--Emby.Server.Implementations/Localization/Core/pt-BR.json2
-rw-r--r--Emby.Server.Implementations/MediaEncoder/EncodingManager.cs25
-rw-r--r--Emby.Server.Implementations/Networking/NetworkManager.cs64
-rw-r--r--Emby.Server.Implementations/Session/HttpSessionController.cs6
-rw-r--r--Emby.Server.Implementations/Session/SessionManager.cs6
-rw-r--r--Emby.Server.Implementations/Session/WebSocketController.cs6
-rw-r--r--Emby.Server.Implementations/Social/SharingManager.cs5
-rw-r--r--Emby.Server.Implementations/Udp/UdpServer.cs28
36 files changed, 729 insertions, 240 deletions
diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs
index 745d83eb5..26450c06c 100644
--- a/Emby.Server.Implementations/ApplicationHost.cs
+++ b/Emby.Server.Implementations/ApplicationHost.cs
@@ -148,6 +148,34 @@ namespace Emby.Server.Implementations
}
}
+ public virtual bool CanLaunchWebBrowser
+ {
+ get
+ {
+ if (!Environment.UserInteractive)
+ {
+ return false;
+ }
+
+ if (StartupOptions.ContainsOption("-service"))
+ {
+ return false;
+ }
+
+ if (EnvironmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Windows)
+ {
+ return true;
+ }
+
+ if (EnvironmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.OSX)
+ {
+ return true;
+ }
+
+ return false;
+ }
+ }
+
/// <summary>
/// Occurs when [has pending restart changed].
/// </summary>
@@ -361,7 +389,7 @@ namespace Emby.Server.Implementations
protected IAuthService AuthService { get; private set; }
- protected readonly StartupOptions StartupOptions;
+ public StartupOptions StartupOptions { get; private set; }
protected readonly string ReleaseAssetFilename;
internal IPowerManagement PowerManagement { get; private set; }
@@ -393,6 +421,7 @@ namespace Emby.Server.Implementations
ISystemEvents systemEvents,
INetworkManager networkManager)
{
+
// hack alert, until common can target .net core
BaseExtensions.CryptographyProvider = CryptographyProvider;
@@ -423,6 +452,13 @@ namespace Emby.Server.Implementations
SetBaseExceptionMessage();
fileSystem.AddShortcutHandler(new MbLinkShortcutHandler(fileSystem));
+
+ NetworkManager.NetworkChanged += NetworkManager_NetworkChanged;
+ }
+
+ private void NetworkManager_NetworkChanged(object sender, EventArgs e)
+ {
+ _validAddressResults.Clear();
}
private Version _version;
@@ -1901,9 +1937,9 @@ namespace Emby.Server.Implementations
/// Gets the system status.
/// </summary>
/// <returns>SystemInfo.</returns>
- public async Task<SystemInfo> GetSystemInfo()
+ public async Task<SystemInfo> GetSystemInfo(CancellationToken cancellationToken)
{
- var localAddress = await GetLocalApiUrl().ConfigureAwait(false);
+ var localAddress = await GetLocalApiUrl(cancellationToken).ConfigureAwait(false);
return new SystemInfo
{
@@ -1928,6 +1964,7 @@ namespace Emby.Server.Implementations
OperatingSystemDisplayName = OperatingSystemDisplayName,
CanSelfRestart = CanSelfRestart,
CanSelfUpdate = CanSelfUpdate,
+ CanLaunchWebBrowser = CanLaunchWebBrowser,
WanAddress = ConnectManager.WanApiAddress,
HasUpdateAvailable = HasUpdateAvailable,
SupportsAutoRunAtStartup = SupportsAutoRunAtStartup,
@@ -1942,6 +1979,21 @@ namespace Emby.Server.Implementations
};
}
+ public async Task<PublicSystemInfo> GetPublicSystemInfo(CancellationToken cancellationToken)
+ {
+ var localAddress = await GetLocalApiUrl(cancellationToken).ConfigureAwait(false);
+
+ return new PublicSystemInfo
+ {
+ Version = ApplicationVersion.ToString(),
+ Id = SystemId,
+ OperatingSystem = EnvironmentInfo.OperatingSystem.ToString(),
+ WanAddress = ConnectManager.WanApiAddress,
+ ServerName = FriendlyName,
+ LocalAddress = localAddress
+ };
+ }
+
public bool EnableHttps
{
get
@@ -1955,14 +2007,14 @@ namespace Emby.Server.Implementations
get { return Certificate != null || ServerConfigurationManager.Configuration.IsBehindProxy; }
}
- public async Task<string> GetLocalApiUrl()
+ public async Task<string> GetLocalApiUrl(CancellationToken cancellationToken)
{
try
{
// Return the first matched address, if found, or the first known local address
- var address = (await GetLocalIpAddresses().ConfigureAwait(false)).FirstOrDefault(i => !i.Equals(IpAddressInfo.Loopback) && !i.Equals(IpAddressInfo.IPv6Loopback));
+ var addresses = await GetLocalIpAddressesInternal(false, 1, cancellationToken).ConfigureAwait(false);
- if (address != null)
+ foreach (var address in addresses)
{
return GetLocalApiUrl(address);
}
@@ -1994,7 +2046,12 @@ namespace Emby.Server.Implementations
HttpPort.ToString(CultureInfo.InvariantCulture));
}
- public async Task<List<IpAddressInfo>> GetLocalIpAddresses()
+ public Task<List<IpAddressInfo>> GetLocalIpAddresses(CancellationToken cancellationToken)
+ {
+ return GetLocalIpAddressesInternal(true, 0, cancellationToken);
+ }
+
+ private async Task<List<IpAddressInfo>> GetLocalIpAddressesInternal(bool allowLoopback, int limit, CancellationToken cancellationToken)
{
var addresses = ServerConfigurationManager
.Configuration
@@ -2006,22 +2063,33 @@ namespace Emby.Server.Implementations
if (addresses.Count == 0)
{
addresses.AddRange(NetworkManager.GetLocalIpAddresses());
+ }
- var list = new List<IpAddressInfo>();
+ var resultList = new List<IpAddressInfo>();
- foreach (var address in addresses)
+ foreach (var address in addresses)
+ {
+ if (!allowLoopback)
{
- var valid = await IsIpAddressValidAsync(address).ConfigureAwait(false);
- if (valid)
+ if (address.Equals(IpAddressInfo.Loopback) || address.Equals(IpAddressInfo.IPv6Loopback))
{
- list.Add(address);
+ continue;
}
}
- addresses = list;
+ var valid = await IsIpAddressValidAsync(address, cancellationToken).ConfigureAwait(false);
+ if (valid)
+ {
+ resultList.Add(address);
+
+ if (limit > 0 && resultList.Count >= limit)
+ {
+ return resultList;
+ }
+ }
}
- return addresses;
+ return resultList;
}
private IpAddressInfo NormalizeConfiguredLocalAddress(string address)
@@ -2042,8 +2110,7 @@ namespace Emby.Server.Implementations
}
private readonly ConcurrentDictionary<string, bool> _validAddressResults = new ConcurrentDictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
- private DateTime _lastAddressCacheClear;
- private async Task<bool> IsIpAddressValidAsync(IpAddressInfo address)
+ private async Task<bool> IsIpAddressValidAsync(IpAddressInfo address, CancellationToken cancellationToken)
{
if (address.Equals(IpAddressInfo.Loopback) ||
address.Equals(IpAddressInfo.IPv6Loopback))
@@ -2054,12 +2121,6 @@ namespace Emby.Server.Implementations
var apiUrl = GetLocalApiUrl(address);
apiUrl += "/system/ping";
- if ((DateTime.UtcNow - _lastAddressCacheClear).TotalMinutes >= 15)
- {
- _lastAddressCacheClear = DateTime.UtcNow;
- _validAddressResults.Clear();
- }
-
bool cachedResult;
if (_validAddressResults.TryGetValue(apiUrl, out cachedResult))
{
@@ -2075,7 +2136,9 @@ namespace Emby.Server.Implementations
LogErrors = false,
LogRequest = false,
TimeoutMs = 30000,
- BufferContent = false
+ BufferContent = false,
+
+ CancellationToken = cancellationToken
}, "POST").ConfigureAwait(false))
{
@@ -2085,14 +2148,19 @@ namespace Emby.Server.Implementations
var valid = string.Equals(Name, result, StringComparison.OrdinalIgnoreCase);
_validAddressResults.AddOrUpdate(apiUrl, valid, (k, v) => valid);
- //Logger.Debug("Ping test result to {0}. Success: {1}", apiUrl, valid);
+ Logger.Debug("Ping test result to {0}. Success: {1}", apiUrl, valid);
return valid;
}
}
}
+ catch (OperationCanceledException)
+ {
+ Logger.Debug("Ping test result to {0}. Success: {1}", apiUrl, "Cancelled");
+ throw;
+ }
catch
{
- //Logger.Debug("Ping test result to {0}. Success: {1}", apiUrl, false);
+ Logger.Debug("Ping test result to {0}. Success: {1}", apiUrl, false);
_validAddressResults.AddOrUpdate(apiUrl, false, (k, v) => false);
return false;
@@ -2317,12 +2385,11 @@ namespace Emby.Server.Implementations
}
}
- public void LaunchUrl(string url)
+ public virtual void LaunchUrl(string url)
{
- if (EnvironmentInfo.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.Windows &&
- EnvironmentInfo.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.OSX)
+ if (!CanLaunchWebBrowser)
{
- throw new NotImplementedException();
+ throw new NotSupportedException();
}
var process = ProcessFactory.Create(new ProcessOptions
diff --git a/Emby.Server.Implementations/Archiving/ZipClient.cs b/Emby.Server.Implementations/Archiving/ZipClient.cs
index d7d37bb61..32938e151 100644
--- a/Emby.Server.Implementations/Archiving/ZipClient.cs
+++ b/Emby.Server.Implementations/Archiving/ZipClient.cs
@@ -89,6 +89,24 @@ namespace Emby.Server.Implementations.Archiving
}
}
+ public void ExtractFirstFileFromGz(Stream source, string targetPath, string defaultFileName)
+ {
+ using (var reader = GZipReader.Open(source))
+ {
+ if (reader.MoveToNextEntry())
+ {
+ var entry = reader.Entry;
+
+ var filename = entry.Key;
+ if (string.IsNullOrWhiteSpace(filename))
+ {
+ filename = defaultFileName;
+ }
+ reader.WriteEntryToFile(Path.Combine(targetPath, filename));
+ }
+ }
+ }
+
/// <summary>
/// Extracts all from7z.
/// </summary>
diff --git a/Emby.Server.Implementations/Browser/BrowserLauncher.cs b/Emby.Server.Implementations/Browser/BrowserLauncher.cs
index 05cde91e2..71497f6bf 100644
--- a/Emby.Server.Implementations/Browser/BrowserLauncher.cs
+++ b/Emby.Server.Implementations/Browser/BrowserLauncher.cs
@@ -61,7 +61,7 @@ namespace Emby.Server.Implementations.Browser
{
appHost.LaunchUrl(url);
}
- catch (NotImplementedException)
+ catch (NotSupportedException)
{
}
diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
index eb0f5150f..830d6447e 100644
--- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs
+++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
@@ -4286,7 +4286,7 @@ namespace Emby.Server.Implementations.Data
if (query.MinParentalRating.HasValue)
{
- whereClauses.Add("InheritedParentalRatingValue<=@MinParentalRating");
+ whereClauses.Add("InheritedParentalRatingValue>=@MinParentalRating");
if (statement != null)
{
statement.TryBind("@MinParentalRating", query.MinParentalRating.Value);
@@ -5264,7 +5264,13 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
ItemIds = query.ItemIds,
TopParentIds = query.TopParentIds,
ParentId = query.ParentId,
- IsPlayed = query.IsPlayed
+ IsPlayed = query.IsPlayed,
+ IsAiring = query.IsAiring,
+ IsMovie = query.IsMovie,
+ IsSports = query.IsSports,
+ IsKids = query.IsKids,
+ IsNews = query.IsNews,
+ IsSeries = query.IsSeries
};
var innerWhereClauses = GetWhereClauses(innerQuery, null);
diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj
index 7ccf54d20..cef37910e 100644
--- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj
+++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj
@@ -708,6 +708,8 @@
<EmbeddedResource Include="Localization\Core\zh-CN.json" />
<EmbeddedResource Include="Localization\Core\zh-HK.json" />
<EmbeddedResource Include="Localization\Core\en-US.json" />
+ <EmbeddedResource Include="Localization\Core\el.json" />
+ <EmbeddedResource Include="Localization\Core\gsw.json" />
<None Include="packages.config" />
<None Include="TextEncoding\NLangDetect\Profiles\afr" />
<None Include="TextEncoding\NLangDetect\Profiles\ara" />
diff --git a/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs b/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs
index 2cef46839..903bb0ff4 100644
--- a/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs
+++ b/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs
@@ -13,6 +13,7 @@ using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Threading;
using Mono.Nat;
using MediaBrowser.Model.Extensions;
+using System.Threading;
namespace Emby.Server.Implementations.EntryPoints
{
@@ -158,7 +159,7 @@ namespace Emby.Server.Implementations.EntryPoints
try
{
- var localAddressString = await _appHost.GetLocalApiUrl().ConfigureAwait(false);
+ var localAddressString = await _appHost.GetLocalApiUrl(CancellationToken.None).ConfigureAwait(false);
Uri uri;
if (Uri.TryCreate(localAddressString, UriKind.Absolute, out uri))
diff --git a/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs b/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs
index 299da0744..0e771cbec 100644
--- a/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs
+++ b/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs
@@ -260,7 +260,7 @@ namespace Emby.Server.Implementations.EntryPoints
LibraryUpdateTimer.Change(LibraryUpdateDuration, Timeout.Infinite);
}
- var parent = e.Item.GetParent() as Folder;
+ var parent = e.Parent as Folder;
if (parent != null)
{
_foldersRemovedFrom.Add(parent);
@@ -363,10 +363,16 @@ namespace Emby.Server.Implementations.EntryPoints
/// <param name="foldersRemovedFrom">The folders removed from.</param>
/// <param name="userId">The user id.</param>
/// <returns>LibraryUpdateInfo.</returns>
- private LibraryUpdateInfo GetLibraryUpdateInfo(IEnumerable<BaseItem> itemsAdded, IEnumerable<BaseItem> itemsUpdated, IEnumerable<BaseItem> itemsRemoved, IEnumerable<Folder> foldersAddedTo, IEnumerable<Folder> foldersRemovedFrom, Guid userId)
+ private LibraryUpdateInfo GetLibraryUpdateInfo(List<BaseItem> itemsAdded, List<BaseItem> itemsUpdated, List<BaseItem> itemsRemoved, List<Folder> foldersAddedTo, List<Folder> foldersRemovedFrom, Guid userId)
{
var user = _userManager.GetUserById(userId);
+ var newAndRemoved = new List<BaseItem>();
+ newAndRemoved.AddRange(foldersAddedTo);
+ newAndRemoved.AddRange(foldersRemovedFrom);
+
+ var allUserRootChildren = _libraryManager.GetUserRootFolder().GetChildren(user, true).OfType<Folder>().ToList();
+
return new LibraryUpdateInfo
{
ItemsAdded = itemsAdded.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToArray(),
@@ -377,7 +383,9 @@ namespace Emby.Server.Implementations.EntryPoints
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().ToArray()
+ FoldersRemovedFrom = foldersRemovedFrom.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToArray(),
+
+ CollectionFolders = GetTopParentIds(newAndRemoved, user, allUserRootChildren).ToArray()
};
}
@@ -396,6 +404,28 @@ namespace Emby.Server.Implementations.EntryPoints
return item.SourceType == SourceType.Library;
}
+ private IEnumerable<string> GetTopParentIds(List<BaseItem> items, User user, List<Folder> allUserRootChildren)
+ {
+ var list = new List<string>();
+
+ foreach (var item in items)
+ {
+ // If the physical root changed, return the user root
+ if (item is AggregateFolder)
+ {
+ continue;
+ }
+
+ var collectionFolders = _libraryManager.GetCollectionFolders(item, allUserRootChildren);
+ foreach (var folder in allUserRootChildren)
+ {
+ list.Add(folder.Id.ToString("N"));
+ }
+ }
+
+ return list.Distinct(StringComparer.Ordinal);
+ }
+
/// <summary>
/// Translates the physical item to user library.
/// </summary>
diff --git a/Emby.Server.Implementations/EntryPoints/StartupWizard.cs b/Emby.Server.Implementations/EntryPoints/StartupWizard.cs
index 614c04fd2..103b4b321 100644
--- a/Emby.Server.Implementations/EntryPoints/StartupWizard.cs
+++ b/Emby.Server.Implementations/EntryPoints/StartupWizard.cs
@@ -3,6 +3,7 @@ using Emby.Server.Implementations.Browser;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Plugins;
using MediaBrowser.Model.Logging;
+using MediaBrowser.Controller.Configuration;
namespace Emby.Server.Implementations.EntryPoints
{
@@ -20,15 +21,13 @@ namespace Emby.Server.Implementations.EntryPoints
/// </summary>
private readonly ILogger _logger;
- /// <summary>
- /// Initializes a new instance of the <see cref="StartupWizard" /> class.
- /// </summary>
- /// <param name="appHost">The app host.</param>
- /// <param name="logger">The logger.</param>
- public StartupWizard(IServerApplicationHost appHost, ILogger logger)
+ private IServerConfigurationManager _config;
+
+ public StartupWizard(IServerApplicationHost appHost, ILogger logger, IServerConfigurationManager config)
{
_appHost = appHost;
_logger = logger;
+ _config = config;
}
/// <summary>
@@ -36,18 +35,24 @@ namespace Emby.Server.Implementations.EntryPoints
/// </summary>
public void Run()
{
+ if (!_appHost.CanLaunchWebBrowser)
+ {
+ return;
+ }
+
if (_appHost.IsFirstRun)
{
- LaunchStartupWizard();
+ BrowserLauncher.OpenDashboardPage("wizardstart.html", _appHost);
}
- }
+ else if (_config.Configuration.IsStartupWizardCompleted && _config.Configuration.AutoRunWebApp)
+ {
+ var options = ((ApplicationHost)_appHost).StartupOptions;
- /// <summary>
- /// Launches the startup wizard.
- /// </summary>
- private void LaunchStartupWizard()
- {
- BrowserLauncher.OpenDashboardPage("wizardstart.html", _appHost);
+ if (!options.ContainsOption("-noautorunwebapp"))
+ {
+ BrowserLauncher.OpenDashboardPage("index.html", _appHost);
+ }
+ }
}
/// <summary>
diff --git a/Emby.Server.Implementations/IO/LibraryMonitor.cs b/Emby.Server.Implementations/IO/LibraryMonitor.cs
index c99b601c9..a2abb2a5c 100644
--- a/Emby.Server.Implementations/IO/LibraryMonitor.cs
+++ b/Emby.Server.Implementations/IO/LibraryMonitor.cs
@@ -237,7 +237,7 @@ namespace Emby.Server.Implementations.IO
/// <param name="e">The <see cref="ItemChangeEventArgs"/> instance containing the event data.</param>
void LibraryManager_ItemRemoved(object sender, ItemChangeEventArgs e)
{
- if (e.Item.GetParent() is AggregateFolder)
+ if (e.Parent is AggregateFolder)
{
StopWatchingPath(e.Item.Path);
}
@@ -250,7 +250,7 @@ namespace Emby.Server.Implementations.IO
/// <param name="e">The <see cref="ItemChangeEventArgs"/> instance containing the event data.</param>
void LibraryManager_ItemAdded(object sender, ItemChangeEventArgs e)
{
- if (e.Item.GetParent() is AggregateFolder)
+ if (e.Parent is AggregateFolder)
{
StartWatching(e.Item);
}
@@ -320,7 +320,8 @@ namespace Emby.Server.Implementations.IO
IncludeSubdirectories = true
};
- if (_environmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Windows)
+ if (_environmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Windows ||
+ _environmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.OSX)
{
newWatcher.InternalBufferSize = 32767;
}
diff --git a/Emby.Server.Implementations/IO/ManagedFileSystem.cs b/Emby.Server.Implementations/IO/ManagedFileSystem.cs
index 125d9e980..c8e4031a9 100644
--- a/Emby.Server.Implementations/IO/ManagedFileSystem.cs
+++ b/Emby.Server.Implementations/IO/ManagedFileSystem.cs
@@ -473,6 +473,11 @@ namespace Emby.Server.Implementations.IO
public void SetHidden(string path, bool isHidden)
{
+ if (_environmentInfo.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.Windows)
+ {
+ return;
+ }
+
if (_sharpCifsFileSystem.IsEnabledForPath(path))
{
_sharpCifsFileSystem.SetHidden(path, isHidden);
@@ -498,6 +503,11 @@ namespace Emby.Server.Implementations.IO
public void SetReadOnly(string path, bool isReadOnly)
{
+ if (_environmentInfo.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.Windows)
+ {
+ return;
+ }
+
if (_sharpCifsFileSystem.IsEnabledForPath(path))
{
_sharpCifsFileSystem.SetReadOnly(path, isReadOnly);
@@ -523,6 +533,11 @@ namespace Emby.Server.Implementations.IO
public void SetAttributes(string path, bool isHidden, bool isReadOnly)
{
+ if (_environmentInfo.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.Windows)
+ {
+ return;
+ }
+
if (_sharpCifsFileSystem.IsEnabledForPath(path))
{
_sharpCifsFileSystem.SetAttributes(path, isHidden, isReadOnly);
diff --git a/Emby.Server.Implementations/Library/CoreResolutionIgnoreRule.cs b/Emby.Server.Implementations/Library/CoreResolutionIgnoreRule.cs
index 961f9886c..5c3e1dab1 100644
--- a/Emby.Server.Implementations/Library/CoreResolutionIgnoreRule.cs
+++ b/Emby.Server.Implementations/Library/CoreResolutionIgnoreRule.cs
@@ -141,17 +141,6 @@ namespace Emby.Server.Implementations.Library
return true;
}
}
-
- // Ignore samples
- var sampleFilename = " " + filename.Replace(".", " ", StringComparison.OrdinalIgnoreCase)
- .Replace("-", " ", StringComparison.OrdinalIgnoreCase)
- .Replace("_", " ", StringComparison.OrdinalIgnoreCase)
- .Replace("!", " ", StringComparison.OrdinalIgnoreCase);
-
- if (sampleFilename.IndexOf(" sample ", StringComparison.OrdinalIgnoreCase) != -1)
- {
- return true;
- }
}
return false;
diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs
index f71e2714a..2934a5147 100644
--- a/Emby.Server.Implementations/Library/LibraryManager.cs
+++ b/Emby.Server.Implementations/Library/LibraryManager.cs
@@ -443,7 +443,7 @@ namespace Emby.Server.Implementations.Library
BaseItem removed;
_libraryItemsCache.TryRemove(item.Id, out removed);
- ReportItemRemoved(item);
+ ReportItemRemoved(item, parent);
}
private IEnumerable<string> GetMetadataPaths(BaseItem item, IEnumerable<BaseItem> children)
@@ -1804,7 +1804,7 @@ namespace Emby.Server.Implementations.Library
/// <returns>Task.</returns>
public void CreateItem(BaseItem item, CancellationToken cancellationToken)
{
- CreateItems(new[] { item }, cancellationToken);
+ CreateItems(new[] { item }, item.GetParent(), cancellationToken);
}
/// <summary>
@@ -1813,7 +1813,7 @@ namespace Emby.Server.Implementations.Library
/// <param name="items">The items.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
- public void CreateItems(IEnumerable<BaseItem> items, CancellationToken cancellationToken)
+ public void CreateItems(IEnumerable<BaseItem> items, BaseItem parent, CancellationToken cancellationToken)
{
var list = items.ToList();
@@ -1830,7 +1830,11 @@ namespace Emby.Server.Implementations.Library
{
try
{
- ItemAdded(this, new ItemChangeEventArgs { Item = item });
+ ItemAdded(this, new ItemChangeEventArgs
+ {
+ Item = item,
+ Parent = parent ?? item.GetParent()
+ });
}
catch (Exception ex)
{
@@ -1878,6 +1882,7 @@ namespace Emby.Server.Implementations.Library
ItemUpdated(this, new ItemChangeEventArgs
{
Item = item,
+ Parent = item.GetParent(),
UpdateReason = updateReason
});
}
@@ -1892,13 +1897,17 @@ namespace Emby.Server.Implementations.Library
/// Reports the item removed.
/// </summary>
/// <param name="item">The item.</param>
- public void ReportItemRemoved(BaseItem item)
+ public void ReportItemRemoved(BaseItem item, BaseItem parent)
{
if (ItemRemoved != null)
{
try
{
- ItemRemoved(this, new ItemChangeEventArgs { Item = item });
+ ItemRemoved(this, new ItemChangeEventArgs
+ {
+ Item = item,
+ Parent = parent
+ });
}
catch (Exception ex)
{
diff --git a/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
index 667616414..d74235ec7 100644
--- a/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
@@ -126,10 +126,6 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
{
leftOver.Add(child);
}
- else if (IsIgnored(child.Name))
- {
-
- }
else
{
files.Add(child);
@@ -298,22 +294,6 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
return item;
}
- private bool IsIgnored(string filename)
- {
- // Ignore samples
- var sampleFilename = " " + filename.Replace(".", " ", StringComparison.OrdinalIgnoreCase)
- .Replace("-", " ", StringComparison.OrdinalIgnoreCase)
- .Replace("_", " ", StringComparison.OrdinalIgnoreCase)
- .Replace("!", " ", StringComparison.OrdinalIgnoreCase);
-
- if (sampleFilename.IndexOf(" sample ", StringComparison.OrdinalIgnoreCase) != -1)
- {
- return true;
- }
-
- return false;
- }
-
/// <summary>
/// Sets the initial item values.
/// </summary>
diff --git a/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs b/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs
index a0ff29482..3bad69b56 100644
--- a/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs
@@ -5,6 +5,7 @@ using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Globalization;
using Emby.Naming.Common;
using Emby.Naming.TV;
+using MediaBrowser.Model.Logging;
namespace Emby.Server.Implementations.Library.Resolvers.TV
{
@@ -21,16 +22,18 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV
private readonly ILibraryManager _libraryManager;
private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
private readonly ILocalizationManager _localization;
+ private readonly ILogger _logger;
/// <summary>
/// Initializes a new instance of the <see cref="SeasonResolver"/> class.
/// </summary>
/// <param name="config">The config.</param>
- public SeasonResolver(IServerConfigurationManager config, ILibraryManager libraryManager, ILocalizationManager localization)
+ public SeasonResolver(IServerConfigurationManager config, ILibraryManager libraryManager, ILocalizationManager localization, ILogger logger)
{
_config = config;
_libraryManager = libraryManager;
_localization = localization;
+ _logger = logger;
}
/// <summary>
@@ -45,20 +48,40 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV
var namingOptions = ((LibraryManager)_libraryManager).GetNamingOptions();
var series = ((Series)args.Parent);
+ var path = args.Path;
+
var season = new Season
{
- IndexNumber = new SeasonPathParser(namingOptions, new RegexProvider()).Parse(args.Path, true, true).SeasonNumber,
+ IndexNumber = new SeasonPathParser(namingOptions, new RegexProvider()).Parse(path, true, true).SeasonNumber,
SeriesId = series.Id,
SeriesName = series.Name
};
if (season.IndexNumber.HasValue)
{
+ var resolver = new Emby.Naming.TV.EpisodeResolver(namingOptions);
+
+ var episodeInfo = resolver.Resolve(path, true);
+
+ if (episodeInfo != null)
+ {
+ if (episodeInfo.EpisodeNumber.HasValue && episodeInfo.SeasonNumber.HasValue)
+ {
+ _logger.Info("Found folder underneath series with episode number: {0}. Season {1}. Episode {2}",
+ path,
+ episodeInfo.SeasonNumber.Value,
+ episodeInfo.EpisodeNumber.Value);
+
+ return null;
+ }
+ }
+
var seasonNumber = season.IndexNumber.Value;
season.Name = seasonNumber == 0 ?
args.LibraryOptions.SeasonZeroDisplayName :
string.Format(_localization.GetLocalizedString("NameSeasonNumber"), seasonNumber.ToString(UsCulture), args.GetLibraryOptions().PreferredMetadataLanguage);
+
}
return season;
diff --git a/Emby.Server.Implementations/Library/SearchEngine.cs b/Emby.Server.Implementations/Library/SearchEngine.cs
index df21c1409..8021399bd 100644
--- a/Emby.Server.Implementations/Library/SearchEngine.cs
+++ b/Emby.Server.Implementations/Library/SearchEngine.cs
@@ -191,7 +191,8 @@ namespace Emby.Server.Implementations.Library
{
ItemFields.AirTime,
ItemFields.DateCreated,
- ItemFields.ChannelInfo
+ ItemFields.ChannelInfo,
+ ItemFields.ParentId
}
}
};
diff --git a/Emby.Server.Implementations/Library/UserManager.cs b/Emby.Server.Implementations/Library/UserManager.cs
index 0f48ff46b..71c953b2c 100644
--- a/Emby.Server.Implementations/Library/UserManager.cs
+++ b/Emby.Server.Implementations/Library/UserManager.cs
@@ -218,7 +218,7 @@ namespace Emby.Server.Implementations.Library
return builder.ToString();
}
- public async Task<User> AuthenticateUser(string username, string password, string hashedPassword, string passwordMd5, string remoteEndPoint)
+ public async Task<User> AuthenticateUser(string username, string password, string hashedPassword, string passwordMd5, string remoteEndPoint, bool isUserSession)
{
if (string.IsNullOrWhiteSpace(username))
{
@@ -288,8 +288,11 @@ namespace Emby.Server.Implementations.Library
// Update LastActivityDate and LastLoginDate, then save
if (success)
{
- user.LastActivityDate = user.LastLoginDate = DateTime.UtcNow;
- UpdateUser(user);
+ if (isUserSession)
+ {
+ user.LastActivityDate = user.LastLoginDate = DateTime.UtcNow;
+ UpdateUser(user);
+ }
UpdateInvalidLoginAttemptCount(user, 0);
}
else
@@ -812,7 +815,7 @@ namespace Emby.Server.Implementations.Library
var text = new StringBuilder();
- var localAddress = _appHost.GetLocalApiUrl().Result ?? string.Empty;
+ var localAddress = _appHost.GetLocalApiUrl(CancellationToken.None).Result ?? string.Empty;
text.AppendLine("Use your web browser to visit:");
text.AppendLine(string.Empty);
diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
index 9992c71ec..35d2d3c0a 100644
--- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
+++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
@@ -1512,6 +1512,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
}
}
+ DeleteFileIfEmpty(recordPath);
+
TriggerRefresh(recordPath);
_libraryMonitor.ReportFileSystemChangeComplete(recordPath, false);
@@ -1542,6 +1544,23 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
}
}
+ private void DeleteFileIfEmpty(string path)
+ {
+ var file = _fileSystem.GetFileInfo(path);
+
+ if (file.Exists && file.Length == 0)
+ {
+ try
+ {
+ _fileSystem.DeleteFile(path);
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error deleting 0-byte failed recording file {0}", ex, path);
+ }
+ }
+ }
+
private void TriggerRefresh(string path)
{
_logger.Info("Triggering refresh on {0}", path);
@@ -1897,7 +1916,15 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
imageSaveFilenameWithoutExtension = "logo";
break;
case ImageType.Thumb:
- imageSaveFilenameWithoutExtension = "landscape";
+ if (program.IsSeries)
+ {
+ imageSaveFilenameWithoutExtension = Path.GetFileNameWithoutExtension(recordingPath) + "-thumb";
+ }
+ else
+ {
+ imageSaveFilenameWithoutExtension = "landscape";
+ }
+
break;
case ImageType.Backdrop:
imageSaveFilenameWithoutExtension = "fanart";
@@ -1921,9 +1948,11 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
private async Task SaveRecordingImages(string recordingPath, LiveTvProgram program)
{
- var image = program.GetImageInfo(ImageType.Primary, 0);
+ var image = program.IsSeries ?
+ (program.GetImageInfo(ImageType.Thumb, 0) ?? program.GetImageInfo(ImageType.Primary, 0)) :
+ (program.GetImageInfo(ImageType.Primary, 0) ?? program.GetImageInfo(ImageType.Thumb, 0));
- if (image != null && program.IsMovie)
+ if (image != null)
{
try
{
diff --git a/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs b/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs
index 95ec1dee0..7c251e303 100644
--- a/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs
+++ b/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs
@@ -105,31 +105,64 @@ namespace Emby.Server.Implementations.LiveTv.Listings
if (string.Equals(ext, ".gz", StringComparison.OrdinalIgnoreCase))
{
- using (var stream = _fileSystem.OpenRead(file))
+ try
{
- var tempFolder = Path.Combine(_config.ApplicationPaths.TempDirectory, Guid.NewGuid().ToString());
- _fileSystem.CreateDirectory(tempFolder);
-
- try
- {
- _zipClient.ExtractAllFromGz(stream, tempFolder, true);
- }
- catch
- {
- // If the extraction fails just return the original file, it could be a gz
- return file;
- }
+ var tempFolder = ExtractGz(file);
+ return FindXmlFile(tempFolder);
+ }
+ catch (Exception ex)
+ {
+ //_logger.ErrorException("Error extracting from gz file {0}", ex, file);
+ }
- return _fileSystem.GetFiles(tempFolder, true)
- .Where(i => string.Equals(i.Extension, ".xml", StringComparison.OrdinalIgnoreCase))
- .Select(i => i.FullName)
- .FirstOrDefault();
+ try
+ {
+ var tempFolder = ExtractFirstFileFromGz(file);
+ return FindXmlFile(tempFolder);
+ }
+ catch (Exception ex)
+ {
+ //_logger.ErrorException("Error extracting from zip file {0}", ex, file);
}
}
return file;
}
+ private string ExtractFirstFileFromGz(string file)
+ {
+ using (var stream = _fileSystem.OpenRead(file))
+ {
+ var tempFolder = Path.Combine(_config.ApplicationPaths.TempDirectory, Guid.NewGuid().ToString());
+ _fileSystem.CreateDirectory(tempFolder);
+
+ _zipClient.ExtractFirstFileFromGz(stream, tempFolder, "data.xml");
+
+ return tempFolder;
+ }
+ }
+
+ private string ExtractGz(string file)
+ {
+ using (var stream = _fileSystem.OpenRead(file))
+ {
+ var tempFolder = Path.Combine(_config.ApplicationPaths.TempDirectory, Guid.NewGuid().ToString());
+ _fileSystem.CreateDirectory(tempFolder);
+
+ _zipClient.ExtractAllFromGz(stream, tempFolder, true);
+
+ return tempFolder;
+ }
+ }
+
+ private string FindXmlFile(string directory)
+ {
+ return _fileSystem.GetFiles(directory, true)
+ .Where(i => string.Equals(i.Extension, ".xml", StringComparison.OrdinalIgnoreCase))
+ .Select(i => i.FullName)
+ .FirstOrDefault();
+ }
+
public async Task<IEnumerable<ProgramInfo>> GetProgramsAsync(ListingsProviderInfo info, string channelId, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken)
{
if (string.IsNullOrWhiteSpace(channelId))
@@ -149,6 +182,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
_logger.Debug("Getting xmltv programs for channel {0}", channelId);
var path = await GetXml(info.Path, cancellationToken).ConfigureAwait(false);
+ _logger.Debug("Opening XmlTvReader for {0}", path);
var reader = new XmlTvReader(path, GetLanguage(info));
var results = reader.GetProgrammes(channelId, startDateUtc, endDateUtc, cancellationToken);
@@ -251,6 +285,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
{
// In theory this should never be called because there is always only one lineup
var path = await GetXml(info.Path, CancellationToken.None).ConfigureAwait(false);
+ _logger.Debug("Opening XmlTvReader for {0}", path);
var reader = new XmlTvReader(path, GetLanguage(info));
var results = reader.GetChannels();
@@ -262,6 +297,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
{
// In theory this should never be called because there is always only one lineup
var path = await GetXml(info.Path, cancellationToken).ConfigureAwait(false);
+ _logger.Debug("Opening XmlTvReader for {0}", path);
var reader = new XmlTvReader(path, GetLanguage(info));
var results = reader.GetChannels();
diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
index 7e72d1b1a..211e0de4b 100644
--- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
+++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
@@ -125,7 +125,7 @@ namespace Emby.Server.Implementations.LiveTv
public void AddParts(IEnumerable<ILiveTvService> services, IEnumerable<ITunerHost> tunerHosts, IEnumerable<IListingsProvider> listingProviders)
{
_services = services.ToArray();
- _tunerHosts.AddRange(tunerHosts);
+ _tunerHosts.AddRange(tunerHosts.Where(i => i.IsSupported));
_listingProviders.AddRange(listingProviders);
foreach (var service in _services)
@@ -947,6 +947,7 @@ namespace Emby.Server.Implementations.LiveTv
IsKids = query.IsKids,
IsNews = query.IsNews,
Genres = query.Genres,
+ GenreIds = query.GenreIds,
StartIndex = query.StartIndex,
Limit = query.Limit,
OrderBy = query.OrderBy,
@@ -1020,7 +1021,8 @@ namespace Emby.Server.Implementations.LiveTv
EnableTotalRecordCount = query.EnableTotalRecordCount,
OrderBy = new[] { new Tuple<string, SortOrder>(ItemSortBy.StartDate, SortOrder.Ascending) },
TopParentIds = new[] { topFolder.Id.ToString("N") },
- DtoOptions = options
+ DtoOptions = options,
+ GenreIds = query.GenreIds
};
if (query.Limit.HasValue)
@@ -1421,7 +1423,7 @@ namespace Emby.Server.Implementations.LiveTv
if (newPrograms.Count > 0)
{
- _libraryManager.CreateItems(newPrograms, cancellationToken);
+ _libraryManager.CreateItems(newPrograms, null, cancellationToken);
}
// TODO: Do this in bulk
diff --git a/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs b/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs
index ed8b3074b..29b7c41ef 100644
--- a/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs
+++ b/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs
@@ -95,7 +95,7 @@ namespace Emby.Server.Implementations.LiveTv
}
var list = sources.ToList();
- var serverUrl = await _appHost.GetLocalApiUrl().ConfigureAwait(false);
+ var serverUrl = await _appHost.GetLocalApiUrl(cancellationToken).ConfigureAwait(false);
foreach (var source in list)
{
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs
index e0fd32aee..45e96c36d 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs
@@ -39,6 +39,14 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
FileSystem = fileSystem;
}
+ public virtual bool IsSupported
+ {
+ get
+ {
+ return true;
+ }
+ }
+
protected abstract Task<List<ChannelInfo>> GetChannelsInternal(TunerHostInfo tuner, CancellationToken cancellationToken);
public abstract string Type { get; }
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
index c96d1f359..04c5303f1 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
@@ -17,6 +17,7 @@ using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.System;
+using System.IO;
namespace Emby.Server.Implementations.LiveTv.TunerHosts
{
@@ -75,6 +76,14 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
return Task.FromResult(list);
}
+ private string[] _disallowedSharedStreamExtensions = new string[]
+ {
+ ".mkv",
+ ".mp4",
+ ".m3u8",
+ ".mpd"
+ };
+
protected override async Task<ILiveStream> GetChannelStream(TunerHostInfo info, string channelId, string streamId, CancellationToken cancellationToken)
{
var tunerCount = info.TunerCount;
@@ -95,7 +104,12 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
if (mediaSource.Protocol == MediaProtocol.Http && !mediaSource.RequiresLooping)
{
- return new SharedHttpStream(mediaSource, info, streamId, FileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _environment);
+ var extension = Path.GetExtension(mediaSource.Path) ?? string.Empty;
+
+ if (!_disallowedSharedStreamExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase))
+ {
+ return new SharedHttpStream(mediaSource, info, streamId, FileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _environment);
+ }
}
return new LiveStream(mediaSource, info, _environment, FileSystem, Logger, Config.ApplicationPaths);
@@ -152,6 +166,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
isRemote = !_networkManager.IsInLocalNetwork(uri.Host);
}
+ var supportsDirectPlay = !info.EnableStreamLooping && info.TunerCount == 0;
+
var mediaSource = new MediaSourceInfo
{
Path = path,
@@ -183,7 +199,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
IsInfiniteStream = true,
IsRemote = isRemote,
- IgnoreDts = true
+ IgnoreDts = true,
+ SupportsDirectPlay = supportsDirectPlay
};
mediaSource.InferTotalBitrate();
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs
index cc2cb3e5e..af7491e86 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs
@@ -71,7 +71,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
}
else if (contentType.IndexOf("mp4", StringComparison.OrdinalIgnoreCase) != -1 ||
contentType.IndexOf("dash", StringComparison.OrdinalIgnoreCase) != -1 ||
- contentType.IndexOf("mpegURL", StringComparison.OrdinalIgnoreCase) != -1)
+ contentType.IndexOf("mpegURL", StringComparison.OrdinalIgnoreCase) != -1 ||
+ contentType.IndexOf("text/", StringComparison.OrdinalIgnoreCase) != -1)
{
requiresRemux = true;
}
@@ -88,6 +89,9 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
SetTempFilePath(extension);
var taskCompletionSource = new TaskCompletionSource<bool>();
+
+ var now = DateTime.UtcNow;
+
StartStreaming(response, taskCompletionSource, LiveStreamCancellationTokenSource.Token);
//OpenedMediaSource.Protocol = MediaProtocol.File;
@@ -97,11 +101,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
OpenedMediaSource.Path = _appHost.GetLocalApiUrl("127.0.0.1") + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts";
OpenedMediaSource.Protocol = MediaProtocol.Http;
- if (OpenedMediaSource.SupportsProbing)
- {
- await Task.Delay(3000).ConfigureAwait(false);
- }
-
//OpenedMediaSource.Path = TempFilePath;
//OpenedMediaSource.Protocol = MediaProtocol.File;
@@ -111,6 +110,20 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
//OpenedMediaSource.SupportsDirectStream = true;
//OpenedMediaSource.SupportsTranscoding = true;
await taskCompletionSource.Task.ConfigureAwait(false);
+
+ if (OpenedMediaSource.SupportsProbing)
+ {
+ var elapsed = (DateTime.UtcNow - now).TotalMilliseconds;
+
+ var delay = Convert.ToInt32(3000 - elapsed);
+
+ if (delay > 0)
+ {
+ Logger.Info("Delaying shared stream by {0}ms to allow the buffer to build.", delay);
+
+ await Task.Delay(delay).ConfigureAwait(false);
+ }
+ }
}
protected override void CloseInternal()
diff --git a/Emby.Server.Implementations/Localization/Core/ca.json b/Emby.Server.Implementations/Localization/Core/ca.json
index f21a0b295..7c55540e5 100644
--- a/Emby.Server.Implementations/Localization/Core/ca.json
+++ b/Emby.Server.Implementations/Localization/Core/ca.json
@@ -1,74 +1,74 @@
{
"Latest": "Darreres",
"ValueSpecialEpisodeName": "Especial - {0}",
- "Inherit": "Inherit",
- "Books": "Books",
- "Music": "Music",
- "Games": "Games",
- "Photos": "Photos",
- "MixedContent": "Mixed content",
- "MusicVideos": "Music videos",
- "HomeVideos": "Home videos",
- "Playlists": "Playlists",
- "HeaderRecordingGroups": "Recording Groups",
+ "Inherit": "Heretat",
+ "Books": "Llibres",
+ "Music": "M\u00fasica",
+ "Games": "Jocs",
+ "Photos": "Fotos",
+ "MixedContent": "Contingut mesclat",
+ "MusicVideos": "V\u00eddeos musicals",
+ "HomeVideos": "V\u00eddeos dom\u00e8stics",
+ "Playlists": "Llistes de reproducci\u00f3",
+ "HeaderRecordingGroups": "Grups d'Enregistrament",
"HeaderContinueWatching": "Continua Veient",
- "HeaderFavoriteArtists": "Favorite Artists",
- "HeaderFavoriteSongs": "Favorite Songs",
+ "HeaderFavoriteArtists": "Artistes Preferits",
+ "HeaderFavoriteSongs": "Can\u00e7ons Preferides",
"HeaderAlbumArtists": "Album Artists",
- "HeaderFavoriteAlbums": "Favorite Albums",
- "HeaderFavoriteEpisodes": "Favorite Episodes",
+ "HeaderFavoriteAlbums": "\u00c0lbums Preferits",
+ "HeaderFavoriteEpisodes": "Episodis Preferits",
"HeaderFavoriteShows": "Programes Preferits",
"HeaderNextUp": "A continuaci\u00f3",
- "Favorites": "Favorites",
- "Collections": "Collections",
- "Channels": "Channels",
- "Movies": "Movies",
- "Albums": "Albums",
- "Artists": "Artists",
- "Folders": "Folders",
- "Songs": "Songs",
- "TvShows": "TV Shows",
- "Shows": "Shows",
+ "Favorites": "Preferits",
+ "Collections": "Col\u00b7leccions",
+ "Channels": "Canals",
+ "Movies": "Pel\u00b7l\u00edcules",
+ "Albums": "\u00c0lbums",
+ "Artists": "Artistes",
+ "Folders": "Directoris",
+ "Songs": "Can\u00e7ons",
+ "TvShows": "Espectacles de TV",
+ "Shows": "Espectacles",
"Genres": "G\u00e8neres",
- "NameSeasonNumber": "Season {0}",
- "AppDeviceValues": "App: {0}, Device: {1}",
- "UserDownloadingItemWithValues": "{0} is downloading {1}",
- "HeaderLiveTV": "Live TV",
- "ChapterNameValue": "Chapter {0}",
- "ScheduledTaskFailedWithName": "{0} failed",
- "LabelRunningTimeValue": "Running time: {0}",
- "ScheduledTaskStartedWithName": "{0} started",
- "VersionNumber": "Version {0}",
- "PluginInstalledWithName": "{0} was installed",
- "StartupEmbyServerIsLoading": "Emby Server is loading. Please try again shortly.",
- "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}",
- "UserCreatedWithName": "User {0} has been created",
- "UserPasswordChangedWithName": "Password has been changed for user {0}",
- "UserDeletedWithName": "User {0} has been deleted",
- "UserConfigurationUpdatedWithName": "User configuration has been updated for {0}",
- "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",
- "UserOfflineFromDevice": "{0} has disconnected from {1}",
- "DeviceOfflineWithName": "{0} has disconnected",
- "UserStartedPlayingItemWithValues": "{0} has started playing {1}",
- "UserStoppedPlayingItemWithValues": "{0} has stopped playing {1}",
- "NotificationOptionPluginError": "Plugin failure",
- "NotificationOptionApplicationUpdateAvailable": "Application update available",
- "NotificationOptionApplicationUpdateInstalled": "Application update installed",
- "NotificationOptionPluginUpdateInstalled": "Plugin update installed",
- "NotificationOptionPluginInstalled": "Plugin installed",
- "NotificationOptionPluginUninstalled": "Plugin uninstalled",
+ "NameSeasonNumber": "Temporada {0}",
+ "AppDeviceValues": "App: {0}, Dispositiu: {1}",
+ "UserDownloadingItemWithValues": "{0} est\u00e0 descarregant {1}",
+ "HeaderLiveTV": "TV en Directe",
+ "ChapterNameValue": "Episodi {0}",
+ "ScheduledTaskFailedWithName": "{0} ha fallat",
+ "LabelRunningTimeValue": "Temps en marxa: {0}",
+ "ScheduledTaskStartedWithName": "{0} iniciat",
+ "VersionNumber": "Versi\u00f3 {0}",
+ "PluginInstalledWithName": "{0} ha estat instal\u00b7lat",
+ "StartupEmbyServerIsLoading": "El Servidor d'Emby est&agrave; carregant. Si et plau, prova de nou en breus.",
+ "PluginUpdatedWithName": "{0} ha estat actualitzat",
+ "PluginUninstalledWithName": "{0} ha estat desinstal\u00b7lat",
+ "ItemAddedWithName": "{0} afegit a la biblioteca",
+ "ItemRemovedWithName": "{0} eliminat de la biblioteca",
+ "LabelIpAddressValue": "Adre\u00e7a IP: {0}",
+ "DeviceOnlineWithName": "{0} est\u00e0 connectat",
+ "UserOnlineFromDevice": "{0} est\u00e0 connectat des de {1}",
+ "ProviderValue": "Prove\u00efdor: {0}",
+ "SubtitlesDownloadedForItem": "Subt\u00edtols descarregats per a {0}",
+ "UserCreatedWithName": "S'ha creat l'usuari {0}",
+ "UserPasswordChangedWithName": "La contrasenya ha estat canviada per a l'usuari {0}",
+ "UserDeletedWithName": "L'usuari {0} ha estat eliminat",
+ "UserConfigurationUpdatedWithName": "La configuraci\u00f3 d'usuari ha estat actualitzada per a {0}",
+ "MessageServerConfigurationUpdated": "S'ha actualitzat la configuraci\u00f3 del servidor",
+ "MessageNamedServerConfigurationUpdatedWithValue": "La secci\u00f3 de configuraci\u00f3 {0} ha estat actualitzada",
+ "MessageApplicationUpdated": "El Servidor d'Emby ha estat actualitzat",
+ "FailedLoginAttemptWithUserName": "Intent de connexi\u00f3 fallit des de {0}",
+ "AuthenticationSucceededWithUserName": "{0} s'ha autenticat correctament",
+ "UserOfflineFromDevice": "{0} s'ha desconnectat de {1}",
+ "DeviceOfflineWithName": "{0} s'ha desconnectat",
+ "UserStartedPlayingItemWithValues": "{0} ha comen\u00e7at a reproduir {1}",
+ "UserStoppedPlayingItemWithValues": "{0} ha parat de reproduir {1}",
+ "NotificationOptionPluginError": "Un component ha fallat",
+ "NotificationOptionApplicationUpdateAvailable": "Actualitzaci\u00f3 d'aplicaci\u00f3 disponible",
+ "NotificationOptionApplicationUpdateInstalled": "Actualitzaci\u00f3 d'aplicaci\u00f3 instal\u00b7lada",
+ "NotificationOptionPluginUpdateInstalled": "Actualitzaci\u00f3 de complement instal\u00b7lada",
+ "NotificationOptionPluginInstalled": "Complement instal\u00b7lat",
+ "NotificationOptionPluginUninstalled": "Complement desinstal\u00b7lat",
"NotificationOptionVideoPlayback": "Video playback started",
"NotificationOptionAudioPlayback": "Audio playback started",
"NotificationOptionGamePlayback": "Game playback started",
diff --git a/Emby.Server.Implementations/Localization/Core/de.json b/Emby.Server.Implementations/Localization/Core/de.json
index 7bab689eb..bcfadb61c 100644
--- a/Emby.Server.Implementations/Localization/Core/de.json
+++ b/Emby.Server.Implementations/Localization/Core/de.json
@@ -7,7 +7,7 @@
"Games": "Spiele",
"Photos": "Fotos",
"MixedContent": "Gemischte Inhalte",
- "MusicVideos": "Musik-Videos",
+ "MusicVideos": "Musikvideos",
"HomeVideos": "Heimvideos",
"Playlists": "Wiedergabelisten",
"HeaderRecordingGroups": "Aufnahme-Gruppen",
@@ -27,7 +27,7 @@
"Artists": "Interpreten",
"Folders": "Verzeichnisse",
"Songs": "Songs",
- "TvShows": "TV Shows",
+ "TvShows": "TV Sendungen",
"Shows": "Serien",
"Genres": "Genres",
"NameSeasonNumber": "Staffel {0}",
diff --git a/Emby.Server.Implementations/Localization/Core/el.json b/Emby.Server.Implementations/Localization/Core/el.json
new file mode 100644
index 000000000..ab229e111
--- /dev/null
+++ b/Emby.Server.Implementations/Localization/Core/el.json
@@ -0,0 +1,91 @@
+{
+ "Latest": "\u03a4\u03b5\u03bb\u03b5\u03c5\u03c4\u03b1\u03af\u03b1",
+ "ValueSpecialEpisodeName": "\u0395\u03b9\u03b4\u03b9\u03ba\u03ac - {0} ",
+ "Inherit": "Inherit",
+ "Books": "\u0392\u03b9\u03b2\u03bb\u03af\u03b1",
+ "Music": "\u039c\u03bf\u03c5\u03c3\u03b9\u03ba\u03ae",
+ "Games": "\u03a0\u03b1\u03b9\u03c7\u03bd\u03af\u03b4\u03b9\u03b1",
+ "Photos": "\u03a6\u03c9\u03c4\u03bf\u03b3\u03c1\u03b1\u03c6\u03af\u03b5\u03c2",
+ "MixedContent": "\u0391\u03bd\u03ac\u03bc\u03b5\u03b9\u03ba\u03c4\u03bf \u03a0\u03b5\u03c1\u03b9\u03b5\u03c7\u03cc\u03bc\u03b5\u03bd\u03bf",
+ "MusicVideos": "\u039c\u03bf\u03c5\u03c3\u03b9\u03ba\u03ac \u03b2\u03af\u03bd\u03c4\u03b5\u03bf",
+ "HomeVideos": "\u03a0\u03c1\u03bf\u03c3\u03c9\u03c0\u03b9\u03ba\u03ac \u0392\u03af\u03bd\u03c4\u03b5\u03bf",
+ "Playlists": "\u039b\u03af\u03c3\u03c4\u03b5\u03c2 \u03b1\u03bd\u03b1\u03c0\u03b1\u03c1\u03b1\u03b3\u03c9\u03b3\u03ae\u03c2",
+ "HeaderRecordingGroups": "\u0393\u03ba\u03c1\u03bf\u03c5\u03c0 \u0395\u03b3\u03b3\u03c1\u03b1\u03c6\u03ce\u03bd",
+ "HeaderContinueWatching": "\u03a3\u03c5\u03bd\u03b5\u03c7\u03af\u03c3\u03c4\u03b5 \u03c4\u03b7\u03bd \u03c0\u03b1\u03c1\u03b1\u03ba\u03bf\u03bb\u03bf\u03cd\u03b8\u03b7\u03c3\u03b7",
+ "HeaderFavoriteArtists": "\u0391\u03b3\u03b1\u03c0\u03b7\u03bc\u03ad\u03bd\u03bf\u03b9 \u039a\u03b1\u03bb\u03bb\u03b9\u03c4\u03ad\u03c7\u03bd\u03b5\u03c2",
+ "HeaderFavoriteSongs": "\u0391\u03b3\u03b1\u03c0\u03b7\u03bc\u03ad\u03bd\u03b1 \u03a4\u03c1\u03b1\u03b3\u03bf\u03cd\u03b4\u03b9\u03b1",
+ "HeaderAlbumArtists": "\u0386\u03bb\u03bc\u03c0\u03bf\u03c5\u03bc \u039a\u03b1\u03bb\u03bb\u03b9\u03c4\u03b5\u03c7\u03bd\u03ce\u03bd",
+ "HeaderFavoriteAlbums": "\u0391\u03b3\u03b1\u03c0\u03b7\u03bc\u03ad\u03bd\u03b1 \u0386\u03bb\u03bc\u03c0\u03bf\u03c5\u03bc",
+ "HeaderFavoriteEpisodes": "\u0391\u03b3\u03b1\u03c0\u03b7\u03bc\u03ad\u03bd\u03b1 \u03b5\u03c0\u03b5\u03b9\u03c3\u03cc\u03b4\u03b9\u03b1",
+ "HeaderFavoriteShows": "\u0391\u03b3\u03b1\u03c0\u03b7\u03bc\u03ad\u03bd\u03b5\u03c2 \u03a3\u03b5\u03b9\u03c1\u03ad\u03c2",
+ "HeaderNextUp": "\u0395\u03c0\u03cc\u03bc\u03b5\u03bd\u03bf",
+ "Favorites": "\u0391\u03b3\u03b1\u03c0\u03b7\u03bc\u03ad\u03bd\u03b1",
+ "Collections": "\u03a3\u03c5\u03bb\u03bb\u03bf\u03b3\u03ad\u03c2",
+ "Channels": "\u039a\u03b1\u03bd\u03ac\u03bb\u03b9\u03b1",
+ "Movies": "\u03a4\u03b1\u03b9\u03bd\u03af\u03b5\u03c2",
+ "Albums": "\u0386\u03bb\u03bc\u03c0\u03bf\u03c5\u03bc",
+ "Artists": "\u039a\u03b1\u03bb\u03bb\u03b9\u03c4\u03ad\u03c7\u03bd\u03b5\u03c2",
+ "Folders": "\u03a6\u03ac\u03ba\u03b5\u03bb\u03bf\u03b9",
+ "Songs": "\u03a4\u03c1\u03b1\u03b3\u03bf\u03cd\u03b4\u03b9\u03b1",
+ "TvShows": "\u03a4\u03b7\u03bb\u03b5\u03bf\u03c0\u03c4\u03b9\u03ba\u03ac \u03c0\u03c1\u03bf\u03b3\u03c1\u03ac\u03bc\u03bc\u03b1\u03c4\u03b1",
+ "Shows": "\u03a3\u03b5\u03b9\u03c1\u03ad\u03c2",
+ "Genres": "\u0395\u03af\u03b4\u03b7",
+ "NameSeasonNumber": "\u039a\u03cd\u03ba\u03bb\u03bf\u03c2 {0}",
+ "AppDeviceValues": "\u0395\u03c6\u03b1\u03c1\u03bc\u03bf\u03b3\u03ae: {0}, \u03a3\u03c5\u03c3\u03ba\u03b5\u03c5\u03ae: {1}",
+ "UserDownloadingItemWithValues": "{0} \u03ba\u03b1\u03c4\u03b5\u03b2\u03ac\u03b6\u03b5\u03b9 {1}",
+ "HeaderLiveTV": "\u0396\u03c9\u03bd\u03c4\u03b1\u03bd\u03ae \u03a4\u03b7\u03bb\u03b5\u03cc\u03c1\u03b1\u03c3\u03b7",
+ "ChapterNameValue": "\u039a\u03b5\u03c6\u03ac\u03bb\u03b1\u03b9\u03bf {0}",
+ "ScheduledTaskFailedWithName": "{0} \u0391\u03c0\u03bf\u03c4\u03c5\u03c7\u03af\u03b1",
+ "LabelRunningTimeValue": "\u0394\u03b9\u03ac\u03c1\u03ba\u03b5\u03b9\u03b1: {0}",
+ "ScheduledTaskStartedWithName": "{0} \u03ad\u03bd\u03b1\u03c1\u03be\u03b7",
+ "VersionNumber": "\u0388\u03ba\u03b4\u03bf\u03c3\u03b7 {0}",
+ "PluginInstalledWithName": "{0} \u03b5\u03b3\u03ba\u03b1\u03c4\u03b1\u03c3\u03c4\u03ae\u03b8\u03b7\u03ba\u03b5",
+ "StartupEmbyServerIsLoading": "\u039f \u03a3\u03ad\u03c1\u03b2\u03b5\u03c1 \u03c6\u03bf\u03c1\u03c4\u03ce\u03bd\u03b5\u03b9. \u03a0\u03b1\u03c1\u03b1\u03ba\u03b1\u03bb\u03ce \u03b4\u03bf\u03ba\u03b9\u03bc\u03ac\u03c3\u03c4\u03b5 \u03c3\u03b5 \u03bb\u03af\u03b3\u03bf",
+ "PluginUpdatedWithName": "{0} \u03ad\u03c7\u03b5\u03b9 \u03b1\u03bd\u03b1\u03b2\u03b1\u03b8\u03bc\u03b9\u03c3\u03c4\u03b5\u03af",
+ "PluginUninstalledWithName": "{0} \u03ad\u03c7\u03b5\u03b9 \u03b1\u03c0\u03b5\u03b3\u03ba\u03b1\u03c4\u03b1\u03c3\u03c4\u03b1\u03b8\u03b5\u03af",
+ "ItemAddedWithName": "{0} \u03c0\u03c1\u03bf\u03c3\u03c4\u03ad\u03b8\u03b7\u03ba\u03b5 \u03c3\u03c4\u03b7 \u03b2\u03b9\u03b2\u03bb\u03b9\u03bf\u03b8\u03ae\u03ba\u03b7",
+ "ItemRemovedWithName": "{0} \u03b4\u03b9\u03b1\u03b3\u03c1\u03ac\u03c6\u03b7\u03ba\u03b5 \u03b1\u03c0\u03cc \u03c4\u03b7 \u03b2\u03b9\u03b2\u03bb\u03b9\u03bf\u03b8\u03ae\u03ba\u03b7",
+ "LabelIpAddressValue": "\u0394\u03b9\u03b5\u03cd\u03b8\u03c5\u03bd\u03c3\u03b7 IP: {0}",
+ "DeviceOnlineWithName": "{0} \u03c3\u03c5\u03bd\u03b4\u03ad\u03b8\u03b7\u03ba\u03b5",
+ "UserOnlineFromDevice": "{0} \u03b5\u03af\u03bd\u03b1\u03b9 \u03c3\u03c5\u03bd\u03b4\u03b5\u03b4\u03b5\u03bc\u03ad\u03bd\u03bf\u03c2 \u03b1\u03c0\u03bf {1}",
+ "ProviderValue": "\u03a0\u03ac\u03c1\u03bf\u03c7\u03bf\u03c2: {0}",
+ "SubtitlesDownloadedForItem": "\u03a5\u03c0\u03cc\u03c4\u03b9\u03c4\u03bb\u03bf\u03b9 \u03bb\u03ae\u03c6\u03b8\u03b7\u03ba\u03b1\u03bd \u03b1\u03c0\u03cc {0}",
+ "UserCreatedWithName": "\u0394\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03ae\u03b8\u03b7\u03ba\u03b5 \u03bf \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7\u03c2 {0}",
+ "UserPasswordChangedWithName": "\u039f \u03ba\u03c9\u03b4\u03b9\u03ba\u03cc\u03c2 \u03c4\u03bf\u03c5 \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7 {0} \u03b1\u03bb\u03bb\u03ac\u03c7\u03b8\u03b7\u03ba\u03b5",
+ "UserDeletedWithName": "\u039f \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7\u03c2 {0} \u03b4\u03b9\u03b5\u03b3\u03c1\u03ac\u03c6\u03b5\u03b9",
+ "UserConfigurationUpdatedWithName": "\u039f\u03b9 \u03c1\u03c5\u03b8\u03bc\u03af\u03c3\u03b5\u03b9\u03c2 \u03c4\u03bf\u03c5 \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7 {0} \u03ad\u03c7\u03bf\u03c5\u03bd \u03b1\u03bb\u03bb\u03ac\u03be\u03b5\u03b9",
+ "MessageServerConfigurationUpdated": "Server configuration has been updated",
+ "MessageNamedServerConfigurationUpdatedWithValue": "\u039f\u03b9 \u03c1\u03c5\u03b8\u03bc\u03af\u03c3\u03b5\u03b9\u03c2 \u03c4\u03bf\u03bc\u03ad\u03b1 \u03c4\u03bf\u03c5 \u03b4\u03b9\u03b1\u03ba\u03bf\u03bc\u03b9\u03c3\u03c4\u03ae {0} \u03ad\u03c7\u03bf\u03c5\u03bd \u03b1\u03bb\u03bb\u03ac\u03be\u03b5\u03b9",
+ "MessageApplicationUpdated": "\u039f \u03a3\u03ad\u03c1\u03b2\u03b5\u03c1 \u03ad\u03c7\u03b5\u03b9 \u03b1\u03bd\u03b1\u03b2\u03b1\u03b8\u03bc\u03b9\u03c3\u03c4\u03b5\u03af",
+ "FailedLoginAttemptWithUserName": "\u0391\u03c0\u03bf\u03c4\u03c5\u03c7\u03af\u03b1 \u03c0\u03c1\u03bf\u03c3\u03c0\u03ac\u03b8\u03b5\u03b9\u03b1 \u03b5\u03b9\u03c3\u03cc\u03b4\u03bf\u03c5 \u03b1\u03c0\u03cc {0}",
+ "AuthenticationSucceededWithUserName": "{0} \u03b5\u03c0\u03b9\u03c4\u03c5\u03c7\u03b5\u03af\u03c2 \u03c3\u03cd\u03bd\u03b4\u03b5\u03c3\u03b7",
+ "UserOfflineFromDevice": "{0} \u03b1\u03c0\u03bf\u03c3\u03c5\u03bd\u03b4\u03ad\u03b8\u03b7\u03ba\u03b5 \u03b1\u03c0\u03cc {1}",
+ "DeviceOfflineWithName": "{0} \u03b1\u03c0\u03bf\u03c3\u03c5\u03bd\u03b4\u03ad\u03b8\u03b7\u03ba\u03b5",
+ "UserStartedPlayingItemWithValues": "{0} \u03be\u03b5\u03ba\u03af\u03bd\u03b7\u03c3\u03b5 \u03bd\u03b1 \u03c0\u03b1\u03af\u03b6\u03b5\u03b9 {1}",
+ "UserStoppedPlayingItemWithValues": "{0} \u03c3\u03c4\u03b1\u03bc\u03ac\u03c4\u03b7\u03c3\u03b5 \u03bd\u03b1 \u03c0\u03b1\u03af\u03b6\u03b5\u03b9 {1}",
+ "NotificationOptionPluginError": "\u0391\u03c0\u03bf\u03c4\u03c5\u03c7\u03af\u03b1 \u03c0\u03c1\u03bf\u03c3\u03b8\u03ad\u03c4\u03bf\u03c5",
+ "NotificationOptionApplicationUpdateAvailable": "\u03a5\u03c0\u03ac\u03c1\u03c7\u03b5\u03b9 \u03b1\u03bd\u03b1\u03b2\u03ac\u03b8\u03bc\u03b9\u03c3\u03b7",
+ "NotificationOptionApplicationUpdateInstalled": "\u0397 \u03b1\u03bd\u03b1\u03b2\u03ac\u03b8\u03bc\u03b9\u03c3\u03b7 \u03bf\u03bb\u03bf\u03ba\u03bb\u03b7\u03c1\u03ce\u03b8\u03b7\u03ba\u03b5",
+ "NotificationOptionPluginUpdateInstalled": "\u0397 \u03b1\u03bd\u03b1\u03b2\u03ac\u03b8\u03bc\u03b9\u03c3\u03b7 \u03c4\u03bf\u03c5 plugin \u03bf\u03bb\u03bf\u03ba\u03bb\u03b7\u03c1\u03ce\u03b8\u03b7\u03ba\u03b5",
+ "NotificationOptionPluginInstalled": "\u03a4\u03bf plugin \u03b5\u03b3\u03ba\u03b1\u03c4\u03b1\u03c3\u03c4\u03ac\u03b8\u03b7\u03ba\u03b5",
+ "NotificationOptionPluginUninstalled": "\u03a4\u03bf plugin \u03b1\u03c0\u03b5\u03b3\u03ba\u03b1\u03c4\u03b1\u03c3\u03c4\u03ac\u03b8\u03b7\u03ba\u03b5",
+ "NotificationOptionVideoPlayback": "\u03a4\u03bf \u03b2\u03af\u03bd\u03c4\u03b5\u03bf \u03c0\u03c1\u03bf\u03b2\u03ac\u03bb\u03bb\u03b5\u03c4\u03b1\u03b9",
+ "NotificationOptionAudioPlayback": "\u0397 \u03bc\u03bf\u03c5\u03c3\u03b9\u03ba\u03ae \u03c0\u03b1\u03af\u03b6\u03b5\u03b9",
+ "NotificationOptionGamePlayback": "\u03a4\u03bf \u03c0\u03b1\u03b9\u03c7\u03bd\u03af\u03b4\u03b9 \u03be\u03b5\u03ba\u03af\u03bd\u03b7\u03c3\u03b5",
+ "NotificationOptionVideoPlaybackStopped": "\u03a4\u03bf \u03b2\u03af\u03bd\u03c4\u03b5\u03bf \u03c3\u03c4\u03b1\u03bc\u03ac\u03c4\u03b7\u03c3\u03b5",
+ "NotificationOptionAudioPlaybackStopped": "\u0397 \u03bc\u03bf\u03c5\u03c3\u03b9\u03ba\u03ae \u03c3\u03c4\u03b1\u03bc\u03ac\u03c4\u03b7\u03c3\u03b5",
+ "NotificationOptionGamePlaybackStopped": "\u03a4\u03bf \u03c0\u03b1\u03b9\u03c7\u03bd\u03af\u03b4\u03b9 \u03c3\u03c4\u03b1\u03bc\u03ac\u03c4\u03b7\u03c3\u03b5",
+ "NotificationOptionTaskFailed": "\u0391\u03c0\u03bf\u03c4\u03c5\u03c7\u03af\u03b1 \u03c0\u03c1\u03bf\u03b3\u03c1\u03b1\u03bc\u03bc\u03b1\u03c4\u03b9\u03c3\u03bc\u03ad\u03bd\u03b7\u03c2 \u03b5\u03c1\u03b3\u03b1\u03c3\u03af\u03b1\u03c2",
+ "NotificationOptionInstallationFailed": "\u0391\u03c0\u03bf\u03c4\u03c5\u03c7\u03af\u03b1 \u03b5\u03b3\u03ba\u03b1\u03c4\u03ac\u03c3\u03c4\u03b1\u03c3\u03b7\u03c2",
+ "NotificationOptionNewLibraryContent": "\u03a0\u03c1\u03bf\u03c3\u03c4\u03ad\u03b8\u03b7\u03ba\u03b5 \u03bd\u03ad\u03bf \u03c0\u03b5\u03c1\u03b9\u03b5\u03c7\u03cc\u03bc\u03b5\u03bd\u03bf",
+ "NotificationOptionCameraImageUploaded": "Camera image uploaded",
+ "NotificationOptionUserLockedOut": "\u039f \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7\u03c2 \u03b1\u03c0\u03bf\u03ba\u03bb\u03b5\u03af\u03c3\u03c4\u03b7\u03ba\u03b5",
+ "NotificationOptionServerRestartRequired": "\u0391\u03c0\u03b1\u03b9\u03c4\u03b5\u03af\u03c4\u03b1\u03b9 \u03b5\u03c0\u03b1\u03bd\u03b5\u03ba\u03ba\u03af\u03bd\u03b7\u03c3\u03b7 \u03c4\u03bf\u03c5 \u03b4\u03b9\u03b1\u03ba\u03bf\u03bc\u03b9\u03c3\u03c4\u03ae",
+ "UserLockedOutWithName": "\u039f \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7\u03c2 {0} \u03b1\u03c0\u03bf\u03ba\u03bb\u03b5\u03af\u03c3\u03c4\u03b7\u03ba\u03b5",
+ "SubtitleDownloadFailureForItem": "\u0391\u03b4\u03c5\u03bd\u03b1\u03bc\u03af\u03b1 \u03bb\u03ae\u03c8\u03b7\u03c2 \u03c5\u03c0\u03bf\u03c4\u03af\u03c4\u03bb\u03c9\u03bd \u03b1\u03c0\u03cc {0}",
+ "Sync": "\u03a3\u03c5\u03b3\u03c7\u03c1\u03bf\u03bd\u03b9\u03c3\u03bc\u03cc\u03c2",
+ "User": "\u03a7\u03c1\u03ae\u03c3\u03c4\u03b7\u03c2",
+ "System": "\u03a3\u03cd\u03c3\u03c4\u03b7\u03bc\u03b1",
+ "Application": "\u0395\u03c6\u03b1\u03c1\u03bc\u03bf\u03b3\u03ae",
+ "Plugin": "\u03a0\u03c1\u03cc\u03c3\u03b8\u03b5\u03c4\u03bf"
+} \ No newline at end of file
diff --git a/Emby.Server.Implementations/Localization/Core/es-MX.json b/Emby.Server.Implementations/Localization/Core/es-MX.json
index 2cc1dd759..8bfaffec8 100644
--- a/Emby.Server.Implementations/Localization/Core/es-MX.json
+++ b/Emby.Server.Implementations/Localization/Core/es-MX.json
@@ -83,7 +83,7 @@
"NotificationOptionServerRestartRequired": "Se necesita reiniciar el Servidor",
"UserLockedOutWithName": "El usuario {0} ha sido bloqueado",
"SubtitleDownloadFailureForItem": "Fall\u00f3 la descarga de subt\u00edtulos para {0}",
- "Sync": "Sinc.",
+ "Sync": "Sincronizar",
"User": "Usuario",
"System": "Sistema",
"Application": "Aplicaci\u00f3n",
diff --git a/Emby.Server.Implementations/Localization/Core/gsw.json b/Emby.Server.Implementations/Localization/Core/gsw.json
new file mode 100644
index 000000000..5c7ff5d6d
--- /dev/null
+++ b/Emby.Server.Implementations/Localization/Core/gsw.json
@@ -0,0 +1,91 @@
+{
+ "Latest": "Letschte",
+ "ValueSpecialEpisodeName": "Spezial - {0}",
+ "Inherit": "Hinzuef\u00fcege",
+ "Books": "B\u00fcecher",
+ "Music": "Musig",
+ "Games": "Spiel",
+ "Photos": "Fotis",
+ "MixedContent": "Gmischte Inhalt",
+ "MusicVideos": "Musigfilm",
+ "HomeVideos": "Heimfilmli",
+ "Playlists": "Abspielliste",
+ "HeaderRecordingGroups": "Ufnahmegruppe",
+ "HeaderContinueWatching": "Wiiterluege",
+ "HeaderFavoriteArtists": "Besti Interpret",
+ "HeaderFavoriteSongs": "Besti Lieder",
+ "HeaderAlbumArtists": "Albuminterprete",
+ "HeaderFavoriteAlbums": "Favorite Albums",
+ "HeaderFavoriteEpisodes": "Favorite Episodes",
+ "HeaderFavoriteShows": "Favorite Shows",
+ "HeaderNextUp": "Next Up",
+ "Favorites": "Favorites",
+ "Collections": "Collections",
+ "Channels": "Channels",
+ "Movies": "Movies",
+ "Albums": "Albums",
+ "Artists": "Artists",
+ "Folders": "Folders",
+ "Songs": "Songs",
+ "TvShows": "TV Shows",
+ "Shows": "Shows",
+ "Genres": "Genres",
+ "NameSeasonNumber": "Season {0}",
+ "AppDeviceValues": "App: {0}, Device: {1}",
+ "UserDownloadingItemWithValues": "{0} is downloading {1}",
+ "HeaderLiveTV": "Live TV",
+ "ChapterNameValue": "Chapter {0}",
+ "ScheduledTaskFailedWithName": "{0} failed",
+ "LabelRunningTimeValue": "Running time: {0}",
+ "ScheduledTaskStartedWithName": "{0} started",
+ "VersionNumber": "Version {0}",
+ "PluginInstalledWithName": "{0} was installed",
+ "StartupEmbyServerIsLoading": "Emby Server is loading. Please try again shortly.",
+ "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}",
+ "UserCreatedWithName": "User {0} has been created",
+ "UserPasswordChangedWithName": "Password has been changed for user {0}",
+ "UserDeletedWithName": "User {0} has been deleted",
+ "UserConfigurationUpdatedWithName": "User configuration has been updated for {0}",
+ "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",
+ "UserOfflineFromDevice": "{0} has disconnected from {1}",
+ "DeviceOfflineWithName": "{0} has disconnected",
+ "UserStartedPlayingItemWithValues": "{0} has started playing {1}",
+ "UserStoppedPlayingItemWithValues": "{0} has stopped playing {1}",
+ "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",
+ "NotificationOptionCameraImageUploaded": "Camera image uploaded",
+ "NotificationOptionUserLockedOut": "User locked out",
+ "NotificationOptionServerRestartRequired": "Server restart required",
+ "UserLockedOutWithName": "User {0} has been locked out",
+ "SubtitleDownloadFailureForItem": "Subtitles failed to download for {0}",
+ "Sync": "Sync",
+ "User": "User",
+ "System": "System",
+ "Application": "Application",
+ "Plugin": "Plugin"
+} \ No newline at end of file
diff --git a/Emby.Server.Implementations/Localization/Core/pt-BR.json b/Emby.Server.Implementations/Localization/Core/pt-BR.json
index fa4eac1c4..e0a375170 100644
--- a/Emby.Server.Implementations/Localization/Core/pt-BR.json
+++ b/Emby.Server.Implementations/Localization/Core/pt-BR.json
@@ -27,7 +27,7 @@
"Artists": "Artistas",
"Folders": "Pastas",
"Songs": "M\u00fasicas",
- "TvShows": "TV Shows",
+ "TvShows": "S\u00e9ries de TV",
"Shows": "S\u00e9ries",
"Genres": "G\u00eaneros",
"NameSeasonNumber": "Temporada {0}",
diff --git a/Emby.Server.Implementations/MediaEncoder/EncodingManager.cs b/Emby.Server.Implementations/MediaEncoder/EncodingManager.cs
index 6e0e55bef..d790f4ab8 100644
--- a/Emby.Server.Implementations/MediaEncoder/EncodingManager.cs
+++ b/Emby.Server.Implementations/MediaEncoder/EncodingManager.cs
@@ -76,6 +76,21 @@ namespace Emby.Server.Implementations.MediaEncoder
return false;
}
+ if (video.VideoType == VideoType.Iso)
+ {
+ return false;
+ }
+
+ if (video.VideoType == VideoType.BluRay || video.VideoType == VideoType.Dvd)
+ {
+ return false;
+ }
+
+ if (video.IsShortcut)
+ {
+ return false;
+ }
+
if (!video.IsCompleteMedia)
{
return false;
@@ -118,16 +133,6 @@ namespace Emby.Server.Implementations.MediaEncoder
{
if (extractImages)
{
- if (video.VideoType == VideoType.Iso)
- {
- continue;
- }
-
- if (video.VideoType == VideoType.BluRay || video.VideoType == VideoType.Dvd)
- {
- continue;
- }
-
try
{
// Add some time for the first chapter to make sure we don't end up with a black image
diff --git a/Emby.Server.Implementations/Networking/NetworkManager.cs b/Emby.Server.Implementations/Networking/NetworkManager.cs
index fbdb5c128..60da8a012 100644
--- a/Emby.Server.Implementations/Networking/NetworkManager.cs
+++ b/Emby.Server.Implementations/Networking/NetworkManager.cs
@@ -17,11 +17,54 @@ namespace Emby.Server.Implementations.Networking
public class NetworkManager : INetworkManager
{
protected ILogger Logger { get; private set; }
- private DateTime _lastRefresh;
+
+ public event EventHandler NetworkChanged;
public NetworkManager(ILogger logger)
{
Logger = logger;
+
+ try
+ {
+ NetworkChange.NetworkAddressChanged += NetworkChange_NetworkAddressChanged;
+ }
+ catch (Exception ex)
+ {
+ Logger.ErrorException("Error binding to NetworkAddressChanged event", ex);
+ }
+
+ try
+ {
+ NetworkChange.NetworkAvailabilityChanged += NetworkChange_NetworkAvailabilityChanged;
+ }
+ catch (Exception ex)
+ {
+ Logger.ErrorException("Error binding to NetworkChange_NetworkAvailabilityChanged event", ex);
+ }
+ }
+
+ private void NetworkChange_NetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e)
+ {
+ Logger.Debug("NetworkAvailabilityChanged");
+ OnNetworkChanged();
+ }
+
+ private void NetworkChange_NetworkAddressChanged(object sender, EventArgs e)
+ {
+ Logger.Debug("NetworkAddressChanged");
+ OnNetworkChanged();
+ }
+
+ private void OnNetworkChanged()
+ {
+ lock (_localIpAddressSyncLock)
+ {
+ _localIpAddresses = null;
+ }
+ if (NetworkChanged != null)
+ {
+ NetworkChanged(this, EventArgs.Empty);
+ }
}
private List<IpAddressInfo> _localIpAddresses;
@@ -29,34 +72,28 @@ namespace Emby.Server.Implementations.Networking
public List<IpAddressInfo> GetLocalIpAddresses()
{
- const int cacheMinutes = 10;
-
lock (_localIpAddressSyncLock)
{
- var forceRefresh = (DateTime.UtcNow - _lastRefresh).TotalMinutes >= cacheMinutes;
-
- if (_localIpAddresses == null || forceRefresh)
+ if (_localIpAddresses == null)
{
- var addresses = GetLocalIpAddressesInternal().Select(ToIpAddressInfo).ToList();
+ var addresses = GetLocalIpAddressesInternal().Result.Select(ToIpAddressInfo).ToList();
_localIpAddresses = addresses;
- _lastRefresh = DateTime.UtcNow;
return addresses;
}
+ return _localIpAddresses;
}
-
- return _localIpAddresses;
}
- private IEnumerable<IPAddress> GetLocalIpAddressesInternal()
+ private async Task<List<IPAddress>> GetLocalIpAddressesInternal()
{
var list = GetIPsDefault()
.ToList();
if (list.Count == 0)
{
- list.AddRange(GetLocalIpAddressesFallback().Result);
+ list.AddRange(await GetLocalIpAddressesFallback().ConfigureAwait(false));
}
var listClone = list.ToList();
@@ -65,7 +102,8 @@ namespace Emby.Server.Implementations.Networking
.OrderBy(i => i.AddressFamily == AddressFamily.InterNetwork ? 0 : 1)
.ThenBy(i => listClone.IndexOf(i))
.Where(FilterIpAddress)
- .DistinctBy(i => i.ToString());
+ .DistinctBy(i => i.ToString())
+ .ToList();
}
private bool FilterIpAddress(IPAddress address)
diff --git a/Emby.Server.Implementations/Session/HttpSessionController.cs b/Emby.Server.Implementations/Session/HttpSessionController.cs
index e1c1bbe2b..6725cd7af 100644
--- a/Emby.Server.Implementations/Session/HttpSessionController.cs
+++ b/Emby.Server.Implementations/Session/HttpSessionController.cs
@@ -117,6 +117,10 @@ namespace Emby.Server.Implementations.Session
{
dict["SubtitleStreamIndex"] = command.SubtitleStreamIndex.Value.ToString(CultureInfo.InvariantCulture);
}
+ if (command.StartIndex.HasValue)
+ {
+ dict["StartIndex"] = command.StartIndex.Value.ToString(CultureInfo.InvariantCulture);
+ }
if (!string.IsNullOrWhiteSpace(command.MediaSourceId))
{
dict["MediaSourceId"] = command.MediaSourceId;
@@ -147,7 +151,7 @@ namespace Emby.Server.Implementations.Session
return SendMessage("LibraryChanged", info, cancellationToken);
}
- public Task SendRestartRequiredNotification(SystemInfo info, CancellationToken cancellationToken)
+ public Task SendRestartRequiredNotification(CancellationToken cancellationToken)
{
return SendMessage("RestartRequired", cancellationToken);
}
diff --git a/Emby.Server.Implementations/Session/SessionManager.cs b/Emby.Server.Implementations/Session/SessionManager.cs
index 30f6e6521..6b70f2cda 100644
--- a/Emby.Server.Implementations/Session/SessionManager.cs
+++ b/Emby.Server.Implementations/Session/SessionManager.cs
@@ -1182,13 +1182,11 @@ namespace Emby.Server.Implementations.Session
{
var sessions = Sessions.Where(i => i.IsActive && i.SessionController != null).ToList();
- var info = await _appHost.GetSystemInfo().ConfigureAwait(false);
-
var tasks = sessions.Select(session => Task.Run(async () =>
{
try
{
- await session.SessionController.SendRestartRequiredNotification(info, cancellationToken).ConfigureAwait(false);
+ await session.SessionController.SendRestartRequiredNotification(cancellationToken).ConfigureAwait(false);
}
catch (Exception ex)
{
@@ -1423,7 +1421,7 @@ namespace Emby.Server.Implementations.Session
if (enforcePassword)
{
- var result = await _userManager.AuthenticateUser(request.Username, request.Password, request.PasswordSha1, request.PasswordMd5, request.RemoteEndPoint).ConfigureAwait(false);
+ var result = await _userManager.AuthenticateUser(request.Username, request.Password, request.PasswordSha1, request.PasswordMd5, request.RemoteEndPoint, true).ConfigureAwait(false);
if (result == null)
{
diff --git a/Emby.Server.Implementations/Session/WebSocketController.cs b/Emby.Server.Implementations/Session/WebSocketController.cs
index ee9ee8969..b13eb6116 100644
--- a/Emby.Server.Implementations/Session/WebSocketController.cs
+++ b/Emby.Server.Implementations/Session/WebSocketController.cs
@@ -145,12 +145,12 @@ namespace Emby.Server.Implementations.Session
/// <param name="info">The information.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
- public Task SendRestartRequiredNotification(SystemInfo info, CancellationToken cancellationToken)
+ public Task SendRestartRequiredNotification(CancellationToken cancellationToken)
{
- return SendMessagesInternal(new WebSocketMessage<SystemInfo>
+ return SendMessagesInternal(new WebSocketMessage<string>
{
MessageType = "RestartRequired",
- Data = info
+ Data = string.Empty
}, cancellationToken);
}
diff --git a/Emby.Server.Implementations/Social/SharingManager.cs b/Emby.Server.Implementations/Social/SharingManager.cs
index 57cf93948..23ce7492a 100644
--- a/Emby.Server.Implementations/Social/SharingManager.cs
+++ b/Emby.Server.Implementations/Social/SharingManager.cs
@@ -5,6 +5,7 @@ using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Social;
using System;
+using System.Threading;
using System.Threading.Tasks;
namespace Emby.Server.Implementations.Social
@@ -42,7 +43,7 @@ namespace Emby.Server.Implementations.Social
throw new ResourceNotFoundException();
}
- var externalUrl = (await _appHost.GetSystemInfo().ConfigureAwait(false)).WanAddress;
+ var externalUrl = (await _appHost.GetPublicSystemInfo(CancellationToken.None).ConfigureAwait(false)).WanAddress;
if (string.IsNullOrWhiteSpace(externalUrl))
{
@@ -73,7 +74,7 @@ namespace Emby.Server.Implementations.Social
{
var info = _repository.GetShareInfo(id);
- AddShareInfo(info, _appHost.GetSystemInfo().Result.WanAddress);
+ AddShareInfo(info, _appHost.GetPublicSystemInfo(CancellationToken.None).Result.WanAddress);
return info;
}
diff --git a/Emby.Server.Implementations/Udp/UdpServer.cs b/Emby.Server.Implementations/Udp/UdpServer.cs
index 8dc1fae4b..28de80da1 100644
--- a/Emby.Server.Implementations/Udp/UdpServer.cs
+++ b/Emby.Server.Implementations/Udp/UdpServer.cs
@@ -25,7 +25,7 @@ namespace Emby.Server.Implementations.Udp
private bool _isDisposed;
- private readonly List<Tuple<string, bool, Func<string, IpEndPointInfo, Encoding, Task>>> _responders = new List<Tuple<string, bool, Func<string, IpEndPointInfo, Encoding, Task>>>();
+ private readonly List<Tuple<string, bool, Func<string, IpEndPointInfo, Encoding, CancellationToken, Task>>> _responders = new List<Tuple<string, bool, Func<string, IpEndPointInfo, Encoding, CancellationToken, Task>>>();
private readonly IServerApplicationHost _appHost;
private readonly IJsonSerializer _json;
@@ -44,9 +44,9 @@ namespace Emby.Server.Implementations.Udp
AddMessageResponder("who is MediaBrowserServer_v2?", false, RespondToV2Message);
}
- private void AddMessageResponder(string message, bool isSubstring, Func<string, IpEndPointInfo, Encoding, Task> responder)
+ private void AddMessageResponder(string message, bool isSubstring, Func<string, IpEndPointInfo, Encoding, CancellationToken, Task> responder)
{
- _responders.Add(new Tuple<string, bool, Func<string, IpEndPointInfo, Encoding, Task>>(message, isSubstring, responder));
+ _responders.Add(new Tuple<string, bool, Func<string, IpEndPointInfo, Encoding, CancellationToken, Task>>(message, isSubstring, responder));
}
/// <summary>
@@ -67,9 +67,15 @@ namespace Emby.Server.Implementations.Udp
if (responder != null)
{
+ var cancellationToken = CancellationToken.None;
+
try
{
- await responder.Item2.Item3(responder.Item1, message.RemoteEndPoint, encoding).ConfigureAwait(false);
+ await responder.Item2.Item3(responder.Item1, message.RemoteEndPoint, encoding, cancellationToken).ConfigureAwait(false);
+ }
+ catch (OperationCanceledException)
+ {
+
}
catch (Exception ex)
{
@@ -78,7 +84,7 @@ namespace Emby.Server.Implementations.Udp
}
}
- private Tuple<string, Tuple<string, bool, Func<string, IpEndPointInfo, Encoding, Task>>> GetResponder(byte[] buffer, int bytesReceived, Encoding encoding)
+ private Tuple<string, Tuple<string, bool, Func<string, IpEndPointInfo, Encoding, CancellationToken, Task>>> GetResponder(byte[] buffer, int bytesReceived, Encoding encoding)
{
var text = encoding.GetString(buffer, 0, bytesReceived);
var responder = _responders.FirstOrDefault(i =>
@@ -94,14 +100,14 @@ namespace Emby.Server.Implementations.Udp
{
return null;
}
- return new Tuple<string, Tuple<string, bool, Func<string, IpEndPointInfo, Encoding, Task>>>(text, responder);
+ return new Tuple<string, Tuple<string, bool, Func<string, IpEndPointInfo, Encoding, CancellationToken, Task>>>(text, responder);
}
- private async Task RespondToV2Message(string messageText, IpEndPointInfo endpoint, Encoding encoding)
+ private async Task RespondToV2Message(string messageText, IpEndPointInfo endpoint, Encoding encoding, CancellationToken cancellationToken)
{
var parts = messageText.Split('|');
- var localUrl = await _appHost.GetLocalApiUrl().ConfigureAwait(false);
+ var localUrl = await _appHost.GetLocalApiUrl(cancellationToken).ConfigureAwait(false);
if (!string.IsNullOrEmpty(localUrl))
{
@@ -112,7 +118,7 @@ namespace Emby.Server.Implementations.Udp
Name = _appHost.FriendlyName
};
- await SendAsync(encoding.GetBytes(_json.SerializeToString(response)), endpoint).ConfigureAwait(false);
+ await SendAsync(encoding.GetBytes(_json.SerializeToString(response)), endpoint, cancellationToken).ConfigureAwait(false);
if (parts.Length > 1)
{
@@ -248,7 +254,7 @@ namespace Emby.Server.Implementations.Udp
}
}
- public async Task SendAsync(byte[] bytes, IpEndPointInfo remoteEndPoint)
+ public async Task SendAsync(byte[] bytes, IpEndPointInfo remoteEndPoint, CancellationToken cancellationToken)
{
if (_isDisposed)
{
@@ -267,7 +273,7 @@ namespace Emby.Server.Implementations.Udp
try
{
- await _udpClient.SendToAsync(bytes, 0, bytes.Length, remoteEndPoint, CancellationToken.None).ConfigureAwait(false);
+ await _udpClient.SendToAsync(bytes, 0, bytes.Length, remoteEndPoint, cancellationToken).ConfigureAwait(false);
_logger.Info("Udp message sent to {0}", remoteEndPoint);
}