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); }
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); }
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); }
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()); }
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)))); }
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); }
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)); }
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)); }
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() }; }
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); }
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 }; }
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()); }
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); } } }
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; }
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); }
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; } }
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)); }
private void ShowBookAction( object sender, RightTappedRoutedEventArgs e ) { LSBookItem G = ( LSBookItem ) sender; FlyoutBase.ShowAttachedFlyout( G ); SelectedBook = ( LocalBook ) G.DataContext; }
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 ); } }
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() ); } } }
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 ) }; }
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)); }
public void ImportTrack(LocalBook localBook, BookFile bookFile, bool isReadOnly) { ImportExtraFiles(localBook, bookFile, isReadOnly); CreateAfterImport(localBook.Author, bookFile); }
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; }
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); } } }
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); }