19 Commits
v0.1.1 ... main

Author SHA1 Message Date
Gitea Actions
7aadb40c82 chore: update manifest for v0.1.4
All checks were successful
Create Release PR / Create Release PR (push) Successful in 4s
2026-04-07 06:40:42 +00:00
Gitea Actions
48e347f5c7 docs: update changelog for v0.1.4
Some checks failed
Create Release PR / Create Release PR (push) Has been cancelled
Build and Publish Plugin / Build Plugin + Update Manifest (release) Successful in 44s
2026-04-07 06:39:55 +00:00
76161230e1 Merge pull request 'chore(main): release 0.1.4' (#27) from release-please--branches--main into main
Some checks failed
Create Release PR / Create Release PR (push) Has been cancelled
Reviewed-on: #27
2026-04-07 08:39:49 +02:00
Gitea Actions
205cbd91af chore(main): release 0.1.4
All checks were successful
Create Release / Publish Release (pull_request) Successful in 9s
2026-04-07 06:38:44 +00:00
a71ced086a Merge branch 'main' of https://git.tdpi.dev/TDPI/jellyfin-plugin-smartnotify
All checks were successful
Create Release PR / Create Release PR (push) Successful in 19s
2026-04-07 08:38:20 +02:00
85fd002f4e fix: slow start of jellyfin 2026-04-07 08:38:18 +02:00
Gitea Actions
f9aacf2436 chore: update manifest for v0.1.3
All checks were successful
Create Release PR / Create Release PR (push) Successful in 4s
2026-04-05 16:13:21 +00:00
Gitea Actions
caee267f8b docs: update changelog for v0.1.3
Some checks failed
Create Release PR / Create Release PR (push) Has been cancelled
Build and Publish Plugin / Build Plugin + Update Manifest (release) Successful in 1m1s
2026-04-05 16:12:18 +00:00
5a60a6f5b4 Merge pull request 'chore(main): release 0.1.3' (#26) from release-please--branches--main into main
Some checks failed
Create Release PR / Create Release PR (push) Has been cancelled
Reviewed-on: #26
2026-04-05 18:12:06 +02:00
Gitea Actions
133c00fab0 chore(main): release 0.1.3
All checks were successful
Create Release / Publish Release (pull_request) Successful in 15s
2026-04-05 15:22:58 +00:00
0bafe691a0 Merge branch 'main' of https://git.tdpi.dev/TDPI/jellyfin-plugin-smartnotify
All checks were successful
Create Release PR / Create Release PR (push) Successful in 16s
2026-04-05 17:22:37 +02:00
82b34e288c fix: stop fodler name as names 2026-04-05 17:22:35 +02:00
Gitea Actions
8c77f82d2c chore: update manifest for v0.1.2
All checks were successful
Create Release PR / Create Release PR (push) Successful in 4s
2026-04-04 09:39:49 +00:00
Gitea Actions
cb0dfe2c21 docs: update changelog for v0.1.2
Some checks failed
Create Release PR / Create Release PR (push) Has been cancelled
Build and Publish Plugin / Build Plugin + Update Manifest (release) Successful in 44s
2026-04-04 09:39:03 +00:00
eaf6ea91e1 Merge pull request 'chore(main): release 0.1.2' (#25) from release-please--branches--main into main
Some checks failed
Create Release PR / Create Release PR (push) Has been cancelled
Reviewed-on: #25
2026-04-04 11:38:56 +02:00
Gitea Actions
180a998be1 chore(main): release 0.1.2
All checks were successful
Create Release / Publish Release (pull_request) Successful in 9s
2026-04-04 09:36:28 +00:00
6fd2638414 Merge branch 'main' of https://git.tdpi.dev/TDPI/jellyfin-plugin-smartnotify
All checks were successful
Create Release PR / Create Release PR (push) Successful in 19s
2026-04-04 11:36:02 +02:00
0e10e3c089 fix: refresh series name before notification 2026-04-04 11:35:59 +02:00
Gitea Actions
e729c7b8d5 chore: update manifest for v0.1.1
All checks were successful
Create Release PR / Create Release PR (push) Successful in 4s
2026-04-03 17:32:41 +00:00
5 changed files with 124 additions and 16 deletions

View File

@@ -1,3 +1,3 @@
{
".": "0.1.1"
".": "0.1.4"
}

View File

@@ -1,5 +1,28 @@
# Changelog
## 0.1.4 (2026-04-07)
## 0.1.4 (2026-04-07)
### Bug Fixes
Langsamer Start von Jellyfin wegen Überprüfung bestehender Einträge.
Läuft nun asynchron.
## 0.1.3 (2026-04-05)
## 0.1.3 (2026-04-05)
### Bug Fixes
Gebe keine Notification wenn der Name der Serie tmdbid oder ähnliches enthält.
Dies verhindert das die Notification kommt wenn noch nicht die Metadaten gezogen wurden.
## 0.1.2 (2026-04-04)
## 0.1.2 (2026-04-04)
### Bug Fixes
* Problem behoben das der Serienname vor der Benachrichtigung nicht aktualisiert wurde.
## 0.1.1 (2026-04-03)
## 0.1.1 (2026-04-03)

View File

@@ -3,8 +3,8 @@
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<RootNamespace>Jellyfin.Plugin.SmartNotify</RootNamespace>
<AssemblyVersion>0.1.1.0</AssemblyVersion>
<FileVersion>0.1.1.0</FileVersion>
<AssemblyVersion>0.1.4.0</AssemblyVersion>
<FileVersion>0.1.4.0</FileVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<GenerateDocumentationFile>true</GenerateDocumentationFile>

View File

@@ -1,6 +1,7 @@
using System;
using System.Linq;
using System.Text.Json;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
@@ -49,11 +50,7 @@ public class SmartNotifyBackgroundService : IHostedService, IDisposable
{
_logger.LogInformation("SmartNotify background service starting");
// Pre-populate DB with all existing library items so they're recognized as "known".
// This prevents mass notifications on first run or after DB reset.
SeedExistingLibraryItems();
// Subscribe to library events
// Subscribe to library events (before seeding so we don't miss items added during seed).
_libraryManager.ItemAdded += OnItemAdded;
_libraryManager.ItemRemoved += OnItemRemoved;
@@ -63,6 +60,10 @@ public class SmartNotifyBackgroundService : IHostedService, IDisposable
_processTimer.AutoReset = true;
_processTimer.Start();
// Pre-populate DB with existing library items in the background
// so we don't block Jellyfin startup.
_ = Task.Run(() => SeedExistingLibraryItems(), cancellationToken);
_logger.LogInformation("SmartNotify is now monitoring library changes");
return Task.CompletedTask;
@@ -318,10 +319,11 @@ public class SmartNotifyBackgroundService : IHostedService, IDisposable
if (item is Episode episode)
{
// episode.SeriesName / SeriesId are often null with Shokofin VFS,
// but the Series navigation property usually works
var seriesObj = episode.Series;
notification.SeriesName = episode.SeriesName ?? seriesObj?.Name;
var rawSeriesName = episode.SeriesName ?? seriesObj?.Name;
// If the name still looks like a Sonarr folder name, leave it null
// so the incomplete-episode logic defers until metadata scrape is done.
notification.SeriesName = LooksLikeFolderName(rawSeriesName) ? null : rawSeriesName;
notification.SeriesId = (episode.SeriesId != Guid.Empty
? episode.SeriesId
: seriesObj?.Id ?? Guid.Empty).ToString();
@@ -430,12 +432,39 @@ public class SmartNotifyBackgroundService : IHostedService, IDisposable
var changed = false;
if (string.IsNullOrEmpty(notification.SeriesName) || notification.SeriesName == "Unknown Series")
// Refresh SeriesName from the library. At queue time the name is often
// the Sonarr folder name (e.g. "Chained Soldier (2024) [tmdbid-139060]").
// After Jellyfin's metadata scrape completes, the name changes to the
// correct provider name (e.g. "Demon Slave - The Chained Soldier").
// We detect the unscraped folder name by checking for bracket patterns
// like [tmdbid-...] or (2024) and clear the SeriesName so the
// incomplete-episode logic defers sending until the scrape is done.
{
// episode.SeriesName is often null (especially with Shokofin VFS),
// but the Series navigation property usually has the correct name
notification.SeriesName = episode.SeriesName ?? episode.Series?.Name;
changed = true;
var freshSeriesName = episode.SeriesName ?? episode.Series?.Name;
if (!string.IsNullOrEmpty(freshSeriesName))
{
if (LooksLikeFolderName(freshSeriesName))
{
// Still the Sonarr folder name — clear so we keep waiting
if (!string.IsNullOrEmpty(notification.SeriesName))
{
_logger.LogInformation(
"[DEBUG Refresh] SeriesName '{Name}' looks like a folder name, clearing to defer",
freshSeriesName);
notification.SeriesName = null;
changed = true;
}
}
else if (freshSeriesName != notification.SeriesName)
{
_logger.LogInformation(
"[DEBUG Refresh] SeriesName changed: '{Old}' -> '{New}'",
notification.SeriesName,
freshSeriesName);
notification.SeriesName = freshSeriesName;
changed = true;
}
}
}
if (string.IsNullOrEmpty(notification.SeriesId) || notification.SeriesId == Guid.Empty.ToString())
@@ -464,6 +493,17 @@ public class SmartNotifyBackgroundService : IHostedService, IDisposable
changed = true;
}
// Always refresh the item name — it may have been a placeholder at queue time
if (!string.IsNullOrEmpty(episode.Name) && episode.Name != notification.Name)
{
_logger.LogInformation(
"[DEBUG Refresh] Name changed: '{Old}' -> '{New}'",
notification.Name,
episode.Name);
notification.Name = episode.Name;
changed = true;
}
// Refresh image if missing
if (string.IsNullOrEmpty(notification.ImagePath) && episode.SeriesId != Guid.Empty)
{
@@ -687,6 +727,19 @@ public class SmartNotifyBackgroundService : IHostedService, IDisposable
}
}
/// <summary>
/// Detects Sonarr-style folder names that haven't been replaced by a metadata scrape yet.
/// Matches patterns like "[tmdbid-139060]", "[tvdbid-412656]", "[imdbid-tt1234]".
/// </summary>
private static readonly Regex FolderNamePattern = new(
@"\[(tmdbid|tvdbid|imdbid)-[^\]]+\]",
RegexOptions.IgnoreCase | RegexOptions.Compiled);
private static bool LooksLikeFolderName(string? name)
{
return !string.IsNullOrEmpty(name) && FolderNamePattern.IsMatch(name);
}
/// <inheritdoc />
public void Dispose()
{

View File

@@ -8,6 +8,38 @@
"category": "Notifications",
"imageUrl": "",
"versions": [
{
"version": "0.1.4.0",
"changelog": "## 0.1.4 (2026-04-07)\n\n### Bug Fixes\n\nLangsamer Start von Jellyfin wegen Überprüfung bestehender Einträge.\nLäuft nun asynchron.",
"targetAbi": "10.11.0.0",
"sourceUrl": "https://git.tdpi.dev/TDPI/jellyfin-plugin-smartnotify/releases/download/v0.1.4/smartnotify_0.1.4.zip",
"checksum": "6241bdf445f91732a917a8e56c956226",
"timestamp": "2026-04-07T06:40:42Z"
},
{
"version": "0.1.3.0",
"changelog": "## 0.1.3 (2026-04-05)\n\n### Bug Fixes\n\nGebe keine Notification wenn der Name der Serie tmdbid oder ähnliches enthält.\nDies verhindert das die Notification kommt wenn noch nicht die Metadaten gezogen wurden.",
"targetAbi": "10.11.0.0",
"sourceUrl": "https://git.tdpi.dev/TDPI/jellyfin-plugin-smartnotify/releases/download/v0.1.3/smartnotify_0.1.3.zip",
"checksum": "0c8a24dcfed8884f768e5b2aad5f251c",
"timestamp": "2026-04-05T16:13:21Z"
},
{
"version": "0.1.2.0",
"changelog": "## 0.1.2 (2026-04-04)\n\n### Bug Fixes\n\n* Problem behoben das der Serienname vor der Benachrichtigung nicht aktualisiert wurde.",
"targetAbi": "10.11.0.0",
"sourceUrl": "https://git.tdpi.dev/TDPI/jellyfin-plugin-smartnotify/releases/download/v0.1.2/smartnotify_0.1.2.zip",
"checksum": "56e2b0005f5bc3368c9a7f53b2f806a0",
"timestamp": "2026-04-04T09:39:49Z"
},
{
"version": "0.1.1.0",
"changelog": "## 0.1.1 (2026-04-03)\n\n### Bug Fixes\n\n* fix: unknown series\n\n### Chores\n\n* chore: workflow fix\n* chore: removed old versions\n* chore: update manifest for v0.1.0",
"targetAbi": "10.11.0.0",
"sourceUrl": "https://git.tdpi.dev/TDPI/jellyfin-plugin-smartnotify/releases/download/v0.1.1/smartnotify_0.1.1.zip",
"checksum": "459569cbae49ba569291011ac9a54202",
"timestamp": "2026-04-03T17:32:41Z"
},
{
"version": "0.1.0.0",
"changelog": "## 0.1.0 (2026-03-05)\n\n**Features**\n\nIntelligente Discord-Benachrichtigungen\n\nAutomatische Benachrichtigungen bei neuen Filmen und Episoden via Discord Webhook\nSchöne Discord-Embeds mit Thumbnail, Beschreibung und Links zu externen Datenbanken (IMDb, TMDb, AniDB, AniList, TVDB)\n\n**Smarte Episoden-Gruppierung**\n\nEpisoden werden intelligent gebündelt statt einzeln gemeldet — z.B. \"Staffel 1: Episode 1-12\" statt 12 einzelne Nachrichten\nKonfigurierbares Zeitfenster für die Gruppierung\n\n**Qualitäts-Upgrade-Erkennung**\n\nErkennt automatisch ob eine Datei neu ist oder nur ein Qualitäts-Upgrade einer bestehenden Datei\nKeine Spam-Benachrichtigungen mehr beim Ersetzen von Dateien durch bessere Versionen\nStabile Erkennung über Provider-IDs (AniDB, TMDb etc.) — funktioniert auch mit Shokofin/VFS\n\n**Robuste Metadaten-Verarbeitung**\n\nVerzögerte Verarbeitung damit Jellyfin Zeit hat Metadaten zu laden\nDreistufige Validierung: beim Hinzufügen, beim Einreihen und beim Senden\nAutomatische Unterdrückung von reorganisierten Items (Pfad-/Metadata-Änderungen)\n\n**Konfigurierbar**\n\nBenachrichtigungen für Filme und Episoden einzeln aktivierbar\nUpgrade-Unterdrückung optional\nAnpassbare Verzögerung, Gruppierungsfenster, Bot-Name und Embed-Farbe",