mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
114 lines
4.5 KiB
C#
114 lines
4.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using Orchard.Environment.Extensions;
|
|
using Orchard.Localization;
|
|
using Orchard.Logging;
|
|
using Orchard.UI.Notify;
|
|
|
|
namespace Orchard.Packaging.Services {
|
|
public interface IFolderUpdater : IDependency {
|
|
void Backup(DirectoryInfo existingFolder, DirectoryInfo backupfolder);
|
|
void Update(DirectoryInfo destinationFolder, DirectoryInfo newFolder);
|
|
}
|
|
|
|
[OrchardFeature("Gallery.Updates")]
|
|
public class FolderUpdater : IFolderUpdater {
|
|
private readonly INotifier _notifier;
|
|
|
|
public class FolderContent {
|
|
public DirectoryInfo Folder { get; set; }
|
|
public IEnumerable<string> Files { get; set; }
|
|
}
|
|
|
|
public FolderUpdater(INotifier notifier) {
|
|
_notifier = notifier;
|
|
T = NullLocalizer.Instance;
|
|
Logger = NullLogger.Instance;
|
|
}
|
|
|
|
public Localizer T { get; set; }
|
|
public ILogger Logger { get; set; }
|
|
|
|
public void Backup(DirectoryInfo existingFolder, DirectoryInfo backupfolder) {
|
|
CopyFolder(GetFolderContent(existingFolder), backupfolder);
|
|
}
|
|
|
|
public void Update(DirectoryInfo destinationFolder, DirectoryInfo newFolder) {
|
|
var destinationContent = GetFolderContent(destinationFolder);
|
|
var newContent = GetFolderContent(newFolder);
|
|
|
|
Update(destinationContent, newContent);
|
|
}
|
|
|
|
private void Update(FolderContent destinationContent, FolderContent newContent) {
|
|
// Copy files from new folder to existing folder
|
|
foreach (var file in newContent.Files) {
|
|
CopyFile(newContent.Folder, file, destinationContent.Folder);
|
|
}
|
|
|
|
// Delete files that are in the existing folder but not in the new folder
|
|
foreach (var file in destinationContent.Files.Except(newContent.Files, StringComparer.OrdinalIgnoreCase)) {
|
|
var fileToDelete = new FileInfo(Path.Combine(destinationContent.Folder.FullName, file));
|
|
try {
|
|
fileToDelete.Delete();
|
|
}
|
|
catch (Exception exception) {
|
|
for (Exception scan = exception; scan != null; scan = scan.InnerException) {
|
|
_notifier.Warning(T("Unable to delete file \"{0}\": {1}", fileToDelete.FullName, scan.Message));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void CopyFolder(FolderContent source, DirectoryInfo dest) {
|
|
foreach (var file in source.Files) {
|
|
CopyFile(source.Folder, file, dest);
|
|
}
|
|
}
|
|
|
|
private void CopyFile(DirectoryInfo sourceFolder, string fileName, DirectoryInfo destinationFolder) {
|
|
var sourceFile = new FileInfo(Path.Combine(sourceFolder.FullName, fileName));
|
|
var destFile = new FileInfo(Path.Combine(destinationFolder.FullName, fileName));
|
|
|
|
// If destination file exist, overwrite only if changed
|
|
if (destFile.Exists) {
|
|
if (sourceFile.Length == destFile.Length) {
|
|
var source = File.ReadAllBytes(sourceFile.FullName);
|
|
var dest = File.ReadAllBytes(destFile.FullName);
|
|
if (source.SequenceEqual(dest)) {
|
|
//_notifier.Information(T("Skipping file \"{0}\" because it is the same content as the source file", destFile.FullName));
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Create destination directory
|
|
if (!destFile.Directory.Exists) {
|
|
destFile.Directory.Create();
|
|
}
|
|
|
|
File.Copy(sourceFile.FullName, destFile.FullName, true);
|
|
}
|
|
|
|
private FolderContent GetFolderContent(DirectoryInfo folder) {
|
|
var files = new List<string>();
|
|
GetFolderContent(folder, "", files);
|
|
return new FolderContent { Folder = folder, Files = files };
|
|
}
|
|
|
|
private void GetFolderContent(DirectoryInfo folder, string prefix, List<string> files) {
|
|
if (!folder.Exists)
|
|
return;
|
|
|
|
foreach (var file in folder.GetFiles()) {
|
|
files.Add(Path.Combine(prefix, file.Name));
|
|
}
|
|
|
|
foreach (var child in folder.GetDirectories()) {
|
|
GetFolderContent(child, Path.Combine(prefix, child.Name), files);
|
|
}
|
|
}
|
|
}
|
|
} |