public async Task CreateLocalMoviesAsync(ICollection <CreateLocalMovieRequest> requests) { if (_type != ScraperType.Local) { throw new InvalidOperationException($"scrape session of type {_type} cannot create local movies"); } var toAdd = requests.Where(x => !LocalImdbCodes.Contains(x.ImdbCode)) .Select(x => new LocalMovie { Source = _source, ImdbCode = x.ImdbCode.Trim().ToLower(), Title = x.Title, Year = x.Year, DateCreated = x.DateCreated, DateScraped = _scrapeDate, ThumbPath = x.ThumbPath }) .ToList(); if (!toAdd.Any()) { return; } LocalImdbCodes.AddRange(toAdd.Select(x => x.ImdbCode)); _context.AddRange(toAdd); var downloadedMovies = toAdd .Join(MovieImdbCodes, lm => lm.ImdbCode, x => x, (lm, x) => new DownloadedMovie { MovieImdbCode = x, LocalMovieImdbCode = x }); _context.AddRange(downloadedMovies); await _context.SaveChangesAsync(_cancellationToken); }
public static async Task <ICollection <Genre> > AssertGenresAsync( this MolliesMoviesContext context, ICollection <string> toAssert, CancellationToken cancellationToken = default) { var cleaned = toAssert.Select(x => x.Trim()).ToList(); var result = await context.Set <Genre>() .Where(x => cleaned.Contains(x.Name)) .ToListAsync(cancellationToken); var newGenres = cleaned.Except(result.Select(x => x.Name)).ToList(); if (newGenres.Any()) { var toAdd = newGenres.Select(x => new Genre { Name = x }).ToList(); result.AddRange(toAdd); await context.AddRangeAsync(toAdd, cancellationToken); await context.SaveChangesAsync(cancellationToken); } return(result); }
public async Task ScrapeAsync(int id, CancellationToken cancellationToken = default) { Scrape scrape; try { scrape = await _context.Scrapes().FirstOrDefaultAsync(x => x.Id == id, cancellationToken); if (scrape is null) { throw new Exception($"cannot find scrape record {id}"); } } catch (Exception e) { _logger.LogError(e, "failed when getting scrape record {id}", id); // TODO requeue on db fail return; } scrape.ScrapeSources = new List <ScrapeSource>(); IScrapeSession session = null; foreach (var scraper in _scrapers) { var source = new ScrapeSource { Source = scraper.Source, Type = scraper.Type, StartDate = _clock.UtcNow }; scrape.ScrapeSources.Add(source); try { session = await _movieService.GetScrapeSessionAsync(scraper.Source, scraper.Type, session, cancellationToken); var result = await scraper.ScrapeAsync(session, cancellationToken); source.Success = true; source.EndDate = _clock.UtcNow; source.MovieCount = result.MovieCount; source.TorrentCount = result.TorrentCount; switch (scraper.Type) { case ScraperType.Local: scrape.LocalMovieCount += result.MovieCount; break; case ScraperType.Torrent: scrape.MovieCount += result.MovieCount; scrape.TorrentCount += result.TorrentCount; break; default: throw new ArgumentOutOfRangeException(); } } catch (Exception e) { _logger.LogError(e, "failed to scrape {source}", scraper.Source); source.Success = false; source.EndDate = _clock.UtcNow; source.Error = e.ToString(); } } try { scrape.ImageCount = await ScrapeImagesAsync(session, cancellationToken); } catch (Exception e) { _logger.LogError(e, "failed to scrape images"); } scrape.Success = scrape.ScrapeSources.All(x => x.Success); scrape.EndDate = _clock.UtcNow; await _context.SaveChangesAsync(cancellationToken); }
public async Task DownloadMovieTorrentAsync(int movieId, int torrentId, CancellationToken cancellationToken = default) { var options = _options.Value; var movie = await _movieService.GetAsync(movieId, cancellationToken); var torrent = movie.MovieSources .SelectMany(x => x.Torrents) .FirstOrDefault(x => x.Id == torrentId); if (torrent is null) { throw BadRequestException.Create($"torrent with id {torrentId} does not exist on movie with id {movieId}"); } if (!(movie.LocalMovie is null)) { throw BadRequestException.Create($"movie with id {movieId} is already downloaded"); } if (movie.TransmissionStatus.HasValue) { throw BadRequestException.Create($"movie with id {movieId} is currently downloading"); } var torrentName = $"{movie.Title} ({movie.Year})"; var client = new Client(options.RpcUri.ToString()); var torrents = await client.TorrentGetAsync(TorrentFields.ALL_FIELDS); if (torrents.Torrents.Any(x => x.Name == torrentName)) { throw BadRequestException.Create($"movie with id {movieId} is currently downloading"); } // get magnet uri var trs = string.Join('&', options.Trackers.Select(x => $"tr={x}")); var magnetUri = $"magnet:?xt=urn:btih:{torrent.Hash}&dn={Uri.EscapeDataString(torrentName)}&{trs}"; var result = await client.TorrentAddAsync(new NewTorrent { Filename = magnetUri }); _logger.LogInformation("added torrent {name}", result.Name); var context = new TransmissionContext { ExternalId = result.ID, Name = result.Name, MagnetUri = magnetUri, MovieId = movie.Id, TorrentId = torrent.Id, Statuses = new List <TransmissionContextStatus> { GetStatus(TransmissionStatusCode.Started) } }; _context.Add(context); await _context.SaveChangesAsync(cancellationToken); _logger.LogInformation("saved context for torrent {name}", result.Name); }