Add nightly job
This commit is contained in:
@@ -20,7 +20,6 @@ namespace Jellyfin.Plugin.SRFPlay.Api;
|
||||
/// </summary>
|
||||
public class SRFApiClient : IDisposable
|
||||
{
|
||||
private static readonly System.Text.CompositeFormat PlayV3UrlFormat = System.Text.CompositeFormat.Parse(ApiEndpoints.PlayV3BaseUrlTemplate);
|
||||
private readonly HttpClient _httpClient;
|
||||
private readonly HttpClient _playV3HttpClient;
|
||||
private readonly ILogger _logger;
|
||||
@@ -58,6 +57,21 @@ public class SRFApiClient : IDisposable
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Builds the Play v3 API base URL for a business unit. The host is normally
|
||||
/// www.<unit>.ch, but SWI's site lives at www.swissinfo.ch (www.swi.ch is an
|
||||
/// unrelated welding institute), while the API path segment stays the unit code.
|
||||
/// </summary>
|
||||
/// <param name="businessUnit">The lowercase business unit (e.g. "srf", "swi").</param>
|
||||
/// <returns>The Play v3 production base URL ending in a slash.</returns>
|
||||
private static string BuildPlayV3BaseUrl(string businessUnit)
|
||||
{
|
||||
var host = string.Equals(businessUnit, "swi", StringComparison.OrdinalIgnoreCase)
|
||||
? "www.swissinfo.ch"
|
||||
: $"www.{businessUnit}.ch";
|
||||
return $"https://{host}/play/v3/api/{businessUnit}/production/";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads HTTP response content as UTF-8 string.
|
||||
/// </summary>
|
||||
@@ -315,7 +329,7 @@ public class SRFApiClient : IDisposable
|
||||
{
|
||||
try
|
||||
{
|
||||
var baseUrl = string.Format(CultureInfo.InvariantCulture, PlayV3UrlFormat, businessUnit);
|
||||
var baseUrl = BuildPlayV3BaseUrl(businessUnit);
|
||||
var url = $"{baseUrl}{endpoint}";
|
||||
_logger.LogInformation("Fetching all {Endpoint} for business unit: {BusinessUnit} from URL: {Url}", endpoint, businessUnit, url);
|
||||
|
||||
@@ -352,7 +366,7 @@ public class SRFApiClient : IDisposable
|
||||
{
|
||||
try
|
||||
{
|
||||
var baseUrl = string.Format(CultureInfo.InvariantCulture, PlayV3UrlFormat, businessUnit);
|
||||
var baseUrl = BuildPlayV3BaseUrl(businessUnit);
|
||||
var url = $"{baseUrl}videos-by-show-id?showId={showId}";
|
||||
_logger.LogDebug("Fetching videos for show {ShowId} from business unit: {BusinessUnit}", showId, businessUnit);
|
||||
|
||||
@@ -392,7 +406,7 @@ public class SRFApiClient : IDisposable
|
||||
{
|
||||
try
|
||||
{
|
||||
var baseUrl = string.Format(CultureInfo.InvariantCulture, PlayV3UrlFormat, businessUnit);
|
||||
var baseUrl = BuildPlayV3BaseUrl(businessUnit);
|
||||
var url = $"{baseUrl}livestreams?eventType={eventType.ToUpperInvariant()}";
|
||||
_logger.LogInformation("Fetching scheduled livestreams for eventType={EventType} from business unit: {BusinessUnit}", eventType, businessUnit);
|
||||
|
||||
|
||||
@@ -175,21 +175,8 @@ public abstract class SrgChannelBase : IChannel, IHasCacheKey
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsUnitEnabled()
|
||||
{
|
||||
var config = Plugin.Instance?.Configuration;
|
||||
return config == null || config.ResolveEnabledUnits().Contains(Unit);
|
||||
}
|
||||
|
||||
private async Task<List<ChannelItemInfo>> GetFolderItemsAsync(string? folderId, CancellationToken cancellationToken)
|
||||
{
|
||||
// If this unit is not enabled in configuration, show nothing (empty tile).
|
||||
if (!IsUnitEnabled())
|
||||
{
|
||||
_logger.LogDebug("Business unit {Unit} is not enabled - returning no items", Unit);
|
||||
return new List<ChannelItemInfo>();
|
||||
}
|
||||
|
||||
// Root level - show folder list
|
||||
if (string.IsNullOrEmpty(folderId))
|
||||
{
|
||||
|
||||
@@ -66,7 +66,6 @@ public class PluginConfiguration : BasePluginConfiguration
|
||||
{
|
||||
// Set default options
|
||||
BusinessUnit = BusinessUnit.SRF;
|
||||
EnabledBusinessUnits = new System.Collections.Generic.List<BusinessUnit> { BusinessUnit.SRF };
|
||||
QualityPreference = QualityPreference.Auto;
|
||||
ContentRefreshIntervalHours = 6;
|
||||
ExpirationCheckIntervalHours = 24;
|
||||
@@ -79,20 +78,11 @@ public class PluginConfiguration : BasePluginConfiguration
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the legacy single business unit. Retained for backwards compatibility and
|
||||
/// migration into <see cref="EnabledBusinessUnits"/>; new code should use the list instead.
|
||||
/// Gets or sets the legacy single business unit. Retained only for backwards compatibility
|
||||
/// with older configs; every unit now has its own always-on channel.
|
||||
/// </summary>
|
||||
public BusinessUnit BusinessUnit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the list of business units to expose as channels. One channel tile is shown
|
||||
/// per enabled unit, so polylingual households can browse e.g. SRF (German) and RTS (French)
|
||||
/// at the same time.
|
||||
/// </summary>
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2227:Collection properties should be read only", Justification = "Required for configuration serialization")]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1002:Do not expose generic lists", Justification = "Configuration DTO")]
|
||||
public System.Collections.Generic.List<BusinessUnit> EnabledBusinessUnits { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the preferred video quality.
|
||||
/// </summary>
|
||||
@@ -172,20 +162,4 @@ public class PluginConfiguration : BasePluginConfiguration
|
||||
/// Gets or sets the output directory for sport livestream recordings.
|
||||
/// </summary>
|
||||
public string RecordingOutputPath { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Resolves the effective set of enabled business units, migrating from the legacy single
|
||||
/// <see cref="BusinessUnit"/> value when the list has not been populated yet.
|
||||
/// </summary>
|
||||
/// <returns>The business units that should have channels.</returns>
|
||||
public System.Collections.Generic.IReadOnlyList<BusinessUnit> ResolveEnabledUnits()
|
||||
{
|
||||
if (EnabledBusinessUnits != null && EnabledBusinessUnits.Count > 0)
|
||||
{
|
||||
return EnabledBusinessUnits;
|
||||
}
|
||||
|
||||
// Legacy installs only had a single BusinessUnit; honour it so they keep working.
|
||||
return new System.Collections.Generic.List<BusinessUnit> { BusinessUnit };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,28 +3,8 @@
|
||||
<div class="content-primary">
|
||||
<form id="SRFPlayConfigForm">
|
||||
<div class="checkboxContainer checkboxContainer-withDescription">
|
||||
<h3>Channels (Business Units)</h3>
|
||||
<div class="fieldDescription" style="margin-bottom: 0.5em;">Enable a channel tile for each Swiss broadcaster you want. A separate tile appears per enabled unit, so polylingual households can browse e.g. SRF (German) and RTS (French) at the same time.</div>
|
||||
<label class="emby-checkbox-label">
|
||||
<input id="buSRF" type="checkbox" is="emby-checkbox" data-bu="SRF" />
|
||||
<span>SRF — Schweizer Radio und Fernsehen (German)</span>
|
||||
</label>
|
||||
<label class="emby-checkbox-label">
|
||||
<input id="buRTS" type="checkbox" is="emby-checkbox" data-bu="RTS" />
|
||||
<span>RTS — Radio Télévision Suisse (French)</span>
|
||||
</label>
|
||||
<label class="emby-checkbox-label">
|
||||
<input id="buRSI" type="checkbox" is="emby-checkbox" data-bu="RSI" />
|
||||
<span>RSI — Radiotelevisione svizzera (Italian)</span>
|
||||
</label>
|
||||
<label class="emby-checkbox-label">
|
||||
<input id="buRTR" type="checkbox" is="emby-checkbox" data-bu="RTR" />
|
||||
<span>RTR — Radiotelevisiun Svizra Rumantscha (Romansh)</span>
|
||||
</label>
|
||||
<label class="emby-checkbox-label">
|
||||
<input id="buSWI" type="checkbox" is="emby-checkbox" data-bu="SWI" />
|
||||
<span>SWI — swissinfo.ch (International)</span>
|
||||
</label>
|
||||
<h3>Channels</h3>
|
||||
<div class="fieldDescription">Every Swiss broadcaster has its own channel tile: SRF (German), RTS (French), RSI (Italian), RTR (Romansh) and SWI (swissinfo.ch). They are always available — pin the ones you use from the Jellyfin home screen.</div>
|
||||
</div>
|
||||
<div class="selectContainer">
|
||||
<label class="selectLabel" for="QualityPreference">Quality Preference</label>
|
||||
@@ -155,12 +135,6 @@
|
||||
.addEventListener('pageshow', function() {
|
||||
Dashboard.showLoadingMsg();
|
||||
ApiClient.getPluginConfiguration(SRFPlayConfig.pluginUniqueId).then(function (config) {
|
||||
var enabled = (config.EnabledBusinessUnits && config.EnabledBusinessUnits.length)
|
||||
? config.EnabledBusinessUnits
|
||||
: [config.BusinessUnit]; // migrate legacy single value
|
||||
['SRF','RTS','RSI','RTR','SWI'].forEach(function(bu) {
|
||||
document.querySelector('#bu' + bu).checked = enabled.indexOf(bu) !== -1;
|
||||
});
|
||||
document.querySelector('#QualityPreference').value = config.QualityPreference;
|
||||
document.querySelector('#ContentRefreshIntervalHours').value = config.ContentRefreshIntervalHours;
|
||||
document.querySelector('#ExpirationCheckIntervalHours').value = config.ExpirationCheckIntervalHours;
|
||||
@@ -186,11 +160,6 @@
|
||||
.addEventListener('submit', function(e) {
|
||||
Dashboard.showLoadingMsg();
|
||||
ApiClient.getPluginConfiguration(SRFPlayConfig.pluginUniqueId).then(function (config) {
|
||||
config.EnabledBusinessUnits = ['SRF','RTS','RSI','RTR','SWI'].filter(function(bu) {
|
||||
return document.querySelector('#bu' + bu).checked;
|
||||
});
|
||||
// Keep legacy field in sync with the first enabled unit for backwards compat.
|
||||
config.BusinessUnit = config.EnabledBusinessUnits[0] || 'SRF';
|
||||
config.QualityPreference = document.querySelector('#QualityPreference').value;
|
||||
config.ContentRefreshIntervalHours = parseInt(document.querySelector('#ContentRefreshIntervalHours').value);
|
||||
config.ExpirationCheckIntervalHours = parseInt(document.querySelector('#ExpirationCheckIntervalHours').value);
|
||||
|
||||
@@ -64,8 +64,8 @@ public class ContentRefreshTask : IScheduledTask
|
||||
return;
|
||||
}
|
||||
|
||||
// Refresh content for every enabled business unit (one channel per unit).
|
||||
var units = config.ResolveEnabledUnits();
|
||||
// Refresh content for every business unit (one channel per unit).
|
||||
var units = System.Enum.GetValues<Configuration.BusinessUnit>();
|
||||
foreach (var unit in units)
|
||||
{
|
||||
var businessUnit = unit.ToLowerString();
|
||||
|
||||
@@ -147,13 +147,12 @@ public class RecordingService : IRecordingService, IDisposable
|
||||
/// <inheritdoc />
|
||||
public async Task<IReadOnlyList<PlayV3TvProgram>> GetUpcomingScheduleAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
var config = Plugin.Instance?.Configuration;
|
||||
var units = config?.ResolveEnabledUnits() ?? new[] { Configuration.BusinessUnit.SRF };
|
||||
var units = System.Enum.GetValues<Configuration.BusinessUnit>();
|
||||
|
||||
using var apiClient = _apiClientFactory.CreateClient();
|
||||
|
||||
// Aggregate sport livestreams across every enabled business unit so the recordings
|
||||
// page shows events from all enabled languages.
|
||||
// Aggregate sport livestreams across every business unit so the recordings
|
||||
// page shows events from all languages.
|
||||
var all = new List<PlayV3TvProgram>();
|
||||
foreach (var unit in units)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user