private Response Search() { if (Request.Query.Id == 0) { //Todo error handling } Profile tempProfile = _profileService.All().First(); 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); if (parsedTitle == null) { m = new Core.Movies.Movie { Title = f.Name.Replace(".", " ").Replace("-", " "), Path = f.Path, Profile = tempProfile }; } else { parsedTitle.ImdbId = Parser.ParseImdbId(parsedTitle.SimpleReleaseTitle); m = new Core.Movies.Movie { Title = parsedTitle.MovieTitle, Year = parsedTitle.Year, ImdbId = parsedTitle.ImdbId, Path = f.Path, Profile = tempProfile }; } 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()); }
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 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); }
public TrackedDownload TrackDownload(DownloadClientDefinition downloadClient, DownloadClientItem downloadItem) { var existingItem = Find(downloadItem.DownloadId); if (existingItem != null && existingItem.State != TrackedDownloadState.Downloading) { LogItemChange(existingItem, existingItem.DownloadItem, downloadItem); existingItem.DownloadItem = downloadItem; existingItem.IsTrackable = true; return(existingItem); } var trackedDownload = new TrackedDownload { DownloadClient = downloadClient.Id, DownloadItem = downloadItem, Protocol = downloadClient.Protocol, IsTrackable = true }; try { var historyItems = _historyService.FindByDownloadId(downloadItem.DownloadId) .OrderByDescending(h => h.Date) .ToList(); var grabbedHistoryItem = historyItems.FirstOrDefault(h => h.EventType == MovieHistoryEventType.Grabbed); //TODO: Create release info from history and use that here, so we don't loose indexer flags! var parsedMovieInfo = _parsingService.ParseMovieInfo(trackedDownload.DownloadItem.Title, new List <object> { grabbedHistoryItem }); if (parsedMovieInfo != null) { trackedDownload.RemoteMovie = _parsingService.Map(parsedMovieInfo, "", null).RemoteMovie; } var downloadHistory = _downloadHistoryService.GetLatestDownloadHistoryItem(downloadItem.DownloadId); if (downloadHistory != null) { var state = GetStateFromHistory(downloadHistory.EventType); trackedDownload.State = state; } if (historyItems.Any()) { var firstHistoryItem = historyItems.FirstOrDefault(); var grabbedEvent = historyItems.FirstOrDefault(v => v.EventType == MovieHistoryEventType.Grabbed); trackedDownload.Indexer = grabbedEvent?.Data["indexer"]; if (parsedMovieInfo == null || trackedDownload.RemoteMovie == null || trackedDownload.RemoteMovie.Movie == null) { parsedMovieInfo = _parsingService.ParseMovieInfo(firstHistoryItem.SourceTitle, new List <object> { grabbedHistoryItem }); if (parsedMovieInfo != null) { trackedDownload.RemoteMovie = _parsingService.Map(parsedMovieInfo, "", null).RemoteMovie; } } } // Calculate custom formats if (trackedDownload.RemoteMovie != null) { trackedDownload.RemoteMovie.CustomFormats = _formatCalculator.ParseCustomFormat(parsedMovieInfo); } // Track it so it can be displayed in the queue even though we can't determine which movie it is for if (trackedDownload.RemoteMovie == null) { _logger.Trace("No Movie found for download '{0}'", trackedDownload.DownloadItem.Title); } } catch (Exception e) { _logger.Debug(e, "Failed to find movie for " + downloadItem.Title); return(null); } LogItemChange(trackedDownload, existingItem?.DownloadItem, trackedDownload.DownloadItem); _cache.Set(trackedDownload.DownloadItem.DownloadId, trackedDownload); return(trackedDownload); }
public TrackedDownload TrackDownload(DownloadClientDefinition downloadClient, DownloadClientItem downloadItem) { var existingItem = Find(downloadItem.DownloadId); if (existingItem != null && existingItem.State != TrackedDownloadStage.Downloading) { LogItemChange(existingItem, existingItem.DownloadItem, downloadItem); existingItem.DownloadItem = downloadItem; existingItem.IsTrackable = true; return(existingItem); } var trackedDownload = new TrackedDownload { DownloadClient = downloadClient.Id, DownloadItem = downloadItem, Protocol = downloadClient.Protocol, IsTrackable = true }; try { var parsedAlbumInfo = Parser.Parser.ParseAlbumTitle(trackedDownload.DownloadItem.Title); var historyItems = _historyService.FindByDownloadId(downloadItem.DownloadId); if (parsedAlbumInfo != null) { trackedDownload.RemoteAlbum = _parsingService.Map(parsedAlbumInfo); } if (historyItems.Any()) { var firstHistoryItem = historyItems.OrderByDescending(h => h.Date).First(); trackedDownload.State = GetStateFromHistory(firstHistoryItem); if (firstHistoryItem.EventType == HistoryEventType.AlbumImportIncomplete) { var messages = Json.Deserialize <List <TrackedDownloadStatusMessage> >(firstHistoryItem?.Data["statusMessages"]).ToArray(); trackedDownload.Warn(messages); } var grabbedEvent = historyItems.FirstOrDefault(v => v.EventType == HistoryEventType.Grabbed); trackedDownload.Indexer = grabbedEvent?.Data["indexer"]; if (parsedAlbumInfo == null || trackedDownload.RemoteAlbum == null || trackedDownload.RemoteAlbum.Artist == null || trackedDownload.RemoteAlbum.Albums.Empty()) { // Try parsing the original source title and if that fails, try parsing it as a special // TODO: Pass the TVDB ID and TVRage IDs in as well so we have a better chance for finding the item var historyArtist = firstHistoryItem.Artist; var historyAlbums = new List <Album> { firstHistoryItem.Album }; parsedAlbumInfo = Parser.Parser.ParseAlbumTitle(firstHistoryItem.SourceTitle); if (parsedAlbumInfo != null) { trackedDownload.RemoteAlbum = _parsingService.Map(parsedAlbumInfo, firstHistoryItem.ArtistId, historyItems.Where(v => v.EventType == HistoryEventType.Grabbed).Select(h => h.AlbumId) .Distinct()); } else { parsedAlbumInfo = Parser.Parser.ParseAlbumTitleWithSearchCriteria(firstHistoryItem.SourceTitle, historyArtist, historyAlbums); if (parsedAlbumInfo != null) { trackedDownload.RemoteAlbum = _parsingService.Map(parsedAlbumInfo, firstHistoryItem.ArtistId, historyItems.Where(v => v.EventType == HistoryEventType.Grabbed).Select(h => h.AlbumId) .Distinct()); } } } } // Track it so it can be displayed in the queue even though we can't determine which artist it is for if (trackedDownload.RemoteAlbum == null) { _logger.Trace("No Album found for download '{0}'", trackedDownload.DownloadItem.Title); trackedDownload.Warn("No Album found for download '{0}'", trackedDownload.DownloadItem.Title); } } catch (Exception e) { _logger.Debug(e, "Failed to find album for " + downloadItem.Title); return(null); } LogItemChange(trackedDownload, existingItem?.DownloadItem, trackedDownload.DownloadItem); _cache.Set(trackedDownload.DownloadItem.DownloadId, trackedDownload); return(trackedDownload); }
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 void Handle(ApplicationStartedEvent message) { var defaultTasks = new List <ScheduledTask> { new ScheduledTask { Interval = 5, TypeName = typeof(MessagingCleanupCommand).FullName }, new ScheduledTask { Interval = 6 * 60, TypeName = typeof(ApplicationCheckUpdateCommand).FullName }, new ScheduledTask { Interval = 6 * 60, TypeName = typeof(CheckHealthCommand).FullName }, new ScheduledTask { Interval = 24 * 60, TypeName = typeof(HousekeepingCommand).FullName }, new ScheduledTask { Interval = 24 * 60, TypeName = typeof(CleanUpHistoryCommand).FullName }, new ScheduledTask { Interval = 24 * 60, TypeName = typeof(IndexerDefinitionUpdateCommand).FullName }, new ScheduledTask { Interval = 6 * 60, TypeName = typeof(ApplicationIndexerSyncCommand).FullName }, new ScheduledTask { Interval = GetBackupInterval(), TypeName = typeof(BackupCommand).FullName } }; var currentTasks = _scheduledTaskRepository.All().ToList(); _logger.Trace("Initializing jobs. Available: {0} Existing: {1}", defaultTasks.Count, currentTasks.Count); foreach (var job in currentTasks) { if (!defaultTasks.Any(c => c.TypeName == job.TypeName)) { _logger.Trace("Removing job from database '{0}'", job.TypeName); _scheduledTaskRepository.Delete(job.Id); } } foreach (var defaultTask in defaultTasks) { var currentDefinition = currentTasks.SingleOrDefault(c => c.TypeName == defaultTask.TypeName) ?? defaultTask; currentDefinition.Interval = defaultTask.Interval; if (currentDefinition.Id == 0) { currentDefinition.LastExecution = DateTime.UtcNow; } currentDefinition.Priority = defaultTask.Priority; _cache.Set(currentDefinition.TypeName, currentDefinition); _scheduledTaskRepository.Upsert(currentDefinition); } }
public static void cacheuserView(string tokenValue, V_xy_sp_userView userView) { _cached.Set(tokenValue, userView); }
/// <summary> /// 缓存信息 /// </summary> /// <param name="tokenValue"></param> /// <param name="userInfo"></param> public void CacheInfo(string tokenValue, object userInfo) { _cached.Set(tokenValue, userInfo, CacheTime); }
public TrackedDownload TrackDownload(DownloadClientDefinition downloadClient, DownloadClientItem downloadItem) { var existingItem = Find(downloadItem.DownloadId); if (existingItem != null && existingItem.State != TrackedDownloadState.Downloading) { LogItemChange(existingItem, existingItem.DownloadItem, downloadItem); existingItem.DownloadItem = downloadItem; existingItem.IsTrackable = true; return(existingItem); } var trackedDownload = new TrackedDownload { DownloadClient = downloadClient.Id, DownloadItem = downloadItem, Protocol = downloadClient.Protocol, IsTrackable = true }; try { var parsedEpisodeInfo = Parser.Parser.ParseTitle(trackedDownload.DownloadItem.Title); var historyItems = _historyService.FindByDownloadId(downloadItem.DownloadId) .OrderByDescending(h => h.Date) .ToList(); if (parsedEpisodeInfo != null) { trackedDownload.RemoteEpisode = _parsingService.Map(parsedEpisodeInfo, 0, 0); } var downloadHistory = _downloadHistoryService.GetLatestDownloadHistoryItem(downloadItem.DownloadId); if (downloadHistory != null) { var state = GetStateFromHistory(downloadHistory.EventType); trackedDownload.State = state; } if (historyItems.Any()) { var firstHistoryItem = historyItems.First(); var grabbedEvent = historyItems.FirstOrDefault(v => v.EventType == EpisodeHistoryEventType.Grabbed); trackedDownload.Indexer = grabbedEvent?.Data["indexer"]; if (parsedEpisodeInfo == null || trackedDownload.RemoteEpisode == null || trackedDownload.RemoteEpisode.Series == null || trackedDownload.RemoteEpisode.Episodes.Empty()) { // Try parsing the original source title and if that fails, try parsing it as a special // TODO: Pass the TVDB ID and TVRage IDs in as well so we have a better chance for finding the item parsedEpisodeInfo = Parser.Parser.ParseTitle(firstHistoryItem.SourceTitle) ?? _parsingService.ParseSpecialEpisodeTitle(parsedEpisodeInfo, firstHistoryItem.SourceTitle, 0, 0); if (parsedEpisodeInfo != null) { trackedDownload.RemoteEpisode = _parsingService.Map(parsedEpisodeInfo, firstHistoryItem.SeriesId, historyItems.Where(v => v.EventType == EpisodeHistoryEventType.Grabbed).Select(h => h.EpisodeId).Distinct()); } } } // Track it so it can be displayed in the queue even though we can't determine which series it is for if (trackedDownload.RemoteEpisode == null) { _logger.Trace("No Episode found for download '{0}'", trackedDownload.DownloadItem.Title); } } catch (Exception e) { _logger.Debug(e, "Failed to find episode for " + downloadItem.Title); return(null); } LogItemChange(trackedDownload, existingItem?.DownloadItem, trackedDownload.DownloadItem); _cache.Set(trackedDownload.DownloadItem.DownloadId, trackedDownload); return(trackedDownload); }
public TrackedDownload TrackDownload(DownloadClientDefinition downloadClient, DownloadClientItem downloadItem) { if (downloadItem.DownloadId.IsNullOrWhiteSpace()) { _logger.Warn("The following download client item ({0}) has no download hash (id), so it cannot be tracked: {1}", downloadClient.Name, downloadItem.Title); return(null); } if (downloadItem.Title.IsNullOrWhiteSpace()) { _logger.Warn("The following download client item ({0}) has no title so it cannot be tracked: {1}", downloadClient.Name, downloadItem.Title); return(null); } var existingItem = Find(downloadItem.DownloadId); if (existingItem != null && existingItem.State != TrackedDownloadStage.Downloading) { existingItem.DownloadItem = downloadItem; return(existingItem); } var trackedDownload = new TrackedDownload { DownloadClient = downloadClient.Id, DownloadItem = downloadItem, Protocol = downloadClient.Protocol }; try { var historyItems = _historyService.FindByDownloadId(downloadItem.DownloadId); var grabbedHistoryItem = historyItems.OrderByDescending(h => h.Date).FirstOrDefault(h => h.EventType == HistoryEventType.Grabbed); var firstHistoryItem = historyItems.OrderByDescending(h => h.Date).FirstOrDefault(); //TODO: Create release info from history and use that here, so we don't loose indexer flags! var parsedMovieInfo = _parsingService.ParseMovieInfo(trackedDownload.DownloadItem.Title, new List <object> { grabbedHistoryItem }); if (parsedMovieInfo != null) { trackedDownload.RemoteMovie = _parsingService.Map(parsedMovieInfo, "", null).RemoteMovie; } if (firstHistoryItem != null) { trackedDownload.State = GetStateFromHistory(firstHistoryItem.EventType); if (parsedMovieInfo == null || trackedDownload.RemoteMovie == null || trackedDownload.RemoteMovie.Movie == null) { parsedMovieInfo = _parsingService.ParseMovieInfo(firstHistoryItem.SourceTitle, new List <object> { grabbedHistoryItem }); if (parsedMovieInfo != null) { trackedDownload.RemoteMovie = _parsingService.Map(parsedMovieInfo, "", null).RemoteMovie; } } } if (trackedDownload.RemoteMovie == null) { return(null); } } catch (Exception e) { _logger.Debug(e, "Failed to find movie for " + downloadItem.Title); return(null); } _cache.Set(trackedDownload.DownloadItem.DownloadId, trackedDownload); return(trackedDownload); }
public void SetStringToRedis() { bool result = cacheClient.Set <string>("kitchen:test", "1234567", 10); Assert.IsTrue(result); }
protected override ReleaseResource MapDecision(DownloadDecision decision, int initialWeight) { _remoteMovieCache.Set(decision.RemoteMovie.Release.Guid, decision.RemoteMovie, TimeSpan.FromMinutes(30)); return(base.MapDecision(decision, initialWeight)); }
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 TrackDownload(DownloadClientDefinition downloadClient, DownloadClientItem downloadItem) { var existingItem = Find(downloadItem.DownloadId); if (existingItem != null && existingItem.State != TrackedDownloadStage.Downloading) { existingItem.DownloadItem = downloadItem; return(existingItem); } var trackedDownload = new TrackedDownload { DownloadClient = downloadClient.Id, DownloadItem = downloadItem, Protocol = downloadClient.Protocol }; try { var parsedEpisodeInfo = Parser.Parser.ParseTitle(trackedDownload.DownloadItem.Title); var historyItems = _historyService.FindByDownloadId(downloadItem.DownloadId); if (parsedEpisodeInfo != null) { trackedDownload.RemoteEpisode = _parsingService.Map(parsedEpisodeInfo, 0, 0); } if (historyItems.Any()) { var firstHistoryItem = historyItems.OrderByDescending(h => h.Date).First(); trackedDownload.State = GetStateFromHistory(firstHistoryItem.EventType); if (parsedEpisodeInfo == null || trackedDownload.RemoteEpisode == null || trackedDownload.RemoteEpisode.Series == null || trackedDownload.RemoteEpisode.Episodes.Empty()) { // Try parsing the original source title and if that fails, try parsing it as a special // TODO: Pass the TVDB ID and TVRage IDs in as well so we have a better chance for finding the item parsedEpisodeInfo = Parser.Parser.ParseTitle(firstHistoryItem.SourceTitle) ?? _parsingService.ParseSpecialEpisodeTitle(firstHistoryItem.SourceTitle, 0, 0); if (parsedEpisodeInfo != null) { trackedDownload.RemoteEpisode = _parsingService.Map(parsedEpisodeInfo, firstHistoryItem.SeriesId, historyItems.Where(v => v.EventType == HistoryEventType.Grabbed).Select(h => h.EpisodeId).Distinct()); } } } if (trackedDownload.RemoteEpisode == null) { return(null); } } catch (Exception e) { _logger.DebugException("Failed to find episode for " + downloadItem.Title, e); return(null); } _cache.Set(trackedDownload.DownloadItem.DownloadId, trackedDownload); return(trackedDownload); }
public TrackedDownload TrackDownload(DownloadClientDefinition downloadClient, DownloadClientItem downloadItem) { var existingItem = Find(downloadItem.DownloadId); if (existingItem != null && existingItem.State != TrackedDownloadState.Downloading) { LogItemChange(existingItem, existingItem.DownloadItem, downloadItem); existingItem.DownloadItem = downloadItem; existingItem.IsTrackable = true; return(existingItem); } var trackedDownload = new TrackedDownload { DownloadClient = downloadClient.Id, DownloadItem = downloadItem, Protocol = downloadClient.Protocol, IsTrackable = true }; try { var parsedBookInfo = Parser.Parser.ParseBookTitle(trackedDownload.DownloadItem.Title); var historyItems = _historyService.FindByDownloadId(downloadItem.DownloadId) .OrderByDescending(h => h.Date) .ToList(); if (parsedBookInfo != null) { trackedDownload.RemoteBook = _parsingService.Map(parsedBookInfo); } if (historyItems.Any()) { var firstHistoryItem = historyItems.First(); var state = GetStateFromHistory(firstHistoryItem); // One potential issue here is if the latest is imported, but other episodes are ignored or never imported. // It's unlikely that will happen, but could happen if additional episodes are added to season after it's already imported. if (state == TrackedDownloadState.Imported) { var allImported = _trackedDownloadAlreadyImported.IsImported(trackedDownload, historyItems); trackedDownload.State = allImported ? TrackedDownloadState.Imported : TrackedDownloadState.Downloading; } else { trackedDownload.State = state; } if (firstHistoryItem.EventType == HistoryEventType.BookImportIncomplete) { var messages = Json.Deserialize <List <TrackedDownloadStatusMessage> >(firstHistoryItem?.Data["statusMessages"]).ToArray(); trackedDownload.Warn(messages); } var grabbedEvent = historyItems.FirstOrDefault(v => v.EventType == HistoryEventType.Grabbed); trackedDownload.Indexer = grabbedEvent?.Data["indexer"]; if (parsedBookInfo == null || trackedDownload.RemoteBook == null || trackedDownload.RemoteBook.Author == null || trackedDownload.RemoteBook.Books.Empty()) { // Try parsing the original source title and if that fails, try parsing it as a special // TODO: Pass the TVDB ID and TVRage IDs in as well so we have a better chance for finding the item var historyAuthor = firstHistoryItem.Author; var historyBooks = new List <Book> { firstHistoryItem.Book }; parsedBookInfo = Parser.Parser.ParseBookTitle(firstHistoryItem.SourceTitle); if (parsedBookInfo != null) { trackedDownload.RemoteBook = _parsingService.Map(parsedBookInfo, firstHistoryItem.AuthorId, historyItems.Where(v => v.EventType == HistoryEventType.Grabbed).Select(h => h.BookId) .Distinct()); } else { parsedBookInfo = Parser.Parser.ParseBookTitleWithSearchCriteria(firstHistoryItem.SourceTitle, historyAuthor, historyBooks); if (parsedBookInfo != null) { trackedDownload.RemoteBook = _parsingService.Map(parsedBookInfo, firstHistoryItem.AuthorId, historyItems.Where(v => v.EventType == HistoryEventType.Grabbed).Select(h => h.BookId) .Distinct()); } } } } // Track it so it can be displayed in the queue even though we can't determine which author it is for if (trackedDownload.RemoteBook == null) { _logger.Trace("No Book found for download '{0}'", trackedDownload.DownloadItem.Title); trackedDownload.Warn("No Book found for download '{0}'", trackedDownload.DownloadItem.Title); } } catch (Exception e) { _logger.Debug(e, "Failed to find book for " + downloadItem.Title); return(null); } LogItemChange(trackedDownload, existingItem?.DownloadItem, trackedDownload.DownloadItem); _cache.Set(trackedDownload.DownloadItem.DownloadId, trackedDownload); return(trackedDownload); }
public TrackedDownload TrackDownload(DownloadClientDefinition downloadClient, DownloadClientItem downloadItem) { var existingItem = Find(downloadItem.DownloadId); if (existingItem != null && existingItem.State != TrackedDownloadState.Downloading) { LogItemChange(existingItem, existingItem.DownloadItem, downloadItem); existingItem.DownloadItem = downloadItem; existingItem.IsTrackable = true; return(existingItem); } var trackedDownload = new TrackedDownload { DownloadClient = downloadClient.Id, DownloadItem = downloadItem, Protocol = downloadClient.Protocol, IsTrackable = true }; try { var parsedEpisodeInfo = Parser.Parser.ParseTitle(trackedDownload.DownloadItem.Title); var historyItems = _historyService.FindByDownloadId(downloadItem.DownloadId) .OrderByDescending(h => h.Date) .ToList(); if (parsedEpisodeInfo != null) { trackedDownload.RemoteEpisode = _parsingService.Map(parsedEpisodeInfo, 0, 0); } if (historyItems.Any()) { var firstHistoryItem = historyItems.First(); var state = GetStateFromHistory(firstHistoryItem.EventType); trackedDownload.State = state; // TODO: Restore check to confirm all files were imported // This will treat partially imported downloads as imported (as it was before), which means a partially imported download after a // restart will get marked as imported without importing the restart of the files. // One potential issue here is if the latest is imported, but other episodes are ignored or never imported. // It's unlikely that will happen, but could happen if additional episodes are added to season after it's already imported. // if (state == TrackedDownloadState.Imported) // { // trackedDownload.State = TrackedDownloadState.Imported; // // var allImported = _trackedDownloadAlreadyImported.IsImported(trackedDownload, historyItems); // // trackedDownload.State = allImported ? TrackedDownloadState.Imported : TrackedDownloadState.Downloading; // } // else // { // trackedDownload.State = state; // } var grabbedEvent = historyItems.FirstOrDefault(v => v.EventType == HistoryEventType.Grabbed); trackedDownload.Indexer = grabbedEvent?.Data["indexer"]; if (parsedEpisodeInfo == null || trackedDownload.RemoteEpisode == null || trackedDownload.RemoteEpisode.Series == null || trackedDownload.RemoteEpisode.Episodes.Empty()) { // Try parsing the original source title and if that fails, try parsing it as a special // TODO: Pass the TVDB ID and TVRage IDs in as well so we have a better chance for finding the item parsedEpisodeInfo = Parser.Parser.ParseTitle(firstHistoryItem.SourceTitle) ?? _parsingService.ParseSpecialEpisodeTitle(parsedEpisodeInfo, firstHistoryItem.SourceTitle, 0, 0); if (parsedEpisodeInfo != null) { trackedDownload.RemoteEpisode = _parsingService.Map(parsedEpisodeInfo, firstHistoryItem.SeriesId, historyItems.Where(v => v.EventType == HistoryEventType.Grabbed).Select(h => h.EpisodeId).Distinct()); } } } // Track it so it can be displayed in the queue even though we can't determine which serires it is for if (trackedDownload.RemoteEpisode == null) { _logger.Trace("No Episode found for download '{0}'", trackedDownload.DownloadItem.Title); } } catch (Exception e) { _logger.Debug(e, "Failed to find episode for " + downloadItem.Title); return(null); } LogItemChange(trackedDownload, existingItem?.DownloadItem, trackedDownload.DownloadItem); _cache.Set(trackedDownload.DownloadItem.DownloadId, trackedDownload); return(trackedDownload); }