using Active_Client.Browser_Tools.Models; using Active_Client.Browser_Tools.Models.Errors; using Active_Client.Browser_Tools.Models.Metadata; using Active_Client.View; using Chromium; using Chromium.Remote; using Chromium.Remote.Event; using Chromium.WebBrowser; using Client.Config; using Client.Config.SubModels; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.IO.Compression; using System.Linq; using System.Management; using System.Net.Http; using System.Text; using System.Threading; using System.Windows.Forms; using static Client.Utils.Constants; namespace Active_Client.Browser_Tools { public class BrowserJSObject : JSObject { private struct EditorVar { public CfrV8Value func; public CfrV8Context context; public string file; } // The first letter of All PUBLIC Variables and Methods must be Lower-Case (CEF Settings) private MainForm mainForm; private static readonly string[] _validExtensions = {".json", ".rcp", ".tpl" }; //private static readonly string[] _validExtensions = { "", ".txt", ".cnc", ".cn", ".cno", ".ini", ".mpf", ".spf", ".tap", ".anc", ".iso" }; private static readonly string[] _validImages = { ".svg" }; private static string jobPath = ""; private static Dictionary _editorOpened = new Dictionary(); private static EditorVar _currentEditorObject = new EditorVar(); public static string RECENT_FOLDER_KEY = "RECENT"; private const string THERMO_RECIPE_PATH = @"C:\CMS\Recipes"; private const string CMS_PATH = @"C:\CMS"; public static FileSystemWatcher watcher = null; public static DateTime _lastTimeFileWatcherEventRaised = DateTime.Now; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #region CONSTRUCTOR_METHOD // Constructor Method public BrowserJSObject(MainForm f) { mainForm = f; AddDynamicProperty("RECENT_FOLDER_KEY").PropertyGet += getProp; AddFunction("minimizeForm").Execute += minimizeForm; AddFunction("maximizeForm").Execute += maximizeForm; AddFunction("closeForm").Execute += closeForm; AddFunction("forceStepFocus").Execute += forceStepFocus; AddFunction("forceNcFocus").Execute += forceNcFocus; AddFunction("reloadBrokenPage").Execute += reloadBrokenPage; AddFunction("setNcWindowState").Execute += setNcWindowState; AddFunction("getNcWindowState").Execute += getNcWindowState; AddFunction("getScreenBase64").Execute += getScreenBase64; AddFunction("getChromiumVersion").Execute += getChromiumVersion; AddFunction("getClientID").Execute += getClientID; AddFunction("getConfiguredProcesses").Execute += getConfiguredProcesses; AddFunction("getConfiguredProcessesInMainMenu").Execute += getConfiguredProcessesInMainMenu; AddFunction("startNewProcess").Execute += startNewProcess; AddFunction("openOrStartProcess").Execute += openOrStartProcess; AddFunction("isVirtualKeybConfigured").Execute += isVirtualKeybConfigured; AddFunction("getOSdriveList").Execute += getOSdriveList; AddFunction("getAllRecipeDirectories").Execute += getAllRecipeDirectories; AddFunction("getFileList").Execute += getFileList; AddFunction("getProgramInfo").Execute += getProgramInfo; AddFunction("editProgram").Execute += editProgram; AddFunction("deleteFile").Execute += deleteFile; AddFunction("deleteFolder").Execute += deleteFolder; AddFunction("createFolder").Execute += createFolder; AddFunction("duplicateRecipe").Execute += duplicateRecipe; AddFunction("uploadAndActivateProgram").Execute += uploadAndActivateProgram; AddFunction("uploadAndAddToQueue").Execute += uploadAndAddToQueue; AddFunction("openJob").Execute += openJob; AddFunction("saveJob").Execute += saveJob; AddFunction("newJob").Execute += newJob; AddFunction("closeJob").Execute += closeJob; AddFunction("saveJobNewPath").Execute += saveJobNewPath; AddFunction("addImageToJob").Execute += addImageToJob; AddFunction("delImageFromJob").Execute += delImageFromJob; AddFunction("addPPToJob").Execute += addPPToJob; AddFunction("delPPFromJob").Execute += delPPFromJob; AddFunction("readJobMetadata").Execute += readJobMetadata; AddFunction("updateJobMetadata").Execute += updateJobMetadata; AddFunction("isHMIenabled").Execute += isHMIenabled; AddFunction("isPRODenabled").Execute += isPRODenabled; AddFunction("isSCMVisualStyle").Execute += isSCMVisualStyle; AddFunction("cleanFileWatcher").Execute += cleanFileWatcher; AddFunction("openExternalBrowser").Execute += openExternalBrowser; } #endregion CONSTRUCTOR_METHOD public void getProp(object sender, CfrV8AccessorGetEventArgs e) { e.Retval = RECENT_FOLDER_KEY; e.SetReturnValue(true); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #region FORM_BEHAVIOUR_METHODS // Minimize Main Window public void minimizeForm(object sender, CfrV8HandlerExecuteEventArgs e) { //Invoke method if is needed or call the method in STD mode if (mainForm.InvokeRequired) mainForm.Invoke((MethodInvoker)delegate () { mainForm.WindowState = FormWindowState.Minimized; }); else { mainForm.WindowState = FormWindowState.Minimized; } NcWindow.ShowTaskBar(); } // Maximize Main Window public void maximizeForm(object sender, CfrV8HandlerExecuteEventArgs e) { //Invoke method if is needed or call the method in STD mode if (mainForm.InvokeRequired) mainForm.Invoke((MethodInvoker)delegate () { mainForm.WindowState = FormWindowState.Maximized; }); else { mainForm.WindowState = FormWindowState.Maximized; } } // Close Main Window public void closeForm(object sender, CfrV8HandlerExecuteEventArgs e) { //If the mainform is disposed do nothing if (mainForm.IsDisposed) return; //Invoke method if is needed or call the method in STD mode if (mainForm.InvokeRequired) mainForm.Invoke((MethodInvoker)delegate () { mainForm.sendClose(); }); else { mainForm.sendClose(); } } // Reload Broken Page private void reloadBrokenPage(object sender, CfrV8HandlerExecuteEventArgs e) { //Invoke method if is needed or call the method in STD mode mainForm.reloadBrokenPage(); } #endregion FORM_BEHAVIOUR_METHODS /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #region NC_BEHAVIOUR_METHODS public void setNcWindowState(object sender, CfrV8HandlerExecuteEventArgs e) { if (e == null || e.Arguments == null || e.Arguments.Count() == 0) return; NcWindow.SetState((NcState)e.Arguments[0].IntValue); if (NcWindow.State == NcState.SHOW) mainForm.ShowNCWindow(); else if (NcWindow.State == NcState.SHOWPROD) mainForm.ShowProdWindow(); else mainForm.HideAUXWindow(); } public void getNcWindowState(object sender, CfrV8HandlerExecuteEventArgs e) { e.SetReturnValue((int)NcWindow.State); } public void getScreenBase64(object sender, CfrV8HandlerExecuteEventArgs e) { if (e.Arguments.Count() > 0 && e.Arguments[0].BoolValue) NcWindow.CaptureHMI(); e.SetReturnValue(NcWindow.NcCapture); } #endregion NC_BEHAVIOUR_METHODS /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #region CHROMIUM_METHODS // Get the Version of Chromium public void getChromiumVersion(object sender, CfrV8HandlerExecuteEventArgs e) { e.SetReturnValue(CfxRuntime.GetCefVersion()); } #endregion CHROMIUM_METHODS /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #region STEP_METHODS // Get the ID of STEP Client public void getClientID(object sender, CfrV8HandlerExecuteEventArgs e) { e.SetReturnValue((int)Config.ConnectionConfig.Id); } public void forceStepFocus(object sender, CfrV8HandlerExecuteEventArgs e) { NcWindow.ForceStepFocus(); } public void forceNcFocus(object sender, CfrV8HandlerExecuteEventArgs e) { //NcWindow.ForceNcRedraw(); NcWindow.ForceNcFocus(); mainForm.ShowNCWindow(); } public void forceProdFocus(object sender, CfrV8HandlerExecuteEventArgs e) { NcWindow.ForceProdFocus(); mainForm.ShowProdWindow(); } // Get the option of virtual Keyb configured private void isVirtualKeybConfigured(object sender, CfrV8HandlerExecuteEventArgs e) { e.SetReturnValue((bool)Config.ClientConfig.ShowVirtualKeyboard); } // Get the option of virtual Keyb configured private void isHMIenabled(object sender, CfrV8HandlerExecuteEventArgs e) { e.SetReturnValue((bool)Config.VendorHmiConfig.Enabled); } // Get the option of PROD Enabled private void isPRODenabled(object sender, CfrV8HandlerExecuteEventArgs e) { e.SetReturnValue((bool)Config.ProdSoftwareConfig.Enabled); } // Get the SCM option private void isSCMVisualStyle(object sender, CfrV8HandlerExecuteEventArgs e) { e.SetReturnValue((bool)Config.ClientConfig.IsSCM); } private void openExternalBrowser(object sender, CfrV8HandlerExecuteEventArgs e) { if (e.Arguments.Count() > 0) { Process.Start(e.Arguments[0].StringValue); } } #endregion STEP_METHODS /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #region PROCESSES_METHODS // Read all configured processes public void getConfiguredProcesses(object sender, CfrV8HandlerExecuteEventArgs e) { e.SetReturnValue(JsonConvert.SerializeObject(Config.ExtSoftwaresConfig.Where(X => X.inMainMenuBar == false))); } // Read all configured processes in main menu public void getConfiguredProcessesInMainMenu(object sender, CfrV8HandlerExecuteEventArgs e) { e.SetReturnValue(JsonConvert.SerializeObject(Config.ExtSoftwaresConfig.Where(X => X.inMainMenuBar == true))); } // Start a new process public void startNewProcess(object sender, CfrV8HandlerExecuteEventArgs e) { if (e.Arguments.Count() == 0) return; Thread t = new Thread(new ParameterizedThreadStart(OpenNew)); t.Start(e.Arguments[0].StringValue); } // Open the last window or Start a new process public void openOrStartProcess(object sender, CfrV8HandlerExecuteEventArgs e) { if (e.Arguments.Count() == 0) return; Thread t = new Thread(new ParameterizedThreadStart(OpenStartNew)); t.Start(e.Arguments[0].StringValue); } // Function used in Thread private void OpenStartNew(object id) { Software sft = Config.ExtSoftwaresConfig.FirstOrDefault(X => X.id == (string)id); if (sft != null && File.Exists(sft.path)) { Process[] p = Process.GetProcessesByName(Path.GetFileNameWithoutExtension(sft.path)).OrderByDescending(X => X.StartTime).ToArray(); if (p.Count() > 0 && p[0].MainWindowHandle != IntPtr.Zero) NcWindow.ForceExtFocus(p[0].MainWindowHandle, 0, 0, 0, 0); else { ProcessStartInfo PS = new ProcessStartInfo(sft.path, sft.arguments); PS.WorkingDirectory = new FileInfo(sft.path).Directory.FullName; Process.Start(PS); } } } // Function used in Thread private void OpenNew(object id) { Software sft = Config.ExtSoftwaresConfig.FirstOrDefault(X => X.id == (string)id); if (sft != null) { ProcessStartInfo PS = new ProcessStartInfo(sft.path, sft.arguments); PS.WorkingDirectory = new FileInfo(sft.path).Directory.FullName; Process.Start(PS); } } #endregion PROCESSES_METHODS /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #region FILESYSTEM_METHODS // Read all drives in Operating System public void getOSdriveList(object sender, CfrV8HandlerExecuteEventArgs e) { List drivelist = new List(); if (Directory.Exists(THERMO_RECIPE_PATH)) { drivelist.Add(new Drive() { Name = ElaborateName("Recipes", "", DriveType.Unknown), Path = THERMO_RECIPE_PATH + "\\", Type = "SPFO" }); } e.SetReturnValue(JsonConvert.SerializeObject(drivelist)); } public void getAllRecipeDirectories(object sender, CfrV8HandlerExecuteEventArgs e) { List dirs = this.DirSearch(THERMO_RECIPE_PATH); for (int i = 0; i< dirs.Count; i++) { dirs[i] = dirs[i].Remove(0,CMS_PATH.Length +1); } e.SetReturnValue(JsonConvert.SerializeObject(dirs)); } public void duplicateRecipe(object sender, CfrV8HandlerExecuteEventArgs e) { if (e.Arguments.Count() < 2) { e.SetReturnValue(JsonConvert.SerializeObject(new ErrorContainer("error_arguments_not_ok"))); return; } string oldFile = CMS_PATH + "\\" + e.Arguments[0].StringValue + ".rcp"; string newFile = CMS_PATH + "\\" + e.Arguments[1].StringValue + ".rcp"; string oldImage = CMS_PATH + "\\" + e.Arguments[0].StringValue + ".svg"; string newImage = CMS_PATH + "\\" + e.Arguments[1].StringValue + ".svg"; if (!File.Exists(oldFile)) { e.SetReturnValue(JsonConvert.SerializeObject(new ErrorContainer("file_not_found"))); return; } if (File.Exists(newFile)) { e.SetReturnValue(JsonConvert.SerializeObject(new ErrorContainer("file_already_exists"))); return; } try { File.Copy(oldFile, newFile, true); if (File.Exists(oldImage)) { File.Copy(oldImage, newImage, true); } } catch (Exception ex) { e.SetReturnValue(JsonConvert.SerializeObject(new ErrorContainer("cannot_copy_file"))); } } // Read all files in directory public void getFileList(object sender, CfrV8HandlerExecuteEventArgs e) { List filelist = new List(); if (e.Arguments.Count() == 0) { e.SetReturnValue(JsonConvert.SerializeObject(new ErrorContainer("error_arguments_not_ok"))); return; } string p = e.Arguments[0].StringValue; if (p != RECENT_FOLDER_KEY && !Directory.Exists(p)) { e.SetReturnValue(JsonConvert.SerializeObject(new ErrorContainer("file_not_exists"))); return; } try { if (p == RECENT_FOLDER_KEY) { filelist = GetLastUploadedFiles(); } else { // Add directories foreach (string item in Directory.GetDirectories(p)) { filelist.Add(new FileModel { Name = Path.GetFileName(item), AbsolutePath = Path.GetFullPath(item), Path = Path.GetFullPath(item), IsDirectory = true, FileExist = true, IsMain = false }); } // Add files foreach (string item in Directory.GetFiles(p)) { if (_validExtensions.Contains(Path.GetExtension(item).ToLower())) { bool isJob = JOB_EXTENSIONS.Contains(Path.GetExtension(item)); filelist.Add(new FileModel { Name = Path.GetFileName(item), AbsolutePath = Path.GetFullPath(item), Path = Path.GetFullPath(item), IsDirectory = false, IsJob = isJob, IsMain = false, FileExist = true }); } } } } catch { } e.SetReturnValue(JsonConvert.SerializeObject(filelist)); } public void deleteFile(object sender, CfrV8HandlerExecuteEventArgs e) { if (e.Arguments.Count() == 0) { e.SetReturnValue(JsonConvert.SerializeObject(new ErrorContainer("error_arguments_not_ok"))); return; } // Get path string p = e.Arguments[0].StringValue; FileAttributes attr = File.GetAttributes(p); if (!File.Exists(p) || attr.HasFlag(FileAttributes.Directory)) { e.SetReturnValue(JsonConvert.SerializeObject(new ErrorContainer("file_not_found"))); return; } if (attr.HasFlag(FileAttributes.ReadOnly)) { e.SetReturnValue(JsonConvert.SerializeObject(new ErrorContainer("file_not_editable"))); return; } try { File.Delete(p); string images = Path.ChangeExtension(p, "svg"); if(File.Exists(images)) { File.Delete(images); } } catch(Exception ex) { e.SetReturnValue(JsonConvert.SerializeObject(new ErrorContainer("cannot_delete_file"))); } } public void deleteFolder(object sender, CfrV8HandlerExecuteEventArgs e) { if (e.Arguments.Count() == 0) { e.SetReturnValue(JsonConvert.SerializeObject(new ErrorContainer("error_arguments_not_ok"))); return; } // Get path string p = e.Arguments[0].StringValue; FileAttributes attr = File.GetAttributes(p); if (!Directory.Exists(p) || !attr.HasFlag(FileAttributes.Directory)) { e.SetReturnValue(JsonConvert.SerializeObject(new ErrorContainer("directory_not_found"))); return; } if (attr.HasFlag(FileAttributes.ReadOnly)) { e.SetReturnValue(JsonConvert.SerializeObject(new ErrorContainer("directory_not_editable"))); return; } try { Directory.Delete(p,true); } catch (Exception ex) { e.SetReturnValue(JsonConvert.SerializeObject(new ErrorContainer("cannot_delete_directory"))); } } public void createFolder(object sender, CfrV8HandlerExecuteEventArgs e) { if (e.Arguments.Count() == 0) { e.SetReturnValue(JsonConvert.SerializeObject(new ErrorContainer("error_arguments_not_ok"))); return; } string path = e.Arguments[0].StringValue; if (Directory.Exists(path)) { e.SetReturnValue(JsonConvert.SerializeObject(new ErrorContainer("directory_already_exists"))); return; } try { Directory.CreateDirectory(path); } catch (Exception ex) { e.SetReturnValue(JsonConvert.SerializeObject(new ErrorContainer("cannot_delete_directory"))); } } // Upload and activate the program public async void uploadAndActivateProgram(object sender, CfrV8HandlerExecuteEventArgs e) { string fileToUpload = ""; byte[] filecontent = null, imagecontent = null; string fileNameNoExt; string imageName = ""; string fileName; string imageDirectory; string dirName; // Check the arguments numbers if (e.Arguments.Length < 2 || e.Arguments[0] == null || e.Arguments[1] == null) { e.SetReturnValue(UPLOAD_PAGE + ";INVALID_ARGUMENTS"); return; } // Check if the file exists fileToUpload = e.Arguments[0].StringValue; if (!File.Exists(fileToUpload)) { e.SetReturnValue(UPLOAD_PAGE + ";FILE_NOT_FOUND"); return; } // Check if must be uploaded all files bool uploadAllFiles = e.Arguments[1].BoolValue; // Check if recent files are selected bool recentDriveSelected = e.Arguments[2].BoolValue; // Get names and content of the file fileNameNoExt = Path.GetFileNameWithoutExtension(fileToUpload); fileName = Path.GetFileName(fileToUpload); filecontent = File.ReadAllBytes(fileToUpload); // Get all bytes of the image (if exists) imageDirectory = Path.GetDirectoryName(fileToUpload); foreach (string ext in _validImages) { if (File.Exists(imageDirectory + "/" + fileNameNoExt + ext)) { imageName = fileNameNoExt + ext; imagecontent = File.ReadAllBytes(imageDirectory + "/" + fileNameNoExt + ext); break; } } // Send all to the server using (HttpClient httpClient = new HttpClient()) { // Create the new FORM MultipartFormDataContent form = new MultipartFormDataContent { // Add the main program to the form { new ByteArrayContent(filecontent), "main", fileName } }; List files = GetFileToUpload(fileToUpload, uploadAllFiles, recentDriveSelected); //if (recentDriveSelected) //{ // List files = GetLastUploadedFiles(); // foreach(FileModel file in files) // { // if(file.FileExist && !file.IsMain) // form.Add(new ByteArrayContent(File.ReadAllBytes(file.AbsolutePath)), "file", file.Name); // } //} //else if (uploadAllFiles) //{ // // Load all the programs in the selected folder // dirName = Path.GetDirectoryName(fileToUpload); // string[] fileEntries = Directory.GetFiles(dirName); // foreach (string subfileName in fileEntries) // { // if (fileToUpload.ToLower() != subfileName.ToLower() && _validExtensions.Contains(Path.GetExtension(subfileName).ToLower())) // form.Add(new ByteArrayContent(File.ReadAllBytes(subfileName)), "file", Path.GetFileName(subfileName)); // } //} foreach (FileModel file in files) { if (!file.IsMain) form.Add(new ByteArrayContent(File.ReadAllBytes(file.AbsolutePath)), "file", Path.GetFileName(file.AbsolutePath)); } if (imagecontent != null) form.Add(new ByteArrayContent(imagecontent), "image", imageName); // Send them HttpResponseMessage response = httpClient .PostAsync("http://" + Config.ConnectionConfig.ServerUrl + ":" + Config.ConnectionConfig.ServerPort + "/" + UPLOAD_PAGE, form) .Result; WriteLastUploadedFile(files); // Wait the answer if (response.StatusCode == System.Net.HttpStatusCode.BadRequest) e.SetReturnValue(UPLOAD_PAGE + ";" + await response.Content.ReadAsStringAsync()); else if (response.StatusCode != System.Net.HttpStatusCode.OK) e.SetReturnValue(UPLOAD_PAGE + ";" + response.ReasonPhrase); else e.SetReturnValue(""); } } // Upload and add to queue public async void uploadAndAddToQueue(object sender, CfrV8HandlerExecuteEventArgs e) { string fileToUpload = ""; byte[] filecontent = null, imagecontent = null; string fileNameNoExt; string imageName = ""; string fileName; string imageDirectory; int reps = 0; // Check the arguments numbers if (e.Arguments.Length < 1 || e.Arguments[0] == null) { e.SetReturnValue(UPLOAD_ADD_QUEUE + "INVALID_ARGUMENTS"); return; } //Check if the file exists fileToUpload = e.Arguments[0].StringValue; reps = e.Arguments[1].IntValue; if (!File.Exists(fileToUpload)) { e.SetReturnValue(UPLOAD_ADD_QUEUE + ";FILE_NOT_FOUND"); return; } // Get names and content of the file fileNameNoExt = Path.GetFileNameWithoutExtension(fileToUpload); fileName = Path.GetFileName(fileToUpload); ; filecontent = File.ReadAllBytes(fileToUpload); // Get all bytes of the image (if exists) imageDirectory = Path.GetDirectoryName(fileToUpload); foreach (string ext in _validImages) { if (File.Exists(imageDirectory + "/" + fileNameNoExt + ext)) { imageName = fileNameNoExt + ext; imagecontent = File.ReadAllBytes(imageDirectory + "/" + fileNameNoExt + ext); break; } } // Send all to the server using (HttpClient httpClient = new HttpClient()) { //Create the new FORM MultipartFormDataContent form = new MultipartFormDataContent { //Add the content to the form { new ByteArrayContent(filecontent), "file", fileName } }; if (imagecontent != null) form.Add(new ByteArrayContent(imagecontent), "image", imageName); // Add reps to the form-data form.Add(new StringContent(reps.ToString()), "reps"); //Send them HttpResponseMessage response = httpClient .PostAsync("http://" + Config.ConnectionConfig.ServerUrl + ":" + Config.ConnectionConfig.ServerPort + "/" + UPLOAD_ADD_QUEUE, form) .Result; //Wait the answer if (response.StatusCode == System.Net.HttpStatusCode.BadRequest) e.SetReturnValue(UPLOAD_ADD_QUEUE + ";" + await response.Content.ReadAsStringAsync()); else if (response.StatusCode != System.Net.HttpStatusCode.OK) e.SetReturnValue(UPLOAD_ADD_QUEUE + ";" + response.ReasonPhrase); else e.SetReturnValue(""); } } // Read info of a file public void getProgramInfo(object sender, CfrV8HandlerExecuteEventArgs e) { string imagePath, imageDirectory; if (e.Arguments.Count() == 0) { e.SetReturnValue(JsonConvert.SerializeObject(new InfoFile())); return; } string p = e.Arguments[0].StringValue; if (!File.Exists(p)) { e.SetReturnValue(JsonConvert.SerializeObject(new InfoFile())); return; } FileInfo f = new FileInfo(p); InfoFile file = new InfoFile { Name = f.Name, CreationDate = f.CreationTime, LastModDate = f.LastAccessTime, AbsolutePath = p, CanEdit = !f.IsReadOnly }; imagePath = Path.GetFileNameWithoutExtension(p); imageDirectory = Path.GetDirectoryName(p); file.SheetX = ""; file.SheetY = ""; file.SheetZ = ""; file.Annotation = ""; try { dynamic content = JsonConvert.DeserializeObject(File.ReadAllText(p)); if(content != null && content.RecipeParameters != null) { if(content.RecipeParameters.general_sizes_sheet_dim_x != null) file.SheetX = content.RecipeParameters.general_sizes_sheet_dim_x; if (content.RecipeParameters.general_sizes_sheet_dim_y != null) file.SheetY = content.RecipeParameters.general_sizes_sheet_dim_y; if (content.RecipeParameters.general_sizes_sheet_thickness != null) file.SheetZ = content.RecipeParameters.general_sizes_sheet_thickness; if (content.recipeNotes != null) file.Annotation = content.recipeNotes; } foreach (string ext in _validImages) { if (File.Exists(imageDirectory + "/" + imagePath + ext)) { if (ext.ToLower().Equals(".svg")) file.PreviewBase64 = File.ReadAllText(imageDirectory + "/" + imagePath + ext); else file.PreviewBase64 = "data:image/" + ext + ";base64," + Convert.ToBase64String(File.ReadAllBytes(imageDirectory + "/" + imagePath + ext)); break; } } } catch (Exception ex) { } e.SetReturnValue(JsonConvert.SerializeObject(file)); } // Launch file editor public void editProgram(object sender, CfrV8HandlerExecuteEventArgs e) { if (e.Arguments.Count() < 2) { e.SetReturnValue(JsonConvert.SerializeObject(new ErrorContainer("error_arguments_not_ok"))); return; } // Get path string p = e.Arguments[0].StringValue; if (!File.Exists(p)) { e.SetReturnValue(JsonConvert.SerializeObject(new ErrorContainer("file_not_found"))); return; } // Check if editor exist if (!File.Exists(Config.TextEditorPath)) { e.SetReturnValue(JsonConvert.SerializeObject(new ErrorContainer("editor_not_configured"))); return; } _currentEditorObject = new EditorVar { context = CfrV8Context.GetCurrentContext(), func = e.Arguments[1], file = p }; Thread t = new Thread(startNewEditor); t.Start(); } public void startNewEditor() { Process proc = new Process { StartInfo = new ProcessStartInfo() { FileName = Config.TextEditorPath, Arguments = _currentEditorObject.file } }; // Start editor process proc.Start(); // Start watcher WatchFile(); } public void cleanFileWatcher(object sender, CfrV8HandlerExecuteEventArgs e) { if (watcher != null) { watcher.EnableRaisingEvents = false; watcher = null; } } public static void WatchFile() { if (watcher == null) { watcher = new FileSystemWatcher { // Watch for changes in LastWrite times NotifyFilter = NotifyFilters.LastWrite }; // Set event handler watcher.Changed += OnChanged; } // Set filter in order to watch only selected files watcher.Filter = Path.GetFileName(_currentEditorObject.file); // Set directory path watcher.Path = Path.GetDirectoryName(_currentEditorObject.file); // Add event handlers if (!watcher.EnableRaisingEvents) watcher.EnableRaisingEvents = true; } // Define the event handlers. private static void OnChanged(object source, FileSystemEventArgs e) { // FileSystemWatcher has a bug which fires twice the onChange event // Avoid duplicated events if (DateTime.Now.Subtract(_lastTimeFileWatcherEventRaised).TotalMilliseconds < 500) return; // Update last event time _lastTimeFileWatcherEventRaised = DateTime.Now; //// Call JS return function CallJSFunction(_currentEditorObject.func, null, _currentEditorObject.context); } private void WriteLastUploadedFile(List files) { StringBuilder stringBuilder = new StringBuilder(); bool isFirst = true; foreach (FileModel file in files) { string stringVal = ""; if (!file.IsMain) stringVal = file.AbsolutePath + ";false"; else stringVal = file.AbsolutePath + ";true"; if (!isFirst) stringVal = Environment.NewLine + stringVal; else isFirst = false; stringBuilder.Append(stringVal); } File.WriteAllLines(RECENT_FILE_PATH, stringBuilder.ToString() .Split( new[] { Environment.NewLine }, StringSplitOptions.None )); } private List GetFileToUpload(string main, bool uploadAllFiles, bool recentDriveSelected) { // Add main to list List files = new List() { new FileModel(){ AbsolutePath = main, Name = Path.GetFileName(main), Path = main, FileExist = File.Exists(main), IsDirectory = false, IsMain = true } }; // Check recent files if (recentDriveSelected) { List recentFiles = GetLastUploadedFiles(); foreach (FileModel file in recentFiles) { if (file.FileExist && !file.IsMain) files.Add(file); } } // Check if software need to upload all the files else if (uploadAllFiles) { string dirName = Path.GetDirectoryName(main); string[] fileEntries = Directory.GetFiles(dirName); foreach (string subfileName in fileEntries) { if (main.ToLower() != subfileName.ToLower() && _validExtensions.Contains(Path.GetExtension(subfileName).ToLower())) { // Add file files.Add(new FileModel() { AbsolutePath = subfileName, FileExist = true, IsDirectory = false, IsMain = false, Name = Path.GetFileName(subfileName), Path = subfileName }); } } } return files; } private List GetLastUploadedFiles() { if (!File.Exists(RECENT_FILE_PATH)) return new List(); string[] fileEntries = File.ReadAllLines(RECENT_FILE_PATH); List files = new List(); foreach (string row in fileEntries) { string[] rowData = row.Split(';'); files.Add(new FileModel { Name = Path.GetFileName(rowData[0]), AbsolutePath = Path.GetFullPath(rowData[0]), Path = Path.GetFullPath(rowData[0]), IsDirectory = false, IsMain = Convert.ToBoolean(rowData[1]), FileExist = File.Exists(rowData[0]) }); } return files; } private string ElaborateType(DriveType type) { switch (type) { case DriveType.Fixed: return "HD"; case DriveType.Removable: return "USB"; case DriveType.Network: return "NTW"; } return "SPFO"; } // Private functions private string ElaborateName(string name, string letter, DriveType type) { var retName = ""; if (!string.IsNullOrWhiteSpace(name)) retName = name; else { switch (type) { case DriveType.Fixed: retName = "Hard_Disk"; break; case DriveType.Removable: retName = "Usb_Disk"; break; case DriveType.Network: retName = "Netword_Disk"; break; default: retName = "Undefined"; break; } } if (!string.IsNullOrWhiteSpace(letter)) retName = retName + " (" + letter + ")"; return retName; } private List DirSearch(string sDir) { List files = new List(); try { files.Add(sDir); foreach (string d in Directory.GetDirectories(sDir)) { files.AddRange(DirSearch(d)); } } catch (System.Exception excpt) { MessageBox.Show(excpt.Message); } return files; } #endregion FILESYSTEM_METHODS /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #region RECALL_METHOD private static void CallJSFunction(CfrV8Value functionIstance, string arguments, CfrV8Context context) { //Create & enter function context var rpcContext = functionIstance.CreateRemoteCallContext(); rpcContext.Enter(); //Task to execute var task = new CfrTask(); task.Execute += (s, e) => { context.Enter(); var args = new CfrV8Value[] { arguments }; functionIstance.ExecuteFunction(null, args); //execute callback, nothing happens here context.Exit(); }; //Start it CfrTaskRunner.GetForThread(CfxThreadId.Renderer).PostTask(task); //Exit rpcContext.Exit(); } #endregion RECALL_METHOD /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #region JOB_METHODS // Read all the job data public void openJob(object sender, CfrV8HandlerExecuteEventArgs e) { JobToStep job = new JobToStep(); OpenFileDialog jobOpenFileDialog = new OpenFileDialog { Filter = "CMS Job Files(*.JOB,*.ZIP)|*.job;*.zip", Multiselect = false }; if (jobOpenFileDialog.ShowDialog() == DialogResult.OK) { // Check if zip is valid var zipIsValid = ValidateZip(jobOpenFileDialog.FileName); if (zipIsValid != null) { e.SetReturnValue(JsonConvert.SerializeObject(zipIsValid)); return; } if (!Directory.Exists(JOB_OPENING_PATH)) Directory.CreateDirectory(JOB_OPENING_PATH); ClearTempPath(); using (ZipArchive archive = ZipFile.OpenRead(jobOpenFileDialog.FileName)) { // Setup main Fields job.name = Path.GetFileName(jobOpenFileDialog.FileName); job.lastEditTimestamp = new FileInfo(jobOpenFileDialog.FileName).LastAccessTime; foreach (ZipArchiveEntry entry in archive.Entries) { // Get main program content if (entry.Name.Equals(JOB_MAIN_FILENAME, StringComparison.OrdinalIgnoreCase)) { using (var reader = new StreamReader(entry.Open())) { job.isoMainProgram = (reader.ReadToEnd()); } } // Add all images else if (_validImages.Contains(Path.GetExtension(entry.Name).ToLower())) { var bytes = default(byte[]); entry.ExtractToFile(JOB_OPENING_PATH + entry.Name, true); using (var memstream = new MemoryStream()) { entry.Open().CopyTo(memstream); bytes = memstream.ToArray(); job.metadata.generics.images.Add(new ImageParam() { name = Path.GetFileName(entry.Name), base64 = "data:image/" + Path.GetExtension(entry.Name).ToLower().TrimStart('.') + ";base64," + Convert.ToBase64String(bytes) }); } } // Metadata else if (entry.Name.Equals(JOB_METADATA_FILENAME, StringComparison.OrdinalIgnoreCase)) { MetadataToFile metasFromFile = new MetadataToFile(); using (var reader = new StreamReader(entry.Open())) { metasFromFile = JsonConvert.DeserializeObject(reader.ReadToEnd()); if (metasFromFile == null) { e.SetReturnValue(JsonConvert.SerializeObject(new ErrorContainer("error_corrupted_model"))); return; } else { job.metadata.generics.description = metasFromFile.description; job.metadata.generics.executionTime = metasFromFile.executionTime; job.metadata.tools = metasFromFile.tools; job.metadata.customs = metasFromFile.customs; } } } // All other files else { entry.ExtractToFile(JOB_OPENING_PATH + entry.Name, true); job.partPrograms.Add(new PPContainer(Path.GetFileName(entry.Name))); } } } jobPath = jobOpenFileDialog.FileName; e.SetReturnValue(JsonConvert.SerializeObject(job)); return; } else { e.SetReturnValue(null); return; } } public void readJobMetadata(object sender, CfrV8HandlerExecuteEventArgs e) { // Get file path string filePath = e.Arguments[0].StringValue; // Check if zip is valid var zipIsValid = ValidateZip(filePath); if (zipIsValid != null) { e.SetReturnValue(JsonConvert.SerializeObject(zipIsValid)); return; } // Open zip archive using (ZipArchive zipArchive = ZipFile.OpenRead(filePath)) { // Setup main Fields JobToStep jobData = new JobToStep() { name = Path.GetFileName(filePath), lastEditTimestamp = new FileInfo(filePath).LastAccessTime }; foreach (ZipArchiveEntry entry in zipArchive.Entries) { // Get images content without extract files if (_validImages.Contains(Path.GetExtension(entry.Name).ToLower())) { using (var memoryReader = new MemoryStream()) { entry.Open().CopyTo(memoryReader); jobData.metadata.generics.images.Add(new ImageParam() { name = Path.GetFileName(entry.Name), base64 = "data:image/" + Path.GetExtension(entry.Name).ToLower().TrimStart('.') + ";base64," + Convert.ToBase64String(memoryReader.ToArray()) }); } } // Metadata else if (entry.Name.Equals(JOB_METADATA_FILENAME, StringComparison.OrdinalIgnoreCase)) { MetadataToFile metasFromFile = new MetadataToFile(); using (var reader = new StreamReader(entry.Open())) { metasFromFile = JsonConvert.DeserializeObject(reader.ReadToEnd()); if (metasFromFile == null) { e.SetReturnValue(JsonConvert.SerializeObject(new ErrorContainer("error_corrupted_model"))); return; } else { jobData.metadata.generics.description = metasFromFile.description; jobData.metadata.generics.executionTime = metasFromFile.executionTime; jobData.metadata.tools = metasFromFile.tools; jobData.metadata.customs = metasFromFile.customs; } } } } e.SetReturnValue(JsonConvert.SerializeObject(jobData)); return; } } public void updateJobMetadata(object sender, CfrV8HandlerExecuteEventArgs e) { MetadataToFile metafile = new MetadataToFile(); // Deserialize job JobToStep job = JsonConvert.DeserializeObject(e.Arguments[1].StringValue); if (job == null) { e.SetReturnValue(JsonConvert.SerializeObject(new ErrorContainer("error_corrupted_model"))); return; } // Set meta data metafile.description = job.metadata.generics.description; metafile.executionTime = job.metadata.generics.executionTime; metafile.tools = job.metadata.tools; metafile.customs = job.metadata.customs; // Open zipArchive in update mode using (ZipArchive zipArchive = ZipFile.Open(e.Arguments[0].StringValue, ZipArchiveMode.Update)) { // Find metadata.json file var file = zipArchive.Entries.Where(x => x.FullName == JOB_METADATA_FILENAME).FirstOrDefault(); if (file == null) { e.SetReturnValue(JsonConvert.SerializeObject(new ErrorContainer("error_corrupted_model"))); return; } // Update metadata file using (StreamWriter streamWriter = new StreamWriter(file.Open())) { JsonSerializer serializer = new JsonSerializer { Formatting = Formatting.Indented }; // Write serializer.Serialize(streamWriter, metafile); } } } // Create job data public void newJob(object sender, CfrV8HandlerExecuteEventArgs e) { JobToStep job = new JobToStep(); if (!Directory.Exists(JOB_OPENING_PATH)) Directory.CreateDirectory(JOB_OPENING_PATH); ClearTempPath(); job.name = "newjob_" + DateTime.Now.ToFileTime() + ".job"; jobPath = ""; e.SetReturnValue(JsonConvert.SerializeObject(job)); return; } // close job public void closeJob(object sender, CfrV8HandlerExecuteEventArgs e) { if (!Directory.Exists(JOB_OPENING_PATH)) Directory.CreateDirectory(JOB_OPENING_PATH); ClearTempPath(); jobPath = ""; e.SetReturnValue(null); return; } // Save all job public void saveJobNewPath(object sender, CfrV8HandlerExecuteEventArgs e) { MetadataToFile metafile = new MetadataToFile(); //check the arguments if (e.Arguments.Count() == 0) return; //Call Save Dialog SaveFileDialog jobSaveFileDialog = new SaveFileDialog(); jobSaveFileDialog.Filter = "CMS Job Files(*.JOB)|*.job|Zip Files(*.ZIP)|*.zip"; if (jobSaveFileDialog.ShowDialog() == DialogResult.OK) { // Job deserialize JobToStep job = JsonConvert.DeserializeObject(e.Arguments[0].StringValue); if (job == null) { e.SetReturnValue(JsonConvert.SerializeObject(new ErrorContainer("error_corrupted_model"))); return; } //Metadata metafile.description = job.metadata.generics.description; metafile.executionTime = job.metadata.generics.executionTime; metafile.tools = job.metadata.tools; metafile.customs = job.metadata.customs; using (StreamWriter file = File.CreateText(JOB_OPENING_PATH + JOB_METADATA_FILENAME)) { JsonSerializer serializer = new JsonSerializer { Formatting = Formatting.Indented }; serializer.Serialize(file, metafile); } //Main Program File.WriteAllText(JOB_OPENING_PATH + JOB_MAIN_FILENAME, job.isoMainProgram); //delete Zip File if exists if (File.Exists(jobSaveFileDialog.FileName)) File.Delete(jobSaveFileDialog.FileName); //Create Zip File ZipFile.CreateFromDirectory(JOB_OPENING_PATH, jobSaveFileDialog.FileName); jobPath = jobSaveFileDialog.FileName; job.name = jobPath; e.SetReturnValue(JsonConvert.SerializeObject(job)); return; } e.SetReturnValue(null); return; } // Save all job public void saveJob(object sender, CfrV8HandlerExecuteEventArgs e) { MetadataToFile metafile = new MetadataToFile(); SaveFileDialog jobSaveFileDialog = new SaveFileDialog(); jobSaveFileDialog.Filter = "CMS Job Files(*.JOB)|*.job|Zip Files(*.ZIP)|*.zip"; // Job deserialize JobToStep job = JsonConvert.DeserializeObject(e.Arguments[0].StringValue); if (job == null) { e.SetReturnValue(JsonConvert.SerializeObject(new ErrorContainer("error_corrupted_model"))); return; } //check the arguments if (e.Arguments.Count() == 0) return; if (string.IsNullOrEmpty(jobPath)) { jobSaveFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); jobSaveFileDialog.FileName = job.name; if (jobSaveFileDialog.ShowDialog() == DialogResult.OK) { jobPath = jobSaveFileDialog.FileName; } else { e.SetReturnValue(null); return; } } if (!string.IsNullOrEmpty(jobPath)) { //Metadata metafile.description = job.metadata.generics.description; metafile.executionTime = job.metadata.generics.executionTime; metafile.tools = job.metadata.tools; metafile.customs = job.metadata.customs; using (StreamWriter file = File.CreateText(JOB_OPENING_PATH + JOB_METADATA_FILENAME)) { JsonSerializer serializer = new JsonSerializer { Formatting = Formatting.Indented }; serializer.Serialize(file, metafile); } //Main Program File.WriteAllText(JOB_OPENING_PATH + JOB_MAIN_FILENAME, job.isoMainProgram); //delete Zip File if exists if (File.Exists(jobPath)) File.Delete(jobPath); //Create Zip File try { ZipFile.CreateFromDirectory(JOB_OPENING_PATH, jobPath); } catch (Exception ex) { e.SetReturnValue(JsonConvert.SerializeObject(new ErrorContainer("error_save_file"))); return; } e.SetReturnValue(JsonConvert.SerializeObject(job)); return; } e.SetReturnValue(null); return; } // Add an image public void addImageToJob(object sender, CfrV8HandlerExecuteEventArgs e) { OpenFileDialog imageOpenFileDialog = new OpenFileDialog(); imageOpenFileDialog.Filter = "Images Files(*.JPG,*.JPEG,*.PNG)|*.jpg;*.jpeg;*.png"; imageOpenFileDialog.Multiselect = false; if (imageOpenFileDialog.ShowDialog() == DialogResult.OK) { string newImagePath = JOB_OPENING_PATH + Path.GetFileName(imageOpenFileDialog.FileName); //If exixts send error if (File.Exists(newImagePath)) { e.SetReturnValue(JsonConvert.SerializeObject(new ErrorContainer("file_esists"))); return; } //Copy the file File.Copy(imageOpenFileDialog.FileName, newImagePath); //Send to Step e.SetReturnValue(JsonConvert.SerializeObject(new ImageParam() { name = Path.GetFileName(imageOpenFileDialog.FileName), base64 = "data:image/" + Path.GetExtension(newImagePath).ToLower().TrimStart('.') + ";base64," + Convert.ToBase64String(File.ReadAllBytes(newImagePath)) })); return; } e.SetReturnValue(null); return; } // Delete an image public void delImageFromJob(object sender, CfrV8HandlerExecuteEventArgs e) { //check the arguments if (e.Arguments.Count() == 0 && e.Arguments[0].IsString) return; //Get the file Path string imagePath = JOB_OPENING_PATH + e.Arguments[0].StringValue; //If not exixts Error! if (!File.Exists(imagePath)) { e.SetReturnValue(JsonConvert.SerializeObject(new ErrorContainer("file_not_esists"))); return; } //delete it File.Delete(imagePath); e.SetReturnValue(null); return; } // Add a Part-Program public void addPPToJob(object sender, CfrV8HandlerExecuteEventArgs e) { OpenFileDialog PPOpenFileDialog = new OpenFileDialog(); PPOpenFileDialog.Multiselect = false; if (PPOpenFileDialog.ShowDialog() == DialogResult.OK) { //Check the extension if (!_validExtensions.Contains(Path.GetExtension(PPOpenFileDialog.FileName).ToLower())) { e.SetReturnValue(JsonConvert.SerializeObject(new ErrorContainer("ext_not_available"))); return; } string newPPPath = JOB_OPENING_PATH + Path.GetFileName(PPOpenFileDialog.FileName); //If exixts delete old file and save the new one if (File.Exists(newPPPath)) { e.SetReturnValue(JsonConvert.SerializeObject(new ErrorContainer("file_esists"))); return; } //Copy the file File.Copy(PPOpenFileDialog.FileName, newPPPath); //Send to Step e.SetReturnValue(JsonConvert.SerializeObject(new PPContainer(Path.GetFileName(PPOpenFileDialog.FileName)))); return; } e.SetReturnValue(null); return; } // Delete an image public void delPPFromJob(object sender, CfrV8HandlerExecuteEventArgs e) { //check the arguments if (e.Arguments.Count() == 0 && e.Arguments[0].IsString) return; //Get the file Path string ppPath = JOB_OPENING_PATH + e.Arguments[0].StringValue; //If not exixts Error! if (!File.Exists(ppPath)) { e.SetReturnValue(JsonConvert.SerializeObject(new ErrorContainer("file_not_esists"))); return; } //delete it File.Delete(ppPath); e.SetReturnValue(null); return; } // Clear the temp folder files private void ClearTempPath() { DirectoryInfo di = new DirectoryInfo(JOB_OPENING_PATH); foreach (FileInfo file in di.GetFiles()) file.Delete(); foreach (DirectoryInfo dir in di.GetDirectories()) dir.Delete(true); } // Clear the temp folder files private string GetExtensionFromBase64(string base64img) { base64img = base64img.Remove(0, "data:image/".Length); return base64img.Substring(0, base64img.IndexOf(";base64,")); } //Clear the temp folder files private string GetContentFromBase64(string base64img) { return base64img.Substring(base64img.IndexOf(";base64,") + ";base64,".Length); } private static ErrorContainer ValidateZip(string filePath) { ErrorContainer result = null; if (!File.Exists(filePath)) return new ErrorContainer("error_file_not_found"); try { using (var archive = ZipFile.OpenRead(filePath)) { List files = archive.Entries.Where(x => x.FullName == JOB_MAIN_FILENAME || x.FullName == JOB_METADATA_FILENAME).ToList(); if (files.Count() < 2) return new ErrorContainer("error_job_not_valid"); else result = null; } } catch (Exception) { result = new ErrorContainer("error_job_not_valid"); } return result; } #endregion JOB_METHODS } }