Esempio n. 1
0
        public static async Task <bool> LoadAsync()
        {
            await semaphoreSlim.WaitAsync();

            using var Trace = new Trace();  //This c# 8.0 using feature will auto dispose when the function is done.

            bool Ret = false;

            try
            {
                //////multiple threads may be trying to save at the same time
                ////lock (ThreadLock)
                //{
                Settings.SettingsValid = false;  //assume failure
                bool Resave = false;

                UpdateSettingsLocation();  //save to \settings folder or appdata\settings

                //get backup json from registry

                AppSettings.LastSettingsJSON = Global.GetSetting("BackupSettingsJSON", "");

                bool IsSettingsFileValid = await IsFileValidAsync(AppSettings.Settings.SettingsFileName);

                bool IsSettingsBakFileValid = await IsFileValidAsync(AppSettings.Settings.SettingsFileName + ".bak");

                //read the old configuration file
                if (!IsSettingsFileValid && !IsSettingsBakFileValid && string.IsNullOrEmpty(AppSettings.LastSettingsJSON))
                {
                    //--------------------------------------------------------------------------------------------------------------------
                    //try to read in OLD aitool.exe.config or user.config files - they were
                    //unreliable because of strict versioning, etc
                    //
                    // NO NEED to add NEW settings to this area
                    //--------------------------------------------------------------------------------------------------------------------

                    List <FileInfo> filist = new List <FileInfo>();
                    FileInfo        fi     = new FileInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Path.GetFileName(Assembly.GetEntryAssembly().Location) + ".config"));
                    if (fi.Exists)
                    {
                        filist.Add(fi);
                    }
                    filist.AddRange(Global.GetFiles(Path.Combine(Environment.GetEnvironmentVariable("LOCALAPPDATA"), "WindowsFormsApp2"), "user.config"));
                    //sort by date
                    filist = filist.OrderByDescending((d) => d.LastWriteTime).ToList();

                    Log("First time load, reading old config file: " + filist[0].FullName);

                    XDocument xmlfile = XDocument.Load(filist[0].FullName);
                    //<configuration>
                    //    <userSettings>
                    //        <WindowsFormsApp2.Properties.Settings>
                    //            <setting name="telegram_token" serializeAs="String">
                    //                <value />
                    //            </setting>
                    //            <setting name="telegram_chatid" serializeAs="String">
                    //                <value />
                    //            </setting>
                    //            <setting name="input_path" serializeAs="String">
                    //                <value>D:\BlueIrisStorage\AIInput</value>
                    //            </setting>

                    IEnumerable <XElement> els = xmlfile.XPathSelectElements("/configuration/userSettings/WindowsFormsApp2.Properties.Settings/setting");
                    if (els == null || els.Count() == 0)
                    {
                        els = xmlfile.XPathSelectElements("/configuration/applicationSettings/WindowsFormsApp2.Properties.Settings/setting");
                    }

                    int cnt = 0;
                    foreach (XElement el in els)
                    {
                        string val = el.Value;
                        if (!string.IsNullOrEmpty(val))
                        {
                            if (el.ToString().Contains("telegram_token"))
                            {
                                Settings.telegram_token = val; cnt += 1;
                            }
                            if (el.ToString().Contains("telegram_chatids"))
                            {
                                Settings.telegram_chatids = Global.Split(val, ","); cnt += 1;
                            }
                            if (el.ToString().Contains("input_path"))
                            {
                                Settings.input_path = val; cnt += 1;
                            }
                            if (el.ToString().Contains("deepstack_url"))
                            {
                                Settings.deepstack_url = val; cnt += 1;
                            }
                            if (el.ToString().Contains("log_everything"))
                            {
                                Settings.log_everything = Convert.ToBoolean(val); cnt += 1;
                            }
                            if (el.ToString().Contains("send_errors"))
                            {
                                Settings.send_telegram_errors = Convert.ToBoolean(val); cnt += 1;
                            }
                            if (el.ToString().Contains("close_instantly"))
                            {
                                Settings.close_instantly = Convert.ToInt32(val); cnt += 1;
                            }
                        }
                    }

                    Resave = (cnt > 0);
                    Settings.SettingsValid = true;
                }
                else if (IsSettingsFileValid)
                {
                    //Load regular settings file
                    Log("Debug: Loading settings from " + AppSettings.Settings.SettingsFileName);
                    Settings = Global.ReadFromJsonFile <ClsSettings>(AppSettings.Settings.SettingsFileName);
                }
                else if (IsSettingsBakFileValid)
                {
                    //revert to backup if its good
                    Log("Error: Reverting to backup settings file: " + AppSettings.Settings.SettingsFileName + ".bak");
                    Log("Loading settings from " + AppSettings.Settings.SettingsFileName + ".bak");
                    Settings = Global.ReadFromJsonFile <ClsSettings>(AppSettings.Settings.SettingsFileName + ".bak");
                }
                else if (!string.IsNullOrEmpty(AppSettings.LastSettingsJSON) && !File.Exists(AppSettings.Settings.SettingsFileName))
                {
                    //revert to REGISTRY backup if its good AND the main settings file doesnt exist at all (so someone can delete the settings file to reset settings)
                    Log("Error: Reverting to REGISTRY backup settings...");
                    Settings = Global.SetJSONString <ClsSettings>(AppSettings.LastSettingsJSON);
                }
                else
                {
                    //nothing valid
                    Log("Error: Settings file AND backup were missing or corrupt.");

                    if (File.Exists(AppSettings.Settings.SettingsFileName))
                    {
                        File.Delete(AppSettings.Settings.SettingsFileName);
                    }

                    if (File.Exists(AppSettings.Settings.SettingsFileName + ".bak"))
                    {
                        File.Delete(AppSettings.Settings.SettingsFileName + ".bak");
                    }
                }

                if (Settings != null)
                {
                    if (Settings.telegram_cooldown_minutes > -1)
                    {
                        Settings.telegram_cooldown_seconds = Convert.ToInt32(Math.Round(TimeSpan.FromMinutes(Settings.telegram_cooldown_minutes).TotalSeconds, 0));
                        Settings.telegram_cooldown_minutes = -1;
                    }

                    UpdateSettingsLocation();  //save to \settings folder or appdata\settings

                    //Ive had a case where MaskManager was null/corrupt to double check:
                    foreach (Camera cam in Settings.CameraList)
                    {
                        if (string.IsNullOrEmpty(cam.BICamName))
                        {
                            //if (!string.IsNullOrEmpty(cam.Prefix) && !cam.Prefix.Contains("*"))
                            //    cam.BICamName = cam.Prefix.Trim(".-".ToCharArray());
                            //else
                            cam.BICamName = cam.Name;
                        }

                        if (string.IsNullOrEmpty(cam.MaskFileName))
                        {
                            cam.MaskFileName = $"{cam.Name}.bmp";
                        }

                        if (cam.ImageResolutions.Count == 0)
                        {
                            cam.ScanImages(10, 500, -1);//run a quick scan to get resolutions
                        }
                        if (cam.cooldown_time > -1)
                        {
                            cam.cooldown_time_seconds = Convert.ToInt32(Math.Round(TimeSpan.FromMinutes(cam.cooldown_time).TotalSeconds, 0));
                            cam.cooldown_time         = -1;
                        }

                        if (cam.maskManager == null)
                        {
                            cam.maskManager = new MaskManager();
                            Log("Warning: Had to reset MaskManager for camera " + cam.Name);
                        }

                        //update threshold in all masks if changed during session
                        cam.maskManager.Update(cam);

                        ///this was an old setting we dont want to use any longer, but pull it over if someone enabled it before
                        if (cam.trigger_url_cancels && !string.IsNullOrWhiteSpace(cam.cancel_urls_as_string))
                        {
                            cam.cancel_urls_as_string = cam.trigger_urls_as_string;
                            cam.trigger_url_cancels   = false;
                        }

                        cam.trigger_urls = Global.Split(cam.trigger_urls_as_string, "\r\n|;,").ToArray();
                        cam.cancel_urls  = Global.Split(cam.cancel_urls_as_string, "\r\n|;,").ToArray();

                        if (cam.Action_image_copy_enabled &&
                            !string.IsNullOrWhiteSpace(cam.Action_network_folder) &&
                            cam.Action_network_folder_purge_older_than_days > 0 &&
                            LastJPGCleanDay != DateTime.Now.DayOfYear &&
                            Directory.Exists(cam.Action_network_folder))
                        {
                            Log($"Debug: Cleaning out jpg files older than '{cam.Action_network_folder_purge_older_than_days}' days in '{cam.Action_network_folder}'...");

                            List <FileInfo> filist  = new List <FileInfo>(Global.GetFiles(cam.Action_network_folder, "*.jpg"));
                            int             deleted = 0;
                            int             errs    = 0;
                            foreach (FileInfo fi in filist)
                            {
                                if ((DateTime.Now - fi.LastWriteTime).TotalDays > cam.Action_network_folder_purge_older_than_days)
                                {
                                    try { fi.Delete(); deleted++; }
                                    catch { errs++; }
                                }
                            }
                            if (errs == 0)
                            {
                                Log($"Debug: ...Deleted {deleted} out of {filist.Count} files");
                            }
                            else
                            {
                                Log($"Debug: ...Deleted {deleted} out of {filist.Count} files with {errs} errors.");
                            }

                            LastJPGCleanDay = DateTime.Now.DayOfYear;
                        }
                    }

                    //load cameras the old way if needed
                    if (Settings.CameraList.Count == 0)
                    {
                        string camerafolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "cameras");
                        Log("No cameras loaded in settings, trying to load old camera files from " + camerafolder);
                        List <FileInfo> files = Global.GetFiles(camerafolder, "*.txt"); //load all settings files in a string array
                                                                                        //Sort so more recent files are processed first - to make sure any dupes that are skipped are older
                                                                                        //I *think* this logic works?
                        files = files.OrderByDescending((d) => d.LastWriteTime).ToList();
                        //create a camera object for every camera settings file
                        int cnt = 0;
                        foreach (FileInfo file in files)
                        {
                            //check if camera with specified name or its prefix already exists. If yes, then abort.
                            bool fnd = false;
                            foreach (Camera c in AppSettings.Settings.CameraList)
                            {
                                if (string.Equals(c.Name, Path.GetFileNameWithoutExtension(file.FullName), StringComparison.OrdinalIgnoreCase))
                                {
                                    fnd = true;
                                }
                                else if (string.Equals(c.Prefix, System.IO.File.ReadAllLines(file.FullName)[2].Split('"')[1], StringComparison.OrdinalIgnoreCase))
                                {
                                    fnd = true;
                                }
                            }
                            if (!fnd)
                            {
                                cnt++;
                                Camera cam = new Camera();                //create new camera object
                                cam.ReadConfig(file.FullName);            //read camera's config from file
                                AppSettings.Settings.CameraList.Add(cam); //add created camera object to CameraList
                            }
                            else
                            {
                                Log("Skipped duplicate camera: " + file);
                            }
                        }

                        if (cnt > 0)
                        {
                            Log($"...Loaded {cnt} camera files.");
                        }
                        else
                        {
                            Log($"...NO old camera txt files could be loaded.");
                        }

                        Resave = (cnt > 1);
                    }

                    //sort the camera list:
                    AppSettings.Settings.CameraList = AppSettings.Settings.CameraList.OrderBy((d) => d.Name).ToList();

                    AITOOL.UpdateAIURLList(true);

                    //clean up image adjust list
                    List <ClsImageAdjust> iaps = AppSettings.Settings.ImageAdjustProfiles;

                    AppSettings.Settings.ImageAdjustProfiles.Clear();

                    for (int i = 0; i < iaps.Count; i++)
                    {
                        if (!AppSettings.Settings.ImageAdjustProfiles.Contains(iaps[i]))
                        {
                            Settings.ImageAdjustProfiles.Add(iaps[i]);
                        }
                    }

                    for (int i = 0; i < AppSettings.Settings.AIURLList.Count; i++)
                    {
                        AppSettings.Settings.AIURLList[i].Order = i + 1;
                        if (!AITOOL.HasImageAdjustProfile(AppSettings.Settings.AIURLList[i].ImageAdjustProfile))
                        {
                            AppSettings.Settings.AIURLList[i].ImageAdjustProfile = "Default";
                        }
                    }

                    Ret = true;
                }
                else
                {
                    Log("Error: Could not load settings?");
                }

                if (Resave)
                {
                    //we imported old settings, save them
                    SaveAsync();
                }

                //}
            }
            catch (Exception ex)
            {
                Log("Error: Could not save settings: " + Global.ExMsg(ex));
            }
            finally
            {
                semaphoreSlim.Release();
            }


            return(Ret);
        }
