public void should_not_delete_if_there_is_large_rar_file()
        {
            GivenValidAuthor();

            var localTrack = new LocalBook();

            var imported = new List <ImportDecision <LocalBook> >();

            imported.Add(new ImportDecision <LocalBook>(localTrack));

            Mocker.GetMock <IMakeImportDecision>()
            .Setup(v => v.GetImportDecisions(It.IsAny <List <IFileInfo> >(), It.IsAny <IdentificationOverrides>(), It.IsAny <ImportDecisionMakerInfo>(), It.IsAny <ImportDecisionMakerConfig>()))
            .Returns(imported);

            Mocker.GetMock <IImportApprovedBooks>()
            .Setup(s => s.Import(It.IsAny <List <ImportDecision <LocalBook> > >(), true, null, ImportMode.Auto))
            .Returns(imported.Select(i => new ImportResult(i)).ToList());

            GivenAudioFiles(new[] { _audioFiles.First().Replace(".ext", ".rar") }, 15.Megabytes());

            Subject.ProcessRootFolder(DiskProvider.GetDirectoryInfo(_droneFactory));

            DiskProvider.FolderExists(_subFolders[0]).Should().BeTrue();

            ExceptionVerification.ExpectedWarns(1);
        }
        public void should_not_delete_if_no_files_were_imported()
        {
            GivenValidAuthor();

            var localTrack = new LocalBook();

            var imported = new List <ImportDecision <LocalBook> >();

            imported.Add(new ImportDecision <LocalBook>(localTrack));

            Mocker.GetMock <IMakeImportDecision>()
            .Setup(v => v.GetImportDecisions(It.IsAny <List <IFileInfo> >(), It.IsAny <IdentificationOverrides>(), It.IsAny <ImportDecisionMakerInfo>(), It.IsAny <ImportDecisionMakerConfig>()))
            .Returns(imported);

            Mocker.GetMock <IImportApprovedBooks>()
            .Setup(s => s.Import(It.IsAny <List <ImportDecision <LocalBook> > >(), true, null, ImportMode.Auto))
            .Returns(new List <ImportResult>());

            Subject.ProcessRootFolder(DiskProvider.GetDirectoryInfo(_droneFactory));

            DiskProvider.FolderExists(_subFolders[0]).Should().BeTrue();

            Mocker.GetMock <IDiskProvider>()
            .Verify(v => v.DeleteFolder(It.IsAny <string>(), true), Times.Never());
        }
예제 #3
0
        public virtual void Start(ProgressNotification notification, dynamic options)
        {
            string dropFolder;

            if (options != null && !String.IsNullOrWhiteSpace(options.Path))
            {
                dropFolder = options.Path;
            }

            else
            {
                dropFolder = _configProvider.DownloadClientTvDirectory;
            }

            if (String.IsNullOrWhiteSpace(dropFolder))
            {
                Logger.Debug("No drop folder is defined. Skipping.");
                return;
            }

            if (!_diskProvider.FolderExists(dropFolder))
            {
                Logger.Warn("Unable to Scan for New Downloads - folder Doesn't exist: [{0}]", dropFolder);
                return;
            }

            _postDownloadProvider.ProcessDropFolder(dropFolder);
        }
예제 #4
0
        public virtual void Add(RootDir rootDir)
        {
            if (String.IsNullOrWhiteSpace(rootDir.Path) || !Path.IsPathRooted(rootDir.Path))
            {
                throw new ArgumentException("Invalid path");
            }

            if (!_diskProvider.FolderExists(rootDir.Path))
            {
                throw new DirectoryNotFoundException("Can't add root directory that doesn't exist.");
            }

            if (GetAll().Exists(r => DiskProvider.PathEquals(r.Path, rootDir.Path)))
            {
                throw new InvalidOperationException("Root directory already exist.");
            }

            _database.Insert(rootDir);
        }
예제 #5
0
        private void Verify(string targetFolder)
        {
            logger.Info("Verifying requirements before update...");

            if (String.IsNullOrWhiteSpace(targetFolder))
            {
                throw new ArgumentException("Target folder can not be null or empty");
            }

            if (!_diskProvider.FolderExists(targetFolder))
            {
                throw new DirectoryNotFoundException("Target folder doesn't exist " + targetFolder);
            }

            logger.Info("Verifying Update Folder");
            if (!_diskProvider.FolderExists(_environmentProvider.GetUpdatePackageFolder()))
            {
                throw new DirectoryNotFoundException("Update folder doesn't exist " + _environmentProvider.GetUpdatePackageFolder());
            }
        }
        public void should_not_delete_folder_if_importmode_copy()
        {
            GivenValidAuthor();

            GivenSuccessfulImport();

            _trackedDownload.DownloadItem.CanMoveFiles = true;

            Subject.ProcessPath(_droneFactory, ImportMode.Copy, _trackedDownload.RemoteBook.Author, _trackedDownload.DownloadItem);

            DiskProvider.FolderExists(_subFolders[0]).Should().BeTrue();
        }
