github ShokoAnime/Shokofin v5.0.5-dev.1
Shokofin Dev 5.0.5.1

latest releases: v6.0.5-dev.31, v6.0.5-dev.30, v6.0.5-dev.29...
pre-release10 months ago

Update your plugin using the dev manifest or by downloading the release from GitHub Releases and installing it manually!

Changes since last build:

fix: Don't assume item id and library options are available:

Don't assume the ItemId and LibraryOptions are always available on VirtualFolderInfo. They can both be null if the library failed to be parsed.

fix: Better media folder mapping logic:

Check all ≥101 (up from ≥100) locations for a match before deciding on a mapping between the media folder and import folder, instead of picking the first found match. This will help in cases where some files have multiple locations with the same file name but different relative paths.

Fixes #68

repo: Update README.md for JF 10.10 UI changes (#77).

fix: Split library check in two:

Split the library exists check and library id is valid check into two, because the library id may be null if the virtual folder is in a bad state in core Jellyfin, but the library may still exist in the UI.

fix: Check if subtitle file is a symbolic link:

When attempting to move a subtitle file, check if it's a symbolic link and abort if the link target doesn't exist, or create a copy to use if it exists but is pointing to the wrong place.

feat: Automagically move trickplay files:

Automagically move trickplay files between the VFS and the underlying library/libraries.

misc: Add logging when moving:

Added debug logging when moving subtitle files and trickplay files from the VFS to the underlying library.

cleanup: Remove unused dictionary in api manager.

fix: Ignore non-titles for episodes:

Ignore non-titles for episodes, e.g. "Episode X",Special X", "OVA", "Complete Movie", and fallback to the next title source or null if it's the last source in the list.

fix: Also ignore volumes.

fix: Move control for merge seasons setting to the correct tab.

repo: Make discord hook optional for building dev releases.

fix: Use ignore patterns during media folder search and in the ignore rule:

Use a copy of the ignore patterns taken from the Jellyfin core (since they're not exposed through the abstraction used by plugins) to ignore paths we shouldn't check in the media folder mapping check and in the ignore rule check. The latter check is redundant since the core also has such a check, but in the off-case that the shoko ignore rule is ran before the core ignore rule then we won't attempt to check the paths that would otherwise had been checked because of the run order.

fix: Check if provider is enabled for item in added/updated events before looking up ids.

fix: Also check if the provider is enabled for seasons/series and not just videos.

fix: Add extra type for 'talk show'.

cleanup: Remove unnecessary namespacing.

fix: Fix dir exists checks for trickplay directory in vfs.

fix: More robust trickplay move logic in VFS:

Some more fixes for moving the trickplay directories in the VFS because the rephrase point is treated like a file while real directories are not, so both need their own handling.

fix: Better forward season merging logic:

Added better forward merging logic for the season merging to allow the "primary" series to match the year regex. Also uglified the year regex some more.

Note: Casual reminder not to use the season merging advanced setting if you don't like pain.

fix: Respect no merge tag:

If you want a series to never be merged, then (potentially create and) add the "shokofin/no merge" custom tag on the series in shoko server, and it will never be merged with another series in the plugin.

fix: Always run custom providers.

fix: Respect map as specials tag:

The custom tag "shokofin/map as specials" should generally be applied to OVAs where you want the episodes to show up as specials and not normal episodes, but the system will allow you to set the tag on any series and it should Just Work™. It can also be combined with the season merging, or used outside it in shoko groups.

fix: Await production locations instead of genres.

fix: Better removal of alternate versions:

Improved the logic where we split the alternate versions in the merge versions manager to also account for local alternate versions. Since we're only operating on Shoko managed libraries then I'm fine with the plugin completely managing the alternate versions so we'll just take control of it all, instead of the partway control we before this commit where we were intentionally ignoring the local versions and somewhat half-baked removing the linked local versions.

Also hello 👋 to the one reading this.

fix: Attempt to upgrade trickplay files:

Attempt to "upgrade" the trickplay files in the underlying library if we have a newer version in the VFS compared to what is in the underlying library.

fix: Skip visited videos regardless of depth.

feat: Make multiple version order configurable (#78):

The order in the multiple versions drop-down on the episode/movie pages for libraries managed by the plugin is now configurable through the plugin settings, and by default will use the imported at date, but you can change the ordering as an advanced setting if you feel like it.

Thanks to @GlawenC (Discord: <@707281950355881994>) for doing the research needed to implement this feature and for providing the basic implementation that was built upon in this commit.

Closes #46

Co-authored-by: Mikal Stordal mikalstordal@gmail.com

fix: Use backdrops as thumbnails for "movie" episodes:

Use backdrops tied to the episode as thumbnails for "movie" episodes inside a shows type (or mixed type) library when a movie type series is showing up as a show.

feat: Add series configuration + more:

  • Added new per-series configuration, stored on the server as custom tags.

  • Added a new selector to chose between anidb structure, shoko structure, and tmdb structure to use by default for all libraries, and together with the new per-series configuration we allow it to be overridden on a per-series basis, though no UI to do it yet.

  • Added a new per-series setting to display specials as normal episodes after the normal episodes.

fix: Fix episode type masking:

Fix the episode type masking i just broke in the last commit.

refactor: Reconstruct the episode info:

Remove the directly exposed anidb and shoko objects on the episode info, and instead place the needed properties directly on the episode info object to make it easier to add episode info for tmdb episodes in the future.

fix: Only mark specials and not normal episodes.

refactor: Add tmdb episode data and constructor for episode info.

fix: More through refresh dispatching logic:

Made the refresh dispatching logic in the event dispatcher service more through, by distincting the input lists we get from the core, and also tracking which entities has been updated and their parents, and only firing the event if the entity or it's parents haven't been updated since the last usage stalled event or if the clear plugin cache task is ran.

refactor: Drop ordering information for now:

Don't request the ordering information for now. We'll request it later if we need it for any future features.

refactor: Add season id to episode info.

fix: Removed erroneous "$" in TMDB API Request (#79):

The pains of working in C# and JS. 😔

feat: Add series config. option to order by airdate:

This option will only make sense if you enable the other series config. to include specials as episodes.

chore: A dashing commit (#81):

The biggest commit ever seen by man (||maybe||).

refactor: Implement multi-structure support + more:

Implemented Multi-Structure Support

  • Finally implemented support for multiple library structures. Users can now set a base structure and override it on a per-Shoko-Series basis. With the addition of the new TMDB shows and movies structure, the library now supports three possible structures, which can be used as a whole and overridden as needed.

  • Leveraging the updated data abstraction, the plugin can now map TMDB _shows as movies_¹ or TMDB movies as shows.

  • For movies, if TMDB movie collections are enabled in Shoko, the plugin uses these collections to create either show entries or collection entries based on how your libraries and plugin settings are configured. In show-type libraries, movies are mapped as seasons/episodes, while in movie-type libraries² collections are mapped as actual collections.

  • For shows, we support using "alternate orderings" (or "episode groups" in TMDB terminology) if enabled in Shoko, allowing alternate season/episode arrangements³ if the default arrangement is not to your liking. You will have to configure the alternate ordering to use in Shoko for now, until the utility is done (||totally not foreshadowing||).

  • Added support for TMDB metadata across all structures, including studios, content ratings, production locations, tags, and genres. The settings apply globally across all structures, and metadata is excluded if any of these options are disabled, even if available.

General Changes

  • Replaced the global language code setting for images with per-entity-type, per-image-type settings. Existing settings are automatically migrated, but feel free to tweak them after the update.

  • Fixed an issue with "missing" episodes. The plugin now disables the server's unaired filter, ensuring unaired episodes populate correctly. Sorry about that.

  • Introduced an option to replace images during automatic metadata updates triggered by SignalR events (disabled by default).

  • Updated references to TMDB in the Jellyfin UI to "TheMovieDb," aligning with TMDB’s native branding and the rest of the Jellyfin UI.

  • Exposed AniDB IDs for series, seasons, episodes, and movies, enabling users to view and link to AniDB pages. No idea how compatible this is with the default AniDB plugin, but even if it's incompatible I don't think you should be using that plugin if you have this plugin installed.

Code Style & Modernization

  • Updated to use primary constructors where applicable.

  • Changed bracket placement from C# style (new line) to JS style (same line) for improved readability and reduced vertical space.

  • Standardized variable naming across the codebase. As part of the refactor, made sure the [Ss]eriesIds that were previously referring to the season info's id and not the Shoko Series' id were renamed to [Ss]easonId, among other similar changes.

  • Added missing .ConfigureAwait(false) calls on await-ed Tasks.

¹ Please don't do that, for your own mental health.
² If collections are enabled ONLY for movies and the option to separate movies from series/shows is enabled in the plugin settings.
³ Note: Alternate season images are not currently available in Shoko or TMDB.

fix: Track usage in virtual root task.

misc: Include our upstream source in images:

Include our upstream source in images provided by the plugin.

fix: Add back proper per-library media folder config removal.

misc: Add log point at the beginning of VFS generation.

fix: Use invariant culture ignore case for resolved tag children.

fix: Unmark library structure mode as expert.

misc: Add debug & experimental setting badges.

feat: Add per library structure type respect preferred image setting.

fix: Upgrade tag/genres sources to include the new TMDB sources by default.

chore: Move all extensions to their own namespace.

misc: Change log level for guarded memory cache exception logging.

fix: Movie collections can be known but not downloaded in the server.

misc: Mark "Require Two Entries for a Collection" option as a debug option.

fix: Don't assume the tmdb episode exists:

Don't assume the TMDB episode exists, even if we have a cross-reference for it.

chore: Rename Default* to * on IBaseItemInfo:

Rename DefaultTitle and DefaultOverview to just Title and Overview on the IBaseItemInfo interface, and also add summaries for the properties of the interface and the interface itself.

fix: Fix double namespacing on series.

fix: Return early in startup tasks if the plugin is not connected to a server.

fix: Fix serialization of component version.

fix: Properly set anidb anime id for series info and season info.

fix: Complain loudly if we find a mismatch between files found and cross-references found.

feat: Add anidb creator id for people.

fix: Fallback to anidb cast/crew if tmdb cast/crew is unavailable.

fix: Add provider ids to cast/crew.

fix: Hopefully fix character names breaking everything.

misc: Better response logging in api client.

fix: Remove unnecessary usage of EpisodeInfo.SeasonNumber.

fix: Improve show info community rating:

Improved the show info community rating by pre-caching it instead of calculating it on demand, allowing us to do different methods of calculation per show info type/impl., which allows us to use a direct value for show infos for tmdb shows and movies and anidb anime, while aggregating the value for shoko groups and tmdb movie collections.

feat: Expose community rating for images if available.

repo: Update version matrix in read-me file.

fix: Inverse reversed boolean logic.

misc: Update comment. (Skip CI)

fix: Always use default tmdb title for tmdb entities and set a better fallback name.

feat: I18n buttons in plugin settings.

misc: Move back accidentally moved file.

fix: Enable more code analyzers & fix locking on this issue.

misc: Remove unnecessary virtual field on external ids.

fix: Remove legacy support for 4.2 in cross-reference by marking the percentage object on the episode reference as non-nullable, since they're always available from 5.0 and onwards.

fix: Fix up creator role for latest daily server.

misc: Add created at and updated at to base info interface.

fix: Missed a spot:

follow up commit for 3ef0aec.

chore: DI usage tracker in api client and manager.

chore: Add concurrency lock to API client:

Added a concurrency lock to the API client, to allow a maximum of 10 concurrent requests at all times, as to not overload the server with a DoS attack when iterating a long-running series like e.g. One Piece.

Also tweaked the log statements and made POST requests able to be cached if needed, but they skip the cache by default.

chore: Further restrict library item searches to only physical libraries in managers/services.

chore: Pass and use cancellation token in the guarded cache.

fix: Fix default selected options in settings html.

fix: Filter out empty series from VFS and library:

Filter out series which we have no normal episodes or specials for from all libraries, be it those managed through the VFS or traditional filtering.

fix: Distinct character names before joining.

fix: Skip cast/crew if staff member don't have a name.

fix: Hard code haruhi '06 for VFS:

<a:thisIsFine:1058294258727145473>

repo: Update shoko link: (Skip CI)

Closes #85 Fixes #85

fix: Improve file system change reports for physical VFS libraries:

Leave it 100% to Jellyfin for how to handle it when new series have been added to the VFS, instead of giving it a random folder in the root of the physical VFS and say it has changed.

fix: Missed a spot in the last commit:

Added the changes to a missing spot in commit def7e76.

fix: Log which locations will be emitted:

Log which locations will be emitted to the core in the event dispatch service when verbose/trace logging is enabled for the service.

fix: Check staff name, not role name, during transform to person info.

refactor: Remove VFS cache placement option.

fix: Readjust season id read from path before use.

refactor: Remove TryGetEpisodeIdFor in favor of TryGetEpisodeIdsFor.

fix: Better "missing" episode removal logic:

This should hopefully fix the faulty removal logic for good… hopefully.

repo: Update version matrix in read-me. (Skip CI)

chore: Remove trailing whitespaces.

feat: Add iterative file checks mode in VFS:

Added a new iterative file check mode for VFS generation, to be used when iterating the file system is expensive (e.g. if the libraries are on a network mapped mount/drive, etc.), if you just prefer it to be done incrementally instead of up front. The setting is marked as debug.

fix: Silently suppress the double namespace issue:

Silently suppress the double namespace issue for the internal plugin id on entities when we encounter it.

misc: Mark all vfs location settings as debug instead of experimental.

feat: Add support for merging side/main stories:

Added EXPERIMENTAL support for merging side/main stories… making the existing merge logic even more complex in the process.

misc: Allow syncing vfs thread count to refresh thread count:

Allow synchronizing the number of threads to use during a VFS (re-)generation to the number of threads to use during a recursive refresh of a folder (any folder, by it the library itself, a series within, etc.) defined in the jellyfin core system settings by setting the VFS threads setting to -1. Setting it to 0 or anything below -1 will still set it to use the number of available CPU cores, but -1 is now reserved for following the system setting.

fix: More systematic ordering of relations during merging.

fix: Add guard for shared side stories:

Added a guard to prevent accidentally duplicating a series across multiple merge groups because the series is a side story to multiple main stories (e.g. linked to two series which have a sequel/prequel relationship, etc.).

fix: Suppress ignored episode titles.

fix: Provide fallback title in providers.

chore: Simplify special prefix logic.

fix: Ignore more episode names.

fix: Check all titles if they're invalid, not just some.

misc: Add roman letter fallback for movie series if no subtitle is available.

fix: Suppress people and committees from studio list.

feat: Add setting to only show animation studios.

misc: Add more invalid episode titles.

repo: Update version matrix in read-me file.

fix: Add missing series types for daily server.

feat: Add support for multiple alt/orig. titles per entry.

chore: Remove extra whitespace.

refactor: Tweak SignalR auto-reconnect behavior:

  • Tweaked the SignalR auto-reconnect behavior to not sort and filter the list, and to use the last interval in the list indefinitely until a successful connection is made, instead of the old behavior of not trying again once we've tried all the intervals in the list.

misc: Remove numbering if it's only one:

  • Removed the numbering of the alternate/original titles in the UI if it's only one.

misc: Move add button, show remaining instead of total:

  • Moved the button responsible for adding new alternate/original titles into the <fieldset> of the first title, making it so it won't move when you press it and also feel more in-line (literally) with the rest of the alternate/original title UI.

  • Show remaining titles you can add instead of showing the maximum allowed titles.

  • Switch the add button from primary to secondary when we disable it, since it seems like Jellyfin doesn't have CSS for disabled primary buttons, so this will make it more obvious (hopefully) that it's in a disabled state.

feat: Add advanced title settings:

  • Added per-structure-type per-base-item title settings, all disabled by default. Can't get more advanced than this I think. but because it's so advanced, it's hard to make an intuitive UI for it, so no UI for now.

Hey! You! Yes, the one reading this. Are you tired of the plugin only supporting a single set of settings for titles across all types (i.e. shows/seasons/episodes/movies/collections)? Rejoice! You now have per-structure-type, per-base-item advanced title settings — because only you know best what you want. 🎉 The only catch? There’s no fancy UI for it, so roll up your sleeves and tweak the XML directly to your heart’s content.

refactor: Impl. series config. service [1/2]:

Part 1 of 2 of the series configuration implementation. This is the backend code and the api client methods to-be-used by the series configuration utility in the future, giving the minimum required to test it in devtools before figuring out the rest.

refactor: Make compatible with provider refactor + more:

  • Made the plugin with the provider info refactor branch on the server without breaking compatibility with the current dailies. This required tweaking the REST API endpoints & models and SignalR channels and models to support both versions at the same time.

  • Updated URL handling for IExternalIds to IExternalUrlProvider and reorganized the external id namespace. Also removed the Shoko fields so you can't edit them. They were only previously exposed because that was the only way to get the redirects back to shoko working.

  • Renamed 'import folder' to 'managed folder' throughout the code base, including in the user/admin facing UIs.

  • Added support for redirecting to the correct location when the Web UI prefix has been tweaked in Shoko Server. So users(/me) mounting the Web UI at / or other locations will still result in the links redirecting to the correct pages.

fix: Fix enum usage for dailies.

fix: Allow release group id to be a number or string.

chore: Clean up style. (Skip CI)

feat: Add yearly seasons & air days:

  • Added yearly seasons as tags. E.g. Winter 2013/14, Spring 2001, etc.

  • Added air days for series. This is a native Jellyfin feature, so they're not added as tags.

feat: Add tag/genre exclusion lists:

  • Added the ability to exclude certain tags from being displayed as tags/genres.

refactor: Add plain text / markdown conversion modes:

  • Added a plain text or markdown conversion mode for descriptions. Markdown is used by default.

feat: Add advanced description settings:

The same advanced settings as for titles, but for descriptions. Only configurable in the XML settings file for now.

repo: Update version matrix. (Skip CI)

fix: Wrap version check in try…catch.

fix: Fix description settings.

fix: Fix web prefix getter in api client.

fix: Fix shoko series url for videos.

misc: Mark file system metadata as nullable. (Skip CI)

misc: Add todo in code. (Skip CI)

chore: Set init value for correct field in plugin config. (Skip CI)

fix: Only react to saved events if the global sync option is enabled.

fix: Handle episode not being part of the preferred alternate ordering.

fix: Always use default ordering when fetching metadata from tmdb episode.

fix: Remove unnecessary $ in template escape.

feat: Move external audio to VFS (#88):

Add support for moving external audio files between the VFS and the underlying library by refactoring the existing subtitle support to more broadly cover external files.

Closes #86

repo: Update read-me. (Skip CI)

refactor: Impl. series config. service [2/2]:

Part 2 of 2 of the series configuration implementation. This is the frontend code and HTML for the series configuration utility. For now it's very basic, as i don't want to go down the custom (pure) JS (hell) route.

misc: Update read-me file. (Skip CI)

fix: Log error message, not a boolean value.

refactor: Always send language code and actual rating to API clients:

Always send the proper language code and actual rating to the API clients. We determine if it's likely to be an API client by tracking the currently in-flight requests to the remote images endpoint (like we've always done so far), but now e're also taking note of the item's id to check if we get a call to the image provider with said id. It's not fool proof, but it should work in 99.9% of use-cases unless you happen to be fetching the images for an item that's also currently getting an automated image refresh, in which case, good luck timing that.

feat: Allow setting season ordering per shoko series.

refactor: Graduate season merging from experimental and refine the logic a little.

feat: Add MVC auto-refresh task and metadata refresh service:

The image logic can still be improved, and no settings UI as of this commit, but the task should be working fine with the current image logic and no settings UI. The rest can be refined/added in a later commit.

feat: Add search to series configuration / utility.

feat: Expose usage tracker stall time & reset default value.

fix: XmlElementXmlArray for array field.

fix: Skip VFS generation if media folders are unavailable:

In some cases, the media folders can be empty or otherwise unavailable (e.g. a local drive on windows is not mounted yet, a network share on windows is temporarily unavailable, a (network?) mount on linux was not mounted correctly, etc.), so skip the generation of the VFS if we detect any of the media folders attached to the library is in a faulted state, to prevent the generation removing all the symbolic links — effectively deleting the whole (or parts of) the VFS.

Fixes #89

misc: Move vfs always include list to config:

Moved the hard-coded AniDB anime ID set for series to always include in the VFS (if all the files are shared between multiple series) to the configuration. For now, no UI.

feat: Allow 'specials as extra featurettes' to be applied per series while not crippling the old global option to do it for all movies.

fix: Add missing managed by text for some tags.

chore: Move around settings.

fix: Remove currently unnecessary .split() on .value.

feat: Allow setting specials placement per shoko series.

chore: Move around settings.

refactor: Merge vfs enabled & library filtering options since both were mutually exclusive and could had just been a single option, so now they are.

fix: Remove Obsolete attributes on enums since the xml deserializer ignores the values if it's set.

chore: Forgot to rename the enum.

chore: Remove brackets. (Skip CI)

fix: Abort earlier during vfs preview if scan is running. (Skip CI)

fix: Add 'is enabled' check to custom providers.

chore: Add 'default' in front of default settings.

chore: Update settings text.

fix: Anidb content ratings should not be tied to country code.

fix: Notify changes if using physical vfs:

When reacting to a remove event, if the series has been removed then only send a normal notify even if the main media folder is the VFS folder to prevent it blocking all future events within the VFS send to jellyfin.

chore: Update settings text.

fix: Check if group has custom description before sanitizing.

chore: Make title a sub-class of text.

refactor: Add season merge groups.

fix: Fixes for series search / select logic in UI.

fix: Apply scale to community ratings for images.

refactor: Overhaul image search logic + more:

Overhauled the automatic image search logic and restructured all settings related to images. The new logic gives more control of which language to use across the different types during an automatic search performed by Jellyfin.

You may need to manually tweak your image settings to follow these news settings if you're a dev plugin user, as I'm not going to tailor the configuration migrations for you, but for the stable plugin users instead.

misc: Don't set tmdb keywords/genres by default:

Users can still enable them, but they're unfiltered compared to the rest of the tags in the tag filter, so they should probably not be enabled by default since they may as well overlap with some of the other (intentionally?) disabled tag sources.

chore: Rename method.

fix: Rename image type to not conflict with jellyfin's type in swagger.

refactor: Cleanup title config:

Cleaned up the structure of the title config, to be more easy to use in the future UI.

misc: Update TODOs in code.

fix: Ignore missing space in git commit messages.

misc: Rename controllers for better naming in swagger.

fix: Add back parsing of legacy text value.

fix: Rename missed image URLs after controller rename (#90).

fix: Make de-duplication of titles optional.

chore: Remove unnecessary markup.

fix: Change magic number from 20 to 13:

We missed a spot in #90.

fix: Use thumbnails and backdrops for episode images:

Thumbnails are hooked up for episodes while backdrops for movies in the backend, so pick the source that's available for the entity.

misc: Separate debug settings into debug mode.

fix: Check if enabled for item before getting external URLs.

chore: Change compare for Guid.Empty.

chore: Move TODO below summary.

fix: Check if enabled for item first.

fix: Properly clear cache in merge version manager.

fix: Don't use provider ids for collections.

fix: Make endpoints use auth.

chore: Fix bracket styling.

refactor: Add more debug settings.

fix: Only set width/height for images in display mode.

misc: Update option description.

refactor: Rework how IDs are linked to the info objects + more:

Reworked how the metadata IDs are linked to the info objects, allowing us to display all external links for the entities if the new setting to display more external URLs is enabled. Also streamlined the usage of the IDs internally.

Note: This change may slow down the metadata construction for info objects which will have multiple metadata IDs linked, since we're now fetching more info from the server compared to before.

fix: Unhide misc. section by default.

fix: Cache plugins exposed state:

Cache the 'has plugins API' state to prevent needing to contact the server before attempting to establish a SignalR connection, among other things.

This change will fix the regression causing the auto-start SignalR option to causing Jellyfin to fail to start properly if the Shoko Server instance is available while Jellyfin is starting.

chore: Minor tweaks.

fix: Re-allow anon. traffic for images:

Fixes the regression caused by "fix: make endpoints use auth".

fix: Don't auto enable display mode for auto search:

Fixes a bug where auto image search would use display mode values causing the selection logic to be more dependent on Jellyfin then on the plugin due to community ratings and/or image dimensions being set.

chore: Consolidate code paths.

fix: Fix tmdb episode page urls.

misc: Tweak logging during signalr connect.

misc: Tweak signalr server timeout to match server.

feat: Add option to set image dimensions in auto image search.

fix: Set missing defaults for image config.

misc: Mark image settings basic/non-advanced.

chore: Tweak style.

misc: Remove now unnecessary call.

chore: Tweak style. (Skip CI)

misc: Expose VFS thread debug option.

misc: Fix mislabeled debug options.

fix: Fix return type for Shoko episodes endpoint.

fix: Fix return type for Shoko episodes endpoint (take 2).

fix: Better cleanup of folders in root of VFS.

fix: Use season id for movies in VFS folder names.

fix: Don't rely on season id in folder to iterate movie files.

misc: Clear merge manager cache in clear task.

misc: Hide clear task behind debug flag.

fix: Even faster season id lookup for series in VFS.

misc: Update setting text.

feat: Display images for season 0 in images search performed by client(s).

fix: Fix warning id.

fix: Ignore external files within designated directories for extras.

fix: Better removal of non-managed folders in root of VFS:

Added some better removal logic of non-managed folders in the root of a VFS by returning a set of all files and folders that should be present in the VFS and flagging any it finds for removal for the existing removal logic to handle.

misc: Change log level of log statements for when a media folder is not found.

chore: Remove unreachable/dead code.

misc: Enable text-less images by default for new installs.

fix: Path to remove is a folder.

refactor: Cache extra external urls at item refresh:

Cache the external urls at item refresh because loading them on-demand seems laggy from a user's POV for larger/more-complex series/shows. Also enable it by default now that it's cached.

fix: Add anti season name patterns.

chore: Remove unnecessary import.

fix: Create new instance before disposing previous, add TODO.

feat: Add refresh field value to update owned items.

fix: Don't do recursive updates during auto refresh:

Since we're updating the items bottom-up, so we shouldn't allow it to do a top-down search.

fix: Make TryGet* methods on api manager safer by not throwing if Shoko is unreachable.

refactor: Conditional merging of multiple version:

Leave things as-is if everything is as intended, and only conditionally update the videos that needs to be updated. This will sped it up from 2m to 7s with a hot cache, and from 4m to 2m on a cold cache for my test server, in addition it will now NOT touch things which are already correctly linked/unlinked.

refactor: Rework external url & provider id logic:

  • Store external urls without the base to save space.

  • Inflate/deflate the external url array after/before storing it.

  • Made the (new) stored external urls mandatory, and removed the option to display more optional urls from the config and UI.

  • Simplified parts of the provider id handling for some providers.

  • Set the internal ID on all items. The lookup paths already existed, but the IDs were not set on all items.

  • Minor variable name tweaks.

misc: Tweak default season merging behavior.

fix: Remove duplicate base url.

feat: Expose per-entity-type overrides for title, desc. & image settings in UI.

fix: Properly set checked state when rendering sortable checkbox list.

fix: Only set a default option for the default title config.

fix: Don't add tvdb to default description order list upon startup.

misc: Move image settings section.

fix: Add missing branch for movie collection.

fix: No stall files during VFS generation for entities:

Disable the request cache for the 'get files' endpoints, so the VFS generation won't fail in edge cases where the series metadata has been updated right before a file is matched, preventing said file from being discovered.

Also removed the unused 'get files' endpoints. We can add them back if/when necessary.

fix: Add missing enablement checks.

chore: Remove double ;s.

fix: Add dedicated path for legacy refresh w/image refresh.

fix: Use application host instead of service provider to get required providers in metadata refresh service.

fix: Always set refreshed at timestamp.

chore: Remove unused imports. (Skip CI)

feat: Expose more VFS debug options in the UI.

fix: Add new update reasons to accommodate changes in daily server.

fix: Always use tmdb titles/overviews for show instead of season for show info.

refactor: Make physical vfs folder mandatory.

chore: Fix brackets.

feat: Add new EXPERIMENTAL iterative VFS generation:

Added a new EXPERIMENTAL mode to iteratively generate the VFS for only newly imported files. There are also a few options to do a full generation every X generation, and to forcefully generate the whole VFS on next generation. It has no effect on generations within the library, only when the library itself is generated (be it in the scheduled task or from a refresh/scan of the media folder itself).

chore: Use DateTime.UtcNow instead of DateTime.Now.

fix: Add edge case for special episode endings to be mapped as extras.

refactor: Hook up resolver for iterative VFS generation + more:

  • Hooked up the resolver for iterative VFS generation. Added a way to skip validating links which wasn't generated in the previous generation.

  • Removed the option to enable iterative file checks. It is now always enabled, because of the rework of the internals of the VFS service to make the iterative generation work.

  • Overhauled the internals of the VFS service to better support iterative VFS generation. It will now only lock and not cache the results when iterating over root of the VFS folder, so two refreshes back-to-back will check with the upstream both times if there has been any changes, instead of only the first time working.

chore: Move more unused properties to DEBUG only builds.

fix: Always set expiration.

fix: Optimize first iterative VFS generation path.

fix: Fix anidb episode urls.

fix: Set creation date for directories in the VFS.

misc: Add doc comment.

refactor: Improve description cleanup logic:

Update the description cleanup logic to better accommodate the current descriptions I found on anime across AniDB. Also added logic to extract the notes to use in the next commit. With the notes extracted and with the cleanup logic enabled then it will allow the description to fall-through to the next description source (if any) if the description was only a note or otherwise cleaned-up text.

feat: Always display notes.

misc: Extract notes after cleaning.

fix: Edit year regex:

Edited the year regex… because there were more cases.

fix: Absolute expiration cannot be below or equal to zero.

fix: Use correct paths for equality check when trying to move files/directories out of VFS.

fix: Ignore all trickplay directories which don't have shoko ids set.

fix: Search for the link with the exact same base path and base name.

fix: Inverse reversed boolean check.

feat: Make no caching during iterative VFS gen. a debug option and disable it by default.

refactor: Improve throughput when enumerating files in VFS service:

Replaced the file and directory enumeration logic in the VFS service with a custom C# implementation that performs recursive traversal in parallel. Previously, the recursion was delegated to .NET Core, which in turn relied on the OS to handle directory walking. We still use the core enumeration methods, but now manage the recursion ourselves — in parallel. The parallelism is handled for us by the ActionBlock, with the maximum parallelism relying on the existing VFS threads (debug) setting.

In testing, walking the entire structure on my network-attached storage dropped from roughly 15 minutes per iteration to about 30 seconds.

refactor: Use ActionBlock while generating structure in VFS service:

Replaced the ol' async semaphore mess with a proper ActionBlock-based implementation, giving us better control over task scheduling and concurrency. Instead of queueing up all the async work at once and juggling semaphore waits everywhere, we now let the block handle throttling and dispatch order cleanly.

fix: Use new fast path for episode ids when available.

fix: Add skipped videos to result during iterative generation.

fix: Use the provided list in resolver:

Now that the VFS is always physical, we can use the provided file list. We previously had to iterate over the VFS folder ourselves because we might be masking the children as children of another media folder, but now that we don't need to care for that we can just as well just use the provided list.

fix: Only output new paths from VFS gen. to resolver.

feat: Add setting to add notes, enabled by default:

Added a new setting to add the AniDB anime summary note(s) to the description for the series/season entities. It's enabled by default to match the older behavior in stable where notes are always included in the description from AniDB.

refactor: Add back the semaphore concurrency:

Added back the semaphore based concurrency limit during VFS generation to test it in the wild against the new ActionBlock based generation. The semaphore based approach is enabled by default for now until the test results from the in-the-wild testing reveals which of them to keep going forward.

chore: Remove unused dependency.

feat: Add provider ids metadata refresh field.

chore: Ensure all ShowInfo.Id setters use a SeasonInfo.Id:

Be it from the "default" season info or from the only season info. In practice it will have the same value as it had.

fix: Don't attempt to sync user data for season 0s.

chore: Remove unnecessary dependency.

fix: Add fast path to get file/series ids for entries in the VFS.

misc: Rename cache key.

refactor: Add cancellation token & "properly" parallelize existing parallel flows in VFS service.

misc: Move method into correct region.

fix: Only check if dir exists once per getter init.

fix: Fix custom providers for non-generated items during iterative VFS generation.

chore: Simplify lookup.

fix: Cache virtual library folder infos.

refactor: Schedule tasks post library-scan:

Fork out sub-tasks to run after a library scan to the pre-existing scheduled tasks, instead of running them all in the last 4% of the library scan. This also benefits that you will see the progress of each individual post-scan task as they're running, and you can cancel them induvidually of each other and the (hopefully finished) library scan.

Also added a new (advanced) setting to disable the automatic (re)construction of collections which used to always run after a library scan. It's enabled by default to match the previous behavior. The reconstruction is would slow down the scan in the post-task step when iterative generation was enabled, because it would have to fetch all the info regardless of how many links we generated, so most of what would had been cache hits becomes cache misses, slowing everything down to almost the same time as a full refresh instead.

The merge episodes/movies tasks will now also be displayed on the dashboard when they're automatically ran after a library scan, so you can track their progress and/or cancel them if you deem them unecessary for a single run. They already had their own (advanced) setting, so no need setting have been added.

fix: Don't over-report changes done in custom providers.

fix: Conditionally also skip custom movie provider during iterative vfs gen.

fix: Fix recursive file system iteration i borked when doing paralleism the "proper" way.

refactor: Clear cache if iterative VFS gen. is enabled:

This will clear the VFS generation cache every time a refresh is triggered for a media folder with iterative generation enabled. This will ensure the VFS gen. for said media folder will always occurr, but the items within the VFS will still use the cached value(s) until the cache expires or a new library-wide generation occurs.

fix: Remove defunct IExternalId.UrlFormatString.

fix: Rename TaskTriggerInfo.*TaskTriggerInfoType.*.

misc: Update to dotnet9 & jellyfin 10.11.

misc: Add dual resolvers for now.

fix: Replace semaphore with actual lock object.

fix: Complete move to dotnet 9.x:

Closes #87

misc: Update dependency version.

fix: Add guard against older data formats when inflating urls.

Don't miss a new Shokofin release

NewReleases is sending notifications on new releases.