// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. #nullable disable using System.Collections.Generic; using System.IO; using osu.Framework.Platform; using osu.Game.Extensions; using osu.Game.Utils; using SharpCompress.Archives.Zip; namespace osu.Game.Database { /// /// A class which handles exporting legacy user data of a single type from osu-stable. /// public abstract class LegacyExporter where TModel : class, IHasNamedFiles { /// /// The file extension for exports (including the leading '.'). /// protected abstract string FileExtension { get; } protected readonly Storage UserFileStorage; private readonly Storage exportStorage; protected LegacyExporter(Storage storage) { exportStorage = storage.GetStorageForDirectory(@"exports"); UserFileStorage = storage.GetStorageForDirectory(@"files"); } protected virtual string GetItemExportString(TModel item) => item.GetDisplayString().GetValidFilename(); /// /// Exports an item to a legacy (.zip based) package. /// /// The item to export. public void Export(TModel item) { IEnumerable existingExports = exportStorage.GetFiles("", $"{GetItemExportString(item)}*{FileExtension}"); string filename = NamingUtils.GetNextBestFilename(existingExports, $"{GetItemExportString(item)}{FileExtension}"); using (var stream = exportStorage.CreateFileSafely(filename)) ExportModelTo(item, stream); exportStorage.PresentFileExternally(filename); } /// /// Exports an item to the given output stream. /// /// The item to export. /// The output stream to export to. public virtual void ExportModelTo(TModel model, Stream outputStream) { using (var archive = ZipArchive.Create()) { foreach (var file in model.Files) archive.AddEntry(file.Filename, UserFileStorage.GetStream(file.File.GetStoragePath())); archive.SaveTo(outputStream); } } } }