Skip to content

Instantly share code, notes, and snippets.

@andrewmarkham
Created September 25, 2021 17:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andrewmarkham/473d36fb60229326a11ce32c1fcc9f14 to your computer and use it in GitHub Desktop.
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
/*
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