private void AuthenticateClient(HttpRequestBuilder requestBuilder, QBittorrentSettings settings, bool reauthenticate = false) { if (settings.Username.IsNullOrWhiteSpace() || settings.Password.IsNullOrWhiteSpace()) { if (reauthenticate) { throw new DownloadClientAuthenticationException("Failed to authenticate with qBittorrent."); } return; } var authKey = string.Format("{0}:{1}", requestBuilder.BaseUrl, settings.Password); var cookies = _authCookieCache.Find(authKey); if (cookies == null || reauthenticate) { _authCookieCache.Remove(authKey); var authLoginRequest = BuildRequest(settings).Resource("/api/v2/auth/login") .Post() .AddFormParameter("username", settings.Username ?? string.Empty) .AddFormParameter("password", settings.Password ?? string.Empty) .Build(); HttpResponse response; try { response = _httpClient.Execute(authLoginRequest); } catch (HttpException ex) { _logger.Debug("qbitTorrent authentication failed."); if (ex.Response.StatusCode == HttpStatusCode.Forbidden) { throw new DownloadClientAuthenticationException("Failed to authenticate with qBittorrent.", ex); } throw new DownloadClientException("Failed to connect to qBittorrent, please check your settings.", ex); } catch (WebException ex) { throw new DownloadClientUnavailableException("Failed to connect to qBittorrent, please check your settings.", ex); } // returns "Fails." on bad login if (response.Content != "Ok.") { _logger.Debug("qbitTorrent authentication failed."); throw new DownloadClientAuthenticationException("Failed to authenticate with qBittorrent."); } _logger.Debug("qBittorrent authentication succeeded."); cookies = response.GetCookies(); _authCookieCache.Set(authKey, cookies); } requestBuilder.SetCookies(cookies); }
public TrackedDownload Find(string downloadId) { return(_cache.Find(downloadId)); }
protected bool HasReachedSeedingTimeLimit(QBittorrentTorrent torrent, QBittorrentPreferences config) { long seedingTimeLimit; if (torrent.SeedingTimeLimit >= 0) { seedingTimeLimit = torrent.SeedingTimeLimit; } else if (torrent.SeedingTimeLimit == -2 && config.MaxSeedingTimeEnabled) { seedingTimeLimit = config.MaxSeedingTime; } else { return(false); } if (torrent.SeedingTime.HasValue) { // SeedingTime can't be available here, but use it if the api starts to provide it. return(torrent.SeedingTime.Value >= seedingTimeLimit); } var cacheKey = Settings.Host + Settings.Port + torrent.Hash; var cacheSeedingTime = _seedingTimeCache.Find(cacheKey); if (cacheSeedingTime != null) { var togo = seedingTimeLimit - cacheSeedingTime.SeedingTime; var elapsed = (DateTime.UtcNow - cacheSeedingTime.LastFetched).TotalSeconds; if (togo <= 0) { // Already reached the limit, keep the cache alive _seedingTimeCache.Set(cacheKey, cacheSeedingTime, TimeSpan.FromMinutes(5)); return(true); } else if (togo > elapsed) { // SeedingTime cannot have reached the required value since the last check, preserve the cache _seedingTimeCache.Set(cacheKey, cacheSeedingTime, TimeSpan.FromMinutes(5)); return(false); } } FetchTorrentDetails(torrent); cacheSeedingTime = new SeedingTimeCacheEntry { LastFetched = DateTime.UtcNow, SeedingTime = torrent.SeedingTime.Value }; _seedingTimeCache.Set(cacheKey, cacheSeedingTime, TimeSpan.FromMinutes(5)); if (cacheSeedingTime.SeedingTime >= seedingTimeLimit) { // Reached the limit, keep the cache alive return(true); } return(false); }
public Command GetById(int id) { return(_cache.Find(id.ToString())); }
private Response Search() { if (Request.Query.Id == 0) { //Todo error handling } RootFolder rootFolder = _rootFolderService.Get(Request.Query.Id); int page = Request.Query.page; int per_page = Request.Query.per_page; int min = (page - 1) * per_page; int max = page * per_page; var unmapped = rootFolder.UnmappedFolders.OrderBy(f => f.Name).ToList(); int total_count = unmapped.Count; if (Request.Query.total_entries.HasValue) { total_count = Request.Query.total_entries; } max = total_count >= max ? max : total_count; var paged = unmapped.GetRange(min, max - min); var mapped = paged.Select(f => { Core.Movies.Movie m = null; var mappedMovie = _mappedMovies.Find(f.Name); if (mappedMovie != null) { return(mappedMovie); } var parsedTitle = _parsingService.ParseMinimalPathMovieInfo(f.Name); parsedTitle.ImdbId = Parser.ParseImdbId(parsedTitle.SimpleReleaseTitle); if (parsedTitle == null) { m = new Core.Movies.Movie { Title = f.Name.Replace(".", " ").Replace("-", " "), Path = f.Path, }; } else { m = new Core.Movies.Movie { Title = parsedTitle.MovieTitle, Year = parsedTitle.Year, ImdbId = parsedTitle.ImdbId, Path = f.Path }; } var files = _diskScanService.GetVideoFiles(f.Path); var decisions = _importDecisionMaker.GetImportDecisions(files.ToList(), m, true); var decision = decisions.Where(d => d.Approved && !d.Rejections.Any()).FirstOrDefault(); if (decision != null) { var local = decision.LocalMovie; m.MovieFile = new MovieFile { Path = local.Path, Edition = local.ParsedMovieInfo.Edition, Quality = local.Quality, MediaInfo = local.MediaInfo, ReleaseGroup = local.ParsedMovieInfo.ReleaseGroup, RelativePath = f.Path.GetRelativePath(local.Path) }; } mappedMovie = _searchProxy.MapMovieToTmdbMovie(m); if (mappedMovie != null) { mappedMovie.Monitored = true; _mappedMovies.Set(f.Name, mappedMovie, TimeSpan.FromDays(2)); return(mappedMovie); } return(null); }); return(new PagingResource <MovieResource> { Page = page, PageSize = per_page, SortDirection = SortDirection.Ascending, SortKey = Request.Query.sort_by, TotalRecords = total_count - mapped.Where(m => m == null).Count(), Records = MapToResource(mapped.Where(m => m != null)).ToList() }.AsResponse()); }
private ImportDecision GetDecision(string file, Movie movie, DownloadClientItem downloadClientItem, ParsedMovieInfo folderInfo, bool sceneSource, bool shouldUseFolderName, bool shouldCheckQuality = false) { ImportDecision decision = null; try { ParsedMovieInfo modifiedFolderInfo = null; if (folderInfo != null) { modifiedFolderInfo = folderInfo.JsonClone(); // We want the filename to be used for parsing quality, etc. even if we didn't get any movie info from there. modifiedFolderInfo.SimpleReleaseTitle = Path.GetFileName(file); } var minimalInfo = _parsingService.ParseMinimalPathMovieInfo(file) ?? modifiedFolderInfo; LocalMovie localMovie = null; if (minimalInfo != null) { //TODO: make it so media info doesn't ruin the import process of a new movie var mediaInfo = (_config.EnableMediaInfo || !movie.Path?.IsParentPath(file) == true) ? _videoFileInfoReader.GetMediaInfo(file) : null; var size = _diskProvider.GetFileSize(file); var historyItems = _historyService.FindByDownloadId(downloadClientItem?.DownloadId ?? ""); var firstHistoryItem = historyItems?.OrderByDescending(h => h.Date)?.FirstOrDefault(); var sizeMovie = new LocalMovie(); sizeMovie.Size = size; localMovie = _parsingService.GetLocalMovie(file, minimalInfo, movie, new List <object> { mediaInfo, firstHistoryItem, sizeMovie, folderInfo }, sceneSource); localMovie.Quality = GetQuality(folderInfo, localMovie.Quality, movie); localMovie.Size = size; _logger.Debug("Size: {0}", localMovie.Size); decision = GetDecision(localMovie, downloadClientItem); } else { localMovie = new LocalMovie(); localMovie.Path = file; if (MediaFileExtensions.Extensions.Contains(Path.GetExtension(file))) { if (_warnedFiles.Find(file) == null) { _warnedFiles.Set(file, "warned"); _logger.Warn("Unable to parse movie info from path {0}", file); } else { _logger.Trace("Already warned user that we are unable to parse movie info from path: {0}", file); } } decision = new ImportDecision(localMovie, new Rejection("Unable to parse file")); } } catch (Exception e) { _logger.Error(e, "Couldn't import file. {0}", file); var localMovie = new LocalMovie { Path = file }; decision = new ImportDecision(localMovie, new Rejection("Unexpected error processing file")); } //LocalMovie nullMovie = null; //decision = new ImportDecision(nullMovie, new Rejection("IMPLEMENTATION MISSING!!!")); return(decision); }
public override IEnumerable <DownloadClientItem> GetItems() { List <UTorrentTorrent> torrents; try { var cacheKey = string.Format("{0}:{1}:{2}", Settings.Host, Settings.Port, Settings.TvCategory); var cache = _torrentCache.Find(cacheKey); var response = _proxy.GetTorrents(cache == null ? null : cache.CacheID, Settings); if (cache != null && response.Torrents == null) { var removedAndUpdated = new HashSet <string>(response.TorrentsChanged.Select(v => v.Hash).Concat(response.TorrentsRemoved)); torrents = cache.Torrents .Where(v => !removedAndUpdated.Contains(v.Hash)) .Concat(response.TorrentsChanged) .ToList(); } else { torrents = response.Torrents; } cache = new UTorrentTorrentCache { CacheID = response.CacheNumber, Torrents = torrents }; _torrentCache.Set(cacheKey, cache, TimeSpan.FromMinutes(15)); } catch (DownloadClientException ex) { _logger.Error(ex, ex.Message); return(Enumerable.Empty <DownloadClientItem>()); } var queueItems = new List <DownloadClientItem>(); foreach (var torrent in torrents) { if (torrent.Label != Settings.TvCategory) { continue; } var item = new DownloadClientItem(); item.DownloadId = torrent.Hash; item.Title = torrent.Name; item.TotalSize = torrent.Size; item.Category = torrent.Label; item.DownloadClient = Definition.Name; item.RemainingSize = torrent.Remaining; if (torrent.Eta != -1) { item.RemainingTime = TimeSpan.FromSeconds(torrent.Eta); } var outputPath = _remotePathMappingService.RemapRemoteToLocal(Settings.Host, new OsPath(torrent.RootDownloadPath)); if (outputPath == null || outputPath.FileName == torrent.Name) { item.OutputPath = outputPath; } else { item.OutputPath = outputPath + torrent.Name; } if (torrent.Status.HasFlag(UTorrentTorrentStatus.Error)) { item.Status = DownloadItemStatus.Warning; item.Message = "uTorrent is reporting an error"; } else if (torrent.Status.HasFlag(UTorrentTorrentStatus.Loaded) && torrent.Status.HasFlag(UTorrentTorrentStatus.Checked) && torrent.Remaining == 0 && torrent.Progress == 1.0) { item.Status = DownloadItemStatus.Completed; } else if (torrent.Status.HasFlag(UTorrentTorrentStatus.Paused)) { item.Status = DownloadItemStatus.Paused; } else if (torrent.Status.HasFlag(UTorrentTorrentStatus.Started)) { item.Status = DownloadItemStatus.Downloading; } else { item.Status = DownloadItemStatus.Queued; } // 'Started' without 'Queued' is when the torrent is 'forced seeding' item.IsReadOnly = torrent.Status.HasFlag(UTorrentTorrentStatus.Queued) || torrent.Status.HasFlag(UTorrentTorrentStatus.Started); queueItems.Add(item); } return(queueItems); }
private object DownloadRelease(ReleaseResource release) { var remoteBook = _remoteBookCache.Find(GetCacheKey(release)); if (remoteBook == null) { _logger.Debug("Couldn't find requested release in cache, cache timeout probably expired."); throw new NzbDroneClientException(HttpStatusCode.NotFound, "Couldn't find requested release in cache, try searching again"); } try { if (remoteBook.Author == null) { if (release.BookId.HasValue) { var book = _bookService.GetBook(release.BookId.Value); remoteBook.Author = _authorService.GetAuthor(book.AuthorId); remoteBook.Books = new List <Book> { book }; } else if (release.AuthorId.HasValue) { var author = _authorService.GetAuthor(release.AuthorId.Value); var books = _parsingService.GetBooks(remoteBook.ParsedBookInfo, author); if (books.Empty()) { throw new NzbDroneClientException(HttpStatusCode.NotFound, "Unable to parse books in the release"); } remoteBook.Author = author; remoteBook.Books = books; } else { throw new NzbDroneClientException(HttpStatusCode.NotFound, "Unable to find matching author and books"); } } else if (remoteBook.Books.Empty()) { var books = _parsingService.GetBooks(remoteBook.ParsedBookInfo, remoteBook.Author); if (books.Empty() && release.BookId.HasValue) { var book = _bookService.GetBook(release.BookId.Value); books = new List <Book> { book }; } remoteBook.Books = books; } if (remoteBook.Books.Empty()) { throw new NzbDroneClientException(HttpStatusCode.NotFound, "Unable to parse books in the release"); } _downloadService.DownloadReport(remoteBook); } catch (ReleaseDownloadException ex) { _logger.Error(ex, "Getting release from indexer failed"); throw new NzbDroneClientException(HttpStatusCode.Conflict, "Getting release from indexer failed"); } return(release); }
public DateTime GetNextExecution(Type type) { var scheduledTask = _cache.Find(type.FullName); return(scheduledTask.LastExecution.AddMinutes(scheduledTask.Interval)); }
public List <SceneMapping> FindByTvdbid(int tvdbId) { return(_findbytvdbIdCache.Find(tvdbId.ToString())); }
private object DownloadRelease(ReleaseResource release) { var remoteEpisode = _remoteEpisodeCache.Find(GetCacheKey(release)); if (remoteEpisode == null) { _logger.Debug("Couldn't find requested release in cache, cache timeout probably expired."); throw new NzbDroneClientException(HttpStatusCode.NotFound, "Couldn't find requested release in cache, try searching again"); } try { if (remoteEpisode.Series == null) { if (release.EpisodeId.HasValue) { var episode = _episodeService.GetEpisode(release.EpisodeId.Value); remoteEpisode.Series = _seriesService.GetSeries(episode.SeriesId); remoteEpisode.Episodes = new List <Episode> { episode }; } else if (release.SeriesId.HasValue) { var series = _seriesService.GetSeries(release.SeriesId.Value); var episodes = _parsingService.GetEpisodes(remoteEpisode.ParsedEpisodeInfo, series, true); if (episodes.Empty()) { throw new NzbDroneClientException(HttpStatusCode.NotFound, "Unable to parse episodes in the release"); } remoteEpisode.Series = series; remoteEpisode.Episodes = episodes; } else { throw new NzbDroneClientException(HttpStatusCode.NotFound, "Unable to find matching series and episodes"); } } else if (remoteEpisode.Episodes.Empty()) { var episodes = _parsingService.GetEpisodes(remoteEpisode.ParsedEpisodeInfo, remoteEpisode.Series, true); if (episodes.Empty() && release.EpisodeId.HasValue) { var episode = _episodeService.GetEpisode(release.EpisodeId.Value); episodes = new List <Episode> { episode }; } remoteEpisode.Episodes = episodes; } if (remoteEpisode.Episodes.Empty()) { throw new NzbDroneClientException(HttpStatusCode.NotFound, "Unable to parse episodes in the release"); } _downloadService.DownloadReport(remoteEpisode); } catch (ReleaseDownloadException ex) { _logger.Error(ex, ex.Message); throw new NzbDroneClientException(HttpStatusCode.Conflict, "Getting release from indexer failed"); } return(release); }
private object DownloadRelease(ReleaseResource release) { var remoteAlbum = _remoteAlbumCache.Find(GetCacheKey(release)); if (remoteAlbum == null) { _logger.Debug("Couldn't find requested release in cache, cache timeout probably expired."); throw new NzbDroneClientException(HttpStatusCode.NotFound, "Couldn't find requested release in cache, try searching again"); } try { if (remoteAlbum.Artist == null) { if (release.AlbumId.HasValue) { var album = _albumService.GetAlbum(release.AlbumId.Value); remoteAlbum.Artist = _artistService.GetArtist(album.ArtistId); remoteAlbum.Albums = new List <Album> { album }; } else if (release.ArtistId.HasValue) { var artist = _artistService.GetArtist(release.ArtistId.Value); var albums = _parsingService.GetAlbums(remoteAlbum.ParsedAlbumInfo, artist); if (albums.Empty()) { throw new NzbDroneClientException(HttpStatusCode.NotFound, "Unable to parse albums in the release"); } remoteAlbum.Artist = artist; remoteAlbum.Albums = albums; } else { throw new NzbDroneClientException(HttpStatusCode.NotFound, "Unable to find matching artist and albums"); } } else if (remoteAlbum.Albums.Empty()) { var albums = _parsingService.GetAlbums(remoteAlbum.ParsedAlbumInfo, remoteAlbum.Artist); if (albums.Empty() && release.AlbumId.HasValue) { var album = _albumService.GetAlbum(release.AlbumId.Value); albums = new List <Album> { album }; } remoteAlbum.Albums = albums; } if (remoteAlbum.Albums.Empty()) { throw new NzbDroneClientException(HttpStatusCode.NotFound, "Unable to parse albums in the release"); } _downloadService.DownloadReport(remoteAlbum); } catch (ReleaseDownloadException ex) { _logger.Error(ex, ex.Message); throw new NzbDroneClientException(HttpStatusCode.Conflict, "Getting release from indexer failed"); } return(release); }