public virtual void DeleteExportProfile(ExportProfile profile, bool force = false) { if (profile == null) { throw new ArgumentNullException("profile"); } if (!force && profile.IsSystemProfile) { throw new SmartException(_localizationService.GetResource("Admin.DataExchange.Export.CannotDeleteSystemProfile")); } int scheduleTaskId = profile.SchedulingTaskId; var folder = profile.GetExportFolder(); _exportProfileRepository.Delete(profile); var scheduleTask = _scheduleTaskService.GetTaskById(scheduleTaskId); _scheduleTaskService.DeleteTask(scheduleTask); _eventPublisher.EntityDeleted(profile); if (System.IO.Directory.Exists(folder)) { FileSystemHelper.ClearDirectory(folder, true); } }
/// <summary> /// Resolves the file name pattern for an export profile /// </summary> /// <param name="profile">Export profile</param> /// <param name="store">Store</param> /// <param name="fileIndex">One based file index</param> /// <param name="maxFileNameLength">The maximum length of the file name</param> /// <returns>Resolved file name pattern</returns> public static string ResolveFileNamePattern(this ExportProfile profile, Store store, int fileIndex, int maxFileNameLength) { var sb = new StringBuilder(profile.FileNamePattern); sb.Replace("%Profile.Id%", profile.Id.ToString()); sb.Replace("%Profile.FolderName%", profile.FolderName); sb.Replace("%Store.Id%", store.Id.ToString()); sb.Replace("%File.Index%", fileIndex.ToString("D4")); if (profile.FileNamePattern.Contains("%Profile.SeoName%")) { sb.Replace("%Profile.SeoName%", SeoHelper.GetSeName(profile.Name, true, false).Replace("/", "").Replace("-", "")); } if (profile.FileNamePattern.Contains("%Store.SeoName%")) { sb.Replace("%Store.SeoName%", profile.PerStore ? SeoHelper.GetSeName(store.Name, true, false) : "allstores"); } if (profile.FileNamePattern.Contains("%Random.Number%")) { sb.Replace("%Random.Number%", CommonHelper.GenerateRandomInteger().ToString()); } if (profile.FileNamePattern.Contains("%Timestamp%")) { sb.Replace("%Timestamp%", DateTime.UtcNow.ToString("s", CultureInfo.InvariantCulture)); } var result = sb.ToString() .ToValidFileName("") .Truncate(maxFileNameLength); return(result); }
public virtual void DeleteExportProfile(ExportProfile profile, bool force = false) { if (profile == null) { throw new ArgumentNullException("profile"); } if (!force && profile.IsSystemProfile) { throw new SmartException(_localizationService.GetResource("Admin.DataExchange.Export.CannotDeleteSystemProfile")); } int scheduleTaskId = profile.SchedulingTaskId; var folder = profile.GetExportFolder(); var deployments = profile.Deployments.Where(x => !x.IsTransientRecord()).ToList(); if (deployments.Any()) { _exportDeploymentRepository.DeleteRange(deployments); _exportDeploymentRepository.Context.SaveChanges(); } _exportProfileRepository.Delete(profile); var scheduleTask = _scheduleTaskService.GetTaskById(scheduleTaskId); _scheduleTaskService.DeleteTask(scheduleTask); if (System.IO.Directory.Exists(folder)) { FileSystemHelper.ClearDirectory(folder, true); } }
/// <summary> /// Gets the ZIP path for an export profile. /// </summary> /// <param name="profile">Export profile.</param> /// <returns>ZIP file path.</returns> public static string GetExportZipPath(this ExportProfile profile) { Guard.NotNull(profile, nameof(profile)); var name = new DirectoryInfo(profile.FolderName).Name.NullEmpty() ?? "ExportData"; return(Path.Combine(profile.GetExportDirectory(), name.ToValidFileName() + ".zip")); }
public DataExportRequest(ExportProfile profile, Provider <IExportProvider> provider) { Guard.NotNull(profile, nameof(profile)); Guard.NotNull(provider, nameof(provider)); Profile = profile; Provider = provider; ProgressValueSetter = _voidProgressValueSetter; }
public DataExportRequest(ExportProfile profile, Provider <IExportProvider> provider) { Guard.NotNull(profile, nameof(profile)); Guard.NotNull(provider, nameof(provider)); Profile = profile; Provider = provider; ProgressCallback = OnProgress; }
public void InitialisesPhotoSetTest() { var profile = ModelBuilder.Model.Create <Profile>(); var photos = ModelBuilder.Model.Create <List <ExportPhoto> >(); var sut = new ExportProfile(profile, photos); sut.Should().BeEquivalentTo(profile, opt => opt.ExcludingMissingMembers()); sut.Photos.Should().BeEquivalentTo(photos); }
/// <summary> /// Gets the ZIP path for a profile /// </summary> /// <param name="profile">Export profile</param> /// <returns>ZIP file path</returns> public static string GetExportZipPath(this ExportProfile profile) { var name = (new DirectoryInfo(profile.FolderName)).Name; if (name.IsEmpty()) { name = "ExportData"; } return(Path.Combine(profile.GetExportFolder(), name.ToValidFileName() + ".zip")); }
/// <summary> /// Get number of existing export files /// </summary> /// <param name="profile">Export profile</param> /// <param name="provider">Export provider</param> /// <returns>Number of export files</returns> public static int GetExportFileCount(this ExportProfile profile, Provider <IExportProvider> provider) { var result = profile.GetExportFiles(provider).Count(); if (File.Exists(profile.GetExportZipPath())) { ++result; } return(result); }
/// <summary> /// Get temporary folder for an export profile /// </summary> /// <param name="profile">Export profile</param> /// <returns>Folder path</returns> public static string GetExportFolder(this ExportProfile profile, bool content = false, bool create = false) { var path = CommonHelper.MapPath(string.Concat(profile.FolderName, content ? "/Content" : "")); if (create && !System.IO.Directory.Exists(path)) { System.IO.Directory.CreateDirectory(path); } return(path); }
public DataExportRequest(ExportProfile profile, Provider <IExportProvider> provider) { Guard.ArgumentNotNull(() => profile); Guard.ArgumentNotNull(() => provider); Profile = profile; Provider = provider; ProgressValueSetter = _voidProgressValueSetter; EntitiesToExport = new List <int>(); CustomData = new Dictionary <string, object>(StringComparer.OrdinalIgnoreCase); }
public DataExportRequest(ExportProfile profile, Provider<IExportProvider> provider) { Guard.ArgumentNotNull(() => profile); Guard.ArgumentNotNull(() => provider); Profile = profile; Provider = provider; ProgressValueSetter = _voidProgressValueSetter; EntitiesToExport = new List<int>(); CustomData = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase); }
/// <summary> /// Get temporary folder for an export profile /// </summary> /// <param name="profile">Export profile</param> /// <returns>Folder path</returns> public static string GetExportFolder(this ExportProfile profile, bool content = false, bool create = false) { Guard.IsTrue(profile.FolderName.EmptyNull().Length > 2, nameof(profile.FolderName), "The export folder name must be at least 3 characters long."); var path = CommonHelper.MapPath(string.Concat(profile.FolderName, content ? "/Content" : "")); if (create && !System.IO.Directory.Exists(path)) { System.IO.Directory.CreateDirectory(path); } return(path); }
public virtual void UpdateExportProfile(ExportProfile profile) { Guard.NotNull(profile, nameof(profile)); profile.FolderName = PathHelper.NormalizeAppRelativePath(profile.FolderName); if (!PathHelper.IsSafeAppRootPath(profile.FolderName)) { throw new SmartException(_localizationService.GetResource("Admin.DataExchange.Export.FolderName.Validate")); } _exportProfileRepository.Update(profile); }
public virtual void UpdateExportProfile(ExportProfile profile) { if (profile == null) { throw new ArgumentNullException("profile"); } profile.FolderName = FileSystemHelper.ValidateRootPath(profile.FolderName); _exportProfileRepository.Update(profile); _eventPublisher.EntityUpdated(profile); }
/// <summary> /// Gets existing export files for an export profile /// </summary> /// <param name="profile">Export profile</param> /// <param name="provider">Export provider</param> /// <returns>List of file names</returns> public static IEnumerable <string> GetExportFiles(this ExportProfile profile, Provider <IExportProvider> provider) { var exportFolder = profile.GetExportFolder(true); if (System.IO.Directory.Exists(exportFolder) && provider.Value.FileExtension.HasValue()) { var filter = "*.{0}".FormatInvariant(provider.Value.FileExtension.ToLower()); return(System.IO.Directory.EnumerateFiles(exportFolder, filter, SearchOption.AllDirectories).OrderBy(x => x)); } return(Enumerable.Empty <string>()); }
/// <summary> /// Gets existing export files for an export profile /// </summary> /// <param name="profile">Export profile</param> /// <returns>List of file names</returns> public static List <string> GetExportFiles(this ExportProfile profile) { var exportFolder = profile.GetExportFolder(true); if (System.IO.Directory.Exists(exportFolder)) { return(System.IO.Directory.EnumerateFiles(exportFolder, "*", SearchOption.TopDirectoryOnly) .OrderBy(x => x) .ToList()); } return(new List <string>()); }
public virtual void UpdateExportProfile(ExportProfile profile) { if (profile == null) { throw new ArgumentNullException("profile"); } profile.FolderName = profile.FolderName .ToValidPath() .Truncate(_dataExchangeSettings.MaxFileNameLength); _exportProfileRepository.Update(profile); _eventPublisher.EntityUpdated(profile); }
public void ExportProfileTest() { //Prepare cuesheet var testHelper = new TestHelper(); Cuesheet cuesheet = testHelper.CuesheetController.Cuesheet; cuesheet.Artist = "Demo Artist"; cuesheet.Title = "Demo Title"; cuesheet.AudioFile = new AudioFile("Testfile.mp3"); var begin = TimeSpan.Zero; for (int i = 1; i < 25; i++) { var track = testHelper.CuesheetController.NewTrack(); track.Artist = String.Format("Demo Track Artist {0}", i); track.Title = String.Format("Demo Track Title {0}", i); track.Begin = begin; begin = begin.Add(new TimeSpan(0, i, i)); track.End = begin; cuesheet.AddTrack(track); } //Test class var exportProfile = new ExportProfile(testHelper.Localizer); exportProfile.SchemeHead.Scheme = "%Cuesheet.Artist%;%Cuesheet.Title%"; Assert.IsTrue(exportProfile.SchemeHead.IsValid); exportProfile.SchemeTracks.Scheme = "%Track.Position%;%Track.Artist%;%Track.Title%;%Track.Begin%;%Track.End%;%Track.Length%"; Assert.IsTrue(exportProfile.SchemeTracks.IsValid); exportProfile.SchemeFooter.Scheme = "Exported %Cuesheet.Title% from %Cuesheet.Artist% using AudioCuesheetEditor"; Assert.IsTrue(exportProfile.SchemeFooter.IsValid); Assert.IsTrue(exportProfile.IsExportable); var fileContent = exportProfile.GenerateExport(cuesheet); Assert.IsNotNull(fileContent); var tempFile = Path.GetTempFileName(); File.WriteAllBytes(tempFile, fileContent); var content = File.ReadAllLines(tempFile); Assert.AreEqual(content[0], "Demo Artist;Demo Title"); for (int i = 1; i < content.Length - 1; i++) { Assert.IsFalse(String.IsNullOrEmpty(content[i])); Assert.AreNotEqual(content[i], ";;;;;"); Assert.IsTrue(content[i].StartsWith(cuesheet.Tracks.ToList()[i - 1].Position + ";")); } Assert.AreEqual(content[^ 1], "Exported Demo Title from Demo Artist using AudioCuesheetEditor");
public virtual void UpdateExportProfile(ExportProfile profile) { if (profile == null) { throw new ArgumentNullException("profile"); } profile.FolderName = FileSystemHelper.ValidateRootPath(profile.FolderName); if (profile.FolderName == "~/") { throw new SmartException("Invalid export folder name."); } _exportProfileRepository.Update(profile); }
public virtual void UpdateExportProfile(ExportProfile profile) { if (profile == null) { throw new ArgumentNullException("profile"); } profile.FolderName = FileSystemHelper.ValidateRootPath(profile.FolderName); if (!FileSystemHelper.IsSafeRootPath(profile.FolderName)) { throw new SmartException(_localizationService.GetResource("Admin.DataExchange.Export.FolderName.Validate")); } _exportProfileRepository.Update(profile); }
/// <summary> /// Gets a temporary folder for an export profile. /// </summary> /// <param name="profile">Export profile.</param> /// <returns>Folder path.</returns> public static string GetExportDirectory(this ExportProfile profile, bool content = false, bool create = false) { // TODO: (mg) (core) All file system related stuff must use IFileSystem. This method should return IDirectory. CommonHelper.ContentRoot could be used as entry point (or IApplicationContext.xyzRoot) // TODO: (mg) (core) Never save something outside of wwwroot or App_Data directories. // TODO: (mg) (core) Given the new requirements, this class has to be refactored rather heavily. Guard.NotNull(profile, nameof(profile)); Guard.IsTrue(profile.FolderName.EmptyNull().Length > 2, nameof(profile.FolderName), "The export folder name must be at least 3 characters long."); var path = CommonHelper.MapPath(string.Concat(profile.FolderName, content ? "/Content" : "")); if (create && !Directory.Exists(path)) { Directory.CreateDirectory(path); } return(path); }
private async Task <ExportDeploymentModel> CreateDeploymentModel( ExportProfile profile, ExportDeployment deployment, Provider <IExportProvider> provider, bool createForEdit) { var model = MiniMapper.Map <ExportDeployment, ExportDeploymentModel>(deployment); model.EmailAddresses = deployment.EmailAddresses.SplitSafe(",").ToArray(); model.DeploymentTypeName = await Services.Localization.GetLocalizedEnumAsync(deployment.DeploymentType); model.PublicFolderUrl = await _exportProfileService.GetDeploymentDirectoryUrlAsync(deployment); if (createForEdit) { model.CreateZip = profile.CreateZipArchive; ViewBag.DeploymentTypes = ExportDeploymentType.FileSystem.ToSelectList(false).ToList(); ViewBag.HttpTransmissionTypes = ExportHttpTransmissionType.SimplePost.ToSelectList(false).ToList(); if (ViewBag.EmailAccounts == null) { var emailAccounts = await _db.EmailAccounts.AsNoTracking().ToListAsync(); ViewBag.EmailAccounts = emailAccounts .Select(x => new SelectListItem { Text = x.FriendlyName, Value = x.Id.ToString() }) .ToList(); } if (provider != null) { model.ThumbnailUrl = GetThumbnailUrl(provider); } } else { model.FileCount = (await CreateFileDetailsModel(profile, deployment)).FileCount; } return(model); }
/// <summary> /// Resolves the file name pattern for an export profile. /// </summary> /// <param name="profile">Export profile.</param> /// <param name="store">Store.</param> /// <param name="fileIndex">One based file index.</param> /// <param name="maxFileNameLength">The maximum length of the file name.</param> /// <param name="fileNamePattern"> /// The file name pattern to be resolved. /// <see cref="ExportProfile.FileNamePattern"/> of <paramref name="profile"/> is used if <c>null</c>. /// </param> /// <returns>Resolved file name pattern.</returns> public static string ResolveFileNamePattern( this ExportProfile profile, Store store, int fileIndex, int maxFileNameLength, string fileNamePattern = null) { fileNamePattern ??= profile.FileNamePattern; using var psb = StringBuilderPool.Instance.Get(out var sb); sb.Append(fileNamePattern); sb.Replace("%Profile.Id%", profile.Id.ToString()); sb.Replace("%Profile.FolderName%", profile.FolderName); sb.Replace("%Store.Id%", store.Id.ToString()); sb.Replace("%File.Index%", fileIndex.ToString("D4")); if (fileNamePattern.Contains("%Profile.SeoName%")) { sb.Replace("%Profile.SeoName%", SeoHelper.BuildSlug(profile.Name, true, false, false).Replace("-", "")); } if (fileNamePattern.Contains("%Store.SeoName%")) { sb.Replace("%Store.SeoName%", profile.PerStore ? SeoHelper.BuildSlug(store.Name, true, false, true) : "allstores"); } if (fileNamePattern.Contains("%Random.Number%")) { sb.Replace("%Random.Number%", CommonHelper.GenerateRandomInteger().ToString()); } if (fileNamePattern.Contains("%Timestamp%")) { sb.Replace("%Timestamp%", DateTime.UtcNow.ToString("s", CultureInfo.InvariantCulture)); } var result = sb.ToString() .ToValidFileName(string.Empty) .Truncate(maxFileNameLength); return(result); }
public virtual void DeleteExportProfile(ExportProfile profile, bool force = false) { if (profile == null) throw new ArgumentNullException("profile"); if (!force && profile.IsSystemProfile) throw new SmartException(_localizationService.GetResource("Admin.DataExchange.Export.CannotDeleteSystemProfile")); int scheduleTaskId = profile.SchedulingTaskId; var folder = profile.GetExportFolder(); _exportProfileRepository.Delete(profile); var scheduleTask = _scheduleTaskService.GetTaskById(scheduleTaskId); _scheduleTaskService.DeleteTask(scheduleTask); _eventPublisher.EntityDeleted(profile); if (System.IO.Directory.Exists(folder)) { FileSystemHelper.ClearDirectory(folder, true); } }
public virtual void UpdateExportProfile(ExportProfile profile) { if (profile == null) throw new ArgumentNullException("profile"); profile.FolderName = FileSystemHelper.ValidateRootPath(profile.FolderName); _exportProfileRepository.Update(profile); _eventPublisher.EntityUpdated(profile); }
public void CreatesPhotoSetOnDefaultConstructorTest() { var sut = new ExportProfile(); sut.Photos.Should().NotBeNull(); }
public virtual ExportProfile InsertExportProfile( string providerSystemName, string name, string fileExtension, ExportFeatures features, bool isSystemProfile = false, string profileSystemName = null, int cloneFromProfileId = 0) { Guard.ArgumentNotEmpty(() => providerSystemName); var profileCount = _exportProfileRepository.Table.Count(x => x.ProviderSystemName == providerSystemName); if (name.IsEmpty()) name = providerSystemName; if (!isSystemProfile) name = string.Concat(_localizationService.GetResource("Common.My"), " ", name); name = string.Concat(name, " ", profileCount + 1); var cloneProfile = GetExportProfileById(cloneFromProfileId); ScheduleTask task = null; ExportProfile profile = null; if (cloneProfile == null) { task = new ScheduleTask { CronExpression = "0 */6 * * *", // every six hours Type = typeof(DataExportTask).AssemblyQualifiedNameWithoutVersion(), Enabled = false, StopOnError = false, IsHidden = true }; } else { task = cloneProfile.ScheduleTask.Clone(); task.LastEndUtc = task.LastStartUtc = task.LastSuccessUtc = null; } task.Name = string.Concat(name, " Task"); _scheduleTaskService.InsertTask(task); if (cloneProfile == null) { profile = new ExportProfile { FileNamePattern = _defaultFileNamePattern }; if (isSystemProfile) { profile.Enabled = true; profile.PerStore = false; profile.CreateZipArchive = false; profile.Cleanup = false; } else { // what we do here is to preset typical settings for feed creation // but on the other hand they may be untypical for generic data export\exchange var projection = new ExportProjection { RemoveCriticalCharacters = true, CriticalCharacters = "¼,½,¾", PriceType = PriceDisplayType.PreSelectedPrice, NoGroupedProducts = (features.HasFlag(ExportFeatures.CanOmitGroupedProducts) ? true : false), DescriptionMerging = ExportDescriptionMerging.Description }; var filter = new ExportFilter { IsPublished = true }; profile.Projection = XmlHelper.Serialize<ExportProjection>(projection); profile.Filtering = XmlHelper.Serialize<ExportFilter>(filter); } } else { profile = cloneProfile.Clone(); } profile.IsSystemProfile = isSystemProfile; profile.Name = name; profile.ProviderSystemName = providerSystemName; profile.SchedulingTaskId = task.Id; var cleanedSystemName = providerSystemName .Replace("Exports.", "") .Replace("Feeds.", "") .Replace("/", "") .Replace("-", ""); var folderName = SeoHelper.GetSeName(cleanedSystemName, true, false) .ToValidPath() .Truncate(_dataExchangeSettings.MaxFileNameLength); profile.FolderName = "~/App_Data/ExportProfiles/" + FileSystemHelper.CreateNonExistingDirectoryName(CommonHelper.MapPath("~/App_Data/ExportProfiles"), folderName); if (profileSystemName.IsEmpty() && isSystemProfile) profile.SystemName = cleanedSystemName; else profile.SystemName = profileSystemName; _exportProfileRepository.Insert(profile); task.Alias = profile.Id.ToString(); _scheduleTaskService.UpdateTask(task); if (fileExtension.HasValue() && !isSystemProfile) { if (cloneProfile == null) { if (features.HasFlag(ExportFeatures.CreatesInitialPublicDeployment)) { var subFolder = FileSystemHelper.CreateNonExistingDirectoryName(CommonHelper.MapPath("~/" + DataExporter.PublicFolder), folderName); profile.Deployments.Add(new ExportDeployment { ProfileId = profile.Id, Enabled = true, DeploymentType = ExportDeploymentType.PublicFolder, Name = profile.Name, SubFolder = subFolder }); UpdateExportProfile(profile); } } else { foreach (var deployment in cloneProfile.Deployments) { profile.Deployments.Add(deployment.Clone()); } UpdateExportProfile(profile); } } _eventPublisher.EntityInserted(profile); return profile; }
private async Task <ExportFileDetailsModel> CreateFileDetailsModel(ExportProfile profile, ExportDeployment deployment) { var model = new ExportFileDetailsModel { Id = deployment?.Id ?? profile.Id, IsForDeployment = deployment != null }; try { var rootPath = (await Services.ApplicationContext.ContentRoot.GetDirectoryAsync(null)).PhysicalPath; // Add export files. var dir = await _exportProfileService.GetExportDirectoryAsync(profile, "Content"); var zipFile = await dir.Parent.GetFileAsync(dir.Parent.Name.ToValidFileName() + ".zip"); var resultInfo = XmlHelper.Deserialize <DataExportResult>(profile.ResultInfo); if (deployment == null) { await AddFileInfo(model.ExportFiles, zipFile, rootPath); if (resultInfo.Files != null) { foreach (var fi in resultInfo.Files) { await AddFileInfo(model.ExportFiles, await dir.GetFileAsync(fi.FileName), rootPath, null, fi); } } } else if (deployment.DeploymentType == ExportDeploymentType.FileSystem) { if (resultInfo.Files != null) { var deploymentDir = await _exportProfileService.GetDeploymentDirectoryAsync(deployment); if (deploymentDir != null) { foreach (var fi in resultInfo.Files) { await AddFileInfo(model.ExportFiles, await deploymentDir.GetFileAsync(fi.FileName), rootPath, null, fi); } } } } // Add public files. var publicDeployment = deployment == null ? profile.Deployments.FirstOrDefault(x => x.DeploymentType == ExportDeploymentType.PublicFolder) : (deployment.DeploymentType == ExportDeploymentType.PublicFolder ? deployment : null); if (publicDeployment != null) { var currentStore = Services.StoreContext.CurrentStore; var deploymentDir = await _exportProfileService.GetDeploymentDirectoryAsync(publicDeployment); if (deploymentDir != null) { // INFO: public folder is not cleaned up during export. We only have to show files that has been created during last export. // Otherwise the merchant might publish URLs of old export files. if (profile.CreateZipArchive) { var url = await _exportProfileService.GetDeploymentDirectoryUrlAsync(publicDeployment, currentStore); await AddFileInfo(model.PublicFiles, await deploymentDir.GetFileAsync(zipFile.Name), rootPath, url); } else if (resultInfo.Files != null) { var stores = Services.StoreContext.GetAllStores().ToDictionary(x => x.Id); foreach (var fi in resultInfo.Files) { stores.TryGetValue(fi.StoreId, out var store); var url = await _exportProfileService.GetDeploymentDirectoryUrlAsync(publicDeployment, store ?? currentStore); await AddFileInfo(model.PublicFiles, await deploymentDir.GetFileAsync(fi.FileName), rootPath, url, fi, store); } } } } } catch (Exception ex) { NotifyError(ex); } return(model); }
// TODO: (mg) (core) add ViewComponent for former child-action "InfoProfile". // TODO: (mg) (core) implement action methods for Deployment. #region Utilities private async Task PrepareProfileModel( ExportProfileModel model, ExportProfile profile, Provider <IExportProvider> provider, TaskExecutionInfo lastExecutionInfo, bool createForEdit) { MiniMapper.Map(profile, model); var dir = await _exportProfileService.GetExportDirectoryAsync(profile); var logFile = await dir.GetFileAsync("log.txt"); //var moduleDescriptor = provider.Metadata.ModuleDescriptor; model.TaskName = profile.Task.Name.NaIfEmpty(); model.IsTaskRunning = lastExecutionInfo?.IsRunning ?? false; model.IsTaskEnabled = profile.Task.Enabled; model.LogFileExists = logFile.Exists; model.HasActiveProvider = provider != null; model.FileNamePatternDescriptions = T("Admin.DataExchange.Export.FileNamePatternDescriptions").Value.SplitSafe(";").ToArray(); model.Provider = new ExportProfileModel.ProviderModel { EntityType = provider.Value.EntityType, EntityTypeName = await Services.Localization.GetLocalizedEnumAsync(provider.Value.EntityType), FileExtension = provider.Value.FileExtension, ThumbnailUrl = GetThumbnailUrl(provider), // TODO: (mg) (core) PluginMediator required in ExportController. //FriendlyName = _pluginMediator.GetLocalizedFriendlyName(provider.Metadata), FriendlyName = provider.Metadata.SystemName, //Description = _pluginMediator.GetLocalizedDescription(provider.Metadata), Description = provider.Metadata.SystemName, //Url = descriptor?.Url, //Author = descriptor?.Author, //Version = descriptor?.Version?.ToString() }; if (!createForEdit) { return; } var projection = XmlHelper.Deserialize <ExportProjection>(profile.Projection); var filter = XmlHelper.Deserialize <ExportFilter>(profile.Filtering); var language = Services.WorkContext.WorkingLanguage; var store = Services.StoreContext.CurrentStore; var stores = Services.StoreContext.GetAllStores(); var emailAccounts = await _db.EmailAccounts.AsNoTracking().ToListAsync(); var languages = await _db.Languages .AsNoTracking() .OrderBy(x => x.DisplayOrder) .ToListAsync(); var currencies = await _db.Currencies .AsNoTracking() .OrderBy(x => x.DisplayOrder) .ToListAsync(); model.Offset = profile.Offset; model.Limit = profile.Limit == 0 ? null : profile.Limit; model.BatchSize = profile.BatchSize == 0 ? null : profile.BatchSize; model.PerStore = profile.PerStore; model.EmailAccountId = profile.EmailAccountId; model.CompletedEmailAddresses = profile.CompletedEmailAddresses.SplitSafe(",").ToArray(); model.CreateZipArchive = profile.CreateZipArchive; model.Cleanup = profile.Cleanup; model.PrimaryStoreCurrencyCode = Services.StoreContext.CurrentStore.PrimaryStoreCurrency.CurrencyCode; model.FileNamePatternExample = profile.ResolveFileNamePattern(store, 1, _dataExchangeSettings.MaxFileNameLength); ViewBag.EmailAccounts = emailAccounts .Select(x => new SelectListItem { Text = x.FriendlyName, Value = x.Id.ToString() }) .ToList(); ViewBag.CompletedEmailAddresses = new MultiSelectList(profile.CompletedEmailAddresses.SplitSafe(",")); // TODO: (mg) (core) check\test whether such ViewBag objects can really be used multiple times for different view controls. ViewBag.Stores = stores.ToSelectListItems(); ViewBag.Languages = languages .Select(y => new SelectListItem { Text = y.Name, Value = y.Id.ToString() }) .ToList(); ViewBag.Currencies = currencies .Select(y => new SelectListItem { Text = y.Name, Value = y.Id.ToString() }) .ToList(); ViewBag.DeploymentTypeIconClasses = DeploymentTypeIconClasses; // Projection. model.Projection = MiniMapper.Map <ExportProjection, ExportProjectionModel>(projection); model.Projection.NumberOfPictures = projection.NumberOfMediaFiles; model.Projection.AppendDescriptionText = projection.AppendDescriptionText.SplitSafe(",").ToArray(); model.Projection.CriticalCharacters = projection.CriticalCharacters.SplitSafe(",").ToArray(); if (profile.Projection.IsEmpty()) { model.Projection.DescriptionMergingId = (int)ExportDescriptionMerging.Description; } // Filtering. model.Filter = MiniMapper.Map <ExportFilter, ExportFilterModel>(filter); // Deployment. model.Deployments = await profile.Deployments.SelectAsync(async x => { var deploymentModel = await CreateDeploymentModel(profile, x, null, false); if (x.ResultInfo.HasValue()) { var resultInfo = XmlHelper.Deserialize <DataDeploymentResult>(x.ResultInfo); var lastExecution = Services.DateTimeHelper.ConvertToUserTime(resultInfo.LastExecutionUtc, DateTimeKind.Utc); deploymentModel.LastResult = new ExportDeploymentModel.LastResultInfo { Execution = lastExecution, ExecutionPretty = lastExecution.Humanize(false), Error = resultInfo.LastError }; } return(deploymentModel); }) .AsyncToList(); // Provider. if (provider != null) { model.Provider.Feature = provider.Metadata.ExportFeatures; if (model.Provider.EntityType == ExportEntityType.Product) { var manufacturers = await _db.Manufacturers .AsNoTracking() .ApplyStandardFilter(true) .ToListAsync(); var productTags = await _db.ProductTags .AsNoTracking() .ToListAsync(); ViewBag.Manufacturers = manufacturers .Select(x => new SelectListItem { Text = x.Name, Value = x.Id.ToString() }) .ToList(); ViewBag.ProductTags = productTags .Select(x => new SelectListItem { Text = x.Name, Value = x.Id.ToString() }) .ToList(); ViewBag.PriceTypes = PriceDisplayType.LowestPrice .ToSelectList(false) .Where(x => x.Value != ((int)PriceDisplayType.Hide).ToString()) .ToList(); ViewBag.AppendDescriptionTexts = new MultiSelectList(projection.AppendDescriptionText.SplitSafe(",")); ViewBag.CriticalCharacters = new MultiSelectList(projection.CriticalCharacters.SplitSafe(",")); if (model.Filter.CategoryIds?.Any() ?? false) { var tree = await _categoryService.GetCategoryTreeAsync(0, true); ViewBag.SelectedCategories = model.Filter.CategoryIds .Where(x => x != 0) .Select(x => { var node = tree.SelectNodeById(x); var item = new SelectListItem { Selected = true, Value = x.ToString(), Text = node == null ? x.ToString() : _categoryService.GetCategoryPath(node) }; return(item); }) .ToList(); } else { ViewBag.SelectedCategories = new List <SelectListItem>(); } } else if (model.Provider.EntityType == ExportEntityType.Customer) { var countries = await _db.Countries .AsNoTracking() .ApplyStandardFilter(true) .ToListAsync(); ViewBag.Countries = countries .Select(x => new SelectListItem { Text = x.GetLocalized(y => y.Name, language, true, false), Value = x.Id.ToString() }) .ToList(); } try { var configInfo = provider.Value.ConfigurationInfo; if (configInfo != null) { model.Provider.ConfigurationWidget = configInfo.ConfigurationWidget; model.Provider.ConfigDataType = configInfo.ModelType; model.Provider.ConfigData = XmlHelper.Deserialize(profile.ProviderConfigData, configInfo.ModelType); if (configInfo.Initialize != null) { try { configInfo.Initialize(model.Provider.ConfigData); } catch (Exception ex) { NotifyWarning(ex.ToAllMessages()); } } } } catch (Exception ex) { NotifyError(ex); } } }
/// <summary> /// Get log file path for an export profile /// </summary> /// <param name="profile">Export profile</param> /// <returns>Log file path</returns> public static string GetExportLogPath(this ExportProfile profile) { return(Path.Combine(profile.GetExportFolder(), "log.txt")); }
public virtual ExportProfile InsertExportProfile( string providerSystemName, string name, string fileExtension, ExportFeatures features, bool isSystemProfile = false, string profileSystemName = null, int cloneFromProfileId = 0) { Guard.ArgumentNotEmpty(() => providerSystemName); var profileCount = _exportProfileRepository.Table.Count(x => x.ProviderSystemName == providerSystemName); if (name.IsEmpty()) { name = providerSystemName; } if (!isSystemProfile) { name = string.Concat(_localizationService.GetResource("Common.My"), " ", name); } name = string.Concat(name, " ", profileCount + 1); var cloneProfile = GetExportProfileById(cloneFromProfileId); ScheduleTask task = null; ExportProfile profile = null; if (cloneProfile == null) { task = new ScheduleTask { CronExpression = "0 */6 * * *", // every six hours Type = typeof(DataExportTask).AssemblyQualifiedNameWithoutVersion(), Enabled = false, StopOnError = false, IsHidden = true }; } else { task = cloneProfile.ScheduleTask.Clone(); task.LastEndUtc = task.LastStartUtc = task.LastSuccessUtc = null; } task.Name = string.Concat(name, " Task"); _scheduleTaskService.InsertTask(task); if (cloneProfile == null) { profile = new ExportProfile { FileNamePattern = _defaultFileNamePattern }; if (isSystemProfile) { profile.Enabled = true; profile.PerStore = false; profile.CreateZipArchive = false; profile.Cleanup = false; } else { // what we do here is to preset typical settings for feed creation // but on the other hand they may be untypical for generic data export\exchange var projection = new ExportProjection { RemoveCriticalCharacters = true, CriticalCharacters = "¼,½,¾", PriceType = PriceDisplayType.PreSelectedPrice, NoGroupedProducts = (features.HasFlag(ExportFeatures.CanOmitGroupedProducts) ? true : false), DescriptionMerging = ExportDescriptionMerging.Description }; var filter = new ExportFilter { IsPublished = true }; profile.Projection = XmlHelper.Serialize <ExportProjection>(projection); profile.Filtering = XmlHelper.Serialize <ExportFilter>(filter); } } else { profile = cloneProfile.Clone(); } profile.IsSystemProfile = isSystemProfile; profile.Name = name; profile.ProviderSystemName = providerSystemName; profile.SchedulingTaskId = task.Id; var cleanedSystemName = providerSystemName .Replace("Exports.", "") .Replace("Feeds.", "") .Replace("/", "") .Replace("-", ""); var folderName = SeoHelper.GetSeName(cleanedSystemName, true, false) .ToValidPath() .Truncate(_dataExchangeSettings.MaxFileNameLength); profile.FolderName = "~/App_Data/ExportProfiles/" + FileSystemHelper.CreateNonExistingDirectoryName(CommonHelper.MapPath("~/App_Data/ExportProfiles"), folderName); if (profileSystemName.IsEmpty() && isSystemProfile) { profile.SystemName = cleanedSystemName; } else { profile.SystemName = profileSystemName; } _exportProfileRepository.Insert(profile); task.Alias = profile.Id.ToString(); _scheduleTaskService.UpdateTask(task); if (fileExtension.HasValue() && !isSystemProfile) { if (cloneProfile == null) { if (features.HasFlag(ExportFeatures.CreatesInitialPublicDeployment)) { var subFolder = FileSystemHelper.CreateNonExistingDirectoryName(CommonHelper.MapPath("~/" + DataExporter.PublicFolder), folderName); profile.Deployments.Add(new ExportDeployment { ProfileId = profile.Id, Enabled = true, DeploymentType = ExportDeploymentType.PublicFolder, Name = profile.Name, SubFolder = subFolder }); UpdateExportProfile(profile); } } else { foreach (var deployment in cloneProfile.Deployments) { profile.Deployments.Add(deployment.Clone()); } UpdateExportProfile(profile); } } _eventPublisher.EntityInserted(profile); return(profile); }
/// <summary> /// Gets the ZIP path for a profile /// </summary> /// <param name="profile">Export profile</param> /// <returns>ZIP file path</returns> public static string GetExportZipPath(this ExportProfile profile) { return(Path.Combine(profile.GetExportFolder(), profile.FolderName + ".zip")); }