aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/PPC/Tango.PPC.Common/BackupRestore/BackupFile.cs
blob: c687377a69da9956779a9bc378ec0e4c2ec8392a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tango.PMR.Exports;
using Tango.Web;

namespace Tango.PPC.Common.BackupRestore
{
    /// <summary>
    /// Represents a backup file record.
    /// </summary>
    public class BackupFile
    {
        /// <summary>
        /// Gets or sets the backup file version.
        /// </summary>
        public int Version { get; set; }

        /// <summary>
        /// Gets or sets the backup name.
        /// </summary>
        public String Name { get; set; }

        /// <summary>
        /// Gets or sets the creation date.
        /// </summary>
        public DateTime Date { get; set; }

        /// <summary>
        /// Gets or sets the machine serial number.
        /// </summary>
        public String MachineSerialNumber { get; set; }

        /// <summary>
        /// Gets or sets the application version.
        /// </summary>
        public String ApplicationVersion { get; set; }

        /// <summary>
        /// Gets or sets the firmware version.
        /// </summary>
        public String FirmwareVersion { get; set; }

        /// <summary>
        /// Gets or sets the settings file.
        /// </summary>
        public String SettingsFile { get; set; }

        /// <summary>
        /// Gets or sets the job files.
        /// </summary>
        public List<JobFile> JobFiles { get; set; }

        /// <summary>
        /// Gets or sets the backup settings.
        /// </summary>
        public BackupSettings Settings { get; set; }

        /// <summary>
        /// Initializes a new instance of the <see cref="BackupFile"/> class.
        /// </summary>
        public BackupFile()
        {
            Settings = new BackupSettings();
            JobFiles = new List<JobFile>();
        }

        public String ToJson()
        {
            return JsonConvert.SerializeObject(this);
        }

        public static BackupFile FromJson(String json)
        {
            return JsonConvert.DeserializeObject<BackupFile>(json);
        }
    }
}
/span>; using Tango.Core.Cryptography; using Tango.Core.Helpers; using Tango.Git; using Tango.MachineStudio.Common.Web; using Tango.Transport.Web; using Tango.Web; namespace Tango.MachineStudio.Common.Publish { public class MachineStudioPublisher : ExtendedObject { private MachineStudioWebClient _client; /// <summary> /// Occurs on publish progress. /// </summary> public event EventHandler<PublishProgressEventArgs> PublishProgress; private PublishOptions _options; /// <summary> /// Gets or sets the publish options. /// </summary> public PublishOptions Options { get { return _options; } set { _options = value; RaisePropertyChangedAuto(); } } /// <summary> /// Initializes a new instance of the <see cref="MachineStudioPublisher"/> class. /// </summary> public MachineStudioPublisher() { _client = new MachineStudioWebClient(); Options = new PublishOptions(); } /// <summary> /// Initializes a new instance of the <see cref="MachineStudioPublisher"/> class. /// </summary> /// <param name="publishOptions">The publish options.</param> public MachineStudioPublisher(PublishOptions publishOptions) : this() { Options = publishOptions; } /// <summary> /// Gets the latest version. /// </summary> /// <returns></returns> public async Task<String> GetRemoteVersion() { _client.Environment = Options.Environment; var response = await _client.GetLatestVersion(new LatestVersionRequest()); return response.Version; } /// <summary> /// Gets the latest version. /// </summary> /// <returns></returns> public async Task<String> GetRemoteVersion(DeploymentSlot environment) { _client.Environment = environment; var response = await _client.GetLatestVersion(new LatestVersionRequest()); return response.Version; } /// <summary> /// Gets the latest version. /// </summary> /// <returns></returns> public String GetLocalVersion() { return FileVersionInfo.GetVersionInfo(GetMachineStudioExecutablePath()).ProductVersion; } /// <summary> /// Gets the machine studio executable path. /// </summary> /// <returns></returns> public String GetMachineStudioExecutablePath() { String appPath = Path.Combine(Options.GetApplicationPath(), "Tango.MachineStudio.UI.exe"); return appPath; } /// <summary> /// Login to machine service and returns an access token. /// </summary> /// <returns></returns> private Task Login() { return Task.Factory.StartNew(() => { return _client.Login(new LoginRequest() { Email = Options.Email, Password = Options.Password, Version = GetLocalVersion(), }).Result; }); } /// <summary> /// Publish a machine studio version using the specified <see cref="Options"/>. /// </summary> /// <returns></returns> public Task Publish() { _client.Environment = Options.Environment; String appPath = GetMachineStudioExecutablePath(); String folder = Options.GetApplicationPath(); if (!File.Exists(appPath)) { throw new FileNotFoundException($"Could not locate the machine studio executable at {appPath}."); } if (!String.IsNullOrWhiteSpace(Options.InstallerProject)) { if (!File.Exists(Options.InstallerProject)) { throw new FileNotFoundException($"Installer project not found at '{Options.InstallerProject}'."); } if (!Directory.Exists(Options.InstallerOutputFolder)) { Directory.CreateDirectory(Options.InstallerOutputFolder); } } String tempFile = TemporaryManager.CreateFile(); return Task.Factory.StartNew(() => { try { OnPublishProgress(0, 100, $"Logging in to machine service at {Options.Environment.ToAddress()}..."); Login().Wait(); OnPublishProgress(0, 100, $"Fetching remote version from {Options.Environment.ToAddress()}..."); String remote_version = GetRemoteVersion().Result; String local_version = GetLocalVersion(); OnPublishProgress(0, 100, $"Remote version: {remote_version}"); OnPublishProgress(0, 100, $"Local version: {local_version}"); if (Version.Parse(local_version) <= Version.Parse(remote_version)) { throw new InvalidOperationException($"The local version '{local_version}' is not greater than the remote version '{remote_version}'."); } OnPublishProgress(0, 100, $"Requesting version upload..."); var response = _client.UploadVersion(new UploadVersionRequest() { Version = local_version, Comments = Options.Comments, WithInstaller = !String.IsNullOrWhiteSpace(Options.InstallerProject), }).Result; if (!String.IsNullOrWhiteSpace(Options.InstallerProject)) { String output_folder = Options.InstallerOutputFolder; OnPublishProgress(0, 100, $"Building installer project..."); InstallerBuilder installerBuilder = new InstallerBuilder(Options.InstallerProject); String installer_name = $"Machine Studio Installer_v{Version.Parse(local_version).ToString(3)}.exe"; String output_file = Path.Combine(output_folder, installer_name); installerBuilder.Build(local_version, output_file).Wait(); Thread.Sleep(5000); OnPublishProgress(0, 100, $"Uploading installer '{installer_name}'..."); using (StorageBlobUploader uploader = new StorageBlobUploader(response.InstallerBlobAddress, output_file)) { uploader.Progress += (x, e) => { OnPublishProgress(e.Current, e.Total, $"Uploading installer {(((double)e.Current / (double)e.Total) * 100d).ToString("0.0")}%...", true); }; uploader.Upload().Wait(); } } OnPublishProgress(0, 100, $"Starting version packaging..."); using (ZipFile zip = new ZipFile()) { foreach (var directory in Directory.GetDirectories(folder)) { zip.AddDirectory(directory, $"/{Path.GetFileName(directory)}"); } var files = Directory.GetFiles(folder, "*.*", SearchOption.TopDirectoryOnly).ToList(); foreach (var file in files) { zip.AddFile(file, "/"); } zip.SaveProgress += (x, e) => { if (e.EventType == ZipProgressEventType.Saving_BeforeWriteEntry) { OnPublishProgress(e.EntriesSaved + 1, e.EntriesTotal, $"Compressing files {(((double)(e.EntriesSaved + 1) / (double)e.EntriesTotal) * 100d).ToString("0.0")}%...", true); } }; zip.ParallelDeflateThreshold = -1; zip.Save(tempFile); } OnPublishProgress(0, 100, $"Starting version upload..."); using (StorageBlobUploader uploader = new StorageBlobUploader(response.BlobAddress, tempFile)) { uploader.Progress += (x, e) => { OnPublishProgress(e.Current, e.Total, $"Uploading version {(((double)e.Current / (double)e.Total) * 100d).ToString("0.0")}%...", true); }; uploader.Upload().Wait(); } OnPublishProgress(100, 100, $"Finalizing version upload..."); _client.NotifyVersionUploadCompleted(new UploadCompletedRequest() { Token = response.Token, }).Wait(); remote_version = GetRemoteVersion().Result; local_version = GetLocalVersion(); OnPublishProgress(0, 0, $"Remote version: {remote_version}"); OnPublishProgress(0, 0, $"Local version: {local_version}"); if (remote_version != local_version) { throw new InvalidOperationException("The remote version does not seems to have been updated."); } if (Options.CreateTag) { String repoPath = Path.GetFullPath("../../../../../"); String tagVersion = System.Version.Parse(GetLocalVersion()).ToString(3); String tagName = $"Machine_Studio_v{tagVersion}"; using (GitRepositoryManager git = new GitRepositoryManager(repoPath, Options.Email, Options.PersonalAccessToken)) { OnPublishProgress(0, 100, "Checking repository changes..."); int changes = git.GetChanges().Count; if (changes > 0) { if (Options.AutoCommitAndPush) { OnPublishProgress(0, 100, "Committing repository changes..."); git.Commit(tagName); } else { throw new InvalidOperationException($"There are {changes} uncommitted changes on the repository. Please commit and push all changes before creating the Tag"); } } OnPublishProgress(0, 100, "Checking outgoing commits..."); int commits = git.GetOutgoingCommits().Count; //if (commits > 0) //{ if (Options.AutoCommitAndPush) { OnPublishProgress(0, 100, "Pushing repository changes..."); git.Sync(); } else { throw new InvalidOperationException($"There are {commits} outgoing commits on the repository. Please push all commits before creating the Tag"); } //} git.Progress += (x, e) => { OnPublishProgress(e.Progress.Value, e.Progress.Maximum, $"Pushing Tag '{tagName}'..."); }; OnPublishProgress(0, 100, $"Creating Tag '{tagName}'..."); git.CreatePushTag(tagName, Options.Comments, "Roy Ben Shabat"); } } OnPublishProgress(0, 0, "Version published successfully."); } catch (Exception ex) { OnPublishProgress(0, 100, $"Failed: {ex.Message}"); throw ex; } finally { PathHelper.TryDeleteFile(tempFile); } }); } /// <summary> /// Raises the publish progress event. /// </summary> /// <param name="progress">The progress.</param> /// <param name="total">The total.</param> /// <param name="message">The message.</param> protected virtual void OnPublishProgress(double progress, double total, String message, bool singleLine = false) { PublishProgress?.Invoke(this, new PublishProgressEventArgs() { Progress = progress, Total = total, Message = message, SingleLineRecommended = singleLine, }); } } }