diff --git a/MatterControlApplication.cs b/MatterControlApplication.cs index 03603cbab..444518cc0 100644 --- a/MatterControlApplication.cs +++ b/MatterControlApplication.cs @@ -55,6 +55,7 @@ using Gaming.Game; using MatterHackers.GuiAutomation; using MatterHackers.MatterControl.PrinterControls.PrinterConnections; using MatterHackers.MatterControl.CustomWidgets; +using Newtonsoft.Json; namespace MatterHackers.MatterControl { @@ -119,6 +120,50 @@ namespace MatterHackers.MatterControl } } + + /// + /// Requests fresh content from online services, falling back to cached content if offline + /// + /// The custom collector function to load the content + /// + internal static T LoadCacheable(string cacheKey, string cacheScope, Func collector) where T : class + { + string cacheDirectory = Path.Combine(ApplicationDataStorage.ApplicationUserDataPath, "data", "temp", "cache", cacheScope); + string cachePath = Path.Combine(cacheDirectory, cacheKey); + + // Ensure directory exists + Directory.CreateDirectory(cacheDirectory); + + try + { + // Try to update the document + string documentText = collector(); + + if (!string.IsNullOrEmpty(documentText)) + { + var results = JsonConvert.DeserializeObject(documentText); + + // update cache on success + File.WriteAllText(cachePath, documentText); + return results; + } + } + catch + { + // fall back to preexisting cache if failed + } + + try + { + // Load from cache and deserialize + return JsonConvert.DeserializeObject(File.ReadAllText(cachePath)); + } + catch + { + return default(T); + } + } + private MatterControlApplication(double width, double height) : base(width, height) { diff --git a/SettingsManagement/OemSettings.cs b/SettingsManagement/OemSettings.cs index b14059126..cb4c73b4e 100644 --- a/SettingsManagement/OemSettings.cs +++ b/SettingsManagement/OemSettings.cs @@ -38,6 +38,8 @@ using System.IO; using System.Linq; using System.Net; using System.Runtime.Serialization; +using System.Threading; +using System.Threading.Tasks; namespace MatterHackers.MatterControl.SettingsManagement { @@ -120,45 +122,28 @@ namespace MatterHackers.MatterControl.SettingsManagement [OnDeserialized] private void Deserialized(StreamingContext context) { - // TODO: Enable caching - // Load the cached data from disk - // Extract the ETAG - // Request the latest content, passing along the ETAG - // Refresh our cache if needed, otherwise stick with the cached data + var oemProfiles = MatterControlApplication.LoadCacheable>>( + "oemprofiles.json", + "profiles", + () => + { + string responseText = null; - PublicProfilesRequest profileRequest = new PublicProfilesRequest(); - profileRequest.Request(); + var autoResetEvent = new AutoResetEvent(false); - //// For now, refresh every time - //string cacheDirectory = Path.Combine(ApplicationDataStorage.ApplicationUserDataPath, "data", "temp", "cache", "profiles"); + var profileRequest = new PublicProfilesRequest(); + profileRequest.RequestSucceeded += (s, e) => responseText = profileRequest.ResponseValues["ProfileList"]; + profileRequest.RequestComplete += (s, e) => autoResetEvent.Set(); + profileRequest.Request(); - //// Ensure directory exists - //Directory.CreateDirectory(cacheDirectory); + // Block on the current thread until the response has completed + autoResetEvent.WaitOne(12000); - //// Cache file path - //string cachePath = Path.Combine(cacheDirectory, "oemprofiles.json"); + return responseText; + }); - //try - //{ - // var fileInfo = new FileInfo(cachePath); - // if (!fileInfo.Exists || (DateTime.Now - fileInfo.LastWriteTime).TotalHours > 1) - // { - // string url = "http://matterdata.azurewebsites.net/api/oemprofiles"; - - // var client = new WebClient(); - - // File.WriteAllText(cachePath, client.DownloadString(url)); - // } - //} - //catch (Exception ex) - //{ - // System.Diagnostics.Trace.WriteLine("An unexpected exception occurred while requesting the latest oem profiles: \r\n" + ex.Message); - //} - - //string profilesText = File.ReadAllText(cachePath); - //OemProfiles = JsonConvert.DeserializeObject>>(profilesText); - - //SetManufacturers(OemProfiles.Select(m => new KeyValuePair(m.Key, m.Key)).ToList()); + OemProfiles = oemProfiles; + SetManufacturers(oemProfiles.Select(m => new KeyValuePair(m.Key, m.Key)).ToList()); } private OemSettings() diff --git a/SlicerConfiguration/Settings/ProfileManager.cs b/SlicerConfiguration/Settings/ProfileManager.cs index 97c365812..78e478b27 100644 --- a/SlicerConfiguration/Settings/ProfileManager.cs +++ b/SlicerConfiguration/Settings/ProfileManager.cs @@ -275,10 +275,9 @@ namespace MatterHackers.MatterControl.SlicerConfiguration private static OemProfile LoadHttpOemProfile(string make, string model) { RetrievePublicProfileRequest profileRequest = new RetrievePublicProfileRequest(); - string profText = profileRequest.getPrinterProfileByMakeModel(make, model); - var printerProfile = JsonConvert.DeserializeObject(profText); - - return printerProfile; + string profileText = profileRequest.GetPrinterProfileByMakeModel(make, model); + + return JsonConvert.DeserializeObject(profileText); } diff --git a/Tests/MatterControl.AutomationTests/RetrievePublicProfileTest.cs b/Tests/MatterControl.AutomationTests/RetrievePublicProfileTest.cs index 8c8a83f2c..bdedb863c 100644 --- a/Tests/MatterControl.AutomationTests/RetrievePublicProfileTest.cs +++ b/Tests/MatterControl.AutomationTests/RetrievePublicProfileTest.cs @@ -63,12 +63,11 @@ namespace MatterControl.Tests.MatterControl File.Delete(expectedProfilePath); } RetrievePublicProfileRequest request = new RetrievePublicProfileRequest(); - RetrievePublicProfileRequest.DownloadBaseUrl = "https://mattercontrol-test.appspot.com/api/1/device/get-public-profile"; - string recievedPrinterProfile = request.getPrinterProfileByMakeModel(make,model); - RetrievePublicProfileRequest.DownloadBaseUrl = "https://mattercontrol.appspot.com/api/1/device/get-public-profile"; + + string recievedPrinterProfile = request.GetPrinterProfileByMakeModel(make,model); Assert.IsNotNullOrEmpty(recievedPrinterProfile); - //Assert.AreEqual(expectedProfilePath, recievedProfilePath,"Recieved Profile path does not match expected path."); + //Assert.AreEqual(expectedProfilePath, recievedProfilePath,"Received Profile path does not match expected path."); //Assert.IsTrue(File.Exists(expectedProfilePath)); } diff --git a/VersionManagement/PublicProfilesRequest.cs b/VersionManagement/PublicProfilesRequest.cs index 6666b2c4a..601a235af 100644 --- a/VersionManagement/PublicProfilesRequest.cs +++ b/VersionManagement/PublicProfilesRequest.cs @@ -24,21 +24,11 @@ namespace MatterHackers.MatterControl.VersionManagement internal string URI { get { return uri; } set { uri = value; } } + public JsonResponseDictionary ResponseValues { get; set; } + public override void ProcessSuccessResponse(JsonResponseDictionary responseValues) { - //For now, refresh every time - string cacheDirectory = Path.Combine(ApplicationDataStorage.ApplicationUserDataPath, "data", "temp", "cache", "profiles"); - //Ensure directory exists - Directory.CreateDirectory(cacheDirectory); - //Cache File Path - string cachePath = Path.Combine(cacheDirectory, "oemprofiles.json"); - File.WriteAllText(cachePath, responseValues["ProfileList"]); - - - OemSettings.Instance.OemProfiles = JsonConvert.DeserializeObject>>(responseValues["ProfileList"]); - OemSettings.Instance.SetManufacturers(OemSettings.Instance.OemProfiles.Select(m => new KeyValuePair(m.Key, m.Key)).ToList()); + ResponseValues = responseValues; } - - } } diff --git a/VersionManagement/RetrievePublicProfileRequest.cs b/VersionManagement/RetrievePublicProfileRequest.cs index a70a6617d..53b318f14 100644 --- a/VersionManagement/RetrievePublicProfileRequest.cs +++ b/VersionManagement/RetrievePublicProfileRequest.cs @@ -5,20 +5,15 @@ using System.Net; namespace MatterHackers.MatterControl.VersionManagement { - class RetrievePublicProfileRequest + public class RetrievePublicProfileRequest { - internal static string DownloadBaseUrl { get; set; } - - public RetrievePublicProfileRequest() - { #if DEBUG - DownloadBaseUrl = "https://mattercontrol-test.appspot.com/api/1/device/get-public-profile"; + internal static string DownloadBaseUrl { get; } = "https://mattercontrol-test.appspot.com/api/1/device/get-public-profile"; #else - DownloadBaseUrl = "https://mattercontrol.appspot.com/api/1/device/get-public-profile"; + internal static string DownloadBaseUrl { get; } = "https://mattercontrol.appspot.com/api/1/device/get-public-profile"; #endif - } - public string getPrinterProfileByMakeModel(string make, string model) + public string GetPrinterProfileByMakeModel(string make, string model) { string deviceToken = OemSettings.Instance.OemProfiles[make][model]; string profiletext = DownloadPrinterProfile(deviceToken); @@ -27,39 +22,16 @@ namespace MatterHackers.MatterControl.VersionManagement internal static string DownloadPrinterProfile(string deviceToken) { - // TODO: Enable caching - //Keept track of version. When retrieving check version - + // Keep track of version. When retrieving check version string url = DownloadBaseUrl + string.Format("/{0}",deviceToken); string profilePath = Path.Combine(ApplicationDataStorage.ApplicationUserDataPath,"Profiles",string.Format("{0}.json",deviceToken)); + WebClient client = new WebClient(); + string profileText = client.DownloadString(url); //File.WriteAllText(profileText, profilePath); - return profileText; - //HttpClient client = new HttpClient(); - - //Get a pemporaty path to write to during download. If download completes without error we move this file to the proper path - //string tempFilePath = ApplicationDataStorage.Instance.GetTempFileName(".json"); - - //byte[] buffer = new byte[65536]; - //using (var writeStream = File.Create(tempFilePath)) - //using (var instream = await client.GetStreamAsync(url)) - //{ - // int bytesRead = await instream.ReadAsync(buffer, 0, buffer.Length); - // while(bytesRead != 0) - // { - // writeStream.Write(buffer, 0, bytesRead); - - // bytesRead = await instream.ReadAsync(buffer, 0, buffer.Length); - // } - //} - - //File.Move(tempFilePath, profilePath); - - //return profilePath; } - //Used in test to access test server before changes go onto live server } }