예제 #7
0
        public void should_not_create_if_artist_folder_does_not_exist_and_create_folder_disabled()
        {
            GivenRootFolder(_otherArtistFolder);

            Mocker.GetMock <IConfigService>()
            .Setup(s => s.CreateEmptyArtistFolders)
            .Returns(false);

            Subject.Scan(_artist);

            DiskProvider.FolderExists(_artist.Path).Should().BeFalse();
        }
예제 #8
0
        public void should_delete_folder_if_importmode_move()
        {
            GivenValidArtist();

            GivenSuccessfulImport();

            _trackedDownload.DownloadItem.CanMoveFiles = false;

            Subject.ProcessPath(_droneFactory, ImportMode.Move, _trackedDownload.RemoteAlbum.Artist, _trackedDownload.DownloadItem);

            DiskProvider.FolderExists(_subFolders[0]).Should().BeFalse();
        }
예제 #9
0
        public void should_clean_if_folder_does_not_exist()
        {
            GivenRootFolder(_otherArtistFolder);

            Subject.Scan(new List <string> {
                _artist.Path
            });

            DiskProvider.FolderExists(_artist.Path).Should().BeFalse();

            Mocker.GetMock <IMediaFileTableCleanupService>()
            .Verify(v => v.Clean(It.IsAny <string>(), It.IsAny <List <string> >()), Times.Once());
        }
예제 #10
0
        public void should_clean_but_not_import_if_artist_folder_does_not_exist()
        {
            GivenRootFolder(_otherArtistFolder);

            Subject.Scan(_artist);

            DiskProvider.FolderExists(_artist.Path).Should().BeFalse();

            Mocker.GetMock <IMediaFileTableCleanupService>()
            .Verify(v => v.Clean(It.IsAny <Artist>(), It.IsAny <List <string> >()), Times.Once());

            Mocker.GetMock <IMakeImportDecision>()
            .Verify(v => v.GetImportDecisions(It.IsAny <List <IFileInfo> >(), _artist, FilterFilesType.Known, true), Times.Never());
        }
예제 #11
0
        public virtual void Start(ProgressNotification notification, dynamic options)
        {
            notification.CurrentMessage = "Checking for updates";

            var updatePackage = _updateProvider.GetAvilableUpdate(_environmentProvider.Version);

            //No updates available
            if (updatePackage == null)
            {
                return;
            }

            var packageDestination = Path.Combine(_environmentProvider.GetUpdateSandboxFolder(), updatePackage.FileName);

            if (_diskProvider.FolderExists(_environmentProvider.GetUpdateSandboxFolder()))
            {
                logger.Info("Deleting old update files");
                _diskProvider.DeleteFolder(_environmentProvider.GetUpdateSandboxFolder(), true);
            }

            logger.Info("Downloading update package from [{0}] to [{1}]", updatePackage.Url, packageDestination);
            notification.CurrentMessage = "Downloading Update " + updatePackage.Version;
            _httpProvider.DownloadFile(updatePackage.Url, packageDestination);
            logger.Info("Download completed for update package from [{0}]", updatePackage.FileName);

            logger.Info("Extracting Update package");
            notification.CurrentMessage = "Extracting Update";
            _archiveProvider.ExtractArchive(packageDestination, _environmentProvider.GetUpdateSandboxFolder());
            logger.Info("Update package extracted successfully");

            logger.Info("Preparing client");
            notification.CurrentMessage = "Preparing to start Update";
            _diskProvider.MoveDirectory(_environmentProvider.GetUpdateClientFolder(), _environmentProvider.GetUpdateSandboxFolder());


            logger.Info("Starting update client");
            var startInfo = new ProcessStartInfo
            {
                FileName  = _environmentProvider.GetUpdateClientExePath(),
                Arguments = string.Format("{0} {1}", _environmentProvider.NzbDroneProcessIdFromEnviroment, _configFileProvider.Guid)
            };

            var process = _processProvider.Start(startInfo);

            notification.CurrentMessage = "Update in progress. NzbDrone will restart shortly.";

            _processProvider.WaitForExit(process);
        }
