Merge pull request #1351 from jlewin/master
Use short identifiers for public profiles
This commit is contained in:
commit
e8a1d27694
8 changed files with 102 additions and 74 deletions
|
|
@ -50,7 +50,18 @@ namespace MatterHackers.MatterControl
|
|||
{
|
||||
using Agg.Font;
|
||||
using System.Reflection;
|
||||
using OemProfileDictionary = Dictionary<string, Dictionary<string, string>>;
|
||||
|
||||
public class OemProfileDictionary : Dictionary<string, Dictionary<string, PublicDevice>>
|
||||
{
|
||||
}
|
||||
|
||||
public class PublicDevice
|
||||
{
|
||||
public string DeviceToken { get; set; }
|
||||
public string ProfileToken { get; set; }
|
||||
public string ShortProfileID { get; set; }
|
||||
public string CacheKey => this.ShortProfileID + ProfileManager.ProfileExtension;
|
||||
}
|
||||
|
||||
public abstract class ApplicationView : GuiWidget
|
||||
{
|
||||
|
|
@ -276,11 +287,7 @@ namespace MatterHackers.MatterControl
|
|||
/// <returns></returns>
|
||||
public async static Task<T> LoadCacheableAsync<T>(string cacheKey, string cacheScope, Func<Task<T>> collector, string staticDataFallbackPath = null) 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);
|
||||
string cachePath = CacheablePath(cacheScope, cacheKey);
|
||||
|
||||
try
|
||||
{
|
||||
|
|
@ -289,13 +296,13 @@ namespace MatterHackers.MatterControl
|
|||
if (item != null)
|
||||
{
|
||||
// update cache on success
|
||||
File.WriteAllText(cachePath, JsonConvert.SerializeObject(item));
|
||||
File.WriteAllText(cachePath, JsonConvert.SerializeObject(item, Formatting.Indented));
|
||||
return item;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// fall back to preexisting cache if failed
|
||||
// Fall back to preexisting cache if failed
|
||||
}
|
||||
|
||||
try
|
||||
|
|
@ -308,7 +315,7 @@ namespace MatterHackers.MatterControl
|
|||
}
|
||||
catch
|
||||
{
|
||||
//Fallback to Static Data
|
||||
// Fall back to StaticData
|
||||
}
|
||||
|
||||
try
|
||||
|
|
@ -327,6 +334,19 @@ namespace MatterHackers.MatterControl
|
|||
return default(T);
|
||||
}
|
||||
|
||||
private static string cacheDirectory = Path.Combine(ApplicationDataStorage.ApplicationUserDataPath, "data", "temp", "cache");
|
||||
|
||||
internal static string CacheablePath(string cacheScope, string cacheKey)
|
||||
{
|
||||
string scopeDirectory = Path.Combine(cacheDirectory, cacheScope);
|
||||
|
||||
// Ensure directory exists
|
||||
Directory.CreateDirectory(scopeDirectory);
|
||||
|
||||
string cachePath = Path.Combine(scopeDirectory, cacheKey);
|
||||
return cachePath;
|
||||
}
|
||||
|
||||
public void StartSignOut()
|
||||
{
|
||||
if (PrinterConnectionAndCommunication.Instance.PrinterIsPrinting
|
||||
|
|
|
|||
|
|
@ -192,15 +192,15 @@ namespace MatterHackers.MatterControl.PrinterControls.PrinterConnections
|
|||
activeModel = null;
|
||||
|
||||
// Select the dictionary containing the printerName->printerToken mappings for the current OEM
|
||||
Dictionary<string, string> printers;
|
||||
Dictionary<string, PublicDevice> printers;
|
||||
if (!OemSettings.Instance.OemProfiles.TryGetValue(activeMake, out printers))
|
||||
{
|
||||
// Fall back to an empty dictionary if no match
|
||||
printers = new Dictionary<string, string>();
|
||||
printers = new Dictionary<string, PublicDevice>();
|
||||
}
|
||||
|
||||
// Models - sort dictionary results by key and assign to .ListSource
|
||||
printerModelSelector.ListSource = printers.OrderBy(p => p.Key).ToList();
|
||||
printerModelSelector.ListSource = printers.OrderBy(p => p.Key).Select(p => new KeyValuePair<string, string>(p.Key, p.Value.ProfileToken)).ToList();
|
||||
if (printerModelSelector.MenuItems.Count == 1)
|
||||
{
|
||||
// SelectIfOnlyOneModel
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@ using System.Threading.Tasks;
|
|||
namespace MatterHackers.MatterControl.SettingsManagement
|
||||
{
|
||||
using Agg.UI;
|
||||
using OemProfileDictionary = Dictionary<string, Dictionary<string, string>>;
|
||||
|
||||
public class OemSettings
|
||||
{
|
||||
|
|
@ -119,8 +118,8 @@ namespace MatterHackers.MatterControl.SettingsManagement
|
|||
if (whiteListedItems == null
|
||||
|| whiteListedItems.Count() == 0)
|
||||
{
|
||||
AllOems = new List<KeyValuePair<string, string>>(manufacturers);
|
||||
return;
|
||||
// No whitelist means all items
|
||||
whiteListedItems = manufacturers;
|
||||
}
|
||||
|
||||
var newItems = new List<KeyValuePair<string, string>>();
|
||||
|
|
@ -165,55 +164,49 @@ namespace MatterHackers.MatterControl.SettingsManagement
|
|||
return;
|
||||
}
|
||||
|
||||
var oemProfiles = await ApplicationController.LoadCacheableAsync<OemProfileDictionary>(
|
||||
await ApplicationController.LoadCacheableAsync<OemProfileDictionary>(
|
||||
"oemprofiles.json",
|
||||
"profiles",
|
||||
ApplicationController.GetPublicProfileList);
|
||||
"public-profiles",
|
||||
async () =>
|
||||
{
|
||||
var result = await ApplicationController.GetPublicProfileList();
|
||||
if (result != null)
|
||||
{
|
||||
OemProfiles = result;
|
||||
|
||||
// If we failed to get anything from load cacheable don't override potentially populated fields
|
||||
if (oemProfiles != null)
|
||||
{
|
||||
OemProfiles = oemProfiles;
|
||||
var manufactures = result.Keys.ToDictionary(oem => oem);
|
||||
SetManufacturers(manufactures);
|
||||
|
||||
var manufactures = oemProfiles.Keys.ToDictionary(oem => oem);
|
||||
SetManufacturers(manufactures);
|
||||
await DownloadMissingProfiles(syncReport);
|
||||
}
|
||||
|
||||
await DownloadMissingProfiles(syncReport);
|
||||
}
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
private async Task DownloadMissingProfiles(IProgress<SyncReportType> syncReport)
|
||||
{
|
||||
string cacheDirectory = Path.Combine(ApplicationDataStorage.ApplicationUserDataPath, "data", "temp", "cache", "profiles");
|
||||
SyncReportType reportValue = new SyncReportType();
|
||||
int index = 0;
|
||||
foreach (string oem in OemProfiles.Keys)
|
||||
{
|
||||
index++;
|
||||
foreach (string profileKey in OemProfiles[oem].Values)
|
||||
{
|
||||
string cacheKey = profileKey + ProfileManager.ProfileExtension;
|
||||
string cachePath = Path.Combine(cacheDirectory, cacheKey);
|
||||
string cacheScope = Path.Combine("public-profiles", oem);
|
||||
|
||||
index++;
|
||||
foreach (var publicDevice in OemProfiles[oem].Values)
|
||||
{
|
||||
string cachePath = ApplicationController.CacheablePath(cacheScope, publicDevice.CacheKey);
|
||||
if (!File.Exists(cachePath))
|
||||
{
|
||||
var profile = await ApplicationController.DownloadPublicProfileAsync(profileKey);
|
||||
if(profile != null)
|
||||
await ProfileManager.LoadOemProfileAsync(publicDevice, oem);
|
||||
|
||||
if (syncReport != null)
|
||||
{
|
||||
string profileJson = JsonConvert.SerializeObject(profile);
|
||||
if (!String.IsNullOrEmpty(profileJson))
|
||||
{
|
||||
File.WriteAllText(cachePath, profileJson);
|
||||
}
|
||||
if (syncReport != null)
|
||||
{
|
||||
reportValue.actionLabel = String.Format("Downloading public profiles for {0}...", oem);
|
||||
reportValue.percComplete = (double)index / OemProfiles.Count;
|
||||
syncReport.Report(reportValue);
|
||||
}
|
||||
reportValue.actionLabel = string.Format("Downloading public profiles for {0}...", oem);
|
||||
reportValue.percComplete = (double)index / OemProfiles.Count;
|
||||
syncReport.Report(reportValue);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -329,8 +329,10 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
|
|||
|
||||
try
|
||||
{
|
||||
string publicProfileDeviceToken = OemSettings.Instance.OemProfiles[profile.Make][profile.Model];
|
||||
string publicProfileToLoad = Path.Combine(ApplicationDataStorage.ApplicationUserDataPath, "data", "temp", "cache", "profiles", publicProfileDeviceToken + ProfileManager.ProfileExtension);
|
||||
var publicDevice = OemSettings.Instance.OemProfiles[profile.Make][profile.Model];
|
||||
string cacheScope = Path.Combine("public-profiles", profile.Make);
|
||||
|
||||
string publicProfileToLoad = ApplicationController.CacheablePath(cacheScope, publicDevice.CacheKey);
|
||||
|
||||
oemProfile = JsonConvert.DeserializeObject<PrinterSettings>(File.ReadAllText(publicProfileToLoad));
|
||||
oemProfile.ID = profile.ID;
|
||||
|
|
|
|||
|
|
@ -387,7 +387,12 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
|
|||
{
|
||||
string guid = Guid.NewGuid().ToString();
|
||||
|
||||
var newProfile = await LoadHttpOemProfile(make, model);
|
||||
var publicDevice = OemSettings.Instance.OemProfiles[make][model];
|
||||
|
||||
// TODO: jlewin - how can we handle lookup failures at this point? Should we throw and check for the exception?
|
||||
//if (publicDevice == null)
|
||||
|
||||
var newProfile = await LoadOemProfileAsync(publicDevice, make);
|
||||
newProfile.ID = guid;
|
||||
newProfile.DocumentVersion = PrinterSettings.LatestVersion;
|
||||
|
||||
|
|
@ -463,28 +468,31 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
|
|||
"Pink - Light",
|
||||
};
|
||||
|
||||
private async static Task<PrinterSettings> LoadHttpOemProfile(string make, string model)
|
||||
public async static Task<PrinterSettings> LoadOemProfileAsync(PublicDevice publicDevice, string make)
|
||||
{
|
||||
string deviceToken = OemSettings.Instance.OemProfiles[make][model];
|
||||
string cacheKey = deviceToken + ProfileManager.ProfileExtension;
|
||||
string cachePath = Path.Combine(ApplicationDataStorage.ApplicationUserDataPath, "data", "temp", "cache", "profiles", cacheKey);
|
||||
string cacheScope = Path.Combine("public-profiles", make);
|
||||
string cachePath = ApplicationController.CacheablePath(cacheScope, publicDevice.CacheKey);
|
||||
|
||||
return await ApplicationController.LoadCacheableAsync<PrinterSettings>(
|
||||
cacheKey,
|
||||
"profiles",
|
||||
publicDevice.CacheKey,
|
||||
cacheScope,
|
||||
async () =>
|
||||
{
|
||||
// The collector specifically returns null to ensure LoadCacheable skips writing the
|
||||
// result to the cache. After this result is returned, it will attempt to load from
|
||||
// the local cache if the collector yielded no result
|
||||
if(File.Exists(cachePath))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the cache file for the current deviceToken does not exist, attempt to download it
|
||||
return await ApplicationController.DownloadPublicProfileAsync(deviceToken);
|
||||
// If the cache file for the current deviceToken does not exist, attempt to download it.
|
||||
// An http 304 results in a null value and LoadCacheable will then load from the cache
|
||||
return await ApplicationController.DownloadPublicProfileAsync(publicDevice.ProfileToken);
|
||||
}
|
||||
},
|
||||
Path.Combine("Profiles",make, model + ProfileManager.ProfileExtension));
|
||||
Path.Combine("Profiles", make, make + ProfileManager.ProfileExtension));
|
||||
}
|
||||
|
||||
public void EnsurePrintersImported()
|
||||
|
|
|
|||
|
|
@ -457,13 +457,17 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
|
|||
ActiveSliceSettings.Instance.ID = newID;
|
||||
}
|
||||
|
||||
this.ID = newID;
|
||||
|
||||
// Ensure the local file with the old ID moves with the new ID change
|
||||
string existingProfile = ProfilePath;
|
||||
if (File.Exists(existingProfile))
|
||||
string existingProfilePath = ProfilePath;
|
||||
if (File.Exists(existingProfilePath))
|
||||
{
|
||||
File.Move(existingProfile, ProfilePath);
|
||||
// Profile ID change must come after existingProfilePath calculation and before ProfilePath getter
|
||||
this.ID = newID;
|
||||
File.Move(existingProfilePath, ProfilePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.ID = newID;
|
||||
}
|
||||
|
||||
if (File.Exists(ProfilePath))
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -57,17 +57,9 @@ namespace MatterControl.Tests.MatterControl
|
|||
|
||||
string make = OemSettings.Instance.OemProfiles.First().Key;
|
||||
string model = OemSettings.Instance.OemProfiles[make].First().Key;
|
||||
string deviceToken = OemSettings.Instance.OemProfiles[make][model];
|
||||
string cacheKey = deviceToken + ProfileManager.ProfileExtension;
|
||||
var publicDevice = OemSettings.Instance.OemProfiles[make][model];
|
||||
|
||||
string expectedProfilePath = Path.Combine(ApplicationDataStorage.ApplicationUserDataPath, "Profiles", cacheKey);
|
||||
if (File.Exists(expectedProfilePath))
|
||||
{
|
||||
File.Delete(expectedProfilePath);
|
||||
}
|
||||
|
||||
// Test will fail until mechanism can be created that exposes MHWebservices to vanilla MatterControl or until these tests are moved to MCCentral
|
||||
var recievedPrinterProfile = await ApplicationController.DownloadPublicProfileAsync(deviceToken);
|
||||
var recievedPrinterProfile = await ApplicationController.DownloadPublicProfileAsync(publicDevice.ProfileToken);
|
||||
|
||||
Assert.IsNotNull(recievedPrinterProfile);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue