From d4154fa1fea533895a8daa641b984f86a5ae26ac Mon Sep 17 00:00:00 2001 From: Daniel Stolt Date: Wed, 21 Aug 2013 00:09:11 +0200 Subject: [PATCH] Cleaned up and fixed a couple of errors in Orchard.Web.csproj. Publishing now works for both Release and Debug configurations (previously worked only for Debug). Added missing module project Orchard.AzureBlobStogare to Orchard.Azure.sln and added a reference to it from Orchard.Azure.Web.csproj. Created separate solution folders Modules and Modules.Deprecated in Orchard.Azure.sln to be consistent with Orchard.sln. Cleaned up web.config transformation files. Upgraded Orchard.Azure, Orchard.Web and Orchard.Azure.Web to new storage client (version 2.0). Removed duplication between Orchard.Azure and Orchard.AzureBlobStorage (the latter is now just a thin wrapper over the former). Added proper transformations for log4net.config and HostComponents.config in both Orchard.Azure.Web and Orchard.Web (recreating what was previously done by custom MSBuild logic in the project files). --- src/Orchard.Azure/AzureFileSystem.cs | 422 ------- .../CloudBlobContainerExtensions.cs | 58 - .../AzureShellSettingsManager.cs | 86 +- .../FileSystems}/AzureFileSystem.cs | 782 ++++++------ .../CloudBlobContainerExtensions.cs | 108 +- .../Media/AzureBlobStorageProvider.cs | 9 +- .../Config/log4net.Debug.config | 4 + .../Config/log4net.Release.config | 4 + .../Orchard.Azure.Web/Config/log4net.config | 39 +- .../Orchard.Azure.Web/Global.asax.cs | 6 +- .../Orchard.Azure.Web.csproj | 1054 +++++++++-------- .../Orchard.Azure.Web/Web.Debug.config | 26 - .../Orchard.Azure.Web/Web.Release.config | 30 +- src/Orchard.Azure/Orchard.Azure.csproj | 17 +- src/Orchard.Azure/Orchard.Azure.sln | 17 +- .../Config/HostComponents.Debug.config | 4 + .../Config/HostComponents.Release.config | 11 + src/Orchard.Web/Config/HostComponents.config | 142 +-- src/Orchard.Web/Config/log4net.Debug.config | 4 + src/Orchard.Web/Config/log4net.Release.config | 21 + src/Orchard.Web/Config/log4net.config | 173 ++- .../Orchard.AzureBlobStorage/Module.txt | 22 +- .../Orchard.AzureBlobStorage.csproj | 278 ++--- .../Services/AzureBlobStorageProvider.cs | 57 - .../AzureBlobStorageProviderDependency.cs | 12 + src/Orchard.Web/Orchard.Web.csproj | 150 +-- src/Orchard.Web/Web.Debug.config | 4 + src/Orchard.Web/Web.Release.config | 8 + src/Orchard.Web/Web.config | 377 +++--- src/Orchard.sln | 12 + 30 files changed, 1719 insertions(+), 2218 deletions(-) delete mode 100644 src/Orchard.Azure/AzureFileSystem.cs delete mode 100644 src/Orchard.Azure/CloudBlobContainerExtensions.cs rename src/{Orchard.Web/Modules/Orchard.AzureBlobStorage/Services => Orchard.Azure/FileSystems}/AzureFileSystem.cs (97%) rename src/{Orchard.Web/Modules/Orchard.AzureBlobStorage/Services => Orchard.Azure/FileSystems}/CloudBlobContainerExtensions.cs (95%) create mode 100644 src/Orchard.Azure/Orchard.Azure.Web/Config/log4net.Debug.config create mode 100644 src/Orchard.Azure/Orchard.Azure.Web/Config/log4net.Release.config create mode 100644 src/Orchard.Web/Config/HostComponents.Debug.config create mode 100644 src/Orchard.Web/Config/HostComponents.Release.config create mode 100644 src/Orchard.Web/Config/log4net.Debug.config create mode 100644 src/Orchard.Web/Config/log4net.Release.config delete mode 100644 src/Orchard.Web/Modules/Orchard.AzureBlobStorage/Services/AzureBlobStorageProvider.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AzureBlobStorage/Services/AzureBlobStorageProviderDependency.cs create mode 100644 src/Orchard.Web/Web.Debug.config create mode 100644 src/Orchard.Web/Web.Release.config diff --git a/src/Orchard.Azure/AzureFileSystem.cs b/src/Orchard.Azure/AzureFileSystem.cs deleted file mode 100644 index 53a78bce8..000000000 --- a/src/Orchard.Azure/AzureFileSystem.cs +++ /dev/null @@ -1,422 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Xml.Linq; -using System.Xml.XPath; -using Microsoft.Win32; -using Microsoft.WindowsAzure; -using Microsoft.WindowsAzure.ServiceRuntime; -using Microsoft.WindowsAzure.StorageClient; -using Orchard.FileSystems.Media; - -namespace Orchard.Azure { - public class AzureFileSystem { - public const string FolderEntry = "$$$ORCHARD$$$.$$$"; - - public string ContainerName { get; protected set; } - - private readonly CloudStorageAccount _storageAccount; - protected readonly string _root; - protected readonly string _absoluteRoot; - public CloudBlobClient BlobClient { get; private set; } - public CloudBlobContainer Container { get; private set; } - - public AzureFileSystem(string containerName, string root, bool isPrivate) - : this(containerName, root, isPrivate, CloudStorageAccount.Parse(RoleEnvironment.GetConfigurationSettingValue("DataConnectionString"))) { - } - - public AzureFileSystem(string containerName, string root, bool isPrivate, CloudStorageAccount storageAccount) { - // Setup the connection to custom storage accountm, e.g. Development Storage - _storageAccount = storageAccount; - ContainerName = containerName; - _root = String.IsNullOrEmpty(root) ? "" : root + "/"; - _absoluteRoot = Combine(Combine(_storageAccount.BlobEndpoint.AbsoluteUri, containerName), root); - - BlobClient = _storageAccount.CreateCloudBlobClient(); - // Get and create the container if it does not exist - // The container is named with DNS naming restrictions (i.e. all lower case) - Container = BlobClient.GetContainerReference(ContainerName); - - Container.CreateIfNotExist(); - - Container.SetPermissions(isPrivate - ? new BlobContainerPermissions { PublicAccess = BlobContainerPublicAccessType.Off } - : new BlobContainerPermissions { PublicAccess = BlobContainerPublicAccessType.Container }); - - } - - private static string ConvertToRelativeUriPath(string path) { - var newPath = path.Replace(@"\", "/"); - - if (newPath.StartsWith("/") || newPath.StartsWith("http://") || newPath.StartsWith("https://")) - throw new ArgumentException("Path must be relative"); - - return newPath; - } - - public string Combine(string path1, string path2) { - if (path1 == null) { - throw new ArgumentNullException("path1"); - } - - if (path2 == null) { - throw new ArgumentNullException("path2"); - } - - if (String.IsNullOrEmpty(path2)) { - return path1; - } - - if (String.IsNullOrEmpty(path1)) { - return path2; - } - - if (path2.StartsWith("http://") || path2.StartsWith("https://")) { - return path2; - } - - var ch = path1[path1.Length - 1]; - - if (ch != '/') { - return (path1.TrimEnd('/') + '/' + path2.TrimStart('/')); - } - - return (path1 + path2); - } - - public IStorageFile GetFile(string path) { - - path = ConvertToRelativeUriPath(path); - - Container.EnsureBlobExists(String.Concat(_root, path)); - return new AzureBlobFileStorage(Container.GetBlockBlobReference(String.Concat(_root, path)), _absoluteRoot); - } - - public bool FileExists(string path) { - return Container.BlobExists(String.Concat(_root, path)); - } - - public bool FolderExists(string path) { - return Container.DirectoryExists(String.Concat(_root, path)); - } - - public IEnumerable ListFiles(string path) { - - path = path ?? String.Empty; - path = ConvertToRelativeUriPath(path); - - string prefix = Combine(Combine(Container.Name, _root), path); - - if (!prefix.EndsWith("/")) - prefix += "/"; - - return BlobClient - .ListBlobsWithPrefix(prefix) - .OfType() - .Where(blobItem => !blobItem.Uri.AbsoluteUri.EndsWith(FolderEntry)) - .Select(blobItem => new AzureBlobFileStorage(blobItem, _absoluteRoot)) - .ToArray(); - } - - public IEnumerable ListFolders(string path) { - - path = path ?? String.Empty; - path = ConvertToRelativeUriPath(path); - - // return root folders - if (String.Concat(_root, path) == String.Empty) { - return Container.ListBlobs() - .OfType() - .Select(d => new AzureBlobFolderStorage(d, _absoluteRoot)) - .ToList(); - } - - if (!Container.DirectoryExists(String.Concat(_root, path))) { - try { - CreateFolder(path); - } - catch (Exception ex) { - throw new ArgumentException(string.Format("The folder could not be created at path: {0}. {1}", - path, ex)); - } - } - - return Container.GetDirectoryReference(String.Concat(_root, path)) - .ListBlobs() - .OfType() - .Select(d => new AzureBlobFolderStorage(d, _absoluteRoot)) - .ToList(); - } - - public bool TryCreateFolder(string path) { - try { - if (!Container.DirectoryExists(String.Concat(_root, path))) { - CreateFolder(path); - return true; - } - - // return false to be consistent with FileSystemProvider's implementation - return false; - } - catch { - return false; - } - } - - public void CreateFolder(string path) { - path = ConvertToRelativeUriPath(path); - Container.EnsureDirectoryDoesNotExist(String.Concat(_root, path)); - - // Creating a virtually hidden file to make the directory an existing concept - CreateFile(Combine(path, FolderEntry)); - - int lastIndex; - while ((lastIndex = path.LastIndexOf('/')) > 0) { - path = path.Substring(0, lastIndex); - if (!Container.DirectoryExists(String.Concat(_root, path))) { - CreateFile(Combine(path, FolderEntry)); - } - } - } - - public void DeleteFolder(string path) { - path = ConvertToRelativeUriPath(path); - - Container.EnsureDirectoryExists(String.Concat(_root, path)); - foreach (var blob in Container.GetDirectoryReference(String.Concat(_root, path)).ListBlobs()) { - if (blob is CloudBlob) - ((CloudBlob)blob).Delete(); - - if (blob is CloudBlobDirectory) - DeleteFolder(blob.Uri.ToString().Substring(Container.Uri.ToString().Length + 1 + _root.Length)); - } - } - - public void RenameFolder(string path, string newPath) { - path = ConvertToRelativeUriPath(path); - newPath = ConvertToRelativeUriPath(newPath); - - if (!path.EndsWith("/")) - path += "/"; - - if (!newPath.EndsWith("/")) - newPath += "/"; - foreach (var blob in Container.GetDirectoryReference(_root + path).ListBlobs()) { - if (blob is CloudBlob) { - string filename = Path.GetFileName(blob.Uri.ToString()); - string source = String.Concat(path, filename); - string destination = String.Concat(newPath, filename); - RenameFile(source, destination); - } - - if (blob is CloudBlobDirectory) { - string foldername = blob.Uri.Segments.Last(); - string source = String.Concat(path, foldername); - string destination = String.Concat(newPath, foldername); - RenameFolder(source, destination); - } - } - } - - public void DeleteFile(string path) { - path = ConvertToRelativeUriPath(path); - - Container.EnsureBlobExists(Combine(_root, path)); - var blob = Container.GetBlockBlobReference(Combine(_root, path)); - blob.Delete(); - } - - public void RenameFile(string path, string newPath) { - path = ConvertToRelativeUriPath(path); - newPath = ConvertToRelativeUriPath(newPath); - - Container.EnsureBlobExists(String.Concat(_root, path)); - Container.EnsureBlobDoesNotExist(String.Concat(_root, newPath)); - - var blob = Container.GetBlockBlobReference(String.Concat(_root, path)); - var newBlob = Container.GetBlockBlobReference(String.Concat(_root, newPath)); - newBlob.CopyFromBlob(blob); - blob.Delete(); - } - - public IStorageFile CreateFile(string path) { - path = ConvertToRelativeUriPath(path); - - if (Container.BlobExists(String.Concat(_root, path))) { - throw new ArgumentException("File " + path + " already exists"); - } - - // create all folder entries in the hierarchy - int lastIndex; - var localPath = path; - while ((lastIndex = localPath.LastIndexOf('/')) > 0) { - localPath = localPath.Substring(0, lastIndex); - var folder = Container.GetBlockBlobReference(String.Concat(_root, Combine(localPath, FolderEntry))); - folder.OpenWrite().Dispose(); - } - - var blob = Container.GetBlockBlobReference(String.Concat(_root, path)); - var contentType = GetContentType(path); - if (!String.IsNullOrWhiteSpace(contentType)) { - blob.Properties.ContentType = contentType; - } - - blob.UploadByteArray(new byte[0]); - return new AzureBlobFileStorage(blob, _absoluteRoot); - } - - public string GetPublicUrl(string path) { - path = ConvertToRelativeUriPath(path); - - Container.EnsureBlobExists(String.Concat(_root, path)); - return Container.GetBlockBlobReference(String.Concat(_root, path)).Uri.ToString(); - } - - /// - /// Returns the mime-type of the specified file path, looking into IIS configuration and the Registry - /// - private string GetContentType(string path) { - string extension = Path.GetExtension(path); - if (String.IsNullOrWhiteSpace(extension)) { - return "application/unknown"; - } - - try { - try { - string applicationHost = System.Environment.ExpandEnvironmentVariables(@"%windir%\system32\inetsrv\config\applicationHost.config"); - string webConfig = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration(null).FilePath; - - // search for custom mime types in web.config and applicationhost.config - foreach (var configFile in new[] { webConfig, applicationHost }) { - if (File.Exists(configFile)) { - var xdoc = XDocument.Load(configFile); - var mimeMap = xdoc.XPathSelectElements("//staticContent/mimeMap[@fileExtension='" + extension + "']").FirstOrDefault(); - if (mimeMap != null) { - var mimeType = mimeMap.Attribute("mimeType"); - if (mimeType != null) { - return mimeType.Value; - } - } - } - } - } - catch { - // ignore issues with web.config to fall back to registry - } - - // search into the registry - RegistryKey regKey = Registry.ClassesRoot.OpenSubKey(extension.ToLower()); - if (regKey != null) { - var contentType = regKey.GetValue("Content Type"); - if (contentType != null) { - return contentType.ToString(); - } - } - } - catch { - // if an exception occured return application/unknown - return "application/unknown"; - } - - return "application/unknown"; - } - - private class AzureBlobFileStorage : IStorageFile { - private CloudBlockBlob _blob; - private readonly string _rootPath; - - public AzureBlobFileStorage(CloudBlockBlob blob, string rootPath) { - _blob = blob; - _rootPath = rootPath; - } - - public string GetPath() { - return _blob.Uri.ToString().Substring(_rootPath.Length).Trim('/'); - } - - public string GetName() { - return Path.GetFileName(GetPath()); - } - - public long GetSize() { - return _blob.Properties.Length; - } - - public DateTime GetLastUpdated() { - return _blob.Properties.LastModifiedUtc; - } - - public string GetFileType() { - return Path.GetExtension(GetPath()); - } - - public Stream OpenRead() { - return _blob.OpenRead(); - } - - public Stream OpenWrite() { - return _blob.OpenWrite(); - } - - public Stream CreateFile() { - // as opposed to the File System implementation, if nothing is done on the stream - // the file will be emptied, because Azure doesn't implement FileMode.Truncate - _blob.DeleteIfExists(); - _blob = _blob.Container.GetBlockBlobReference(_blob.Uri.ToString()); - _blob.OpenWrite().Dispose(); // force file creation - - return OpenWrite(); - } - } - - private class AzureBlobFolderStorage : IStorageFolder { - private readonly CloudBlobDirectory _blob; - private readonly string _rootPath; - - public AzureBlobFolderStorage(CloudBlobDirectory blob, string rootPath) { - _blob = blob; - _rootPath = rootPath; - } - - public string GetName() { - var path = GetPath(); - return path.Substring(path.LastIndexOf('/') + 1); - } - - public string GetPath() { - return _blob.Uri.ToString().Substring(_rootPath.Length).Trim('/'); - } - - public long GetSize() { - return GetDirectorySize(_blob); - } - - public DateTime GetLastUpdated() { - return DateTime.MinValue; - } - - public IStorageFolder GetParent() { - if (_blob.Parent != null) { - return new AzureBlobFolderStorage(_blob.Parent, _rootPath); - } - throw new ArgumentException("Directory " + _blob.Uri + " does not have a parent directory"); - } - - private static long GetDirectorySize(CloudBlobDirectory directoryBlob) { - long size = 0; - - foreach (var blobItem in directoryBlob.ListBlobs()) { - if (blobItem is CloudBlob) - size += ((CloudBlob)blobItem).Properties.Length; - - if (blobItem is CloudBlobDirectory) - size += GetDirectorySize((CloudBlobDirectory)blobItem); - } - - return size; - } - } - - } -} diff --git a/src/Orchard.Azure/CloudBlobContainerExtensions.cs b/src/Orchard.Azure/CloudBlobContainerExtensions.cs deleted file mode 100644 index 030d4040d..000000000 --- a/src/Orchard.Azure/CloudBlobContainerExtensions.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System; -using System.ComponentModel; -using System.Linq; -using Microsoft.WindowsAzure.StorageClient; - -namespace Orchard.Azure { - public static class CloudBlobContainerExtensions { - - public static bool BlobExists(this CloudBlobContainer container, string path) { - if ( String.IsNullOrEmpty(path) || path.Trim() == String.Empty ) - throw new ArgumentException("Path can't be empty"); - - try { - var blob = container.GetBlockBlobReference(path); - blob.FetchAttributes(); - return true; - } - catch ( StorageClientException e ) { - if ( e.ErrorCode == StorageErrorCode.ResourceNotFound ) { - return false; - } - - throw; - } - } - - public static void EnsureBlobExists(this CloudBlobContainer container, string path) { - if ( !BlobExists(container, path) ) { - throw new ArgumentException("File " + path + " does not exist"); - } - } - - public static void EnsureBlobDoesNotExist(this CloudBlobContainer container, string path) { - if ( BlobExists(container, path) ) { - throw new ArgumentException("File " + path + " already exists"); - } - } - - public static bool DirectoryExists(this CloudBlobContainer container, string path) { - if ( String.IsNullOrEmpty(path) || path.Trim() == String.Empty ) - throw new ArgumentException("Path can't be empty"); - - return container.GetDirectoryReference(path).ListBlobs().Count() > 0; - } - - public static void EnsureDirectoryExists(this CloudBlobContainer container, string path) { - if ( !DirectoryExists(container, path) ) { - throw new ArgumentException("Directory " + path + " does not exist"); - } - } - - public static void EnsureDirectoryDoesNotExist(this CloudBlobContainer container, string path) { - if ( DirectoryExists(container, path) ) { - throw new ArgumentException("Directory " + path + " already exists"); - } - } - } -} diff --git a/src/Orchard.Azure/Environment/Configuration/AzureShellSettingsManager.cs b/src/Orchard.Azure/Environment/Configuration/AzureShellSettingsManager.cs index 59559deb9..c5e4ea1c3 100644 --- a/src/Orchard.Azure/Environment/Configuration/AzureShellSettingsManager.cs +++ b/src/Orchard.Azure/Environment/Configuration/AzureShellSettingsManager.cs @@ -5,58 +5,62 @@ using System.Linq; using Microsoft.WindowsAzure; using Microsoft.WindowsAzure.ServiceRuntime; using Orchard.Environment.Configuration; +using Orchard.Azure.FileSystems; +using Microsoft.WindowsAzure.Storage; +using Orchard.FileSystems.Media; namespace Orchard.Azure.Environment.Configuration { - public class AzureShellSettingsManager : IShellSettingsManager { - public const string ContainerName = "sites"; // container names must be lower cased - public const string SettingsFilename = "Settings.txt"; - public const char Separator = ':'; - public const string EmptyValue = "null"; + public class AzureShellSettingsManager : IShellSettingsManager { + public const string ContainerName = "sites"; // container names must be lower cased + public const string SettingsFilename = "Settings.txt"; + public const char Separator = ':'; + public const string EmptyValue = "null"; - private readonly IShellSettingsManagerEventHandler _events; - private readonly AzureFileSystem _fileSystem; + private readonly IShellSettingsManagerEventHandler _events; + private readonly AzureFileSystem _fileSystem; - public AzureShellSettingsManager(IShellSettingsManagerEventHandler events) - : this(CloudStorageAccount.Parse(RoleEnvironment.GetConfigurationSettingValue("DataConnectionString")), events) {} + public AzureShellSettingsManager(IShellSettingsManagerEventHandler events, IMimeTypeProvider mimeTypeProvider) + : this(CloudStorageAccount.Parse(RoleEnvironment.GetConfigurationSettingValue("DataConnectionString")), events, mimeTypeProvider) {} - public AzureShellSettingsManager(CloudStorageAccount storageAccount, IShellSettingsManagerEventHandler events) { - _events = events; - _fileSystem = new AzureFileSystem(ContainerName, String.Empty, true, storageAccount); - } + public AzureShellSettingsManager(CloudStorageAccount storageAccount, IShellSettingsManagerEventHandler events, IMimeTypeProvider mimeTypeProvider) + { + _events = events; + _fileSystem = new AzureFileSystem(ContainerName, String.Empty, true, mimeTypeProvider); + } - IEnumerable IShellSettingsManager.LoadSettings() { - var settings = LoadSettings().ToArray(); - return settings; - } + IEnumerable IShellSettingsManager.LoadSettings() { + var settings = LoadSettings().ToArray(); + return settings; + } - void IShellSettingsManager.SaveSettings(ShellSettings settings) { - var content = ShellSettingsSerializer.ComposeSettings(settings); - var filePath = _fileSystem.Combine(settings.Name, SettingsFilename); + void IShellSettingsManager.SaveSettings(ShellSettings settings) { + var content = ShellSettingsSerializer.ComposeSettings(settings); + var filePath = _fileSystem.Combine(settings.Name, SettingsFilename); - var file = _fileSystem.FileExists(filePath) - ? _fileSystem.GetFile(filePath) - : _fileSystem.CreateFile(filePath); + var file = _fileSystem.FileExists(filePath) + ? _fileSystem.GetFile(filePath) + : _fileSystem.CreateFile(filePath); - using (var stream = file.OpenWrite()) { - using (var writer = new StreamWriter(stream)) { - writer.Write(content); - } - } + using (var stream = file.OpenWrite()) { + using (var writer = new StreamWriter(stream)) { + writer.Write(content); + } + } - _events.Saved(settings); - } + _events.Saved(settings); + } - IEnumerable LoadSettings() { - foreach (var folder in _fileSystem.ListFolders(null)) - foreach (var file in _fileSystem.ListFiles(folder.GetPath())) { - if (!String.Equals(file.GetName(), SettingsFilename)) - continue; + IEnumerable LoadSettings() { + foreach (var folder in _fileSystem.ListFolders(null)) + foreach (var file in _fileSystem.ListFiles(folder.GetPath())) { + if (!String.Equals(file.GetName(), SettingsFilename)) + continue; - using (var stream = file.OpenRead()) - using (var reader = new StreamReader(stream)) - yield return ShellSettingsSerializer.ParseSettings(reader.ReadToEnd()); - } - } - } + using (var stream = file.OpenRead()) + using (var reader = new StreamReader(stream)) + yield return ShellSettingsSerializer.ParseSettings(reader.ReadToEnd()); + } + } + } } diff --git a/src/Orchard.Web/Modules/Orchard.AzureBlobStorage/Services/AzureFileSystem.cs b/src/Orchard.Azure/FileSystems/AzureFileSystem.cs similarity index 97% rename from src/Orchard.Web/Modules/Orchard.AzureBlobStorage/Services/AzureFileSystem.cs rename to src/Orchard.Azure/FileSystems/AzureFileSystem.cs index 48542e4d1..22919cf5c 100644 --- a/src/Orchard.Web/Modules/Orchard.AzureBlobStorage/Services/AzureFileSystem.cs +++ b/src/Orchard.Azure/FileSystems/AzureFileSystem.cs @@ -1,391 +1,391 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using Microsoft.WindowsAzure; -using Microsoft.WindowsAzure.Storage; -using Microsoft.WindowsAzure.Storage.Blob; -using Orchard.FileSystems.Media; - -namespace Orchard.AzureBlobStorage.Services { - public class AzureFileSystem { - public const string FolderEntry = "$$$ORCHARD$$$.$$$"; - - private readonly bool _isPrivate; - private readonly IMimeTypeProvider _mimeTypeProvider; - - protected string _root; - protected string _absoluteRoot; - - private CloudStorageAccount _storageAccount; - private CloudBlobClient _blobClient; - private CloudBlobContainer _container; - - public string ContainerName { get; protected set; } - - public CloudBlobClient BlobClient { - get { - EnsureInitialized(); - return _blobClient; - } - } - - public CloudBlobContainer Container { - get { - EnsureInitialized(); - return _container; - } - } - - public AzureFileSystem(string containerName, string root, bool isPrivate, IMimeTypeProvider mimeTypeProvider) { - _isPrivate = isPrivate; - _mimeTypeProvider = mimeTypeProvider; - ContainerName = containerName; - _root = String.IsNullOrEmpty(root) ? "" : root + "/"; - } - - private void EnsureInitialized() { - if (_storageAccount != null) { - return; - } - - - _storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageConnectionString")); - _absoluteRoot = Combine(Combine(_storageAccount.BlobEndpoint.AbsoluteUri, ContainerName), _root); - - _blobClient = _storageAccount.CreateCloudBlobClient(); - // Get and create the container if it does not exist - // The container is named with DNS naming restrictions (i.e. all lower case) - _container = _blobClient.GetContainerReference(ContainerName); - - _container.CreateIfNotExists(); - - _container.SetPermissions(_isPrivate - ? new BlobContainerPermissions { PublicAccess = BlobContainerPublicAccessType.Off } - : new BlobContainerPermissions { PublicAccess = BlobContainerPublicAccessType.Container }); - - } - - private static string ConvertToRelativeUriPath(string path) { - var newPath = path.Replace(@"\", "/"); - - if (newPath.StartsWith("/") || newPath.StartsWith("http://") || newPath.StartsWith("https://")) - throw new ArgumentException("Path must be relative"); - - return newPath; - } - - public string Combine(string path1, string path2) { - if (path1 == null) { - throw new ArgumentNullException("path1"); - } - - if (path2 == null) { - throw new ArgumentNullException("path2"); - } - - if (String.IsNullOrEmpty(path2)) { - return path1; - } - - if (String.IsNullOrEmpty(path1)) { - return path2; - } - - if (path2.StartsWith("http://") || path2.StartsWith("https://")) { - return path2; - } - - var ch = path1[path1.Length - 1]; - - if (ch != '/') { - return (path1.TrimEnd('/') + '/' + path2.TrimStart('/')); - } - - return (path1 + path2); - } - - public IStorageFile GetFile(string path) { - - path = ConvertToRelativeUriPath(path); - - Container.EnsureBlobExists(String.Concat(_root, path)); - return new AzureBlobFileStorage(Container.GetBlockBlobReference(String.Concat(_root, path)), _absoluteRoot); - } - - public bool FileExists(string path) { - return Container.BlobExists(String.Concat(_root, path)); - } - - public bool FolderExists(string path) { - return Container.DirectoryExists(String.Concat(_root, path)); - } - - public IEnumerable ListFiles(string path) { - - path = path ?? String.Empty; - path = ConvertToRelativeUriPath(path); - - string prefix = Combine(Combine(Container.Name, _root), path); - - if (!prefix.EndsWith("/")) - prefix += "/"; - - return BlobClient.ListBlobs(prefix, true) - .OfType() - .Where(blobItem => !blobItem.Uri.AbsoluteUri.EndsWith(FolderEntry)) - .Select(blobItem => new AzureBlobFileStorage(blobItem, _absoluteRoot)) - .ToArray(); - } - - public IEnumerable ListFolders(string path) { - - path = path ?? String.Empty; - path = ConvertToRelativeUriPath(path); - - // return root folders - if (String.Concat(_root, path) == String.Empty) { - return Container.ListBlobs() - .OfType() - .Select(d => new AzureBlobFolderStorage(d, _absoluteRoot)) - .ToList(); - } - - if (!Container.DirectoryExists(String.Concat(_root, path))) { - try { - CreateFolder(path); - } - catch (Exception ex) { - throw new ArgumentException(string.Format("The folder could not be created at path: {0}. {1}", - path, ex)); - } - } - - return Container.GetDirectoryReference(String.Concat(_root, path)) - .ListBlobs() - .OfType() - .Select(d => new AzureBlobFolderStorage(d, _absoluteRoot)) - .ToList(); - } - - public bool TryCreateFolder(string path) { - try { - if (!Container.DirectoryExists(String.Concat(_root, path))) { - CreateFolder(path); - return true; - } - - // return false to be consistent with FileSystemProvider's implementation - return false; - } - catch { - return false; - } - } - - public void CreateFolder(string path) { - path = ConvertToRelativeUriPath(path); - Container.EnsureDirectoryDoesNotExist(String.Concat(_root, path)); - - // Creating a virtually hidden file to make the directory an existing concept - CreateFile(Combine(path, FolderEntry)); - - int lastIndex; - while ((lastIndex = path.LastIndexOf('/')) > 0) { - path = path.Substring(0, lastIndex); - if (!Container.DirectoryExists(String.Concat(_root, path))) { - CreateFile(Combine(path, FolderEntry)); - } - } - } - - public void DeleteFolder(string path) { - path = ConvertToRelativeUriPath(path); - - Container.EnsureDirectoryExists(String.Concat(_root, path)); - foreach (var blob in Container.GetDirectoryReference(String.Concat(_root, path)).ListBlobs()) { - if (blob is CloudBlockBlob) - ((CloudBlockBlob)blob).Delete(); - - if (blob is CloudBlobDirectory) - DeleteFolder(blob.Uri.ToString().Substring(Container.Uri.ToString().Length + 1 + _root.Length)); - } - } - - public void RenameFolder(string path, string newPath) { - path = ConvertToRelativeUriPath(path); - newPath = ConvertToRelativeUriPath(newPath); - - if (!path.EndsWith("/")) - path += "/"; - - if (!newPath.EndsWith("/")) - newPath += "/"; - foreach (var blob in Container.GetDirectoryReference(_root + path).ListBlobs()) { - if (blob is CloudBlockBlob) { - string filename = Path.GetFileName(blob.Uri.ToString()); - string source = String.Concat(path, filename); - string destination = String.Concat(newPath, filename); - RenameFile(source, destination); - } - - if (blob is CloudBlobDirectory) { - string foldername = blob.Uri.Segments.Last(); - string source = String.Concat(path, foldername); - string destination = String.Concat(newPath, foldername); - RenameFolder(source, destination); - } - } - } - - public void DeleteFile(string path) { - path = ConvertToRelativeUriPath(path); - - Container.EnsureBlobExists(Combine(_root, path)); - var blob = Container.GetBlockBlobReference(Combine(_root, path)); - blob.DeleteIfExists(); - } - - public void RenameFile(string path, string newPath) { - path = ConvertToRelativeUriPath(path); - newPath = ConvertToRelativeUriPath(newPath); - - Container.EnsureBlobExists(String.Concat(_root, path)); - Container.EnsureBlobDoesNotExist(String.Concat(_root, newPath)); - - var blob = Container.GetBlockBlobReference(String.Concat(_root, path)); - var newBlob = Container.GetBlockBlobReference(String.Concat(_root, newPath)); - newBlob.StartCopyFromBlob(blob); - } - - public IStorageFile CreateFile(string path) { - path = ConvertToRelativeUriPath(path); - - if (Container.BlobExists(String.Concat(_root, path))) { - throw new ArgumentException("File " + path + " already exists"); - } - - // create all folder entries in the hierarchy - int lastIndex; - var localPath = path; - while ((lastIndex = localPath.LastIndexOf('/')) > 0) { - localPath = localPath.Substring(0, lastIndex); - var folder = Container.GetBlockBlobReference(String.Concat(_root, Combine(localPath, FolderEntry))); - folder.OpenWrite().Dispose(); - } - - var blob = Container.GetBlockBlobReference(String.Concat(_root, path)); - var contentType = _mimeTypeProvider.GetMimeType(path); - if (!String.IsNullOrWhiteSpace(contentType)) { - blob.Properties.ContentType = contentType; - } - - blob.UploadFromStream(new MemoryStream(new byte[0])); - return new AzureBlobFileStorage(blob, _absoluteRoot); - } - - public string GetPublicUrl(string path) { - path = ConvertToRelativeUriPath(path); - - Container.EnsureBlobExists(String.Concat(_root, path)); - return Container.GetBlockBlobReference(String.Concat(_root, path)).Uri.ToString(); - } - - private class AzureBlobFileStorage : IStorageFile { - private CloudBlockBlob _blob; - private readonly string _rootPath; - - public AzureBlobFileStorage(CloudBlockBlob blob, string rootPath) { - _blob = blob; - _rootPath = rootPath; - } - - public string GetPath() { - return _blob.Uri.ToString().Substring(_rootPath.Length).Trim('/'); - } - - public string GetName() { - return Path.GetFileName(GetPath()); - } - - public long GetSize() { - return _blob.Properties.Length; - } - - public DateTime GetLastUpdated() { - return _blob.Properties.LastModified.GetValueOrDefault().DateTime; - } - - public string GetFileType() { - return Path.GetExtension(GetPath()); - } - - public Stream OpenRead() { - return _blob.OpenRead(); - } - - public Stream OpenWrite() { - return _blob.OpenWrite(); - } - - public Stream CreateFile() { - // as opposed to the File System implementation, if nothing is done on the stream - // the file will be emptied, because Azure doesn't implement FileMode.Truncate - _blob.DeleteIfExists(); - _blob = _blob.Container.GetBlockBlobReference(_blob.Uri.ToString()); - _blob.UploadFromStream(new MemoryStream(new byte[0])); - - return OpenWrite(); - } - } - - private class AzureBlobFolderStorage : IStorageFolder { - private readonly CloudBlobDirectory _blob; - private readonly string _rootPath; - - public AzureBlobFolderStorage(CloudBlobDirectory blob, string rootPath) { - _blob = blob; - _rootPath = rootPath; - } - - public string GetName() { - var path = GetPath(); - return path.Substring(path.LastIndexOf('/') + 1); - } - - public string GetPath() { - return _blob.Uri.ToString().Substring(_rootPath.Length).Trim('/'); - } - - public long GetSize() { - return GetDirectorySize(_blob); - } - - public DateTime GetLastUpdated() { - return DateTime.MinValue; - } - - public IStorageFolder GetParent() { - if (_blob.Parent != null) { - return new AzureBlobFolderStorage(_blob.Parent, _rootPath); - } - throw new ArgumentException("Directory " + _blob.Uri + " does not have a parent directory"); - } - - private static long GetDirectorySize(CloudBlobDirectory directoryBlob) { - long size = 0; - - foreach (var blobItem in directoryBlob.ListBlobs()) { - if (blobItem is CloudBlockBlob) - size += ((CloudBlockBlob)blobItem).Properties.Length; - - if (blobItem is CloudBlobDirectory) - size += GetDirectorySize((CloudBlobDirectory)blobItem); - } - - return size; - } - } - - } -} +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Microsoft.WindowsAzure; +using Microsoft.WindowsAzure.Storage; +using Microsoft.WindowsAzure.Storage.Blob; +using Orchard.FileSystems.Media; + +namespace Orchard.Azure.FileSystems { + public class AzureFileSystem { + public const string FolderEntry = "$$$ORCHARD$$$.$$$"; + + private readonly bool _isPrivate; + private readonly IMimeTypeProvider _mimeTypeProvider; + + protected string _root; + protected string _absoluteRoot; + + private CloudStorageAccount _storageAccount; + private CloudBlobClient _blobClient; + private CloudBlobContainer _container; + + public string ContainerName { get; protected set; } + + public CloudBlobClient BlobClient { + get { + EnsureInitialized(); + return _blobClient; + } + } + + public CloudBlobContainer Container { + get { + EnsureInitialized(); + return _container; + } + } + + public AzureFileSystem(string containerName, string root, bool isPrivate, IMimeTypeProvider mimeTypeProvider) { + _isPrivate = isPrivate; + _mimeTypeProvider = mimeTypeProvider; + ContainerName = containerName; + _root = String.IsNullOrEmpty(root) ? "" : root + "/"; + } + + private void EnsureInitialized() { + if (_storageAccount != null) { + return; + } + + + _storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageConnectionString")); + _absoluteRoot = Combine(Combine(_storageAccount.BlobEndpoint.AbsoluteUri, ContainerName), _root); + + _blobClient = _storageAccount.CreateCloudBlobClient(); + // Get and create the container if it does not exist + // The container is named with DNS naming restrictions (i.e. all lower case) + _container = _blobClient.GetContainerReference(ContainerName); + + _container.CreateIfNotExists(); + + _container.SetPermissions(_isPrivate + ? new BlobContainerPermissions { PublicAccess = BlobContainerPublicAccessType.Off } + : new BlobContainerPermissions { PublicAccess = BlobContainerPublicAccessType.Container }); + + } + + private static string ConvertToRelativeUriPath(string path) { + var newPath = path.Replace(@"\", "/"); + + if (newPath.StartsWith("/") || newPath.StartsWith("http://") || newPath.StartsWith("https://")) + throw new ArgumentException("Path must be relative"); + + return newPath; + } + + public string Combine(string path1, string path2) { + if (path1 == null) { + throw new ArgumentNullException("path1"); + } + + if (path2 == null) { + throw new ArgumentNullException("path2"); + } + + if (String.IsNullOrEmpty(path2)) { + return path1; + } + + if (String.IsNullOrEmpty(path1)) { + return path2; + } + + if (path2.StartsWith("http://") || path2.StartsWith("https://")) { + return path2; + } + + var ch = path1[path1.Length - 1]; + + if (ch != '/') { + return (path1.TrimEnd('/') + '/' + path2.TrimStart('/')); + } + + return (path1 + path2); + } + + public IStorageFile GetFile(string path) { + + path = ConvertToRelativeUriPath(path); + + Container.EnsureBlobExists(String.Concat(_root, path)); + return new AzureBlobFileStorage(Container.GetBlockBlobReference(String.Concat(_root, path)), _absoluteRoot); + } + + public bool FileExists(string path) { + return Container.BlobExists(String.Concat(_root, path)); + } + + public bool FolderExists(string path) { + return Container.DirectoryExists(String.Concat(_root, path)); + } + + public IEnumerable ListFiles(string path) { + + path = path ?? String.Empty; + path = ConvertToRelativeUriPath(path); + + string prefix = Combine(Combine(Container.Name, _root), path); + + if (!prefix.EndsWith("/")) + prefix += "/"; + + return BlobClient.ListBlobs(prefix, true) + .OfType() + .Where(blobItem => !blobItem.Uri.AbsoluteUri.EndsWith(FolderEntry)) + .Select(blobItem => new AzureBlobFileStorage(blobItem, _absoluteRoot)) + .ToArray(); + } + + public IEnumerable ListFolders(string path) { + + path = path ?? String.Empty; + path = ConvertToRelativeUriPath(path); + + // return root folders + if (String.Concat(_root, path) == String.Empty) { + return Container.ListBlobs() + .OfType() + .Select(d => new AzureBlobFolderStorage(d, _absoluteRoot)) + .ToList(); + } + + if (!Container.DirectoryExists(String.Concat(_root, path))) { + try { + CreateFolder(path); + } + catch (Exception ex) { + throw new ArgumentException(string.Format("The folder could not be created at path: {0}. {1}", + path, ex)); + } + } + + return Container.GetDirectoryReference(String.Concat(_root, path)) + .ListBlobs() + .OfType() + .Select(d => new AzureBlobFolderStorage(d, _absoluteRoot)) + .ToList(); + } + + public bool TryCreateFolder(string path) { + try { + if (!Container.DirectoryExists(String.Concat(_root, path))) { + CreateFolder(path); + return true; + } + + // return false to be consistent with FileSystemProvider's implementation + return false; + } + catch { + return false; + } + } + + public void CreateFolder(string path) { + path = ConvertToRelativeUriPath(path); + Container.EnsureDirectoryDoesNotExist(String.Concat(_root, path)); + + // Creating a virtually hidden file to make the directory an existing concept + CreateFile(Combine(path, FolderEntry)); + + int lastIndex; + while ((lastIndex = path.LastIndexOf('/')) > 0) { + path = path.Substring(0, lastIndex); + if (!Container.DirectoryExists(String.Concat(_root, path))) { + CreateFile(Combine(path, FolderEntry)); + } + } + } + + public void DeleteFolder(string path) { + path = ConvertToRelativeUriPath(path); + + Container.EnsureDirectoryExists(String.Concat(_root, path)); + foreach (var blob in Container.GetDirectoryReference(String.Concat(_root, path)).ListBlobs()) { + if (blob is CloudBlockBlob) + ((CloudBlockBlob)blob).Delete(); + + if (blob is CloudBlobDirectory) + DeleteFolder(blob.Uri.ToString().Substring(Container.Uri.ToString().Length + 1 + _root.Length)); + } + } + + public void RenameFolder(string path, string newPath) { + path = ConvertToRelativeUriPath(path); + newPath = ConvertToRelativeUriPath(newPath); + + if (!path.EndsWith("/")) + path += "/"; + + if (!newPath.EndsWith("/")) + newPath += "/"; + foreach (var blob in Container.GetDirectoryReference(_root + path).ListBlobs()) { + if (blob is CloudBlockBlob) { + string filename = Path.GetFileName(blob.Uri.ToString()); + string source = String.Concat(path, filename); + string destination = String.Concat(newPath, filename); + RenameFile(source, destination); + } + + if (blob is CloudBlobDirectory) { + string foldername = blob.Uri.Segments.Last(); + string source = String.Concat(path, foldername); + string destination = String.Concat(newPath, foldername); + RenameFolder(source, destination); + } + } + } + + public void DeleteFile(string path) { + path = ConvertToRelativeUriPath(path); + + Container.EnsureBlobExists(Combine(_root, path)); + var blob = Container.GetBlockBlobReference(Combine(_root, path)); + blob.DeleteIfExists(); + } + + public void RenameFile(string path, string newPath) { + path = ConvertToRelativeUriPath(path); + newPath = ConvertToRelativeUriPath(newPath); + + Container.EnsureBlobExists(String.Concat(_root, path)); + Container.EnsureBlobDoesNotExist(String.Concat(_root, newPath)); + + var blob = Container.GetBlockBlobReference(String.Concat(_root, path)); + var newBlob = Container.GetBlockBlobReference(String.Concat(_root, newPath)); + newBlob.StartCopyFromBlob(blob); + } + + public IStorageFile CreateFile(string path) { + path = ConvertToRelativeUriPath(path); + + if (Container.BlobExists(String.Concat(_root, path))) { + throw new ArgumentException("File " + path + " already exists"); + } + + // create all folder entries in the hierarchy + int lastIndex; + var localPath = path; + while ((lastIndex = localPath.LastIndexOf('/')) > 0) { + localPath = localPath.Substring(0, lastIndex); + var folder = Container.GetBlockBlobReference(String.Concat(_root, Combine(localPath, FolderEntry))); + folder.OpenWrite().Dispose(); + } + + var blob = Container.GetBlockBlobReference(String.Concat(_root, path)); + var contentType = _mimeTypeProvider.GetMimeType(path); + if (!String.IsNullOrWhiteSpace(contentType)) { + blob.Properties.ContentType = contentType; + } + + blob.UploadFromStream(new MemoryStream(new byte[0])); + return new AzureBlobFileStorage(blob, _absoluteRoot); + } + + public string GetPublicUrl(string path) { + path = ConvertToRelativeUriPath(path); + + Container.EnsureBlobExists(String.Concat(_root, path)); + return Container.GetBlockBlobReference(String.Concat(_root, path)).Uri.ToString(); + } + + private class AzureBlobFileStorage : IStorageFile { + private CloudBlockBlob _blob; + private readonly string _rootPath; + + public AzureBlobFileStorage(CloudBlockBlob blob, string rootPath) { + _blob = blob; + _rootPath = rootPath; + } + + public string GetPath() { + return _blob.Uri.ToString().Substring(_rootPath.Length).Trim('/'); + } + + public string GetName() { + return Path.GetFileName(GetPath()); + } + + public long GetSize() { + return _blob.Properties.Length; + } + + public DateTime GetLastUpdated() { + return _blob.Properties.LastModified.GetValueOrDefault().DateTime; + } + + public string GetFileType() { + return Path.GetExtension(GetPath()); + } + + public Stream OpenRead() { + return _blob.OpenRead(); + } + + public Stream OpenWrite() { + return _blob.OpenWrite(); + } + + public Stream CreateFile() { + // as opposed to the File System implementation, if nothing is done on the stream + // the file will be emptied, because Azure doesn't implement FileMode.Truncate + _blob.DeleteIfExists(); + _blob = _blob.Container.GetBlockBlobReference(_blob.Uri.ToString()); + _blob.UploadFromStream(new MemoryStream(new byte[0])); + + return OpenWrite(); + } + } + + private class AzureBlobFolderStorage : IStorageFolder { + private readonly CloudBlobDirectory _blob; + private readonly string _rootPath; + + public AzureBlobFolderStorage(CloudBlobDirectory blob, string rootPath) { + _blob = blob; + _rootPath = rootPath; + } + + public string GetName() { + var path = GetPath(); + return path.Substring(path.LastIndexOf('/') + 1); + } + + public string GetPath() { + return _blob.Uri.ToString().Substring(_rootPath.Length).Trim('/'); + } + + public long GetSize() { + return GetDirectorySize(_blob); + } + + public DateTime GetLastUpdated() { + return DateTime.MinValue; + } + + public IStorageFolder GetParent() { + if (_blob.Parent != null) { + return new AzureBlobFolderStorage(_blob.Parent, _rootPath); + } + throw new ArgumentException("Directory " + _blob.Uri + " does not have a parent directory"); + } + + private static long GetDirectorySize(CloudBlobDirectory directoryBlob) { + long size = 0; + + foreach (var blobItem in directoryBlob.ListBlobs()) { + if (blobItem is CloudBlockBlob) + size += ((CloudBlockBlob)blobItem).Properties.Length; + + if (blobItem is CloudBlobDirectory) + size += GetDirectorySize((CloudBlobDirectory)blobItem); + } + + return size; + } + } + + } +} diff --git a/src/Orchard.Web/Modules/Orchard.AzureBlobStorage/Services/CloudBlobContainerExtensions.cs b/src/Orchard.Azure/FileSystems/CloudBlobContainerExtensions.cs similarity index 95% rename from src/Orchard.Web/Modules/Orchard.AzureBlobStorage/Services/CloudBlobContainerExtensions.cs rename to src/Orchard.Azure/FileSystems/CloudBlobContainerExtensions.cs index c94e98c02..6adc192d7 100644 --- a/src/Orchard.Web/Modules/Orchard.AzureBlobStorage/Services/CloudBlobContainerExtensions.cs +++ b/src/Orchard.Azure/FileSystems/CloudBlobContainerExtensions.cs @@ -1,54 +1,54 @@ -using System; -using System.Linq; -using Microsoft.WindowsAzure.Storage; -using Microsoft.WindowsAzure.Storage.Blob; - -namespace Orchard.AzureBlobStorage.Services { - public static class CloudBlobContainerExtensions { - - public static bool BlobExists(this CloudBlobContainer container, string path) { - if (String.IsNullOrEmpty(path) || path.Trim() == String.Empty) - throw new ArgumentException("Path can't be empty"); - - try { - var blob = container.GetBlockBlobReference(path); - blob.FetchAttributes(); - return true; - } - catch (StorageException) { - return false; - } - } - - public static void EnsureBlobExists(this CloudBlobContainer container, string path) { - if (!BlobExists(container, path)) { - throw new ArgumentException("File " + path + " does not exist"); - } - } - - public static void EnsureBlobDoesNotExist(this CloudBlobContainer container, string path) { - if (BlobExists(container, path)) { - throw new ArgumentException("File " + path + " already exists"); - } - } - - public static bool DirectoryExists(this CloudBlobContainer container, string path) { - if (String.IsNullOrEmpty(path) || path.Trim() == String.Empty) - throw new ArgumentException("Path can't be empty"); - - return container.GetDirectoryReference(path).ListBlobs().Any(); - } - - public static void EnsureDirectoryExists(this CloudBlobContainer container, string path) { - if (!DirectoryExists(container, path)) { - throw new ArgumentException("Directory " + path + " does not exist"); - } - } - - public static void EnsureDirectoryDoesNotExist(this CloudBlobContainer container, string path) { - if (DirectoryExists(container, path)) { - throw new ArgumentException("Directory " + path + " already exists"); - } - } - } -} +using System; +using System.Linq; +using Microsoft.WindowsAzure.Storage; +using Microsoft.WindowsAzure.Storage.Blob; + +namespace Orchard.Azure.FileSystems { + public static class CloudBlobContainerExtensions { + + public static bool BlobExists(this CloudBlobContainer container, string path) { + if (String.IsNullOrEmpty(path) || path.Trim() == String.Empty) + throw new ArgumentException("Path can't be empty"); + + try { + var blob = container.GetBlockBlobReference(path); + blob.FetchAttributes(); + return true; + } + catch (StorageException) { + return false; + } + } + + public static void EnsureBlobExists(this CloudBlobContainer container, string path) { + if (!BlobExists(container, path)) { + throw new ArgumentException("File " + path + " does not exist"); + } + } + + public static void EnsureBlobDoesNotExist(this CloudBlobContainer container, string path) { + if (BlobExists(container, path)) { + throw new ArgumentException("File " + path + " already exists"); + } + } + + public static bool DirectoryExists(this CloudBlobContainer container, string path) { + if (String.IsNullOrEmpty(path) || path.Trim() == String.Empty) + throw new ArgumentException("Path can't be empty"); + + return container.GetDirectoryReference(path).ListBlobs().Any(); + } + + public static void EnsureDirectoryExists(this CloudBlobContainer container, string path) { + if (!DirectoryExists(container, path)) { + throw new ArgumentException("Directory " + path + " does not exist"); + } + } + + public static void EnsureDirectoryDoesNotExist(this CloudBlobContainer container, string path) { + if (DirectoryExists(container, path)) { + throw new ArgumentException("Directory " + path + " already exists"); + } + } + } +} diff --git a/src/Orchard.Azure/FileSystems/Media/AzureBlobStorageProvider.cs b/src/Orchard.Azure/FileSystems/Media/AzureBlobStorageProvider.cs index 95900ddde..be5de8973 100644 --- a/src/Orchard.Azure/FileSystems/Media/AzureBlobStorageProvider.cs +++ b/src/Orchard.Azure/FileSystems/Media/AzureBlobStorageProvider.cs @@ -1,16 +1,13 @@ using System.IO; -using Microsoft.WindowsAzure; using Orchard.Environment.Configuration; +using Orchard.Environment.Extensions; using Orchard.FileSystems.Media; namespace Orchard.Azure.FileSystems.Media { + public class AzureBlobStorageProvider : AzureFileSystem, IStorageProvider { - public AzureBlobStorageProvider(ShellSettings shellSettings) - : this(shellSettings, CloudStorageAccount.FromConfigurationSetting("DataConnectionString")) { - } - - public AzureBlobStorageProvider(ShellSettings shellSettings, CloudStorageAccount storageAccount) : base("media", shellSettings.Name, false, storageAccount) { } + public AzureBlobStorageProvider(ShellSettings shellSettings, IMimeTypeProvider mimeTypeProvider) : base("media", shellSettings.Name, false, mimeTypeProvider) { } public bool TrySaveStream(string path, Stream inputStream) { try { diff --git a/src/Orchard.Azure/Orchard.Azure.Web/Config/log4net.Debug.config b/src/Orchard.Azure/Orchard.Azure.Web/Config/log4net.Debug.config new file mode 100644 index 000000000..49bc2c5d2 --- /dev/null +++ b/src/Orchard.Azure/Orchard.Azure.Web/Config/log4net.Debug.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/Orchard.Azure/Orchard.Azure.Web/Config/log4net.Release.config b/src/Orchard.Azure/Orchard.Azure.Web/Config/log4net.Release.config new file mode 100644 index 000000000..49bc2c5d2 --- /dev/null +++ b/src/Orchard.Azure/Orchard.Azure.Web/Config/log4net.Release.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/Orchard.Azure/Orchard.Azure.Web/Config/log4net.config b/src/Orchard.Azure/Orchard.Azure.Web/Config/log4net.config index 74a066fa0..9ab248527 100644 --- a/src/Orchard.Azure/Orchard.Azure.Web/Config/log4net.config +++ b/src/Orchard.Azure/Orchard.Azure.Web/Config/log4net.config @@ -1,27 +1,20 @@  - - - - - + + + + + + - - - - - - - - - - - - - + + + + + + + + + + diff --git a/src/Orchard.Azure/Orchard.Azure.Web/Global.asax.cs b/src/Orchard.Azure/Orchard.Azure.Web/Global.asax.cs index bd2b37c44..673b93234 100644 --- a/src/Orchard.Azure/Orchard.Azure.Web/Global.asax.cs +++ b/src/Orchard.Azure/Orchard.Azure.Web/Global.asax.cs @@ -3,8 +3,8 @@ using System.Web; using System.Web.Mvc; using System.Web.Routing; using Autofac; -using Microsoft.WindowsAzure; using Microsoft.WindowsAzure.ServiceRuntime; +using Microsoft.WindowsAzure.Storage; using Orchard.Environment; namespace Orchard.Azure.Web { @@ -19,10 +19,6 @@ namespace Orchard.Azure.Web { } protected void Application_Start() { - CloudStorageAccount.SetConfigurationSettingPublisher( - (configName, configSetter) => - configSetter(RoleEnvironment.GetConfigurationSettingValue(configName)) - ); // For information on handling configuration changes // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357. diff --git a/src/Orchard.Azure/Orchard.Azure.Web/Orchard.Azure.Web.csproj b/src/Orchard.Azure/Orchard.Azure.Web/Orchard.Azure.Web.csproj index fb5d023cf..d2ad69d4d 100644 --- a/src/Orchard.Azure/Orchard.Azure.Web/Orchard.Azure.Web.csproj +++ b/src/Orchard.Azure/Orchard.Azure.Web/Orchard.Azure.Web.csproj @@ -1,524 +1,536 @@  - - - Debug - AnyCPU - 9.0.30729 - 2.0 - {0DF8F426-9F30-4918-8F64-A5B40BA12D10} - {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} - Library - Properties - Orchard.Azure.Web - Orchard.Azure.Web - v4.0 - false - - - 4.0 - - - - false - - - - - - - true - full - false - bin\ - DEBUG;TRACE - prompt - 4 - AllRules.ruleset - - - pdbonly - true - bin\ - TRACE - prompt - 4 - AllRules.ruleset - AnyCPU - - - - False - ..\..\..\lib\autofac\Autofac.dll - True - - - ..\..\..\lib\autofac\Autofac.Integration.Web.dll - True - - - False - ..\..\..\lib\aspnetmvc\Microsoft.Web.Infrastructure.dll - True - - - False - C:\Program Files\Microsoft SDKs\Windows Azure\.NET SDK\2012-10\ref\Microsoft.WindowsAzure.Configuration.dll - - - C:\Program Files\Microsoft SDKs\Windows Azure\.NET SDK\2012-10\ref\Microsoft.WindowsAzure.Diagnostics.dll - True - - - False - - - False - - - ..\..\..\lib\newtonsoft.json\Newtonsoft.Json.dll - True - - - ..\..\..\lib\nhibernate.sqlazure\NHibernate.SqlAzure.dll - - - False - - - False - - - 3.5 - False - - - False - - - - False - ..\..\..\lib\sqlce\System.Data.SqlServerCe.dll - True - - - False - - - False - - - False - - - False - - - ..\..\..\lib\aspnetmvc\System.Web.Helpers.dll - True - - - False - ..\..\..\lib\aspnetmvc\System.Web.Mvc.dll - True - - - False - - - False - - - ..\..\..\lib\aspnetmvc\System.Web.Razor.dll - True - - - False - - - ..\..\..\lib\aspnetmvc\System.Web.WebPages.dll - True - - - False - ..\..\..\lib\aspnetmvc\System.Web.WebPages.Deployment.dll - True - - - ..\..\..\lib\aspnetmvc\System.Web.WebPages.Razor.dll - True - - - False - - - False - - - False - - - False - - - False - - - ..\..\..\lib\aspnetmvc\WebMatrix.Data.dll - True - - - - - Global.asax - - - - - - - - - Designer - - - - - Web.config - - - Web.config - - - - - {9916839C-39FC-4CEB-A5AF-89CA7E87119F} - Orchard.Core - True - - - {D5D447D7-EF8E-43A6-B9A4-3B025DD9F45D} - Lucene - True - - - {3158C928-888C-4A84-8BC1-4A8257489538} - Markdown - - - {475B6C45-B27C-438B-8966-908B9D6D1077} - Orchard.Alias - - - {91bc2e7f-da04-421c-98ef-76d37cec130c} - Orchard.AntiSpam - - - {1C981BB3-26F7-494C-9005-CC27A5144233} - Orchard.ArchiveLater - True - - - {66FCCD76-2761-47E3-8D11-B45D0001DDAA} - Orchard.Autoroute - - - {63FBD4D9-E1DA-4A7B-AA6A-D6074FE50867} - Orchard.Blogs - True - - - {C0C45321-B51D-4D8D-9B7B-AA4C2E0B2962} - Orchard.CodeGeneration - True - - - {14C049FD-B35B-415A-A824-87F26B26E7FD} - Orchard.Comments - True - - - {e826f796-8ce3-4b5b-8423-5aa5f81d2fc3} - Orchard.ContentPermissions - - - {f301ef7d-f19c-4d83-aa94-cb64f29c037d} - Orchard.ContentPicker - - - {0E7646E8-FE8F-43C1-8799-D97860925EC4} - Orchard.ContentTypes - True - - - {2cf067ca-064b-43c6-8b88-5e3b99a65f1d} - Orchard.CustomForms - - - {4A4595EF-6C37-4F99-96ED-4AE0B9E438D3} - Orchard.DesignerTools - True - - - {05660F47-D649-48BD-9DED-DF4E01E7CFF9} - Orchard.Email - True - - - {3787DDE5-E5C8-4841-BDA7-DCB325388064} - Orchard.Fields - - - {642A49D7-8752-4177-80D6-BFBBCFAD3DE0} - Orchard.Forms - - - {1f0b6b85-8b0b-47ca-899d-f25b4f1b52c3} - Orchard.ImageEditor - - - {fe5c5947-d2d5-42c5-992a-13d672946135} - Orchard.ImportExport - - - {EA2B9121-EF54-40A6-A53E-6593C86EE696} - Orchard.Indexing - True - - - {8F116B06-1C0E-4E4C-9A0A-D2FAB851E768} - Orchard.jQuery - True - - - {137906EA-15FE-4AD8-A6A0-27528F0477D6} - Orchard.Lists - True - - - {FBC8B571-ED50-49D8-8D9D-64AB7454A0D6} - Orchard.Localization - True - - - {73a7688a-5bd3-4f7e-adfa-ce36c5a10e3b} - Orchard.MediaLibrary - - - {43D0EC0B-1955-4566-8D31-7B9102DA1703} - Orchard.MediaPicker - True - - - {08191fcd-7258-4f19-95fb-aec3de77b2eb} - Orchard.MediaProcessing - - - {D9A7B330-CD22-4DA1-A95A-8DE1982AD8EB} - Orchard.Media - True - - - {085948FF-0E9B-4A9A-B564-F8B8B4BDDDBC} - Orchard.Messaging - True - - - {EA4F1DA7-F2AB-4384-9AA4-9B756E2026B1} - Orchard.Migrations - True - - - {17F86780-9A1F-4AA1-86F1-875EEC2730C7} - Orchard.Modules - True - - - {72457126-E118-4171-A08F-9A709EE4B7FC} - Orchard.MultiTenancy - True - - - {6e444ff1-a47c-4cf6-bb3f-507c8ebd776d} - Orchard.OutputCache - - - {DFD137A2-DDB5-4D22-BE0D-FA9AD4C8B059} - Orchard.Packaging - True - - - {3420C92A-747F-4990-BA08-F2C9531E44AD} - Orchard.Pages - True - - - {5531E894-D259-45A3-AA61-26DBE720C1CE} - Orchard.Projections - - - {C889167C-E52C-4A65-A419-224B3D1B957D} - Orchard.PublishLater - True - - - {FC1D74E8-7A4D-48F4-83DE-95C6173780C4} - Orchard.Recipes - True - - - {D10AD48F-407D-4DB5-A328-173EC7CB010F} - Orchard.Roles - True - - - {966EC390-3C7F-4D98-92A6-F0F30D02E9B1} - Orchard.Rules - - - {5d13ef34-8b39-4ec5-847f-e12892acf841} - Orchard.Scripting.CSharp - - - {2AD6973D-C7BB-416E-89FE-EEE34664E05F} - Orchard.Scripting.Dlr - True - - - {2AD6973D-C7BB-416E-89FE-EEE34664E05F} - Orchard.Scripting - True - - - {4BE4EB01-AC56-4048-924E-2CA77F509ABA} - Orchard.Search - True - - - {8C7FCBC2-E6E1-405E-BFB5-D8D9E67A09C4} - Orchard.Setup - True - - - {5D0F00F0-26C9-4785-AD61-B85710C60EB0} - Orchard.Tags - True - - - {3F72A4E9-7B72-4260-B010-C16EC54F9BAF} - Orchard.TaskLease - - - {e649ea64-d213-461b-87f7-d67035801443} - Orchard.Taxonomies - - - {CDE24A24-01D3-403C-84B9-37722E18DFB7} - Orchard.Themes - True - - - {6F759635-13D7-4E94-BCC9-80445D63F117} - Orchard.Tokens - - - {79AED36E-ABD0-4747-93D3-8722B042454B} - Orchard.Users - True - - - {9cd5c81f-5828-4384-8474-2e2be71d5edd} - Orchard.Warmup - - - {194D3CCC-1153-474D-8176-FDE8D7D0D0BD} - Orchard.Widgets - True - - - {7059493c-8251-4764-9c1e-2368b8b485bc} - Orchard.Workflows - - - {3bd22132-d538-48c6-8854-f71333c798eb} - SysCache - - - {954CA994-D204-468B-9D69-51F6AD3E1C29} - TinyMce - True - - - {8a9fdb57-342d-49c2-bafc-d885aae5cc7c} - Upgrade - - - {2D1D92BB-4555-4CBE-8D0E-63563D6CE4C6} - Orchard.Framework - False - True - - - {33B1BC8D-E292-4972-A363-22056B207156} - Orchard - True - - - {2505AA84-65A6-43D0-9C27-4F44FD576284} - Orchard.Azure - True - - - - - - Designer - - - - - - - - - - - Designer - - - - 10.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - - - - - - - - - - - False - True - 60453 - / - - - False - False - - - False - - - - + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {0DF8F426-9F30-4918-8F64-A5B40BA12D10} + {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} + Library + Properties + Orchard.Azure.Web + Orchard.Azure.Web + v4.0 + false + false + + + + + + + true + full + false + bin\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + + + pdbonly + true + bin\ + TRACE + prompt + 4 + AllRules.ruleset + AnyCPU + + + + False + ..\..\..\lib\autofac\Autofac.dll + True + + + ..\..\..\lib\autofac\Autofac.Integration.Web.dll + True + + + False + ..\..\..\lib\aspnetmvc\Microsoft.Web.Infrastructure.dll + True + + + False + C:\Program Files\Microsoft SDKs\Windows Azure\.NET SDK\2012-10\ref\Microsoft.WindowsAzure.Configuration.dll + + + C:\Program Files\Microsoft SDKs\Windows Azure\.NET SDK\2012-10\ref\Microsoft.WindowsAzure.Diagnostics.dll + True + + + False + + + + ..\..\..\lib\newtonsoft.json\Newtonsoft.Json.dll + True + + + ..\..\..\lib\nhibernate.sqlazure\NHibernate.SqlAzure.dll + + + False + + + False + + + 3.5 + False + + + False + + + + False + ..\..\..\lib\sqlce\System.Data.SqlServerCe.dll + True + + + False + + + False + + + False + + + False + + + ..\..\..\lib\aspnetmvc\System.Web.Helpers.dll + True + + + False + ..\..\..\lib\aspnetmvc\System.Web.Mvc.dll + True + + + False + + + False + + + ..\..\..\lib\aspnetmvc\System.Web.Razor.dll + True + + + False + + + ..\..\..\lib\aspnetmvc\System.Web.WebPages.dll + True + + + False + ..\..\..\lib\aspnetmvc\System.Web.WebPages.Deployment.dll + True + + + ..\..\..\lib\aspnetmvc\System.Web.WebPages.Razor.dll + True + + + False + + + False + + + False + + + False + + + False + + + ..\..\..\lib\aspnetmvc\WebMatrix.Data.dll + True + + + + + Global.asax + + + + + + + + + Designer + + + + + Web.config + + + Web.config + + + + + {9916839C-39FC-4CEB-A5AF-89CA7E87119F} + Orchard.Core + True + + + {D5D447D7-EF8E-43A6-B9A4-3B025DD9F45D} + Lucene + True + + + {3158C928-888C-4A84-8BC1-4A8257489538} + Markdown + + + {475B6C45-B27C-438B-8966-908B9D6D1077} + Orchard.Alias + + + {91bc2e7f-da04-421c-98ef-76d37cec130c} + Orchard.AntiSpam + + + {1C981BB3-26F7-494C-9005-CC27A5144233} + Orchard.ArchiveLater + True + + + {66FCCD76-2761-47E3-8D11-B45D0001DDAA} + Orchard.Autoroute + + + {cbc7993c-57d8-4a6c-992c-19e849dfe71d} + Orchard.AzureBlobStorage + + + {63FBD4D9-E1DA-4A7B-AA6A-D6074FE50867} + Orchard.Blogs + True + + + {C0C45321-B51D-4D8D-9B7B-AA4C2E0B2962} + Orchard.CodeGeneration + True + + + {14C049FD-B35B-415A-A824-87F26B26E7FD} + Orchard.Comments + True + + + {e826f796-8ce3-4b5b-8423-5aa5f81d2fc3} + Orchard.ContentPermissions + + + {f301ef7d-f19c-4d83-aa94-cb64f29c037d} + Orchard.ContentPicker + + + {0E7646E8-FE8F-43C1-8799-D97860925EC4} + Orchard.ContentTypes + True + + + {2cf067ca-064b-43c6-8b88-5e3b99a65f1d} + Orchard.CustomForms + + + {4A4595EF-6C37-4F99-96ED-4AE0B9E438D3} + Orchard.DesignerTools + True + + + {05660F47-D649-48BD-9DED-DF4E01E7CFF9} + Orchard.Email + True + + + {3787DDE5-E5C8-4841-BDA7-DCB325388064} + Orchard.Fields + + + {642A49D7-8752-4177-80D6-BFBBCFAD3DE0} + Orchard.Forms + + + {1f0b6b85-8b0b-47ca-899d-f25b4f1b52c3} + Orchard.ImageEditor + + + {fe5c5947-d2d5-42c5-992a-13d672946135} + Orchard.ImportExport + + + {EA2B9121-EF54-40A6-A53E-6593C86EE696} + Orchard.Indexing + True + + + {8F116B06-1C0E-4E4C-9A0A-D2FAB851E768} + Orchard.jQuery + True + + + {137906EA-15FE-4AD8-A6A0-27528F0477D6} + Orchard.Lists + True + + + {FBC8B571-ED50-49D8-8D9D-64AB7454A0D6} + Orchard.Localization + True + + + {73a7688a-5bd3-4f7e-adfa-ce36c5a10e3b} + Orchard.MediaLibrary + + + {43D0EC0B-1955-4566-8D31-7B9102DA1703} + Orchard.MediaPicker + True + + + {08191fcd-7258-4f19-95fb-aec3de77b2eb} + Orchard.MediaProcessing + + + {D9A7B330-CD22-4DA1-A95A-8DE1982AD8EB} + Orchard.Media + True + + + {085948FF-0E9B-4A9A-B564-F8B8B4BDDDBC} + Orchard.Messaging + True + + + {EA4F1DA7-F2AB-4384-9AA4-9B756E2026B1} + Orchard.Migrations + True + + + {17F86780-9A1F-4AA1-86F1-875EEC2730C7} + Orchard.Modules + True + + + {72457126-E118-4171-A08F-9A709EE4B7FC} + Orchard.MultiTenancy + True + + + {6e444ff1-a47c-4cf6-bb3f-507c8ebd776d} + Orchard.OutputCache + + + {DFD137A2-DDB5-4D22-BE0D-FA9AD4C8B059} + Orchard.Packaging + True + + + {3420C92A-747F-4990-BA08-F2C9531E44AD} + Orchard.Pages + True + + + {5531E894-D259-45A3-AA61-26DBE720C1CE} + Orchard.Projections + + + {C889167C-E52C-4A65-A419-224B3D1B957D} + Orchard.PublishLater + True + + + {FC1D74E8-7A4D-48F4-83DE-95C6173780C4} + Orchard.Recipes + True + + + {D10AD48F-407D-4DB5-A328-173EC7CB010F} + Orchard.Roles + True + + + {966EC390-3C7F-4D98-92A6-F0F30D02E9B1} + Orchard.Rules + + + {5d13ef34-8b39-4ec5-847f-e12892acf841} + Orchard.Scripting.CSharp + + + {2AD6973D-C7BB-416E-89FE-EEE34664E05F} + Orchard.Scripting.Dlr + True + + + {2AD6973D-C7BB-416E-89FE-EEE34664E05F} + Orchard.Scripting.Dlr + True + + + {4BE4EB01-AC56-4048-924E-2CA77F509ABA} + Orchard.Search + True + + + {8C7FCBC2-E6E1-405E-BFB5-D8D9E67A09C4} + Orchard.Setup + True + + + {5D0F00F0-26C9-4785-AD61-B85710C60EB0} + Orchard.Tags + True + + + {3F72A4E9-7B72-4260-B010-C16EC54F9BAF} + Orchard.TaskLease + + + {e649ea64-d213-461b-87f7-d67035801443} + Orchard.Taxonomies + + + {CDE24A24-01D3-403C-84B9-37722E18DFB7} + Orchard.Themes + True + + + {6F759635-13D7-4E94-BCC9-80445D63F117} + Orchard.Tokens + + + {79AED36E-ABD0-4747-93D3-8722B042454B} + Orchard.Users + True + + + {9cd5c81f-5828-4384-8474-2e2be71d5edd} + Orchard.Warmup + + + {194D3CCC-1153-474D-8176-FDE8D7D0D0BD} + Orchard.Widgets + True + + + {7059493c-8251-4764-9c1e-2368b8b485bc} + Orchard.Workflows + + + {3bd22132-d538-48c6-8854-f71333c798eb} + SysCache + + + {954CA994-D204-468B-9D69-51F6AD3E1C29} + TinyMce + True + + + {8a9fdb57-342d-49c2-bafc-d885aae5cc7c} + Upgrade + + + {2D1D92BB-4555-4CBE-8D0E-63563D6CE4C6} + Orchard.Framework + False + True + + + {33B1BC8D-E292-4972-A363-22056B207156} + Orchard + True + + + {2505AA84-65A6-43D0-9C27-4F44FD576284} + Orchard.Azure + True + + + + + + Designer + + + + + + + + Designer + + + + 10.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + + + + Config\log4net.config + False + $(TransformWebConfigIntermediateLocation)\original + Config\log4net.$(Configuration).config + $(TransformWebConfigIntermediateLocation)\original + $(TransformWebConfigIntermediateLocation)\original\%(DestinationRelativePath) + $(TransformWebConfigIntermediateLocation)\transformed\%(DestinationRelativePath) + $(_PackageTempDir)\%(DestinationRelativePath) + Designer + + + log4net.config + + + log4net.config + + + + + + + + + + False + True + 60453 + / + + + False + False + + + False + + + + + \ No newline at end of file diff --git a/src/Orchard.Azure/Orchard.Azure.Web/Web.Debug.config b/src/Orchard.Azure/Orchard.Azure.Web/Web.Debug.config index 24f336cd6..1c6ccb00c 100644 --- a/src/Orchard.Azure/Orchard.Azure.Web/Web.Debug.config +++ b/src/Orchard.Azure/Orchard.Azure.Web/Web.Debug.config @@ -1,30 +1,4 @@ - - - - - - \ No newline at end of file diff --git a/src/Orchard.Azure/Orchard.Azure.Web/Web.Release.config b/src/Orchard.Azure/Orchard.Azure.Web/Web.Release.config index a6579812d..4e3958124 100644 --- a/src/Orchard.Azure/Orchard.Azure.Web/Web.Release.config +++ b/src/Orchard.Azure/Orchard.Azure.Web/Web.Release.config @@ -1,31 +1,7 @@ - - - - - - - + + + \ No newline at end of file diff --git a/src/Orchard.Azure/Orchard.Azure.csproj b/src/Orchard.Azure/Orchard.Azure.csproj index 22cb727ed..bfb25270b 100644 --- a/src/Orchard.Azure/Orchard.Azure.csproj +++ b/src/Orchard.Azure/Orchard.Azure.csproj @@ -56,6 +56,7 @@ ..\..\lib\log4net\log4net.dll + False C:\Program Files\Microsoft SDKs\Windows Azure\.NET SDK\2012-10\ref\Microsoft.WindowsAzure.Diagnostics.dll @@ -64,9 +65,7 @@ False True - - False - + @@ -83,12 +82,15 @@ - + - + + + + - + @@ -114,9 +116,6 @@ true - - - + + \ No newline at end of file diff --git a/src/Orchard.Web/Config/HostComponents.Release.config b/src/Orchard.Web/Config/HostComponents.Release.config new file mode 100644 index 000000000..c7c3f13e7 --- /dev/null +++ b/src/Orchard.Web/Config/HostComponents.Release.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/Orchard.Web/Config/HostComponents.config b/src/Orchard.Web/Config/HostComponents.config index 6faa3b82c..9a025ed4f 100644 --- a/src/Orchard.Web/Config/HostComponents.config +++ b/src/Orchard.Web/Config/HostComponents.config @@ -1,85 +1,85 @@  - - - - - - - - + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - - - + + + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - + + + + + + + + diff --git a/src/Orchard.Web/Config/log4net.Debug.config b/src/Orchard.Web/Config/log4net.Debug.config new file mode 100644 index 000000000..49bc2c5d2 --- /dev/null +++ b/src/Orchard.Web/Config/log4net.Debug.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/Orchard.Web/Config/log4net.Release.config b/src/Orchard.Web/Config/log4net.Release.config new file mode 100644 index 000000000..689a1c5dd --- /dev/null +++ b/src/Orchard.Web/Config/log4net.Release.config @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Orchard.Web/Config/log4net.config b/src/Orchard.Web/Config/log4net.config index ce0769c29..31cdde087 100644 --- a/src/Orchard.Web/Config/log4net.config +++ b/src/Orchard.Web/Config/log4net.config @@ -1,110 +1,93 @@  - - - - - - - - + - - - - - - + + + + + + - - + + - - - - - - - - - + + + + + - - - - + + + + - - - - + + + + - - - - - - - - - - - + + + + - - - - - + + + + - - + + + + - - - - - - - - - - + + + + + - - - - - + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/src/Orchard.Web/Modules/Orchard.AzureBlobStorage/Module.txt b/src/Orchard.Web/Modules/Orchard.AzureBlobStorage/Module.txt index c089a6eed..ce5feb438 100644 --- a/src/Orchard.Web/Modules/Orchard.AzureBlobStorage/Module.txt +++ b/src/Orchard.Web/Modules/Orchard.AzureBlobStorage/Module.txt @@ -1,12 +1,12 @@ -Name: Orchard.AzureBlobStorage -AntiForgery: enabled -Author: The Orchard Team -Website: http://orchardproject.net -Version: 1.0 -OrchardVersion: 1.7 -Description: Description for the module -Features: - Orchard.AzureBlobStorage: - Description: Stores the files on Azure Blob Storage - Name: Azure Blob Storage +Name: Orchard.AzureBlobStorage +AntiForgery: enabled +Author: The Orchard Team +Website: http://orchardproject.net +Version: 1.0 +OrchardVersion: 1.7 +Description: Description for the module +Features: + Orchard.AzureBlobStorage: + Description: Configures Windows Azure Blob Storage to be used as the underlying storage for Orchard + Name: Azure Blob Storage Category: Hosting \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AzureBlobStorage/Orchard.AzureBlobStorage.csproj b/src/Orchard.Web/Modules/Orchard.AzureBlobStorage/Orchard.AzureBlobStorage.csproj index 8dcceaf32..4b0e18004 100644 --- a/src/Orchard.Web/Modules/Orchard.AzureBlobStorage/Orchard.AzureBlobStorage.csproj +++ b/src/Orchard.Web/Modules/Orchard.AzureBlobStorage/Orchard.AzureBlobStorage.csproj @@ -1,139 +1,141 @@ - - - - - Debug - AnyCPU - 9.0.30729 - 2.0 - {CBC7993C-57D8-4A6C-992C-19E849DFE71D} - {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} - Library - Properties - Orchard.AzureBlobStorage - Orchard.AzureBlobStorage - v4.0 - false - - - 4.0 - - - false - - - - - - - true - full - false - bin\ - DEBUG;TRACE - prompt - 4 - AllRules.ruleset - - - pdbonly - true - bin\ - TRACE - prompt - 4 - AllRules.ruleset - - - - - False - ..\..\..\..\lib\windowsazure\Microsoft.WindowsAzure.Configuration.dll - - - False - ..\..\..\..\lib\windowsazure\Microsoft.WindowsAzure.Storage.dll - - - - - 3.5 - - - - False - ..\..\..\..\lib\aspnetmvc\System.Web.Mvc.dll - - - - - - - - - - - - - - - - {2D1D92BB-4555-4CBE-8D0E-63563D6CE4C6} - Orchard.Framework - - - {9916839C-39FC-4CEB-A5AF-89CA7E87119F} - Orchard.Core - - - - - - - - - - 10.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - - - - - $(ProjectDir)\..\Manifests - - - - - - - - - - - - False - True - 45979 - / - - - False - True - http://orchard.codeplex.com - False - - - - + + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {CBC7993C-57D8-4A6C-992C-19E849DFE71D} + {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} + Library + Properties + Orchard.AzureBlobStorage + Orchard.AzureBlobStorage + v4.0 + false + + + 4.0 + + + false + + + + + + + true + full + false + bin\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + + + pdbonly + true + bin\ + TRACE + prompt + 4 + AllRules.ruleset + + + + + False + ..\..\..\..\lib\windowsazure\Microsoft.WindowsAzure.Configuration.dll + + + False + ..\..\..\..\lib\windowsazure\Microsoft.WindowsAzure.Storage.dll + + + + + 3.5 + + + + False + ..\..\..\..\lib\aspnetmvc\System.Web.Mvc.dll + + + + + + + + + + + + + + + + {2505aa84-65a6-43d0-9c27-4f44fd576284} + Orchard.Azure + + + {2D1D92BB-4555-4CBE-8D0E-63563D6CE4C6} + Orchard.Framework + + + {9916839C-39FC-4CEB-A5AF-89CA7E87119F} + Orchard.Core + + + + + + + + 10.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + + + + + $(ProjectDir)\..\Manifests + + + + + + + + + + + + False + True + 45979 + / + + + False + True + http://orchard.codeplex.com + False + + + + \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AzureBlobStorage/Services/AzureBlobStorageProvider.cs b/src/Orchard.Web/Modules/Orchard.AzureBlobStorage/Services/AzureBlobStorageProvider.cs deleted file mode 100644 index 35acbc7e3..000000000 --- a/src/Orchard.Web/Modules/Orchard.AzureBlobStorage/Services/AzureBlobStorageProvider.cs +++ /dev/null @@ -1,57 +0,0 @@ -using System.IO; -using Orchard.Environment.Configuration; -using Orchard.Environment.Extensions; -using Orchard.FileSystems.Media; - -namespace Orchard.AzureBlobStorage.Services { - [OrchardSuppressDependency("Orchard.FileSystems.Media.FileSystemStorageProvider")] - public class AzureBlobStorageProvider : AzureFileSystem, IStorageProvider { - - public AzureBlobStorageProvider(ShellSettings shellSettings, IMimeTypeProvider mimeTypeProvider) : base("media", shellSettings.Name, false, mimeTypeProvider) { } - - public bool TrySaveStream(string path, Stream inputStream) { - try { - SaveStream(path, inputStream); - } - catch { - return false; - } - - return true; - } - - public void SaveStream(string path, Stream inputStream) { - // Create the file. - // The CreateFile method will map the still relative path - var file = CreateFile(path); - - using(var outputStream = file.OpenWrite()) { - var buffer = new byte[8192]; - for (;;) { - var length = inputStream.Read(buffer, 0, buffer.Length); - if (length <= 0) - break; - outputStream.Write(buffer, 0, length); - } - } - } - - /// - /// Retrieves the local path for a given url within the storage provider. - /// - /// The public url of the media. - /// The local path. - public string GetStoragePath(string url) { - if (url.StartsWith(_absoluteRoot)) { - return url.Substring(Combine(_absoluteRoot, "/").Length); - } - - return null; - } - - public string GetRelativePath(string path) { - return GetPublicUrl(path); - } - - } -} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AzureBlobStorage/Services/AzureBlobStorageProviderDependency.cs b/src/Orchard.Web/Modules/Orchard.AzureBlobStorage/Services/AzureBlobStorageProviderDependency.cs new file mode 100644 index 000000000..d8e5d5fd2 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AzureBlobStorage/Services/AzureBlobStorageProviderDependency.cs @@ -0,0 +1,12 @@ +using System.IO; +using Orchard.Environment.Configuration; +using Orchard.Environment.Extensions; +using Orchard.FileSystems.Media; +using Orchard.Azure.FileSystems.Media; + +namespace Orchard.AzureBlobStorage.Services { + [OrchardSuppressDependency("Orchard.FileSystems.Media.FileSystemStorageProvider")] + public class AzureBlobStorageProviderDependency : AzureBlobStorageProvider { + public AzureBlobStorageProviderDependency(ShellSettings shellSettings, IMimeTypeProvider mimeTypeProvider) : base(shellSettings, mimeTypeProvider) { } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Orchard.Web.csproj b/src/Orchard.Web/Orchard.Web.csproj index 21fc895ba..ff9df31fd 100644 --- a/src/Orchard.Web/Orchard.Web.csproj +++ b/src/Orchard.Web/Orchard.Web.csproj @@ -14,12 +14,6 @@ Orchard.Web v4.0 false - - - 4.0 - - - true @@ -46,6 +40,8 @@ prompt 4 AllRules.ruleset + AllFilesInProjectFolder + false @@ -128,12 +124,6 @@ Global.asax - - Designer - - - Designer - @@ -165,7 +155,13 @@ - + + + Web.config + + + Web.config + 10.0 @@ -174,15 +170,71 @@ + + + Config\log4net.config + False + $(TransformWebConfigIntermediateLocation)\original + Config\log4net.$(Configuration).config + $(TransformWebConfigIntermediateLocation)\original + $(TransformWebConfigIntermediateLocation)\original\%(DestinationRelativePath) + $(TransformWebConfigIntermediateLocation)\transformed\%(DestinationRelativePath) + $(_PackageTempDir)\%(DestinationRelativePath) + Designer + + + log4net.config + + + log4net.config + + + + + Config\HostComponents.config + False + $(TransformWebConfigIntermediateLocation)\original + Config\HostComponents.$(Configuration).config + $(TransformWebConfigIntermediateLocation)\original + $(TransformWebConfigIntermediateLocation)\original\%(DestinationRelativePath) + $(TransformWebConfigIntermediateLocation)\transformed\%(DestinationRelativePath) + $(_PackageTempDir)\%(DestinationRelativePath) + Designer + + + HostComponents.config + + + HostComponents.config + + + + + + + + + + True + False + 30321 + /OrchardLocal + http://localhost:30321/OrchardLocal + False + False + + + False + + + + + Other similar extension points exist, see Microsoft.Common.targets. + + --> - - CustomCollectFiles; - $(CopyAllFilesToSingleFolderForMsdeployDependsOn); - + CustomCollectFiles;$(CopyAllFilesToSingleFolderForMsdeployDependsOn); @@ -209,63 +261,19 @@ - + - - - - - $(ProjectDir)obj\Release\Package\PackageTmp - - - - - - - - - - - - - - - - - - - + $(ProjectDir)\..\Manifests + + --> + + + --> - - - - - - - - True - False - 30321 - /OrchardLocal - http://localhost:30321/OrchardLocal - False - False - - - False - - - - \ No newline at end of file diff --git a/src/Orchard.Web/Web.Debug.config b/src/Orchard.Web/Web.Debug.config new file mode 100644 index 000000000..1c6ccb00c --- /dev/null +++ b/src/Orchard.Web/Web.Debug.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/Orchard.Web/Web.Release.config b/src/Orchard.Web/Web.Release.config new file mode 100644 index 000000000..3503bc5dc --- /dev/null +++ b/src/Orchard.Web/Web.Release.config @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/src/Orchard.Web/Web.config b/src/Orchard.Web/Web.config index fcd259ab8..2c4e8e8c2 100644 --- a/src/Orchard.Web/Web.config +++ b/src/Orchard.Web/Web.config @@ -1,195 +1,196 @@ - - - - -
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Orchard.sln b/src/Orchard.sln index b5a85db51..304ec0d7d 100644 --- a/src/Orchard.sln +++ b/src/Orchard.sln @@ -162,6 +162,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Modules.Deprecated", "Modul EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.AzureBlobStorage", "Orchard.Web\Modules\Orchard.AzureBlobStorage\Orchard.AzureBlobStorage.csproj", "{CBC7993C-57D8-4A6C-992C-19E849DFE71D}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.Azure", "Orchard.Azure\Orchard.Azure.csproj", "{2505AA84-65A6-43D0-9C27-4F44FD576284}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution CodeCoverage|Any CPU = CodeCoverage|Any CPU @@ -900,6 +902,16 @@ Global {CBC7993C-57D8-4A6C-992C-19E849DFE71D}.FxCop|Any CPU.Build.0 = Release|Any CPU {CBC7993C-57D8-4A6C-992C-19E849DFE71D}.Release|Any CPU.ActiveCfg = Release|Any CPU {CBC7993C-57D8-4A6C-992C-19E849DFE71D}.Release|Any CPU.Build.0 = Release|Any CPU + {2505AA84-65A6-43D0-9C27-4F44FD576284}.CodeCoverage|Any CPU.ActiveCfg = Release|Any CPU + {2505AA84-65A6-43D0-9C27-4F44FD576284}.CodeCoverage|Any CPU.Build.0 = Release|Any CPU + {2505AA84-65A6-43D0-9C27-4F44FD576284}.Coverage|Any CPU.ActiveCfg = Release|Any CPU + {2505AA84-65A6-43D0-9C27-4F44FD576284}.Coverage|Any CPU.Build.0 = Release|Any CPU + {2505AA84-65A6-43D0-9C27-4F44FD576284}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2505AA84-65A6-43D0-9C27-4F44FD576284}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2505AA84-65A6-43D0-9C27-4F44FD576284}.FxCop|Any CPU.ActiveCfg = Release|Any CPU + {2505AA84-65A6-43D0-9C27-4F44FD576284}.FxCop|Any CPU.Build.0 = Release|Any CPU + {2505AA84-65A6-43D0-9C27-4F44FD576284}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2505AA84-65A6-43D0-9C27-4F44FD576284}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE