private void VerifyData(LocalBook track, string artist, string title, int trackNum, int disc)
 {
     track.FileTrackInfo.ArtistTitle.Should().Be(artist);
     track.FileTrackInfo.Title.Should().Be(title);
     track.FileTrackInfo.TrackNumbers[0].Should().Be(trackNum);
     track.FileTrackInfo.DiscNumber.Should().Be(disc);
 }
示例#2
0
        public LocalBook Augment(LocalBook localTrack, bool otherFiles)
        {
            if (localTrack.DownloadClientAlbumInfo == null &&
                localTrack.FolderTrackInfo == null &&
                localTrack.FileTrackInfo == null)
            {
                if (MediaFileExtensions.AllExtensions.Contains(Path.GetExtension(localTrack.Path)))
                {
                    throw new AugmentingFailedException("Unable to parse book info from path: {0}", localTrack.Path);
                }
            }

            localTrack.Size = _diskProvider.GetFileSize(localTrack.Path);

            foreach (var augmenter in _trackAugmenters)
            {
                try
                {
                    augmenter.Aggregate(localTrack, otherFiles);
                }
                catch (Exception ex)
                {
                    _logger.Warn(ex, ex.Message);
                }
            }

            return(localTrack);
        }
示例#3
0
        private ImportDecision <LocalBook> GetDecision(LocalBook localBook, DownloadClientItem downloadClientItem)
        {
            ImportDecision <LocalBook> decision = null;

            if (localBook.Book == null)
            {
                decision = new ImportDecision <LocalBook>(localBook, new Rejection($"Couldn't parse book from: {localBook.FileTrackInfo}"));
            }
            else
            {
                var reasons = _trackSpecifications.Select(c => EvaluateSpec(c, localBook, downloadClientItem))
                              .Where(c => c != null);

                decision = new ImportDecision <LocalBook>(localBook, reasons.ToArray());
            }

            if (decision == null)
            {
                _logger.Error("Unable to make a decision on {0}", localBook.Path);
            }
            else if (decision.Rejections.Any())
            {
                _logger.Debug("File rejected for the following reasons: {0}", string.Join(", ", decision.Rejections));
            }
            else
            {
                _logger.Debug("File accepted");
            }

            return(decision);
        }
示例#4
0
        public void Setup()
        {
            _localTrack        = new LocalBook();
            _localTrack.Author = new Author
            {
                Path = _rootPath
            };

            _trackFile = Builder <BookFile>
                         .CreateNew()
                         .Build();

            Mocker.GetMock <IDiskProvider>()
            .Setup(c => c.FileExists(It.IsAny <string>()))
            .Returns(true);

            Mocker.GetMock <IDiskProvider>()
            .Setup(c => c.FolderExists(It.IsAny <string>()))
            .Returns(true);

            Mocker.GetMock <IDiskProvider>()
            .Setup(c => c.GetParentFolder(It.IsAny <string>()))
            .Returns <string>(c => Path.GetDirectoryName(c));

            Mocker.GetMock <IRootFolderService>()
            .Setup(c => c.GetBestRootFolder(It.IsAny <string>()))
            .Returns(new RootFolder());
        }
示例#5
0
        public void should_use_file_name_for_source_title_if_scene_name_is_null()
        {
            var artist = Builder <Author> .CreateNew().Build();

            var trackFile = Builder <BookFile> .CreateNew()
                            .With(f => f.SceneName = null)
                            .With(f => f.Author    = artist)
                            .Build();

            var localTrack = new LocalBook
            {
                Author = artist,
                Book   = new Book(),
                Path   = @"C:\Test\Unsorted\Artist.01.Hymn.mp3"
            };

            var downloadClientItem = new DownloadClientItem
            {
                DownloadClientInfo = new DownloadClientItemClientInfo
                {
                    Protocol = DownloadProtocol.Usenet,
                    Id       = 1,
                    Name     = "sab"
                },
                DownloadId = "abcd"
            };

            Subject.Handle(new TrackImportedEvent(localTrack, trackFile, new List <BookFile>(), true, downloadClientItem));

            Mocker.GetMock <IHistoryRepository>()
            .Verify(v => v.Insert(It.Is <History.History>(h => h.SourceTitle == Path.GetFileNameWithoutExtension(localTrack.Path))));
        }
