Ejemplo n.º 1
0
    public ArchiveFileStream GetFileData(IDisposable?generator)
    {
        if (!IsPendingImport && generator == null)
        {
            throw new ArgumentNullException(nameof(generator), "A generator must be specified if there is no pending import");
        }

        // Get the stream
        ArchiveFileStream stream = IsPendingImport
            ? new ArchiveFileStream(PendingImport, FileName, false)
            : new ArchiveFileStream(() => Manager.GetFileData(generator !, ArchiveEntry), FileName, true);

        // Seek to the beginning
        stream.SeekToBeginning();

        // Return the stream
        return(stream);
    }
Ejemplo n.º 2
0
    /// <summary>
    /// Exports the directory
    /// </summary>
    /// <param name="forceNativeFormat">Indicates if the native format should be forced</param>
    /// <param name="selectedFilesOnly">Indicates if only selected files in the current directory should be exported</param>
    /// <returns>The task</returns>
    public async Task ExportAsync(bool forceNativeFormat, bool selectedFilesOnly = false)
    {
        // Run as a load operation
        using (await Archive.LoadOperation.RunAsync())
        {
            // Lock the access to the archive
            using (await Archive.ArchiveLock.LockAsync())
            {
                // Get the output path
                DirectoryBrowserResult result = await Services.BrowseUI.BrowseDirectoryAsync(new DirectoryBrowserViewModel()
                {
                    Title = Resources.Archive_ExportHeader
                });

                if (result.CanceledByUser)
                {
                    return;
                }

                // Make sure there isn't an existing file at the output path
                if ((result.SelectedDirectory + ExportDirName).FileExists)
                {
                    await Services.MessageUI.DisplayMessageAsync(String.Format(Resources.Archive_ExportDirFileConflict, ExportDirName), MessageType.Error);

                    return;
                }

                // Run as a task
                await Task.Run(async() =>
                {
                    // Get the manager
                    IArchiveDataManager manager = Archive.Manager;

                    // Save the selected format for each collection
                    Dictionary <IArchiveFileType, FileExtension?> selectedFormats = new();

                    try
                    {
                        ArchiveDirectoryViewModel[] allDirs;

                        if (selectedFilesOnly)
                        {
                            allDirs = new ArchiveDirectoryViewModel[]
                            {
                                this
                            }
                        }
                        ;
                        else
                        {
                            allDirs = this.GetAllChildren(true).ToArray();
                        }

                        int fileIndex  = 0;
                        int filesCount = allDirs.SelectMany(x => x.Files).Count(x => !selectedFilesOnly || x.IsSelected);

                        // Handle each directory
                        foreach (ArchiveDirectoryViewModel item in allDirs)
                        {
                            // Get the directory path
                            FileSystemPath path = result.SelectedDirectory + ExportDirName + item.FullPath.Remove(0, FullPath.Length).Trim(manager.PathSeparatorCharacter);

                            // Create the directory
                            Directory.CreateDirectory(path);

                            // Save each file
                            foreach (ArchiveFileViewModel file in item.Files.Where(x => !selectedFilesOnly || x.IsSelected))
                            {
                                // Get the file stream
                                using ArchiveFileStream fileStream = file.GetDecodedFileStream();

                                // Initialize the file without loading the thumbnail
                                file.InitializeFile(fileStream, ArchiveFileViewModel.ThumbnailLoadMode.None);

                                fileStream.SeekToBeginning();

                                // Check if the format has not been selected
                                if (!forceNativeFormat && !selectedFormats.ContainsKey(file.FileType) && file.FileType is not ArchiveFileType_Default)
                                {
                                    // Get the available extensions
                                    string[] ext = new string[]
                                    {
                                        Resources.Archive_Export_Format_Original
                                    }.Concat(file.FileType.ExportFormats.Select(x => x.FileExtensions)).ToArray();

                                    // Have user select the format
                                    FileExtensionSelectionDialogResult extResult = await Services.UI.SelectFileExtensionAsync(new FileExtensionSelectionDialogViewModel(ext, String.Format(Resources.Archive_FileExtensionSelectionInfoHeader, file.FileType.TypeDisplayName)));

                                    // Since this operation can't be canceled we get the first format
                                    if (extResult.CanceledByUser)
                                    {
                                        extResult.SelectedFileFormat = ext.First();
                                    }

                                    // Add the selected format
                                    FileExtension?e = extResult.SelectedFileFormat == ext.First()
                                        ? null
                                        : new FileExtension(extResult.SelectedFileFormat, multiple: true);

                                    selectedFormats.Add(file.FileType, e);
                                }

                                // Get the selected format
                                FileExtension?format = forceNativeFormat || file.FileType is ArchiveFileType_Default
                                    ? null
                                    : selectedFormats[file.FileType];

                                // Get the final file name to use when exporting
                                FileSystemPath exportFileName = format == null
                                    ? new FileSystemPath(file.FileName)
                                    : new FileSystemPath(file.FileName).ChangeFileExtension(format, true);

                                Archive.SetDisplayStatus($"{String.Format(Resources.Archive_ExportingFileStatus, file.FileName)}" +
                                                         $"{Environment.NewLine}{++fileIndex}/{filesCount}");

                                try
                                {
                                    // Export the file
                                    file.ExportFile(path + exportFileName, fileStream, format);
                                }
                                catch (Exception ex)
                                {
                                    // If the export failed for a native format we throw
                                    if (format == null)
                                    {
                                        throw;
                                    }

                                    Logger.Error(ex, "Exporting archive file {0}", file.FileName);

                                    // If the export failed and we tried converting it we instead export it as the native format
                                    // Start by setting the file in the error state, thus changing the type
                                    file.InitializeAsError();

                                    // Seek to the beginning of the stream in case some bytes were read
                                    fileStream.SeekToBeginning();

                                    // Export the file as the native format
                                    file.ExportFile(path + file.FileName, fileStream, null);
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Logger.Error(ex, "Exporting archive directory {0}", DisplayName);

                        await Services.MessageUI.DisplayExceptionMessageAsync(ex, String.Format(Resources.Archive_ExportError, DisplayName));

                        return;
                    }
                    finally
                    {
                        Archive.SetDisplayStatus(String.Empty);
                    }

                    await Services.MessageUI.DisplaySuccessfulActionMessageAsync(Resources.Archive_ExportFilesSuccess);
                });
            }
        }
    }