Revise PublicProfileRequests, make functional offline

- Add prototype for loading cacheable content
 - Make RetrievePrinterProfile test use public server
 - Expose JsonResponseDictionary on PublicProfilesRequest
This commit is contained in:
John Lewin 2016-06-23 18:30:51 -07:00
parent cdc953f7c3
commit ca55930bf4
6 changed files with 80 additions and 90 deletions

View file

@ -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
}
}
/// <summary>
/// Requests fresh content from online services, falling back to cached content if offline
/// </summary>
/// <param name="collector">The custom collector function to load the content</param>
/// <returns></returns>
internal static T LoadCacheable<T>(string cacheKey, string cacheScope, Func<string> 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<T>(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<T>(File.ReadAllText(cachePath));
}
catch
{
return default(T);
}
}
private MatterControlApplication(double width, double height)
: base(width, height)
{

View file

@ -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<Dictionary<string, Dictionary<string, string>>>(
"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<Dictionary<string, List<string>>>(profilesText);
//SetManufacturers(OemProfiles.Select(m => new KeyValuePair<string, string>(m.Key, m.Key)).ToList());
OemProfiles = oemProfiles;
SetManufacturers(oemProfiles.Select(m => new KeyValuePair<string, string>(m.Key, m.Key)).ToList());
}
private OemSettings()

View file

@ -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<OemProfile>(profText);
return printerProfile;
string profileText = profileRequest.GetPrinterProfileByMakeModel(make, model);
return JsonConvert.DeserializeObject<OemProfile>(profileText);
}

View file

@ -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));
}

View file

@ -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<Dictionary<string,Dictionary<string,string>>>(responseValues["ProfileList"]);
OemSettings.Instance.SetManufacturers(OemSettings.Instance.OemProfiles.Select(m => new KeyValuePair<string, string>(m.Key, m.Key)).ToList());
ResponseValues = responseValues;
}
}
}

View file

@ -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
}
}