Update: Disco ICT Online Services - Plugin Library

Migrate plugin library to https://services.discoict.com.au
This commit is contained in:
Gary Sharp
2014-07-28 15:02:33 +10:00
parent 1cc7e94646
commit 3358d9e320
37 changed files with 729 additions and 763 deletions
@@ -0,0 +1,149 @@
using Disco.Data.Repository;
using Disco.Models.Services.Interop.DiscoServices;
using Disco.Services.Tasks;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Web;
namespace Disco.Services.Interop.DiscoServices
{
public static class PluginLibrary
{
private static string UpdateUrl()
{
return string.Concat(DiscoServiceHelpers.ServicesUrl, "API/Plugins/Library/V2");
}
public static string InitialManifestFilename()
{
return HttpContext.Current.Server.MapPath("~/ClientBin/DiscoServices.InitialPluginLibraryManifest.json");
}
public static string ManifestFilename(DiscoDataContext Database)
{
return Path.Combine(Database.DiscoConfiguration.PluginPackagesLocation, "LibraryManifest.json");
}
public static PluginLibraryManifestV2 LoadManifest(DiscoDataContext Database)
{
var manifestFile = ManifestFilename(Database);
if (File.Exists(manifestFile))
{
return JsonConvert.DeserializeObject<PluginLibraryManifestV2>(File.ReadAllText(manifestFile));
}
else
{
// Use Initial Plugin Library Manifest
manifestFile = InitialManifestFilename();
if (File.Exists(manifestFile))
return JsonConvert.DeserializeObject<PluginLibraryManifestV2>(File.ReadAllText(manifestFile));
throw new FileNotFoundException("No plugin library manifest file was found", manifestFile);
}
}
public static PluginLibraryIncompatibility LoadIncompatibilityData(this PluginLibraryManifestV2 LibraryManifest)
{
var pluginAssembly = typeof(PluginLibrary).Assembly;
Version hostVersion = pluginAssembly.GetName().Version;
return new PluginLibraryIncompatibility()
{
IncompatiblePlugins = LibraryManifest.Plugins.SelectMany(p => p.Releases, (p, r) =>
{
var rVersion = Version.Parse(r.Version);
if (r.Blocked)
return new PluginIncompatibility() { PluginId = r.PluginId, Version = rVersion, Reason = "This plugin release is blocked by Disco ICT Online Services" };
if (r.HostMinVersion != null && hostVersion < Version.Parse(r.HostMinVersion))
return new PluginIncompatibility() { PluginId = r.PluginId, Version = rVersion, Reason = string.Format("This plugin requires v{0} or newer", r.HostMinVersion) };
if (r.HostMaxVersion != null && hostVersion > Version.Parse(r.HostMaxVersion))
return new PluginIncompatibility() { PluginId = r.PluginId, Version = rVersion, Reason = string.Format("This plugin requires v{0} or older", r.HostMaxVersion) };
return null;
}).Where(i => i != null).ToList()
};
}
public static PluginLibraryManifestV2 UpdateManifest(DiscoDataContext Database, IScheduledTaskStatus Status)
{
Status.UpdateStatus(10, "Sending Request");
PluginLibraryManifestV2 result;
var discoVersion = UpdateQuery.CurrentDiscoVersionFormatted();
var url = UpdateUrl();
using (var httpClient = new HttpClient())
{
using (var formData = new FormUrlEncodedContent(new KeyValuePair<string, string>[] {
new KeyValuePair<string, string>("DeploymentId", Database.DiscoConfiguration.DeploymentId),
new KeyValuePair<string, string>("DiscoVersion", discoVersion)
}))
{
var response = httpClient.PostAsync(url, formData).Result;
response.EnsureSuccessStatusCode();
Status.UpdateStatus(50, "Waiting for Response");
var resultJson = response.Content.ReadAsStringAsync().Result;
Status.UpdateStatus(90, "Processing Response");
result = JsonConvert.DeserializeObject<PluginLibraryManifestV2>(resultJson);
}
}
var manifestJson = JsonConvert.SerializeObject(result);
var manifestFile = PluginLibrary.ManifestFilename(Database);
if (!Directory.Exists(Path.GetDirectoryName(manifestFile)))
Directory.CreateDirectory(Path.GetDirectoryName(manifestFile));
File.WriteAllText(manifestFile, manifestJson);
return result;
}
public static PluginLibraryItemReleaseV2 LatestCompatibleRelease(this PluginLibraryItemV2 LibraryItem, PluginLibraryIncompatibility Incompatibility)
{
return LibraryItem.Releases.OrderByDescending(r => Version.Parse(r.Version)).FirstOrDefault(r => Incompatibility.IsCompatible(r));
}
public static bool IsCompatible(this PluginLibraryIncompatibility IncompatibilityLibrary, PluginLibraryItemReleaseV2 Release)
{
PluginIncompatibility incompatibility;
return IsCompatible(IncompatibilityLibrary, Release, out incompatibility);
}
public static bool IsCompatible(this PluginLibraryIncompatibility IncompatibilityLibrary, PluginLibraryItemReleaseV2 Release, out PluginIncompatibility Incompatibility)
{
return IsCompatible(IncompatibilityLibrary, Release.PluginId, Version.Parse(Release.Version), out Incompatibility);
}
public static bool IsCompatible(this PluginLibraryIncompatibility IncompatibilityLibrary, string PluginId, Version Version)
{
PluginIncompatibility incompatibility;
return IsCompatible(IncompatibilityLibrary, PluginId, Version, out incompatibility);
}
public static bool IsCompatible(this PluginLibraryIncompatibility IncompatibilityLibrary, string PluginId, Version Version, out PluginIncompatibility Incompatibility)
{
Incompatibility = IncompatibilityLibrary.IncompatiblePlugins.FirstOrDefault(i => i.PluginId.Equals(PluginId, StringComparison.OrdinalIgnoreCase) && i.Version == Version);
return Incompatibility == null;
}
}
}
@@ -0,0 +1,63 @@
using Disco.Data.Repository;
using Disco.Services.Tasks;
using Newtonsoft.Json;
using Quartz;
using System;
using System.IO;
using System.Linq;
namespace Disco.Services.Interop.DiscoServices
{
public class PluginLibraryUpdateTask : ScheduledTask
{
public override string TaskName { get { return "Disco ICT - Update Plugin Library"; } }
public override bool SingleInstanceTask { get { return true; } }
public override bool CancelInitiallySupported { get { return false; } }
public override void InitalizeScheduledTask(DiscoDataContext Database)
{
// Random time between midday and midnight.
var rnd = new Random();
var rndHour = rnd.Next(12, 23);
var rndMinute = rnd.Next(0, 59);
TriggerBuilder triggerBuilder = TriggerBuilder.Create().
WithSchedule(CronScheduleBuilder.DailyAtHourAndMinute(rndHour, rndMinute));
this.ScheduleTask(triggerBuilder);
}
protected override void ExecuteTask()
{
using (DiscoDataContext database = new DiscoDataContext())
{
Status.UpdateStatus(1, "Updating Plugin Library Manifest", "Initializing");
var manifest = PluginLibrary.UpdateManifest(database, this.Status);
Status.SetFinishedMessage("The Plugin Library Manifest was updated successfully");
}
}
public static ScheduledTaskStatus ScheduleNow()
{
var taskStatus = RunningStatus;
if (taskStatus != null)
return taskStatus;
else
{
var task = new PluginLibraryUpdateTask();
return task.ScheduleTask();
}
}
public static ScheduledTaskStatus RunningStatus
{
get
{
return ScheduledTasks.GetTaskStatuses(typeof(PluginLibraryUpdateTask)).Where(ts => ts.IsRunning).FirstOrDefault();
}
}
}
}