public async Task <IActionResult> Get(string imdb) { var cachedMovie = _cachingService.GetCache(imdb); if (cachedMovie == null) { using (var context = new PopcornContextFactory().Create(new DbContextFactoryOptions())) { var movie = context.MovieSet.Include(a => a.Torrents) .Include(a => a.Cast) .Include(a => a.Similars) .Include(a => a.Genres).AsQueryable() .FirstOrDefault( document => document.ImdbCode.ToLower() == imdb.ToLower()); if (movie == null) { return(BadRequest()); } var movieJson = ConvertMovieToJson(movie); _cachingService.SetCache(imdb, JsonConvert.SerializeObject(movieJson)); return(Json(movieJson)); } } return(Json(JsonConvert.DeserializeObject <MovieJson>(cachedMovie))); }
public async Task <IActionResult> Get(string imdb) { var hash = Convert.ToBase64String( Encoding.UTF8.GetBytes(imdb)); try { var cachedShow = await _cachingService.GetCache(hash); if (cachedShow != null) { try { return(Content(cachedShow, "application/json")); } catch (Exception ex) { _loggingService.Telemetry.TrackException(ex); } } } catch (Exception ex) { _loggingService.Telemetry.TrackException(ex); } using (var context = new PopcornContextFactory().CreateDbContext(new string[0])) { var show = await context.ShowSet.Include(a => a.Rating) .Include(a => a.Episodes) .ThenInclude(episode => episode.Torrents) .ThenInclude(torrent => torrent.Torrent0) .Include(a => a.Episodes) .ThenInclude(episode => episode.Torrents) .ThenInclude(torrent => torrent.Torrent1080p) .Include(a => a.Episodes) .ThenInclude(episode => episode.Torrents) .ThenInclude(torrent => torrent.Torrent480p) .Include(a => a.Episodes) .Include(a => a.Episodes) .ThenInclude(episode => episode.Torrents) .ThenInclude(torrent => torrent.Torrent720p) .Include(a => a.Genres) .Include(a => a.Images) .Include(a => a.Similars).AsQueryable() .FirstOrDefaultAsync(a => a.ImdbId == imdb); if (show == null) { return(BadRequest()); } var showJson = ConvertShowToJson(show); var json = JsonSerializer.ToJsonString(showJson, StandardResolver.SnakeCase); await _cachingService.SetCache(hash, json, TimeSpan.FromDays(1)); return(Content(json, "application/json")); } }
public async Task <IActionResult> Get(string imdb) { var hash = Convert.ToBase64String( Encoding.UTF8.GetBytes($"full:{imdb}")); try { var cachedMovie = await _cachingService.GetCache(hash); if (cachedMovie != null) { try { return(Content(cachedMovie, "application/json")); } catch (Exception ex) { _loggingService.Telemetry.TrackException(ex); } } } catch (Exception ex) { _loggingService.Telemetry.TrackException(ex); } using (var context = new PopcornContextFactory().CreateDbContext(new string[0])) { var movie = await context.MovieSet.Include(a => a.Torrents) .Include(a => a.Cast) .Include(a => a.Similars) .Include(a => a.Genres).AsQueryable() .FirstOrDefaultAsync( document => document.ImdbCode == imdb); if (movie == null) { return(BadRequest()); } var movieJson = ConvertMovieToJson(movie); var json = JsonSerializer.ToJsonString(movieJson, StandardResolver.SnakeCase); await _cachingService.SetCache(hash, json, TimeSpan.FromDays(1)); return(Content(json, "application/json")); } }
public async Task <IActionResult> Get(string imdb) { var hash = Convert.ToBase64String( Encoding.UTF8.GetBytes($"full:{imdb}")); try { var cachedMovie = await _cachingService.GetCache(hash); if (cachedMovie != null) { try { return(Json(JsonConvert.DeserializeObject <MovieJson>(cachedMovie))); } catch (Exception ex) { _loggingService.Telemetry.TrackException(ex); } } } catch (Exception ex) { _loggingService.Telemetry.TrackException(ex); } using (var context = new PopcornContextFactory().CreateDbContext(new string[0])) { var movie = await context.MovieSet.Include(a => a.Torrents) .Include(a => a.Cast) .Include(a => a.Similars) .Include(a => a.Genres).AsQueryable() .FirstOrDefaultAsync( document => document.ImdbCode == imdb); if (movie == null) { return(BadRequest()); } var movieJson = ConvertMovieToJson(movie); await _cachingService.SetCache(hash, JsonConvert.SerializeObject(movieJson)); return(Json(movieJson)); } }
public async Task <IActionResult> Get(string imdb) { var cachedShow = _cachingService.GetCache(imdb); if (cachedShow == null) { using (var context = new PopcornContextFactory().Create(new DbContextFactoryOptions())) { var show = context.ShowSet.Include(a => a.Rating) .Include(a => a.Episodes) .ThenInclude(episode => episode.Torrents) .ThenInclude(torrent => torrent.Torrent0) .Include(a => a.Episodes) .ThenInclude(episode => episode.Torrents) .ThenInclude(torrent => torrent.Torrent1080p) .Include(a => a.Episodes) .ThenInclude(episode => episode.Torrents) .ThenInclude(torrent => torrent.Torrent480p) .Include(a => a.Episodes) .ThenInclude(episode => episode.Torrents) .ThenInclude(torrent => torrent.Torrent720p) .Include(a => a.Genres) .Include(a => a.Images) .Include(a => a.Similars).AsQueryable() .FirstOrDefault(a => a.ImdbId.ToLower() == imdb.ToLower()); if (show == null) { return(BadRequest()); } var showJson = ConvertShowToJson(show); _cachingService.SetCache(imdb, JsonConvert.SerializeObject(showJson)); return(Json(showJson)); } } return(Json(JsonConvert.DeserializeObject <ShowJson>(cachedShow))); }
public async Task <IActionResult> Get(string malid) { var cachedAnime = _cachingService.GetCache(malid); if (cachedAnime == null) { using (var context = new PopcornContextFactory().Create(new DbContextFactoryOptions())) { var anime = context.AnimeSet.Include(a => a.Rating) .Include(a => a.Episodes) .ThenInclude(episode => episode.Torrents) .ThenInclude(torrent => torrent.Torrent0) .Include(a => a.Episodes) .ThenInclude(episode => episode.Torrents) .ThenInclude(torrent => torrent.Torrent1080p) .Include(a => a.Episodes) .ThenInclude(episode => episode.Torrents) .ThenInclude(torrent => torrent.Torrent480p) .Include(a => a.Episodes) .ThenInclude(episode => episode.Torrents) .ThenInclude(torrent => torrent.Torrent720p) .Include(a => a.Genres) .Include(a => a.Images).AsQueryable().FirstOrDefault(a => a.MalId.ToLower() == malid.ToLower()); if (anime == null) { return(BadRequest()); } var animeJson = ConvertAnimeToJson(anime); _cachingService.SetCache(malid, JsonConvert.SerializeObject(animeJson)); return(Json(animeJson)); } } return(Json(JsonConvert.DeserializeObject <AnimeJson>(cachedAnime))); }
public async Task <IActionResult> Get([RequiredFromQuery] int page, [FromQuery] int limit, [FromQuery] int minimum_rating, [FromQuery] string query_term, [FromQuery] string genre, [FromQuery] string sort_by) { var nbShowsPerPage = 20; if (limit >= 20 && limit <= 50) { nbShowsPerPage = limit; } var currentPage = 1; if (page >= 1) { currentPage = page; } var queryTerm = string.Empty; if (!string.IsNullOrWhiteSpace(query_term)) { queryTerm = query_term; } var genreFilter = string.Empty; if (!string.IsNullOrWhiteSpace(genre)) { genreFilter = genre; } var hash = Convert.ToBase64String( Encoding.UTF8.GetBytes( $@"type=shows&page={page}&limit={limit}&minimum_rating={minimum_rating}&query_term={ query_term }&genre={genre}&sort_by={sort_by}")); try { var cachedShows = await _cachingService.GetCache(hash); if (cachedShows != null) { try { return(Json(JsonConvert.DeserializeObject <ShowLightResponse>(cachedShows))); } catch (Exception ex) { _loggingService.Telemetry.TrackException(ex); } } } catch (Exception ex) { _loggingService.Telemetry.TrackException(ex); } using (var context = new PopcornContextFactory().CreateDbContext(new string[0])) { var skipParameter = new SqlParameter("@skip", (currentPage - 1) * nbShowsPerPage); var takeParameter = new SqlParameter("@take", nbShowsPerPage); var ratingParameter = new SqlParameter("@rating", minimum_rating); var queryParameter = new SqlParameter("@Keywords", queryTerm); var genreParameter = new SqlParameter("@genre", genreFilter); var query = @" SELECT Show.Title, Show.Year, Rating.Percentage, Rating.Loved, Rating.Votes, Rating.Hated, Rating.Watching, Show.LastUpdated, Image.Banner, Image.Fanart, Image.Poster, Show.ImdbId, Show.TvdbId, Show.GenreNames, COUNT(*) OVER () as TotalCount FROM ShowSet AS Show INNER JOIN ImageShowSet AS Image ON Image.Id = Show.ImagesId INNER JOIN RatingSet AS Rating ON Rating.Id = Show.RatingId WHERE 1 = 1"; if (minimum_rating > 0 && minimum_rating < 10) { query += @" AND Rating >= @rating"; } if (!string.IsNullOrWhiteSpace(query_term)) { query += @" AND FREETEXT(Title, @Keywords)"; } if (!string.IsNullOrWhiteSpace(genre)) { query += @" AND CONTAINS(GenreNames, @genre)"; } if (!string.IsNullOrWhiteSpace(sort_by)) { switch (sort_by) { case "title": query += " ORDER BY Show.Title ASC"; break; case "year": query += " ORDER BY Show.Year DESC"; break; case "rating": query += " ORDER BY Rating.Percentage DESC"; break; case "loved": query += " ORDER BY Rating.Loved DESC"; break; case "votes": query += " ORDER BY Rating.Votes DESC"; break; case "watching": query += " ORDER BY Rating.Watching DESC"; break; case "date_added": query += " ORDER BY Show.LastUpdated DESC"; break; default: query += " ORDER BY Show.LastUpdated DESC"; break; } } else { query += " ORDER BY Show.LastUpdated DESC"; } query += @" OFFSET @skip ROWS FETCH NEXT @take ROWS ONLY"; var showsQuery = await context.Database.ExecuteSqlQueryAsync(query, new CancellationToken(), skipParameter, takeParameter, ratingParameter, queryParameter, genreParameter); var reader = showsQuery.DbDataReader; var count = 0; var shows = new List <ShowLightJson>(); while (await reader.ReadAsync()) { var show = new ShowLightJson { Title = reader[0].GetType() != typeof(DBNull) ? (string)reader[0] : string.Empty, Year = reader[1].GetType() != typeof(DBNull) ? (int)reader[1] : 0, Rating = new RatingJson { Percentage = reader[2].GetType() != typeof(DBNull) ? (int)reader[2] : 0, Loved = reader[3].GetType() != typeof(DBNull) ? (int)reader[3] : 0, Votes = reader[4].GetType() != typeof(DBNull) ? (int)reader[4] : 0, Hated = reader[5].GetType() != typeof(DBNull) ? (int)reader[5] : 0, Watching = reader[6].GetType() != typeof(DBNull) ? (int)reader[6] : 0 }, Images = new ImageShowJson { Banner = reader[8].GetType() != typeof(DBNull) ? (string)reader[8] : string.Empty, Fanart = reader[9].GetType() != typeof(DBNull) ? (string)reader[9] : string.Empty, Poster = reader[10].GetType() != typeof(DBNull) ? (string)reader[10] : string.Empty, }, ImdbId = reader[11].GetType() != typeof(DBNull) ? (string)reader[11] : string.Empty, TvdbId = reader[12].GetType() != typeof(DBNull) ? (string)reader[12] : string.Empty, Genres = reader[13].GetType() != typeof(DBNull) ? (string)reader[13] : string.Empty }; shows.Add(show); count = reader[14].GetType() != typeof(DBNull) ? (int)reader[14] : 0; } var response = new ShowLightResponse { TotalShows = count, Shows = shows }; await _cachingService.SetCache(hash, JsonConvert.SerializeObject(response), TimeSpan.FromDays(1)); return (Json(response)); } }
/// <summary> /// Import movies to database /// </summary> /// <param name="docs">Documents to import</param> /// <returns><see cref="Task"/></returns> public async Task Import(IEnumerable <BsonDocument> docs) { var documents = docs.ToList(); var loggingTraceBegin = $@"Import {documents.Count} movies started at { DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss.fff", CultureInfo.InvariantCulture) }"; _loggingService.Telemetry.TrackTrace(loggingTraceBegin); var updatedMovies = 0; using (var context = new PopcornContextFactory().CreateDbContext(new string[0])) { foreach (var document in documents) { try { var watch = new Stopwatch(); watch.Start(); // Deserialize a document to a movie var movieJson = BsonSerializer.Deserialize <MovieBson>(document); var movie = new Movie { ImdbCode = movieJson.ImdbCode, Url = movieJson.Url, Torrents = movieJson.Torrents.Select(torrent => new TorrentMovie { Url = torrent.Url, DateUploaded = torrent.DateUploaded, DateUploadedUnix = torrent.DateUploadedUnix, Quality = torrent.Quality, Hash = torrent.Hash, Peers = torrent.Peers, Seeds = torrent.Seeds, Size = torrent.Size, SizeBytes = torrent.SizeBytes }).ToList(), DateUploaded = movieJson.DateUploaded, DateUploadedUnix = movieJson.DateUploadedUnix, DownloadCount = movieJson.DownloadCount, MpaRating = movieJson.MpaRating, Runtime = movieJson.Runtime, YtTrailerCode = movieJson.YtTrailerCode, DescriptionIntro = movieJson.DescriptionIntro, TitleLong = movieJson.TitleLong, Rating = movieJson.Rating, Year = movieJson.Year, LikeCount = movieJson.LikeCount, DescriptionFull = movieJson.DescriptionFull, Cast = movieJson.Cast?.Select(cast => new Database.Cast { ImdbCode = cast?.ImdbCode, SmallImage = cast?.SmallImage, CharacterName = cast?.CharacterName, Name = cast?.Name }).ToList(), Genres = movieJson.Genres.Select(genre => new Genre { Name = genre }).ToList(), GenreNames = string.Join(", ", movieJson.Genres.Select(FirstCharToUpper)), Language = movieJson.Language, Slug = movieJson.Slug, Title = movieJson.Title, BackgroundImage = movieJson.BackgroundImage, PosterImage = movieJson.PosterImage }; if (!context.MovieSet.Any(a => a.ImdbCode == movie.ImdbCode)) { await RetrieveAssets(movie).ConfigureAwait(false); context.MovieSet.Add(movie); await context.SaveChangesAsync().ConfigureAwait(false); } else { var existingEntity = await context.MovieSet.Include(a => a.Torrents) .FirstOrDefaultAsync(a => a.ImdbCode == movie.ImdbCode).ConfigureAwait(false); existingEntity.DownloadCount = movie.DownloadCount; existingEntity.LikeCount = movie.LikeCount; existingEntity.Rating = movie.Rating; foreach (var torrent in existingEntity.Torrents) { var updatedTorrent = movie.Torrents.FirstOrDefault(a => a.Quality == torrent.Quality); if (updatedTorrent == null) { continue; } torrent.Peers = updatedTorrent.Peers; torrent.Seeds = updatedTorrent.Seeds; } await context.SaveChangesAsync().ConfigureAwait(false); } watch.Stop(); updatedMovies++; Console.WriteLine(Environment.NewLine); Console.WriteLine( $"{DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss.fff", CultureInfo.InvariantCulture)} UPDATED MOVIE {movie.Title} in {watch.ElapsedMilliseconds} ms. {updatedMovies}/{documents.Count}"); } catch (Exception ex) { _loggingService.Telemetry.TrackException(ex); } } } // Finish Console.WriteLine(Environment.NewLine); Console.WriteLine("Done processing movies."); var loggingTraceEnd = $@"Import movies ended at { DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss.fff", CultureInfo.InvariantCulture) }"; _loggingService.Telemetry.TrackTrace(loggingTraceEnd); }
public async Task <IActionResult> GetLight(string imdb) { var hash = Convert.ToBase64String( Encoding.UTF8.GetBytes($"light:{imdb}")); try { var cachedShow = await _cachingService.GetCache(hash); if (cachedShow != null) { try { return(Json(JsonConvert.DeserializeObject <ShowLightJson>(cachedShow))); } catch (Exception ex) { _loggingService.Telemetry.TrackException(ex); } } } catch (Exception ex) { _loggingService.Telemetry.TrackException(ex); } using (var context = new PopcornContextFactory().CreateDbContext(new string[0])) { var imdbParameter = new SqlParameter("@imdbId", imdb); var query = @" SELECT Show.Title, Show.Year, Rating.Percentage, Rating.Loved, Rating.Votes, Rating.Hated, Rating.Watching, Show.LastUpdated, Image.Banner, Image.Fanart, Image.Poster, Show.ImdbId, Show.TvdbId, Show.GenreNames FROM ShowSet AS Show INNER JOIN ImageShowSet AS Image ON Image.Id = Show.ImagesId INNER JOIN RatingSet AS Rating ON Rating.Id = Show.RatingId WHERE Show.ImdbId = @imdbId"; var showQuery = await context.Database.ExecuteSqlQueryAsync(query, new CancellationToken(), imdbParameter); var reader = showQuery.DbDataReader; var show = new ShowLightJson(); while (await reader.ReadAsync()) { show.Title = reader[0].GetType() != typeof(DBNull) ? (string)reader[0] : string.Empty; show.Year = reader[1].GetType() != typeof(DBNull) ? (int)reader[1] : 0; show.Rating = new RatingJson { Percentage = reader[2].GetType() != typeof(DBNull) ? (int)reader[2] : 0, Loved = reader[3].GetType() != typeof(DBNull) ? (int)reader[3] : 0, Votes = reader[4].GetType() != typeof(DBNull) ? (int)reader[4] : 0, Hated = reader[5].GetType() != typeof(DBNull) ? (int)reader[5] : 0, Watching = reader[6].GetType() != typeof(DBNull) ? (int)reader[6] : 0 }; show.Images = new ImageShowJson { Banner = reader[8].GetType() != typeof(DBNull) ? (string)reader[8] : string.Empty, Fanart = reader[9].GetType() != typeof(DBNull) ? (string)reader[9] : string.Empty, Poster = reader[10].GetType() != typeof(DBNull) ? (string)reader[10] : string.Empty }; show.ImdbId = reader[11].GetType() != typeof(DBNull) ? (string)reader[11] : string.Empty; show.TvdbId = reader[12].GetType() != typeof(DBNull) ? (string)reader[12] : string.Empty; show.Genres = reader[13].GetType() != typeof(DBNull) ? (string)reader[13] : string.Empty; } if (string.IsNullOrEmpty(show.ImdbId)) { return(BadRequest()); } await _cachingService.SetCache(hash, JsonConvert.SerializeObject(show)); return(Json(show)); } }
public async Task <IActionResult> Get([RequiredFromQuery] int page, [FromQuery] int limit, [FromQuery] int minimum_rating, [FromQuery] string query_term, [FromQuery] string genre, [FromQuery] string sort_by) { var nbMoviesPerPage = 20; if (limit >= 20 && limit <= 50) { nbMoviesPerPage = limit; } var currentPage = 1; if (page >= 1) { currentPage = page; } using (var context = new PopcornContextFactory().Create(new DbContextFactoryOptions())) { var query = context.MovieSet.Include(movie => movie.Torrents) .Include(movie => movie.Cast) .Include(movie => movie.Similars) .Include(movie => movie.Genres) .AsQueryable(); if (minimum_rating > 0 && minimum_rating < 10) { query = query.Where(movie => movie.Rating > minimum_rating); } if (!string.IsNullOrWhiteSpace(query_term)) { query = query.Where( movie => movie.Title.ToLower().Contains(query_term.ToLower())); } if (!string.IsNullOrWhiteSpace(genre)) { query = query.Where(movie => movie.Genres.Any(a => a.Name.ToLower().Contains(genre.ToLower()))); } if (!string.IsNullOrWhiteSpace(sort_by)) { switch (sort_by) { case "title": query = query.OrderBy(movie => movie.Title); break; case "year": query = query.OrderByDescending(movie => movie.Year); break; case "rating": query = query.OrderByDescending(movie => movie.Rating); break; case "peers": query = query.OrderByDescending( movie => movie.Torrents.Max(torrent => torrent.Peers)); break; case "seeds": query = query.OrderByDescending( movie => movie.Torrents.Max(torrent => torrent.Seeds)); break; case "download_count": query = query.OrderByDescending(movie => movie.DownloadCount); break; case "like_count": query = query.OrderByDescending(movie => movie.LikeCount); break; case "date_added": query = query.OrderByDescending(movie => movie.DateUploadedUnix); break; } } else { query = query.OrderByDescending(movie => movie.DateUploadedUnix); } var count = query.Count(); var skip = (currentPage - 1) * nbMoviesPerPage; if (count <= nbMoviesPerPage) { skip = 0; } var movies = query.Skip(skip).Take(nbMoviesPerPage).ToList(); return (Json(new MovieResponse { TotalMovies = count, Movies = movies.Select(ConvertMovieToJson) })); } }
public async Task <IActionResult> Get([RequiredFromQuery] int page, [FromQuery] int limit, [FromQuery] int minimum_rating, [FromQuery] string query_term, [FromQuery] string genre, [FromQuery] string sort_by) { var nbMoviesPerPage = 20; if (limit >= 20 && limit <= 50) { nbMoviesPerPage = limit; } var currentPage = 1; if (page >= 1) { currentPage = page; } var queryTerm = string.Empty; if (!string.IsNullOrWhiteSpace(query_term)) { queryTerm = query_term; } var genreFilter = string.Empty; if (!string.IsNullOrWhiteSpace(genre)) { genreFilter = genre; } var hash = Convert.ToBase64String( Encoding.UTF8.GetBytes( $@"type=movies&page={page}&limit={limit}&minimum_rating={minimum_rating}&query_term={ query_term }&genre={genre}&sort_by={sort_by}")); try { var cachedMovies = await _cachingService.GetCache(hash); if (cachedMovies != null) { try { return(Json(JsonConvert.DeserializeObject <MovieLightResponse>(cachedMovies))); } catch (Exception ex) { _loggingService.Telemetry.TrackException(ex); } } } catch (Exception ex) { _loggingService.Telemetry.TrackException(ex); } using (var context = new PopcornContextFactory().CreateDbContext(new string[0])) { var skipParameter = new SqlParameter("@skip", (currentPage - 1) * nbMoviesPerPage); var takeParameter = new SqlParameter("@take", nbMoviesPerPage); var ratingParameter = new SqlParameter("@rating", minimum_rating); var queryParameter = new SqlParameter("@Keywords", queryTerm); var genreParameter = new SqlParameter("@genre", genreFilter); var query = @" SELECT Movie.Title, Movie.Year, Movie.Rating, Movie.PosterImage, Movie.ImdbCode, Movie.GenreNames, Torrent.Peers, Torrent.Seeds, COUNT(*) OVER () as TotalCount FROM MovieSet AS Movie INNER JOIN TorrentMovieSet AS Torrent ON Torrent.MovieId = Movie.Id AND Torrent.Quality = '720p' WHERE 1 = 1"; if (minimum_rating > 0 && minimum_rating < 10) { query += @" AND Rating >= @rating"; } if (!string.IsNullOrWhiteSpace(query_term)) { query += @" AND FREETEXT(Title, @Keywords)"; } if (!string.IsNullOrWhiteSpace(genre)) { query += @" AND CONTAINS(GenreNames, @genre)"; } if (!string.IsNullOrWhiteSpace(sort_by)) { switch (sort_by) { case "title": query += " ORDER BY Movie.Title ASC"; break; case "year": query += " ORDER BY Movie.Year DESC"; break; case "rating": query += " ORDER BY Movie.Rating DESC"; break; case "peers": query += " ORDER BY Torrent.Peers DESC"; break; case "seeds": query += " ORDER BY Torrent.Seeds DESC"; break; case "download_count": query += " ORDER BY Movie.DownloadCount DESC"; break; case "like_count": query += " ORDER BY Movie.LikeCount DESC"; break; case "date_added": query += " ORDER BY Movie.DateUploadedUnix DESC"; break; default: query += " ORDER BY Movie.DateUploadedUnix DESC"; break; } } else { query += " ORDER BY Movie.DateUploadedUnix DESC"; } query += @" OFFSET @skip ROWS FETCH NEXT @take ROWS ONLY"; var moviesQuery = await context.Database.ExecuteSqlQueryAsync(query, new CancellationToken(), skipParameter, takeParameter, ratingParameter, queryParameter, genreParameter); var reader = moviesQuery.DbDataReader; var count = 0; var movies = new List <MovieLightJson>(); while (await reader.ReadAsync()) { var movie = new MovieLightJson { Title = reader[0].GetType() != typeof(DBNull) ? (string)reader[0] : string.Empty, Year = reader[1].GetType() != typeof(DBNull) ? (int)reader[1] : 0, Rating = reader[2].GetType() != typeof(DBNull) ? (double)reader[2] : 0d, PosterImage = reader[3].GetType() != typeof(DBNull) ? (string)reader[3] : string.Empty, ImdbCode = reader[4].GetType() != typeof(DBNull) ? (string)reader[4] : string.Empty, Genres = reader[5].GetType() != typeof(DBNull) ? (string)reader[5] : string.Empty }; movies.Add(movie); count = reader[8].GetType() != typeof(DBNull) ? (int)reader[8] : 0; } var response = new MovieLightResponse { TotalMovies = count, Movies = movies }; await _cachingService.SetCache(hash, JsonConvert.SerializeObject(response), TimeSpan.FromDays(1)); return (Json(response)); } }
public async Task <IActionResult> GetShowByIds([FromBody] IEnumerable <string> imdbIds) { if (!imdbIds.Any()) { return(Json(new ShowLightResponse { Shows = new List <ShowLightJson>(), TotalShows = 0 })); } var hash = Convert.ToBase64String( Encoding.UTF8.GetBytes( $@"type=shows&imdbIds={string.Join(',', imdbIds)}")); try { var cachedShow = await _cachingService.GetCache(hash); if (cachedShow != null) { try { return(Content(cachedShow, "application/json")); } catch (Exception ex) { _loggingService.Telemetry.TrackException(ex); } } } catch (Exception ex) { _loggingService.Telemetry.TrackException(ex); } using (var context = new PopcornContextFactory().CreateDbContext(new string[0])) { var query = @" SELECT DISTINCT Show.Title, Show.Year, Rating.Percentage, Rating.Loved, Rating.Votes, Rating.Hated, Rating.Watching, Show.LastUpdated, Image.Banner, Image.Poster, Show.ImdbId, Show.TvdbId, Show.GenreNames, COUNT(*) OVER () as TotalCount FROM ShowSet AS Show INNER JOIN ImageShowSet AS Image ON Image.Id = Show.ImagesId INNER JOIN RatingSet AS Rating ON Rating.Id = Show.RatingId WHERE Show.ImdbId IN ({@imdbIds})"; using (var cmd = new SqlCommand(query, new SqlConnection(context.Database.GetDbConnection().ConnectionString))) { cmd.AddArrayParameters(imdbIds, "@imdbIds"); await cmd.Connection.OpenAsync(); var reader = await cmd.ExecuteReaderAsync(new CancellationToken()); var count = 0; var shows = new List <ShowLightJson>(); while (await reader.ReadAsync()) { var show = new ShowLightJson { Title = !await reader.IsDBNullAsync(0) ? reader.GetString(0) : string.Empty, Year = !await reader.IsDBNullAsync(1) ? reader.GetInt32(1) : 0, Rating = new RatingJson { Percentage = !await reader.IsDBNullAsync(2) ? reader.GetInt32(2) : 0, Loved = !await reader.IsDBNullAsync(3) ? reader.GetInt32(3) : 0, Votes = !await reader.IsDBNullAsync(4) ? reader.GetInt32(4) : 0, Hated = !await reader.IsDBNullAsync(5) ? reader.GetInt32(5) : 0, Watching = !await reader.IsDBNullAsync(6) ? reader.GetInt32(6) : 0 }, Images = new ImageShowJson { Banner = !await reader.IsDBNullAsync(8) ? reader.GetString(8) : string.Empty, Poster = !await reader.IsDBNullAsync(9) ? reader.GetString(9) : string.Empty, }, ImdbId = !await reader.IsDBNullAsync(10) ? reader.GetString(10) : string.Empty, TvdbId = !await reader.IsDBNullAsync(11) ? reader.GetString(11) : string.Empty, Genres = !await reader.IsDBNullAsync(12) ? reader.GetString(12) : string.Empty }; shows.Add(show); count = !await reader.IsDBNullAsync(13) ? reader.GetInt32(13) : 0; } var response = new ShowLightResponse { TotalShows = count, Shows = shows }; var json = JsonSerializer.ToJsonString(response, StandardResolver.SnakeCase); await _cachingService.SetCache(hash, json, TimeSpan.FromDays(1)); return(Content(json, "application /json")); } } }
public async Task <IActionResult> GetLight(string imdb) { var hash = Convert.ToBase64String( Encoding.UTF8.GetBytes($"light:{imdb}")); try { var cachedMovie = await _cachingService.GetCache(hash); if (cachedMovie != null) { try { return(Json(JsonConvert.DeserializeObject <MovieLightJson>(cachedMovie))); } catch (Exception ex) { _loggingService.Telemetry.TrackException(ex); } } } catch (Exception ex) { _loggingService.Telemetry.TrackException(ex); } using (var context = new PopcornContextFactory().CreateDbContext(new string[0])) { var imdbParameter = new SqlParameter("@imdbCode", imdb); var query = @" SELECT Movie.Title, Movie.Year, Movie.Rating, Movie.PosterImage, Movie.ImdbCode, Movie.GenreNames FROM MovieSet AS Movie WHERE Movie.ImdbCode = @imdbCode"; var movieQuery = await context.Database.ExecuteSqlQueryAsync(query, new CancellationToken(), imdbParameter); var reader = movieQuery.DbDataReader; var movie = new MovieLightJson(); while (await reader.ReadAsync()) { movie.Title = reader[0].GetType() != typeof(DBNull) ? (string)reader[0] : string.Empty; movie.Year = reader[1].GetType() != typeof(DBNull) ? (int)reader[1] : 0; movie.Rating = reader[2].GetType() != typeof(DBNull) ? (double)reader[2] : 0d; movie.PosterImage = reader[3].GetType() != typeof(DBNull) ? (string)reader[3] : string.Empty; movie.ImdbCode = reader[4].GetType() != typeof(DBNull) ? (string)reader[4] : string.Empty; movie.Genres = reader[5].GetType() != typeof(DBNull) ? (string)reader[5] : string.Empty; } if (string.IsNullOrEmpty(movie.ImdbCode)) { return(BadRequest()); } await _cachingService.SetCache(hash, JsonConvert.SerializeObject(movie)); return(Json(movie)); } }
public async Task <IActionResult> Get([RequiredFromQuery] int page, [FromQuery] int limit, [FromQuery] int minimum_rating, [FromQuery] string query_term, [FromQuery] string genre, [FromQuery] string sort_by) { var nbMoviesPerPage = 20; if (limit >= 20 && limit <= 50) { nbMoviesPerPage = limit; } var currentPage = 1; if (page >= 1) { currentPage = page; } var queryTerm = string.Empty; if (!string.IsNullOrWhiteSpace(query_term)) { queryTerm = query_term; } var genreFilter = string.Empty; if (!string.IsNullOrWhiteSpace(genre)) { genreFilter = genre; } var hash = Convert.ToBase64String( Encoding.UTF8.GetBytes( $@"type=movies&page={page}&limit={limit}&minimum_rating={minimum_rating}&query_term={ query_term }&genre={genre}&sort_by={sort_by}")); try { var cachedMovies = await _cachingService.GetCache(hash); if (cachedMovies != null) { try { return(Content(cachedMovies, "application/json")); } catch (Exception ex) { _loggingService.Telemetry.TrackException(ex); } } } catch (Exception ex) { _loggingService.Telemetry.TrackException(ex); } using (var context = new PopcornContextFactory().CreateDbContext(new string[0])) { var skipParameter = new SqlParameter("@skip", (currentPage - 1) * nbMoviesPerPage); var takeParameter = new SqlParameter("@take", nbMoviesPerPage); var ratingParameter = new SqlParameter("@rating", minimum_rating); var queryParameter = new SqlParameter("@Keywords", string.Format(@"""{0}""", queryTerm)); var genreParameter = new SqlParameter("@genre", genreFilter); var query = @" SELECT DISTINCT Movie.Title, Movie.Year, Movie.Rating, Movie.PosterImage, Movie.ImdbCode, Movie.GenreNames, Torrent.Peers, Torrent.Seeds, COUNT(*) OVER () as TotalCount, Movie.DateUploadedUnix, Movie.Id, Movie.DownloadCount, Movie.LikeCount FROM MovieSet AS Movie CROSS APPLY ( SELECT TOP 1 Torrent.MovieId, Torrent.Peers, Torrent.Seeds FROM TorrentMovieSet AS Torrent WHERE Torrent.MovieId = Movie.Id AND Torrent.Url <> '' AND Torrent.Url IS NOT NULL ) Torrent INNER JOIN CastSet AS Cast ON Cast.MovieId = Movie.Id WHERE 1 = 1"; if (minimum_rating > 0 && minimum_rating < 10) { query += @" AND Rating >= @rating"; } if (!string.IsNullOrWhiteSpace(query_term)) { query += @" AND (CONTAINS(Movie.Title, @Keywords) OR CONTAINS(Cast.Name, @Keywords) OR CONTAINS(Movie.ImdbCode, @Keywords) OR CONTAINS(Cast.ImdbCode, @Keywords))"; } if (!string.IsNullOrWhiteSpace(genre)) { query += @" AND CONTAINS(Movie.GenreNames, @genre)"; } query += " GROUP BY Movie.Id, Movie.Title, Movie.Year, Movie.Rating, Movie.PosterImage, Movie.ImdbCode, Movie.GenreNames, Torrent.Peers, Torrent.Seeds, Movie.DateUploadedUnix, Movie.Id, Movie.DownloadCount, Movie.LikeCount"; if (!string.IsNullOrWhiteSpace(sort_by)) { switch (sort_by) { case "title": query += " ORDER BY Movie.Title ASC"; break; case "year": query += " ORDER BY Movie.Year DESC"; break; case "rating": query += " ORDER BY Movie.Rating DESC"; break; case "peers": query += " ORDER BY Torrent.Peers DESC"; break; case "seeds": query += " ORDER BY Torrent.Seeds DESC"; break; case "download_count": query += " ORDER BY Movie.DownloadCount DESC"; break; case "like_count": query += " ORDER BY Movie.LikeCount DESC"; break; case "date_added": query += " ORDER BY Movie.DateUploadedUnix DESC"; break; default: query += " ORDER BY Movie.DateUploadedUnix DESC"; break; } } else { query += " ORDER BY Movie.DateUploadedUnix DESC"; } query += @" OFFSET @skip ROWS FETCH NEXT @take ROWS ONLY"; var moviesQuery = await context.Database.ExecuteSqlQueryAsync(query, new CancellationToken(), skipParameter, takeParameter, ratingParameter, queryParameter, genreParameter); var reader = moviesQuery.DbDataReader; var count = 0; var movies = new List <MovieLightJson>(); while (await reader.ReadAsync()) { var movie = new MovieLightJson { Title = !await reader.IsDBNullAsync(0) ? reader.GetString(0) : string.Empty, Year = !await reader.IsDBNullAsync(1) ? reader.GetInt32(1) : 0, Rating = !await reader.IsDBNullAsync(2) ? reader.GetDouble(2) : 0d, PosterImage = !await reader.IsDBNullAsync(3) ? reader.GetString(3) : string.Empty, ImdbCode = !await reader.IsDBNullAsync(4) ? reader.GetString(4) : string.Empty, Genres = !await reader.IsDBNullAsync(5) ? reader.GetString(5) : string.Empty }; movies.Add(movie); count = !await reader.IsDBNullAsync(8) ? reader.GetInt32(8) : 0; } var response = new MovieLightResponse { TotalMovies = count, Movies = movies }; var json = JsonSerializer.ToJsonString(response, StandardResolver.SnakeCase); await _cachingService.SetCache(hash, json, TimeSpan.FromDays(1)); return(Content(json, "application/json")); } }
public async Task <IActionResult> GetFromCast(string castId) { var hash = Convert.ToBase64String( Encoding.UTF8.GetBytes($"cast:{castId}")); try { var cachedMovie = await _cachingService.GetCache(hash); if (cachedMovie != null) { try { return(Content(cachedMovie, "application/json")); } catch (Exception ex) { _loggingService.Telemetry.TrackException(ex); } } } catch (Exception ex) { _loggingService.Telemetry.TrackException(ex); } using (var context = new PopcornContextFactory().CreateDbContext(new string[0])) { var imdbParameter = new SqlParameter("@imdbCode", castId); var query = @" SELECT Movie.Title, Movie.Year, Movie.Rating, Movie.PosterImage, Movie.ImdbCode, Movie.GenreNames FROM MovieSet AS Movie INNER JOIN CastSet AS Cast ON Cast.MovieId = Movie.Id WHERE Cast.ImdbCode = @imdbCode"; var movieQuery = await context.Database.ExecuteSqlQueryAsync(query, new CancellationToken(), imdbParameter); var reader = movieQuery.DbDataReader; var movies = new List <MovieLightJson>(); while (await reader.ReadAsync()) { var movie = new MovieLightJson { Title = !await reader.IsDBNullAsync(0) ? reader.GetString(0) : string.Empty, Year = !await reader.IsDBNullAsync(1) ? reader.GetInt32(1) : 0, Rating = !await reader.IsDBNullAsync(2) ? reader.GetDouble(2) : 0d, PosterImage = !await reader.IsDBNullAsync(3) ? reader.GetString(3) : string.Empty, ImdbCode = !await reader.IsDBNullAsync(4) ? reader.GetString(4) : string.Empty, Genres = !await reader.IsDBNullAsync(5) ? reader.GetString(5) : string.Empty }; movies.Add(movie); } var response = new MovieLightResponse { TotalMovies = movies.Count, Movies = movies }; var json = JsonSerializer.ToJsonString(response, StandardResolver.SnakeCase); await _cachingService.SetCache(hash, json, TimeSpan.FromDays(1)); return(Content(json, "application/json")); } }
public async Task <IActionResult> GetMoviesByIds([FromBody] IEnumerable <string> imdbIds) { if (!imdbIds.Any()) { return(Json(new MovieLightResponse { Movies = new List <MovieLightJson>(), TotalMovies = 0 })); } var hash = Convert.ToBase64String( Encoding.UTF8.GetBytes( $@"type=movies&imdbIds={string.Join(',', imdbIds)}")); try { var cachedMovies = await _cachingService.GetCache(hash); if (cachedMovies != null) { try { return(Content(cachedMovies, "application/json")); } catch (Exception ex) { _loggingService.Telemetry.TrackException(ex); } } } catch (Exception ex) { _loggingService.Telemetry.TrackException(ex); } using (var context = new PopcornContextFactory().CreateDbContext(new string[0])) { var query = @" SELECT DISTINCT Movie.Title, Movie.Year, Movie.Rating, Movie.PosterImage, Movie.ImdbCode, Movie.GenreNames, COUNT(*) OVER () as TotalCount FROM MovieSet AS Movie WHERE Movie.ImdbCode IN ({@imdbIds}) ORDER BY Movie.Rating DESC"; using (var cmd = new SqlCommand(query, new SqlConnection(context.Database.GetDbConnection().ConnectionString))) { cmd.AddArrayParameters(imdbIds, "@imdbIds"); await cmd.Connection.OpenAsync(); var reader = await cmd.ExecuteReaderAsync(new CancellationToken()); var count = 0; var movies = new List <MovieLightJson>(); while (await reader.ReadAsync()) { var movie = new MovieLightJson { Title = !await reader.IsDBNullAsync(0) ? reader.GetString(0) : string.Empty, Year = !await reader.IsDBNullAsync(1) ? reader.GetInt32(1) : 0, Rating = !await reader.IsDBNullAsync(2) ? reader.GetDouble(2) : 0d, PosterImage = !await reader.IsDBNullAsync(3) ? reader.GetString(3) : string.Empty, ImdbCode = !await reader.IsDBNullAsync(4) ? reader.GetString(4) : string.Empty, Genres = !await reader.IsDBNullAsync(5) ? reader.GetString(5) : string.Empty }; movies.Add(movie); count = !await reader.IsDBNullAsync(6) ? reader.GetInt32(6) : 0; } var response = new MovieLightResponse { TotalMovies = count, Movies = movies }; var json = JsonSerializer.ToJsonString(response, StandardResolver.SnakeCase); await _cachingService.SetCache(hash, json, TimeSpan.FromDays(1)); return(Content(json, "application/json")); } } }
public async Task <IActionResult> Get([RequiredFromQuery] int page, [FromQuery] int limit, [FromQuery] int minimum_rating, [FromQuery] string query_term, [FromQuery] string genre, [FromQuery] string sort_by) { var nbShowsPerPage = 20; if (limit >= 20 && limit <= 50) { nbShowsPerPage = limit; } var currentPage = 1; if (page >= 1) { currentPage = page; } var queryTerm = string.Empty; if (!string.IsNullOrWhiteSpace(query_term)) { queryTerm = query_term; } var genreFilter = string.Empty; if (!string.IsNullOrWhiteSpace(genre)) { genreFilter = genre; } var hash = Convert.ToBase64String( Encoding.UTF8.GetBytes( $@"type=shows&page={page}&limit={limit}&minimum_rating={minimum_rating}&query_term={ query_term }&genre={genre}&sort_by={sort_by}")); try { var cachedShows = await _cachingService.GetCache(hash); if (cachedShows != null) { try { return(Content(cachedShows, "application/json")); } catch (Exception ex) { _loggingService.Telemetry.TrackException(ex); } } } catch (Exception ex) { _loggingService.Telemetry.TrackException(ex); } using (var context = new PopcornContextFactory().CreateDbContext(new string[0])) { var skipParameter = new SqlParameter("@skip", (currentPage - 1) * nbShowsPerPage); var takeParameter = new SqlParameter("@take", nbShowsPerPage); var ratingParameter = new SqlParameter("@rating", minimum_rating); var queryParameter = new SqlParameter("@Keywords", string.Format(@"""{0}""", queryTerm)); var genreParameter = new SqlParameter("@genre", genreFilter); var query = @" SELECT Show.Title, Show.Year, Rating.Percentage, Rating.Loved, Rating.Votes, Rating.Hated, Rating.Watching, Show.LastUpdated, Image.Banner, Image.Poster, Show.ImdbId, Show.TvdbId, Show.GenreNames, COUNT(*) OVER () as TotalCount FROM ShowSet AS Show INNER JOIN ImageShowSet AS Image ON Image.Id = Show.ImagesId INNER JOIN RatingSet AS Rating ON Rating.Id = Show.RatingId WHERE Show.NumSeasons <> 0"; if (minimum_rating > 0 && minimum_rating < 10) { query += @" AND Rating >= @rating"; } if (!string.IsNullOrWhiteSpace(query_term)) { query += @" AND (CONTAINS(Title, @Keywords) OR CONTAINS(ImdbId, @Keywords) OR CONTAINS(TvdbId, @Keywords))"; } if (!string.IsNullOrWhiteSpace(genre)) { query += @" AND CONTAINS(GenreNames, @genre)"; } if (!string.IsNullOrWhiteSpace(sort_by)) { switch (sort_by) { case "title": query += " ORDER BY Show.Title ASC"; break; case "year": query += " ORDER BY Show.Year DESC"; break; case "rating": query += " ORDER BY Rating.Percentage DESC"; break; case "loved": query += " ORDER BY Rating.Loved DESC"; break; case "votes": query += " ORDER BY Rating.Votes DESC"; break; case "watching": query += " ORDER BY Rating.Watching DESC"; break; case "date_added": query += " ORDER BY Show.LastUpdated DESC"; break; default: query += " ORDER BY Show.LastUpdated DESC"; break; } } else { query += " ORDER BY Show.LastUpdated DESC"; } query += @" OFFSET @skip ROWS FETCH NEXT @take ROWS ONLY"; var showsQuery = await context.Database.ExecuteSqlQueryAsync(query, new CancellationToken(), skipParameter, takeParameter, ratingParameter, queryParameter, genreParameter); var reader = showsQuery.DbDataReader; var count = 0; var shows = new List <ShowLightJson>(); while (await reader.ReadAsync()) { var show = new ShowLightJson { Title = !await reader.IsDBNullAsync(0) ? reader.GetString(0) : string.Empty, Year = !await reader.IsDBNullAsync(1) ? reader.GetInt32(1) : 0, Rating = new RatingJson { Percentage = !await reader.IsDBNullAsync(2) ? reader.GetInt32(2) : 0, Loved = !await reader.IsDBNullAsync(3) ? reader.GetInt32(3) : 0, Votes = !await reader.IsDBNullAsync(4) ? reader.GetInt32(4) : 0, Hated = !await reader.IsDBNullAsync(5) ? reader.GetInt32(5) : 0, Watching = !await reader.IsDBNullAsync(6) ? reader.GetInt32(6) : 0 }, Images = new ImageShowJson { Banner = !await reader.IsDBNullAsync(8) ? reader.GetString(8) : string.Empty, Poster = !await reader.IsDBNullAsync(9) ? reader.GetString(9) : string.Empty, }, ImdbId = !await reader.IsDBNullAsync(10) ? reader.GetString(10) : string.Empty, TvdbId = !await reader.IsDBNullAsync(11) ? reader.GetString(11) : string.Empty, Genres = !await reader.IsDBNullAsync(12) ? reader.GetString(12) : string.Empty }; shows.Add(show); count = !await reader.IsDBNullAsync(13) ? reader.GetInt32(13) : 0; } var response = new ShowLightResponse { TotalShows = count, Shows = shows }; var json = JsonSerializer.ToJsonString(response, StandardResolver.SnakeCase); await _cachingService.SetCache(hash, json, TimeSpan.FromDays(1)); return(Content(json, "application/json")); } }
/// <summary> /// Import shows to database /// </summary> /// <param name="rawImports">Imports to import</param> /// <param name="pbar"><see cref="IProgressBar"/></param> /// <returns><see cref="Task"/></returns> public async Task Import(IEnumerable <string> rawImports, IProgressBar pbar) { await TmdbClient.GetConfigAsync(); var imports = rawImports.ToList(); var workBarOptions = new ProgressBarOptions { ForegroundColor = ConsoleColor.Yellow, ProgressCharacter = '─', BackgroundColor = ConsoleColor.DarkGray, }; using (var childProgress = pbar?.Spawn(imports.Count, "step import progress", workBarOptions)) { using (var context = new PopcornContextFactory().CreateDbContext(new string[0])) { foreach (var import in imports) { try { // Deserialize a document to a show var showJson = JsonSerializer.Deserialize <ShowJson>(import); if (showJson.Year == null) { continue; } var show = new Show { Rating = new Rating { Hated = showJson.Rating.Hated, Percentage = Convert.ToInt32(showJson.Rating.Percentage), Votes = showJson.Rating.Votes, Loved = showJson.Rating.Loved, Watching = showJson.Rating.Watching }, Images = new ImageShow { Banner = showJson.Images?.Banner, Poster = showJson.Images?.Poster }, ImdbId = showJson.ImdbId, Title = WebUtility.HtmlDecode(showJson.Title), Year = int.Parse(showJson.Year), Runtime = showJson.Runtime, Genres = showJson.Genres.Select(genre => new Genre { Name = genre }).ToList(), GenreNames = string.Join(", ", showJson.Genres.Select(FirstCharToUpper)), Slug = showJson.Slug, LastUpdated = showJson.LastUpdated, TvdbId = showJson.TvdbId, NumSeasons = showJson.NumSeasons, Status = showJson.Status, Synopsis = showJson.Synopsis, Country = showJson.Country, Episodes = showJson.Episodes.Select(episode => new EpisodeShow { Title = WebUtility.HtmlDecode(episode.Title), DateBased = episode.DateBased, TvdbId = episode.TvdbId != null && int.TryParse(episode.TvdbId.ToString(), out var tvdbId) ? tvdbId : 0, Torrents = new TorrentNode { Torrent0 = new Torrent { Url = episode.Torrents.Torrent_0?.Url, Peers = episode.Torrents.Torrent_0?.Peers, Seeds = episode.Torrents.Torrent_0?.Seeds }, Torrent1080p = new Torrent { Url = episode.Torrents.Torrent_1080p?.Url, Peers = episode.Torrents.Torrent_1080p?.Peers, Seeds = episode.Torrents.Torrent_1080p?.Seeds }, Torrent480p = new Torrent { Url = episode.Torrents.Torrent_480p?.Url, Peers = episode.Torrents.Torrent_480p?.Peers, Seeds = episode.Torrents.Torrent_480p?.Seeds }, Torrent720p = new Torrent { Url = episode.Torrents.Torrent_720p?.Url, Peers = episode.Torrents.Torrent_720p?.Peers, Seeds = episode.Torrents.Torrent_720p?.Seeds } }, EpisodeNumber = int.TryParse(episode.EpisodeNumber.ToString(), out var episodeNumber) ? episodeNumber : 0, Season = int.TryParse(episode.Season.ToString(), out var season) ? season : 0, Overview = episode.Overview, FirstAired = episode.FirstAired }).ToList(), AirDay = showJson.AirDay, AirTime = showJson.AirTime, Network = showJson.Network }; if (!context.ShowSet.Any(a => a.ImdbId == show.ImdbId)) { await UpdateImagesAndSimilarShow(show); context.ShowSet.Add(show); } else { var existingEntity = await context.ShowSet.Include(a => a.Rating) .Include(a => a.Episodes) .ThenInclude(episode => episode.Torrents) .ThenInclude(torrent => torrent.Torrent0) .Include(a => a.Episodes) .ThenInclude(episode => episode.Torrents) .ThenInclude(torrent => torrent.Torrent1080p) .Include(a => a.Episodes) .ThenInclude(episode => episode.Torrents) .ThenInclude(torrent => torrent.Torrent480p) .Include(a => a.Episodes) .ThenInclude(episode => episode.Torrents) .ThenInclude(torrent => torrent.Torrent720p) .Include(a => a.Genres) .Include(a => a.Images) .Include(a => a.Similars).FirstOrDefaultAsync(a => a.ImdbId == show.ImdbId) ; existingEntity.Rating.Hated = show.Rating.Hated; existingEntity.Rating.Loved = show.Rating.Loved; existingEntity.Rating.Percentage = show.Rating.Percentage; existingEntity.Rating.Votes = show.Rating.Votes; existingEntity.Rating.Watching = show.Rating.Watching; existingEntity.AirDay = show.AirDay; existingEntity.AirTime = show.AirTime; existingEntity.Status = show.Status; existingEntity.NumSeasons = show.NumSeasons; foreach (var episode in existingEntity.Episodes) { var updatedEpisode = show.Episodes.FirstOrDefault(a => a.TvdbId == episode.TvdbId); if (updatedEpisode == null) { continue; } if (episode.Torrents?.Torrent0 != null && updatedEpisode.Torrents.Torrent0 != null) { episode.Torrents.Torrent0.Peers = updatedEpisode.Torrents.Torrent0.Peers; episode.Torrents.Torrent0.Seeds = updatedEpisode.Torrents.Torrent0.Seeds; if (!string.IsNullOrWhiteSpace(updatedEpisode.Torrents.Torrent0.Url)) { episode.Torrents.Torrent0.Url = updatedEpisode.Torrents.Torrent0.Url; } } if (episode.Torrents?.Torrent1080p != null && updatedEpisode.Torrents.Torrent1080p != null) { episode.Torrents.Torrent1080p.Peers = updatedEpisode.Torrents.Torrent1080p.Peers; episode.Torrents.Torrent1080p.Seeds = updatedEpisode.Torrents.Torrent1080p.Seeds; if (!string.IsNullOrWhiteSpace(updatedEpisode.Torrents.Torrent1080p.Url)) { episode.Torrents.Torrent1080p.Url = updatedEpisode.Torrents.Torrent1080p.Url; } } if (episode.Torrents?.Torrent720p != null && updatedEpisode.Torrents.Torrent720p != null) { episode.Torrents.Torrent720p.Peers = updatedEpisode.Torrents.Torrent720p.Peers; episode.Torrents.Torrent720p.Seeds = updatedEpisode.Torrents.Torrent720p.Seeds; if (!string.IsNullOrWhiteSpace(updatedEpisode.Torrents.Torrent720p.Url)) { episode.Torrents.Torrent720p.Url = updatedEpisode.Torrents.Torrent720p.Url; } } if (episode.Torrents?.Torrent480p != null && updatedEpisode.Torrents.Torrent480p != null) { episode.Torrents.Torrent480p.Peers = updatedEpisode.Torrents.Torrent480p.Peers; episode.Torrents.Torrent480p.Seeds = updatedEpisode.Torrents.Torrent480p.Seeds; if (!string.IsNullOrWhiteSpace(updatedEpisode.Torrents.Torrent480p.Url)) { episode.Torrents.Torrent480p.Url = updatedEpisode.Torrents.Torrent480p.Url; } } } var newEpisodes = show.Episodes.Except(existingEntity.Episodes, new EpisodeComparer()); foreach (var newEpisode in newEpisodes.ToList()) { existingEntity.Episodes.Add(newEpisode); } if (existingEntity.Episodes.Any()) { var lastEpisode = existingEntity.Episodes.OrderBy(a => a.FirstAired).Last(); existingEntity.LastUpdated = lastEpisode.FirstAired; } } await context.SaveChangesAsync(); childProgress?.Tick(); }
/// <summary> /// Import movies to database /// </summary> /// <param name="docs">Documents to import</param> /// <returns><see cref="Task"/></returns> public async Task Import(IEnumerable <BsonDocument> docs) { var documents = docs.ToList(); var loggingTraceBegin = $@"Import {documents.Count} movies started at {DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss.fff", CultureInfo.InvariantCulture)}"; _loggingService.Telemetry.TrackTrace(loggingTraceBegin); var updatedMovies = 0; var tmdbClient = new TMDbClient(Constants.TmdbClientApiKey); tmdbClient.GetConfig(); using (var context = new PopcornContextFactory().CreateDbContext(new string[0])) { foreach (var document in documents) { try { var watch = new Stopwatch(); watch.Start(); // Deserialize a document to a movie var movieJson = BsonSerializer.Deserialize <MovieBson>(document); var movie = new Database.Movie { ImdbCode = movieJson.ImdbCode, Url = movieJson.Url, Torrents = movieJson.Torrents.Select(torrent => new TorrentMovie { Url = torrent.Url, DateUploaded = torrent.DateUploaded, DateUploadedUnix = torrent.DateUploadedUnix, Quality = torrent.Quality, Hash = torrent.Hash, Peers = torrent.Peers, Seeds = torrent.Seeds, Size = torrent.Size, SizeBytes = torrent.SizeBytes }).ToList(), DateUploaded = movieJson.DateUploaded, DateUploadedUnix = movieJson.DateUploadedUnix, DownloadCount = movieJson.DownloadCount, MpaRating = movieJson.MpaRating, Runtime = movieJson.Runtime, YtTrailerCode = movieJson.YtTrailerCode, DescriptionIntro = movieJson.DescriptionIntro, TitleLong = movieJson.TitleLong, Rating = movieJson.Rating, Year = movieJson.Year, LikeCount = movieJson.LikeCount, DescriptionFull = movieJson.DescriptionFull, Cast = movieJson.Cast?.Select(cast => new Database.Cast { ImdbCode = cast?.ImdbCode, SmallImage = cast?.SmallImage, CharacterName = cast?.CharacterName, Name = cast?.Name }).ToList(), Genres = movieJson.Genres.Select(genre => new Database.Genre { Name = genre }).ToList(), GenreNames = string.Join(", ", movieJson.Genres.Select(FirstCharToUpper)), Language = movieJson.Language, Slug = movieJson.Slug, Title = movieJson.Title, BackdropImage = movieJson.BackdropImage, BackgroundImage = movieJson.BackgroundImage, LargeCoverImage = movieJson.LargeCoverImage, LargeScreenshotImage1 = movieJson.LargeScreenshotImage1, LargeScreenshotImage2 = movieJson.LargeScreenshotImage2, LargeScreenshotImage3 = movieJson.LargeScreenshotImage3, MediumCoverImage = movieJson.MediumCoverImage, MediumScreenshotImage1 = movieJson.MediumScreenshotImage1, MediumScreenshotImage2 = movieJson.MediumScreenshotImage2, MediumScreenshotImage3 = movieJson.MediumScreenshotImage3, SmallCoverImage = movieJson.SmallCoverImage, PosterImage = movieJson.PosterImage }; var existingEntity = await context.MovieSet.Include(a => a.Torrents) .Include(a => a.Cast) .Include(a => a.Genres).Include(a => a.Similars).FirstOrDefaultAsync(a => a.ImdbCode == movie.ImdbCode); if (existingEntity == null) { try { var tmdbMovie = await TmdbClient.GetMovieAsync(movie.ImdbCode, MovieMethods.Similar); if (tmdbMovie.Similar.TotalResults != 0) { movie.Similars = new List <Similar>(); await tmdbMovie.Similar.Results.Select(a => a.Id) .ParallelForEachAsync(async id => { var res = await TmdbClient.GetMovieAsync(id); if (!string.IsNullOrEmpty(res?.ImdbId)) { movie.Similars.Add(new Similar { TmdbId = res.ImdbId }); } }); } await movie.Torrents.ParallelForEachAsync(async torrent => { torrent.Url = await _assetsService.UploadFile( $@"torrents/{movie.ImdbCode}/{torrent.Url.Split('/').Last()}.torrent", torrent.Url); }); } catch (Exception) { } await RetrieveAssets(tmdbClient, movie); context.MovieSet.Add(movie); } else { foreach (var torrent in existingEntity.Torrents) { var updatedTorrent = movie.Torrents.FirstOrDefault(a => a.Quality == torrent.Quality); torrent.Peers = updatedTorrent.Peers; torrent.Seeds = updatedTorrent.Seeds; if (string.IsNullOrEmpty(torrent.Url)) { torrent.Url = updatedTorrent.Url; } } existingEntity.GenreNames = string.Join(", ", movieJson.Genres.Select(FirstCharToUpper)); } await context.SaveChangesAsync(); watch.Stop(); updatedMovies++; Console.WriteLine(Environment.NewLine); Console.WriteLine( $"{DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss.fff", CultureInfo.InvariantCulture)} UPDATED MOVIE {movie.Title} in {watch.ElapsedMilliseconds} ms. {updatedMovies}/{documents.Count}"); } catch (Exception ex) { _loggingService.Telemetry.TrackException(ex); } } } // Finish Console.WriteLine(Environment.NewLine); Console.WriteLine("Done processing movies."); var loggingTraceEnd = $@"Import movies ended at {DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss.fff", CultureInfo.InvariantCulture)}"; _loggingService.Telemetry.TrackTrace(loggingTraceEnd); }
/// <summary> /// Import movies to database /// </summary> /// <param name="rawImports">Documents to import</param> /// <param name="pbar"><see cref="IProgressBar"/></param> /// <returns><see cref="Task"/></returns> public async Task Import(IEnumerable <string> rawImports, IProgressBar pbar) { await TmdbClient.GetConfigAsync(); var imports = rawImports.ToList(); var workBarOptions = new ProgressBarOptions { ForegroundColor = ConsoleColor.Yellow, ProgressCharacter = '─', BackgroundColor = ConsoleColor.DarkGray, }; using (var childProgress = pbar?.Spawn(imports.Count, "step import progress", workBarOptions)) { using (var context = new PopcornContextFactory().CreateDbContext(new string[0])) { foreach (var import in imports) { try { // Deserialize a document to a movie var movieJson = JsonSerializer.Deserialize <MovieJson>(import); if (movieJson.Torrents == null || movieJson.Cast == null) { continue; } var movie = new Movie { ImdbCode = movieJson.ImdbCode, Url = movieJson.Url, Torrents = movieJson.Torrents.Select(torrent => new TorrentMovie { Url = torrent.Url, DateUploaded = torrent.DateUploaded, DateUploadedUnix = torrent.DateUploadedUnix, Quality = torrent.Quality, Hash = torrent.Hash, Peers = torrent.Peers, Seeds = torrent.Seeds, Size = torrent.Size, SizeBytes = torrent.SizeBytes }).ToList(), DateUploaded = movieJson.DateUploaded, DateUploadedUnix = movieJson.DateUploadedUnix, DownloadCount = movieJson.DownloadCount, MpaRating = movieJson.MpaRating, Runtime = movieJson.Runtime, YtTrailerCode = movieJson.YtTrailerCode, DescriptionIntro = movieJson.DescriptionIntro, TitleLong = movieJson.TitleLong, Rating = movieJson.Rating, Year = movieJson.Year, LikeCount = movieJson.LikeCount, DescriptionFull = movieJson.DescriptionFull, Cast = movieJson.Cast?.Select(cast => new Database.Cast { ImdbCode = cast?.ImdbCode, SmallImage = cast?.SmallImage, CharacterName = cast?.CharacterName, Name = cast?.Name }).ToList(), Genres = movieJson.Genres?.Select(genre => new Genre { Name = genre }).ToList() ?? new List <Genre>(), GenreNames = string.Join(", ", movieJson.Genres?.Select(FirstCharToUpper) ?? new List <string>()), Language = movieJson.Language, Slug = movieJson.Slug, Title = movieJson.Title, BackgroundImage = movieJson.BackgroundImage, PosterImage = movieJson.PosterImage }; if (!context.MovieSet.Any(a => a.ImdbCode == movie.ImdbCode)) { await RetrieveAssets(movie); context.MovieSet.Add(movie); await context.SaveChangesAsync(); } else { var existingEntity = await context.MovieSet.Include(a => a.Torrents) .FirstOrDefaultAsync(a => a.ImdbCode == movie.ImdbCode); existingEntity.DownloadCount = movie.DownloadCount; existingEntity.LikeCount = movie.LikeCount; existingEntity.Rating = movie.Rating; foreach (var torrent in existingEntity.Torrents) { var updatedTorrent = movie.Torrents.FirstOrDefault(a => a.Quality == torrent.Quality); if (updatedTorrent == null) { continue; } torrent.Peers = updatedTorrent.Peers; torrent.Seeds = updatedTorrent.Seeds; } await context.SaveChangesAsync(); } childProgress?.Tick(); } catch (Exception ex) { _loggingService.Telemetry.TrackException(ex); } } } // Finish pbar?.Tick(); } }
public async Task <IActionResult> GetSimilar([FromBody] IEnumerable <string> imdbIds, [RequiredFromQuery] int page, [FromQuery] int limit, [FromQuery] int minimum_rating, [FromQuery] string query_term, [FromQuery] string genre, [FromQuery] string sort_by) { var nbMoviesPerPage = 20; if (limit >= 20 && limit <= 50) { nbMoviesPerPage = limit; } var currentPage = 1; if (page >= 1) { currentPage = page; } var queryTerm = string.Empty; if (!string.IsNullOrWhiteSpace(query_term)) { queryTerm = query_term; } var genreFilter = string.Empty; if (!string.IsNullOrWhiteSpace(genre)) { genreFilter = genre; } if (!imdbIds.Any()) { return(Json(new MovieLightResponse { Movies = new List <MovieLightJson>(), TotalMovies = 0 })); } var hash = Convert.ToBase64String( Encoding.UTF8.GetBytes( $@"type=movies&similar&imdbIds={string.Join(',', imdbIds)}&page={page}&limit={limit}&minimum_rating={minimum_rating}&query_term={ query_term }&genre={genre}&sort_by={sort_by}")); try { var cachedMovies = await _cachingService.GetCache(hash); if (cachedMovies != null) { try { return(Content(cachedMovies, "application/json")); } catch (Exception ex) { _loggingService.Telemetry.TrackException(ex); } } } catch (Exception ex) { _loggingService.Telemetry.TrackException(ex); } using (var context = new PopcornContextFactory().CreateDbContext(new string[0])) { var skipParameter = new SqlParameter("@skip", (currentPage - 1) * nbMoviesPerPage); var takeParameter = new SqlParameter("@take", nbMoviesPerPage); var ratingParameter = new SqlParameter("@rating", minimum_rating); var queryParameter = new SqlParameter("@Keywords", string.Format(@"""{0}""", queryTerm)); var genreParameter = new SqlParameter("@genre", genreFilter); var query = @" SELECT DISTINCT Movie.Title, Movie.Year, Movie.Rating, Movie.PosterImage, Movie.ImdbCode, Movie.GenreNames, COUNT(*) OVER () as TotalCount FROM MovieSet AS Movie WHERE Movie.ImdbCode IN (SELECT Similar.TmdbId FROM Similar AS Similar INNER JOIN ( SELECT Movie.ID FROM MovieSet AS Movie WHERE Movie.ImdbCode IN ({@imdbIds}) ) Movie ON Similar.MovieId = Movie.Id) AND 1 = 1"; if (minimum_rating > 0 && minimum_rating < 10) { query += @" AND Rating >= @rating"; } if (!string.IsNullOrWhiteSpace(query_term)) { query += @" AND (CONTAINS(Movie.Title, @Keywords) OR CONTAINS(Movie.ImdbCode, @Keywords))"; } if (!string.IsNullOrWhiteSpace(genre)) { query += @" AND CONTAINS(Movie.GenreNames, @genre)"; } query += " ORDER BY Movie.Rating DESC"; query += @" OFFSET @skip ROWS FETCH NEXT @take ROWS ONLY"; using (var cmd = new SqlCommand(query, new SqlConnection(context.Database.GetDbConnection().ConnectionString))) { cmd.AddArrayParameters(imdbIds, "@imdbIds"); cmd.Parameters.Add(skipParameter); cmd.Parameters.Add(takeParameter); cmd.Parameters.Add(ratingParameter); cmd.Parameters.Add(queryParameter); cmd.Parameters.Add(genreParameter); await cmd.Connection.OpenAsync(); var reader = await cmd.ExecuteReaderAsync(new CancellationToken()); var count = 0; var movies = new List <MovieLightJson>(); while (await reader.ReadAsync()) { var movie = new MovieLightJson { Title = !await reader.IsDBNullAsync(0) ? reader.GetString(0) : string.Empty, Year = !await reader.IsDBNullAsync(1) ? reader.GetInt32(1) : 0, Rating = !await reader.IsDBNullAsync(2) ? reader.GetDouble(2) : 0d, PosterImage = !await reader.IsDBNullAsync(3) ? reader.GetString(3) : string.Empty, ImdbCode = !await reader.IsDBNullAsync(4) ? reader.GetString(4) : string.Empty, Genres = !await reader.IsDBNullAsync(5) ? reader.GetString(5) : string.Empty }; movies.Add(movie); count = !await reader.IsDBNullAsync(6) ? reader.GetInt32(6) : 0; } var response = new MovieLightResponse { TotalMovies = count, Movies = movies }; var json = JsonSerializer.ToJsonString(response, StandardResolver.SnakeCase); await _cachingService.SetCache(hash, json, TimeSpan.FromDays(1)); return(Content(json, "application/json")); } } }
public async Task <IActionResult> Get([RequiredFromQuery] int page, [FromQuery] int limit, [FromQuery] int minimum_rating, [FromQuery] string query_term, [FromQuery] string genre, [FromQuery] string sort_by) { var nbAnimesPerPage = 20; if (limit >= 20 && limit <= 50) { nbAnimesPerPage = limit; } var currentPage = 1; if (page >= 1) { currentPage = page; } using (var context = new PopcornContextFactory().Create(new DbContextFactoryOptions())) { var query = context.AnimeSet.Include(anime => anime.Rating) .Include(anime => anime.Episodes) .ThenInclude(episode => episode.Torrents) .ThenInclude(torrent => torrent.Torrent0) .Include(anime => anime.Episodes) .ThenInclude(episode => episode.Torrents) .ThenInclude(torrent => torrent.Torrent1080p) .Include(anime => anime.Episodes) .ThenInclude(episode => episode.Torrents) .ThenInclude(torrent => torrent.Torrent480p) .Include(anime => anime.Episodes) .ThenInclude(episode => episode.Torrents) .ThenInclude(torrent => torrent.Torrent720p) .Include(anime => anime.Genres) .Include(anime => anime.Images) .AsQueryable(); if (minimum_rating > 0 && minimum_rating < 100) { query = query.Where(anime => anime.Rating.Percentage > minimum_rating); } if (!string.IsNullOrWhiteSpace(query_term)) { query = query.Where( anime => anime.Title.ToLower().Contains(query_term.ToLower())); } if (!string.IsNullOrWhiteSpace(genre)) { query = query.Where(show => show.Genres.Any(a => a.Name.ToLower().Contains(genre.ToLower()))); } if (!string.IsNullOrWhiteSpace(sort_by)) { switch (sort_by) { case "title": query = query.OrderBy(anime => anime.Title); break; case "year": query = query.OrderByDescending(anime => anime.Year); break; case "rating": query = query.OrderByDescending(anime => anime.Rating.Percentage); break; case "loved": query = query.OrderByDescending(anime => anime.Rating.Loved); break; case "votes": query = query.OrderByDescending(anime => anime.Rating.Votes); break; case "watching": query = query.OrderByDescending(anime => anime.Rating.Watching); break; case "date_added": query = query.OrderByDescending(anime => anime.LastUpdated); break; } } else { query = query.OrderByDescending(movie => movie.LastUpdated); } var count = query.Count(); var skip = (currentPage - 1) * nbAnimesPerPage; if (count <= nbAnimesPerPage) { skip = 0; } var result = query.Skip(skip).Take(nbAnimesPerPage).ToList(); return (Json(new AnimeResponse { TotalAnimes = count, Animes = result.Select(ConvertAnimeToJson) })); } }
public async Task <IActionResult> GetLight(string imdb) { var hash = Convert.ToBase64String( Encoding.UTF8.GetBytes($"light:{imdb}")); try { var cachedMovie = await _cachingService.GetCache(hash); if (cachedMovie != null) { try { return(Content(cachedMovie, "application/json")); } catch (Exception ex) { _loggingService.Telemetry.TrackException(ex); } } } catch (Exception ex) { _loggingService.Telemetry.TrackException(ex); } using (var context = new PopcornContextFactory().CreateDbContext(new string[0])) { var imdbParameter = new SqlParameter("@imdbCode", imdb); var query = @" SELECT Movie.Title, Movie.Year, Movie.Rating, Movie.PosterImage, Movie.ImdbCode, Movie.GenreNames FROM MovieSet AS Movie WHERE Movie.ImdbCode = @imdbCode"; var movieQuery = await context.Database.ExecuteSqlQueryAsync(query, new CancellationToken(), imdbParameter); var reader = movieQuery.DbDataReader; var movie = new MovieLightJson(); while (await reader.ReadAsync()) { movie.Title = !await reader.IsDBNullAsync(0) ? reader.GetString(0) : string.Empty; movie.Year = !await reader.IsDBNullAsync(1) ? reader.GetInt32(1) : 0; movie.Rating = !await reader.IsDBNullAsync(2) ? reader.GetDouble(2) : 0d; movie.PosterImage = !await reader.IsDBNullAsync(3) ? reader.GetString(3) : string.Empty; movie.ImdbCode = !await reader.IsDBNullAsync(4) ? reader.GetString(4) : string.Empty; movie.Genres = !await reader.IsDBNullAsync(5) ? reader.GetString(5) : string.Empty; } if (string.IsNullOrEmpty(movie.ImdbCode)) { return(BadRequest()); } var json = JsonSerializer.ToJsonString(movie, StandardResolver.SnakeCase); await _cachingService.SetCache(hash, json, TimeSpan.FromDays(1)); return(Content(json, "application/json")); } }
public async Task <IActionResult> GetLight(string imdb) { var hash = Convert.ToBase64String( Encoding.UTF8.GetBytes($"light:{imdb}")); try { var cachedShow = await _cachingService.GetCache(hash); if (cachedShow != null) { try { return(Content(cachedShow, "application/json")); } catch (Exception ex) { _loggingService.Telemetry.TrackException(ex); } } } catch (Exception ex) { _loggingService.Telemetry.TrackException(ex); } using (var context = new PopcornContextFactory().CreateDbContext(new string[0])) { var imdbParameter = new SqlParameter("@imdbId", imdb); var query = @" SELECT Show.Title, Show.Year, Rating.Percentage, Rating.Loved, Rating.Votes, Rating.Hated, Rating.Watching, Show.LastUpdated, Image.Banner, Image.Fanart, Image.Poster, Show.ImdbId, Show.TvdbId, Show.GenreNames FROM ShowSet AS Show INNER JOIN ImageShowSet AS Image ON Image.Id = Show.ImagesId INNER JOIN RatingSet AS Rating ON Rating.Id = Show.RatingId WHERE Show.ImdbId = @imdbId"; var showQuery = await context.Database.ExecuteSqlQueryAsync(query, new CancellationToken(), imdbParameter); var reader = showQuery.DbDataReader; var show = new ShowLightJson(); while (await reader.ReadAsync()) { show.Title = !await reader.IsDBNullAsync(0) ? reader.GetString(0) : string.Empty; show.Year = !await reader.IsDBNullAsync(1) ? reader.GetInt32(1) : 0; show.Rating = new RatingJson { Percentage = !await reader.IsDBNullAsync(2) ? reader.GetInt32(2) : 0, Loved = !await reader.IsDBNullAsync(3) ? reader.GetInt32(3) : 0, Votes = !await reader.IsDBNullAsync(4) ? reader.GetInt32(4) : 0, Hated = !await reader.IsDBNullAsync(5) ? reader.GetInt32(5) : 0, Watching = !await reader.IsDBNullAsync(6) ? reader.GetInt32(6) : 0 }; show.Images = new ImageShowJson { Banner = !await reader.IsDBNullAsync(8) ? reader.GetString(8) : string.Empty, Fanart = !await reader.IsDBNullAsync(9) ? reader.GetString(9) : string.Empty, Poster = !await reader.IsDBNullAsync(10) ? reader.GetString(10) : string.Empty, }; show.ImdbId = !await reader.IsDBNullAsync(11) ? reader.GetString(11) : string.Empty; show.TvdbId = !await reader.IsDBNullAsync(12) ? reader.GetString(12) : string.Empty; show.Genres = !await reader.IsDBNullAsync(13) ? reader.GetString(13) : string.Empty; } if (string.IsNullOrEmpty(show.ImdbId)) { return(BadRequest()); } var json = JsonSerializer.ToJsonString(show, StandardResolver.SnakeCase); await _cachingService.SetCache(hash, json, TimeSpan.FromDays(1)); return(Content(json, "application/json")); } }
public async Task <IActionResult> GetSimilar([FromBody] IEnumerable <string> imdbIds, [RequiredFromQuery] int page, [FromQuery] int limit) { if (!imdbIds.Any()) { return(Json(new MovieLightResponse { Movies = new List <MovieLightJson>(), TotalMovies = 0 })); } var nbMoviesPerPage = 20; if (limit >= 20 && limit <= 50) { nbMoviesPerPage = limit; } var currentPage = 1; if (page >= 1) { currentPage = page; } var hash = Convert.ToBase64String( Encoding.UTF8.GetBytes( $@"type=movies&page={page}&limit={limit}&imdbId={string.Join(',', imdbIds)}")); try { var cachedMovies = await _cachingService.GetCache(hash); if (cachedMovies != null) { try { return(Json(JsonConvert.DeserializeObject <MovieLightResponse>(cachedMovies))); } catch (Exception ex) { _loggingService.Telemetry.TrackException(ex); } } } catch (Exception ex) { _loggingService.Telemetry.TrackException(ex); } using (var context = new PopcornContextFactory().CreateDbContext(new string[0])) { var skipParameter = new SqlParameter("@skip", (currentPage - 1) * nbMoviesPerPage); var takeParameter = new SqlParameter("@take", nbMoviesPerPage); var query = @" SELECT DISTINCT Movie.Title, Movie.Year, Movie.Rating, Movie.PosterImage, Movie.ImdbCode, Movie.GenreNames, Torrent.Peers, Torrent.Seeds, COUNT(*) OVER () as TotalCount FROM MovieSet AS Movie INNER JOIN TorrentMovieSet AS Torrent ON Torrent.MovieId = Movie.Id INNER JOIN Similar ON Similar.MovieId = Movie.Id AND Torrent.Quality = '720p' WHERE Similar.TmdbId IN ({@imdbIds}) ORDER BY Movie.Rating DESC"; query += @" OFFSET @skip ROWS FETCH NEXT @take ROWS ONLY"; using (var cmd = new SqlCommand(query, new SqlConnection(context.Database.GetDbConnection().ConnectionString))) { cmd.AddArrayParameters(imdbIds, "@imdbIds"); cmd.Parameters.Add(skipParameter); cmd.Parameters.Add(takeParameter); await cmd.Connection.OpenAsync(); var reader = await cmd.ExecuteReaderAsync(new CancellationToken()); var count = 0; var movies = new List <MovieLightJson>(); while (await reader.ReadAsync()) { var movie = new MovieLightJson { Title = reader[0].GetType() != typeof(DBNull) ? (string)reader[0] : string.Empty, Year = reader[1].GetType() != typeof(DBNull) ? (int)reader[1] : 0, Rating = reader[2].GetType() != typeof(DBNull) ? (double)reader[2] : 0d, PosterImage = reader[3].GetType() != typeof(DBNull) ? (string)reader[3] : string.Empty, ImdbCode = reader[4].GetType() != typeof(DBNull) ? (string)reader[4] : string.Empty, Genres = reader[5].GetType() != typeof(DBNull) ? (string)reader[5] : string.Empty }; movies.Add(movie); count = reader[8].GetType() != typeof(DBNull) ? (int)reader[8] : 0; } var response = new MovieLightResponse { TotalMovies = count, Movies = movies }; await _cachingService.SetCache(hash, JsonConvert.SerializeObject(response), TimeSpan.FromDays(1)); return (Json(response)); } } }
/// <summary> /// Import shows to database /// </summary> /// <param name="docs">Documents to import</param> /// <returns><see cref="Task"/></returns> public async Task Import(IEnumerable <BsonDocument> docs) { var documents = docs.ToList(); var loggingTraceBegin = $@"Import {documents.Count} shows started at { DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss.fff", CultureInfo.InvariantCulture) }"; _loggingService.Telemetry.TrackTrace(loggingTraceBegin); var updatedShows = 0; using (var context = new PopcornContextFactory().CreateDbContext(new string[0])) { foreach (var document in documents) { try { var watch = new Stopwatch(); watch.Start(); // Deserialize a document to a show var showJson = BsonSerializer.Deserialize <ShowBson>(document); if (showJson.Year == null) { continue; } var show = new Show { Rating = new Rating { Watching = showJson.Rating.Watching, Hated = showJson.Rating.Hated, Percentage = showJson.Rating.Percentage, Votes = showJson.Rating.Votes, Loved = showJson.Rating.Loved }, Images = new ImageShow { Banner = showJson.Images.Banner, Poster = showJson.Images.Poster }, ImdbId = showJson.ImdbId, Title = WebUtility.HtmlDecode(showJson.Title), Year = int.Parse(showJson.Year), Runtime = showJson.Runtime, Genres = showJson.Genres.Select(genre => new Genre { Name = genre.AsString }).ToList(), GenreNames = string.Join(", ", showJson.Genres.Select(a => FirstCharToUpper(a.AsString))), Slug = showJson.Slug, LastUpdated = showJson.LastUpdated, TvdbId = showJson.TvdbId, NumSeasons = showJson.NumSeasons, Status = showJson.Status, Synopsis = showJson.Synopsis, Country = showJson.Country, Episodes = showJson.Episodes.Select(episode => new EpisodeShow { Title = WebUtility.HtmlDecode(episode.Title), DateBased = episode.DateBased, TvdbId = episode.TvdbId, Torrents = new TorrentNode { Torrent0 = new Torrent { Url = episode.Torrents.Torrent_0?.Url, Peers = episode.Torrents.Torrent_0?.Peers, Seeds = episode.Torrents.Torrent_0?.Seeds, Provider = episode.Torrents.Torrent_0?.Provider }, Torrent1080p = new Torrent { Url = episode.Torrents.Torrent_1080p?.Url, Peers = episode.Torrents.Torrent_1080p?.Peers, Seeds = episode.Torrents.Torrent_1080p?.Seeds, Provider = episode.Torrents.Torrent_1080p?.Provider }, Torrent480p = new Torrent { Url = episode.Torrents.Torrent_480p?.Url, Peers = episode.Torrents.Torrent_480p?.Peers, Seeds = episode.Torrents.Torrent_480p?.Seeds, Provider = episode.Torrents.Torrent_480p?.Provider }, Torrent720p = new Torrent { Url = episode.Torrents.Torrent_720p?.Url, Peers = episode.Torrents.Torrent_720p?.Peers, Seeds = episode.Torrents.Torrent_720p?.Seeds, Provider = episode.Torrents.Torrent_720p?.Provider } }, EpisodeNumber = episode.EpisodeNumber, Season = episode.Season, Overview = episode.Overview, FirstAired = episode.FirstAired }).ToList(), AirDay = showJson.AirDay, AirTime = showJson.AirTime, Network = showJson.Network }; if (!context.ShowSet.Any(a => a.ImdbId == show.ImdbId)) { await UpdateImagesAndSimilarShow(show).ConfigureAwait(false); context.ShowSet.Add(show); } else { var existingEntity = await context.ShowSet.Include(a => a.Rating) .Include(a => a.Episodes) .ThenInclude(episode => episode.Torrents) .ThenInclude(torrent => torrent.Torrent0) .Include(a => a.Episodes) .ThenInclude(episode => episode.Torrents) .ThenInclude(torrent => torrent.Torrent1080p) .Include(a => a.Episodes) .ThenInclude(episode => episode.Torrents) .ThenInclude(torrent => torrent.Torrent480p) .Include(a => a.Episodes) .ThenInclude(episode => episode.Torrents) .ThenInclude(torrent => torrent.Torrent720p) .Include(a => a.Genres) .Include(a => a.Images) .Include(a => a.Similars).FirstOrDefaultAsync(a => a.ImdbId == show.ImdbId) .ConfigureAwait(false); existingEntity.Rating.Hated = show.Rating.Hated; existingEntity.Rating.Loved = show.Rating.Loved; existingEntity.Rating.Percentage = show.Rating.Percentage; existingEntity.Rating.Votes = show.Rating.Votes; existingEntity.Rating.Watching = show.Rating.Watching; existingEntity.AirDay = show.AirDay; existingEntity.AirTime = show.AirTime; existingEntity.Status = show.Status; existingEntity.NumSeasons = show.NumSeasons; foreach (var episode in existingEntity.Episodes) { var updatedEpisode = show.Episodes.FirstOrDefault(a => a.TvdbId == episode.TvdbId); if (updatedEpisode == null) { continue; } if (episode.Torrents?.Torrent0 != null && updatedEpisode.Torrents.Torrent0 != null) { episode.Torrents.Torrent0.Peers = updatedEpisode.Torrents.Torrent0.Peers; episode.Torrents.Torrent0.Seeds = updatedEpisode.Torrents.Torrent0.Seeds; } if (episode.Torrents?.Torrent1080p != null && updatedEpisode.Torrents.Torrent1080p != null) { episode.Torrents.Torrent1080p.Peers = updatedEpisode.Torrents.Torrent1080p.Peers; episode.Torrents.Torrent1080p.Seeds = updatedEpisode.Torrents.Torrent1080p.Seeds; } if (episode.Torrents?.Torrent720p != null && updatedEpisode.Torrents.Torrent720p != null) { episode.Torrents.Torrent720p.Peers = updatedEpisode.Torrents.Torrent720p.Peers; episode.Torrents.Torrent720p.Seeds = updatedEpisode.Torrents.Torrent720p.Seeds; } if (episode.Torrents?.Torrent480p != null && updatedEpisode.Torrents.Torrent480p != null) { episode.Torrents.Torrent480p.Peers = updatedEpisode.Torrents.Torrent480p.Peers; episode.Torrents.Torrent480p.Seeds = updatedEpisode.Torrents.Torrent480p.Seeds; } } var newEpisodes = show.Episodes.Except(existingEntity.Episodes, new EpisodeComparer()); foreach (var newEpisode in newEpisodes.ToList()) { existingEntity.Episodes.Add(newEpisode); } if (existingEntity.Episodes.Any()) { var lastEpisode = existingEntity.Episodes.OrderBy(a => a.FirstAired).Last(); existingEntity.LastUpdated = lastEpisode.FirstAired; } } await context.SaveChangesAsync().ConfigureAwait(false); watch.Stop(); updatedShows++; Console.WriteLine(Environment.NewLine); Console.WriteLine( $"{DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss.fff", CultureInfo.InvariantCulture)} UPDATED SHOW {show.Title} in {watch.ElapsedMilliseconds} ms. {updatedShows}/{documents.Count}"); } catch (Exception ex) { _loggingService.Telemetry.TrackException(ex); } } } // Finish Console.WriteLine(Environment.NewLine); Console.WriteLine("Done processing shows."); var loggingTraceEnd = $@"Import shows ended at { DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss.fff", CultureInfo.InvariantCulture) }"; _loggingService.Telemetry.TrackTrace(loggingTraceEnd); }