예제 #12
0
        public virtual Dictionary <DateTime, string> UpdateLogFile()
        {
            var         list     = new Dictionary <DateTime, string>();
            CultureInfo provider = CultureInfo.InvariantCulture;

            if (_diskProvider.FolderExists(_environmentProvider.GetUpdateLogFolder()))
            {
                var files = _diskProvider.GetFiles(_environmentProvider.GetUpdateLogFolder(), SearchOption.TopDirectoryOnly).ToList();

                foreach (var file in files.Select(c => new FileInfo(c)).OrderByDescending(c => c.Name))
                {
                    list.Add(DateTime.ParseExact(file.Name.Replace(file.Extension, string.Empty), "yyyy.MM.dd-H-mm", provider), file.FullName);
                }
            }

            return(list);
        }
예제 #13
0
        /// <summary>
        ///   Scans the specified series folder for media files
        /// </summary>
        /// <param name = "series">The series to be scanned</param>
        /// <param name="path">Path to scan</param>
        public virtual List <EpisodeFile> Scan(Series series, string path)
        {
            _mediaFileProvider.CleanUpDatabase();

            if (!_diskProvider.FolderExists(path))
            {
                Logger.Warn("Series folder doesn't exist: {0}", path);
                return(new List <EpisodeFile>());
            }

            if (_episodeProvider.GetEpisodeBySeries(series.SeriesId).Count == 0)
            {
                Logger.Debug("Series {0} has no episodes. skipping", series.Title);
                return(new List <EpisodeFile>());
            }

            var seriesFile = _mediaFileProvider.GetSeriesFiles(series.SeriesId);

            CleanUp(seriesFile);

            var mediaFileList = GetVideoFiles(path);
            var importedFiles = new List <EpisodeFile>();

            foreach (var filePath in mediaFileList)
            {
                var file = ImportFile(series, filePath);
                if (file != null)
                {
                    importedFiles.Add(file);
                }
            }

            //Todo: Find the "best" episode file for all found episodes and import that one
            //Todo: Move the episode linking to here, instead of import (or rename import)

            series.LastDiskSync = DateTime.Now;
            _seriesProvider.UpdateSeries(series);

            return(importedFiles);
        }
        public virtual void ProcessDownload(DirectoryInfo subfolderInfo)
        {
            if (subfolderInfo.Name.StartsWith("_") && _diskProvider.GetLastDirectoryWrite(subfolderInfo.FullName).AddMinutes(2) > DateTime.UtcNow)
            {
                Logger.Trace("[{0}] is too fresh. skipping", subfolderInfo.Name);
                return;
            }

            if (_diskProvider.IsFolderLocked(subfolderInfo.FullName))
            {
                Logger.Trace("[{0}] is currently locked by another process, skipping", subfolderInfo.Name);
                return;
            }

            string seriesName = Parser.ParseSeriesName(RemoveStatusFromFolderName(subfolderInfo.Name));
            var    series     = _seriesProvider.FindSeries(seriesName);

            if (series == null)
            {
                Logger.Trace("Unknown Series on Import: {0}", subfolderInfo.Name);
                TagFolder(subfolderInfo, PostDownloadStatusType.UnknownSeries);
                return;
            }

            if (!_diskProvider.FolderExists(series.Path))
            {
                Logger.Warn("Series Folder doesn't exist: {0}, creating it.", series.Path);
                _diskProvider.CreateDirectory(series.Path);
            }

            var size      = _diskProvider.GetDirectorySize(subfolderInfo.FullName);
            var freeSpace = _diskProvider.FreeDiskSpace(new DirectoryInfo(series.Path));

            if (Convert.ToUInt64(size) > freeSpace)
            {
                Logger.Error("Not enough free disk space for series: {0}, {1}", series.Title, series.Path);
                return;
            }

            _diskScanProvider.CleanUpDropFolder(subfolderInfo.FullName);

            var importedFiles = _diskScanProvider.Scan(series, subfolderInfo.FullName);

            importedFiles.ForEach(file => _diskScanProvider.MoveEpisodeFile(file, true));

            //Create Metadata for all the episode files found
            if (importedFiles.Any())
            {
                _metadataProvider.CreateForEpisodeFiles(importedFiles);
            }

            //Delete the folder only if folder is small enough
            if (_diskProvider.GetDirectorySize(subfolderInfo.FullName) < Constants.IgnoreFileSize)
            {
                Logger.Trace("Episode(s) imported, deleting folder: {0}", subfolderInfo.Name);
                _diskProvider.DeleteFolder(subfolderInfo.FullName, true);
            }
            else
            {
                if (importedFiles.Count == 0)
                {
                    Logger.Trace("No Imported files: {0}", subfolderInfo.Name);
                    TagFolder(subfolderInfo, PostDownloadStatusType.ParseError);
                }
                else
                {
                    //Unknown Error Importing (Possibly a lesser quality than episode currently on disk)
                    Logger.Trace("Unable to import series (Unknown): {0}", subfolderInfo.Name);
                    TagFolder(subfolderInfo, PostDownloadStatusType.Unknown);
                }
            }
        }