Example #1
0
        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)));
        }
Example #2
0
        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"));
            }
        }
Example #3
0
        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"));
            }
        }
Example #4
0
        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));
            }
        }
Example #5
0
        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)));
        }
Example #6
0
        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)));
        }
Example #7
0
        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));
            }
        }
Example #8
0
        /// <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);
        }
Example #9
0
        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));
            }
        }
Example #10
0
        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)
                }));
            }
        }
Example #11
0
        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));
            }
        }
Example #12
0
        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"));
                }
            }
        }
Example #13
0
        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));
            }
        }
Example #14
0
        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"));
            }
        }
Example #15
0
        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"));
            }
        }
Example #16
0
        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"));
                }
            }
        }
Example #17
0
        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"));
            }
        }
Example #18
0
        /// <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();
                        }
Example #19
0
        /// <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();
            }
        }
Example #21
0
        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"));
                }
            }
        }
Example #22
0
        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)
                }));
            }
        }
Example #23
0
        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"));
            }
        }
Example #24
0
        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"));
            }
        }
Example #25
0
        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));
                }
            }
        }
Example #26
0
        /// <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);
        }