mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-04-21 09:34:44 +01:00
Merge branch 'master' into warn17
This commit is contained in:
@@ -28,7 +28,7 @@ using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Emby.Server.Implementations.Activity
|
||||
{
|
||||
public class ActivityLogEntryPoint : IServerEntryPoint
|
||||
public sealed class ActivityLogEntryPoint : IServerEntryPoint
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly IInstallationManager _installationManager;
|
||||
@@ -38,7 +38,6 @@ namespace Emby.Server.Implementations.Activity
|
||||
private readonly ILocalizationManager _localization;
|
||||
private readonly ISubtitleManager _subManager;
|
||||
private readonly IUserManager _userManager;
|
||||
private readonly IServerApplicationHost _appHost;
|
||||
private readonly IDeviceManager _deviceManager;
|
||||
|
||||
/// <summary>
|
||||
@@ -63,8 +62,7 @@ namespace Emby.Server.Implementations.Activity
|
||||
ILocalizationManager localization,
|
||||
IInstallationManager installationManager,
|
||||
ISubtitleManager subManager,
|
||||
IUserManager userManager,
|
||||
IServerApplicationHost appHost)
|
||||
IUserManager userManager)
|
||||
{
|
||||
_logger = logger;
|
||||
_sessionManager = sessionManager;
|
||||
@@ -75,7 +73,6 @@ namespace Emby.Server.Implementations.Activity
|
||||
_installationManager = installationManager;
|
||||
_subManager = subManager;
|
||||
_userManager = userManager;
|
||||
_appHost = appHost;
|
||||
}
|
||||
|
||||
public Task RunAsync()
|
||||
@@ -140,7 +137,7 @@ namespace Emby.Server.Implementations.Activity
|
||||
CultureInfo.InvariantCulture,
|
||||
_localization.GetLocalizedString("SubtitleDownloadFailureFromForItem"),
|
||||
e.Provider,
|
||||
Notifications.Notifications.GetItemName(e.Item)),
|
||||
Emby.Notifications.NotificationEntryPoint.GetItemName(e.Item)),
|
||||
Type = "SubtitleDownloadFailure",
|
||||
ItemId = e.Item.Id.ToString("N", CultureInfo.InvariantCulture),
|
||||
ShortOverview = e.Exception.Message
|
||||
@@ -532,6 +529,7 @@ namespace Emby.Server.Implementations.Activity
|
||||
private void CreateLogEntry(ActivityLogEntry entry)
|
||||
=> _activityManager.Create(entry);
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
_taskManager.TaskCompleted -= OnTaskCompleted;
|
||||
|
||||
@@ -118,7 +118,6 @@ namespace Emby.Server.Implementations
|
||||
public abstract class ApplicationHost : IServerApplicationHost, IDisposable
|
||||
{
|
||||
private SqliteUserRepository _userRepository;
|
||||
|
||||
private SqliteDisplayPreferencesRepository _displayPreferencesRepository;
|
||||
|
||||
/// <summary>
|
||||
@@ -166,10 +165,9 @@ namespace Emby.Server.Implementations
|
||||
public bool IsShuttingDown { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the logger.
|
||||
/// Gets the logger.
|
||||
/// </summary>
|
||||
/// <value>The logger.</value>
|
||||
protected ILogger Logger { get; set; }
|
||||
protected ILogger Logger { get; }
|
||||
|
||||
private IPlugin[] _plugins;
|
||||
|
||||
@@ -180,10 +178,9 @@ namespace Emby.Server.Implementations
|
||||
public IReadOnlyList<IPlugin> Plugins => _plugins;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the logger factory.
|
||||
/// Gets the logger factory.
|
||||
/// </summary>
|
||||
/// <value>The logger factory.</value>
|
||||
public ILoggerFactory LoggerFactory { get; protected set; }
|
||||
protected ILoggerFactory LoggerFactory { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the application paths.
|
||||
@@ -327,8 +324,6 @@ namespace Emby.Server.Implementations
|
||||
|
||||
private IMediaSourceManager MediaSourceManager { get; set; }
|
||||
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the installation manager.
|
||||
/// </summary>
|
||||
@@ -366,11 +361,8 @@ namespace Emby.Server.Implementations
|
||||
IStartupOptions options,
|
||||
IFileSystem fileSystem,
|
||||
IImageEncoder imageEncoder,
|
||||
INetworkManager networkManager,
|
||||
IConfiguration configuration)
|
||||
INetworkManager networkManager)
|
||||
{
|
||||
_configuration = configuration;
|
||||
|
||||
XmlSerializer = new MyXmlSerializer();
|
||||
|
||||
NetworkManager = networkManager;
|
||||
@@ -586,7 +578,8 @@ namespace Emby.Server.Implementations
|
||||
}
|
||||
}
|
||||
|
||||
public async Task InitAsync(IServiceCollection serviceCollection)
|
||||
/// <inheritdoc/>
|
||||
public async Task InitAsync(IServiceCollection serviceCollection, IConfiguration startupConfig)
|
||||
{
|
||||
HttpPort = ServerConfigurationManager.Configuration.HttpServerPortNumber;
|
||||
HttpsPort = ServerConfigurationManager.Configuration.HttpsPortNumber;
|
||||
@@ -619,7 +612,7 @@ namespace Emby.Server.Implementations
|
||||
|
||||
DiscoverTypes();
|
||||
|
||||
await RegisterResources(serviceCollection).ConfigureAwait(false);
|
||||
await RegisterResources(serviceCollection, startupConfig).ConfigureAwait(false);
|
||||
|
||||
ContentRoot = ServerConfigurationManager.Configuration.DashboardSourcePath;
|
||||
if (string.IsNullOrEmpty(ContentRoot))
|
||||
@@ -651,14 +644,14 @@ namespace Emby.Server.Implementations
|
||||
var response = context.Response;
|
||||
var localPath = context.Request.Path.ToString();
|
||||
|
||||
var req = new WebSocketSharpRequest(request, response, request.Path, Logger);
|
||||
var req = new WebSocketSharpRequest(request, response, request.Path, LoggerFactory.CreateLogger<WebSocketSharpRequest>());
|
||||
await HttpServer.RequestHandler(req, request.GetDisplayUrl(), request.Host.ToString(), localPath, context.RequestAborted).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers resources that classes will depend on
|
||||
/// </summary>
|
||||
protected async Task RegisterResources(IServiceCollection serviceCollection)
|
||||
protected async Task RegisterResources(IServiceCollection serviceCollection, IConfiguration startupConfig)
|
||||
{
|
||||
serviceCollection.AddMemoryCache();
|
||||
|
||||
@@ -667,13 +660,10 @@ namespace Emby.Server.Implementations
|
||||
|
||||
serviceCollection.AddSingleton<IApplicationPaths>(ApplicationPaths);
|
||||
|
||||
serviceCollection.AddSingleton<IConfiguration>(_configuration);
|
||||
|
||||
serviceCollection.AddSingleton(JsonSerializer);
|
||||
|
||||
serviceCollection.AddSingleton(LoggerFactory);
|
||||
serviceCollection.AddLogging();
|
||||
serviceCollection.AddSingleton(Logger);
|
||||
// TODO: Support for injecting ILogger should be deprecated in favour of ILogger<T> and this removed
|
||||
serviceCollection.AddSingleton<ILogger>(Logger);
|
||||
|
||||
serviceCollection.AddSingleton(FileSystemManager);
|
||||
serviceCollection.AddSingleton<TvDbClientManager>();
|
||||
@@ -761,7 +751,7 @@ namespace Emby.Server.Implementations
|
||||
ProcessFactory,
|
||||
LocalizationManager,
|
||||
() => SubtitleEncoder,
|
||||
_configuration,
|
||||
startupConfig,
|
||||
StartupOptions.FFmpegPath);
|
||||
serviceCollection.AddSingleton(MediaEncoder);
|
||||
|
||||
@@ -783,7 +773,7 @@ namespace Emby.Server.Implementations
|
||||
this,
|
||||
LoggerFactory.CreateLogger<HttpListenerHost>(),
|
||||
ServerConfigurationManager,
|
||||
_configuration,
|
||||
startupConfig,
|
||||
NetworkManager,
|
||||
JsonSerializer,
|
||||
XmlSerializer,
|
||||
@@ -846,7 +836,10 @@ namespace Emby.Server.Implementations
|
||||
UserViewManager = new UserViewManager(LibraryManager, LocalizationManager, UserManager, ChannelManager, LiveTvManager, ServerConfigurationManager);
|
||||
serviceCollection.AddSingleton(UserViewManager);
|
||||
|
||||
NotificationManager = new NotificationManager(LoggerFactory, UserManager, ServerConfigurationManager);
|
||||
NotificationManager = new NotificationManager(
|
||||
LoggerFactory.CreateLogger<NotificationManager>(),
|
||||
UserManager,
|
||||
ServerConfigurationManager);
|
||||
serviceCollection.AddSingleton(NotificationManager);
|
||||
|
||||
serviceCollection.AddSingleton<IDeviceDiscovery>(new DeviceDiscovery(ServerConfigurationManager));
|
||||
@@ -1202,7 +1195,7 @@ namespace Emby.Server.Implementations
|
||||
});
|
||||
}
|
||||
|
||||
protected IHttpListener CreateHttpListener() => new WebSocketSharpListener(Logger);
|
||||
protected IHttpListener CreateHttpListener() => new WebSocketSharpListener(LoggerFactory.CreateLogger<WebSocketSharpListener>());
|
||||
|
||||
private CertificateInfo GetCertificateInfo(bool generateCertificate)
|
||||
{
|
||||
|
||||
@@ -19,7 +19,11 @@ namespace Emby.Server.Implementations.Channels
|
||||
private readonly ILogger _logger;
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
|
||||
public RefreshChannelsScheduledTask(IChannelManager channelManager, IUserManager userManager, ILogger logger, ILibraryManager libraryManager)
|
||||
public RefreshChannelsScheduledTask(
|
||||
IChannelManager channelManager,
|
||||
IUserManager userManager,
|
||||
ILogger<RefreshChannelsScheduledTask> logger,
|
||||
ILibraryManager libraryManager)
|
||||
{
|
||||
_channelManager = channelManager;
|
||||
_userManager = userManager;
|
||||
|
||||
@@ -347,7 +347,10 @@ namespace Emby.Server.Implementations.Collections
|
||||
private readonly IServerConfigurationManager _config;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public CollectionManagerEntryPoint(ICollectionManager collectionManager, IServerConfigurationManager config, ILogger logger)
|
||||
public CollectionManagerEntryPoint(
|
||||
ICollectionManager collectionManager,
|
||||
IServerConfigurationManager config,
|
||||
ILogger<CollectionManagerEntryPoint> logger)
|
||||
{
|
||||
_collectionManager = (CollectionManager)collectionManager;
|
||||
_config = config;
|
||||
|
||||
@@ -8,7 +8,6 @@ namespace Emby.Server.Implementations
|
||||
public static Dictionary<string, string> Configuration => new Dictionary<string, string>
|
||||
{
|
||||
{ "HttpListenerHost:DefaultRedirectPath", "web/index.html" },
|
||||
{ "MusicBrainz:BaseUrl", "https://www.musicbrainz.org" },
|
||||
{ FfmpegProbeSizeKey, "1G" },
|
||||
{ FfmpegAnalyzeDurationKey, "200M" }
|
||||
};
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace Emby.Server.Implementations.Data
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public CleanDatabaseScheduledTask(ILibraryManager libraryManager, ILogger logger)
|
||||
public CleanDatabaseScheduledTask(ILibraryManager libraryManager, ILogger<CleanDatabaseScheduledTask> logger)
|
||||
{
|
||||
_libraryManager = libraryManager;
|
||||
_logger = logger;
|
||||
|
||||
@@ -406,7 +406,10 @@ namespace Emby.Server.Implementations.Devices
|
||||
private readonly IServerConfigurationManager _config;
|
||||
private ILogger _logger;
|
||||
|
||||
public DeviceManagerEntryPoint(IDeviceManager deviceManager, IServerConfigurationManager config, ILogger logger)
|
||||
public DeviceManagerEntryPoint(
|
||||
IDeviceManager deviceManager,
|
||||
IServerConfigurationManager config,
|
||||
ILogger<DeviceManagerEntryPoint> logger)
|
||||
{
|
||||
_deviceManager = (DeviceManager)deviceManager;
|
||||
_config = config;
|
||||
|
||||
@@ -55,7 +55,12 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
|
||||
private readonly IProviderManager _providerManager;
|
||||
|
||||
public LibraryChangedNotifier(ILibraryManager libraryManager, ISessionManager sessionManager, IUserManager userManager, ILogger logger, IProviderManager providerManager)
|
||||
public LibraryChangedNotifier(
|
||||
ILibraryManager libraryManager,
|
||||
ISessionManager sessionManager,
|
||||
IUserManager userManager,
|
||||
ILogger<LibraryChangedNotifier> logger,
|
||||
IProviderManager providerManager)
|
||||
{
|
||||
_libraryManager = libraryManager;
|
||||
_sessionManager = sessionManager;
|
||||
|
||||
@@ -12,14 +12,18 @@ using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Emby.Server.Implementations.EntryPoints
|
||||
{
|
||||
public class RecordingNotifier : IServerEntryPoint
|
||||
public sealed class RecordingNotifier : IServerEntryPoint
|
||||
{
|
||||
private readonly ILiveTvManager _liveTvManager;
|
||||
private readonly ISessionManager _sessionManager;
|
||||
private readonly IUserManager _userManager;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public RecordingNotifier(ISessionManager sessionManager, IUserManager userManager, ILogger logger, ILiveTvManager liveTvManager)
|
||||
public RecordingNotifier(
|
||||
ISessionManager sessionManager,
|
||||
IUserManager userManager,
|
||||
ILogger<RecordingNotifier> logger,
|
||||
ILiveTvManager liveTvManager)
|
||||
{
|
||||
_sessionManager = sessionManager;
|
||||
_userManager = userManager;
|
||||
@@ -27,32 +31,33 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
_liveTvManager = liveTvManager;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task RunAsync()
|
||||
{
|
||||
_liveTvManager.TimerCancelled += _liveTvManager_TimerCancelled;
|
||||
_liveTvManager.SeriesTimerCancelled += _liveTvManager_SeriesTimerCancelled;
|
||||
_liveTvManager.TimerCreated += _liveTvManager_TimerCreated;
|
||||
_liveTvManager.SeriesTimerCreated += _liveTvManager_SeriesTimerCreated;
|
||||
_liveTvManager.TimerCancelled += OnLiveTvManagerTimerCancelled;
|
||||
_liveTvManager.SeriesTimerCancelled += OnLiveTvManagerSeriesTimerCancelled;
|
||||
_liveTvManager.TimerCreated += OnLiveTvManagerTimerCreated;
|
||||
_liveTvManager.SeriesTimerCreated += OnLiveTvManagerSeriesTimerCreated;
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private void _liveTvManager_SeriesTimerCreated(object sender, MediaBrowser.Model.Events.GenericEventArgs<TimerEventInfo> e)
|
||||
private void OnLiveTvManagerSeriesTimerCreated(object sender, MediaBrowser.Model.Events.GenericEventArgs<TimerEventInfo> e)
|
||||
{
|
||||
SendMessage("SeriesTimerCreated", e.Argument);
|
||||
}
|
||||
|
||||
private void _liveTvManager_TimerCreated(object sender, MediaBrowser.Model.Events.GenericEventArgs<TimerEventInfo> e)
|
||||
private void OnLiveTvManagerTimerCreated(object sender, MediaBrowser.Model.Events.GenericEventArgs<TimerEventInfo> e)
|
||||
{
|
||||
SendMessage("TimerCreated", e.Argument);
|
||||
}
|
||||
|
||||
private void _liveTvManager_SeriesTimerCancelled(object sender, MediaBrowser.Model.Events.GenericEventArgs<TimerEventInfo> e)
|
||||
private void OnLiveTvManagerSeriesTimerCancelled(object sender, MediaBrowser.Model.Events.GenericEventArgs<TimerEventInfo> e)
|
||||
{
|
||||
SendMessage("SeriesTimerCancelled", e.Argument);
|
||||
}
|
||||
|
||||
private void _liveTvManager_TimerCancelled(object sender, MediaBrowser.Model.Events.GenericEventArgs<TimerEventInfo> e)
|
||||
private void OnLiveTvManagerTimerCancelled(object sender, MediaBrowser.Model.Events.GenericEventArgs<TimerEventInfo> e)
|
||||
{
|
||||
SendMessage("TimerCancelled", e.Argument);
|
||||
}
|
||||
@@ -63,11 +68,7 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
|
||||
try
|
||||
{
|
||||
await _sessionManager.SendMessageToUserSessions(users, name, info, CancellationToken.None);
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
// TODO Log exception or Investigate and properly fix.
|
||||
await _sessionManager.SendMessageToUserSessions(users, name, info, CancellationToken.None).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -75,12 +76,13 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
_liveTvManager.TimerCancelled -= _liveTvManager_TimerCancelled;
|
||||
_liveTvManager.SeriesTimerCancelled -= _liveTvManager_SeriesTimerCancelled;
|
||||
_liveTvManager.TimerCreated -= _liveTvManager_TimerCreated;
|
||||
_liveTvManager.SeriesTimerCreated -= _liveTvManager_SeriesTimerCreated;
|
||||
_liveTvManager.TimerCancelled -= OnLiveTvManagerTimerCancelled;
|
||||
_liveTvManager.SeriesTimerCancelled -= OnLiveTvManagerSeriesTimerCancelled;
|
||||
_liveTvManager.TimerCreated -= OnLiveTvManagerTimerCreated;
|
||||
_liveTvManager.SeriesTimerCreated -= OnLiveTvManagerSeriesTimerCreated;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.Model.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Emby.Server.Implementations.EntryPoints
|
||||
{
|
||||
@@ -15,21 +14,17 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
/// </summary>
|
||||
public class RefreshUsersMetadata : IScheduledTask, IConfigurableScheduledTask
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
|
||||
/// <summary>
|
||||
/// The user manager.
|
||||
/// </summary>
|
||||
private readonly IUserManager _userManager;
|
||||
|
||||
private IFileSystem _fileSystem;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RefreshUsersMetadata" /> class.
|
||||
/// </summary>
|
||||
public RefreshUsersMetadata(ILogger logger, IUserManager userManager, IFileSystem fileSystem)
|
||||
public RefreshUsersMetadata(IUserManager userManager, IFileSystem fileSystem)
|
||||
{
|
||||
_logger = logger;
|
||||
_userManager = userManager;
|
||||
_fileSystem = fileSystem;
|
||||
}
|
||||
|
||||
@@ -3,37 +3,28 @@ using Emby.Server.Implementations.Browser;
|
||||
using MediaBrowser.Controller;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Plugins;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Emby.Server.Implementations.EntryPoints
|
||||
{
|
||||
/// <summary>
|
||||
/// Class StartupWizard.
|
||||
/// </summary>
|
||||
public class StartupWizard : IServerEntryPoint
|
||||
public sealed class StartupWizard : IServerEntryPoint
|
||||
{
|
||||
/// <summary>
|
||||
/// The app host.
|
||||
/// </summary>
|
||||
private readonly IServerApplicationHost _appHost;
|
||||
|
||||
/// <summary>
|
||||
/// The user manager.
|
||||
/// </summary>
|
||||
private readonly ILogger _logger;
|
||||
|
||||
private IServerConfigurationManager _config;
|
||||
private readonly IServerConfigurationManager _config;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="StartupWizard"/> class.
|
||||
/// </summary>
|
||||
/// <param name="appHost">The application host.</param>
|
||||
/// <param name="logger">The logger.</param>
|
||||
/// <param name="config">The configuration manager.</param>
|
||||
public StartupWizard(IServerApplicationHost appHost, ILogger logger, IServerConfigurationManager config)
|
||||
public StartupWizard(IServerApplicationHost appHost, IServerConfigurationManager config)
|
||||
{
|
||||
_appHost = appHost;
|
||||
_logger = logger;
|
||||
_config = config;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@ using System.Threading.Tasks;
|
||||
using Emby.Server.Implementations.Udp;
|
||||
using MediaBrowser.Controller;
|
||||
using MediaBrowser.Controller.Plugins;
|
||||
using MediaBrowser.Model.Net;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Emby.Server.Implementations.EntryPoints
|
||||
@@ -23,9 +21,7 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
/// The logger.
|
||||
/// </summary>
|
||||
private readonly ILogger _logger;
|
||||
private readonly ISocketFactory _socketFactory;
|
||||
private readonly IServerApplicationHost _appHost;
|
||||
private readonly IJsonSerializer _json;
|
||||
|
||||
/// <summary>
|
||||
/// The UDP server.
|
||||
@@ -64,7 +60,7 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
|
||||
_cancellationTokenSource.Cancel();
|
||||
_udpServer.Dispose();
|
||||
|
||||
_cancellationTokenSource.Dispose();
|
||||
_cancellationTokenSource = null;
|
||||
_udpServer = null;
|
||||
|
||||
|
||||
@@ -12,39 +12,38 @@ using MediaBrowser.Controller.Plugins;
|
||||
using MediaBrowser.Controller.Session;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Session;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Emby.Server.Implementations.EntryPoints
|
||||
{
|
||||
public class UserDataChangeNotifier : IServerEntryPoint
|
||||
public sealed class UserDataChangeNotifier : IServerEntryPoint
|
||||
{
|
||||
private const int UpdateDuration = 500;
|
||||
|
||||
private readonly ISessionManager _sessionManager;
|
||||
private readonly ILogger _logger;
|
||||
private readonly IUserDataManager _userDataManager;
|
||||
private readonly IUserManager _userManager;
|
||||
|
||||
private readonly object _syncLock = new object();
|
||||
private Timer UpdateTimer { get; set; }
|
||||
private const int UpdateDuration = 500;
|
||||
|
||||
private readonly Dictionary<Guid, List<BaseItem>> _changedItems = new Dictionary<Guid, List<BaseItem>>();
|
||||
|
||||
public UserDataChangeNotifier(IUserDataManager userDataManager, ISessionManager sessionManager, ILogger logger, IUserManager userManager)
|
||||
private readonly object _syncLock = new object();
|
||||
private Timer _updateTimer;
|
||||
|
||||
|
||||
public UserDataChangeNotifier(IUserDataManager userDataManager, ISessionManager sessionManager, IUserManager userManager)
|
||||
{
|
||||
_userDataManager = userDataManager;
|
||||
_sessionManager = sessionManager;
|
||||
_logger = logger;
|
||||
_userManager = userManager;
|
||||
}
|
||||
|
||||
public Task RunAsync()
|
||||
{
|
||||
_userDataManager.UserDataSaved += _userDataManager_UserDataSaved;
|
||||
_userDataManager.UserDataSaved += OnUserDataManagerUserDataSaved;
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
void _userDataManager_UserDataSaved(object sender, UserDataSaveEventArgs e)
|
||||
void OnUserDataManagerUserDataSaved(object sender, UserDataSaveEventArgs e)
|
||||
{
|
||||
if (e.SaveReason == UserDataSaveReason.PlaybackProgress)
|
||||
{
|
||||
@@ -53,14 +52,17 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
|
||||
lock (_syncLock)
|
||||
{
|
||||
if (UpdateTimer == null)
|
||||
if (_updateTimer == null)
|
||||
{
|
||||
UpdateTimer = new Timer(UpdateTimerCallback, null, UpdateDuration,
|
||||
Timeout.Infinite);
|
||||
_updateTimer = new Timer(
|
||||
UpdateTimerCallback,
|
||||
null,
|
||||
UpdateDuration,
|
||||
Timeout.Infinite);
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateTimer.Change(UpdateDuration, Timeout.Infinite);
|
||||
_updateTimer.Change(UpdateDuration, Timeout.Infinite);
|
||||
}
|
||||
|
||||
if (!_changedItems.TryGetValue(e.UserId, out List<BaseItem> keys))
|
||||
@@ -96,10 +98,10 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
|
||||
var task = SendNotifications(changes, CancellationToken.None);
|
||||
|
||||
if (UpdateTimer != null)
|
||||
if (_updateTimer != null)
|
||||
{
|
||||
UpdateTimer.Dispose();
|
||||
UpdateTimer = null;
|
||||
_updateTimer.Dispose();
|
||||
_updateTimer = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -144,13 +146,13 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (UpdateTimer != null)
|
||||
if (_updateTimer != null)
|
||||
{
|
||||
UpdateTimer.Dispose();
|
||||
UpdateTimer = null;
|
||||
_updateTimer.Dispose();
|
||||
_updateTimer = null;
|
||||
}
|
||||
|
||||
_userDataManager.UserDataSaved -= _userDataManager_UserDataSaved;
|
||||
_userDataManager.UserDataSaved -= OnUserDataManagerUserDataSaved;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||
if (!string.IsNullOrWhiteSpace(userInfo))
|
||||
{
|
||||
_logger.LogWarning("Found userInfo in url: {0} ... url: {1}", userInfo, url);
|
||||
url = url.Replace(userInfo + '@', string.Empty);
|
||||
url = url.Replace(userInfo + '@', string.Empty, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
var request = new HttpRequestMessage(method, url);
|
||||
|
||||
@@ -39,9 +39,9 @@ namespace Emby.Server.Implementations.HttpServer
|
||||
private readonly Func<Type, Func<string, object>> _funcParseFn;
|
||||
private readonly string _defaultRedirectPath;
|
||||
private readonly string _baseUrlPrefix;
|
||||
private readonly Dictionary<Type, Type> ServiceOperationsMap = new Dictionary<Type, Type>();
|
||||
private IWebSocketListener[] _webSocketListeners = Array.Empty<IWebSocketListener>();
|
||||
private readonly Dictionary<Type, Type> _serviceOperationsMap = new Dictionary<Type, Type>();
|
||||
private readonly List<IWebSocketConnection> _webSocketConnections = new List<IWebSocketConnection>();
|
||||
private IWebSocketListener[] _webSocketListeners = Array.Empty<IWebSocketListener>();
|
||||
private bool _disposed = false;
|
||||
|
||||
public HttpListenerHost(
|
||||
@@ -71,6 +71,8 @@ namespace Emby.Server.Implementations.HttpServer
|
||||
ResponseFilters = Array.Empty<Action<IRequest, HttpResponse, object>>();
|
||||
}
|
||||
|
||||
public event EventHandler<GenericEventArgs<IWebSocketConnection>> WebSocketConnected;
|
||||
|
||||
public Action<IRequest, HttpResponse, object>[] ResponseFilters { get; set; }
|
||||
|
||||
public static HttpListenerHost Instance { get; protected set; }
|
||||
@@ -81,8 +83,6 @@ namespace Emby.Server.Implementations.HttpServer
|
||||
|
||||
public ServiceController ServiceController { get; private set; }
|
||||
|
||||
public event EventHandler<GenericEventArgs<IWebSocketConnection>> WebSocketConnected;
|
||||
|
||||
public object CreateInstance(Type type)
|
||||
{
|
||||
return _appHost.CreateInstance(type);
|
||||
@@ -90,7 +90,7 @@ namespace Emby.Server.Implementations.HttpServer
|
||||
|
||||
private static string NormalizeUrlPath(string path)
|
||||
{
|
||||
if (path.StartsWith("/"))
|
||||
if (path.Length > 0 && path[0] == '/')
|
||||
{
|
||||
// If the path begins with a leading slash, just return it as-is
|
||||
return path;
|
||||
@@ -130,13 +130,13 @@ namespace Emby.Server.Implementations.HttpServer
|
||||
|
||||
public Type GetServiceTypeByRequest(Type requestType)
|
||||
{
|
||||
ServiceOperationsMap.TryGetValue(requestType, out var serviceType);
|
||||
_serviceOperationsMap.TryGetValue(requestType, out var serviceType);
|
||||
return serviceType;
|
||||
}
|
||||
|
||||
public void AddServiceInfo(Type serviceType, Type requestType)
|
||||
{
|
||||
ServiceOperationsMap[requestType] = serviceType;
|
||||
_serviceOperationsMap[requestType] = serviceType;
|
||||
}
|
||||
|
||||
private List<IHasRequestFilter> GetRequestFilterAttributes(Type requestDtoType)
|
||||
@@ -198,7 +198,7 @@ namespace Emby.Server.Implementations.HttpServer
|
||||
else
|
||||
{
|
||||
var inners = agg.InnerExceptions;
|
||||
if (inners != null && inners.Count > 0)
|
||||
if (inners.Count > 0)
|
||||
{
|
||||
return GetActualException(inners[0]);
|
||||
}
|
||||
@@ -361,7 +361,7 @@ namespace Emby.Server.Implementations.HttpServer
|
||||
return true;
|
||||
}
|
||||
|
||||
host = host ?? string.Empty;
|
||||
host ??= string.Empty;
|
||||
|
||||
if (_networkManager.IsInPrivateAddressSpace(host))
|
||||
{
|
||||
@@ -432,7 +432,7 @@ namespace Emby.Server.Implementations.HttpServer
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overridable method that can be used to implement a custom hnandler
|
||||
/// Overridable method that can be used to implement a custom handler.
|
||||
/// </summary>
|
||||
public async Task RequestHandler(IHttpRequest httpReq, string urlString, string host, string localPath, CancellationToken cancellationToken)
|
||||
{
|
||||
@@ -491,7 +491,7 @@ namespace Emby.Server.Implementations.HttpServer
|
||||
|| string.Equals(localPath, _baseUrlPrefix, StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(localPath, "/", StringComparison.OrdinalIgnoreCase)
|
||||
|| string.IsNullOrEmpty(localPath)
|
||||
|| !localPath.StartsWith(_baseUrlPrefix))
|
||||
|| !localPath.StartsWith(_baseUrlPrefix, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// Always redirect back to the default path if the base prefix is invalid or missing
|
||||
_logger.LogDebug("Normalizing a URL at {0}", localPath);
|
||||
@@ -692,7 +692,10 @@ namespace Emby.Server.Implementations.HttpServer
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (_disposed) return;
|
||||
if (_disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
|
||||
@@ -5,7 +5,9 @@ namespace Emby.Server.Implementations.IO
|
||||
public class ExtendedFileSystemInfo
|
||||
{
|
||||
public bool IsHidden { get; set; }
|
||||
|
||||
public bool IsReadOnly { get; set; }
|
||||
|
||||
public bool Exists { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,27 +14,29 @@ namespace Emby.Server.Implementations.IO
|
||||
{
|
||||
public class FileRefresher : IDisposable
|
||||
{
|
||||
private ILogger Logger { get; set; }
|
||||
private ILibraryManager LibraryManager { get; set; }
|
||||
private IServerConfigurationManager ConfigurationManager { get; set; }
|
||||
private readonly List<string> _affectedPaths = new List<string>();
|
||||
private Timer _timer;
|
||||
private readonly object _timerLock = new object();
|
||||
public string Path { get; private set; }
|
||||
private readonly ILogger _logger;
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
private readonly IServerConfigurationManager _configurationManager;
|
||||
|
||||
public event EventHandler<EventArgs> Completed;
|
||||
private readonly List<string> _affectedPaths = new List<string>();
|
||||
private readonly object _timerLock = new object();
|
||||
private Timer _timer;
|
||||
|
||||
public FileRefresher(string path, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, ILogger logger)
|
||||
{
|
||||
logger.LogDebug("New file refresher created for {0}", path);
|
||||
Path = path;
|
||||
|
||||
ConfigurationManager = configurationManager;
|
||||
LibraryManager = libraryManager;
|
||||
Logger = logger;
|
||||
_configurationManager = configurationManager;
|
||||
_libraryManager = libraryManager;
|
||||
_logger = logger;
|
||||
AddPath(path);
|
||||
}
|
||||
|
||||
public event EventHandler<EventArgs> Completed;
|
||||
|
||||
public string Path { get; private set; }
|
||||
|
||||
private void AddAffectedPath(string path)
|
||||
{
|
||||
if (string.IsNullOrEmpty(path))
|
||||
@@ -79,11 +81,11 @@ namespace Emby.Server.Implementations.IO
|
||||
|
||||
if (_timer == null)
|
||||
{
|
||||
_timer = new Timer(OnTimerCallback, null, TimeSpan.FromSeconds(ConfigurationManager.Configuration.LibraryMonitorDelay), TimeSpan.FromMilliseconds(-1));
|
||||
_timer = new Timer(OnTimerCallback, null, TimeSpan.FromSeconds(_configurationManager.Configuration.LibraryMonitorDelay), TimeSpan.FromMilliseconds(-1));
|
||||
}
|
||||
else
|
||||
{
|
||||
_timer.Change(TimeSpan.FromSeconds(ConfigurationManager.Configuration.LibraryMonitorDelay), TimeSpan.FromMilliseconds(-1));
|
||||
_timer.Change(TimeSpan.FromSeconds(_configurationManager.Configuration.LibraryMonitorDelay), TimeSpan.FromMilliseconds(-1));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -92,7 +94,7 @@ namespace Emby.Server.Implementations.IO
|
||||
{
|
||||
lock (_timerLock)
|
||||
{
|
||||
Logger.LogDebug("Resetting file refresher from {0} to {1}", Path, path);
|
||||
_logger.LogDebug("Resetting file refresher from {0} to {1}", Path, path);
|
||||
|
||||
Path = path;
|
||||
AddAffectedPath(path);
|
||||
@@ -115,7 +117,7 @@ namespace Emby.Server.Implementations.IO
|
||||
paths = _affectedPaths.ToList();
|
||||
}
|
||||
|
||||
Logger.LogDebug("Timer stopped.");
|
||||
_logger.LogDebug("Timer stopped.");
|
||||
|
||||
DisposeTimer();
|
||||
Completed?.Invoke(this, EventArgs.Empty);
|
||||
@@ -126,7 +128,7 @@ namespace Emby.Server.Implementations.IO
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError(ex, "Error processing directory changes");
|
||||
_logger.LogError(ex, "Error processing directory changes");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,7 +148,7 @@ namespace Emby.Server.Implementations.IO
|
||||
continue;
|
||||
}
|
||||
|
||||
Logger.LogInformation("{name} ({path}) will be refreshed.", item.Name, item.Path);
|
||||
_logger.LogInformation("{name} ({path}) will be refreshed.", item.Name, item.Path);
|
||||
|
||||
try
|
||||
{
|
||||
@@ -157,11 +159,11 @@ namespace Emby.Server.Implementations.IO
|
||||
// For now swallow and log.
|
||||
// Research item: If an IOException occurs, the item may be in a disconnected state (media unavailable)
|
||||
// Should we remove it from it's parent?
|
||||
Logger.LogError(ex, "Error refreshing {name}", item.Name);
|
||||
_logger.LogError(ex, "Error refreshing {name}", item.Name);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError(ex, "Error refreshing {name}", item.Name);
|
||||
_logger.LogError(ex, "Error refreshing {name}", item.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -177,7 +179,7 @@ namespace Emby.Server.Implementations.IO
|
||||
|
||||
while (item == null && !string.IsNullOrEmpty(path))
|
||||
{
|
||||
item = LibraryManager.FindByPath(path, null);
|
||||
item = _libraryManager.FindByPath(path, null);
|
||||
|
||||
path = System.IO.Path.GetDirectoryName(path);
|
||||
}
|
||||
|
||||
@@ -943,7 +943,6 @@ namespace Emby.Server.Implementations.Library
|
||||
IncludeItemTypes = new[] { typeof(T).Name },
|
||||
Name = name,
|
||||
DtoOptions = options
|
||||
|
||||
}).Cast<MusicArtist>()
|
||||
.OrderBy(i => i.IsAccessedByName ? 1 : 0)
|
||||
.Cast<T>()
|
||||
@@ -1079,7 +1078,7 @@ namespace Emby.Server.Implementations.Library
|
||||
|
||||
var innerProgress = new ActionableProgress<double>();
|
||||
|
||||
innerProgress.RegisterAction(pct => progress.Report(pct * pct * 0.96));
|
||||
innerProgress.RegisterAction(pct => progress.Report(pct * 0.96));
|
||||
|
||||
// Validate the entire media library
|
||||
await RootFolder.ValidateChildren(innerProgress, cancellationToken, new MetadataRefreshOptions(new DirectoryService(_fileSystem)), recursive: true).ConfigureAwait(false);
|
||||
|
||||
@@ -27,7 +27,11 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
|
||||
/// <param name="fileSystem">The file system.</param>
|
||||
/// <param name="libraryManager">The library manager.</param>
|
||||
/// <param name="config">The configuration manager.</param>
|
||||
public MusicArtistResolver(ILogger logger, IFileSystem fileSystem, ILibraryManager libraryManager, IServerConfigurationManager config)
|
||||
public MusicArtistResolver(
|
||||
ILogger<MusicArtistResolver> logger,
|
||||
IFileSystem fileSystem,
|
||||
ILibraryManager libraryManager,
|
||||
IServerConfigurationManager config)
|
||||
{
|
||||
_logger = logger;
|
||||
_fileSystem = fileSystem;
|
||||
|
||||
@@ -5,38 +5,33 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Playlists;
|
||||
using MediaBrowser.Controller.Resolvers;
|
||||
using MediaBrowser.LocalMetadata.Savers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
||||
namespace Emby.Server.Implementations.Library.Resolvers
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref="IItemResolver"/> for <see cref="Playlist"/> library items.
|
||||
/// </summary>
|
||||
public class PlaylistResolver : FolderResolver<Playlist>
|
||||
{
|
||||
private string[] SupportedCollectionTypes = new string[] {
|
||||
|
||||
private string[] _musicPlaylistCollectionTypes = new string[] {
|
||||
string.Empty,
|
||||
CollectionType.Music
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Resolves the specified args.
|
||||
/// </summary>
|
||||
/// <param name="args">The args.</param>
|
||||
/// <returns>BoxSet.</returns>
|
||||
/// <inheritdoc/>
|
||||
protected override Playlist Resolve(ItemResolveArgs args)
|
||||
{
|
||||
// It's a boxset if all of the following conditions are met:
|
||||
// Is a Directory
|
||||
// Contains [playlist] in the path
|
||||
if (args.IsDirectory)
|
||||
{
|
||||
var filename = Path.GetFileName(args.Path);
|
||||
|
||||
if (string.IsNullOrEmpty(filename))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (filename.IndexOf("[playlist]", StringComparison.OrdinalIgnoreCase) != -1)
|
||||
// It's a boxset if the path is a directory with [playlist] in it's the name
|
||||
// TODO: Should this use Path.GetDirectoryName() instead?
|
||||
bool isBoxSet = Path.GetFileName(args.Path)
|
||||
?.Contains("[playlist]", StringComparison.OrdinalIgnoreCase)
|
||||
?? false;
|
||||
if (isBoxSet)
|
||||
{
|
||||
return new Playlist
|
||||
{
|
||||
@@ -44,21 +39,32 @@ namespace Emby.Server.Implementations.Library.Resolvers
|
||||
Name = Path.GetFileName(args.Path).Replace("[playlist]", string.Empty, StringComparison.OrdinalIgnoreCase).Trim()
|
||||
};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SupportedCollectionTypes.Contains(args.CollectionType ?? string.Empty, StringComparer.OrdinalIgnoreCase))
|
||||
|
||||
// It's a directory-based playlist if the directory contains a playlist file
|
||||
var filePaths = Directory.EnumerateFiles(args.Path);
|
||||
if (filePaths.Any(f => f.EndsWith(PlaylistXmlSaver.DefaultPlaylistFilename, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
var extension = Path.GetExtension(args.Path);
|
||||
if (Playlist.SupportedExtensions.Contains(extension ?? string.Empty, StringComparer.OrdinalIgnoreCase))
|
||||
return new Playlist
|
||||
{
|
||||
return new Playlist
|
||||
{
|
||||
Path = args.Path,
|
||||
Name = Path.GetFileNameWithoutExtension(args.Path),
|
||||
IsInMixedFolder = true
|
||||
};
|
||||
}
|
||||
Path = args.Path,
|
||||
Name = Path.GetFileName(args.Path)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Check if this is a music playlist file
|
||||
// It should have the correct collection type and a supported file extension
|
||||
else if (_musicPlaylistCollectionTypes.Contains(args.CollectionType ?? string.Empty, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
var extension = Path.GetExtension(args.Path);
|
||||
if (Playlist.SupportedExtensions.Contains(extension ?? string.Empty, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
return new Playlist
|
||||
{
|
||||
Path = args.Path,
|
||||
Name = Path.GetFileNameWithoutExtension(args.Path),
|
||||
IsInMixedFolder = true
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,11 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV
|
||||
/// <param name="libraryManager">The library manager.</param>
|
||||
/// <param name="localization">The localization</param>
|
||||
/// <param name="logger">The logger</param>
|
||||
public SeasonResolver(IServerConfigurationManager config, ILibraryManager libraryManager, ILocalizationManager localization, ILogger logger)
|
||||
public SeasonResolver(
|
||||
IServerConfigurationManager config,
|
||||
ILibraryManager libraryManager,
|
||||
ILocalizationManager localization,
|
||||
ILogger<SeasonResolver> logger)
|
||||
{
|
||||
_config = config;
|
||||
_libraryManager = libraryManager;
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV
|
||||
/// <param name="fileSystem">The file system.</param>
|
||||
/// <param name="logger">The logger.</param>
|
||||
/// <param name="libraryManager">The library manager.</param>
|
||||
public SeriesResolver(IFileSystem fileSystem, ILogger logger, ILibraryManager libraryManager)
|
||||
public SeriesResolver(IFileSystem fileSystem, ILogger<SeriesResolver> logger, ILibraryManager libraryManager)
|
||||
{
|
||||
_fileSystem = fileSystem;
|
||||
_logger = logger;
|
||||
|
||||
@@ -25,7 +25,10 @@ namespace Emby.Server.Implementations.Library.Validators
|
||||
/// <param name="libraryManager">The library manager.</param>
|
||||
/// <param name="logger">The logger.</param>
|
||||
/// <param name="itemRepo">The item repository.</param>
|
||||
public ArtistsPostScanTask(ILibraryManager libraryManager, ILogger logger, IItemRepository itemRepo)
|
||||
public ArtistsPostScanTask(
|
||||
ILibraryManager libraryManager,
|
||||
ILogger<ArtistsPostScanTask> logger,
|
||||
IItemRepository itemRepo)
|
||||
{
|
||||
_libraryManager = libraryManager;
|
||||
_logger = logger;
|
||||
|
||||
@@ -25,7 +25,10 @@ namespace Emby.Server.Implementations.Library.Validators
|
||||
/// <param name="libraryManager">The library manager.</param>
|
||||
/// <param name="logger">The logger.</param>
|
||||
/// <param name="itemRepo">The item repository.</param>
|
||||
public GenresPostScanTask(ILibraryManager libraryManager, ILogger logger, IItemRepository itemRepo)
|
||||
public GenresPostScanTask(
|
||||
ILibraryManager libraryManager,
|
||||
ILogger<GenresPostScanTask> logger,
|
||||
IItemRepository itemRepo)
|
||||
{
|
||||
_libraryManager = libraryManager;
|
||||
_logger = logger;
|
||||
|
||||
@@ -25,7 +25,10 @@ namespace Emby.Server.Implementations.Library.Validators
|
||||
/// <param name="libraryManager">The library manager.</param>
|
||||
/// <param name="logger">The logger.</param>
|
||||
/// <param name="itemRepo">The item repository.</param>
|
||||
public MusicGenresPostScanTask(ILibraryManager libraryManager, ILogger logger, IItemRepository itemRepo)
|
||||
public MusicGenresPostScanTask(
|
||||
ILibraryManager libraryManager,
|
||||
ILogger<MusicGenresPostScanTask> logger,
|
||||
IItemRepository itemRepo)
|
||||
{
|
||||
_libraryManager = libraryManager;
|
||||
_logger = logger;
|
||||
|
||||
@@ -26,7 +26,10 @@ namespace Emby.Server.Implementations.Library.Validators
|
||||
/// <param name="libraryManager">The library manager.</param>
|
||||
/// <param name="logger">The logger.</param>
|
||||
/// <param name="itemRepo">The item repository.</param>
|
||||
public StudiosPostScanTask(ILibraryManager libraryManager, ILogger logger, IItemRepository itemRepo)
|
||||
public StudiosPostScanTask(
|
||||
ILibraryManager libraryManager,
|
||||
ILogger<StudiosPostScanTask> logger,
|
||||
IItemRepository itemRepo)
|
||||
{
|
||||
_libraryManager = libraryManager;
|
||||
_logger = logger;
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable SA1600
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net.Http;
|
||||
|
||||
@@ -29,7 +29,6 @@ using MediaBrowser.Model.Diagnostics;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Events;
|
||||
using MediaBrowser.Model.Extensions;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.Model.LiveTv;
|
||||
using MediaBrowser.Model.MediaInfo;
|
||||
@@ -80,7 +79,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
||||
IServerApplicationHost appHost,
|
||||
IStreamHelper streamHelper,
|
||||
IMediaSourceManager mediaSourceManager,
|
||||
ILogger logger,
|
||||
ILogger<EmbyTV> logger,
|
||||
IJsonSerializer jsonSerializer,
|
||||
IHttpClient httpClient,
|
||||
IServerConfigurationManager config,
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable SA1600
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable SA1600
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Controller.Plugins;
|
||||
|
||||
@@ -5,11 +8,13 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
||||
{
|
||||
public class EntryPoint : IServerEntryPoint
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public Task RunAsync()
|
||||
{
|
||||
return EmbyTV.Current.Start();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable SA1600
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable SA1600
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable SA1600
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using MediaBrowser.Controller.LiveTv;
|
||||
@@ -21,7 +24,11 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
||||
|
||||
if (info.SeasonNumber.HasValue && info.EpisodeNumber.HasValue)
|
||||
{
|
||||
name += string.Format(" S{0}E{1}", info.SeasonNumber.Value.ToString("00", CultureInfo.InvariantCulture), info.EpisodeNumber.Value.ToString("00", CultureInfo.InvariantCulture));
|
||||
name += string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
" S{0}E{1}",
|
||||
info.SeasonNumber.Value.ToString("00", CultureInfo.InvariantCulture),
|
||||
info.EpisodeNumber.Value.ToString("00", CultureInfo.InvariantCulture));
|
||||
addHyphen = false;
|
||||
}
|
||||
else if (info.OriginalAirDate.HasValue)
|
||||
@@ -32,7 +39,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
||||
}
|
||||
else
|
||||
{
|
||||
name += " " + info.OriginalAirDate.Value.ToLocalTime().ToString("yyyy-MM-dd");
|
||||
name += " " + info.OriginalAirDate.Value.ToLocalTime().ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -67,14 +74,15 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
||||
{
|
||||
date = date.ToLocalTime();
|
||||
|
||||
return string.Format("{0}_{1}_{2}_{3}_{4}_{5}",
|
||||
return string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
"{0}_{1}_{2}_{3}_{4}_{5}",
|
||||
date.Year.ToString("0000", CultureInfo.InvariantCulture),
|
||||
date.Month.ToString("00", CultureInfo.InvariantCulture),
|
||||
date.Day.ToString("00", CultureInfo.InvariantCulture),
|
||||
date.Hour.ToString("00", CultureInfo.InvariantCulture),
|
||||
date.Minute.ToString("00", CultureInfo.InvariantCulture),
|
||||
date.Second.ToString("00", CultureInfo.InvariantCulture)
|
||||
);
|
||||
date.Second.ToString("00", CultureInfo.InvariantCulture));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable SA1600
|
||||
|
||||
using System;
|
||||
using MediaBrowser.Controller.LiveTv;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
@@ -12,6 +15,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Add(SeriesTimerInfo item)
|
||||
{
|
||||
if (string.IsNullOrEmpty(item.Id))
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable SA1600
|
||||
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Globalization;
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable SA1600
|
||||
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
@@ -30,7 +33,11 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
||||
|
||||
private const string ApiUrl = "https://json.schedulesdirect.org/20141201";
|
||||
|
||||
public SchedulesDirect(ILogger logger, IJsonSerializer jsonSerializer, IHttpClient httpClient, IApplicationHost appHost)
|
||||
public SchedulesDirect(
|
||||
ILogger<SchedulesDirect> logger,
|
||||
IJsonSerializer jsonSerializer,
|
||||
IHttpClient httpClient,
|
||||
IApplicationHost appHost)
|
||||
{
|
||||
_logger = logger;
|
||||
_jsonSerializer = jsonSerializer;
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable SA1600
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
@@ -31,7 +34,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
||||
public XmlTvListingsProvider(
|
||||
IServerConfigurationManager config,
|
||||
IHttpClient httpClient,
|
||||
ILogger logger,
|
||||
ILogger<XmlTvListingsProvider> logger,
|
||||
IFileSystem fileSystem,
|
||||
IZipClient zipClient)
|
||||
{
|
||||
@@ -91,12 +94,12 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
||||
{
|
||||
using (var gzStream = new GZipStream(stream, CompressionMode.Decompress))
|
||||
{
|
||||
await gzStream.CopyToAsync(fileStream).ConfigureAwait(false);
|
||||
await gzStream.CopyToAsync(fileStream, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await stream.CopyToAsync(fileStream).ConfigureAwait(false);
|
||||
await stream.CopyToAsync(fileStream, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable SA1600
|
||||
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Model.LiveTv;
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable SA1600
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable SA1600
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@@ -1,52 +1,48 @@
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable SA1600
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Controller;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.LiveTv;
|
||||
using MediaBrowser.Controller.MediaEncoding;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.MediaInfo;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Emby.Server.Implementations.LiveTv
|
||||
{
|
||||
public class LiveTvMediaSourceProvider : IMediaSourceProvider
|
||||
{
|
||||
// Do not use a pipe here because Roku http requests to the server will fail, without any explicit error message.
|
||||
private const char StreamIdDelimeter = '_';
|
||||
private const string StreamIdDelimeterString = "_";
|
||||
|
||||
private readonly ILiveTvManager _liveTvManager;
|
||||
private readonly IJsonSerializer _jsonSerializer;
|
||||
private readonly ILogger _logger;
|
||||
private readonly IMediaSourceManager _mediaSourceManager;
|
||||
private readonly IMediaEncoder _mediaEncoder;
|
||||
private readonly IServerApplicationHost _appHost;
|
||||
private IApplicationPaths _appPaths;
|
||||
|
||||
public LiveTvMediaSourceProvider(ILiveTvManager liveTvManager, IApplicationPaths appPaths, IJsonSerializer jsonSerializer, ILoggerFactory loggerFactory, IMediaSourceManager mediaSourceManager, IMediaEncoder mediaEncoder, IServerApplicationHost appHost)
|
||||
public LiveTvMediaSourceProvider(ILiveTvManager liveTvManager, ILogger<LiveTvMediaSourceProvider> logger, IMediaSourceManager mediaSourceManager, IServerApplicationHost appHost)
|
||||
{
|
||||
_liveTvManager = liveTvManager;
|
||||
_jsonSerializer = jsonSerializer;
|
||||
_logger = logger;
|
||||
_mediaSourceManager = mediaSourceManager;
|
||||
_mediaEncoder = mediaEncoder;
|
||||
_appHost = appHost;
|
||||
_logger = loggerFactory.CreateLogger(GetType().Name);
|
||||
_appPaths = appPaths;
|
||||
}
|
||||
|
||||
public Task<IEnumerable<MediaSourceInfo>> GetMediaSources(BaseItem item, CancellationToken cancellationToken)
|
||||
{
|
||||
var baseItem = (BaseItem)item;
|
||||
|
||||
if (baseItem.SourceType == SourceType.LiveTV)
|
||||
if (item.SourceType == SourceType.LiveTV)
|
||||
{
|
||||
var activeRecordingInfo = _liveTvManager.GetActiveRecordingInfo(item.Path);
|
||||
|
||||
if (string.IsNullOrEmpty(baseItem.Path) || activeRecordingInfo != null)
|
||||
if (string.IsNullOrEmpty(item.Path) || activeRecordingInfo != null)
|
||||
{
|
||||
return GetMediaSourcesInternal(item, activeRecordingInfo, cancellationToken);
|
||||
}
|
||||
@@ -55,10 +51,6 @@ namespace Emby.Server.Implementations.LiveTv
|
||||
return Task.FromResult<IEnumerable<MediaSourceInfo>>(Array.Empty<MediaSourceInfo>());
|
||||
}
|
||||
|
||||
// Do not use a pipe here because Roku http requests to the server will fail, without any explicit error message.
|
||||
private const char StreamIdDelimeter = '_';
|
||||
private const string StreamIdDelimeterString = "_";
|
||||
|
||||
private async Task<IEnumerable<MediaSourceInfo>> GetMediaSourcesInternal(BaseItem item, ActiveRecordingInfo activeRecordingInfo, CancellationToken cancellationToken)
|
||||
{
|
||||
IEnumerable<MediaSourceInfo> sources;
|
||||
@@ -91,7 +83,7 @@ namespace Emby.Server.Implementations.LiveTv
|
||||
foreach (var source in list)
|
||||
{
|
||||
source.Type = MediaSourceType.Default;
|
||||
source.BufferMs = source.BufferMs ?? 1500;
|
||||
source.BufferMs ??= 1500;
|
||||
|
||||
if (source.RequiresOpening || forceRequireOpening)
|
||||
{
|
||||
@@ -100,11 +92,14 @@ namespace Emby.Server.Implementations.LiveTv
|
||||
|
||||
if (source.RequiresOpening)
|
||||
{
|
||||
var openKeys = new List<string>();
|
||||
openKeys.Add(item.GetType().Name);
|
||||
openKeys.Add(item.Id.ToString("N", CultureInfo.InvariantCulture));
|
||||
openKeys.Add(source.Id ?? string.Empty);
|
||||
source.OpenToken = string.Join(StreamIdDelimeterString, openKeys.ToArray());
|
||||
var openKeys = new List<string>
|
||||
{
|
||||
item.GetType().Name,
|
||||
item.Id.ToString("N", CultureInfo.InvariantCulture),
|
||||
source.Id ?? string.Empty
|
||||
};
|
||||
|
||||
source.OpenToken = string.Join(StreamIdDelimeterString, openKeys);
|
||||
}
|
||||
|
||||
// Dummy this up so that direct play checks can still run
|
||||
@@ -114,11 +109,12 @@ namespace Emby.Server.Implementations.LiveTv
|
||||
}
|
||||
}
|
||||
|
||||
_logger.LogDebug("MediaSources: {0}", _jsonSerializer.SerializeToString(list));
|
||||
_logger.LogDebug("MediaSources: {@MediaSources}", list);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<ILiveStream> OpenMediaSource(string openToken, List<ILiveStream> currentLiveStreams, CancellationToken cancellationToken)
|
||||
{
|
||||
var keys = openToken.Split(new[] { StreamIdDelimeter }, 3);
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable SA1600
|
||||
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable SA1600
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
@@ -36,7 +39,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
||||
|
||||
public HdHomerunHost(
|
||||
IServerConfigurationManager config,
|
||||
ILogger logger,
|
||||
ILogger<HdHomerunHost> logger,
|
||||
IJsonSerializer jsonSerializer,
|
||||
IFileSystem fileSystem,
|
||||
IHttpClient httpClient,
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable SA1600
|
||||
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable SA1600
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable SA1600
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable SA1600
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable SA1600
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable SA1600
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
@@ -2,22 +2,22 @@
|
||||
"Albums": "ألبومات",
|
||||
"AppDeviceValues": "تطبيق: {0}, جهاز: {1}",
|
||||
"Application": "التطبيق",
|
||||
"Artists": "الفنان",
|
||||
"Artists": "الفنانين",
|
||||
"AuthenticationSucceededWithUserName": "{0} سجل الدخول بنجاح",
|
||||
"Books": "كتب",
|
||||
"CameraImageUploadedFrom": "صورة كاميرا جديدة تم رفعها من {0}",
|
||||
"Channels": "القنوات",
|
||||
"ChapterNameValue": "الباب {0}",
|
||||
"ChapterNameValue": "فصل {0}",
|
||||
"Collections": "مجموعات",
|
||||
"DeviceOfflineWithName": "تم قطع اتصال {0}",
|
||||
"DeviceOfflineWithName": "قُطِع الاتصال بـ{0}",
|
||||
"DeviceOnlineWithName": "{0} متصل",
|
||||
"FailedLoginAttemptWithUserName": "عملية تسجيل الدخول فشلت من {0}",
|
||||
"Favorites": "التفضيلات",
|
||||
"Favorites": "المفضلة",
|
||||
"Folders": "المجلدات",
|
||||
"Genres": "أنواع الأفلام",
|
||||
"Genres": "الأنواع",
|
||||
"HeaderAlbumArtists": "فناني الألبومات",
|
||||
"HeaderCameraUploads": "تحميلات الكاميرا",
|
||||
"HeaderContinueWatching": "استئناف المشاهدة",
|
||||
"HeaderContinueWatching": "استئناف",
|
||||
"HeaderFavoriteAlbums": "الألبومات المفضلة",
|
||||
"HeaderFavoriteArtists": "الفنانون المفضلون",
|
||||
"HeaderFavoriteEpisodes": "الحلقات المفضلة",
|
||||
@@ -31,28 +31,28 @@
|
||||
"ItemAddedWithName": "تم إضافة {0} للمكتبة",
|
||||
"ItemRemovedWithName": "تم إزالة {0} من المكتبة",
|
||||
"LabelIpAddressValue": "عنوان الآي بي: {0}",
|
||||
"LabelRunningTimeValue": "وقت التشغيل: {0}",
|
||||
"LabelRunningTimeValue": "المدة: {0}",
|
||||
"Latest": "الأحدث",
|
||||
"MessageApplicationUpdated": "لقد تم تحديث خادم أمبي",
|
||||
"MessageApplicationUpdated": "لقد تم تحديث خادم Jellyfin",
|
||||
"MessageApplicationUpdatedTo": "تم تحديث سيرفر Jellyfin الى {0}",
|
||||
"MessageNamedServerConfigurationUpdatedWithValue": "تم تحديث إعدادات الخادم في قسم {0}",
|
||||
"MessageServerConfigurationUpdated": "تم تحديث إعدادات الخادم",
|
||||
"MixedContent": "محتوى مخلوط",
|
||||
"MixedContent": "محتوى مختلط",
|
||||
"Movies": "الأفلام",
|
||||
"Music": "الموسيقى",
|
||||
"MusicVideos": "الفيديوهات الموسيقية",
|
||||
"NameInstallFailed": "فشل التثبيت {0}",
|
||||
"NameSeasonNumber": "الموسم {0}",
|
||||
"NameSeasonUnknown": "الموسم غير معروف",
|
||||
"NewVersionIsAvailable": "نسخة حديثة من سيرفر Jellyfin متوفرة للتحميل .",
|
||||
"NewVersionIsAvailable": "نسخة جديدة من سيرفر Jellyfin متوفرة للتحميل.",
|
||||
"NotificationOptionApplicationUpdateAvailable": "يوجد تحديث للتطبيق",
|
||||
"NotificationOptionApplicationUpdateInstalled": "تم تحديث التطبيق",
|
||||
"NotificationOptionAudioPlayback": "بدأ تشغيل المقطع الصوتي",
|
||||
"NotificationOptionAudioPlaybackStopped": "تم إيقاف تشغيل المقطع الصوتي",
|
||||
"NotificationOptionCameraImageUploaded": "تم رقع صورة الكاميرا",
|
||||
"NotificationOptionCameraImageUploaded": "تم رفع صورة الكاميرا",
|
||||
"NotificationOptionInstallationFailed": "فشل في التثبيت",
|
||||
"NotificationOptionNewLibraryContent": "تم إضافة محتوى جديد",
|
||||
"NotificationOptionPluginError": "فشل في الملحق",
|
||||
"NotificationOptionNewLibraryContent": "أُضِيفَ محتوى جديد",
|
||||
"NotificationOptionPluginError": "فشل في الـPlugin",
|
||||
"NotificationOptionPluginInstalled": "تم تثبيت الملحق",
|
||||
"NotificationOptionPluginUninstalled": "تمت إزالة الملحق",
|
||||
"NotificationOptionPluginUpdateInstalled": "تم تثبيت تحديثات الملحق",
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"AppDeviceValues": "App: {0}, Enhed: {1}",
|
||||
"Application": "Applikation",
|
||||
"Artists": "Kunstnere",
|
||||
"AuthenticationSucceededWithUserName": "{0} bekræftet med succes",
|
||||
"AuthenticationSucceededWithUserName": "{0} succesfuldt autentificeret",
|
||||
"Books": "Bøger",
|
||||
"CameraImageUploadedFrom": "Et nyt kamerabillede er blevet uploadet fra {0}",
|
||||
"Channels": "Kanaler",
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"Albums": "Alben",
|
||||
"AppDeviceValues": "App: {0}, Gerät: {1}",
|
||||
"Application": "Anwendung",
|
||||
"AppDeviceValues": "Anw: {0}, Gerät: {1}",
|
||||
"Application": "Programm",
|
||||
"Artists": "Interpreten",
|
||||
"AuthenticationSucceededWithUserName": "{0} hat sich erfolgreich angemeldet",
|
||||
"Books": "Bücher",
|
||||
"CameraImageUploadedFrom": "Ein neues Foto wurde hochgeladen von {0}",
|
||||
"CameraImageUploadedFrom": "Ein neues Foto wurde von {0} hochgeladen",
|
||||
"Channels": "Kanäle",
|
||||
"ChapterNameValue": "Kapitel {0}",
|
||||
"Collections": "Sammlungen",
|
||||
"DeviceOfflineWithName": "{0} wurde getrennt",
|
||||
"DeviceOfflineWithName": "{0} hat die Verbindung getrennt",
|
||||
"DeviceOnlineWithName": "{0} ist verbunden",
|
||||
"FailedLoginAttemptWithUserName": "Fehlgeschlagener Anmeldeversuch von {0}",
|
||||
"Favorites": "Favoriten",
|
||||
@@ -17,7 +17,7 @@
|
||||
"Genres": "Genres",
|
||||
"HeaderAlbumArtists": "Album-Interpreten",
|
||||
"HeaderCameraUploads": "Kamera-Uploads",
|
||||
"HeaderContinueWatching": "Weiterschauen",
|
||||
"HeaderContinueWatching": "Fortsetzen",
|
||||
"HeaderFavoriteAlbums": "Lieblingsalben",
|
||||
"HeaderFavoriteArtists": "Lieblings-Interpreten",
|
||||
"HeaderFavoriteEpisodes": "Lieblingsepisoden",
|
||||
|
||||
@@ -10,5 +10,12 @@
|
||||
"CameraImageUploadedFrom": "Se ha subido una nueva imagen de cámara desde {0}",
|
||||
"AuthenticationSucceededWithUserName": "{0} autenticado con éxito",
|
||||
"Application": "Aplicación",
|
||||
"AppDeviceValues": "App: {0}, Dispositivo: {1}"
|
||||
"AppDeviceValues": "App: {0}, Dispositivo: {1}",
|
||||
"HeaderContinueWatching": "Continuar Viendo",
|
||||
"HeaderCameraUploads": "Subidas de Cámara",
|
||||
"HeaderAlbumArtists": "Artistas del Álbum",
|
||||
"Genres": "Géneros",
|
||||
"Folders": "Carpetas",
|
||||
"Favorites": "Favoritos",
|
||||
"FailedLoginAttemptWithUserName": "Intento de inicio de sesión fallido de {0}"
|
||||
}
|
||||
|
||||
@@ -17,31 +17,31 @@
|
||||
"LabelIpAddressValue": "IP-osoite: {0}",
|
||||
"ItemRemovedWithName": "{0} poistettiin kirjastosta",
|
||||
"ItemAddedWithName": "{0} lisättiin kirjastoon",
|
||||
"Inherit": "Periä",
|
||||
"Inherit": "Periytyä",
|
||||
"HomeVideos": "Kotivideot",
|
||||
"HeaderRecordingGroups": "Äänitysryhmät",
|
||||
"HeaderRecordingGroups": "Nauhoitusryhmät",
|
||||
"HeaderNextUp": "Seuraavaksi",
|
||||
"HeaderFavoriteSongs": "Lempikappaleet",
|
||||
"HeaderFavoriteShows": "Lempisarjat",
|
||||
"HeaderFavoriteEpisodes": "Lempijaksot",
|
||||
"HeaderCameraUploads": "Kamerasta lähetetyt",
|
||||
"HeaderCameraUploads": "Kameralataukset",
|
||||
"HeaderFavoriteArtists": "Lempiartistit",
|
||||
"HeaderFavoriteAlbums": "Lempialbumit",
|
||||
"HeaderContinueWatching": "Jatka katsomista",
|
||||
"HeaderAlbumArtists": "Albumin artistit",
|
||||
"Genres": "Tyylilaji",
|
||||
"HeaderAlbumArtists": "Albumin esittäjä",
|
||||
"Genres": "Tyylilajit",
|
||||
"Folders": "Kansiot",
|
||||
"Favorites": "Suosikit",
|
||||
"FailedLoginAttemptWithUserName": "Epäonnistunut kirjautumisyritys kohteesta {0}",
|
||||
"DeviceOnlineWithName": "{0} on yhdistynyt",
|
||||
"FailedLoginAttemptWithUserName": "Kirjautuminen epäonnistui kohteesta {0}",
|
||||
"DeviceOnlineWithName": "{0} on yhdistetty",
|
||||
"DeviceOfflineWithName": "{0} on katkaissut yhteytensä",
|
||||
"Collections": "Kokoelmat",
|
||||
"ChapterNameValue": "Luku: {0}",
|
||||
"Channels": "Kanavat",
|
||||
"CameraImageUploadedFrom": "Uusi kamerakuva on lähetetty kohteesta {0}",
|
||||
"CameraImageUploadedFrom": "Uusi kamerakuva on ladattu {0}",
|
||||
"Books": "Kirjat",
|
||||
"AuthenticationSucceededWithUserName": "{0} todennettu onnistuneesti",
|
||||
"Artists": "Artistit",
|
||||
"AuthenticationSucceededWithUserName": "{0} todennus onnistui",
|
||||
"Artists": "Esiintyjät",
|
||||
"Application": "Sovellus",
|
||||
"AppDeviceValues": "Sovellus: {0}, Laite: {1}",
|
||||
"Albums": "Albumit",
|
||||
@@ -76,21 +76,21 @@
|
||||
"Shows": "Ohjelmat",
|
||||
"ServerNameNeedsToBeRestarted": "{0} vaatii uudelleenkäynnistyksen",
|
||||
"ProviderValue": "Palveluntarjoaja: {0}",
|
||||
"Plugin": "Laajennus",
|
||||
"Plugin": "Liitännäinen",
|
||||
"NotificationOptionVideoPlaybackStopped": "Videon toistaminen pysäytetty",
|
||||
"NotificationOptionVideoPlayback": "Videon toistaminen aloitettu",
|
||||
"NotificationOptionUserLockedOut": "Käyttäjä kirjautui ulos",
|
||||
"NotificationOptionTaskFailed": "Ajastetun tehtävän ongelma",
|
||||
"NotificationOptionServerRestartRequired": "Palvelimen uudelleenkäynnistys vaaditaan",
|
||||
"NotificationOptionPluginUpdateInstalled": "Laajennuksen päivitys asennettu",
|
||||
"NotificationOptionPluginUninstalled": "Laajennus poistettu",
|
||||
"NotificationOptionPluginInstalled": "Laajennus asennettu",
|
||||
"NotificationOptionPluginError": "Ongelma laajennuksessa",
|
||||
"NotificationOptionNewLibraryContent": "Uusi sisältö lisätty",
|
||||
"NotificationOptionInstallationFailed": "Asennusvirhe",
|
||||
"NotificationOptionCameraImageUploaded": "Kameran kuva lisätty",
|
||||
"NotificationOptionAudioPlaybackStopped": "Äänen toistaminen pysäytetty",
|
||||
"NotificationOptionAudioPlayback": "Äänen toistaminen aloitettu",
|
||||
"NotificationOptionPluginUpdateInstalled": "Liitännäinen päivitetty",
|
||||
"NotificationOptionPluginUninstalled": "Liitännäinen poistettu",
|
||||
"NotificationOptionPluginInstalled": "Liitännäinen asennettu",
|
||||
"NotificationOptionPluginError": "Ongelma liitännäisessä",
|
||||
"NotificationOptionNewLibraryContent": "Uutta sisältöä lisätty",
|
||||
"NotificationOptionInstallationFailed": "Asennus epäonnistui",
|
||||
"NotificationOptionCameraImageUploaded": "Kuva ladattu kamerasta",
|
||||
"NotificationOptionAudioPlaybackStopped": "Audion toisto pysäytetty",
|
||||
"NotificationOptionAudioPlayback": "Audion toisto aloitettu",
|
||||
"NotificationOptionApplicationUpdateInstalled": "Ohjelmistopäivitys asennettu",
|
||||
"NotificationOptionApplicationUpdateAvailable": "Ohjelmistopäivitys saatavilla"
|
||||
}
|
||||
|
||||
@@ -2,33 +2,33 @@
|
||||
"Albums": "אלבומים",
|
||||
"AppDeviceValues": "יישום: {0}, מכשיר: {1}",
|
||||
"Application": "אפליקציה",
|
||||
"Artists": "אמנים",
|
||||
"AuthenticationSucceededWithUserName": "{0} זוהה בהצלחה",
|
||||
"Artists": "אומנים",
|
||||
"AuthenticationSucceededWithUserName": "{0} אומת בהצלחה",
|
||||
"Books": "ספרים",
|
||||
"CameraImageUploadedFrom": "תמונה חדשה הועלתה מ{0}",
|
||||
"CameraImageUploadedFrom": "תמונת מצלמה חדשה הועלתה מ {0}",
|
||||
"Channels": "ערוצים",
|
||||
"ChapterNameValue": "פרק {0}",
|
||||
"Collections": "קולקציות",
|
||||
"Collections": "אוספים",
|
||||
"DeviceOfflineWithName": "{0} התנתק",
|
||||
"DeviceOnlineWithName": "{0} מחובר",
|
||||
"FailedLoginAttemptWithUserName": "ניסיון כניסה שגוי מ{0}",
|
||||
"Favorites": "אהובים",
|
||||
"Favorites": "מועדפים",
|
||||
"Folders": "תיקיות",
|
||||
"Genres": "ז'אנרים",
|
||||
"HeaderAlbumArtists": "אמני האלבום",
|
||||
"HeaderCameraUploads": "העלאות ממצלמה",
|
||||
"HeaderContinueWatching": "המשך לצפות",
|
||||
"HeaderFavoriteAlbums": "אלבומים שאהבתי",
|
||||
"HeaderFavoriteArtists": "אמנים שאהבתי",
|
||||
"HeaderFavoriteEpisodes": "פרקים אהובים",
|
||||
"HeaderFavoriteShows": "תוכניות אהובות",
|
||||
"HeaderFavoriteSongs": "שירים שאהבתי",
|
||||
"HeaderLiveTV": "טלוויזיה בשידור חי",
|
||||
"HeaderFavoriteArtists": "אמנים מועדפים",
|
||||
"HeaderFavoriteEpisodes": "פרקים מועדפים",
|
||||
"HeaderFavoriteShows": "סדרות מועדפות",
|
||||
"HeaderFavoriteSongs": "שירים מועדפים",
|
||||
"HeaderLiveTV": "שידורים חיים",
|
||||
"HeaderNextUp": "הבא",
|
||||
"HeaderRecordingGroups": "קבוצות הקלטה",
|
||||
"HomeVideos": "סרטונים בייתים",
|
||||
"Inherit": "הורש",
|
||||
"ItemAddedWithName": "{0} was added to the library",
|
||||
"ItemAddedWithName": "{0} הוסף לספרייה",
|
||||
"ItemRemovedWithName": "{0} נמחק מהספרייה",
|
||||
"LabelIpAddressValue": "Ip כתובת: {0}",
|
||||
"LabelRunningTimeValue": "משך צפייה: {0}",
|
||||
@@ -36,15 +36,15 @@
|
||||
"MessageApplicationUpdated": "שרת הJellyfin עודכן",
|
||||
"MessageApplicationUpdatedTo": "שרת הJellyfin עודכן לגרסא {0}",
|
||||
"MessageNamedServerConfigurationUpdatedWithValue": "הגדרת השרת {0} שונתה",
|
||||
"MessageServerConfigurationUpdated": "Server configuration has been updated",
|
||||
"MessageServerConfigurationUpdated": "תצורת השרת עודכנה",
|
||||
"MixedContent": "תוכן מעורב",
|
||||
"Movies": "סרטים",
|
||||
"Music": "מוזיקה",
|
||||
"MusicVideos": "Music videos",
|
||||
"NameInstallFailed": "{0} installation failed",
|
||||
"NameSeasonNumber": "Season {0}",
|
||||
"NameSeasonUnknown": "Season Unknown",
|
||||
"NewVersionIsAvailable": "A new version of Jellyfin Server is available for download.",
|
||||
"MusicVideos": "קליפים",
|
||||
"NameInstallFailed": "התקנת {0} נכשלה",
|
||||
"NameSeasonNumber": "עונה {0}",
|
||||
"NameSeasonUnknown": "עונה לא ידועה",
|
||||
"NewVersionIsAvailable": "גרסה חדשה של שרת Jellyfin זמינה להורדה.",
|
||||
"NotificationOptionApplicationUpdateAvailable": "Application update available",
|
||||
"NotificationOptionApplicationUpdateInstalled": "Application update installed",
|
||||
"NotificationOptionAudioPlayback": "Audio playback started",
|
||||
@@ -53,10 +53,10 @@
|
||||
"NotificationOptionInstallationFailed": "התקנה נכשלה",
|
||||
"NotificationOptionNewLibraryContent": "New content added",
|
||||
"NotificationOptionPluginError": "Plugin failure",
|
||||
"NotificationOptionPluginInstalled": "Plugin installed",
|
||||
"NotificationOptionPluginUninstalled": "Plugin uninstalled",
|
||||
"NotificationOptionPluginUpdateInstalled": "Plugin update installed",
|
||||
"NotificationOptionServerRestartRequired": "Server restart required",
|
||||
"NotificationOptionPluginInstalled": "התוסף הותקן",
|
||||
"NotificationOptionPluginUninstalled": "התוסף הוסר",
|
||||
"NotificationOptionPluginUpdateInstalled": "העדכון לתוסף הותקן",
|
||||
"NotificationOptionServerRestartRequired": "יש לאתחל את השרת",
|
||||
"NotificationOptionTaskFailed": "Scheduled task failure",
|
||||
"NotificationOptionUserLockedOut": "User locked out",
|
||||
"NotificationOptionVideoPlayback": "Video playback started",
|
||||
@@ -71,26 +71,26 @@
|
||||
"ScheduledTaskFailedWithName": "{0} failed",
|
||||
"ScheduledTaskStartedWithName": "{0} started",
|
||||
"ServerNameNeedsToBeRestarted": "{0} needs to be restarted",
|
||||
"Shows": "Shows",
|
||||
"Songs": "Songs",
|
||||
"StartupEmbyServerIsLoading": "Jellyfin Server is loading. Please try again shortly.",
|
||||
"Shows": "סדרות",
|
||||
"Songs": "שירים",
|
||||
"StartupEmbyServerIsLoading": "שרת Jellyfin בהליכי טעינה. אנא נסה שנית בעוד זמן קצר.",
|
||||
"SubtitleDownloadFailureForItem": "Subtitles failed to download for {0}",
|
||||
"SubtitleDownloadFailureFromForItem": "Subtitles failed to download from {0} for {1}",
|
||||
"SubtitlesDownloadedForItem": "Subtitles downloaded for {0}",
|
||||
"Sync": "סנכרן",
|
||||
"System": "System",
|
||||
"TvShows": "TV Shows",
|
||||
"TvShows": "סדרות טלוויזיה",
|
||||
"User": "User",
|
||||
"UserCreatedWithName": "User {0} has been created",
|
||||
"UserDeletedWithName": "User {0} has been deleted",
|
||||
"UserDownloadingItemWithValues": "{0} is downloading {1}",
|
||||
"UserCreatedWithName": "המשתמש {0} נוצר",
|
||||
"UserDeletedWithName": "המשתמש {0} הוסר",
|
||||
"UserDownloadingItemWithValues": "{0} מוריד את {1}",
|
||||
"UserLockedOutWithName": "User {0} has been locked out",
|
||||
"UserOfflineFromDevice": "{0} has disconnected from {1}",
|
||||
"UserOnlineFromDevice": "{0} is online from {1}",
|
||||
"UserPasswordChangedWithName": "Password has been changed for user {0}",
|
||||
"UserPolicyUpdatedWithName": "User policy has been updated for {0}",
|
||||
"UserStartedPlayingItemWithValues": "{0} is playing {1} on {2}",
|
||||
"UserStoppedPlayingItemWithValues": "{0} has finished playing {1} on {2}",
|
||||
"UserStartedPlayingItemWithValues": "{0} מנגן את {1} על {2}",
|
||||
"UserStoppedPlayingItemWithValues": "{0} סיים לנגן את {1} על {2}",
|
||||
"ValueHasBeenAddedToLibrary": "{0} has been added to your media library",
|
||||
"ValueSpecialEpisodeName": "מיוחד- {0}",
|
||||
"VersionNumber": "Version {0}"
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"Collections": "Gyűjtemények",
|
||||
"DeviceOfflineWithName": "{0} kijelentkezett",
|
||||
"DeviceOnlineWithName": "{0} belépett",
|
||||
"FailedLoginAttemptWithUserName": "Sikertelen bejelentkezési kísérlet {0}",
|
||||
"FailedLoginAttemptWithUserName": "Sikertelen bejelentkezési kísérlet tőle: {0}",
|
||||
"Favorites": "Kedvencek",
|
||||
"Folders": "Könyvtárak",
|
||||
"Genres": "Műfajok",
|
||||
@@ -27,7 +27,7 @@
|
||||
"HeaderNextUp": "Következik",
|
||||
"HeaderRecordingGroups": "Felvételi csoportok",
|
||||
"HomeVideos": "Házi videók",
|
||||
"Inherit": "Öröklés",
|
||||
"Inherit": "Örökölt",
|
||||
"ItemAddedWithName": "{0} hozzáadva a könyvtárhoz",
|
||||
"ItemRemovedWithName": "{0} eltávolítva a könyvtárból",
|
||||
"LabelIpAddressValue": "IP cím: {0}",
|
||||
@@ -73,7 +73,7 @@
|
||||
"ServerNameNeedsToBeRestarted": "{0}-t újra kell indítani",
|
||||
"Shows": "Műsorok",
|
||||
"Songs": "Dalok",
|
||||
"StartupEmbyServerIsLoading": "A Jellyfin Szerver betöltődik. Kérlek próbáld újra később.",
|
||||
"StartupEmbyServerIsLoading": "A Jellyfin Szerver betöltődik. Kérlek, próbáld újra hamarosan.",
|
||||
"SubtitleDownloadFailureForItem": "Subtitles failed to download for {0}",
|
||||
"SubtitleDownloadFailureFromForItem": "Nem sikerült a felirat letöltése innen: {0} ehhez: {1}",
|
||||
"SubtitlesDownloadedForItem": "Letöltött feliratok a következőhöz: {0}",
|
||||
@@ -86,11 +86,11 @@
|
||||
"UserDownloadingItemWithValues": "{0} letölti {1}",
|
||||
"UserLockedOutWithName": "{0} felhasználó zárolva van",
|
||||
"UserOfflineFromDevice": "{0} kijelentkezett innen: {1}",
|
||||
"UserOnlineFromDevice": "{0} online itt: {1}",
|
||||
"UserOnlineFromDevice": "{0} online innen: {1}",
|
||||
"UserPasswordChangedWithName": "Jelszó megváltozott a következő felhasználó számára: {0}",
|
||||
"UserPolicyUpdatedWithName": "A felhasználói házirend frissítve lett neki: {0}",
|
||||
"UserStartedPlayingItemWithValues": "{0} elkezdte játszani a következőt: {1} itt: {2}",
|
||||
"UserStoppedPlayingItemWithValues": "{0} befejezte a következőt: {1} itt: {2}",
|
||||
"UserStoppedPlayingItemWithValues": "{0} befejezte {1} lejátászását itt: {2}",
|
||||
"ValueHasBeenAddedToLibrary": "{0} hozzáadva a médiatárhoz",
|
||||
"ValueSpecialEpisodeName": "Special - {0}",
|
||||
"VersionNumber": "Verzió: {0}"
|
||||
|
||||
@@ -91,5 +91,6 @@
|
||||
"NotificationOptionVideoPlayback": "Pemutaran video dimulai",
|
||||
"NotificationOptionAudioPlaybackStopped": "Pemutaran audio berhenti",
|
||||
"NotificationOptionAudioPlayback": "Pemutaran audio dimulai",
|
||||
"MixedContent": "Konten campur"
|
||||
"MixedContent": "Konten campur",
|
||||
"PluginUninstalledWithName": "{0} telah dihapus"
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"Artists": "Artisti",
|
||||
"AuthenticationSucceededWithUserName": "{0} autenticato con successo",
|
||||
"Books": "Libri",
|
||||
"CameraImageUploadedFrom": "È stata caricata una nuova immagine della fotocamera {0}",
|
||||
"CameraImageUploadedFrom": "È stata caricata una nuova immagine della fotocamera da {0}",
|
||||
"Channels": "Canali",
|
||||
"ChapterNameValue": "Capitolo {0}",
|
||||
"Collections": "Collezioni",
|
||||
@@ -18,7 +18,7 @@
|
||||
"HeaderAlbumArtists": "Artisti dell' Album",
|
||||
"HeaderCameraUploads": "Caricamenti Fotocamera",
|
||||
"HeaderContinueWatching": "Continua a guardare",
|
||||
"HeaderFavoriteAlbums": "Album preferiti",
|
||||
"HeaderFavoriteAlbums": "Album Preferiti",
|
||||
"HeaderFavoriteArtists": "Artisti Preferiti",
|
||||
"HeaderFavoriteEpisodes": "Episodi Preferiti",
|
||||
"HeaderFavoriteShows": "Serie TV Preferite",
|
||||
|
||||
96
Emby.Server.Implementations/Localization/Core/lv.json
Normal file
96
Emby.Server.Implementations/Localization/Core/lv.json
Normal file
@@ -0,0 +1,96 @@
|
||||
{
|
||||
"ServerNameNeedsToBeRestarted": "{0} ir vajadzīgs restarts",
|
||||
"NotificationOptionTaskFailed": "Plānota uzdevuma kļūme",
|
||||
"HeaderRecordingGroups": "Ierakstu Grupas",
|
||||
"UserPolicyUpdatedWithName": "Lietotāju politika atjaunota priekš {0}",
|
||||
"SubtitleDownloadFailureFromForItem": "Subtitru lejupielāde no {0} priekš {1} neizdevās",
|
||||
"NotificationOptionVideoPlaybackStopped": "Video atskaņošana apturēta",
|
||||
"NotificationOptionVideoPlayback": "Video atskaņošana sākta",
|
||||
"NotificationOptionInstallationFailed": "Instalācija neizdevās",
|
||||
"AuthenticationSucceededWithUserName": "{0} veiksmīgi autentificējies",
|
||||
"ValueSpecialEpisodeName": "Speciālais - {0}",
|
||||
"ScheduledTaskStartedWithName": "{0} iesākts",
|
||||
"ScheduledTaskFailedWithName": "{0} neizdevās",
|
||||
"Photos": "Attēli",
|
||||
"NotificationOptionUserLockedOut": "Lietotājs bloķēts",
|
||||
"LabelRunningTimeValue": "Garums: {0}",
|
||||
"Inherit": "Mantot",
|
||||
"AppDeviceValues": "Lietotne:{0}, Ierīce:{1}",
|
||||
"VersionNumber": "Versija {0}",
|
||||
"ValueHasBeenAddedToLibrary": "{0} ir ticis pievienots tavai multvides bibliotēkai",
|
||||
"UserStoppedPlayingItemWithValues": "{0} ir beidzis atskaņot {1} uz {2}",
|
||||
"UserStartedPlayingItemWithValues": "{0} atskaņo {1} uz {2}",
|
||||
"UserPasswordChangedWithName": "Parole nomainīta lietotājam {0}",
|
||||
"UserOnlineFromDevice": "{0} ir tiešsaistē no {1}",
|
||||
"UserOfflineFromDevice": "{0} ir atvienojies no {1}",
|
||||
"UserLockedOutWithName": "Lietotājs {0} ir ticis bloķēts",
|
||||
"UserDownloadingItemWithValues": "{0} lejupielādē {1}",
|
||||
"UserDeletedWithName": "Lietotājs {0} ir izdzēsts",
|
||||
"UserCreatedWithName": "Lietotājs {0} ir ticis izveidots",
|
||||
"User": "Lietotājs",
|
||||
"TvShows": "TV Raidījumi",
|
||||
"Sync": "Sinhronizācija",
|
||||
"System": "Sistēma",
|
||||
"SubtitlesDownloadedForItem": "Subtitri lejupielādēti priekš {0}",
|
||||
"StartupEmbyServerIsLoading": "Jellyfin Serveris lādējas. Lūdzu mēģiniet vēlreiz pēc brīža.",
|
||||
"Songs": "Dziesmas",
|
||||
"Shows": "Raidījumi",
|
||||
"PluginUpdatedWithName": "{0} tika atjaunots",
|
||||
"PluginUninstalledWithName": "{0} tika noņemts",
|
||||
"PluginInstalledWithName": "{0} tika uzstādīts",
|
||||
"Plugin": "Paplašinājums",
|
||||
"Playlists": "Atskaņošanas Saraksti",
|
||||
"MixedContent": "Jaukts saturs",
|
||||
"HomeVideos": "Mājas Video",
|
||||
"HeaderNextUp": "Nākamais",
|
||||
"ChapterNameValue": "Nodaļa {0}",
|
||||
"Application": "Lietotne",
|
||||
"NotificationOptionServerRestartRequired": "Vajadzīgs servera restarts",
|
||||
"NotificationOptionPluginUpdateInstalled": "Paplašinājuma atjauninājums uzstādīts",
|
||||
"NotificationOptionPluginUninstalled": "Paplašinājums noņemts",
|
||||
"NotificationOptionPluginInstalled": "Paplašinājums uzstādīts",
|
||||
"NotificationOptionPluginError": "Paplašinājuma kļūda",
|
||||
"NotificationOptionNewLibraryContent": "Jauns saturs pievienots",
|
||||
"NotificationOptionCameraImageUploaded": "Kameras attēls augšupielādēts",
|
||||
"NotificationOptionAudioPlaybackStopped": "Audio atskaņošana apturēta",
|
||||
"NotificationOptionAudioPlayback": "Audio atskaņošana sākta",
|
||||
"NotificationOptionApplicationUpdateInstalled": "Lietotnes atjauninājums uzstādīts",
|
||||
"NotificationOptionApplicationUpdateAvailable": "Lietotnes atjauninājums pieejams",
|
||||
"NewVersionIsAvailable": "Lejupielādei ir pieejama jauna Jellyfin Server versija.",
|
||||
"NameSeasonUnknown": "Nezināma Sezona",
|
||||
"NameSeasonNumber": "Sezona {0}",
|
||||
"NameInstallFailed": "{0} instalācija neizdevās",
|
||||
"MusicVideos": "Mūzikas video",
|
||||
"Music": "Mūzika",
|
||||
"Movies": "Filmas",
|
||||
"MessageServerConfigurationUpdated": "Servera konfigurācija ir tikusi atjaunota",
|
||||
"MessageNamedServerConfigurationUpdatedWithValue": "Servera konfigurācijas sadaļa {0} ir tikusi atjaunota",
|
||||
"MessageApplicationUpdatedTo": "Jellyfin Server ir ticis atjaunots uz {0}",
|
||||
"MessageApplicationUpdated": "Jellyfin Server ir ticis atjaunots",
|
||||
"Latest": "Jaunākais",
|
||||
"LabelIpAddressValue": "IP adrese: {0}",
|
||||
"ItemRemovedWithName": "{0} tika noņemts no bibliotēkas",
|
||||
"ItemAddedWithName": "{0} tika pievienots bibliotēkai",
|
||||
"HeaderLiveTV": "Tiešraides TV",
|
||||
"HeaderContinueWatching": "Turpināt Skatīšanos",
|
||||
"HeaderCameraUploads": "Kameras augšupielādes",
|
||||
"HeaderAlbumArtists": "Albumu Izpildītāji",
|
||||
"Genres": "Žanri",
|
||||
"Folders": "Mapes",
|
||||
"Favorites": "Favorīti",
|
||||
"FailedLoginAttemptWithUserName": "Neizdevies pieslēgšanās mēģinājums no {0}",
|
||||
"DeviceOnlineWithName": "{0} ir pievienojies",
|
||||
"DeviceOfflineWithName": "{0} ir atvienojies",
|
||||
"Collections": "Kolekcijas",
|
||||
"Channels": "Kanāli",
|
||||
"CameraImageUploadedFrom": "Jauns kameras attēls ir ticis augšupielādēts no {0}",
|
||||
"Books": "Grāmatas",
|
||||
"Artists": "Izpildītāji",
|
||||
"Albums": "Albumi",
|
||||
"ProviderValue": "Provider: {0}",
|
||||
"HeaderFavoriteSongs": "Dziesmu Favorīti",
|
||||
"HeaderFavoriteShows": "Raidījumu Favorīti",
|
||||
"HeaderFavoriteEpisodes": "Episožu Favorīti",
|
||||
"HeaderFavoriteArtists": "Izpildītāju Favorīti",
|
||||
"HeaderFavoriteAlbums": "Albumu Favorīti"
|
||||
}
|
||||
96
Emby.Server.Implementations/Localization/Core/mk.json
Normal file
96
Emby.Server.Implementations/Localization/Core/mk.json
Normal file
@@ -0,0 +1,96 @@
|
||||
{
|
||||
"ScheduledTaskFailedWithName": "{0} неуспешно",
|
||||
"ProviderValue": "Провајдер: {0}",
|
||||
"PluginUpdatedWithName": "{0} беше надоградено",
|
||||
"PluginUninstalledWithName": "{0} беше успешно деинсталирано",
|
||||
"PluginInstalledWithName": "{0} беше успешно инсталирано",
|
||||
"Plugin": "Додатоци",
|
||||
"Playlists": "Листи",
|
||||
"Photos": "Слики",
|
||||
"NotificationOptionVideoPlaybackStopped": "Видео стопирано",
|
||||
"NotificationOptionVideoPlayback": "Видео пуштено",
|
||||
"NotificationOptionUserLockedOut": "Корисникот е ослободен",
|
||||
"NotificationOptionTaskFailed": "Закажани задачи неуспешно",
|
||||
"NotificationOptionServerRestartRequired": "Задолжително рестартирање на серверот",
|
||||
"NotificationOptionPluginUpdateInstalled": "Надоградба на Додаток успешна",
|
||||
"NotificationOptionPluginUninstalled": "Додаток успешно деинсталиран",
|
||||
"NotificationOptionPluginInstalled": "Додаток успешно инсталиран",
|
||||
"NotificationOptionPluginError": "Грешка на додаток",
|
||||
"NotificationOptionNewLibraryContent": "Додадена нова содржина",
|
||||
"NotificationOptionInstallationFailed": "Неуспешна Инсталација",
|
||||
"NotificationOptionCameraImageUploaded": "Слика од камера поставена",
|
||||
"NotificationOptionAudioPlaybackStopped": "Аудио стопирано",
|
||||
"NotificationOptionAudioPlayback": "Аудио стартувано",
|
||||
"NotificationOptionApplicationUpdateInstalled": "Надоградбата на Апликацијата е иснталирана",
|
||||
"NotificationOptionApplicationUpdateAvailable": "Возможна надоградба на Апликацијата",
|
||||
"NewVersionIsAvailable": "Нова верзија од Jellyfin е возможна за спуштање.",
|
||||
"NameSeasonUnknown": "Непозната Сезона",
|
||||
"NameSeasonNumber": "Сезона {0}",
|
||||
"NameInstallFailed": "{0} неуспешна инсталација",
|
||||
"MusicVideos": "Музички видеа",
|
||||
"Music": "Музика",
|
||||
"Movies": "Филмови",
|
||||
"MixedContent": "Мешана содржина",
|
||||
"MessageServerConfigurationUpdated": "Серверската конфигурација беше надградена",
|
||||
"MessageNamedServerConfigurationUpdatedWithValue": "Секцијата на конфигурација на сервер {0} беше надоградена",
|
||||
"MessageApplicationUpdatedTo": "Jellyfin беше надограден до {0}",
|
||||
"MessageApplicationUpdated": "Jellyfin Серверот беше надограден",
|
||||
"Latest": "Последно",
|
||||
"LabelRunningTimeValue": "Време на работа: {0}",
|
||||
"LabelIpAddressValue": "ИП Адреса: {0}",
|
||||
"ItemRemovedWithName": "{0} е избришано до Библиотеката",
|
||||
"ItemAddedWithName": "{0} беше додадено во Библиотеката",
|
||||
"Inherit": "Следно",
|
||||
"HomeVideos": "Домашни Видеа",
|
||||
"HeaderRecordingGroups": "Групи на снимање",
|
||||
"HeaderNextUp": "Следно",
|
||||
"HeaderLiveTV": "ТВ",
|
||||
"HeaderFavoriteSongs": "Омилени Песни",
|
||||
"HeaderFavoriteShows": "Омилени Серии",
|
||||
"HeaderFavoriteEpisodes": "Омилени Епизоди",
|
||||
"HeaderFavoriteArtists": "Омилени Изведувачи",
|
||||
"HeaderFavoriteAlbums": "Омилени Албуми",
|
||||
"HeaderContinueWatching": "Продолжи со гледање",
|
||||
"HeaderCameraUploads": "Поставувања од камера",
|
||||
"HeaderAlbumArtists": "Изведувачи од Албуми",
|
||||
"Genres": "Жанрови",
|
||||
"Folders": "Папки",
|
||||
"Favorites": "Омилени",
|
||||
"FailedLoginAttemptWithUserName": "Неуспешно поврзување од {0}",
|
||||
"DeviceOnlineWithName": "{0} е приклучен",
|
||||
"DeviceOfflineWithName": "{0} се исклучи",
|
||||
"Collections": "Колекции",
|
||||
"ChapterNameValue": "Дел {0}",
|
||||
"Channels": "Канали",
|
||||
"CameraImageUploadedFrom": "Нова слика од камера беше поставена од {0}",
|
||||
"Books": "Книги",
|
||||
"AuthenticationSucceededWithUserName": "{0} успешно поврзан",
|
||||
"Artists": "Изведувач",
|
||||
"Application": "Апликација",
|
||||
"AppDeviceValues": "Аплиакција: {0}, Уред: {1}",
|
||||
"Albums": "Албуми",
|
||||
"VersionNumber": "Верзија {0}",
|
||||
"ValueSpecialEpisodeName": "Специјално - {0}",
|
||||
"ValueHasBeenAddedToLibrary": "{0} е додадено во твојата библиотека",
|
||||
"UserStoppedPlayingItemWithValues": "{0} заврши со репродукција {1} во {2}",
|
||||
"UserStartedPlayingItemWithValues": "{0} пушти {1} на {2}",
|
||||
"UserPolicyUpdatedWithName": "Полисата на користење беше надоградена за {0}",
|
||||
"UserPasswordChangedWithName": "Лозинката е сменета за корисникот {0}",
|
||||
"UserOnlineFromDevice": "{0} е приклучен од {1}",
|
||||
"UserOfflineFromDevice": "{0} е дисконектиран од {1}",
|
||||
"UserLockedOutWithName": "Корисникот {0} е заклучен",
|
||||
"UserDownloadingItemWithValues": "{0} се спушта {1}",
|
||||
"UserDeletedWithName": "Корисникот {0} е избришан",
|
||||
"UserCreatedWithName": "Корисникот {0} е креиран",
|
||||
"User": "Корисник",
|
||||
"TvShows": "ТВ Серии",
|
||||
"System": "Систем",
|
||||
"Sync": "Синхронизација",
|
||||
"SubtitlesDownloadedForItem": "Спуштање превод за {0}",
|
||||
"SubtitleDownloadFailureFromForItem": "Преводот неуспешно се спушти од {0} за {1}",
|
||||
"StartupEmbyServerIsLoading": "Jellyfin Server се пушта. Ве молиме причекајте.",
|
||||
"Songs": "Песни",
|
||||
"Shows": "Серии",
|
||||
"ServerNameNeedsToBeRestarted": "{0} треба да се рестартира",
|
||||
"ScheduledTaskStartedWithName": "{0} започна"
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"Albums": "Album-album",
|
||||
"AppDeviceValues": "App: {0}, Device: {1}",
|
||||
"AppDeviceValues": "Apl: {0}, Peranti: {1}",
|
||||
"Application": "Aplikasi",
|
||||
"Artists": "Artis-artis",
|
||||
"AuthenticationSucceededWithUserName": "{0} successfully authenticated",
|
||||
"Artists": "Artis",
|
||||
"AuthenticationSucceededWithUserName": "{0} berjaya disahkan",
|
||||
"Books": "Buku-buku",
|
||||
"CameraImageUploadedFrom": "A new camera image has been uploaded from {0}",
|
||||
"Channels": "Saluran",
|
||||
@@ -30,7 +30,7 @@
|
||||
"Inherit": "Inherit",
|
||||
"ItemAddedWithName": "{0} was added to the library",
|
||||
"ItemRemovedWithName": "{0} was removed from the library",
|
||||
"LabelIpAddressValue": "Ip address: {0}",
|
||||
"LabelIpAddressValue": "Alamat IP: {0}",
|
||||
"LabelRunningTimeValue": "Running time: {0}",
|
||||
"Latest": "Latest",
|
||||
"MessageApplicationUpdated": "Jellyfin Server has been updated",
|
||||
@@ -50,7 +50,7 @@
|
||||
"NotificationOptionAudioPlayback": "Audio playback started",
|
||||
"NotificationOptionAudioPlaybackStopped": "Audio playback stopped",
|
||||
"NotificationOptionCameraImageUploaded": "Camera image uploaded",
|
||||
"NotificationOptionInstallationFailed": "Installation failure",
|
||||
"NotificationOptionInstallationFailed": "Pemasangan gagal",
|
||||
"NotificationOptionNewLibraryContent": "New content added",
|
||||
"NotificationOptionPluginError": "Plugin failure",
|
||||
"NotificationOptionPluginInstalled": "Plugin installed",
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
"AppDeviceValues": "App: {0}, Apparaat: {1}",
|
||||
"Application": "Applicatie",
|
||||
"Artists": "Artiesten",
|
||||
"AuthenticationSucceededWithUserName": "{0} is succesvol geverifieerd",
|
||||
"AuthenticationSucceededWithUserName": "{0} succesvol geauthenticeerd",
|
||||
"Books": "Boeken",
|
||||
"CameraImageUploadedFrom": "Er is een nieuwe foto toegevoegd van {0}",
|
||||
"Channels": "Kanalen",
|
||||
"ChapterNameValue": "Hoofdstuk {0}",
|
||||
"Collections": "Verzamelingen",
|
||||
"DeviceOfflineWithName": "{0} heeft de verbinding verbroken",
|
||||
"DeviceOfflineWithName": "Verbinding met {0} is verbroken",
|
||||
"DeviceOnlineWithName": "{0} is verbonden",
|
||||
"FailedLoginAttemptWithUserName": "Mislukte aanmeld poging van {0}",
|
||||
"Favorites": "Favorieten",
|
||||
|
||||
@@ -1 +1,40 @@
|
||||
{}
|
||||
{
|
||||
"MessageServerConfigurationUpdated": "Tenar konfigurasjonen har blitt oppdatert",
|
||||
"MessageNamedServerConfigurationUpdatedWithValue": "Tenar konfigurasjon seksjon {0} har blitt oppdatert",
|
||||
"MessageApplicationUpdatedTo": "Jellyfin Tenaren har blitt oppdatert til {0}",
|
||||
"MessageApplicationUpdated": "Jellyfin Tenaren har blitt oppdatert",
|
||||
"Latest": "Nyaste",
|
||||
"LabelRunningTimeValue": "Speletid: {0}",
|
||||
"LabelIpAddressValue": "IP adresse: {0}",
|
||||
"ItemRemovedWithName": "{0} vart fjerna frå biblioteket",
|
||||
"ItemAddedWithName": "{0} vart lagt til i biblioteket",
|
||||
"Inherit": "Arv",
|
||||
"HomeVideos": "Heime Videoar",
|
||||
"HeaderRecordingGroups": "Innspelingsgrupper",
|
||||
"HeaderNextUp": "Neste",
|
||||
"HeaderLiveTV": "Direkte TV",
|
||||
"HeaderFavoriteSongs": "Favoritt Songar",
|
||||
"HeaderFavoriteShows": "Favoritt Seriar",
|
||||
"HeaderFavoriteEpisodes": "Favoritt Episodar",
|
||||
"HeaderFavoriteArtists": "Favoritt Artistar",
|
||||
"HeaderFavoriteAlbums": "Favoritt Album",
|
||||
"HeaderContinueWatching": "Fortsett å sjå",
|
||||
"HeaderCameraUploads": "Kamera Opplastingar",
|
||||
"HeaderAlbumArtists": "Album Artist",
|
||||
"Genres": "Sjangrar",
|
||||
"Folders": "Mapper",
|
||||
"Favorites": "Favorittar",
|
||||
"FailedLoginAttemptWithUserName": "Mislukka påloggingsforsøk frå {0}",
|
||||
"DeviceOnlineWithName": "{0} er tilkopla",
|
||||
"DeviceOfflineWithName": "{0} har kopla frå",
|
||||
"Collections": "Samlingar",
|
||||
"ChapterNameValue": "Kapittel {0}",
|
||||
"Channels": "Kanalar",
|
||||
"CameraImageUploadedFrom": "Eit nytt kamera bilete har blitt lasta opp frå {0}",
|
||||
"Books": "Bøker",
|
||||
"AuthenticationSucceededWithUserName": "{0} Har logga inn",
|
||||
"Artists": "Artistar",
|
||||
"Application": "Program",
|
||||
"AppDeviceValues": "App: {0}, Einheit: {1}",
|
||||
"Albums": "Album"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"HeaderLiveTV": "TV ao Vivo",
|
||||
"HeaderLiveTV": "TV em Directo",
|
||||
"Collections": "Colecções",
|
||||
"Books": "Livros",
|
||||
"Artists": "Artistas",
|
||||
@@ -10,13 +10,13 @@
|
||||
"HeaderFavoriteAlbums": "Álbuns Favoritos",
|
||||
"HeaderFavoriteEpisodes": "Episódios Favoritos",
|
||||
"HeaderFavoriteShows": "Séries Favoritas",
|
||||
"HeaderContinueWatching": "Continuar a Ver",
|
||||
"HeaderContinueWatching": "Continuar a Assistir",
|
||||
"HeaderAlbumArtists": "Artistas do Álbum",
|
||||
"Genres": "Géneros",
|
||||
"Folders": "Pastas",
|
||||
"Folders": "Directórios",
|
||||
"Favorites": "Favoritos",
|
||||
"Channels": "Canais",
|
||||
"UserDownloadingItemWithValues": "{0} está a transferir {1}",
|
||||
"UserDownloadingItemWithValues": "{0} está a ser transferido {1}",
|
||||
"VersionNumber": "Versão {0}",
|
||||
"ValueHasBeenAddedToLibrary": "{0} foi adicionado à sua biblioteca multimédia",
|
||||
"UserStoppedPlayingItemWithValues": "{0} terminou a reprodução de {1} em {2}",
|
||||
@@ -24,12 +24,12 @@
|
||||
"UserPolicyUpdatedWithName": "A política do utilizador {0} foi alterada",
|
||||
"UserPasswordChangedWithName": "A palavra-passe do utilizador {0} foi alterada",
|
||||
"UserOnlineFromDevice": "{0} ligou-se a partir de {1}",
|
||||
"UserOfflineFromDevice": "{0} desligou-se a partir de {1}",
|
||||
"UserLockedOutWithName": "Utilizador {0} bloqueado",
|
||||
"UserDeletedWithName": "Utilizador {0} removido",
|
||||
"UserCreatedWithName": "Utilizador {0} criado",
|
||||
"UserOfflineFromDevice": "{0} desconectou-se a partir de {1}",
|
||||
"UserLockedOutWithName": "O utilizador {0} foi bloqueado",
|
||||
"UserDeletedWithName": "O utilizador {0} foi removido",
|
||||
"UserCreatedWithName": "O utilizador {0} foi criado",
|
||||
"User": "Utilizador",
|
||||
"TvShows": "Programas",
|
||||
"TvShows": "Séries",
|
||||
"System": "Sistema",
|
||||
"SubtitlesDownloadedForItem": "Legendas transferidas para {0}",
|
||||
"SubtitleDownloadFailureFromForItem": "Falha na transferência de legendas de {0} para {1}",
|
||||
@@ -38,22 +38,22 @@
|
||||
"ScheduledTaskStartedWithName": "{0} iniciou",
|
||||
"ScheduledTaskFailedWithName": "{0} falhou",
|
||||
"ProviderValue": "Fornecedor: {0}",
|
||||
"PluginUpdatedWithName": "{0} foi actualizado",
|
||||
"PluginUpdatedWithName": "{0} foi atualizado",
|
||||
"PluginUninstalledWithName": "{0} foi desinstalado",
|
||||
"PluginInstalledWithName": "{0} foi instalado",
|
||||
"Plugin": "Extensão",
|
||||
"Plugin": "Plugin",
|
||||
"NotificationOptionVideoPlaybackStopped": "Reprodução de vídeo parada",
|
||||
"NotificationOptionVideoPlayback": "Reprodução de vídeo iniciada",
|
||||
"NotificationOptionUserLockedOut": "Utilizador bloqueado",
|
||||
"NotificationOptionTaskFailed": "Falha em tarefa agendada",
|
||||
"NotificationOptionServerRestartRequired": "É necessário reiniciar o servidor",
|
||||
"NotificationOptionPluginUpdateInstalled": "Extensão actualizada",
|
||||
"NotificationOptionPluginUninstalled": "Extensão desinstalada",
|
||||
"NotificationOptionPluginInstalled": "Extensão instalada",
|
||||
"NotificationOptionPluginError": "Falha na extensão",
|
||||
"NotificationOptionPluginUpdateInstalled": "Plugin actualizado",
|
||||
"NotificationOptionPluginUninstalled": "Plugin desinstalado",
|
||||
"NotificationOptionPluginInstalled": "Plugin instalado",
|
||||
"NotificationOptionPluginError": "Falha no plugin",
|
||||
"NotificationOptionNewLibraryContent": "Novo conteúdo adicionado",
|
||||
"NotificationOptionInstallationFailed": "Falha de instalação",
|
||||
"NotificationOptionCameraImageUploaded": "Imagem da câmara enviada",
|
||||
"NotificationOptionCameraImageUploaded": "Imagem de câmara enviada",
|
||||
"NotificationOptionAudioPlaybackStopped": "Reprodução Parada",
|
||||
"NotificationOptionAudioPlayback": "Reprodução Iniciada",
|
||||
"NotificationOptionApplicationUpdateInstalled": "A actualização da aplicação foi instalada",
|
||||
@@ -66,30 +66,30 @@
|
||||
"Music": "Música",
|
||||
"MixedContent": "Conteúdo Misto",
|
||||
"MessageServerConfigurationUpdated": "A configuração do servidor foi actualizada",
|
||||
"MessageNamedServerConfigurationUpdatedWithValue": "Configurações do servidor na secção {0} foram atualizadas",
|
||||
"MessageApplicationUpdatedTo": "O servidor Jellyfin foi actualizado para a versão {0}",
|
||||
"MessageNamedServerConfigurationUpdatedWithValue": "As configurações do servidor na secção {0} foram atualizadas",
|
||||
"MessageApplicationUpdatedTo": "O servidor Jellyfin foi atualizado para a versão {0}",
|
||||
"MessageApplicationUpdated": "O servidor Jellyfin foi actualizado",
|
||||
"Latest": "Mais Recente",
|
||||
"LabelRunningTimeValue": "Duração: {0}",
|
||||
"LabelIpAddressValue": "Endereço IP: {0}",
|
||||
"LabelIpAddressValue": "Endereço de IP: {0}",
|
||||
"ItemRemovedWithName": "{0} foi removido da biblioteca",
|
||||
"ItemAddedWithName": "{0} foi adicionado à biblioteca",
|
||||
"Inherit": "Herdar",
|
||||
"HomeVideos": "Vídeos Caseiros",
|
||||
"HeaderRecordingGroups": "Grupos de Gravação",
|
||||
"ValueSpecialEpisodeName": "Especial - {0}",
|
||||
"ValueSpecialEpisodeName": "Episódio Especial - {0}",
|
||||
"Sync": "Sincronização",
|
||||
"Songs": "Músicas",
|
||||
"Shows": "Séries",
|
||||
"Playlists": "Listas de Reprodução",
|
||||
"Photos": "Fotografias",
|
||||
"Movies": "Filmes",
|
||||
"HeaderCameraUploads": "Envios a partir da câmara",
|
||||
"FailedLoginAttemptWithUserName": "Tentativa de ligação a partir de {0} falhou",
|
||||
"DeviceOnlineWithName": "{0} ligou-se",
|
||||
"DeviceOfflineWithName": "{0} desligou-se",
|
||||
"HeaderCameraUploads": "Carregamentos a partir da câmara",
|
||||
"FailedLoginAttemptWithUserName": "Tentativa de ligação falhada a partir de {0}",
|
||||
"DeviceOnlineWithName": "{0} está connectado",
|
||||
"DeviceOfflineWithName": "{0} desconectou-se",
|
||||
"ChapterNameValue": "Capítulo {0}",
|
||||
"CameraImageUploadedFrom": "Uma nova imagem de câmara foi enviada a partir de {0}",
|
||||
"CameraImageUploadedFrom": "Uma nova imagem da câmara foi enviada a partir de {0}",
|
||||
"AuthenticationSucceededWithUserName": "{0} autenticado com sucesso",
|
||||
"Application": "Aplicação",
|
||||
"AppDeviceValues": "Aplicação {0}, Dispositivo: {1}"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"Albums": "Album",
|
||||
"AppDeviceValues": "App: {0}, Enhet: {1}",
|
||||
"Application": "App",
|
||||
"AppDeviceValues": "Applikation: {0}, Enhet: {1}",
|
||||
"Application": "Applikation",
|
||||
"Artists": "Artister",
|
||||
"AuthenticationSucceededWithUserName": "{0} har autentiserats",
|
||||
"Books": "Böcker",
|
||||
@@ -16,15 +16,15 @@
|
||||
"Folders": "Mappar",
|
||||
"Genres": "Genrer",
|
||||
"HeaderAlbumArtists": "Albumartister",
|
||||
"HeaderCameraUploads": "Kamera Uppladdningar",
|
||||
"HeaderContinueWatching": "Fortsätt kolla på",
|
||||
"HeaderCameraUploads": "Kamerauppladdningar",
|
||||
"HeaderContinueWatching": "Fortsätt kolla",
|
||||
"HeaderFavoriteAlbums": "Favoritalbum",
|
||||
"HeaderFavoriteArtists": "Favoritartister",
|
||||
"HeaderFavoriteEpisodes": "Favoritavsnitt",
|
||||
"HeaderFavoriteShows": "Favoritserier",
|
||||
"HeaderFavoriteSongs": "Favoritlåtar",
|
||||
"HeaderLiveTV": "Live-TV",
|
||||
"HeaderNextUp": "Nästa på tur",
|
||||
"HeaderNextUp": "Nästa",
|
||||
"HeaderRecordingGroups": "Inspelningsgrupper",
|
||||
"HomeVideos": "Hemvideor",
|
||||
"Inherit": "Ärv",
|
||||
@@ -34,9 +34,9 @@
|
||||
"LabelRunningTimeValue": "Speltid: {0}",
|
||||
"Latest": "Senaste",
|
||||
"MessageApplicationUpdated": "Jellyfin Server har uppdaterats",
|
||||
"MessageApplicationUpdatedTo": "Jellyfin Server har uppgraderats till {0}",
|
||||
"MessageApplicationUpdatedTo": "Jellyfin Server har uppdaterats till {0}",
|
||||
"MessageNamedServerConfigurationUpdatedWithValue": "Serverinställningarna {0} har uppdaterats",
|
||||
"MessageServerConfigurationUpdated": "Server konfigurationen har uppdaterats",
|
||||
"MessageServerConfigurationUpdated": "Serverkonfigurationen har uppdaterats",
|
||||
"MixedContent": "Blandat innehåll",
|
||||
"Movies": "Filmer",
|
||||
"Music": "Musik",
|
||||
@@ -44,11 +44,11 @@
|
||||
"NameInstallFailed": "{0} installationen misslyckades",
|
||||
"NameSeasonNumber": "Säsong {0}",
|
||||
"NameSeasonUnknown": "Okänd säsong",
|
||||
"NewVersionIsAvailable": "En ny version av Jellyfin Server är klar för nedladdning.",
|
||||
"NewVersionIsAvailable": "En ny version av Jellyfin Server är tillgänglig att hämta.",
|
||||
"NotificationOptionApplicationUpdateAvailable": "Ny programversion tillgänglig",
|
||||
"NotificationOptionApplicationUpdateInstalled": "Programuppdatering installerad",
|
||||
"NotificationOptionAudioPlayback": "Ljuduppspelning har påbörjats",
|
||||
"NotificationOptionAudioPlaybackStopped": "Ljuduppspelning stoppad",
|
||||
"NotificationOptionAudioPlaybackStopped": "Ljuduppspelning stoppades",
|
||||
"NotificationOptionCameraImageUploaded": "Kamerabild har laddats upp",
|
||||
"NotificationOptionInstallationFailed": "Fel vid installation",
|
||||
"NotificationOptionNewLibraryContent": "Nytt innehåll har lagts till",
|
||||
@@ -60,7 +60,7 @@
|
||||
"NotificationOptionTaskFailed": "Schemalagd aktivitet har misslyckats",
|
||||
"NotificationOptionUserLockedOut": "Användare har låsts ut",
|
||||
"NotificationOptionVideoPlayback": "Videouppspelning har påbörjats",
|
||||
"NotificationOptionVideoPlaybackStopped": "Videouppspelning stoppad",
|
||||
"NotificationOptionVideoPlaybackStopped": "Videouppspelning stoppades",
|
||||
"Photos": "Bilder",
|
||||
"Playlists": "Spellistor",
|
||||
"Plugin": "Tillägg",
|
||||
@@ -69,13 +69,13 @@
|
||||
"PluginUpdatedWithName": "{0} uppdaterades",
|
||||
"ProviderValue": "Källa: {0}",
|
||||
"ScheduledTaskFailedWithName": "{0} misslyckades",
|
||||
"ScheduledTaskStartedWithName": "{0} startad",
|
||||
"ScheduledTaskStartedWithName": "{0} startades",
|
||||
"ServerNameNeedsToBeRestarted": "{0} behöver startas om",
|
||||
"Shows": "Serier",
|
||||
"Songs": "Låtar",
|
||||
"StartupEmbyServerIsLoading": "Jellyfin server arbetar. Pröva igen inom kort.",
|
||||
"StartupEmbyServerIsLoading": "Jellyfin Server arbetar. Pröva igen snart.",
|
||||
"SubtitleDownloadFailureForItem": "Nerladdning av undertexter för {0} misslyckades",
|
||||
"SubtitleDownloadFailureFromForItem": "Undertexter misslyckades att ladda ner {0} för {1}",
|
||||
"SubtitleDownloadFailureFromForItem": "Undertexter kunde inte laddas ner från {0} för {1}",
|
||||
"SubtitlesDownloadedForItem": "Undertexter har laddats ner till {0}",
|
||||
"Sync": "Synk",
|
||||
"System": "System",
|
||||
@@ -89,9 +89,9 @@
|
||||
"UserOnlineFromDevice": "{0} är uppkopplad från {1}",
|
||||
"UserPasswordChangedWithName": "Lösenordet för {0} har ändrats",
|
||||
"UserPolicyUpdatedWithName": "Användarpolicyn har uppdaterats för {0}",
|
||||
"UserStartedPlayingItemWithValues": "{0} har börjat spela upp {1}",
|
||||
"UserStoppedPlayingItemWithValues": "{0} har avslutat uppspelningen av {1}",
|
||||
"ValueHasBeenAddedToLibrary": "{0} har blivit tillagd till ditt mediabibliotek",
|
||||
"UserStartedPlayingItemWithValues": "{0} spelar upp {1} på {2}",
|
||||
"UserStoppedPlayingItemWithValues": "{0} har avslutat uppspelningen av {1} på {2}",
|
||||
"ValueHasBeenAddedToLibrary": "{0} har lagts till i ditt mediebibliotek",
|
||||
"ValueSpecialEpisodeName": "Specialavsnitt - {0}",
|
||||
"VersionNumber": "Version {0}"
|
||||
}
|
||||
|
||||
@@ -17,14 +17,14 @@
|
||||
"Genres": "风格",
|
||||
"HeaderAlbumArtists": "专辑作家",
|
||||
"HeaderCameraUploads": "相机上传",
|
||||
"HeaderContinueWatching": "继续观看",
|
||||
"HeaderContinueWatching": "继续观影",
|
||||
"HeaderFavoriteAlbums": "收藏的专辑",
|
||||
"HeaderFavoriteArtists": "最爱的艺术家",
|
||||
"HeaderFavoriteEpisodes": "最爱的剧集",
|
||||
"HeaderFavoriteShows": "最爱的节目",
|
||||
"HeaderFavoriteSongs": "最爱的歌曲",
|
||||
"HeaderLiveTV": "电视直播",
|
||||
"HeaderNextUp": "下一步",
|
||||
"HeaderNextUp": "接下来",
|
||||
"HeaderRecordingGroups": "录制组",
|
||||
"HomeVideos": "家庭视频",
|
||||
"Inherit": "继承",
|
||||
|
||||
@@ -33,14 +33,14 @@ namespace Emby.Server.Implementations.Playlists
|
||||
ILibraryManager libraryManager,
|
||||
IFileSystem fileSystem,
|
||||
ILibraryMonitor iLibraryMonitor,
|
||||
ILoggerFactory loggerFactory,
|
||||
ILogger<PlaylistManager> logger,
|
||||
IUserManager userManager,
|
||||
IProviderManager providerManager)
|
||||
{
|
||||
_libraryManager = libraryManager;
|
||||
_fileSystem = fileSystem;
|
||||
_iLibraryMonitor = iLibraryMonitor;
|
||||
_logger = loggerFactory.CreateLogger(nameof(PlaylistManager));
|
||||
_logger = logger;
|
||||
_userManager = userManager;
|
||||
_providerManager = providerManager;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,10 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DeleteCacheFileTask" /> class.
|
||||
/// </summary>
|
||||
public DeleteCacheFileTask(IApplicationPaths appPaths, ILogger logger, IFileSystem fileSystem)
|
||||
public DeleteCacheFileTask(
|
||||
IApplicationPaths appPaths,
|
||||
ILogger<DeleteCacheFileTask> logger,
|
||||
IFileSystem fileSystem)
|
||||
{
|
||||
ApplicationPaths = appPaths;
|
||||
_logger = logger;
|
||||
|
||||
@@ -23,7 +23,10 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DeleteTranscodeFileTask" /> class.
|
||||
/// </summary>
|
||||
public DeleteTranscodeFileTask(ILogger logger, IFileSystem fileSystem, IConfigurationManager configurationManager)
|
||||
public DeleteTranscodeFileTask(
|
||||
ILogger<DeleteTranscodeFileTask> logger,
|
||||
IFileSystem fileSystem,
|
||||
IConfigurationManager configurationManager)
|
||||
{
|
||||
_logger = logger;
|
||||
_fileSystem = fileSystem;
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
||||
|
||||
private readonly IInstallationManager _installationManager;
|
||||
|
||||
public PluginUpdateTask(ILogger logger, IInstallationManager installationManager)
|
||||
public PluginUpdateTask(ILogger<PluginUpdateTask> logger, IInstallationManager installationManager)
|
||||
{
|
||||
_logger = logger;
|
||||
_installationManager = installationManager;
|
||||
|
||||
@@ -21,15 +21,14 @@ namespace Emby.Server.Implementations.SocketSharp
|
||||
private CancellationTokenSource _disposeCancellationTokenSource = new CancellationTokenSource();
|
||||
private CancellationToken _disposeCancellationToken;
|
||||
|
||||
public WebSocketSharpListener(
|
||||
ILogger logger)
|
||||
public WebSocketSharpListener(ILogger<WebSocketSharpListener> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
|
||||
_disposeCancellationToken = _disposeCancellationTokenSource.Token;
|
||||
}
|
||||
|
||||
public Func<Exception, IRequest, bool, bool, Task> ErrorHandler { get; set; }
|
||||
|
||||
public Func<IHttpRequest, string, string, string, CancellationToken, Task> RequestHandler { get; set; }
|
||||
|
||||
public Action<WebSocketConnectEventArgs> WebSocketConnected { get; set; }
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using MediaBrowser.Controller.Sorting;
|
||||
|
||||
namespace Emby.Server.Implementations.Sorting
|
||||
{
|
||||
public class AlphanumComparator : IComparer<string>
|
||||
{
|
||||
public static int CompareValues(string s1, string s2)
|
||||
{
|
||||
if (s1 == null || s2 == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int thisMarker = 0, thisNumericChunk = 0;
|
||||
int thatMarker = 0, thatNumericChunk = 0;
|
||||
|
||||
while ((thisMarker < s1.Length) || (thatMarker < s2.Length))
|
||||
{
|
||||
if (thisMarker >= s1.Length)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (thatMarker >= s2.Length)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
char thisCh = s1[thisMarker];
|
||||
char thatCh = s2[thatMarker];
|
||||
|
||||
var thisChunk = new StringBuilder();
|
||||
var thatChunk = new StringBuilder();
|
||||
|
||||
while ((thisMarker < s1.Length) && (thisChunk.Length == 0 || SortHelper.InChunk(thisCh, thisChunk[0])))
|
||||
{
|
||||
thisChunk.Append(thisCh);
|
||||
thisMarker++;
|
||||
|
||||
if (thisMarker < s1.Length)
|
||||
{
|
||||
thisCh = s1[thisMarker];
|
||||
}
|
||||
}
|
||||
|
||||
while ((thatMarker < s2.Length) && (thatChunk.Length == 0 || SortHelper.InChunk(thatCh, thatChunk[0])))
|
||||
{
|
||||
thatChunk.Append(thatCh);
|
||||
thatMarker++;
|
||||
|
||||
if (thatMarker < s2.Length)
|
||||
{
|
||||
thatCh = s2[thatMarker];
|
||||
}
|
||||
}
|
||||
|
||||
int result = 0;
|
||||
// If both chunks contain numeric characters, sort them numerically
|
||||
if (char.IsDigit(thisChunk[0]) && char.IsDigit(thatChunk[0]))
|
||||
{
|
||||
if (!int.TryParse(thisChunk.ToString(), out thisNumericChunk))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (!int.TryParse(thatChunk.ToString(), out thatNumericChunk))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (thisNumericChunk < thatNumericChunk)
|
||||
{
|
||||
result = -1;
|
||||
}
|
||||
|
||||
if (thisNumericChunk > thatNumericChunk)
|
||||
{
|
||||
result = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = thisChunk.ToString().CompareTo(thatChunk.ToString());
|
||||
}
|
||||
|
||||
if (result != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int Compare(string x, string y)
|
||||
{
|
||||
return CompareValues(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user