Skip to content

Commit

Permalink
Added storage provider for Azure BlobStorage. Fixes #23
Browse files Browse the repository at this point in the history
  • Loading branch information
tidyui committed Jan 23, 2018
1 parent 2b5b6e4 commit 10ea62e
Show file tree
Hide file tree
Showing 3 changed files with 210 additions and 0 deletions.
81 changes: 81 additions & 0 deletions core/Piranha.Azure.BlobStorage/BlobStorage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Copyright (c) 2018 Håkan Edling
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*
* https://github.com/piranhacms/piranha.core
*
*/

using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Auth;
using Microsoft.WindowsAzure.Storage.Blob;
using System;
using System.Threading.Tasks;

namespace Piranha.Azure
{
public class BlobStorage : IStorage
{
/// <summary>
/// The private storage account.
/// </summary>
private readonly CloudStorageAccount storage;

/// <summary>
/// The name of the container to use.
/// </summary>
private readonly string containerName;

/// <summary>
/// The container url.
/// </summary>
private string containerUrl;

/// <summary>
/// Default constructor.
/// </summary>
public BlobStorage(StorageCredentials credentials, string containerName = "uploads") {
this.storage = new CloudStorageAccount(credentials, true);
this.containerName = containerName;
}

/// <summary>
/// Opens a new storage session.
/// </summary>
/// <returns>A new open session</returns>
public async Task<IStorageSession> OpenAsync() {
var session = storage.CreateCloudBlobClient();
var container = session.GetContainerReference(containerName);

if (!await container.ExistsAsync()) {
await container.CreateAsync();
await container.SetPermissionsAsync(new BlobContainerPermissions() {
PublicAccess = BlobContainerPublicAccessType.Blob
});
}
containerUrl = container.Uri.AbsoluteUri;

return new BlobStorageSession(container);
}

/// <summary>
/// Gets the public URL for the given media object.
/// </summary>
/// <param name="media">The media</param>
/// <returns>The public url</returns>
public string GetPublicUrl(Data.Media media) {
if (media.Id != Guid.Empty) {
if (string.IsNullOrEmpty(containerUrl)) {
var session = storage.CreateCloudBlobClient();
var container = session.GetContainerReference(containerName);

containerUrl = container.Uri.AbsoluteUri;
}
return containerUrl + "/" + media.Id + "-" + media.Filename;
}
return null;
}
}
}
104 changes: 104 additions & 0 deletions core/Piranha.Azure.BlobStorage/BlobStorageSession.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/*
* Copyright (c) 2018 Håkan Edling
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*
* https://github.com/piranhacms/piranha.core
*
*/

using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
using System;
using System.IO;
using System.Threading.Tasks;

namespace Piranha.Azure
{
public class BlobStorageSession : IStorageSession
{
/// <summary>
/// The container in which to store media.
/// </summary>
private CloudBlobContainer container;

/// <summary>
/// Default constructor.
/// </summary>
public BlobStorageSession(CloudBlobContainer container) {
this.container = container;
}

/// <summary>
/// Writes the content for the specified media content to the given stream.
/// </summary>
/// <param name="id">The unique id</param>
/// <param name="stream">The output stream</param>
/// <returns>If the media was found</returns>
public async Task<bool> GetAsync(string id, Stream stream) {
var blob = container.GetBlockBlobReference(id);

if (await blob.ExistsAsync()) {
await blob.DownloadToStreamAsync(stream);
return true;
}
return false;
}

/// <summary>
/// Stores the given media content.
/// </summary>
/// <param name="id">The unique id</param>
/// <param name="contentType">The content type</param>
/// <param name="stream">The input stream</param>
/// <returns>The public URL</returns>
public async Task<string> PutAsync(string id, string contentType, Stream stream) {
var blob = container.GetBlockBlobReference(id);

await blob.UploadFromStreamAsync(stream);
blob.Properties.ContentType = contentType;
await blob.SetPropertiesAsync();

return blob.Uri.AbsoluteUri;
}

/// <summary>
/// Stores the given media content.
/// </summary>
/// <param name="id">The unique id</param>
/// <param name="contentType">The content type</param>
/// <param name="bytes">The binary data</param>
/// <returns>The public URL</returns>
public async Task<string> PutAsync(string id, string contentType, byte[] bytes) {
var blob = container.GetBlockBlobReference(id);

await blob.UploadFromByteArrayAsync(bytes, 0, bytes.Length);
blob.Properties.ContentType = contentType;
await blob.SetPropertiesAsync();

return blob.Uri.AbsoluteUri;
}

/// <summary>
/// Deletes the content for the specified media.
/// </summary>
/// <param name="id">The unique id/param>
public async Task<bool> DeleteAsync(string id) {
var blob = container.GetBlockBlobReference(id);

if (await blob.ExistsAsync()) {
await blob.DeleteAsync();
return true;
}
return false;
}

/// <summary>
/// Disposes the session.
/// </summary>
public void Dispose() {
GC.SuppressFinalize(this);
}
}
}
25 changes: 25 additions & 0 deletions core/Piranha.Azure.BlobStorage/Piranha.Azure.BlobStorage.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<Version>4.2.0</Version>
<Company>Piranha CMS</Company>
<AssemblyTitle>Piranha.Azure.BlogStorage</AssemblyTitle>
<RootNamespace>Piranha.Azure</RootNamespace>
</PropertyGroup>
<PropertyGroup>
<PackageId>Piranha.Azure.BlobStorage</PackageId>
<PackageVersion>4.2.0</PackageVersion>
<Authors>Håkan Edling</Authors>
<Description>Library for storing media assets on disc.</Description>
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
<PackageReleaseNotes></PackageReleaseNotes>
<PackageTags>cms mvc aspnetcore netstandard</PackageTags>
<Copyright>Copyright 2018 (c) Håkan Edling</Copyright>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Piranha\Piranha.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="WindowsAzure.Storage" Version="8.7.0" />
</ItemGroup>
</Project>

0 comments on commit 10ea62e

Please sign in to comment.