Skip to content

Instantly share code, notes, and snippets.

@davidknipe
Last active November 18, 2016 16:26
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 davidknipe/b67f7b4937cf3042204f0924174a849a to your computer and use it in GitHub Desktop.
Save davidknipe/b67f7b4937cf3042204f0924174a849a to your computer and use it in GitHub Desktop.
namespace ApprovalsApi.Models
{
public class ApprovalDecision
{
public string Decision;
public int StepId;
public int ActiveStepIndex;
}
}
using System;
namespace ApprovalsApi.Models
{
public class ApprovalDetail
{
public string ContentUrl;
public DateTime Started;
public string StartedBy;
public int StepId;
public int ActiveStepIndex;
public int ContentId;
public int WorkId;
}
}
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;
using ApprovalsApi.Models;
using EPiServer;
using EPiServer.Approvals;
using EPiServer.Core;
using EPiServer.Notification;
using EPiServer.ServiceLocation;
namespace ApprovalsApi.Controllers
{
public class ApprovalsController : ApiController
{
private Injected<IApprovalEngine> _approvalEngine;
private Injected<IApprovalRepository> _approvalRepository;
private Injected<IContentRepository> _contentRepository;
public IEnumerable<ApprovalDetail> GetAll()
{
// Get all approvals waiting for approval
var query = new ApprovalsQuery
{
Status = ApprovalStatus.Pending,
Username = "epibot",
OnlyActiveSteps = true
};
var allApprovals = _approvalRepository.Service.ListAsync(query).Result;
// Generate the results
var results = new List<ApprovalDetail>();
foreach (var approval in allApprovals)
{
var content = _contentRepository.Service.Get<PageData>(approval.ContentLink);
results.Add(new ApprovalDetail()
{
ContentUrl =
UriSupport.SiteUrl + "globalassets/screencaptures/" + approval.ContentLink.ID + "_" +
approval.ContentLink.WorkID.ToString() + ".png?r=" + Guid.NewGuid().ToString(),
StartedBy = approval.StartedBy,
Started = approval.Started,
StepId = approval.ID,
ActiveStepIndex = approval.ActiveStepIndex,
ContentId = approval.ContentLink.ID,
WorkId = approval.ContentLink.WorkID
});
}
return results;
}
public async Task<HttpResponseMessage> Post([FromBody]ApprovalDecision approvalDecision)
{
// Recieve inbound decision
if (approvalDecision.Decision == "Approve")
{
await _approvalEngine.Service.ApproveAsync(approvalDecision.StepId, "epibot", approvalDecision.ActiveStepIndex, ApprovalDecisionScope.Step);
}
if (approvalDecision.Decision == "Reject")
{
await _approvalEngine.Service.RejectAsync(approvalDecision.StepId, "epibot", approvalDecision.ActiveStepIndex, ApprovalDecisionScope.Step);
}
await Notify(approvalDecision);
var response = Request.CreateResponse(HttpStatusCode.OK);
return response;
}
private async Task Notify(ApprovalDecision approvalDecision)
{
var content = GetContentFromDecision(approvalDecision);
// Send a notification back to the person who originally changed the content
INotifier notifier = ServiceLocator.Current.GetInstance<INotifier>();
await notifier.PostNotificationAsync(new NotificationMessage
{
// These needs to be set, but they don't have to match a formatter.
ChannelName = "EpibotChannelName",
TypeName = "EpibotTypeName",
// These have to be set so the notification knows who sent it, where to go, and what to show.
Sender = new NotificationUser("epibot"),
Recipients = new[]
{
new NotificationUser("david.knipe")
},
Subject = "Update from Epibot",
Content = $"Epibot gave the following decision: " + approvalDecision.Decision
});
}
private PageData GetContentFromDecision(ApprovalDecision approvalDecision)
{
var allApprovals = _approvalRepository.Service.ListAsync(new ApprovalsQuery
{
Status = ApprovalStatus.Pending,
Username = "epibot",
OnlyActiveSteps = true
});
var anyApprovals = _approvalRepository.Service.ListAsync(new ApprovalsQuery
{
Status = ApprovalStatus.Pending,
OnlyActiveSteps = true
});
foreach (var approval in anyApprovals.Result)
{
if (approvalDecision.StepId == approval.ID)
{
return _contentRepository.Service.Get<PageData>(approval.ContentLink);
}
}
return null;
}
}
}
using System;
using System.IO;
using System.Web;
using EPiServer;
using EPiServer.Async;
using EPiServer.Core;
using EPiServer.DataAccess;
using EPiServer.Framework;
using EPiServer.Framework.Blobs;
using EPiServer.Framework.Initialization;
using EPiServer.Logging;
using EPiServer.Security;
using EPiServer.ServiceLocation;
using ScreenCapture.Models;
using GrabzIt;
using GrabzIt.Parameters;
using GrabzIt.Enums;
namespace ScreenCapture.Init
{
[InitializableModule]
[ModuleDependency(typeof(ScreenCaptureFolderInit))]
public class CaptureApprovalRequestsInit : IInitializableModule
{
private IContentRepository _contentRepository;
private TaskExecutor _taskExecutor;
private ILogger _logger;
public void Initialize(InitializationEngine context)
{
_contentRepository = ServiceLocator.Current.GetInstance<IContentRepository>();
_taskExecutor = ServiceLocator.Current.GetInstance<TaskExecutor>();
IContentEvents events = ServiceLocator.Current.GetInstance<IContentEvents>();
events.RequestingApproval += GrabzIt;
_logger = ServiceLocator.Current.GetInstance<ILogger>();
}
private void GrabzIt(object sender, ContentEventArgs e)
{
if (e.Content.GetOriginalType().IsAssignableFrom(typeof(ScreenCaptureFile)))
return;
var cookies = HttpContext.Current.Request.Cookies;
this._taskExecutor.Start(new System.Action(delegate
{
this.GrabzItAsync(e.ContentLink, cookies);
}));
}
public void Uninitialize(InitializationEngine context)
{
}
private void GrabzItAsync(ContentReference contentReference, HttpCookieCollection cookies)
{
try
{
var contentId = contentReference.ID.ToString();
var workId = contentReference.WorkID.ToString();
var editUrl = UriSupport.SiteUrl + UriSupport.UIUrl.AbsolutePath.TrimStart('/') + "/Content/,," + contentId + "_" + workId + "/?epieditmode=True";
GrabzItClient grabzIt = GrabzItClient.Create("<app key>", "<app secret>");
ImageOptions options = new ImageOptions
{
Quality = 100,
RequestAs = BrowserType.StandardBrowser,
Delay = 1000,
Format = ImageFormat.png,
BrowserHeight = -1,
BrowserWidth = 1366
};
grabzIt.URLToImage(editUrl, options);
SaveGrabzItToRepo(grabzIt, contentReference);
}
catch (Exception ex)
{
_logger.Log(Level.Error, ex.ToString());
}
}
private void SaveGrabzItToRepo(GrabzItClient screenshotJob, ContentReference contentReference)
{
var blobFactory = ServiceLocator.Current.GetInstance<IBlobFactory>();
// Initialise our screen shot image
var screenShotFile = ScreenShotExists(contentReference);
if (screenShotFile == null)
{
screenShotFile =
_contentRepository.GetDefault<ScreenCaptureFile>(ScreenCaptureFolderInit.ScreenCapturesFolder);
screenShotFile.Name = GetFileName(contentReference);
}
else
{
screenShotFile = screenShotFile.CreateWritableClone() as ScreenCaptureFile;
}
// Populate the binary image data
if (screenShotFile != null)
{
var blob = blobFactory.CreateBlob(screenShotFile.BinaryDataContainer, ".png");
blob.Write(new MemoryStream(screenshotJob.SaveTo().Bytes));
screenShotFile.BinaryData = blob;
// Save the image into the repo
_contentRepository.Save(screenShotFile, SaveAction.ForceNewVersion, AccessLevel.NoAccess);
_contentRepository.Save(screenShotFile, SaveAction.Publish, AccessLevel.NoAccess);
}
}
private string GetFileName(ContentReference contentReference)
{
return contentReference.ID.ToString() + "_" + contentReference.WorkID + ".png";
}
private ScreenCaptureFile ScreenShotExists(ContentReference contentReference)
{
string fileName = GetFileName(contentReference);
var screenCaptureImages = _contentRepository.GetChildren<ScreenCaptureFile>(ScreenCaptureFolderInit.ScreenCapturesFolder);
foreach (var screenCaptureImage in screenCaptureImages)
{
if (screenCaptureImage.Name == fileName)
{
return screenCaptureImage;
}
}
return null;
}
}
}
using EPiServer.Core;
using EPiServer.DataAnnotations;
using EPiServer.Framework.DataAnnotations;
namespace ScreenCapture.Models
{
[ContentType(GUID = "9590EEE0-52D3-4247-A431-FA48DB88A0AE"
, AvailableInEditMode = false
, DisplayName = "Screen capture"
, Description = "A screen capture of a page when it was marked as ready for review")]
[MediaDescriptor(ExtensionString = "png")]
public class ScreenCaptureFile : ImageData
{
public virtual string OriginalUrl { get; set; }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment