aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/PropertyCompletionItem.cs
blob: c301e8ede03458de44bac9b701e530ac6711c6f3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media.Imaging;

namespace Tango.Scripting.Editors.Intellisense
{
    public class PropertyCompletionItem : CompletionItem
    {
        private static BitmapSource image = GetImage("property.png");

        public override string Text => Name;
        public override CompletionItemPopupControl PopupControl => new PropertyCompletionItemPopup();
        public override BitmapSource Image => image;

        public String Name { get; set; }
        public String Class { get; set; }
        public String Type { get; set; }
    }
}
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Tango.Core;
using Tango.Core.DI;
using Tango.Core.Helpers;
using Tango.PPC.Common.Application;
using Tango.PPC.Common.Connection;
using Tango.PPC.Common.Notifications;

namespace Tango.PPC.Common.UpdatePackages
{
    public class DefaultPackageRunner : ExtendedObject, IPackageRunner
    {
        private JsonSerializerSettings _jsonSettings;
        private String _configFile;
        private PackagesFile _packagesFile;

        public event EventHandler<PackageStateChangedEventArgs> PackageStateChanged;
        public event EventHandler<PackageProgressEventArgs> PackageProgress;

        public DefaultPackageRunner()
        {
            _jsonSettings = new JsonSerializerSettings
            {
                Formatting = Formatting.Indented,
                Error = (sender, args) =>
                {
                    args.ErrorContext.Handled = true;
                    LogManager.Log(args.ErrorContext.Error.Message);
                }
            };

            _jsonSettings.Converters.Add(new StringEnumConverter(false));

            _configFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Twine", "Tango", "Packages", "packages.json");
        }

        public Task<PackagesFile> GetPackagesFile()
        {
            return Task.Factory.StartNew<PackagesFile>(() =>
            {
                if (_packagesFile != null)
                {
                    return _packagesFile;
                }
                else
                {
                    Directory.CreateDirectory(Path.GetDirectoryName(_configFile));

                    _packagesFile = new PackagesFile();

                    try
                    {
                        if (File.Exists(_configFile))
                        {
                            LogManager.Log("Loading packages config from " + _configFile + "...");
                            _packagesFile = JsonConvert.DeserializeObject<PackagesFile>(File.ReadAllText(_configFile), _jsonSettings);
                        }
                    }
                    catch (Exception ex)
                    {
                        LogManager.Log(ex, "Error loading packages file.");
                    }

                    return _packagesFile;
                }
            });
        }

        private void SavePackagesConfig()
        {
            Directory.CreateDirectory(Path.GetDirectoryName(_configFile));

            String json = String.Empty;

            if (_packagesFile != null)
            {
                json = JsonConvert.SerializeObject(_packagesFile, _jsonSettings);
            }
            else
            {
                json = JsonConvert.SerializeObject(new PackagesFile(), _jsonSettings);
            }

            File.WriteAllText(_configFile, json);
        }

        public Task<PackageRunnerResult> Run(PackageType type, Version deltaVersion, String packagesFolder)
        {
            return Task.Factory.StartNew<PackageRunnerResult>(() =>
            {
                PackageRunnerResult result = new PackageRunnerResult();

                PackageContext context = new PackageContext();
                context.ApplicationManager = TangoIOC.Default.GetInstance<IPPCApplicationManager>();
                context.MachineProvider = TangoIOC.Default.GetInstance<IMachineProvider>();
                context.NotificationProvider = TangoIOC.Default.GetInstance<INotificationProvider>();
                context.InstalledVersion = context.ApplicationManager.Version;
                context.DeltaVersion = deltaVersion;

                LogManager.Log($"Running {type}-update packages...");

                //Get installed packages.
                _packagesFile = GetPackagesFile().Result;

                LogManager.Log($"Installed packages file:\n{_packagesFile}");

                if (Debugger.IsAttached)
                {
                    LogManager.Log("Debugger attached detected. switching packages folder to main application path...");

                    //TO DEBUG PACKAGES --
                    //
                    //On DEBUG build the packages assemblies are copied to the main application output folder using post-build events.
                    //Then, if a debugger is attached, we change the packages folder to the main output folder so they can be debugged easily.
                    packagesFolder = AssemblyHelper.GetCurrentAssemblyFolder();
                }

                LogManager.Log($"Scanning for packages on '{packagesFolder}'...");

                //Get all packages in folder.
                foreach (var packageFile in Directory.GetFiles(packagesFolder, "*.dll"))
                {
                    LogManager.Log($"Loading assembly '{Path.GetFileName(packageFile)}'...");

                    Assembly asm;

                    //Load assembly and investigate for types based on package type.
                    try
                    {
                        asm = Assembly.LoadFile(packageFile);
                    }
                    catch (Exception ex)
                    {
                        LogManager.Log(ex, "Error loading assembly!");
                        continue;
                    }

                    try
                    {
                        foreach (var packageType in asm.GetTypes().Where(
                            x => typeof(IPPCPackage).IsAssignableFrom(x) &&
                            x.GetCustomAttribute<PPCPackageAttribute>() != null &&
                            x.GetCustomAttribute<PPCPackageAttribute>().Type == type))
                        {
                            LogManager.Log($"Checking package '{packageType.FullName}'...");

                            try
                            {
                                //Getting installed package from file.
                                var installedPackage = _packagesFile.PackageInstallations.SingleOrDefault(x => x.PackageName == packageType.FullName);

                                //Check if requires installation.
                                if (installedPackage == null || installedPackage.State != PackageInstallationState.Installed)
                                {
                                    if (installedPackage == null)
                                    {
                                        LogManager.Log("Package was never installed.");

                                        installedPackage = new PackageInstallation();
                                        installedPackage.State = PackageInstallationState.NotInstalled;
                                        installedPackage.PackageName = packageType.FullName;
                                        installedPackage.Type = type;
                                        _packagesFile.PackageInstallations.Add(installedPackage);
                                    }
                                    else
                                    {
                                        LogManager.Log($"Package installation state is '{installedPackage.State}' due to {installedPackage.FailedReason}");
                                    }

                                    LogManager.Log("Installing package...");

                                    //Install package...
                                    var att = packageType.GetCustomAttribute<PPCPackageAttribute>();

                                    var packageInstance = Activator.CreateInstance(packageType) as IPPCPackage;

                                    if (packageInstance != null)
                                    {
                                        try
                                        {
                                            OnPackageRuns(att.Name, installedPackage.State, installedPackage.Type);
                                            installedPackage.InstallationDate = DateTime.Now;
                                            context.ProgressAction = (message, isIntermediate, progress, total) =>
                                            {
                                                PackageProgress?.Invoke(this, new PackageProgressEventArgs()
                                                {
                                                    PackageName = att.Name,
                                                    Message = message,
                                                    IsIntermediate = isIntermediate,
                                                    Progress = progress,
                                                    Total = total
                                                });
                                            };

                                            PackageProgress?.Invoke(this, new PackageProgressEventArgs()
                                            {
                                                PackageName = type == PackageType.Pre ? "Preparing" : "Finalizing",
                                                Message = att.Name,
                                                IsIntermediate = true,
                                                Progress = 0,
                                                Total = 100
                                            });

                                            packageInstance.Run(context).GetAwaiter().GetResult();
                                            installedPackage.State = PackageInstallationState.Installed;
                                            installedPackage.FailedReason = null;
                                            OnPackageRuns(att.Name, installedPackage.State, installedPackage.Type);
                                            LogManager.Log("Package installed successfully.");

                                            if (att.RequiresRestart)
                                            {
                                                result.RestartRequired = true;
                                            }

                                            Thread.Sleep(2000);
                                        }
                                        catch (Exception ex)
                                        {
                                            LogManager.Log(ex, "Package installation failed.");
                                            installedPackage.State = PackageInstallationState.Failed;
                                            installedPackage.FailedReason = ex.FlattenMessage();
                                            OnPackageRuns(att.Name, installedPackage.State, installedPackage.Type);
                                            continue;
                                        }
                                    }
                                }
                                else
                                {
                                    LogManager.Log("Package is already installed.");
                                }
                            }
                            catch (Exception ex)
                            {
                                LogManager.Log(ex, "Error in handling the package!");
                                continue;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        LogManager.Log(ex, "Error investigating assembly!");
                        continue;
                    }
                }

                //Save package file.
                LogManager.Log("Running packages has completed. Saving packages config file.");

                try
                {
                    SavePackagesConfig();
                }
                catch (Exception ex)
                {
                    LogManager.Log(ex, "Error saving packages file!");
                }

                return result;
            });
        }

        public Task<bool> IsPackageInstallationRequired(PackageType type, String packagesFolder)
        {
            return Task.Factory.StartNew<bool>(() =>
            {
                LogManager.Log("Checking if any package installation is required...");

                _packagesFile = GetPackagesFile().Result;

                //Get all packages in folder.
                foreach (var packageFile in Directory.GetFiles(packagesFolder, "*.dll"))
                {
                    LogManager.Log($"Loading assembly '{Path.GetFileName(packageFile)}'...");

                    Assembly asm;

                    //Load assembly and investigate for types based on package type.
                    try
                    {
                        asm = Assembly.LoadFile(packageFile);
                    }
                    catch (Exception ex)
                    {
                        LogManager.Log(ex, "Error loading assembly!");
                        continue;
                    }

                    try
                    {
                        foreach (var packageType in asm.GetTypes().Where(
                            x => typeof(IPPCPackage).IsAssignableFrom(x) &&
                            x.GetCustomAttribute<PPCPackageAttribute>() != null &&
                            x.GetCustomAttribute<PPCPackageAttribute>().Type == type))
                        {
                            LogManager.Log($"Checking package '{packageType.FullName}'...");

                            try
                            {
                                //Getting installed package from file.
                                var installedPackage = _packagesFile.PackageInstallations.SingleOrDefault(x => x.PackageName == packageType.FullName);

                                //Check if requires installation.
                                if (installedPackage == null || installedPackage.State != PackageInstallationState.Installed)
                                {
                                    if (installedPackage == null)
                                    {
                                        LogManager.Log("Package was never installed.");
                                        return true;
                                    }
                                    else
                                    {
                                        LogManager.Log($"Package installation state is '{installedPackage.State}' due to {installedPackage.FailedReason}");
                                        return true;
                                    }
                                }
                                else
                                {
                                    LogManager.Log("Package is already installed.");
                                }
                            }
                            catch (Exception ex)
                            {
                                LogManager.Log(ex, "Error in handling the package!");
                                continue;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        LogManager.Log(ex, "Error investigating assembly!");
                        continue;
                    }
                }

                LogManager.Log("No packages to install.");

                return false;
            });
        }

        protected virtual void OnPackageRuns(String packageName, PackageInstallationState state, PackageType type)
        {
            PackageStateChanged?.Invoke(this, new PackageStateChangedEventArgs()
            {
                PackageName = packageName,
                State = state,
                PackageType = type,
            });
        }
    }
}