示例#6
0
 private void VerifyData(LocalBook track, string author, string title, int trackNum, int disc)
 {
     track.FileTrackInfo.AuthorTitle.Should().Be(author);
     track.FileTrackInfo.BookTitle.Should().Be(title);
     track.FileTrackInfo.TrackNumbers[0].Should().Be(trackNum);
     track.FileTrackInfo.DiscNumber.Should().Be(disc);
 }
        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());
        }
        public void should_not_delete_folder_if_files_were_imported_and_audio_files_remain()
        {
            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());

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

            Mocker.GetMock <IDiskProvider>()
            .Verify(v => v.DeleteFolder(It.IsAny <string>(), true), Times.Never());

            ExceptionVerification.ExpectedWarns(1);
        }
示例#10
0
        public WDeathblow(IDeathblow Deathblow)
            : this()
        {
            this.Deathblow = Deathblow;

            LB = Deathblow.GetParser();
            LayoutRoot.DataContext = LB;
        }
        public override IEnumerable <ExtraFile> ProcessFiles(Author author, List <string> filesOnDisk, List <string> importedFiles)
        {
            _logger.Debug("Looking for existing extra files in {0}", author.Path);

            var extraFiles   = new List <OtherExtraFile>();
            var filterResult = FilterAndClean(author, filesOnDisk, importedFiles);

            foreach (var possibleExtraFile in filterResult.FilesOnDisk)
            {
                var extension = Path.GetExtension(possibleExtraFile);

                if (extension.IsNullOrWhiteSpace())
                {
                    _logger.Debug("No extension for file: {0}", possibleExtraFile);
                    continue;
                }

                var localTrack = new LocalBook
                {
                    FileTrackInfo = Parser.Parser.ParseMusicPath(possibleExtraFile),
                    Author        = author,
                    Path          = possibleExtraFile
                };

                try
                {
                    _augmentingService.Augment(localTrack, false);
                }
                catch (AugmentingFailedException)
                {
                    _logger.Debug("Unable to parse extra file: {0}", possibleExtraFile);
                    continue;
                }

                if (localTrack.Book == null)
                {
                    _logger.Debug("Cannot find related book for: {0}", possibleExtraFile);
                    continue;
                }

                var extraFile = new OtherExtraFile
                {
                    AuthorId     = author.Id,
                    BookId       = localTrack.Book.Id,
                    RelativePath = author.Path.GetRelativePath(possibleExtraFile),
                    Extension    = extension
                };

                extraFiles.Add(extraFile);
            }

            _logger.Info("Found {0} existing other extra files", extraFiles.Count);
            _otherExtraFileService.Upsert(extraFiles);

            // Return files that were just imported along with files that were
            // previously imported so previously imported files aren't imported twice
            return(extraFiles.Concat(filterResult.PreviouslyImported));
        }
示例#12
0
        public BookFile MoveBookFile(BookFile bookFile, LocalBook localBook)
        {
            var newFileName = _buildFileNames.BuildBookFileName(localBook.Author, localBook.Edition, bookFile);
            var filePath    = _buildFileNames.BuildBookFilePath(localBook.Author, localBook.Edition, newFileName, Path.GetExtension(localBook.Path));

            EnsureTrackFolder(bookFile, localBook, filePath);

            _logger.Debug("Moving book file: {0} to {1}", bookFile.Path, filePath);

            return(TransferFile(bookFile, localBook.Author, localBook.Book, filePath, TransferMode.Move));
        }
示例#13
0
        public TrackImportFailedEvent(Exception exception, LocalBook bookInfo, bool newDownload, DownloadClientItem downloadClientItem)
        {
            Exception   = exception;
            BookInfo    = bookInfo;
            NewDownload = newDownload;

            if (downloadClientItem != null)
            {
                DownloadClient = downloadClientItem.DownloadClient;
                DownloadId     = downloadClientItem.DownloadId;
            }
        }
        public void should_return_permissions_error_on_book_import_failed_event_if_file_exists()
        {
            var localBook = new LocalBook
            {
                Path = Path.Combine(_downloadItemPath, "file.mp3")
            };

            GivenFileExists(localBook.Path);

            var importEvent = new TrackImportFailedEvent(new Exception(), localBook, true, _downloadItem);

            Subject.Check(importEvent).ShouldBeError(wikiFragment: "permissions-error");
        }
        public void Setup()
        {
            Mocker.GetMock <IConfigService>()
            .SetupGet(s => s.DownloadClientWorkingFolders)
            .Returns("_UNPACK_|_FAILED_");

            _localTrack = new LocalBook
            {
                Path   = @"C:\Test\Unsorted Music\Kid.Rock\Kid.Rock.Cowboy.mp3".AsOsAgnostic(),
                Size   = 100,
                Author = Builder <Author> .CreateNew().Build()
            };
        }
示例#16
0
        public override FlyoutBase GetContextMenu(FrameworkElement elem)
        {
            if (elem.DataContext is GRRow <IBookProcess> Row)
            {
                LocalBook BkProc = ( LocalBook )Row.Source;

                DirectView.IsEnabled = (BkProc.File != null);
                Reanalyze.IsEnabled  = BkProc.CanProcess && !(BkProc.Processed || BkProc.Processing);

                return(ContextMenu);
            }
            return(null);
        }
示例#17
0
        public TrackImportedEvent(LocalBook bookInfo, BookFile importedBook, List <BookFile> oldFiles, bool newDownload, DownloadClientItem downloadClientItem)
        {
            BookInfo     = bookInfo;
            ImportedBook = importedBook;
            OldFiles     = oldFiles;
            NewDownload  = newDownload;

            if (downloadClientItem != null)
            {
                DownloadClient = downloadClientItem.DownloadClient;
                DownloadId     = downloadClientItem.DownloadId;
            }
        }
        public void Setup()
        {
            _rootFolder = @"C:\Test\Music".AsOsAgnostic();

            _author = Builder <Author> .CreateNew()
                      .With(s => s.Path = Path.Combine(_rootFolder, "Alice in Chains"))
                      .Build();

            _localTrack = new LocalBook
            {
                Path   = @"C:\Test\Unsorted\Alice in Chains\Alice in Chains - track1.mp3".AsOsAgnostic(),
                Book   = new Book(),
                Author = _author
            };
        }
示例#19
0
        public BookFile CopyBookFile(BookFile bookFile, LocalBook localBook)
        {
            var newFileName = _buildFileNames.BuildBookFileName(localBook.Author, localBook.Edition, bookFile);
            var filePath    = _buildFileNames.BuildBookFilePath(localBook.Author, localBook.Edition, newFileName, Path.GetExtension(localBook.Path));

            EnsureTrackFolder(bookFile, localBook, filePath);

            if (_configService.CopyUsingHardlinks)
            {
                _logger.Debug("Hardlinking book file: {0} to {1}", bookFile.Path, filePath);
                return(TransferFile(bookFile, localBook.Author, localBook.Book, filePath, TransferMode.HardLinkOrCopy));
            }

            _logger.Debug("Copying book file: {0} to {1}", bookFile.Path, filePath);
            return(TransferFile(bookFile, localBook.Author, localBook.Book, filePath, TransferMode.Copy));
        }
        private void GivenSuccessfulImport()
        {
            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> > >(), It.IsAny <bool>(), It.IsAny <DownloadClientItem>(), It.IsAny <ImportMode>()))
            .Returns(imported.Select(i => new ImportResult(i)).ToList())
            .Callback(() => WasImportedResponse());
        }
示例#21
0
 public void ProcessOrOpenItem(IGRRow DataContext)
 {
     if (DataContext is GRRow <IBookProcess> Row)
     {
         LocalBook BkProc = ( LocalBook )Row.Source;
         if (BkProc.Processed && BkProc.ProcessSuccess)
         {
             Book Bk = Shared.BooksDb.QueryBook(BookType.L, BkProc.ZoneId, BkProc.ZItemId);
             if (Bk != null)
             {
                 PageProcessor.NavigateToTOC(Page, ItemProcessor.GetBookItem(Bk));
             }
         }
         else
         {
             ProcessItem(DataContext);
         }
     }
 }
示例#22
0
        public async void OpenDirectory()
        {
            BookStorage BS = new BookStorage();
            string[] ids = BS.GetIdList();
            IEnumerable<LocalBook> Items = await Shared.Storage.GetLocalText( async ( x, i, l ) =>
            {
                if ( i % 20 == 0 )
                {
                    Worker.UIInvoke( () => Loading = string.Format( "{0}/{1}", i, l ) );
                    await Task.Delay( 15 );
                }

                LocalBook LB = new LocalBook( x );
                LB.IsFav = ids.Contains( LB.aid );
                return LB;
            } );

            Loading = null;
            if ( Items != null && 0 < Items.Count() ) SearchSet = Items;
        }
示例#23
0
        public static bool InsertOrUpdatBook(string path, Book book)
        {
            bool result = true;

            using (var db = new SQLiteConnection(new SQLitePlatformWinRT(), path))
            {
                db.BusyTimeout = TimeSpan.FromSeconds(5);
                db.CreateTable <LocalBook>();
                db.RunInTransaction(() =>
                {
                    try
                    {
                        var temp = (from m in db.Table <LocalBook>()
                                    where m.BookId == book.BookId
                                    select m
                                    ).FirstOrDefault();
                        if (temp == null)
                        {
                            var schema = new LocalBook()
                            {
                                BookId     = book.BookId,
                                BookJson   = JsonConvert.SerializeObject(book),
                                UpdateTime = DateTime.Now.ToString("yyyy-MM-dd HH:ss:mm")
                            };
                            db.Insert(schema);
                        }
                        else
                        {
                            temp.BookJson   = JsonConvert.SerializeObject(book);
                            temp.UpdateTime = DateTime.Now.ToString("yyyy-MM-dd HH:ss:mm");
                            db.Update(temp);
                        }
                    }
                    catch (Exception)
                    {
                        result = false;
                    }
                });
            }
            return(result);
        }
示例#24
0
        private void MessageBus_OnDelivery(Message Mesg)
        {
            switch (Mesg.Content)
            {
            case AppKeys.SP_PROCESS_COMP:

                LocalBook     SBook = ( LocalBook )Mesg.Payload;
                HubScriptItem HSC   = SearchSet.Cast <HubScriptItem>().FirstOrDefault(x => x.Id == SBook.ZItemId);

                if (HSC == null)
                {
                    Logger.Log(ID, "Book is not from Sharer's hub", LogType.DEBUG);
                }
                else
                {
                    HSC.InCollection = SBook.ProcessSuccess;
                }

                break;

            case AppKeys.HS_REPORT_SUCCESS:

                Tuple <string, DRequestCompletedEventArgs> Payload = (Tuple <string, DRequestCompletedEventArgs>)Mesg.Payload;
                SearchItemUpdate(Payload.Item2, Payload.Item1);

                break;

            case AppKeys.HS_REPORT_FAILED:

                Tuple <string, string> ErrorPayload = (Tuple <string, string>)Mesg.Payload;

                HubScriptItem HSI;
                if (TryGetId(ErrorPayload.Item1, out HSI))
                {
                    HSI.ErrorMessage = ErrorPayload.Item2;
                }

                break;
            }
        }
示例#25
0
        public void Setup()
        {
            _artist = Builder <Author> .CreateNew()
                      .With(s => s.Path = @"C:\Test\Music\Artist".AsOsAgnostic())
                      .Build();

            _trackFile = Builder <BookFile> .CreateNew()
                         .With(f => f.Path = null)
                         .With(f => f.Path = Path.Combine(_artist.Path, @"Album\File.mp3"))
                         .Build();

            _localtrack = Builder <LocalBook> .CreateNew()
                          .With(l => l.Author = _artist)
                          .With(l => l.Book   = Builder <Book> .CreateNew().Build())
                          .Build();

            Mocker.GetMock <IBuildFileNames>()
            .Setup(s => s.BuildBookFileName(It.IsAny <Author>(), It.IsAny <Edition>(), It.IsAny <BookFile>(), null, null))
            .Returns("File Name");

            Mocker.GetMock <IBuildFileNames>()
            .Setup(s => s.BuildBookFilePath(It.IsAny <Author>(), It.IsAny <Edition>(), It.IsAny <string>(), It.IsAny <string>()))
            .Returns(@"C:\Test\Music\Artist\Album\File Name.mp3".AsOsAgnostic());

            Mocker.GetMock <IBuildFileNames>()
            .Setup(s => s.BuildBookPath(It.IsAny <Author>()))
            .Returns(@"C:\Test\Music\Artist\Album".AsOsAgnostic());

            var rootFolder = @"C:\Test\Music\".AsOsAgnostic();

            Mocker.GetMock <IDiskProvider>()
            .Setup(s => s.FolderExists(rootFolder))
            .Returns(true);

            Mocker.GetMock <IDiskProvider>()
            .Setup(s => s.FileExists(It.IsAny <string>()))
            .Returns(true);
        }
        public override IEnumerable <ExtraFile> ProcessFiles(Author author, List <string> filesOnDisk, List <string> importedFiles)
        {
            _logger.Debug("Looking for existing metadata in {0}", author.Path);

            var metadataFiles = new List <MetadataFile>();
            var filterResult  = FilterAndClean(author, filesOnDisk, importedFiles);

            foreach (var possibleMetadataFile in filterResult.FilesOnDisk)
            {
                foreach (var consumer in _consumers)
                {
                    var metadata = consumer.FindMetadataFile(author, possibleMetadataFile);

                    if (metadata == null)
                    {
                        continue;
                    }

                    if (metadata.Type == MetadataType.BookImage || metadata.Type == MetadataType.BookMetadata)
                    {
                        var localAlbum = _parsingService.GetLocalAlbum(possibleMetadataFile, author);

                        if (localAlbum == null)
                        {
                            _logger.Debug("Extra file folder has multiple Books: {0}", possibleMetadataFile);
                            continue;
                        }

                        metadata.BookId = localAlbum.Id;
                    }

                    if (metadata.Type == MetadataType.BookMetadata)
                    {
                        var localTrack = new LocalBook
                        {
                            FileTrackInfo = Parser.Parser.ParseMusicPath(possibleMetadataFile),
                            Author        = author,
                            Path          = possibleMetadataFile
                        };

                        try
                        {
                            _augmentingService.Augment(localTrack, false);
                        }
                        catch (AugmentingFailedException)
                        {
                            _logger.Debug("Unable to parse extra file: {0}", possibleMetadataFile);
                            continue;
                        }

                        if (localTrack.Book == null)
                        {
                            _logger.Debug("Cannot find related book for: {0}", possibleMetadataFile);
                            continue;
                        }
                    }

                    metadata.Extension = Path.GetExtension(possibleMetadataFile);

                    metadataFiles.Add(metadata);
                }
            }

            _logger.Info("Found {0} existing metadata files", metadataFiles.Count);
            _metadataFileService.Upsert(metadataFiles);

            // Return files that were just imported along with files that were
            // previously imported so previously imported files aren't imported twice
            return(metadataFiles.Concat(filterResult.PreviouslyImported));
        }
示例#27
0
        private void ShowBookAction( object sender, RightTappedRoutedEventArgs e )
        {
            LSBookItem G = ( LSBookItem ) sender;
            FlyoutBase.ShowAttachedFlyout( G );

            SelectedBook = ( LocalBook ) G.DataContext;
        }
示例#28
0
        private void OpenBookInfoView( LocalBook Item )
        {
            // Prevent double processing on the already processed item
            if ( !Item.ProcessSuccess && Item.CanProcess ) ProcessItem( Item );

            if ( Item.ProcessSuccess )
            {
                if ( Item is SpiderBook )
                {
                    BackMask.HandleForward(
                        Frame, () => Frame.Navigate( typeof( BookInfoView ), ( Item as SpiderBook ).GetBook() )
                    );
                }
                else
                {
                    BackMask.HandleForward(
                        Frame, () => Frame.Navigate( typeof( BookInfoView ), new LocalTextDocument( Item.aid ) )
                    );
                }
            }
            else if ( !Item.Processing && Item.File != null )
            {
                Frame.Navigate( typeof( DirectTextViewer ), Item.File );
            }
        }
示例#29
0
 private async void ProcessItem( LocalBook LB )
 {
     await LB.Process();
     if ( LB is SpiderBook )
     {
         SpiderBook SB = ( SpiderBook ) LB;
         BookInstruction BS = SB.GetBook();
         if ( BS.Packable )
         {
             BS.PackVolumes( SB.GetPPConvoy() );
         }
     }
 }
示例#30
0
        private async void SaveTemp( DRequestCompletedEventArgs e, LocalModeTxtList.DownloadBookContext Context )
        {
            StorageFile ISF = await AppStorage.MkTemp(
                Context.Id
                + ". "
                + ( string.IsNullOrEmpty( Context.Title ) ? "{ Parse Needed }" : Context.Title )
                + ".txt"
            );

            await ISF.WriteBytes( e.ResponseBytes );

            SearchSet = new LocalBook[] { new LocalBook( ISF ) };
        }
示例#31
0
        public Tuple <List <LocalBook>, List <ImportDecision <LocalBook> > > GetLocalTracks(List <IFileInfo> musicFiles, DownloadClientItem downloadClientItem, ParsedTrackInfo folderInfo, FilterFilesType filter)
        {
            var watch = new System.Diagnostics.Stopwatch();

            watch.Start();

            var files = _mediaFileService.FilterUnchangedFiles(musicFiles, filter);

            var localTracks = new List <LocalBook>();
            var decisions   = new List <ImportDecision <LocalBook> >();

            _logger.Debug("Analyzing {0}/{1} files.", files.Count, musicFiles.Count);

            if (!files.Any())
            {
                return(Tuple.Create(localTracks, decisions));
            }

            ParsedBookInfo downloadClientItemInfo = null;

            if (downloadClientItem != null)
            {
                downloadClientItemInfo = Parser.Parser.ParseBookTitle(downloadClientItem.Title);
            }

            var i = 1;

            foreach (var file in files)
            {
                _logger.ProgressInfo($"Reading file {i++}/{files.Count}");

                var localTrack = new LocalBook
                {
                    DownloadClientAlbumInfo = downloadClientItemInfo,
                    FolderTrackInfo         = folderInfo,
                    Path           = file.FullName,
                    Size           = file.Length,
                    Modified       = file.LastWriteTimeUtc,
                    FileTrackInfo  = _eBookTagService.ReadTags(file),
                    AdditionalFile = false
                };

                try
                {
                    // TODO fix otherfiles?
                    _augmentingService.Augment(localTrack, true);
                    localTracks.Add(localTrack);
                }
                catch (AugmentingFailedException)
                {
                    decisions.Add(new ImportDecision <LocalBook>(localTrack, new Rejection("Unable to parse file")));
                }
                catch (Exception e)
                {
                    _logger.Error(e, "Couldn't import file. {0}", localTrack.Path);

                    decisions.Add(new ImportDecision <LocalBook>(localTrack, new Rejection("Unexpected error processing file")));
                }
            }

            _logger.Debug($"Tags parsed for {files.Count} files in {watch.ElapsedMilliseconds}ms");

            return(Tuple.Create(localTracks, decisions));
        }
示例#32
0
        public void ImportTrack(LocalBook localBook, BookFile bookFile, bool isReadOnly)
        {
            ImportExtraFiles(localBook, bookFile, isReadOnly);

            CreateAfterImport(localBook.Author, bookFile);
        }
示例#33
0
        private async void ProcessAll(object sender, RoutedEventArgs e)
        {
            StringResources stx = StringResources.Load("AppBar", "AdvDM", "AppResources");

            if (Processing)
            {
                Terminate = !Terminate;
            }
            else
            {
                Terminate = false;
            }

            if (Terminate)
            {
                ProcessBtn.Label = stx.Text("ProcessAll");
                ProcessBtn.Icon  = new SymbolIcon(Symbol.Play);
                PTargets?
                .Where(x => !x.Processing && x.File != null)
                .ExecEach(x => x.Desc = stx.Text("Ready", "AppResources"));
            }
            else
            {
                ProcessBtn.Label = stx.Text("Pause");
                ProcessBtn.Icon  = new SymbolIcon(Symbol.Pause);
                PTargets?
                .Where(x => !x.Processing && x.File != null)
                .ExecEach(x => x.Desc = stx.Text("Waiting", "AdvDM"));
            }

            if (Processing)
            {
                return;
            }
            Processing = true;

            PTargets = ((GRTable <IBookProcess>)ViewSource.BSData.Table).Items
                       .Where(x =>
            {
                LocalBook Bk = ( LocalBook )x.Source;
                return(Bk.CanProcess && !Bk.Processed);
            })
                       .Remap(x =>
            {
                LocalBook Bk = ( LocalBook )x.Source;
                Bk.Desc      = stx.Text("Waiting", "AdvDM");
                return(Bk);
            });

            if (PTargets.Any())
            {
                if (await Shared.Conv.ConfirmTranslate("__ALL__", "All"))
                {
                    Shared.Conv.SetPrefs(PTargets);
                }

                foreach (LocalBook b in PTargets)
                {
                    await ItemProcessor.ProcessLocal(b);

                    if (Terminate)
                    {
                        break;
                    }
                }
            }

            ProcessBtn.Label = stx.Text("ProcessAll");
            ProcessBtn.Icon  = new SymbolIcon(Symbol.Play);
            PTargets         = null;
            Terminate        = false;
            Processing       = false;
        }
