diff options
| author | David <daullmer@gmail.com> | 2020-07-18 19:21:43 +0200 |
|---|---|---|
| committer | David <daullmer@gmail.com> | 2020-07-18 19:21:43 +0200 |
| commit | 0e1bf316b5c8da1d1f334fabe4a0abf77185f2e0 (patch) | |
| tree | dd59ea68b275ec8125ca454422cd027d891de477 /Emby.Server.Implementations | |
| parent | fa4e0a73d5eb0b33dc85dffb2a2d35033c5ce698 (diff) | |
| parent | 09c05ff9faff4fd5013e19fad74835bdf796393f (diff) | |
Merge branch 'master' of github.com:jellyfin/jellyfin into socket-binding
Diffstat (limited to 'Emby.Server.Implementations')
12 files changed, 119 insertions, 82 deletions
diff --git a/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs b/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs index b207397bd..9486874d5 100644 --- a/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs +++ b/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs @@ -1,3 +1,4 @@ +using System.Net.Sockets; using System.Threading; using System.Threading.Tasks; using Emby.Server.Implementations.Udp; @@ -48,8 +49,16 @@ namespace Emby.Server.Implementations.EntryPoints /// <inheritdoc /> public Task RunAsync() { - _udpServer = new UdpServer(_logger, _appHost, _config); - _udpServer.Start(PortNumber, _cancellationTokenSource.Token); + try + { + _udpServer = new UdpServer(_logger, _appHost, _config); + _udpServer.Start(PortNumber, _cancellationTokenSource.Token); + } + catch (SocketException ex) + { + _logger.LogWarning(ex, "Unable to start AutoDiscovery listener on UDP port {PortNumber}", PortNumber); + } + return Task.CompletedTask; } diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index 77d44e131..06cfc78b3 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -341,7 +341,7 @@ namespace Emby.Server.Implementations.Library if (item is LiveTvProgram) { _logger.LogDebug( - "Deleting item, Type: {0}, Name: {1}, Path: {2}, Id: {3}", + "Removing item, Type: {0}, Name: {1}, Path: {2}, Id: {3}", item.GetType().Name, item.Name ?? "Unknown name", item.Path ?? string.Empty, @@ -350,7 +350,7 @@ namespace Emby.Server.Implementations.Library else { _logger.LogInformation( - "Deleting item, Type: {0}, Name: {1}, Path: {2}, Id: {3}", + "Removing item, Type: {0}, Name: {1}, Path: {2}, Id: {3}", item.GetType().Name, item.Name ?? "Unknown name", item.Path ?? string.Empty, @@ -368,7 +368,12 @@ namespace Emby.Server.Implementations.Library continue; } - _logger.LogDebug("Deleting path {MetadataPath}", metadataPath); + _logger.LogDebug( + "Deleting metadata path, Type: {0}, Name: {1}, Path: {2}, Id: {3}", + item.GetType().Name, + item.Name ?? "Unknown name", + metadataPath, + item.Id); try { @@ -392,7 +397,13 @@ namespace Emby.Server.Implementations.Library { try { - _logger.LogDebug("Deleting path {path}", fileSystemInfo.FullName); + _logger.LogInformation( + "Deleting item path, Type: {0}, Name: {1}, Path: {2}, Id: {3}", + item.GetType().Name, + item.Name ?? "Unknown name", + fileSystemInfo.FullName, + item.Id); + if (fileSystemInfo.IsDirectory) { Directory.Delete(fileSystemInfo.FullName, true); diff --git a/Emby.Server.Implementations/Localization/Core/af.json b/Emby.Server.Implementations/Localization/Core/af.json index 20447347b..e587c37d5 100644 --- a/Emby.Server.Implementations/Localization/Core/af.json +++ b/Emby.Server.Implementations/Localization/Core/af.json @@ -19,8 +19,8 @@ "Sync": "Sinkroniseer", "HeaderFavoriteSongs": "Gunsteling Liedjies", "Songs": "Liedjies", - "DeviceOnlineWithName": "{0} is verbind", - "DeviceOfflineWithName": "{0} het afgesluit", + "DeviceOnlineWithName": "{0} gekoppel is", + "DeviceOfflineWithName": "{0} is ontkoppel", "Collections": "Versamelings", "Inherit": "Ontvang", "HeaderLiveTV": "Live TV", @@ -91,5 +91,9 @@ "ChapterNameValue": "Hoofstuk", "CameraImageUploadedFrom": "'n Nuwe kamera photo opgelaai van {0}", "AuthenticationSucceededWithUserName": "{0} suksesvol geverifieer", - "Albums": "Albums" + "Albums": "Albums", + "TasksChannelsCategory": "Internet kanale", + "TasksApplicationCategory": "aansoek", + "TasksLibraryCategory": "biblioteek", + "TasksMaintenanceCategory": "onderhoud" } diff --git a/Emby.Server.Implementations/Localization/Core/de.json b/Emby.Server.Implementations/Localization/Core/de.json index 82df43be1..a6e9779c9 100644 --- a/Emby.Server.Implementations/Localization/Core/de.json +++ b/Emby.Server.Implementations/Localization/Core/de.json @@ -3,7 +3,7 @@ "AppDeviceValues": "App: {0}, Gerät: {1}", "Application": "Anwendung", "Artists": "Interpreten", - "AuthenticationSucceededWithUserName": "{0} hat sich erfolgreich authentifiziert", + "AuthenticationSucceededWithUserName": "{0} hat sich erfolgreich angemeldet", "Books": "Bücher", "CameraImageUploadedFrom": "Ein neues Foto wurde von {0} hochgeladen", "Channels": "Kanäle", diff --git a/Emby.Server.Implementations/Localization/Core/ms.json b/Emby.Server.Implementations/Localization/Core/ms.json index 79d078d4a..7f8df1289 100644 --- a/Emby.Server.Implementations/Localization/Core/ms.json +++ b/Emby.Server.Implementations/Localization/Core/ms.json @@ -5,47 +5,47 @@ "Artists": "Artis", "AuthenticationSucceededWithUserName": "{0} berjaya disahkan", "Books": "Buku-buku", - "CameraImageUploadedFrom": "A new camera image has been uploaded from {0}", + "CameraImageUploadedFrom": "Ada gambar dari kamera yang baru dimuat naik melalui {0}", "Channels": "Saluran", - "ChapterNameValue": "Chapter {0}", + "ChapterNameValue": "Bab {0}", "Collections": "Koleksi", - "DeviceOfflineWithName": "{0} has disconnected", - "DeviceOnlineWithName": "{0} is connected", + "DeviceOfflineWithName": "{0} telah diputuskan sambungan", + "DeviceOnlineWithName": "{0} telah disambung", "FailedLoginAttemptWithUserName": "Cubaan log masuk gagal dari {0}", - "Favorites": "Favorites", - "Folders": "Folders", + "Favorites": "Kegemaran", + "Folders": "Fail-fail", "Genres": "Genre-genre", - "HeaderAlbumArtists": "Album Artists", + "HeaderAlbumArtists": "Album Artis-artis", "HeaderCameraUploads": "Muatnaik Kamera", "HeaderContinueWatching": "Terus Menonton", - "HeaderFavoriteAlbums": "Favorite Albums", - "HeaderFavoriteArtists": "Favorite Artists", - "HeaderFavoriteEpisodes": "Favorite Episodes", - "HeaderFavoriteShows": "Favorite Shows", - "HeaderFavoriteSongs": "Favorite Songs", - "HeaderLiveTV": "Live TV", - "HeaderNextUp": "Next Up", - "HeaderRecordingGroups": "Recording Groups", - "HomeVideos": "Home videos", - "Inherit": "Inherit", - "ItemAddedWithName": "{0} was added to the library", - "ItemRemovedWithName": "{0} was removed from the library", + "HeaderFavoriteAlbums": "Album-album Kegemaran", + "HeaderFavoriteArtists": "Artis-artis Kegemaran", + "HeaderFavoriteEpisodes": "Episod-episod Kegemaran", + "HeaderFavoriteShows": "Rancangan-rancangan Kegemaran", + "HeaderFavoriteSongs": "Lagu-lagu Kegemaran", + "HeaderLiveTV": "TV Siaran Langsung", + "HeaderNextUp": "Seterusnya", + "HeaderRecordingGroups": "Kumpulan-kumpulan Rakaman", + "HomeVideos": "Video Personal", + "Inherit": "Mewarisi", + "ItemAddedWithName": "{0} telah ditambahkan ke dalam pustaka", + "ItemRemovedWithName": "{0} telah dibuang daripada pustaka", "LabelIpAddressValue": "Alamat IP: {0}", - "LabelRunningTimeValue": "Running time: {0}", - "Latest": "Latest", - "MessageApplicationUpdated": "Jellyfin Server has been updated", - "MessageApplicationUpdatedTo": "Jellyfin Server has been updated to {0}", - "MessageNamedServerConfigurationUpdatedWithValue": "Server configuration section {0} has been updated", - "MessageServerConfigurationUpdated": "Server configuration has been updated", - "MixedContent": "Mixed content", - "Movies": "Movies", + "LabelRunningTimeValue": "Masa berjalan: {0}", + "Latest": "Terbaru", + "MessageApplicationUpdated": "Jellyfin Server telah dikemas kini", + "MessageApplicationUpdatedTo": "Jellyfin Server telah dikemas kini ke {0}", + "MessageNamedServerConfigurationUpdatedWithValue": "Konfigurasi pelayan di bahagian {0} telah dikemas kini", + "MessageServerConfigurationUpdated": "Konfigurasi pelayan telah dikemas kini", + "MixedContent": "Kandungan campuran", + "Movies": "Filem", "Music": "Muzik", "MusicVideos": "Video muzik", - "NameInstallFailed": "{0} installation failed", - "NameSeasonNumber": "Season {0}", - "NameSeasonUnknown": "Season Unknown", - "NewVersionIsAvailable": "A new version of Jellyfin Server is available for download.", - "NotificationOptionApplicationUpdateAvailable": "Application update available", + "NameInstallFailed": "{0} pemasangan gagal", + "NameSeasonNumber": "Musim {0}", + "NameSeasonUnknown": "Musim Tidak Diketahui", + "NewVersionIsAvailable": "Versi terbaru Jellyfin Server bersedia untuk dimuat turunkan.", + "NotificationOptionApplicationUpdateAvailable": "Kemas kini aplikasi telah sedia", "NotificationOptionApplicationUpdateInstalled": "Application update installed", "NotificationOptionAudioPlayback": "Audio playback started", "NotificationOptionAudioPlaybackStopped": "Audio playback stopped", diff --git a/Emby.Server.Implementations/Localization/Core/pt.json b/Emby.Server.Implementations/Localization/Core/pt.json index 5365fff23..b534d0bbe 100644 --- a/Emby.Server.Implementations/Localization/Core/pt.json +++ b/Emby.Server.Implementations/Localization/Core/pt.json @@ -104,5 +104,14 @@ "TaskRefreshChapterImagesDescription": "Cria miniaturas para vídeos que têm capítulos.", "TaskCleanCacheDescription": "Apaga ficheiros em cache que já não são usados pelo sistema.", "TasksChannelsCategory": "Canais de Internet", - "TaskRefreshChapterImages": "Extrair Imagens do Capítulo" + "TaskRefreshChapterImages": "Extrair Imagens do Capítulo", + "TaskDownloadMissingSubtitlesDescription": "Pesquisa na Internet as legendas em falta com base na configuração de metadados.", + "TaskDownloadMissingSubtitles": "Download das legendas em falta", + "TaskRefreshChannelsDescription": "Atualiza as informações do canal da Internet.", + "TaskCleanTranscodeDescription": "Apagar os ficheiros com mais de um dia, de Transcode.", + "TaskCleanTranscode": "Limpar o diretório de Transcode", + "TaskUpdatePluginsDescription": "Download e instala as atualizações para plug-ins configurados para atualização automática.", + "TaskRefreshPeopleDescription": "Atualiza os metadados para atores e diretores na tua biblioteca de media.", + "TaskRefreshPeople": "Atualizar pessoas", + "TaskRefreshLibraryDescription": "Pesquisa a tua biblioteca de media por novos ficheiros e atualiza os metadados." } diff --git a/Emby.Server.Implementations/Localization/Core/th.json b/Emby.Server.Implementations/Localization/Core/th.json index 32538ac03..576aaeb1b 100644 --- a/Emby.Server.Implementations/Localization/Core/th.json +++ b/Emby.Server.Implementations/Localization/Core/th.json @@ -67,5 +67,7 @@ "Artists": "นักแสดง", "Application": "แอปพลิเคชั่น", "AppDeviceValues": "App: {0}, อุปกรณ์: {1}", - "Albums": "อัลบั้ม" + "Albums": "อัลบั้ม", + "ScheduledTaskStartedWithName": "{0} เริ่มต้น", + "ScheduledTaskFailedWithName": "{0} ล้มเหลว" } diff --git a/Emby.Server.Implementations/Session/SessionManager.cs b/Emby.Server.Implementations/Session/SessionManager.cs index d069d1ada..ca9f95c70 100644 --- a/Emby.Server.Implementations/Session/SessionManager.cs +++ b/Emby.Server.Implementations/Session/SessionManager.cs @@ -296,7 +296,7 @@ namespace Emby.Server.Implementations.Session } catch (DbUpdateConcurrencyException e) { - _logger.LogWarning(e, "Error updating user's last activity date."); + _logger.LogDebug(e, "Error updating user's last activity date."); } } } diff --git a/Emby.Server.Implementations/SyncPlay/SyncPlayController.cs b/Emby.Server.Implementations/SyncPlay/SyncPlayController.cs index b1f8fd330..39d17833f 100644 --- a/Emby.Server.Implementations/SyncPlay/SyncPlayController.cs +++ b/Emby.Server.Implementations/SyncPlay/SyncPlayController.cs @@ -194,26 +194,24 @@ namespace Emby.Server.Implementations.SyncPlay } /// <inheritdoc /> - public void InitGroup(SessionInfo session, CancellationToken cancellationToken) + public void CreateGroup(SessionInfo session, CancellationToken cancellationToken) { _group.AddSession(session); _syncPlayManager.AddSessionToGroup(session, this); _group.PlayingItem = session.FullNowPlayingItem; - _group.IsPaused = true; + _group.IsPaused = session.PlayState.IsPaused; _group.PositionTicks = session.PlayState.PositionTicks ?? 0; _group.LastActivity = DateTime.UtcNow; var updateSession = NewSyncPlayGroupUpdate(GroupUpdateType.GroupJoined, DateToUTCString(DateTime.UtcNow)); SendGroupUpdate(session, BroadcastType.CurrentSession, updateSession, cancellationToken); - var pauseCommand = NewSyncPlayCommand(SendCommandType.Pause); - SendCommand(session, BroadcastType.CurrentSession, pauseCommand, cancellationToken); } /// <inheritdoc /> public void SessionJoin(SessionInfo session, JoinGroupRequest request, CancellationToken cancellationToken) { - if (session.NowPlayingItem?.Id == _group.PlayingItem.Id && request.PlayingItemId == _group.PlayingItem.Id) + if (session.NowPlayingItem?.Id == _group.PlayingItem.Id) { _group.AddSession(session); _syncPlayManager.AddSessionToGroup(session, this); @@ -224,7 +222,7 @@ namespace Emby.Server.Implementations.SyncPlay var updateOthers = NewSyncPlayGroupUpdate(GroupUpdateType.UserJoined, session.UserName); SendGroupUpdate(session, BroadcastType.AllExceptCurrentSession, updateOthers, cancellationToken); - // Client join and play, syncing will happen client side + // Syncing will happen client-side if (!_group.IsPaused) { var playCommand = NewSyncPlayCommand(SendCommandType.Play); @@ -262,10 +260,9 @@ namespace Emby.Server.Implementations.SyncPlay /// <inheritdoc /> public void HandleRequest(SessionInfo session, PlaybackRequest request, CancellationToken cancellationToken) { - // The server's job is to mantain a consistent state to which clients refer to, - // as also to notify clients of state changes. - // The actual syncing of media playback happens client side. - // Clients are aware of the server's time and use it to sync. + // The server's job is to maintain a consistent state for clients to reference + // and notify clients of state changes. The actual syncing of media playback + // happens client side. Clients are aware of the server's time and use it to sync. switch (request.Type) { case PlaybackRequestType.Play: @@ -277,13 +274,13 @@ namespace Emby.Server.Implementations.SyncPlay case PlaybackRequestType.Seek: HandleSeekRequest(session, request, cancellationToken); break; - case PlaybackRequestType.Buffering: + case PlaybackRequestType.Buffer: HandleBufferingRequest(session, request, cancellationToken); break; - case PlaybackRequestType.BufferingDone: + case PlaybackRequestType.Ready: HandleBufferingDoneRequest(session, request, cancellationToken); break; - case PlaybackRequestType.UpdatePing: + case PlaybackRequestType.Ping: HandlePingUpdateRequest(session, request); break; } @@ -301,7 +298,7 @@ namespace Emby.Server.Implementations.SyncPlay { // Pick a suitable time that accounts for latency var delay = _group.GetHighestPing() * 2; - delay = delay < _group.DefaulPing ? _group.DefaulPing : delay; + delay = delay < _group.DefaultPing ? _group.DefaultPing : delay; // Unpause group and set starting point in future // Clients will start playback at LastActivity (datetime) from PositionTicks (playback position) @@ -337,8 +334,9 @@ namespace Emby.Server.Implementations.SyncPlay var currentTime = DateTime.UtcNow; var elapsedTime = currentTime - _group.LastActivity; _group.LastActivity = currentTime; + // Seek only if playback actually started - // (a pause request may be issued during the delay added to account for latency) + // Pause request may be issued during the delay added to account for latency _group.PositionTicks += elapsedTime.Ticks > 0 ? elapsedTime.Ticks : 0; var command = NewSyncPlayCommand(SendCommandType.Pause); @@ -451,7 +449,7 @@ namespace Emby.Server.Implementations.SyncPlay { // Client, that was buffering, resumed playback but did not update others in time delay = _group.GetHighestPing() * 2; - delay = delay < _group.DefaulPing ? _group.DefaulPing : delay; + delay = delay < _group.DefaultPing ? _group.DefaultPing : delay; _group.LastActivity = currentTime.AddMilliseconds( delay); @@ -495,7 +493,7 @@ namespace Emby.Server.Implementations.SyncPlay private void HandlePingUpdateRequest(SessionInfo session, PlaybackRequest request) { // Collected pings are used to account for network latency when unpausing playback - _group.UpdatePing(session, request.Ping ?? _group.DefaulPing); + _group.UpdatePing(session, request.Ping ?? _group.DefaultPing); } /// <inheritdoc /> diff --git a/Emby.Server.Implementations/SyncPlay/SyncPlayManager.cs b/Emby.Server.Implementations/SyncPlay/SyncPlayManager.cs index 45a43fd78..966ed5024 100644 --- a/Emby.Server.Implementations/SyncPlay/SyncPlayManager.cs +++ b/Emby.Server.Implementations/SyncPlay/SyncPlayManager.cs @@ -170,10 +170,11 @@ namespace Emby.Server.Implementations.SyncPlay { _logger.LogWarning("NewGroup: {0} does not have permission to create groups.", session.Id); - var error = new GroupUpdate<string>() + var error = new GroupUpdate<string> { Type = GroupUpdateType.CreateGroupDenied }; + _sessionManager.SendSyncPlayGroupUpdate(session.Id, error, CancellationToken.None); return; } @@ -188,7 +189,7 @@ namespace Emby.Server.Implementations.SyncPlay var group = new SyncPlayController(_sessionManager, this); _groups[group.GetGroupId()] = group; - group.InitGroup(session, cancellationToken); + group.CreateGroup(session, cancellationToken); } } @@ -205,6 +206,7 @@ namespace Emby.Server.Implementations.SyncPlay { Type = GroupUpdateType.JoinGroupDenied }; + _sessionManager.SendSyncPlayGroupUpdate(session.Id, error, CancellationToken.None); return; } @@ -300,9 +302,9 @@ namespace Emby.Server.Implementations.SyncPlay group => group.GetPlayingItemId().Equals(filterItemId) && HasAccessToItem(user, group.GetPlayingItemId())).Select( group => group.GetInfo()).ToList(); } - // Otherwise show all available groups else { + // Otherwise show all available groups return _groups.Values.Where( group => HasAccessToItem(user, group.GetPlayingItemId())).Select( group => group.GetInfo()).ToList(); @@ -322,6 +324,7 @@ namespace Emby.Server.Implementations.SyncPlay { Type = GroupUpdateType.JoinGroupDenied }; + _sessionManager.SendSyncPlayGroupUpdate(session.Id, error, CancellationToken.None); return; } @@ -366,7 +369,6 @@ namespace Emby.Server.Implementations.SyncPlay } _sessionToGroupMap.Remove(session.Id, out var tempGroup); - if (!tempGroup.GetGroupId().Equals(group.GetGroupId())) { throw new InvalidOperationException("Session was in wrong group!"); diff --git a/Emby.Server.Implementations/TV/TVSeriesManager.cs b/Emby.Server.Implementations/TV/TVSeriesManager.cs index 21c12ae79..d1818deff 100644 --- a/Emby.Server.Implementations/TV/TVSeriesManager.cs +++ b/Emby.Server.Implementations/TV/TVSeriesManager.cs @@ -117,23 +117,20 @@ namespace Emby.Server.Implementations.TV limit = limit.Value + 10; } - var items = _libraryManager.GetItemList(new InternalItemsQuery(user) - { - IncludeItemTypes = new[] { typeof(Episode).Name }, - OrderBy = new[] { new ValueTuple<string, SortOrder>(ItemSortBy.DatePlayed, SortOrder.Descending) }, - SeriesPresentationUniqueKey = presentationUniqueKey, - Limit = limit, - DtoOptions = new DtoOptions - { - Fields = new ItemFields[] + var items = _libraryManager + .GetItemList( + new InternalItemsQuery(user) { - ItemFields.SeriesPresentationUniqueKey - }, - EnableImages = false - }, - GroupBySeriesPresentationUniqueKey = true - - }, parentsFolders.ToList()).Cast<Episode>().Select(GetUniqueSeriesKey); + IncludeItemTypes = new[] { typeof(Episode).Name }, + OrderBy = new[] { new ValueTuple<string, SortOrder>(ItemSortBy.DatePlayed, SortOrder.Descending) }, + SeriesPresentationUniqueKey = presentationUniqueKey, + Limit = limit, + DtoOptions = new DtoOptions { Fields = new[] { ItemFields.SeriesPresentationUniqueKey }, EnableImages = false }, + GroupBySeriesPresentationUniqueKey = true + }, parentsFolders.ToList()) + .Cast<Episode>() + .Where(episode => !string.IsNullOrEmpty(episode.SeriesPresentationUniqueKey)) + .Select(GetUniqueSeriesKey); // Avoid implicitly captured closure var episodes = GetNextUpEpisodes(request, user, items, dtoOptions); diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs index 146ebaf25..4f54c06dd 100644 --- a/Emby.Server.Implementations/Updates/InstallationManager.cs +++ b/Emby.Server.Implementations/Updates/InstallationManager.cs @@ -148,6 +148,11 @@ namespace Emby.Server.Implementations.Updates _logger.LogError(ex, "An error occurred while accessing the plugin manifest: {Manifest}", manifest); return Array.Empty<PackageInfo>(); } + catch (HttpRequestException ex) + { + _logger.LogError(ex, "An error occurred while accessing the plugin manifest: {Manifest}", manifest); + return Array.Empty<PackageInfo>(); + } } /// <inheritdoc /> |
