public async Task <PublicInfo> GetServerInfo([FromBody] JellyfinServers server) { var client = await JellyfinApi.CreateClient(); var result = await client.GetPublicInformation(server.FullUri); return(result); }
private bool ValidateSettings(JellyfinServers server) { if (server?.Ip == null || string.IsNullOrEmpty(server?.ApiKey)) { _logger.LogInformation(LoggingEvents.JellyfinContentCacher, $"Server {server?.Name} is not configured correctly"); return(false); } return(true); }
public async Task <bool> Jellyfin([FromBody] JellyfinServers settings) { try { var result = await _jellyfinApi.GetUsers(settings.FullUri, settings.ApiKey); return(result.Any()); } catch (Exception e) { Log.LogError(LoggingEvents.Api, e, "Could not test Jellyfin"); return(false); } }
public async Task <JellyfinItemContainer <MediaFolders> > GetLibaries([FromBody] JellyfinServers server) { var client = await JellyfinApi.CreateClient(); var result = await client.GetLibraries(server.ApiKey, server.FullUri); var mediaFolders = new JellyfinItemContainer <MediaFolders> { TotalRecordCount = result.Count, Items = new List <MediaFolders>() }; foreach (var folder in result) { var toAdd = new MediaFolders { Name = folder.Name, Id = folder.ItemId, ServerId = server.ServerId }; var types = folder?.LibraryOptions?.TypeOptions?.Select(x => x.Type).ToList(); if (!types.Any()) { continue; } if (types.Where(x => x.Equals("Movie", System.StringComparison.InvariantCultureIgnoreCase) || x.Equals("Episode", System.StringComparison.InvariantCultureIgnoreCase)).Count() >= 2) { toAdd.CollectionType = "mixed"; } else if (types.Any(x => x.Equals("Movie", StringComparison.InvariantCultureIgnoreCase))) { toAdd.CollectionType = "movies"; } else if (types.Any(x => x.Equals("Episode", StringComparison.InvariantCultureIgnoreCase))) { toAdd.CollectionType = "tvshows"; } mediaFolders.Items.Add(toAdd); } return(mediaFolders); }
private async Task ProcessMovies(JellyfinServers server, string parentId = default) { var movies = await Api.GetAllMovies(server.ApiKey, parentId, 0, 200, server.AdministratorId, server.FullUri); var totalCount = movies.TotalRecordCount; var processed = 0; var mediaToAdd = new HashSet <JellyfinContent>(); var mediaToUpdate = new HashSet <JellyfinContent>(); while (processed < totalCount) { foreach (var movie in movies.Items) { if (movie.Type.Equals("boxset", StringComparison.InvariantCultureIgnoreCase)) { var movieInfo = await Api.GetCollection(movie.Id, server.ApiKey, server.AdministratorId, server.FullUri); foreach (var item in movieInfo.Items) { await ProcessMovies(item, mediaToAdd, mediaToUpdate, server); } processed++; } else { processed++; // Regular movie await ProcessMovies(movie, mediaToAdd, mediaToUpdate, server); } } // Get the next batch movies = await Api.GetAllMovies(server.ApiKey, parentId, processed, 200, server.AdministratorId, server.FullUri); await _repo.AddRange(mediaToAdd); await _repo.UpdateRange(mediaToUpdate); mediaToAdd.Clear(); } }
private async Task StartServerCache(JellyfinServers server) { if (!ValidateSettings(server)) { return; } //await _repo.ExecuteSql("DELETE FROM JellyfinEpisode"); //await _repo.ExecuteSql("DELETE FROM JellyfinContent"); if (server.JellyfinSelectedLibraries.Any() && server.JellyfinSelectedLibraries.Any(x => x.Enabled)) { var movieLibsToFilter = server.JellyfinSelectedLibraries.Where(x => x.Enabled && x.CollectionType == "movies"); foreach (var movieParentIdFilder in movieLibsToFilter) { _logger.LogInformation($"Scanning Lib '{movieParentIdFilder.Title}'"); await ProcessMovies(server, movieParentIdFilder.Key); } var tvLibsToFilter = server.JellyfinSelectedLibraries.Where(x => x.Enabled && x.CollectionType == "tvshows"); foreach (var tvParentIdFilter in tvLibsToFilter) { _logger.LogInformation($"Scanning Lib '{tvParentIdFilter.Title}'"); await ProcessTv(server, tvParentIdFilter.Key); } var mixedLibs = server.JellyfinSelectedLibraries.Where(x => x.Enabled && x.CollectionType == "mixed"); foreach (var m in mixedLibs) { _logger.LogInformation($"Scanning Lib '{m.Title}'"); await ProcessTv(server, m.Key); await ProcessMovies(server, m.Key); } } else { await ProcessMovies(server); await ProcessTv(server); } }
private async Task ProcessMovies(JellyfinMovie movieInfo, ICollection <JellyfinContent> content, JellyfinServers server) { // Check if it exists var existingMovie = await _repo.GetByJellyfinId(movieInfo.Id); var alreadyGoingToAdd = content.Any(x => x.JellyfinId == movieInfo.Id); if (existingMovie == null && !alreadyGoingToAdd) { _logger.LogDebug("Adding new movie {0}", movieInfo.Name); content.Add(new JellyfinContent { ImdbId = movieInfo.ProviderIds.Imdb, TheMovieDbId = movieInfo.ProviderIds?.Tmdb, Title = movieInfo.Name, Type = JellyfinMediaType.Movie, JellyfinId = movieInfo.Id, Url = JellyfinHelper.GetJellyfinMediaUrl(movieInfo.Id, server?.ServerId, server.ServerHostname), AddedAt = DateTime.UtcNow, }); } else { // we have this _logger.LogDebug("We already have movie {0}", movieInfo.Name); } }
private async Task ProcessTv(JellyfinServers server, string parentId = default) { // TV Time var mediaToAdd = new HashSet <JellyfinContent>(); var tv = await Api.GetAllShows(server.ApiKey, parentId, 0, 200, server.AdministratorId, server.FullUri); var totalTv = tv.TotalRecordCount; var processed = 1; while (processed < totalTv) { foreach (var tvShow in tv.Items) { try { processed++; if (string.IsNullOrEmpty(tvShow.ProviderIds?.Tvdb)) { _logger.LogInformation("Provider Id on tv {0} is null", tvShow.Name); continue; } var existingTv = await _repo.GetByJellyfinId(tvShow.Id); if (existingTv == null) { _logger.LogDebug("Adding new TV Show {0}", tvShow.Name); mediaToAdd.Add(new JellyfinContent { TvDbId = tvShow.ProviderIds?.Tvdb, ImdbId = tvShow.ProviderIds?.Imdb, TheMovieDbId = tvShow.ProviderIds?.Tmdb, Title = tvShow.Name, Type = JellyfinMediaType.Series, JellyfinId = tvShow.Id, Url = JellyfinHelper.GetJellyfinMediaUrl(tvShow.Id, server?.ServerId, server.ServerHostname), AddedAt = DateTime.UtcNow }); } else { _logger.LogDebug("We already have TV Show {0}", tvShow.Name); } } catch (Exception) { throw; } } // Get the next batch tv = await Api.GetAllShows(server.ApiKey, parentId, processed, 200, server.AdministratorId, server.FullUri); await _repo.AddRange(mediaToAdd); mediaToAdd.Clear(); } if (mediaToAdd.Any()) { await _repo.AddRange(mediaToAdd); } }
private async Task CacheEpisodes(JellyfinServers server) { var allEpisodes = await Api.GetAllEpisodes(server.ApiKey, 0, 200, server.AdministratorId, server.FullUri); var total = allEpisodes.TotalRecordCount; var processed = 1; var epToAdd = new HashSet <JellyfinEpisode>(); while (processed < total) { foreach (var ep in allEpisodes.Items) { processed++; if (ep.LocationType?.Equals("Virtual", StringComparison.InvariantCultureIgnoreCase) ?? false) { // For some reason Jellyfin is not respecting the `IsVirtualItem` field. continue; } // Let's make sure we have the parent request, stop those pesky forign key errors, // Damn me having data integrity var parent = await _repo.GetByJellyfinId(ep.SeriesId); if (parent == null) { _logger.LogInformation("The episode {0} does not relate to a series, so we cannot save this", ep.Name); continue; } var existingEpisode = await _repo.GetEpisodeByJellyfinId(ep.Id); // Make sure it's not in the hashset too var existingInList = epToAdd.Any(x => x.JellyfinId == ep.Id); if (existingEpisode == null && !existingInList) { _logger.LogDebug("Adding new episode {0} to parent {1}", ep.Name, ep.SeriesName); // add it epToAdd.Add(new JellyfinEpisode { JellyfinId = ep.Id, EpisodeNumber = ep.IndexNumber, SeasonNumber = ep.ParentIndexNumber, ParentId = ep.SeriesId, TvDbId = ep.ProviderIds.Tvdb, TheMovieDbId = ep.ProviderIds.Tmdb, ImdbId = ep.ProviderIds.Imdb, Title = ep.Name, AddedAt = DateTime.UtcNow }); if (ep.IndexNumberEnd.HasValue && ep.IndexNumberEnd.Value != ep.IndexNumber) { epToAdd.Add(new JellyfinEpisode { JellyfinId = ep.Id, EpisodeNumber = ep.IndexNumberEnd.Value, SeasonNumber = ep.ParentIndexNumber, ParentId = ep.SeriesId, TvDbId = ep.ProviderIds.Tvdb, TheMovieDbId = ep.ProviderIds.Tmdb, ImdbId = ep.ProviderIds.Imdb, Title = ep.Name, AddedAt = DateTime.UtcNow }); } } } await _repo.AddRange(epToAdd); epToAdd.Clear(); allEpisodes = await Api.GetAllEpisodes(server.ApiKey, processed, 200, server.AdministratorId, server.FullUri); } if (epToAdd.Any()) { await _repo.AddRange(epToAdd); } }
private async Task ProcessMovies(JellyfinMovie movieInfo, ICollection <JellyfinContent> content, ICollection <JellyfinContent> toUpdate, JellyfinServers server) { var quality = movieInfo.MediaStreams?.FirstOrDefault()?.DisplayTitle ?? string.Empty; var has4K = false; if (quality.Contains("4K", CompareOptions.IgnoreCase)) { has4K = true; } // Check if it exists var existingMovie = await _repo.GetByJellyfinId(movieInfo.Id); var alreadyGoingToAdd = content.Any(x => x.JellyfinId == movieInfo.Id); if (existingMovie == null && !alreadyGoingToAdd) { if (!movieInfo.ProviderIds.Any()) { _logger.LogWarning($"Movie {movieInfo.Name} has no relevant metadata. Skipping."); return; } _logger.LogDebug($"Adding new movie {movieInfo.Name}"); content.Add(new JellyfinContent { ImdbId = movieInfo.ProviderIds.Imdb, TheMovieDbId = movieInfo.ProviderIds?.Tmdb, Title = movieInfo.Name, Type = MediaType.Movie, JellyfinId = movieInfo.Id, Url = JellyfinHelper.GetJellyfinMediaUrl(movieInfo.Id, server?.ServerId, server.ServerHostname), AddedAt = DateTime.UtcNow, Quality = has4K ? null : quality, Has4K = has4K }); } else { if (!quality.Equals(existingMovie?.Quality, StringComparison.InvariantCultureIgnoreCase)) { _logger.LogDebug($"We have found another quality for Movie '{movieInfo.Name}', Quality: '{quality}'"); existingMovie.Quality = has4K ? null : quality; existingMovie.Has4K = has4K; // Probably could refactor here // If a 4k movie comes in (we don't store the quality on 4k) // it will always get updated even know it's not changed toUpdate.Add(existingMovie); } else { // we have this _logger.LogDebug($"We already have movie {movieInfo.Name}"); } } }
private async Task StartServerCache(JellyfinServers server, JellyfinSettings settings) { if (!ValidateSettings(server)) { return; } //await _repo.ExecuteSql("DELETE FROM JellyfinEpisode"); //await _repo.ExecuteSql("DELETE FROM JellyfinContent"); var movies = await Api.GetAllMovies(server.ApiKey, 0, 200, server.AdministratorId, server.FullUri); var totalCount = movies.TotalRecordCount; var processed = 1; var mediaToAdd = new HashSet <JellyfinContent>(); while (processed < totalCount) { foreach (var movie in movies.Items) { if (movie.Type.Equals("boxset", StringComparison.InvariantCultureIgnoreCase)) { var movieInfo = await Api.GetCollection(movie.Id, server.ApiKey, server.AdministratorId, server.FullUri); foreach (var item in movieInfo.Items) { await ProcessMovies(item, mediaToAdd, server); } processed++; } else { processed++; // Regular movie await ProcessMovies(movie, mediaToAdd, server); } } // Get the next batch movies = await Api.GetAllMovies(server.ApiKey, processed, 200, server.AdministratorId, server.FullUri); await _repo.AddRange(mediaToAdd); mediaToAdd.Clear(); } // TV Time var tv = await Api.GetAllShows(server.ApiKey, 0, 200, server.AdministratorId, server.FullUri); var totalTv = tv.TotalRecordCount; processed = 1; while (processed < totalTv) { foreach (var tvShow in tv.Items) { try { processed++; if (string.IsNullOrEmpty(tvShow.ProviderIds?.Tvdb)) { _logger.LogInformation("Provider Id on tv {0} is null", tvShow.Name); continue; } var existingTv = await _repo.GetByJellyfinId(tvShow.Id); if (existingTv == null) { _logger.LogDebug("Adding new TV Show {0}", tvShow.Name); mediaToAdd.Add(new JellyfinContent { TvDbId = tvShow.ProviderIds?.Tvdb, ImdbId = tvShow.ProviderIds?.Imdb, TheMovieDbId = tvShow.ProviderIds?.Tmdb, Title = tvShow.Name, Type = JellyfinMediaType.Series, JellyfinId = tvShow.Id, Url = JellyfinHelper.GetJellyfinMediaUrl(tvShow.Id, server?.ServerId, server.ServerHostname), AddedAt = DateTime.UtcNow }); } else { _logger.LogDebug("We already have TV Show {0}", tvShow.Name); } } catch (Exception) { throw; } } // Get the next batch tv = await Api.GetAllShows(server.ApiKey, processed, 200, server.AdministratorId, server.FullUri); await _repo.AddRange(mediaToAdd); mediaToAdd.Clear(); } if (mediaToAdd.Any()) { await _repo.AddRange(mediaToAdd); } }