Merge pull request #51 from wolffshots/master
Episodes by YYYYMMDD and some other cleanup
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
namespace Jellyfin.Plugin.TubeArchivistMetadata.Configuration;
|
||||
|
||||
/// <summary>
|
||||
/// The NumberingScheme.
|
||||
/// </summary>
|
||||
public enum NumberingScheme
|
||||
{
|
||||
/// <summary>
|
||||
/// Default (no numbering).
|
||||
/// </summary>
|
||||
Default,
|
||||
|
||||
/// <summary>
|
||||
/// YYYYMMDD (e.g. 20250804 for August 4th, 2025).
|
||||
/// </summary>
|
||||
YYYYMMDD,
|
||||
}
|
||||
@@ -186,6 +186,11 @@ namespace Jellyfin.Plugin.TubeArchivistMetadata.Configuration
|
||||
/// </summary>
|
||||
public int TAJFPlaylistsSyncTaskInterval { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the preferred numbering scheme for episodes (index number) in Jellyfin.
|
||||
/// </summary>
|
||||
public NumberingScheme EpisodeNumberingScheme { get; set; } = NumberingScheme.Default;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the playback progress owners Jellyfin usernames to synchronize data from TubeArchivist.
|
||||
/// </summary>
|
||||
|
||||
@@ -41,6 +41,18 @@
|
||||
<div class="fieldDescription">This is the maximum length of the descriptions showed in series
|
||||
and episodes</div>
|
||||
</div>
|
||||
<div class="selectContainer">
|
||||
<label class="selectLabel" for="EpisodeNumberingScheme">Episode numbering scheme</label>
|
||||
<select is="emby-select" id="EpisodeNumberingScheme" name="EpisodeNumberingScheme" label="Description markup" class="emby-select-withcolor emby-select">
|
||||
<option value="Default">Default (no specified numbering)</option>
|
||||
<option value="YYYYMMDD">YYYYMMDD (e.g. 20250804 for August 4th, 2025)</option>
|
||||
</select>
|
||||
<div class="selectArrowContainer">
|
||||
<span class="selectArrow material-icons keyboard_arrow_down" aria-hidden="true"></span>
|
||||
</div>
|
||||
<div class="fieldDescription">This is the numbering scheme for episodes in Jellyfin (IndexNumber).
|
||||
Default is the same as no numbering which allows Jellyfin to use the fallback numbering scheme.
|
||||
</div>
|
||||
<div>
|
||||
<h2>Synchronization</h2>
|
||||
</div>
|
||||
@@ -160,6 +172,7 @@
|
||||
document.querySelector('#JFTAPlaylistsSync').checked = config.JFTAPlaylistsSync;
|
||||
document.querySelector('#TAJFPlaylistsSync').checked = config.TAJFPlaylistsSync;
|
||||
document.querySelector('#JFUsernameFrom').value = config.JFUsernameFrom;
|
||||
document.querySelector('#EpisodeNumberingScheme').value = config.EpisodeNumberingScheme;
|
||||
document.querySelector('#TAJFProgressTaskInterval').value = config.TAJFProgressTaskInterval;
|
||||
document.querySelector('#JFTAPlaylistsSyncTaskInterval').value = config.JFTAPlaylistsSyncTaskInterval;
|
||||
document.querySelector('#TAJFPlaylistsSyncTaskInterval').value = config.TAJFPlaylistsSyncTaskInterval;
|
||||
@@ -181,6 +194,7 @@
|
||||
config.JFTAPlaylistsSync = document.querySelector('#JFTAPlaylistsSync').checked;
|
||||
config.TAJFPlaylistsSync = document.querySelector('#TAJFPlaylistsSync').checked;
|
||||
config.JFUsernameFrom = document.querySelector('#JFUsernameFrom').value;
|
||||
config.EpisodeNumberingScheme = document.querySelector('#EpisodeNumberingScheme').value;
|
||||
config.TAJFProgressTaskInterval = document.querySelector('#TAJFProgressTaskInterval').value;
|
||||
config.JFTAPlaylistsSyncTaskInterval = document.querySelector('#JFTAPlaylistsSyncTaskInterval').value;
|
||||
config.TAJFPlaylistsSyncTaskInterval = document.querySelector('#TAJFPlaylistsSyncTaskInterval').value;
|
||||
|
||||
@@ -162,20 +162,20 @@ namespace Jellyfin.Plugin.TubeArchivistMetadata
|
||||
return;
|
||||
}
|
||||
|
||||
if (Instance!.Configuration.JFTAProgressSync && eventArgs.Users.Any(u => Instance!.Configuration.JFUsernameFrom.Equals(u.Username, StringComparison.Ordinal)))
|
||||
var topParent = eventArgs.Item.GetTopParent();
|
||||
if (
|
||||
Instance!.Configuration.JFTAProgressSync &&
|
||||
eventArgs.Users.Any(u => Instance!.Configuration.JFUsernameFrom.Equals(u.Username, StringComparison.Ordinal)) &&
|
||||
eventArgs.PlaybackPositionTicks.HasValue &&
|
||||
string.Equals(topParent?.Name, Instance?.Configuration.CollectionTitle, StringComparison.OrdinalIgnoreCase)
|
||||
)
|
||||
{
|
||||
BaseItem? season = LibraryManager.GetItemById(eventArgs.Item.ParentId);
|
||||
BaseItem? channel = LibraryManager.GetItemById(season!.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 videoId = Utils.GetVideoNameFromPath(eventArgs.Item.Path);
|
||||
var statusCode = await TubeArchivistApi.GetInstance().SetProgress(videoId, progress).ConfigureAwait(true);
|
||||
if (statusCode != System.Net.HttpStatusCode.OK)
|
||||
{
|
||||
long progress = (long)eventArgs.PlaybackPositionTicks / TimeSpan.TicksPerSecond;
|
||||
var videoId = Utils.GetVideoNameFromPath(eventArgs.Item.Path);
|
||||
var statusCode = await TubeArchivistApi.GetInstance().SetProgress(videoId, progress).ConfigureAwait(true);
|
||||
if (statusCode != System.Net.HttpStatusCode.OK)
|
||||
{
|
||||
Logger.LogCritical("{Message}", $"POST /video/{videoId}/progress returned {statusCode} for video {eventArgs.Item.Name} with progress {progress} seconds");
|
||||
}
|
||||
Logger.LogCritical("{Message}", $"POST /video/{videoId}/progress returned {statusCode} for video {eventArgs.Item.Name} with progress {progress} seconds");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -188,16 +188,22 @@ namespace Jellyfin.Plugin.TubeArchivistMetadata
|
||||
return;
|
||||
}
|
||||
|
||||
var topParent = eventArgs.Item.GetTopParent();
|
||||
var user = _userManager.GetUserById(eventArgs.UserId);
|
||||
if (user == null)
|
||||
if (
|
||||
Configuration.JFTAProgressSync &&
|
||||
user != null &&
|
||||
Configuration.GetJFUsernamesToArray().Contains(user!.Username) &&
|
||||
string.Equals(topParent?.Name, Instance?.Configuration.CollectionTitle, StringComparison.OrdinalIgnoreCase)
|
||||
)
|
||||
{
|
||||
Logger.LogError("OnWatchedStatusChange callback called without user id for item {ItemName}", eventArgs.Item.Name);
|
||||
return;
|
||||
}
|
||||
|
||||
var userItemData = _userDataManager.GetUserData(user, eventArgs.Item);
|
||||
if (Configuration.JFTAProgressSync && user != null && Configuration.GetJFUsernamesToArray().Contains(user!.Username))
|
||||
{
|
||||
var userItemData = _userDataManager.GetUserData(user, eventArgs.Item);
|
||||
var isPlayed = eventArgs.Item.IsPlayed(user, userItemData);
|
||||
Logger.LogDebug("User {UserId} changed watched status to {Status} for the item {ItemName}", eventArgs.UserId, isPlayed, eventArgs.Item.Name);
|
||||
string itemYTId;
|
||||
|
||||
@@ -67,6 +67,7 @@ namespace Jellyfin.Plugin.TubeArchivistMetadata.Providers
|
||||
});
|
||||
result.HasMetadata = true;
|
||||
result.Item = video.ToEpisode();
|
||||
result.Item.Path = info.Path;
|
||||
result.Provider = Name;
|
||||
result.People = peopleInfo;
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ namespace Jellyfin.Plugin.TubeArchivistMetadata.Tasks
|
||||
foreach (Episode video in videos)
|
||||
{
|
||||
var videoYTId = Utils.GetVideoNameFromPath(video.Path);
|
||||
_logger.LogDebug("{VideoYtId}", videoYTId);
|
||||
_logger.LogDebug("Current video extracted YouTube id: {VideoYtId}", videoYTId);
|
||||
HttpStatusCode statusCode;
|
||||
var userItemData = _userDataManager.GetUserData(user, channel);
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Jellyfin.Plugin.TubeArchivistMetadata.Configuration;
|
||||
using Jellyfin.Plugin.TubeArchivistMetadata.Utilities;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
@@ -126,6 +127,11 @@ namespace Jellyfin.Plugin.TubeArchivistMetadata.TubeArchivist
|
||||
Overview = Utils.FormatDescription(Description),
|
||||
SeasonName = Published.Year.ToString(CultureInfo.CurrentCulture),
|
||||
ParentIndexNumber = Published.Year,
|
||||
IndexNumber = Plugin.Instance?.Configuration?.EpisodeNumberingScheme switch
|
||||
{
|
||||
NumberingScheme.YYYYMMDD => (Published.Year * 10000) + (Published.Month * 100) + Published.Day,
|
||||
_ => null
|
||||
},
|
||||
SeriesName = Channel.Name,
|
||||
ProductionYear = Published.Year,
|
||||
PremiereDate = Published,
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Jellyfin.Plugin.TubeArchivistMetadata.Utilities
|
||||
{
|
||||
@@ -45,6 +47,11 @@ namespace Jellyfin.Plugin.TubeArchivistMetadata.Utilities
|
||||
/// <returns>A string with \n replaced by br tags.</returns>
|
||||
public static string FormatDescription(string description)
|
||||
{
|
||||
if (description == null)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
var maxLength = 500;
|
||||
if (Plugin.Instance != null)
|
||||
{
|
||||
@@ -54,9 +61,10 @@ namespace Jellyfin.Plugin.TubeArchivistMetadata.Utilities
|
||||
if (description.Length > maxLength)
|
||||
{
|
||||
description = description.Substring(0, maxLength);
|
||||
description = description.Replace("\n", "<br>", System.StringComparison.CurrentCulture);
|
||||
}
|
||||
|
||||
description = description.Replace("\n", "<br>", System.StringComparison.CurrentCulture);
|
||||
|
||||
return description;
|
||||
}
|
||||
|
||||
|
||||
@@ -114,6 +114,16 @@ Keep in mind that Jellyfin lowest accepted period is of 1 minute (60 seconds) an
|
||||
|
||||

|
||||
|
||||
## Episode numbering
|
||||
|
||||
<p>There are different ways to number the episodes as they are configured in Jellyfin.<br>
|
||||
This changes the number after E in S--E-- (for example S2024E100 for episode number 100 of season 2024).</p>
|
||||
|
||||

|
||||
|
||||
The options correlate with:
|
||||
- Default - leave the numbering to what Jellyfin does by default (this is what the plugin has always done)
|
||||
- YYYYMMDD - numbers the episode by the year, month, day (e.g. 20250804 for a video published on the 4th of August 2025)
|
||||
|
||||
## Build
|
||||
|
||||
|
||||
Reference in New Issue
Block a user