public List <ImportResult> ProcessRootFolder(DirectoryInfo directoryInfo) { var results = new List <ImportResult>(); foreach (var subFolder in _diskProvider.GetDirectories(directoryInfo.FullName)) { var folderResults = ProcessFolder(new DirectoryInfo(subFolder)); results.AddRange(folderResults); } foreach (var videoFile in _diskScanService.GetVideoFiles(directoryInfo.FullName, false)) { var fileResults = ProcessFile(new FileInfo(videoFile)); results.AddRange(fileResults); } return(results); }
private List<ManualImportItem> ProcessFolder(string rootFolder, string baseFolder, string downloadId, int? movieId, bool filterExistingFiles) { DownloadClientItem downloadClientItem = null; var directoryInfo = new DirectoryInfo(baseFolder); var movie = movieId.HasValue ? _movieService.GetMovie(movieId.Value) : _parsingService.GetMovie(directoryInfo.Name); if (downloadId.IsNotNullOrWhiteSpace()) { var trackedDownload = _trackedDownloadService.Find(downloadId); downloadClientItem = trackedDownload.DownloadItem; if (movie == null) { movie = trackedDownload.RemoteMovie?.Movie; } } if (movie == null) { // Filter paths based on the rootFolder, so files in subfolders that should be ignored are ignored. // It will lead to some extra directories being checked for files, but it saves the processing of them and is cleaner than // teaching FilterPaths to know whether it's processing a file or a folder and changing it's filtering based on that. var files = _diskScanService.FilterPaths(rootFolder, _diskScanService.GetVideoFiles(baseFolder, false)); var subfolders = _diskScanService.FilterPaths(rootFolder, _diskProvider.GetDirectories(baseFolder)); var processedFiles = files.Select(file => ProcessFile(rootFolder, baseFolder, file, downloadId)); var processedFolders = subfolders.SelectMany(subfolder => ProcessFolder(rootFolder, subfolder, downloadId, null, filterExistingFiles)); return processedFiles.Concat(processedFolders).Where(i => i != null).ToList(); } var folderInfo = Parser.Parser.ParseMovieTitle(directoryInfo.Name); var movieFiles = _diskScanService.FilterPaths(rootFolder, _diskScanService.GetVideoFiles(baseFolder).ToList()); var decisions = _importDecisionMaker.GetImportDecisions(movieFiles, movie, downloadClientItem, folderInfo, SceneSource(movie, baseFolder), filterExistingFiles); return decisions.Select(decision => MapItem(decision, rootFolder, downloadId, directoryInfo.Name)).ToList(); }
public object GetMediaFiles(string path) { if (!_diskProvider.FolderExists(path)) { return(Array.Empty <string>()); } return(_diskScanService.GetVideoFiles(path).Select(f => new { Path = f, RelativePath = path.GetRelativePath(f), Name = Path.GetFileName(f) })); }
private List <ManualImportItem> ProcessFolder(string rootFolder, string baseFolder, string downloadId, int?seriesId, bool filterExistingFiles) { DownloadClientItem downloadClientItem = null; var directoryInfo = new DirectoryInfo(baseFolder); var series = seriesId.HasValue ? _seriesService.GetSeries(seriesId.Value) : _parsingService.GetSeries(directoryInfo.Name); if (downloadId.IsNotNullOrWhiteSpace()) { var trackedDownload = _trackedDownloadService.Find(downloadId); downloadClientItem = trackedDownload.DownloadItem; if (series == null) { series = trackedDownload.RemoteEpisode?.Series; } } if (series == null) { var files = _diskScanService.FilterFiles(baseFolder, _diskScanService.GetVideoFiles(baseFolder, false)); var subfolders = _diskScanService.FilterFiles(baseFolder, _diskProvider.GetDirectories(baseFolder)); var processedFiles = files.Select(file => ProcessFile(rootFolder, baseFolder, file, downloadId)); var processedFolders = subfolders.SelectMany(subfolder => ProcessFolder(rootFolder, subfolder, downloadId, null, filterExistingFiles)); return(processedFiles.Concat(processedFolders).Where(i => i != null).ToList()); } var folderInfo = Parser.Parser.ParseTitle(directoryInfo.Name); var seriesFiles = _diskScanService.GetVideoFiles(baseFolder).ToList(); var decisions = _importDecisionMaker.GetImportDecisions(seriesFiles, series, downloadClientItem, folderInfo, SceneSource(series, baseFolder), filterExistingFiles); return(decisions.Select(decision => MapItem(decision, rootFolder, downloadId, directoryInfo.Name)).ToList()); }
private List <ManualImportItem> ProcessFolder(string folder, string downloadId) { var directoryInfo = new DirectoryInfo(folder); var series = _parsingService.GetSeries(directoryInfo.Name); if (series == null && downloadId.IsNotNullOrWhiteSpace()) { var trackedDownload = _trackedDownloadService.Find(downloadId); series = trackedDownload.RemoteEpisode.Series; } if (series == null) { var files = _diskScanService.GetVideoFiles(folder); return(files.Select(file => ProcessFile(file, downloadId, folder)).Where(i => i != null).ToList()); } var folderInfo = Parser.Parser.ParseTitle(directoryInfo.Name); var seriesFiles = _diskScanService.GetVideoFiles(folder).ToList(); var decisions = _importDecisionMaker.GetImportDecisions(seriesFiles, series, folderInfo, SceneSource(series, folder)); return(decisions.Select(decision => MapItem(decision, folder, downloadId)).ToList()); }
private Response GetMediaFiles() { var pathQuery = Request.Query.path; var path = (string)pathQuery.Value; if (!_diskProvider.FolderExists(path)) { return(new string[0].AsResponse()); } return(_diskScanService.GetVideoFiles(path).Select(f => new { Path = f, RelativePath = path.GetRelativePath(f), Name = Path.GetFileName(f) }).AsResponse()); }
private object GetMediaFiles() { var pathQuery = Request.Query.path; var path = (string)pathQuery.Value; if (!_diskProvider.FolderExists(path)) { return(Array.Empty <string>()); } return(_diskScanService.GetVideoFiles(path).Select(f => new { Path = f, RelativePath = path.GetRelativePath(f), Name = Path.GetFileName(f) })); }
public override IEnumerable <DownloadClientItem> GetItems() { foreach (var folder in _diskProvider.GetDirectories(Settings.WatchFolder)) { var title = FileNameBuilder.CleanFileName(Path.GetFileName(folder)); var files = _diskProvider.GetFiles(folder, SearchOption.AllDirectories); var historyItem = new DownloadClientItem { DownloadClient = Definition.Name, DownloadClientId = Definition.Name + "_" + Path.GetFileName(folder) + "_" + _diskProvider.FolderGetCreationTimeUtc(folder).Ticks, Title = title, TotalSize = files.Select(_diskProvider.GetFileSize).Sum(), OutputPath = folder }; if (files.Any(_diskProvider.IsFileLocked)) { historyItem.Status = DownloadItemStatus.Downloading; } else { historyItem.Status = DownloadItemStatus.Completed; historyItem.RemainingTime = TimeSpan.Zero; } historyItem.RemoteEpisode = GetRemoteEpisode(historyItem.Title); if (historyItem.RemoteEpisode == null) { continue; } yield return(historyItem); } foreach (var videoFile in _diskScanService.GetVideoFiles(Settings.WatchFolder, false)) { var title = FileNameBuilder.CleanFileName(Path.GetFileName(videoFile)); var historyItem = new DownloadClientItem { DownloadClient = Definition.Name, DownloadClientId = Definition.Name + "_" + Path.GetFileName(videoFile) + "_" + _diskProvider.FileGetLastWriteUtc(videoFile).Ticks, Title = title, TotalSize = _diskProvider.GetFileSize(videoFile), OutputPath = videoFile }; if (_diskProvider.IsFileLocked(videoFile)) { historyItem.Status = DownloadItemStatus.Downloading; } else { historyItem.Status = DownloadItemStatus.Completed; historyItem.RemainingTime = TimeSpan.Zero; } historyItem.RemoteEpisode = GetRemoteEpisode(historyItem.Title); if (historyItem.RemoteEpisode == null) { continue; } yield return(historyItem); } }
private IEnumerable <WatchFolderItem> GetDownloadItems(string watchFolder, Dictionary <string, WatchFolderItem> lastWatchItems, TimeSpan waitPeriod) { // get a fresh naming config each time, in case the user has made changes foreach (var folder in _diskProvider.GetDirectories(watchFolder)) { var title = FileNameBuilder.CleanFileName(Path.GetFileName(folder)); var newWatchItem = new WatchFolderItem { DownloadId = Path.GetFileName(folder) + "_" + _diskProvider.FolderGetCreationTime(folder).Ticks, Title = title, OutputPath = new OsPath(folder), Status = DownloadItemStatus.Completed, RemainingTime = TimeSpan.Zero }; var oldWatchItem = lastWatchItems.GetValueOrDefault(newWatchItem.DownloadId); if (PreCheckWatchItemExpiry(newWatchItem, oldWatchItem)) { var files = _diskProvider.GetFiles(folder, SearchOption.AllDirectories); newWatchItem.TotalSize = files.Select(_diskProvider.GetFileSize).Sum(); newWatchItem.Hash = GetHash(folder, files); if (files.Any(_diskProvider.IsFileLocked)) { newWatchItem.Status = DownloadItemStatus.Downloading; newWatchItem.RemainingTime = null; } UpdateWatchItemExpiry(newWatchItem, oldWatchItem, waitPeriod); } yield return(newWatchItem); } foreach (var videoFile in _diskScanService.GetVideoFiles(watchFolder, false)) { var title = FileNameBuilder.CleanFileName(Path.GetFileName(videoFile)); var newWatchItem = new WatchFolderItem { DownloadId = Path.GetFileName(videoFile) + "_" + _diskProvider.FileGetLastWrite(videoFile).Ticks, Title = title, OutputPath = new OsPath(videoFile), Status = DownloadItemStatus.Completed, RemainingTime = TimeSpan.Zero }; var oldWatchItem = lastWatchItems.GetValueOrDefault(newWatchItem.DownloadId); if (PreCheckWatchItemExpiry(newWatchItem, oldWatchItem)) { newWatchItem.TotalSize = _diskProvider.GetFileSize(videoFile); newWatchItem.Hash = GetHash(videoFile); if (_diskProvider.IsFileLocked(videoFile)) { newWatchItem.Status = DownloadItemStatus.Downloading; } UpdateWatchItemExpiry(newWatchItem, oldWatchItem, waitPeriod); } yield return(newWatchItem); } }
private List <ManualImportItem> ProcessFolder(string rootFolder, string baseFolder, string downloadId, int?seriesId, bool filterExistingFiles) { DownloadClientItem downloadClientItem = null; Series series = null; var directoryInfo = new DirectoryInfo(baseFolder); if (seriesId.HasValue) { series = _seriesService.GetSeries(seriesId.Value); } else { try { series = _parsingService.GetSeries(directoryInfo.Name); } catch (MultipleSeriesFoundException e) { _logger.Warn(e, "Unable to find series from title"); } } if (downloadId.IsNotNullOrWhiteSpace()) { var trackedDownload = _trackedDownloadService.Find(downloadId); downloadClientItem = trackedDownload.DownloadItem; if (series == null) { series = trackedDownload.RemoteEpisode?.Series; } } if (series == null) { // Filter paths based on the rootFolder, so files in subfolders that should be ignored are ignored. // It will lead to some extra directories being checked for files, but it saves the processing of them and is cleaner than // teaching FilterPaths to know whether it's processing a file or a folder and changing it's filtering based on that. // If the series is unknown for the directory and there are more than 100 files in the folder don't process the items before returning. var files = _diskScanService.FilterPaths(rootFolder, _diskScanService.GetVideoFiles(baseFolder, false)); if (files.Count() > 100) { return(ProcessDownloadDirectory(rootFolder, files)); } var subfolders = _diskScanService.FilterPaths(rootFolder, _diskProvider.GetDirectories(baseFolder)); var processedFiles = files.Select(file => ProcessFile(rootFolder, baseFolder, file, downloadId)); var processedFolders = subfolders.SelectMany(subfolder => ProcessFolder(rootFolder, subfolder, downloadId, null, filterExistingFiles)); return(processedFiles.Concat(processedFolders).Where(i => i != null).ToList()); } var folderInfo = Parser.Parser.ParseTitle(directoryInfo.Name); var seriesFiles = _diskScanService.FilterPaths(rootFolder, _diskScanService.GetVideoFiles(baseFolder).ToList()); var decisions = _importDecisionMaker.GetImportDecisions(seriesFiles, series, downloadClientItem, folderInfo, SceneSource(series, baseFolder), filterExistingFiles); return(decisions.Select(decision => MapItem(decision, rootFolder, downloadId, directoryInfo.Name)).ToList()); }
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()); }