| ofs | hex dump | ascii |
|---|
| 0000 | 00 00 01 00 06 00 10 10 00 00 00 00 20 00 68 04 00 00 66 00 00 00 20 20 00 00 00 00 20 00 a8 10 | ..............h...f............. |
| 0020 | 00 00 ce 04 00 00 30 30 00 00 00 00 20 00 a8 25 00 00 76 15 00 00 40 40 00 00 00 00 20 00 28 42 | ......00.......%..v...@@......(B |
| 0040 | 00 00 1e 3b 00 00 80 80 00 00 00 00 20 00 28 08 01 00 46 7d 00 00 00 00 00 00 00 00 20 00 28 20 | ...;..........(...F}..........(. |
| 0060 | 04 00 6e 85 01 00 28 00 00 00 10 00 00 00 20 00 00 00 01 00 20 00 00 00 00 00 40 04 00 00 00 00 | ..n...(...................@..... |
| 0080 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff ff ff 01 ff ff ff 01 ff ff ff 01 ff ff ff 01 ff ff | ................................ |
| 00a0 | ff 01 ff ff ff 01 29 2b 2d 19 8c 8d 8e 47 b8 b8 b9 73 c9 c9 ca 9d b7 b7 b8 c5 ba bb bc e9 c1 c2 | ......)+-....G...s.............. |
| 00c0 | c3 f3 9b 9c 9d 45 ff ff ff 01 ff ff ff 01 ff ff ff 01 ff ff ff 01 99 9a 9b 47 bf c0 c0 8b ab ab | .....E...................G...... |
| 00e0 | ac bb b4 b5 b6 e9 d4 d4 d5 ff df df df ff da db db ff cc cc cd ff f7 f7 f7 ff fd fd fd ff f4 f4 | ................................ |
| 0100 | f5 ff 8b 8c 8d 99 ff ff ff 01 ff ff ff 01 ff ff ff 01 28 2a 2e 03 b8 b8 b9 c3 e0 e1 e1 ff e8 e8 | ..................(*............ |
| 0120 | e8 ff f2 f2 f2 ff fe fe fe ff fe fe fe ff e3 e4 e4 ff f9 f9 f9 ff fe fe fe ff fe fe fe ff fe fe | ................................ |
| 0140 | fe ff bb bc bc fd 6a 6b 6d 33 ff ff ff 01 ff ff ff 01 8e 8f 90 49 fd fd fd ff fe fe fe ff df df | ......jkm3...........I.......... |
| 0160 | df ff fd fd fd ff fe fe fe ff fe fe fe ff df df e0 ff fd fd fd ff fe fe fe ff fe fe fe ff fe fe | ................................ |
| 0180 | fe ff d9 d9 da ff 88 88 89 77 ff ff ff 01 ff ff ff 01 be be bf 7b fe fe fe ff fe fe fe ff df df | .........w...........{.......... |
| 01a0 | df ff fe fe fe ff fe fe fe ff fe fe fe ff df df e0 ff fd fd fd ff fe fe fe ff fe fe fe ff fe fe | ................................ |
| 01c0 | fe ff df df df ff 8c 8d 8e 85 ff ff ff 01 ff ff ff 01 ca ca cb 97 fe fe fe ff fe fe fe ff df df | ................................ |
| 01e0 | e0 ff fe fe fe ff fe fe fe ff fe fe fe ff df df e0 ff fe fe fe ff fe fe fe ff fe fe fe ff fe fe | ................................ |
| 0200 | fe ff df e0 e0 ff 94 95 96 91 ff ff ff 01 ff ff ff 01 d0 d1 d1 ad fe fe fe ff fe fe fe ff df df | ................................ |
| 0220 | e0 ff fe fe fe ff fd fd fd ff fd fd fd ff da da db ff e3 e4 e4 ff df df e0 ff e7 e8 e8 ff fe fe | ................................ |
| 0240 | fe ff df df e0 ff 9a 9a 9b 9b ff ff ff 01 ff ff ff 01 d4 d5 d5 bb e3 e3 e4 ff d9 d9 da ff bb bc | ................................ |
| 0260 | bc ff c0 c1 c2 ff c0 c1 c2 ff c0 c1 c1 ff c7 c7 c8 ff db db db ff df df e0 ff d4 d4 d4 ff df df | ................................ |
| 0280 | e0 ff c3 c3 c4 ff 9c 9d 9e a3 ff ff ff 01 ff ff ff 01 bc bc bd bf dd dd dd ff e5 e5 e5 ff f8 f8 | ................................ |
| 02a0 | f8 ff fd fd fd ff fe fe fe ff fe fe fe ff fe fe fe ff fe fe fe ff fe fe fe ff fe fe fe ff fe fe | ................................ |
| 02c0 | fe ff da da da ff a7 a7 a8 ab ff ff ff 01 ff ff ff 01 c1 c1 c2 9d fd fd fd ff fd fd fd ff fd fd | ................................ |
| 02e0 | fd ff fb fb fb ff ee ed e8 ff f0 ef ea ff f0 ee ec ff ed e9 e3 ff f7 f5 f1 ff fe fe fe ff dc dc | ................................ |
| 0300 | dd ff cc cd cd ff d2 d2 d2 b3 ff ff ff 01 ff ff ff 01 21 22 24 07 dd dd de e7 fd fd fd ff ed f1 | ..................!"$........... |
| 0320 | f9 ff e2 f4 f6 ff e5 ef de ff ec e5 d3 ff e2 d8 c0 ff df d4 b9 ff f0 ea de ff fe fe fe ff ba bb | ................................ |
| 0340 | bb ff dd dd dd ff d4 d4 d5 b9 ff ff ff 01 ff ff ff 01 ff ff ff 01 d8 d9 d9 d9 fd fd fd ff fb fb | ................................ |
| 0360 | fb ff fc fc fc ff fe fe fe ff fd fd fd ff fc fb fa ff fe fe fe ff fe fe fe ff fe fe fe ff c1 c1 | ................................ |
| 0380 | c1 ff fd fd fd ff d4 d4 d4 b9 ff ff ff 01 ff ff ff 01 ff ff ff 01 a5 a5 a6 b5 de df df ff e6 e6 | ................................ |
| 03a0 | e6 ff ed ed ed ff e8 e8 e8 ff d9 d9 da ff ce ce cf ff c5 c5 c6 ff c1 c1 c2 ff bd be bf ff d6 d6 | ................................ |
| 03c0 | d7 ff fd fd fd ff bb bb bc 85 ff ff ff 01 ff ff ff 01 ff ff ff 01 76 77 79 21 c8 c8 c9 99 cf cf | ......................vwy!...... |
| 03e0 | d0 cd cd cd ce e5 d4 d4 d4 ef dc dc dc f5 de de de f7 d9 d9 d9 f3 ca ca cb ff d7 d8 d8 fd c6 c7 | ................................ |
| 0400 | c7 c1 b6 b6 b7 79 20 21 24 07 ff ff ff 01 ff ff ff 01 ff ff ff 01 ff ff ff 01 ff ff ff 01 ff ff | .....y.!$....................... |
| 0420 | ff 01 ff ff ff 01 ff ff ff 01 ff ff ff 01 ff ff ff 01 69 6a 6c 35 d4 d4 d5 87 b7 b9 bb 5d b7 b7 | ..................ijl5.......].. |
| 0440 | b8 6f ff ff ff 01 ff ff ff 01 ff ff ff 01 ff ff ff 01 ff ff ff 01 ff ff ff 01 ff ff ff 01 ff ff | .o.............................. |
| 0460 | ff 01 ff ff ff 01 ff ff ff 01 ff ff ff 01 ff ff ff 01 4b 4c 4e 27 b3 b4 b5 a5 9a 9b 9c 85 a7 a8 | ..................KLN'.......... |
| 0480 | a9 7d ff ff ff 01 ff ff ff 01 ff ff ff 01 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 | .}.............................. |
| 04a0 | ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 | ................................ |
| 04c0 | ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff 28 00 00 00 20 00 00 00 40 00 00 00 01 00 20 00 00 00 | ..............(.......@......... |
| 04e0 | 00 00 80 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff ff ff 01 ff ff ff 01 ff ff | ................................ |
| 0500 | ff 01 ff ff ff 01 ff ff ff 01 ff ff ff 01 ff ff ff 01 ff ff ff 01 ff ff ff 01 ff ff ff 01 ff ff | ................................ |
| 0520 | ff 01 ff ff ff 01 ff ff ff 01 ff ff ff 01 ff ff ff 01 ff ff ff 01 ff ff ff 01 65 69 72 05 19 1b | ..........................eir... |
| 0540 | 1d 25 36 37 3a 4f 79 7a 7c 77 9a 9b 9c 9f ad ad ae c3 b9 b9 ba e3 bf c0 c1 f9 a9 aa ab d3 34 36 | .%67:Oyz|w....................46 |
| 0560 | 38 2b ff ff ff 01 ff ff ff 01 ff ff ff 01 ff ff ff 01 ff ff ff 01 ff ff ff 01 ff ff ff 01 ff ff | 8+.............................. |
| 0580 | ff 01 ff ff ff 01 ff ff ff 01 ff ff ff 01 ff ff ff 01 ff ff ff 01 ff ff ff 01 ff ff ff 01 ff ff | ................................ |
| 05a0 | ff 01 ff ff ff 01 22 24 27 1b 2c 2d 30 49 76 77 78 75 9c 9d 9e a3 b0 b1 b2 cf bf c0 c0 f5 e1 e1 | ......"$'.,-0Ivwxu.............. |
| 05c0 | e1 ff f7 f8 f8 ff da da da ff c2 c2 c3 ff c0 c1 c1 ff c0 c0 c1 ff bf bf c0 ff da da db ff b2 b3 | ................................ |
| 05e0 | b4 e1 35 38 3c 09 ff ff ff 01 ff ff ff 01 ff ff ff 01 ff ff ff 01 ff ff ff 01 ff ff ff 01 ff ff | ..58<...........using CommandLine;
using Ionic.Zip;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Tango.AdvancedInstaller;
using Tango.Core;
using Tango.Core.Cryptography;
using Tango.Core.Helpers;
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))
{
throw new DirectoryNotFoundException($"Installer output folder does not exists '{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.");
}
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,
});
}
}
}
|