public virtual void Publish(ExportDeploymentContext context, ExportDeployment deployment) { _context = context; _deployment = deployment; _succeededFiles = 0; _ftpRootUrl = deployment.Url; if (!_ftpRootUrl.StartsWith("ftp://", StringComparison.InvariantCultureIgnoreCase)) { _ftpRootUrl = "ftp://" + _ftpRootUrl; } _ftpRootUrl = _ftpRootUrl.EnsureEndsWith("/"); if (context.CreateZipArchive) { if (File.Exists(context.ZipPath)) { var fileUrl = _ftpRootUrl + Path.GetFileName(context.ZipPath); UploadFile(context.ZipPath, fileUrl, false); } } else { FtpCopyDirectory(new DirectoryInfo(context.FolderContent)); } context.Log.Info("{0} file(s) successfully uploaded via FTP.".FormatInvariant(_succeededFiles)); }
public async Task PublishAsync(ExportDeployment deployment, ExportDeploymentContext context, CancellationToken cancelToken) { _deployment = deployment; _context = context; _cancelToken = cancelToken; _succeededFiles = 0; _ftpRootUrl = deployment.Url; if (!_ftpRootUrl.StartsWith("ftp://", StringComparison.InvariantCultureIgnoreCase)) { _ftpRootUrl = "ftp://" + _ftpRootUrl; } _ftpRootUrl = _ftpRootUrl.EnsureEndsWith("/"); if (context.CreateZipArchive) { if (context.ZipFile?.Exists ?? false) { await UploadFile(context.ZipFile, _ftpRootUrl + context.ZipFile.Name, false); } } else { await FtpCopyDirectory(context.ExportDirectory); } context.Log.Info($"{_succeededFiles} file(s) successfully uploaded via FTP."); }
public virtual void Publish(ExportDeploymentContext context, ExportDeployment deployment) { var destinationFolder = deployment.GetDeploymentFolder(true); if (destinationFolder.IsEmpty()) return; if (!System.IO.Directory.Exists(destinationFolder)) { System.IO.Directory.CreateDirectory(destinationFolder); } if (context.CreateZipArchive) { if (File.Exists(context.ZipPath)) { var destinationFile = Path.Combine(destinationFolder, Path.GetFileName(context.ZipPath)); File.Copy(context.ZipPath, destinationFile, true); context.Log.Information("Copied zipped export data to " + destinationFile); } } else { if (!FileSystemHelper.CopyDirectory(new DirectoryInfo(context.FolderContent), new DirectoryInfo(destinationFolder))) { context.Result.LastError = context.T("Admin.DataExchange.Export.Deployment.CopyFileFailed"); } context.Log.Information("Copied export data files to " + destinationFolder); } }
public virtual void Publish(ExportDeploymentContext context, ExportDeployment deployment) { var destinationFolder = deployment.GetDeploymentFolder(true); if (destinationFolder.IsEmpty()) { return; } if (!System.IO.Directory.Exists(destinationFolder)) { System.IO.Directory.CreateDirectory(destinationFolder); } if (context.CreateZipArchive) { if (File.Exists(context.ZipPath)) { var destinationFile = Path.Combine(destinationFolder, Path.GetFileName(context.ZipPath)); File.Copy(context.ZipPath, destinationFile, true); context.Log.Information("Copied zipped export data to " + destinationFile); } } else { if (!FileSystemHelper.CopyDirectory(new DirectoryInfo(context.FolderContent), new DirectoryInfo(destinationFolder))) { context.Result.LastError = context.T("Admin.DataExchange.Export.Deployment.CopyFileFailed"); } context.Log.Information("Copied export data files to " + destinationFolder); } }
/// <summary> /// Get url of the public folder and take filtering and projection into consideration /// </summary> /// <param name="deployment">Export deployment</param> /// <param name="services">Common services</param> /// <param name="store">Store entity</param> /// <returns>Absolute URL of the public folder (always ends with /) or <c>null</c></returns> public static string GetPublicFolderUrl(this ExportDeployment deployment, ICommonServices services, Store store = null) { if (deployment != null && deployment.DeploymentType == ExportDeploymentType.PublicFolder) { if (store == null) { var filter = XmlHelper.Deserialize <ExportFilter>(deployment.Profile.Filtering); var storeId = filter.StoreId; if (storeId == 0) { var projection = XmlHelper.Deserialize <ExportProjection>(deployment.Profile.Projection); storeId = (projection.StoreId ?? 0); } store = (storeId == 0 ? services.StoreContext.CurrentStore : services.StoreService.GetStoreById(storeId)); } var url = string.Concat( store.Url.EnsureEndsWith("/"), DataExporter.PublicFolder.EnsureEndsWith("/"), deployment.SubFolder.HasValue() ? deployment.SubFolder.EnsureEndsWith("/") : "" ); return(url); } return(null); }
public virtual void DeleteExportDeployment(ExportDeployment deployment) { if (deployment == null) throw new ArgumentNullException("deployment"); _exportDeploymentRepository.Delete(deployment); _eventPublisher.EntityDeleted(deployment); }
public async Task PublishAsync(ExportDeployment deployment, ExportDeploymentContext context, CancellationToken cancellationToken) { var emailAddresses = deployment.EmailAddresses .SplitSafe(",") .Where(x => x.IsEmail()) .ToArray(); if (!emailAddresses.Any()) { return; } var emailAccount = await _db.EmailAccounts.FindByIdAsync(deployment.EmailAccountId, false, cancellationToken); var fromEmailAddress = emailAccount.ToMailAddress(); var files = await context.GetDeploymentFilesAsync(cancellationToken); var canStreamBlob = _db.DataProvider.CanStreamBlob; var num = 0; foreach (var emailAddress in emailAddresses) { var queuedEmail = new QueuedEmail { From = fromEmailAddress, SendManually = false, To = emailAddress, Subject = deployment.EmailSubject.NaIfEmpty(), Body = deployment.EmailSubject.NaIfEmpty(), CreatedOnUtc = DateTime.UtcNow, EmailAccountId = deployment.EmailAccountId }; foreach (var file in files) { var name = file.Name; var attachment = new QueuedEmailAttachment { StorageLocation = EmailAttachmentStorageLocation.Blob, Name = name, MimeType = MimeTypes.MapNameToMimeType(name) }; using var item = MediaStorageItem.FromFile(file); await _dbMediaStorageProvider.ApplyBlobAsync(attachment, item, false); queuedEmail.Attachments.Add(attachment); } _db.QueuedEmails.Add(queuedEmail); // Blob data could be large, so better not bulk commit here. num += await _db.SaveChangesAsync(cancellationToken); } context.Log.Info($"{num} email(s) created and queued for deployment."); }
public virtual void DeleteExportDeployment(ExportDeployment deployment) { if (deployment == null) { throw new ArgumentNullException("deployment"); } _exportDeploymentRepository.Delete(deployment); }
public virtual void Publish(ExportDeploymentContext context, ExportDeployment deployment) { var targetFolder = deployment.GetDeploymentFolder(true); if (!FileSystemHelper.CopyDirectory(new DirectoryInfo(context.FolderContent), new DirectoryInfo(targetFolder))) { context.Result.LastError = context.T("Admin.DataExchange.Export.Deployment.CopyFileFailed"); } context.Log.Information("Copied export data files to " + targetFolder); }
public virtual void UpdateExportDeployment(ExportDeployment deployment) { if (deployment == null) { throw new ArgumentNullException("deployment"); } _exportDeploymentRepository.Update(deployment); _eventPublisher.EntityUpdated(deployment); }
public virtual void UpdateExportDeployment(ExportDeployment deployment) { if (deployment == null) { throw new ArgumentNullException("deployment"); } if (deployment.DeploymentType == ExportDeploymentType.FileSystem && deployment.FileSystemPath == "~/") { throw new SmartException("Invalid deployment path."); } _exportDeploymentRepository.Update(deployment); }
/// <summary> /// Get path of the deployment folder /// </summary> /// <param name="deployment">Export deployment</param> /// <returns>Deployment folder path</returns> public static string GetDeploymentFolder(this ExportDeployment deployment, bool create = false) { if (deployment == null) { return(null); } string path = null; if (deployment.DeploymentType == ExportDeploymentType.PublicFolder) { if (deployment.SubFolder.HasValue()) { path = Path.Combine(HttpRuntime.AppDomainAppPath, DataExporter.PublicFolder, deployment.SubFolder); } else { path = Path.Combine(HttpRuntime.AppDomainAppPath, DataExporter.PublicFolder); } } else if (deployment.DeploymentType == ExportDeploymentType.FileSystem) { if (deployment.FileSystemPath.IsEmpty()) { return(null); } if (Path.IsPathRooted(deployment.FileSystemPath)) { path = deployment.FileSystemPath; } else { path = PathHelper.NormalizeAppRelativePath(deployment.FileSystemPath); path = CommonHelper.MapPath(path); } } if (create && !System.IO.Directory.Exists(path)) { System.IO.Directory.CreateDirectory(path); } return(path); }
public async Task PublishAsync(ExportDeployment deployment, ExportDeploymentContext context, CancellationToken cancellationToken) { var deploymentDir = await context.ExportProfileService.GetDeploymentDirectoryAsync(deployment, true); if (deploymentDir == null) { return; } var source = _appContext.ContentRoot.AttachEntry(context.ExportDirectory); if (context.CreateZipArchive) { if (context?.ZipFile?.Exists ?? false) { var zipPath = source.FileSystem.PathCombine(source.Parent.SubPath, context.ZipFile.Name); var zipFile = await source.FileSystem.GetFileAsync(zipPath); using var stream = await zipFile.OpenReadAsync(); var newPath = deploymentDir.FileSystem.PathCombine(deploymentDir.SubPath, zipFile.Name); var newFile = await deploymentDir.FileSystem.CreateFileAsync(newPath, stream, true); if (newFile?.Exists ?? false) { context.Log.Info($"Copied zipped export data to {newPath}."); } else { context.Log.Warn($"Failed to copy zipped export data to {newPath}."); } } } else { // Ugly, but the only way I got it to work with CopyDirectoryAsync. var webRootDir = await _appContext.WebRoot.GetDirectoryAsync(null); var newPath = deploymentDir.FileSystem.PathCombine(webRootDir.Name, deploymentDir.SubPath); await source.FileSystem.CopyDirectoryAsync(source.SubPath, newPath); context.Log.Info($"Export data files are copied to {newPath}."); } }
public async Task PublishAsync(ExportDeployment deployment, ExportDeploymentContext context, CancellationToken cancelToken) { var deploymentDir = await context.ExportProfileService.GetDeploymentDirectoryAsync(deployment, true); if (deploymentDir == null) { return; } var source = _appContext.ContentRoot.AttachEntry(context.ExportDirectory); var webRootDir = await _appContext.WebRoot.GetDirectoryAsync(null); var newPath = deploymentDir.FileSystem.PathCombine(webRootDir.Name, deploymentDir.SubPath); await source.FileSystem.CopyDirectoryAsync(source.SubPath, newPath); context.Log.Info($"Export data files are copied to {newPath}."); }
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); }
public virtual void Publish(ExportDeploymentContext context, ExportDeployment deployment) { string folderDestination = null; if (deployment.IsPublic) { folderDestination = Path.Combine(HttpRuntime.AppDomainAppPath, DataExporter.PublicFolder); } else if (deployment.FileSystemPath.IsEmpty()) { return; } else if (deployment.FileSystemPath.StartsWith("/") || deployment.FileSystemPath.StartsWith("\\") || !Path.IsPathRooted(deployment.FileSystemPath)) { folderDestination = CommonHelper.MapPath(deployment.FileSystemPath); } else { folderDestination = deployment.FileSystemPath; } if (!System.IO.Directory.Exists(folderDestination)) { System.IO.Directory.CreateDirectory(folderDestination); } if (deployment.CreateZip) { var path = Path.Combine(folderDestination, deployment.Profile.FolderName + ".zip"); if (FileSystemHelper.Copy(context.ZipPath, path)) { context.Log.Information("Copied ZIP archive " + path); } } else { FileSystemHelper.CopyDirectory(new DirectoryInfo(context.FolderContent), new DirectoryInfo(folderDestination)); context.Log.Information("Copied export data files to " + folderDestination); } }
public virtual void Publish(ExportDeploymentContext context, ExportDeployment deployment) { var emailAccount = _emailAccountService.GetEmailAccountById(deployment.EmailAccountId); var smtpContext = new SmtpContext(emailAccount); var count = 0; foreach (var email in deployment.EmailAddresses.SplitSafe(",").Where(x => x.IsEmail())) { var queuedEmail = new QueuedEmail { From = emailAccount.ToEmailAddress(), SendManually = false, To = email, Subject = deployment.EmailSubject.NaIfEmpty(), Body = deployment.EmailSubject.NaIfEmpty(), CreatedOnUtc = DateTime.UtcNow, EmailAccountId = deployment.EmailAccountId }; foreach (var path in context.GetDeploymentFiles()) { var name = Path.GetFileName(path); queuedEmail.Attachments.Add(new QueuedEmailAttachment { StorageLocation = EmailAttachmentStorageLocation.Blob, MediaStorage = new MediaStorage { Data = File.ReadAllBytes(path) }, Name = name, MimeType = MimeTypes.MapNameToMimeType(name) }); } _queuedEmailService.InsertQueuedEmail(queuedEmail); ++count; } context.Log.Info("{0} email(s) created and queued for deployment.".FormatInvariant(count)); }
public virtual void Publish(ExportDeploymentContext context, ExportDeployment deployment) { var emailAccount = _emailAccountService.GetEmailAccountById(deployment.EmailAccountId); var smtpContext = new SmtpContext(emailAccount); var count = 0; foreach (var email in deployment.EmailAddresses.SplitSafe(",").Where(x => x.IsEmail())) { var queuedEmail = new QueuedEmail { From = emailAccount.Email, FromName = emailAccount.DisplayName, SendManually = true, To = email, Subject = deployment.EmailSubject.NaIfEmpty(), CreatedOnUtc = DateTime.UtcNow, EmailAccountId = deployment.EmailAccountId }; foreach (string path in context.DeploymentFiles) { string name = Path.GetFileName(path); queuedEmail.Attachments.Add(new QueuedEmailAttachment { StorageLocation = EmailAttachmentStorageLocation.Path, Path = path, Name = name, MimeType = MimeTypes.MapNameToMimeType(name) }); } _queuedEmailService.InsertQueuedEmail(queuedEmail); ++count; } context.Log.Information("{0} email(s) created and queued for deployment.".FormatInvariant(count)); }
public virtual void Publish(ExportDeploymentContext context, ExportDeployment deployment) { var bytesRead = 0; var succeededFiles = 0; var url = deployment.Url; var buffLength = 32768; byte[] buff = new byte[buffLength]; var deploymentFiles = context.GetDeploymentFiles().ToList(); var lastIndex = (deploymentFiles.Count - 1); if (!url.StartsWith("ftp://", StringComparison.InvariantCultureIgnoreCase)) { url = "ftp://" + url; } foreach (var path in deploymentFiles) { var fileUrl = url.EnsureEndsWith("/") + Path.GetFileName(path); var request = (FtpWebRequest)WebRequest.Create(fileUrl); request.Method = WebRequestMethods.Ftp.UploadFile; request.KeepAlive = (deploymentFiles.IndexOf(path) != lastIndex); request.UseBinary = true; request.Proxy = null; request.UsePassive = deployment.PassiveMode; request.EnableSsl = deployment.UseSsl; if (deployment.Username.HasValue()) { request.Credentials = new NetworkCredential(deployment.Username, deployment.Password); } request.ContentLength = (new FileInfo(path)).Length; var requestStream = request.GetRequestStream(); using (var stream = new FileStream(path, FileMode.Open)) { while ((bytesRead = stream.Read(buff, 0, buffLength)) != 0) { requestStream.Write(buff, 0, bytesRead); } } requestStream.Close(); using (var response = (FtpWebResponse)request.GetResponse()) { var statusCode = (int)response.StatusCode; if (statusCode >= 200 && statusCode <= 299) { ++succeededFiles; } else { context.Result.LastError = context.T("Admin.Common.FtpStatus", statusCode, response.StatusCode.ToString()); context.Log.Error("The FTP transfer failed. FTP status {0} ({1}). File {3}".FormatInvariant(statusCode, response.StatusCode.ToString(), path)); } } } context.Log.Information("{0} file(s) successfully uploaded via FTP.".FormatInvariant(succeededFiles)); }
public virtual void Publish(ExportDeploymentContext context, ExportDeployment deployment) { var succeededFiles = 0; var url = deployment.Url; if (!url.StartsWith("http://", StringComparison.InvariantCultureIgnoreCase) && !url.StartsWith("https://", StringComparison.InvariantCultureIgnoreCase)) { url = "http://" + url; } if (deployment.HttpTransmissionType == ExportHttpTransmissionType.MultipartFormDataPost) { var countFiles = 0; ICredentials credentials = null; if (deployment.Username.HasValue()) { credentials = new NetworkCredential(deployment.Username, deployment.Password); } using (var handler = new HttpClientHandler { Credentials = credentials }) using (var client = new HttpClient(handler)) using (var formData = new MultipartFormDataContent()) { foreach (var path in context.GetDeploymentFiles()) { byte[] fileData = File.ReadAllBytes(path); formData.Add(new ByteArrayContent(fileData), "file {0}".FormatInvariant(++countFiles), Path.GetFileName(path)); } var response = client.PostAsync(url, formData).Result; if (response.IsSuccessStatusCode) { succeededFiles = countFiles; } else if (response.Content != null) { context.Result.LastError = context.T("Admin.Common.HttpStatus", (int)response.StatusCode, response.StatusCode.ToString()); var content = response.Content.ReadAsStringAsync().Result; var msg = "Multipart form data upload failed. HTTP status {0} ({1}). Response: {2}".FormatInvariant( (int)response.StatusCode, response.StatusCode.ToString(), content.NaIfEmpty().Truncate(2000, "...")); context.Log.Error(msg); } } } else { using (var webClient = new WebClient()) { if (deployment.Username.HasValue()) { webClient.Credentials = new NetworkCredential(deployment.Username, deployment.Password); } foreach (var path in context.GetDeploymentFiles()) { webClient.UploadFile(url, path); ++succeededFiles; } } } context.Log.Information("{0} file(s) successfully uploaded via HTTP ({1}).".FormatInvariant(succeededFiles, deployment.HttpTransmissionType.ToString())); }
public async Task PublishAsync(ExportDeployment deployment, ExportDeploymentContext context, CancellationToken cancelToken) { var succeededFiles = 0; var url = deployment.Url; var files = await context.GetDeploymentFilesAsync(cancelToken); if (!url.StartsWith("http://", StringComparison.InvariantCultureIgnoreCase) && !url.StartsWith("https://", StringComparison.InvariantCultureIgnoreCase)) { url = "http://" + url; } var uri = new Uri(url); if (deployment.HttpTransmissionType == ExportHttpTransmissionType.MultipartFormDataPost) { var num = 0; var credentials = deployment.Username.HasValue() ? new NetworkCredential(deployment.Username, deployment.Password) : null; using var handler = new HttpClientHandler { Credentials = credentials }; using var client = new HttpClient(handler); using var formData = new MultipartFormDataContent(); foreach (var file in files) { var bytes = await file.ReadAllBytesAsync(); formData.Add(new ByteArrayContent(bytes), "file {0}".FormatInvariant(++num), file.Name); } var response = await client.PostAsync(uri, formData, cancelToken); if (response.IsSuccessStatusCode) { succeededFiles = num; } else if (response.Content != null) { context.Result.LastError = context.T("Admin.Common.HttpStatus", (int)response.StatusCode, response.StatusCode.ToString()); var content = await response.Content.ReadAsStringAsync(cancelToken); var msg = "Multipart form data upload failed. HTTP status {0} ({1}). Response: {2}".FormatInvariant( (int)response.StatusCode, response.StatusCode.ToString(), content.NaIfEmpty().Truncate(2000, "...")); context.Log.Error(msg); } } else { using var webClient = new WebClient(); if (deployment.Username.HasValue()) { webClient.Credentials = new NetworkCredential(deployment.Username, deployment.Password); } foreach (var file in files) { await webClient.UploadFileTaskAsync(uri, file.PhysicalPath); ++succeededFiles; } } context.Log.Info($"{succeededFiles} file(s) successfully uploaded via HTTP ({deployment.HttpTransmissionType})."); }
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); }