Created
September 25, 2021 17:21
-
-
Save andrewmarkham/473d36fb60229326a11ce32c1fcc9f14 to your computer and use it in GitHub Desktop.
Image Resizer plugin for Episerver/Optimizley that will copy images between environments, works for local file storage along with Azure Blob Storage
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Add to web.config | |
<plugins> | |
<add name="EPiServerAzureBlobReaderPlugin" /> | |
<add name="PatchImagePlugin" azureMode="true|false" hostUrl="https://source.of.images"/> | |
</plugins> | |
*/ | |
public class PatchImagePlugin : AzurePipelineBase, IPlugin | |
{ | |
private bool azureMode = true; | |
private string hostUrl = string.Empty; | |
public PatchImagePlugin(NameValueCollection settings) | |
{ | |
this.hostUrl = settings["hostUrl"]; | |
this.azureMode = settings["azureMode"].Equals("true", StringComparison.InvariantCultureIgnoreCase); | |
} | |
public IPlugin Install(Config config) | |
{ | |
config.Plugins.add_plugin(this); | |
config.Pipeline.ImageMissing += Pipeline_ImageMissing; | |
return this; | |
} | |
public bool Uninstall(Config config) | |
{ | |
config.Plugins.remove_plugin(this); | |
config.Pipeline.ImageMissing -= Pipeline_ImageMissing; | |
return true; | |
} | |
private void Pipeline_ImageMissing(IHttpModule sender, HttpContext context, IUrlEventArgs e) | |
{ | |
var productionFile = $"{hostUrl}{e.VirtualPath}"; | |
var blobImage = GetBlobFile(e.VirtualPath, e.QueryString); | |
using (var c = new HttpClient()) | |
{ | |
var fileStream = c.GetStreamAsync(productionFile).Result; | |
if (!azureMode) | |
{ | |
fileStream.CopyTo(blobImage.Blob.OpenWrite()); | |
} | |
else | |
{ | |
var cloudBlobContainer = this.GetContainer(); | |
var filename = blobImage.Blob.ID.PathAndQuery.Substring(1); | |
cloudBlobContainer.GetBlockBlobReference(filename).UploadFromStream(fileStream); | |
} | |
} | |
} | |
private EPiServerBlobFile GetBlobFile(string virtualPath, NameValueCollection queryString) | |
{ | |
var blobFile = new EPiServerBlobFile(virtualPath, queryString); | |
return blobFile; | |
} | |
} | |
public class EPiServerAzureBlobReaderPlugin : AzurePipelineBase, IVirtualImageProvider | |
{ | |
public bool FileExists(string virtualPath, NameValueCollection queryString) | |
{ | |
bool fileExists; | |
try | |
{ | |
var blobFile = new EPiServerBlobFile(virtualPath, queryString); | |
if (blobFile.Blob is AzureBlob) | |
{ | |
var cloudBlobContainer = this.GetContainer(); | |
fileExists = cloudBlobContainer.GetBlobReference(blobFile.Blob.ID.PathAndQuery).Exists(); | |
} | |
else | |
{ | |
fileExists = blobFile.BlobExists; | |
} | |
} | |
catch | |
{ | |
fileExists = false; | |
} | |
return fileExists; | |
} | |
public IVirtualFile GetFile(string virtualPath, NameValueCollection queryString) | |
{ | |
var blobFile = new EPiServerBlobFile(virtualPath, queryString); | |
return blobFile; | |
} | |
} | |
public abstract class AzurePipelineBase | |
{ | |
protected string connectionString; | |
protected string container; | |
protected AzurePipelineBase() | |
{ | |
GetAzureConfiguration(); | |
} | |
protected virtual CloudBlobContainer GetContainer() | |
{ | |
return CloudStorageAccount.Parse(this.connectionString).CreateCloudBlobClient() | |
.GetContainerReference(this.container); | |
} | |
protected void GetAzureConfiguration() | |
{ | |
var episerverFramework = ConfigurationManager.GetSection("episerver.framework") as EPiServer.Framework.Configuration.EPiServerFrameworkSection; | |
var blobConfigSection = episerverFramework?.Blob as EPiServer.Framework.Configuration.BlobElement; | |
var defaultProvider = blobConfigSection?.DefaultProvider; | |
var providerSection = blobConfigSection?.Providers[defaultProvider]; | |
var connectionStringName = providerSection?.Parameters["connectionStringName"] ?? string.Empty; | |
this.connectionString = ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString; | |
this.container = providerSection?.Parameters["container"] ?? string.Empty; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment