コード例 #1
0
ファイル: RunnerUtils.cs プロジェクト: hexuallyactive/Zombie
        /// <summary>
        ///
        /// </summary>
        /// <param name="settings"></param>
        /// <param name="asset"></param>
        /// <param name="destinationDir"></param>
        /// <param name="type"></param>
        /// <param name="streams"></param>
        /// <returns></returns>
        private static bool LockAllContents(ZombieSettings settings, AssetObject asset, string destinationDir, LocationType type, out Dictionary <string, FileStream> streams)
        {
            streams = new Dictionary <string, FileStream>();
            var    dir = FileUtils.GetZombieDownloadsDirectory();
            string filePath;

            if (type == LocationType.Trash)
            {
                filePath = Path.Combine(dir,
                                        Path.GetFileNameWithoutExtension(asset.Name) + "_old" + Path.GetExtension(asset.Name));

                if (!File.Exists(filePath))
                {
                    if (!GitHubUtils.DownloadAssets(settings, asset.Url, filePath))
                    {
                        return(false);
                    }
                }
            }
            else
            {
                filePath = Path.Combine(dir, asset.Name);
            }

            try
            {
                using (var zip = ZipFile.Open(filePath, ZipArchiveMode.Read))
                {
                    foreach (var file in zip.Entries)
                    {
                        var completeFileName = Path.Combine(destinationDir, file.FullName);
                        if (file.Name == string.Empty ||
                            !Directory.Exists(Path.GetDirectoryName(completeFileName)) ||
                            !File.Exists(completeFileName))
                        {
                            continue;
                        }

                        var fs = new FileStream(completeFileName, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
                        streams.Add(completeFileName, fs);
                    }
                }
            }
            catch (Exception e)
            {
                _logger.Fatal(e.Message);
                return(false);
            }

            return(true);
        }
コード例 #2
0
        private void OnShowContents()
        {
            IsContentVisible = !IsContentVisible;

            if (Contents.Any())
            {
                return;
            }

            var dir = Path.Combine(Directory.GetCurrentDirectory(), "downloads");

            if (!Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
            }

            try
            {
                var filePath = Path.Combine(dir, Asset.Name);

                // download
                GitHubUtils.DownloadAssets(App.Settings, Asset.Url, filePath);

                // verify
                if (!File.Exists(filePath))
                {
                    StatusBarManager.StatusLabel.Text = "Could not retrieve contents of the Asset!";
                    return;
                }

                using (var zip = ZipFile.Open(filePath, ZipArchiveMode.Read))
                {
                    foreach (var asset in zip.Entries)
                    {
                        Contents.Add(new AssetViewModel(new AssetObject {
                            Name = asset.Name
                        })
                        {
                            IsContent = true
                        });
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
        }
コード例 #3
0
ファイル: ZombieModel.cs プロジェクト: karthi1015/Zombie
        /// <summary>
        ///
        /// </summary>
        /// <param name="settings"></param>
        public async void GetLatestRelease(ZombieSettings settings)
        {
            if (string.IsNullOrEmpty(settings?.AccessToken) || string.IsNullOrEmpty(settings.Address))
            {
                UpdateUI("Connection failed!", ConnectionResult.Failure);
                return;
            }

            var response = await GetLatestReleaseFromGitHub(settings);

            if (response.StatusCode != HttpStatusCode.OK)
            {
                UpdateUI("Connection failed!", ConnectionResult.Failure);
                return;
            }

            var release        = response.Data;
            var currentVersion = Properties.Settings.Default["CurrentVersion"].ToString();

            if (!release.Assets.Any() || new Version(release.TagName).CompareTo(new Version(currentVersion)) <= 0)
            {
                UpdateUI("Your release is up to date!", ConnectionResult.UpToDate, release);
                return;
            }

            var dir        = FileUtils.GetZombieDownloadsDirectory();
            var downloaded = 0;

            foreach (var asset in release.Assets)
            {
                var filePath = Path.Combine(dir, asset.Name);
                if (GitHubUtils.DownloadAssets(settings, asset.Url, filePath))
                {
                    downloaded++;
                }
            }

            if (downloaded != release.Assets.Count)
            {
                UpdateUI("Failed to download assets!", ConnectionResult.Failure);
                return;
            }

            // (Konrad) Let's get updated settings, they might be local, or remote.
            // We need latest settings since there might be changes to the target locations.
            ZombieSettings newSettings;

            if (File.Exists(settings.SettingsLocation))
            {
                if (!SettingsUtils.TryGetStoredSettings(settings.SettingsLocation, out newSettings))
                {
                    UpdateUI("Could not get latest local Zombie Settings!", ConnectionResult.Failure);
                    return;
                }
            }
            else
            {
                if (!SettingsUtils.TryGetRemoteSettings(settings.SettingsLocation, out newSettings))
                {
                    UpdateUI("Could not get latest remote Zombie Settings!", ConnectionResult.Failure);
                    return;
                }
            }

            // (Konrad) Let's make sure that we own the files that we are trying to override
            var fileStreams = new Dictionary <string, FileStream>();

            foreach (var loc in newSettings.DestinationAssets)
            {
                foreach (var asset in loc.Assets)
                {
                    if (asset.IsArchive())
                    {
                        if (LockAllContents(settings, asset, loc.DirectoryPath, out var zippedStreams))
                        {
                            fileStreams = fileStreams.Concat(zippedStreams).GroupBy(x => x.Key)
                                          .ToDictionary(x => x.Key, x => x.First().Value);
                            continue;
                        }

                        UpdateUI("Could not get access to all ZIP contents!", ConnectionResult.Failure);
                        return;
                    }

                    var to = Path.Combine(FilePathUtils.CreateUserSpecificPath(loc.DirectoryPath), asset.Name);
                    try
                    {
                        var fs = new FileStream(to, FileMode.OpenOrCreate, FileAccess.ReadWrite,
                                                FileShare.None);
                        fileStreams.Add(to, fs);
                    }
                    catch (Exception e)
                    {
                        UpdateUI(e.Message, ConnectionResult.Failure);
                        return;
                    }
                }
            }

            // (Konrad) Move assets to target locations
            foreach (var loc in newSettings.DestinationAssets)
            {
                foreach (var asset in loc.Assets)
                {
                    if (asset.IsArchive())
                    {
                        if (ExtractToDirectory(asset, loc.DirectoryPath, fileStreams))
                        {
                            continue;
                        }

                        UpdateUI("Could not override existing ZIP contents!", ConnectionResult.Failure);
                        return;
                    }

                    var from = Path.Combine(dir, asset.Name);
                    var to   = Path.Combine(FilePathUtils.CreateUserSpecificPath(loc.DirectoryPath), asset.Name);

                    // make sure that file is not locked
                    var stream = fileStreams[to];
                    stream?.Close();

                    if (FileUtils.Copy(@from, @to))
                    {
                        continue;
                    }

                    UpdateUI("Could not override existing file!", ConnectionResult.Failure);
                    return;
                }
            }

            // (Konrad) Remove temporary assets
            if (!FileUtils.DeleteDirectory(dir))
            {
                UpdateUI("Could not remove temporary download assets!", ConnectionResult.Failure);
                return;
            }

            // (Konrad) Update UI and save current version
            Properties.Settings.Default.CurrentVersion = release.TagName;
            Properties.Settings.Default.Save();

            _logger.Info("Successfully updated to version: " + release.TagName);
            Messenger.Default.Send(new UpdateStatus {
                Status = "Successfully updated to version: " + release.TagName
            });
            Messenger.Default.Send(new ReleaseDownloaded
            {
                Release = release,
                Result  = ConnectionResult.Success
            });
        }
コード例 #4
0
ファイル: RunnerUtils.cs プロジェクト: hexuallyactive/Zombie
        /// <summary>
        /// Method that retrieves the latest release from GitHub.
        /// </summary>
        /// <param name="settings">Zombie Settings to be used to retrieve latest Release.</param>
        public static async void GetLatestRelease(ZombieSettings settings)
        {
            if (IsProcessRunning("Revit"))
            {
                _logger.Error("Update failed. Revit is running.");

                // (Konrad) Since release was not up to date. Let's show a notification to user that update is in progress.
                PublishGuiUpdate(Program.Settings, Status.Notification, "Update failed. Revit is running.");

                return;
            }

            if (string.IsNullOrWhiteSpace(settings?.AccessToken) || string.IsNullOrWhiteSpace(settings.Address))
            {
                var a = string.IsNullOrWhiteSpace(settings.Address) ? "Not found" : "Exists";
                _logger.Error($"Connection failed! Address: {a}");
                return;
            }

            var segments  = GitHubUtils.ParseUrl(settings.Address);
            var client    = new GitHubClient(new ProductHeaderValue("Zombie"));
            var tokenAuth = new Credentials(settings.AccessToken);

            client.Credentials = tokenAuth;

            Release release;

            try
            {
                release = await client.Repository.Release.GetLatest(segments["owner"], segments["repo"]);

                var currentVersion = RegistryUtils.GetZombieVersion();
                if (!release.Assets.Any() || new Version(release.TagName).CompareTo(new Version(currentVersion)) <= 0)
                {
                    PublishGuiUpdate(Program.Settings, Status.UpToDate, "Your release is up to date! Version: " + currentVersion);
                    return;
                }
            }
            catch (Exception e)
            {
                _logger.Fatal("Failed to retrieve Release from GitHub. " + e.Message);
                return;
            }

            // (Konrad) Since release was not up to date. Let's show a notification to user that update is in progress.
            PublishGuiUpdate(Program.Settings, Status.Notification, "Update in progress. Please do not launch Revit.");

            var dir        = FileUtils.GetZombieDownloadsDirectory();
            var downloaded = 0;

            foreach (var asset in release.Assets)
            {
                var filePath = Path.Combine(dir, asset.Name);
                if (GitHubUtils.DownloadAssets(settings, asset.Url, filePath))
                {
                    downloaded++;
                }
            }

            if (downloaded != release.Assets.Count)
            {
                _logger.Error("Failed to download assets!");

                // (Konrad) Since release was not up to date. Let's show a notification to user that update is in progress.
                PublishGuiUpdate(Program.Settings, Status.Notification, "Update failed. Check your internet connection and try again.");

                return;
            }

            // (Konrad) Let's get updated settings, they might be local, or remote.
            // We need latest settings since there might be changes to the target locations.
            ZombieSettings newSettings;

            if (File.Exists(settings.SettingsLocation))
            {
                if (!SettingsUtils.TryGetStoredSettings(settings.SettingsLocation, out newSettings))
                {
                    _logger.Error("Could not get latest local Zombie Settings!");

                    // (Konrad) Since release was not up to date. Let's show a notification to user that update is in progress.
                    PublishGuiUpdate(Program.Settings, Status.Notification, "Update failed. Zombie Settings not found.");

                    return;
                }
            }
            else
            {
                if (!SettingsUtils.TryGetRemoteSettings(settings.SettingsLocation, out newSettings))
                {
                    _logger.Error("Could not get latest remote Zombie Settings!");

                    // (Konrad) Since release was not up to date. Let's show a notification to user that update is in progress.
                    PublishGuiUpdate(Program.Settings, Status.Notification, "Update failed. Zombie Settings not found.");

                    return;
                }
            }

            // (Konrad) Let's make sure that we own the files that we are trying to override
            var fileStreams = new Dictionary <string, FileStream>();

            foreach (var loc in newSettings.DestinationAssets.OrderByDescending(x => (int)x.LocationType))
            {
                foreach (var asset in loc.Assets)
                {
                    if (asset.IsArchive())
                    {
                        // (Konrad) Use old settings
                        if (LockAllContents(loc.LocationType == LocationType.Trash ? settings : newSettings, asset, loc.DirectoryPath, loc.LocationType, out var zippedStreams))
                        {
                            fileStreams = fileStreams
                                          .Concat(zippedStreams)
                                          .GroupBy(x => x.Key)
                                          .ToDictionary(x => x.Key, x => x.First().Value);
                            continue;
                        }

                        ReleaseStreams(fileStreams);

                        // (Konrad) Since release was not up to date. Let's show a notification to user that update is in progress.
                        PublishGuiUpdate(Program.Settings, Status.Notification, "Update failed. Revit is potentially running preventing an update.");

                        return;
                    }

                    if (loc.LocationType != LocationType.Trash)
                    {
                        // (Konrad) Make sure that destination folder exists.
                        if (!Directory.Exists(loc.DirectoryPath))
                        {
                            FileUtils.CreateDirectory(loc.DirectoryPath);
                        }
                    }

                    var to = Path.Combine(loc.DirectoryPath, asset.Name);
                    if (!File.Exists(to))
                    {
                        continue;
                    }

                    try
                    {
                        var fs = new FileStream(to, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
                        fileStreams.Add(to, fs);
                    }
                    catch (Exception e)
                    {
                        _logger.Fatal(e.Message);
                        ReleaseStreams(fileStreams);

                        // (Konrad) Since release was not up to date. Let's show a notification to user that update is in progress.
                        PublishGuiUpdate(Program.Settings, Status.Notification, "Update failed...due to unknown reasons. Sorry about that.");

                        return;
                    }
                }
            }

            // (Konrad) Move assets to target locations.
            // We sort the locations list so that Trash (3) is first.
            // This should make sure that we delete first, then move.
            // Could be important with Zipped contents and overriding.
            foreach (var loc in newSettings.DestinationAssets.OrderByDescending(x => (int)x.LocationType))
            {
                if (loc.LocationType == LocationType.Trash)
                {
                    // (Konrad) Let's remove these files.
                    foreach (var asset in loc.Assets)
                    {
                        if (asset.IsArchive())
                        {
                            if (DeleteZipContents(asset, loc.DirectoryPath, fileStreams))
                            {
                                continue;
                            }

                            ReleaseStreams(fileStreams);

                            // (Konrad) Since release was not up to date. Let's show a notification to user that update is in progress.
                            PublishGuiUpdate(Program.Settings, Status.Notification, "Update failed. Revit is potentially running preventing an update.");

                            return;
                        }

                        var to = Path.Combine(loc.DirectoryPath, asset.Name);
                        if (fileStreams.ContainsKey(to))
                        {
                            // make sure that file is not locked
                            var stream = fileStreams[to];
                            stream?.Close();
                        }

                        if (FileUtils.DeleteFile(to))
                        {
                            continue;
                        }

                        ReleaseStreams(fileStreams);

                        // (Konrad) Since release was not up to date. Let's show a notification to user that update is in progress.
                        PublishGuiUpdate(Program.Settings, Status.Notification, "Update failed. Revit is potentially running preventing an update.");

                        return;
                    }
                }
                else
                {
                    // (Konrad) Let's copy these files.
                    foreach (var asset in loc.Assets)
                    {
                        if (asset.IsArchive())
                        {
                            if (ExtractToDirectory(asset, loc.DirectoryPath, fileStreams))
                            {
                                continue;
                            }

                            ReleaseStreams(fileStreams);

                            // (Konrad) Since release was not up to date. Let's show a notification to user that update is in progress.
                            PublishGuiUpdate(Program.Settings, Status.Notification, "Update failed. Revit is potentially running preventing an update.");

                            return;
                        }

                        var from = Path.Combine(dir, asset.Name);
                        var to   = Path.Combine(loc.DirectoryPath, asset.Name);
                        if (fileStreams.ContainsKey(to))
                        {
                            // make sure that file is not locked
                            var stream = fileStreams[to];
                            stream?.Close();
                        }

                        // (Konrad) Make sure that directory exists.
                        if (!Directory.Exists(Path.GetDirectoryName(to)))
                        {
                            FileUtils.CreateDirectory(Path.GetDirectoryName(to));
                        }

                        if (FileUtils.Copy(from, to))
                        {
                            continue;
                        }

                        ReleaseStreams(fileStreams);

                        // (Konrad) Since release was not up to date. Let's show a notification to user that update is in progress.
                        PublishGuiUpdate(Program.Settings, Status.Notification, "Update failed. Revit is potentially running preventing an update.");

                        return;
                    }
                }
            }

            // (Konrad) Remove temporary assets
            if (!FileUtils.DeleteDirectory(dir))
            {
                // (Konrad) Cleanup failed but we can continue.
                _logger.Error("Could not remove temporary download assets!");
            }

            // (Konrad) This is important!
            ReleaseStreams(fileStreams);

            // (Konrad) We need to store the current version for comparison on next update
            RegistryUtils.SetZombieVersion(release.TagName);

            // (Konrad) Settings need to be updated with the latest one just downloaded
            newSettings.LatestRelease = new ReleaseObject(release);
            if (!newSettings.StoreSettings)
            {
                newSettings.AccessToken      = Program.Settings.AccessToken;
                newSettings.SettingsLocation = Program.Settings.SettingsLocation;
            }
            Program.Settings = newSettings;

            // (Konrad) Publish to any open GUIs
            PublishGuiUpdate(newSettings, Status.Succeeded, "Successfully updated to Version: " + release.TagName);

            // (Konrad) Since release was not up to date. Let's show a notification to user that update is in progress.
            PublishGuiUpdate(Program.Settings, Status.Notification, "Update succeeded. Go ahead and launch Revit to see what's new.");
        }