示例#34
0
        public void ImportExtraFiles(LocalBook localBook, BookFile bookFile, bool isReadOnly)
        {
            if (!_configService.ImportExtraFiles)
            {
                return;
            }

            var sourcePath     = localBook.Path;
            var sourceFolder   = _diskProvider.GetParentFolder(sourcePath);
            var sourceFileName = Path.GetFileNameWithoutExtension(sourcePath);
            var files          = _diskProvider.GetFiles(sourceFolder, SearchOption.TopDirectoryOnly);

            var wantedExtensions = _configService.ExtraFileExtensions.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
                                   .Select(e => e.Trim(' ', '.'))
                                   .ToList();

            var matchingFilenames = files.Where(f => Path.GetFileNameWithoutExtension(f).StartsWith(sourceFileName, StringComparison.InvariantCultureIgnoreCase)).ToList();
            var filteredFilenames = new List <string>();
            var hasNfo            = false;

            foreach (var matchingFilename in matchingFilenames)
            {
                // Filter out duplicate NFO files
                if (matchingFilename.EndsWith(".nfo", StringComparison.InvariantCultureIgnoreCase))
                {
                    if (hasNfo)
                    {
                        continue;
                    }

                    hasNfo = true;
                }

                filteredFilenames.Add(matchingFilename);
            }

            foreach (var matchingFilename in filteredFilenames)
            {
                var matchingExtension = wantedExtensions.FirstOrDefault(e => matchingFilename.EndsWith(e));

                if (matchingExtension == null)
                {
                    continue;
                }

                try
                {
                    foreach (var extraFileManager in _extraFileManagers)
                    {
                        var extension = Path.GetExtension(matchingFilename);
                        var extraFile = extraFileManager.Import(localBook.Author, bookFile, matchingFilename, extension, isReadOnly);

                        if (extraFile != null)
                        {
                            break;
                        }
                    }
                }
                catch (Exception ex)
                {
                    _logger.Warn(ex, "Failed to import extra file: {0}", matchingFilename);
                }
            }
        }
示例#35
0
        public BookFileMoveResult UpgradeBookFile(BookFile bookFile, LocalBook localBook, bool copyOnly = false)
        {
            var moveFileResult = new BookFileMoveResult();
            var existingFiles  = localBook.Book.BookFiles.Value;

            var rootFolderPath = _diskProvider.GetParentFolder(localBook.Author.Path);
            var rootFolder     = _rootFolderService.GetBestRootFolder(rootFolderPath);
            var isCalibre      = rootFolder.IsCalibreLibrary && rootFolder.CalibreSettings != null;

            var settings = rootFolder.CalibreSettings;

            // If there are existing book files and the root folder is missing, throw, so the old file isn't left behind during the import process.
            if (existingFiles.Any() && !_diskProvider.FolderExists(rootFolderPath))
            {
                throw new RootFolderNotFoundException($"Root folder '{rootFolderPath}' was not found.");
            }

            foreach (var file in existingFiles)
            {
                var bookFilePath = file.Path;
                var subfolder    = rootFolderPath.GetRelativePath(_diskProvider.GetParentFolder(bookFilePath));

                bookFile.CalibreId = file.CalibreId;

                if (_diskProvider.FileExists(bookFilePath))
                {
                    _logger.Debug("Removing existing book file: {0} CalibreId: {1}", file, file.CalibreId);

                    if (!isCalibre)
                    {
                        _recycleBinProvider.DeleteFile(bookFilePath, subfolder);
                    }
                    else
                    {
                        var existing        = _calibre.GetBook(file.CalibreId, settings);
                        var existingFormats = existing.Formats.Keys;
                        _logger.Debug($"Removing existing formats {existingFormats.ConcatToString()} from calibre");
                        _calibre.RemoveFormats(file.CalibreId, existingFormats, settings);
                    }
                }

                moveFileResult.OldFiles.Add(file);
                _mediaFileService.Delete(file, DeleteMediaFileReason.Upgrade);
            }

            if (!isCalibre)
            {
                if (copyOnly)
                {
                    moveFileResult.BookFile = _bookFileMover.CopyBookFile(bookFile, localBook);
                }
                else
                {
                    moveFileResult.BookFile = _bookFileMover.MoveBookFile(bookFile, localBook);
                }

                _metadataTagService.WriteTags(bookFile, true);
            }
            else
            {
                var source = bookFile.Path;

                moveFileResult.BookFile = _calibre.AddAndConvert(bookFile, settings);

                if (!copyOnly)
                {
                    _diskProvider.DeleteFile(source);
                }
            }

            return(moveFileResult);
        }