Skip to content

Instantly share code, notes, and snippets.

@AThraen
Last active September 3, 2018 13:12
Show Gist options
  • Select an option

  • Save AThraen/77b856633ff90489b4c46cd9095e45f7 to your computer and use it in GitHub Desktop.

Select an option

Save AThraen/77b856633ff90489b4c46cd9095e45f7 to your computer and use it in GitHub Desktop.
Episerver scheduled job to publish site to Azure Storage Static Websites
using System;
using EPiServer.Core;
using EPiServer.PlugIn;
using EPiServer.Scheduler;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
using EPiServer;
using EPiServer.ServiceLocation;
using EPiServer.Web.Routing;
using System.Net;
using System.Web.Hosting;
using System.IO;
using System.Web;
using System.Collections.Generic;
using EPiServer.DataAbstraction;
using System.Web.Configuration;
namespace StaticAlloy.StaticSiteGenerator
{
[ScheduledPlugIn(DisplayName = "Generate Static Site")]
public class StaticGeneratorJob : ScheduledJobBase
{
public const string DEFAULTFILENAME = "index.html";
private bool _stopSignaled;
/// <summary>
/// Called when a user clicks on Stop for a manually started job, or when ASP.NET shuts down.
/// </summary>
public override void Stop()
{
_stopSignaled = true;
}
public StaticGeneratorJob(IContentLoader loader, ContentAssetHelper assethelper, ILanguageBranchRepository languagerepo)
{
_loader = loader;
_assethelper = assethelper;
_languagerepo = languagerepo;
IsStoppable = true;
}
protected CloudStorageAccount account;
protected CloudBlobContainer container;
protected IContentLoader _loader;
protected ContentAssetHelper _assethelper;
protected ILanguageBranchRepository _languagerepo;
protected int TraverseSite(ContentReference n, string language)
{
int cnt = 0;
var u = UrlResolver.Current.GetUrl(n,language);
//Url is null if it's not url adressable (for example block or folder)
if (u != null)
{
var uri = new Uri(u);
var rel = uri.AbsolutePath;
OnStatusChanged(String.Format("Fetching {0}", rel));
try
{
WebClient wc = new WebClient();
var data = wc.DownloadData(u);
var name = rel.TrimStart('/');
if (name.EndsWith("/")) name = name + DEFAULTFILENAME;
var blob = container.GetBlockBlobReference(name);
blob.Properties.ContentType = wc.ResponseHeaders[HttpResponseHeader.ContentType];
blob.Properties.ContentEncoding = wc.ResponseHeaders[HttpResponseHeader.ContentEncoding];
blob.Properties.CacheControl = wc.ResponseHeaders[HttpResponseHeader.CacheControl];
blob.UploadFromByteArray(data, 0, data.Length);
blob.SetProperties();
cnt++;
}
catch
{
//TODO: Log error
}
}
//Get Content Assets recursively
var l = _assethelper.GetAssetFolder(n);
if (l != null)
{
foreach (var a in _loader.GetDescendents(l.ContentLink))
{
cnt += TraverseSite(a,language);
}
}
return cnt;
}
public static string[] GetFiles(string path, string searchPattern, SearchOption searchOption)
{
string[] searchPatterns = searchPattern.Split('|');
List<string> files = new List<string>();
foreach (string sp in searchPatterns)
files.AddRange(System.IO.Directory.GetFiles(path, sp, searchOption));
files.Sort();
return files.ToArray();
}
public int TraverseFiles(string basefolder,string folder, string pattern, bool recursive)
{
int cnt = 0;
foreach(var f in GetFiles(Path.Combine(basefolder,folder), pattern, (recursive)? SearchOption.AllDirectories:SearchOption.TopDirectoryOnly))
{
string rel = f.Replace(basefolder, "");
OnStatusChanged(String.Format("Uploading {0}", rel));
var blob=container.GetBlockBlobReference(rel);
var mime=MimeMapping.GetMimeMapping(Path.GetFileName(f));
blob.Properties.ContentType = mime;
blob.UploadFromFile(f);
blob.SetProperties();
cnt++;
}
return cnt;
}
/// <summary>
/// Called when a scheduled job executes
/// </summary>
/// <returns>A status message to be stored in the database log and visible from admin mode</returns>
public override string Execute()
{
//Call OnStatusChanged to periodically notify progress of job for manually started jobs
OnStatusChanged(String.Format("Starting execution of {0}", this.GetType()));
//Configure Blog storage
account = CloudStorageAccount.Parse(WebConfigurationManager.AppSettings["StaticStorage"]);
container = account.CreateCloudBlobClient().GetContainerReference("$web");
//Traverse content
int cnt = 0;
foreach (var b in _languagerepo.ListEnabled())
{
List<ContentReference> lst = new List<ContentReference>();
lst.Add(ContentReference.StartPage);
lst.AddRange(_loader.GetDescendents(ContentReference.StartPage));
lst.Add(ContentReference.SiteBlockFolder);
lst.AddRange(_loader.GetDescendents(ContentReference.SiteBlockFolder));
foreach (var n in lst)
{
cnt += TraverseSite(n, b.LanguageID);
}
}
//Traverse static files and folders
var rootPath = HostingEnvironment.MapPath("~/");
cnt += TraverseFiles(rootPath, "", "*.txt|*.ico", false);
cnt += TraverseFiles(rootPath, "Static", "*.css|*.js|*.png|*.gif|*.jpg|*.mp4|*.htm|*.html", true);
//For long running jobs periodically check if stop is signaled and if so stop execution
if (_stopSignaled)
{
return "Stop of job was called";
}
return string.Format("Moved {0} items to static web site storage",cnt);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment