diff --git a/Jellyfin.Plugin.TubeArchivistMetadata/Plugin.cs b/Jellyfin.Plugin.TubeArchivistMetadata/Plugin.cs index c1f3b40..9affaad 100644 --- a/Jellyfin.Plugin.TubeArchivistMetadata/Plugin.cs +++ b/Jellyfin.Plugin.TubeArchivistMetadata/Plugin.cs @@ -5,10 +5,15 @@ using System.Net.Http; using System.Threading.Tasks; using Jellyfin.Plugin.TubeArchivistMetadata.Configuration; using Jellyfin.Plugin.TubeArchivistMetadata.TubeArchivist; +using Jellyfin.Plugin.TubeArchivistMetadata.Utilities; using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Plugins; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Session; using MediaBrowser.Model.Plugins; using MediaBrowser.Model.Serialization; +using MediaBrowser.Model.Session; using Microsoft.Extensions.Logging; namespace Jellyfin.Plugin.TubeArchivistMetadata @@ -24,7 +29,9 @@ namespace Jellyfin.Plugin.TubeArchivistMetadata /// Instance of the interface. /// Instance of the interface. /// Instance of the interface. - public Plugin(IApplicationPaths applicationPaths, IXmlSerializer xmlSerializer, ILogger logger) + /// Instance of the interface. + /// Instance of the interface. + public Plugin(IApplicationPaths applicationPaths, IXmlSerializer xmlSerializer, ILogger logger, ISessionManager sessionManager, ILibraryManager libraryManager) : base(applicationPaths, xmlSerializer) { Instance = this; @@ -34,6 +41,9 @@ namespace Jellyfin.Plugin.TubeArchivistMetadata handler.CheckCertificateRevocationList = true; HttpClient = new HttpClient(handler); HttpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Token", Instance?.Configuration.TubeArchivistApiKey); + SessionManager = sessionManager; + sessionManager.PlaybackProgress += OnPlaybackProgress; + LibraryManager = libraryManager; logger.LogInformation("{Message}", "Collection display name: " + Instance?.Configuration.CollectionTitle); logger.LogInformation("{Message}", "TubeArchivist API URL: " + Instance?.Configuration.TubeArchivistUrl); logger.LogInformation("{Message}", "Pinging TubeArchivist API..."); @@ -60,6 +70,16 @@ namespace Jellyfin.Plugin.TubeArchivistMetadata /// public HttpClient HttpClient { get; } + /// + /// Gets the SessionManager used globally by the plugin. + /// + public ISessionManager SessionManager { get; } + + /// + /// Gets the LibraryManager used globally by the plugin. + /// + public ILibraryManager LibraryManager { get; } + /// public IEnumerable GetPages() => new[] { @@ -92,5 +112,20 @@ namespace Jellyfin.Plugin.TubeArchivistMetadata }, TaskScheduler.Default); } + + private async void OnPlaybackProgress(object? sender, PlaybackProgressEventArgs eventArgs) + { + BaseItem? channel = LibraryManager.GetItemById(eventArgs.Item.ParentId); + BaseItem? collection = LibraryManager.GetItemById(channel!.ParentId); + if (collection?.Name.ToLower(CultureInfo.CurrentCulture) == Instance?.Configuration.CollectionTitle.ToLower(CultureInfo.CurrentCulture) && eventArgs.PlaybackPositionTicks != null) + { + long progress = (long)eventArgs.PlaybackPositionTicks / TimeSpan.TicksPerSecond; + var statusCode = await TubeArchivistApi.GetInstance().SetProgress(Utils.GetVideoNameFromPath(eventArgs.Item.Path), progress).ConfigureAwait(true); + if (statusCode != System.Net.HttpStatusCode.OK) + { + Logger.LogInformation("{Message}", $"POST /progress returned {statusCode} for video {eventArgs.Item.Name} with progress {progress} seconds"); + } + } + } } } diff --git a/Jellyfin.Plugin.TubeArchivistMetadata/TubeArchivist/TubeArchivistApi.cs b/Jellyfin.Plugin.TubeArchivistMetadata/TubeArchivist/TubeArchivistApi.cs index 53adfbb..ce7565e 100644 --- a/Jellyfin.Plugin.TubeArchivistMetadata/TubeArchivist/TubeArchivistApi.cs +++ b/Jellyfin.Plugin.TubeArchivistMetadata/TubeArchivist/TubeArchivistApi.cs @@ -2,6 +2,7 @@ using System; using System.Data; using System.Net; using System.Net.Http; +using System.Text; using System.Threading.Tasks; using Jellyfin.Plugin.TubeArchivistMetadata.Utilities; using Microsoft.Extensions.Logging; @@ -146,5 +147,28 @@ namespace Jellyfin.Plugin.TubeArchivistMetadata.TubeArchivist return pong; } + + /// + /// Send video playback progress to TubeArchivist. + /// + /// Video id. + /// Progress in seconds. + /// Nothing if successful. + /// Throws this exception if the request was not successful. + public async Task SetProgress(string videoId, long progress) + { + var progressEndpoint = $"/api/video/{videoId}/progress/"; + var url = new Uri(Utils.SanitizeUrl(Plugin.Instance!.Configuration.TubeArchivistUrl + progressEndpoint)); + var body = JsonConvert.SerializeObject(new + { + position = progress + }); + + var sc = new StringContent(body, Encoding.UTF8, "application/json"); + + var response = await client.PostAsync(url, new StringContent(body, Encoding.UTF8, "application/json")).ConfigureAwait(true); + + return response.StatusCode; + } } }