Esempio n. 2
0
        public static async Task <bool> LoadAsync()
        {
            await semaphoreSlim.WaitAsync();

            using var Trace = new Trace();  //This c# 8.0 using feature will auto dispose when the function is done.

            bool Ret = false;

            try
            {
                //////multiple threads may be trying to save at the same time
                ////lock (ThreadLock)
                //{
                Settings.SettingsValid = false;  //assume failure
                bool Resave = false;

                UpdateSettingsLocation();  //save to \settings folder or appdata\settings

                //get backup json from registry

                AppSettings.LastSettingsJSON = Global.GetRegSetting("BackupSettingsJSON", "");

                bool IsSettingsFileValid = await IsFileValidAsync(AppSettings.Settings.SettingsFileName);

                bool SettingsFileExists     = File.Exists(AppSettings.Settings.SettingsFileName);
                bool IsSettingsBakFileValid = await IsFileValidAsync(AppSettings.Settings.SettingsFileName + ".bak");

                string LastRunPath        = Global.GetRegSetting("LastRunPath", "");
                string LastSettingsFile   = "";
                string LastSettingsFolder = "";

                if (!LastRunPath.IsEmpty() && !Directory.GetCurrentDirectory().EqualsIgnoreCase(LastRunPath) && Directory.Exists(LastRunPath))
                {
                    LastSettingsFolder = Path.Combine(LastRunPath, "_SETTINGS");
                    LastSettingsFile   = Path.Combine(LastSettingsFolder, "AITOOL.Settings.JSON");
                    if (!File.Exists(LastSettingsFile))
                    {
                        LastSettingsFile   = "";
                        LastSettingsFolder = "";
                    }
                }
                //read the old configuration file
                if (!IsSettingsFileValid && !IsSettingsBakFileValid && string.IsNullOrEmpty(AppSettings.LastSettingsJSON))
                {
                    //--------------------------------------------------------------------------------------------------------------------
                    //try to read in OLD aitool.exe.config or user.config files - they were
                    //unreliable because of strict versioning, etc
                    //
                    // NO NEED to add NEW settings to this area
                    //--------------------------------------------------------------------------------------------------------------------

                    List <FileInfo> filist = new List <FileInfo>();
                    FileInfo        fi     = new FileInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Path.GetFileName(Assembly.GetEntryAssembly().Location) + ".config"));
                    if (fi.Exists)
                    {
                        filist.Add(fi);
                    }
                    filist.AddRange(Global.GetFiles(Path.Combine(Environment.GetEnvironmentVariable("LOCALAPPDATA"), "WindowsFormsApp2"), "user.config"));
                    //sort by date
                    filist = filist.OrderByDescending((d) => d.LastWriteTime).ToList();

                    Log("First time load, reading old config file: " + filist[0].FullName);

                    XDocument xmlfile = XDocument.Load(filist[0].FullName);
                    //<configuration>
                    //    <userSettings>
                    //        <WindowsFormsApp2.Properties.Settings>
                    //            <setting name="telegram_token" serializeAs="String">
                    //                <value />
                    //            </setting>
                    //            <setting name="telegram_chatid" serializeAs="String">
                    //                <value />
                    //            </setting>
                    //            <setting name="input_path" serializeAs="String">
                    //                <value>D:\BlueIrisStorage\AIInput</value>
                    //            </setting>

                    IEnumerable <XElement> els = xmlfile.XPathSelectElements("/configuration/userSettings/WindowsFormsApp2.Properties.Settings/setting");
                    if (els == null || els.Count() == 0)
                    {
                        els = xmlfile.XPathSelectElements("/configuration/applicationSettings/WindowsFormsApp2.Properties.Settings/setting");
                    }

                    int cnt = 0;
                    foreach (XElement el in els)
                    {
                        string val = el.Value;
                        if (!string.IsNullOrEmpty(val))
                        {
                            if (el.ToString().Contains("telegram_token"))
                            {
                                Settings.telegram_token = val; cnt += 1;
                            }
                            if (el.ToString().Contains("telegram_chatids"))
                            {
                                Settings.telegram_chatids = val.SplitStr(","); cnt += 1;
                            }
                            if (el.ToString().Contains("input_path"))
                            {
                                Settings.input_path = val; cnt += 1;
                            }
                            if (el.ToString().Contains("deepstack_url"))
                            {
                                Settings.deepstack_url = val; cnt += 1;
                            }
                            if (el.ToString().Contains("log_everything"))
                            {
                                Settings.log_everything = Convert.ToBoolean(val); cnt += 1;
                            }
                            if (el.ToString().Contains("send_errors"))
                            {
                                Settings.send_telegram_errors = Convert.ToBoolean(val); cnt += 1;
                            }
                            if (el.ToString().Contains("close_instantly"))
                            {
                                Settings.close_instantly = Convert.ToInt32(val); cnt += 1;
                            }
                        }
                    }

                    Resave = (cnt > 0);
                    Settings.SettingsValid = true;
                }
                else if (IsSettingsFileValid)
                {
                    //Load regular settings file
                    Log("Debug: Loading settings from " + AppSettings.Settings.SettingsFileName);
                    Settings = Global.ReadFromJsonFile <ClsSettings>(AppSettings.Settings.SettingsFileName);
                }
                else if (IsSettingsBakFileValid)
                {
                    //revert to backup if its good
                    Log("Error: Reverting to backup settings file: " + AppSettings.Settings.SettingsFileName + ".bak");
                    Log("Loading settings from " + AppSettings.Settings.SettingsFileName + ".bak");
                    Settings = Global.ReadFromJsonFile <ClsSettings>(AppSettings.Settings.SettingsFileName + ".bak");
                }
                else if (!string.IsNullOrEmpty(AppSettings.LastSettingsJSON) && SettingsFileExists)
                {
                    //revert to REGISTRY backup if its good AND the main settings file doesnt exist at all (so someone can delete the settings file to reset settings)
                    Log("Error: Reverting to REGISTRY backup settings...");
                    Settings = Global.SetJSONString <ClsSettings>(AppSettings.LastSettingsJSON);
                }
                else if (!LastSettingsFile.IsEmpty() && !SettingsFileExists && !Global.IsService)
                {
                    //revert to REGISTRY backup and look for the last folder to migrate settings from
                    string newfolder = Path.GetDirectoryName(Settings.SettingsFileName);
                    Log($"Debug: Previous settings found at {LastSettingsFolder} but not {newfolder}...");
                    if (System.Windows.Forms.MessageBox.Show($"Would you like to migrate settings from the last folder?\r\n\r\n{LastSettingsFolder}", "Migrate Settings?", System.Windows.Forms.MessageBoxButtons.YesNo, System.Windows.Forms.MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
                    {
                        //copy the old settings folder:
                        Log($"Debug: Copying settings folder from original '{LastSettingsFolder}' to '{newfolder}'...");
                        Global.MoveFiles(LastSettingsFolder, newfolder, "*.*", true, true);
                        Log("Debug: Loading settings from " + AppSettings.Settings.SettingsFileName);
                        Settings = Global.ReadFromJsonFile <ClsSettings>(AppSettings.Settings.SettingsFileName);
                    }
                    else
                    {
                        Log("Debug: Did NOT import settings from folder.");
                    }
                }
                else if (!AppSettings.LastSettingsJSON.IsEmpty() && !SettingsFileExists && !Global.IsService)
                {
                    //revert to REGISTRY backup and look for the last folder to migrate settings from
                    string newfolder = Path.GetDirectoryName(Settings.SettingsFileName);
                    Log($"Debug: Previous settings found in the registry but not {newfolder}...");
                    if (System.Windows.Forms.MessageBox.Show($"Would you like to migrate settings from the last saved REGISTRY copy?", "Migrate Settings?", System.Windows.Forms.MessageBoxButtons.YesNo, System.Windows.Forms.MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
                    {
                        //copy the old settings folder:
                        Log("Debug: Loading settings from previous REGISTRY...");
                        Settings = Global.SetJSONString <ClsSettings>(AppSettings.LastSettingsJSON);
                    }
                    else
                    {
                        Log("Debug: Did NOT import settings from previous registry copy.");
                    }
                }
                else
                {
                    //nothing valid
                    Log("Error: Settings file AND backup were missing or corrupt.");

                    if (File.Exists(AppSettings.Settings.SettingsFileName))
                    {
                        File.Delete(AppSettings.Settings.SettingsFileName);
                    }

                    if (File.Exists(AppSettings.Settings.SettingsFileName + ".bak"))
                    {
                        File.Delete(AppSettings.Settings.SettingsFileName + ".bak");
                    }
                }

                if (Settings != null)
                {
                    //The client identifier (ClientId) identifies each MQTT client that connects to an MQTT broker.
                    //The broker uses the ClientID to identify the client and the current state of the client.Therefore,
                    //this ID should be unique per client and broker. In MQTT 3.1.1 (the current standard), you can send
                    //an empty ClientId, if you don’t need a state to be held by the broker. The empty ClientID results
                    //in a connection without any state. In this case, the clean session flag must be set to true or
                    //the broker will reject the connection.

                    if (Settings.mqtt_clientid.EqualsIgnoreCase("aitool"))
                    {
                        Settings.mqtt_clientid = "AITool-BATMAN-" + Global.GetMacAddress();  //set the id to a unique number that should not *usually* change on a machine - the mac address of an active adapter
                    }
                    //but only set it once if the default clientid is set

                    if (Settings.telegram_cooldown_minutes > -1)
                    {
                        Settings.telegram_cooldown_seconds = Convert.ToInt32(Math.Round(TimeSpan.FromMinutes(Settings.telegram_cooldown_minutes).TotalSeconds, 0));
                        Settings.telegram_cooldown_minutes = -1;
                    }

                    UpdateSettingsLocation();  //save to \settings folder or appdata\settings


                    //load cameras the old way if needed
                    if (Settings.CameraList.Count == 0)
                    {
                        string camerafolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "cameras");
                        Log("No cameras loaded in settings, trying to load old camera files from " + camerafolder);
                        List <FileInfo> files = Global.GetFiles(camerafolder, "*.txt"); //load all settings files in a string array
                                                                                        //Sort so more recent files are processed first - to make sure any dupes that are skipped are older
                                                                                        //I *think* this logic works?
                        files = files.OrderByDescending((d) => d.LastWriteTime).ToList();
                        //create a camera object for every camera settings file
                        int cnt = 0;
                        foreach (FileInfo file in files)
                        {
                            //check if camera with specified name or its prefix already exists. If yes, then abort.
                            bool fnd = false;
                            foreach (Camera c in AppSettings.Settings.CameraList)
                            {
                                if (string.Equals(c.Name, Path.GetFileNameWithoutExtension(file.FullName), StringComparison.OrdinalIgnoreCase))
                                {
                                    fnd = true;
                                }
                                else if (string.Equals(c.Prefix, System.IO.File.ReadAllLines(file.FullName)[2].Split('"')[1], StringComparison.OrdinalIgnoreCase))
                                {
                                    fnd = true;
                                }
                            }
                            if (!fnd)
                            {
                                cnt++;
                                Camera cam = new Camera();                //create new camera object
                                cam.ReadConfig(file.FullName);            //read camera's config from file
                                AppSettings.Settings.CameraList.Add(cam); //add created camera object to CameraList
                            }
                            else
                            {
                                Log("Skipped duplicate camera: " + file);
                            }
                        }

                        if (cnt > 0)
                        {
                            Log($"...Loaded {cnt} camera files.");
                        }
                        else
                        {
                            Log($"...NO old camera txt files could be loaded.");
                        }

                        Resave = (cnt > 1);
                    }

                    Camera DefaultCam = GetCamera("default", ReturnDefault: true);
                    if (DefaultCam == null)
                    {
                        //add a default camera
                        Camera cam = new Camera("Default");
                        Settings.CameraList.Add(cam);
                    }
                    else if (DefaultCam.DefaultTriggeringObjects == null)
                    {
                        //replace the old default camera with a new one or else we have trouble with the triggering objects manager
                        Camera cam = new Camera(DefaultCam.Name);
                        Settings.CameraList.Remove(DefaultCam);
                        Settings.CameraList.Add(cam);
                    }

                    if (!Settings.ObjectPriority.Has("suv") || !Settings.ObjectPriority.Has("van"))
                    {
                        Settings.ObjectPriority = "person, bear, elephant, car, truck, SUV, van, bicycle, motorcycle, bus, dog, horse, boat, train, airplane, zebra, giraffe, cow, sheep, cat, bird";
                    }

                    //make sure everything in the cameras look correct:
                    foreach (Camera cam in Settings.CameraList)
                    {
                        cam.UpdateCamera();
                    }


                    //sort the camera list:
                    AppSettings.Settings.CameraList = AppSettings.Settings.CameraList.OrderBy((d) => d.Name).ToList();

                    AITOOL.UpdateAIURLList(true);

                    //clean up image adjust list
                    List <ClsImageAdjust> iaps = AppSettings.Settings.ImageAdjustProfiles;

                    AppSettings.Settings.ImageAdjustProfiles.Clear();

                    for (int i = 0; i < iaps.Count; i++)
                    {
                        if (!AppSettings.Settings.ImageAdjustProfiles.Contains(iaps[i]))
                        {
                            Settings.ImageAdjustProfiles.Add(iaps[i]);
                        }
                    }

                    for (int i = 0; i < AppSettings.Settings.AIURLList.Count; i++)
                    {
                        AppSettings.Settings.AIURLList[i].Order = i + 1;
                        if (!AITOOL.HasImageAdjustProfile(AppSettings.Settings.AIURLList[i].ImageAdjustProfile))
                        {
                            AppSettings.Settings.AIURLList[i].ImageAdjustProfile = "Default";
                        }
                    }

                    if (Settings.FacesPath.IsEmpty())
                    {
                        string pth = Path.GetDirectoryName(Settings.SettingsFileName);
                        Settings.FacesPath = Path.Combine(pth, "FaceStorage");
                    }

                    string facefile = Path.Combine(Settings.FacesPath, "Faces.JSON");

                    if (await IsFileValidAsync(facefile, 400))
                    {
                        AITOOL.FaceMan = Global.ReadFromJsonFile <ClsFaceManager>(facefile);
                    }
                    else
                    {
                        AITOOL.FaceMan = new ClsFaceManager();
                    }


                    Ret = true;
                }
                else
                {
                    Log("Error: Could not load settings?");
                }

                if (Resave)
                {
                    //we imported old settings, save them
                    SaveAsync();
                }

                //}
            }
            catch (Exception ex)
            {
                Log("Error: Could not save settings: " + ex.Msg());
            }
            finally
            {
                semaphoreSlim.Release();
            }


            return(Ret);
        }