diff --git a/Disco.BI/BI/Interop/Community/CommunityHelpers.cs b/Disco.BI/BI/Interop/Community/CommunityHelpers.cs new file mode 100644 index 00000000..0d63758b --- /dev/null +++ b/Disco.BI/BI/Interop/Community/CommunityHelpers.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Text; +using System.Threading.Tasks; + +namespace Disco.BI.Interop.Community +{ + public static class CommunityHelpers + { + public static string CommunityUrl() + { + // Special case for DiscoCommunity Hosting Network + try + { + var ip = (from addr in Dns.GetHostEntry(Dns.GetHostName()).AddressList + where addr.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork + && addr.ToString().StartsWith("10.131.200.") + select addr).FirstOrDefault(); + if (ip != null) + { + return "http://hades3:9393/base/"; + } + } + catch (Exception) + { } // Ignore Errors + + return "http://discoict.com.au/base/"; + } + } +} diff --git a/Disco.BI/BI/Interop/Community/PluginLibraryUpdateTask.cs b/Disco.BI/BI/Interop/Community/PluginLibraryUpdateTask.cs new file mode 100644 index 00000000..3ffa9c25 --- /dev/null +++ b/Disco.BI/BI/Interop/Community/PluginLibraryUpdateTask.cs @@ -0,0 +1,195 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Disco.Data.Repository; +using Disco.Services.Plugins; +using Disco.Services.Tasks; +using Disco.Models.BI.Interop.Community; +using System.Net; +using System.Xml.Serialization; +using System.IO; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; + +namespace Disco.BI.Interop.Community +{ + public class PluginLibraryUpdateTask : ScheduledTask + { + public override string TaskName { get { return "Disco Community - Update Plugin Library"; } } + + protected override void ExecuteTask() + { + PluginLibraryUpdateRequest updateRequestBody; + PluginLibraryUpdateResponse updateResult; + string catalogueFile; + PluginLibraryCompatibilityRequest compatRequestBody; + PluginLibraryCompatibilityResponse compatResult; + string compatibilityFile; + + var DiscoBIVersion = UpdateCheck.CurrentDiscoVersion(); + HttpWebRequest webRequest; + + #region Update + + Status.UpdateStatus(1, "Updating Plugin Library Catalogue", "Building Request"); + + using (DiscoDataContext dbContext = new DiscoDataContext()) + { + catalogueFile = Plugins.CatalogueFile(dbContext); + + updateRequestBody = new PluginLibraryUpdateRequest() + { + DeploymentId = dbContext.DiscoConfiguration.DeploymentId, + HostVersion = typeof(Plugins).Assembly.GetName().Version.ToString(4) + }; + } + + Status.UpdateStatus(10, "Sending Request"); + + webRequest = (HttpWebRequest)HttpWebRequest.Create(PluginLibraryUpdateUrl()); + webRequest.KeepAlive = false; + + webRequest.ContentType = "application/json"; + webRequest.Method = WebRequestMethods.Http.Post; + webRequest.UserAgent = string.Format("Disco/{0} (PluginLibrary)", DiscoBIVersion); + + using (var wrStream = webRequest.GetRequestStream()) + { + XmlSerializer xml = new XmlSerializer(typeof(PluginLibraryUpdateRequest)); + xml.Serialize(wrStream, updateRequestBody); + } + + Status.UpdateStatus(20, "Waiting for Response"); + + using (HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse()) + { + if (webResponse.StatusCode == HttpStatusCode.OK) + { + Status.UpdateStatus(45, "Reading Response"); + using (var wResStream = webResponse.GetResponseStream()) + { + XmlSerializer xml = new XmlSerializer(typeof(PluginLibraryUpdateResponse)); + updateResult = (PluginLibraryUpdateResponse)xml.Deserialize(wResStream); + } + } + else + { + Status.SetTaskException(new WebException(string.Format("Server responded with: [{0}] {1}", webResponse.StatusCode, webResponse.StatusDescription))); + return; + } + } + + if (!Directory.Exists(Path.GetDirectoryName(catalogueFile))) + Directory.CreateDirectory(Path.GetDirectoryName(catalogueFile)); + + using (FileStream fs = new FileStream(catalogueFile, FileMode.Create, FileAccess.Write, FileShare.None)) + { + using (StreamWriter fsWriter = new StreamWriter(fs)) + { + fsWriter.Write(JsonConvert.SerializeObject(updateResult)); + fsWriter.Flush(); + } + } + #endregion + + #region Compatibility + + Status.UpdateStatus(50, "Updating Plugin Library Compatibility", "Building Request"); + + using (DiscoDataContext dbContext = new DiscoDataContext()) + { + compatibilityFile = Plugins.CompatibilityFile(dbContext); + + compatRequestBody = new PluginLibraryCompatibilityRequest() + { + DeploymentId = dbContext.DiscoConfiguration.DeploymentId, + HostVersion = typeof(Plugins).Assembly.GetName().Version.ToString(4) + }; + } + + Status.UpdateStatus(60, "Sending Request"); + + webRequest = (HttpWebRequest)HttpWebRequest.Create(PluginLibraryCompatibilityUrl()); + webRequest.KeepAlive = false; + + webRequest.ContentType = "application/json"; + webRequest.Method = WebRequestMethods.Http.Post; + webRequest.UserAgent = string.Format("Disco/{0} (PluginLibrary)", DiscoBIVersion); + + using (var wrStream = webRequest.GetRequestStream()) + { + XmlSerializer xml = new XmlSerializer(typeof(PluginLibraryCompatibilityRequest)); + xml.Serialize(wrStream, compatRequestBody); + } + + Status.UpdateStatus(70, "Waiting for Response"); + + using (HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse()) + { + if (webResponse.StatusCode == HttpStatusCode.OK) + { + Status.UpdateStatus(95, "Reading Response"); + using (var wResStream = webResponse.GetResponseStream()) + { + XmlSerializer xml = new XmlSerializer(typeof(PluginLibraryCompatibilityResponse)); + compatResult = (PluginLibraryCompatibilityResponse)xml.Deserialize(wResStream); + } + } + else + { + Status.SetTaskException(new WebException(string.Format("Server responded with: [{0}] {1}", webResponse.StatusCode, webResponse.StatusDescription))); + return; + } + } + + if (!Directory.Exists(Path.GetDirectoryName(compatibilityFile))) + Directory.CreateDirectory(Path.GetDirectoryName(compatibilityFile)); + + using (FileStream fs = new FileStream(compatibilityFile, FileMode.Create, FileAccess.Write, FileShare.None)) + { + using (StreamWriter fsWriter = new StreamWriter(fs)) + { + fsWriter.Write(JsonConvert.SerializeObject(compatResult)); + fsWriter.Flush(); + } + } + #endregion + + + + + Status.SetFinishedMessage("The Plugin Library Catalogue was updated."); + } + + private static string PluginLibraryUpdateUrl() + { + return string.Concat(CommunityHelpers.CommunityUrl(), "DiscoPluginLibrary/V1"); + } + private static string PluginLibraryCompatibilityUrl() + { + return string.Concat(CommunityHelpers.CommunityUrl(), "DiscoPluginLibrary/CompatibilityV1"); + } + + public static ScheduledTaskStatus ScheduleNow() + { + + var taskStatus = ScheduledTasks.GetTaskStatuses(typeof(PluginLibraryUpdateTask)).Where(ts => ts.IsRunning).FirstOrDefault(); + if (taskStatus != null) + return taskStatus; + else + { + var t = new PluginLibraryUpdateTask(); + return t.ScheduleTask(); + } + } + public static ScheduledTaskStatus RunningStatus + { + get + { + return ScheduledTasks.GetTaskStatuses(typeof(PluginLibraryUpdateTask)).Where(ts => ts.IsRunning).FirstOrDefault(); + } + } + } +} diff --git a/Disco.BI/BI/Interop/Community/UpdateCheck.cs b/Disco.BI/BI/Interop/Community/UpdateCheck.cs index 6da4bd12..678c98e2 100644 --- a/Disco.BI/BI/Interop/Community/UpdateCheck.cs +++ b/Disco.BI/BI/Interop/Community/UpdateCheck.cs @@ -16,24 +16,9 @@ namespace Disco.BI.Interop.Community { public static class UpdateCheck { - private static string UpdateUrl(DiscoDataContext db) + private static string UpdateUrl() { - // Special case for DiscoCommunity Hosting Network - try - { - var ip = (from addr in Dns.GetHostEntry(Dns.GetHostName()).AddressList - where addr.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork - && addr.ToString().StartsWith("10.131.200.") - select addr).FirstOrDefault(); - if (ip != null) - { - return "http://hades3:9393/base/DiscoUpdate/V1"; - } - } - catch (Exception) - { } // Ignore Errors - - return "http://discoict.com.au/base/DiscoUpdate/V1"; + return string.Concat(CommunityHelpers.CommunityUrl(), "DiscoUpdate/V1"); } public static string CurrentDiscoVersion() @@ -55,7 +40,7 @@ namespace Disco.BI.Interop.Community var DiscoBIVersion = CurrentDiscoVersion(); - HttpWebRequest webRequest = (HttpWebRequest)HttpWebRequest.Create(UpdateUrl(db)); + HttpWebRequest webRequest = (HttpWebRequest)HttpWebRequest.Create(UpdateUrl()); // Added: 2013-02-08 G# // Fix for Proxy Servers which dont support KeepAlive @@ -123,6 +108,8 @@ namespace Disco.BI.Interop.Community m.Stat_ActiveDeviceModelCounts = db.DeviceModels.Select(dm => new Disco.Models.BI.Interop.Community.UpdateRequestV1.Stat { Key = dm.Manufacturer + ";" + dm.Model, Count = dm.Devices.Count(d => d.DecommissionedDate == null && (d.LastNetworkLogonDate == null || d.LastNetworkLogonDate > activeThreshold)) }).ToList(); m.Stat_UserCounts = db.Users.GroupBy(u => u.Type).Select(g => new Disco.Models.BI.Interop.Community.UpdateRequestV1.Stat { Key = g.Key, Count = g.Count() }).ToList(); + m.InstalledPlugins = Disco.Services.Plugins.Plugins.GetPlugins().Select(manifest => new Disco.Models.BI.Interop.Community.UpdateRequestV1.PluginRef { Id = manifest.Id, Version = manifest.VersionFormatted }).ToList(); + return m; } @@ -162,7 +149,7 @@ namespace Disco.BI.Interop.Community HttpWebRequest wReq = (HttpWebRequest)HttpWebRequest.Create("http://broadband.doe.wan/ipsearch/showresult.php"); // Added: 2013-02-08 G# // Fix for Proxy Servers which dont support KeepAlive - webRequest.KeepAlive = false; + wReq.KeepAlive = false; // End Added: 2013-02-08 G# if (!useProxy) wReq.Proxy = new WebProxy(); // Empty Proxy Config diff --git a/Disco.Models/BI/Interop/Community/PluginLibraryCompatibilityItem.cs b/Disco.Models/BI/Interop/Community/PluginLibraryCompatibilityItem.cs new file mode 100644 index 00000000..74ff740b --- /dev/null +++ b/Disco.Models/BI/Interop/Community/PluginLibraryCompatibilityItem.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Disco.Models.BI.Interop.Community +{ + public class PluginLibraryCompatibilityItem + { + public string Id { get; set; } + public string Version { get; set; } + public bool Compatible { get; set; } + public string Reason { get; set; } + } +} diff --git a/Disco.Models/BI/Interop/Community/PluginLibraryCompatibilityRequest.cs b/Disco.Models/BI/Interop/Community/PluginLibraryCompatibilityRequest.cs new file mode 100644 index 00000000..14fd0eaa --- /dev/null +++ b/Disco.Models/BI/Interop/Community/PluginLibraryCompatibilityRequest.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Disco.Models.BI.Interop.Community +{ + public class PluginLibraryCompatibilityRequest + { + public string HostVersion { get; set; } + public string DeploymentId { get; set; } + } +} diff --git a/Disco.Models/BI/Interop/Community/PluginLibraryCompatibilityResponse.cs b/Disco.Models/BI/Interop/Community/PluginLibraryCompatibilityResponse.cs new file mode 100644 index 00000000..9af50f48 --- /dev/null +++ b/Disco.Models/BI/Interop/Community/PluginLibraryCompatibilityResponse.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Disco.Models.BI.Interop.Community +{ + public class PluginLibraryCompatibilityResponse + { + public string HostVersion { get; set; } + public DateTime ResponseTimestamp { get; set; } + public List Plugins { get; set; } + } +} diff --git a/Disco.Models/BI/Interop/Community/PluginLibraryItem.cs b/Disco.Models/BI/Interop/Community/PluginLibraryItem.cs new file mode 100644 index 00000000..a8b7d117 --- /dev/null +++ b/Disco.Models/BI/Interop/Community/PluginLibraryItem.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Disco.Models.BI.Interop.Community +{ + public class PluginLibraryItem + { + public string Id { get; set; } + public string Name { get; set; } + public string Author { get; set; } + public string Url { get; set; } + public string Blurb { get; set; } + + public string LatestVersion { get; set; } + public string LatestChangeLog { get; set; } + public string LatestHostVersionMin { get; set; } + public string LatestHostVersionMax { get; set; } + public string LatestDownloadUrl { get; set; } + } +} diff --git a/Disco.Models/BI/Interop/Community/PluginLibraryUpdateRequest.cs b/Disco.Models/BI/Interop/Community/PluginLibraryUpdateRequest.cs new file mode 100644 index 00000000..11199452 --- /dev/null +++ b/Disco.Models/BI/Interop/Community/PluginLibraryUpdateRequest.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Disco.Models.BI.Interop.Community +{ + public class PluginLibraryUpdateRequest + { + public string HostVersion { get; set; } + public string DeploymentId { get; set; } + } +} diff --git a/Disco.Models/BI/Interop/Community/PluginLibraryUpdateResponse.cs b/Disco.Models/BI/Interop/Community/PluginLibraryUpdateResponse.cs new file mode 100644 index 00000000..9905e483 --- /dev/null +++ b/Disco.Models/BI/Interop/Community/PluginLibraryUpdateResponse.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Disco.Models.BI.Interop.Community +{ + public class PluginLibraryUpdateResponse + { + public DateTime ResponseTimestamp { get; set; } + public List Plugins { get; set; } + } +} diff --git a/Disco.Models/BI/Interop/Community/UpdateRequestV1.cs b/Disco.Models/BI/Interop/Community/UpdateRequestV1.cs index 9c910310..8d4e1c09 100644 --- a/Disco.Models/BI/Interop/Community/UpdateRequestV1.cs +++ b/Disco.Models/BI/Interop/Community/UpdateRequestV1.cs @@ -1,32 +1,39 @@ -using System; -using System.Collections.Generic; - -namespace Disco.Models.BI.Interop.Community -{ - public class UpdateRequestV1 : UpdateRequestBase - { - public UpdateRequestV1() - { - this.RequestVersion = 1; - } - - public string DeploymentId { get; set; } - public string CurrentDiscoVersion { get; set; } - public bool BetaDeployment { get; set; } - - public string OrganisationName { get; set; } - public string BroadbandDoeWanId { get; set; } - - public List Stat_JobCounts { get; set; } - public List Stat_OpenJobCounts { get; set; } - public List Stat_ActiveDeviceModelCounts { get; set; } - public List Stat_UserCounts { get; set; } - - public class Stat - { - public string Key { get; set; } - public int Count { get; set; } - } - - } -} +using System; +using System.Collections.Generic; + +namespace Disco.Models.BI.Interop.Community +{ + public class UpdateRequestV1 : UpdateRequestBase + { + public UpdateRequestV1() + { + this.RequestVersion = 1; + } + + public string DeploymentId { get; set; } + public string CurrentDiscoVersion { get; set; } + public bool BetaDeployment { get; set; } + + public string OrganisationName { get; set; } + public string BroadbandDoeWanId { get; set; } + + public List Stat_JobCounts { get; set; } + public List Stat_OpenJobCounts { get; set; } + public List Stat_ActiveDeviceModelCounts { get; set; } + public List Stat_UserCounts { get; set; } + + public List InstalledPlugins { get; set; } + + public class Stat + { + public string Key { get; set; } + public int Count { get; set; } + } + + public class PluginRef + { + public string Id { get; set; } + public string Version { get; set; } + } + } +}