aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Azure/Tango.AzureUtils/FTP/FtpManager.cs
blob: 5a174dcb2fae5d6bfecadb77b193f28474bff76b (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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Authentication;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using FluentFTP;
using Microsoft.Azure.Management.AppService.Fluent;
using Microsoft.Azure.Management.Fluent;

namespace Tango.AzureUtils.FTP
{
    public class FtpManager : AzureUtilsComponentBase
    {
        private IProgress<FtpProgress> _ftpDownloadProgress;
        private IProgress<FtpProgress> _ftpUploadProgress;
        private String _currentDownloadFile;

        public FtpManager(IAzure azure) : base(azure)
        {
            _ftpDownloadProgress = new Progress<FtpProgress>((p) =>
            {
                OnProgress(AzureUtilsStage.FtpDownload, $"Downloading {_currentDownloadFile}...", p.Progress, 100, false);
            });

            _ftpUploadProgress = new Progress<FtpProgress>((p) =>
            {
                OnProgress(AzureUtilsStage.FtpUpload, $"Uploading {_currentDownloadFile}...", p.Progress, 100, false);
            });
        }

        private FtpClient CreateFtpClient(String address, String userName, String password)
        {
            Uri uri = new Uri("ftp://" + address);
            string host = uri.Host;

            FtpClient client = new FtpClient(host, userName, password);
            //client.EncryptionMode = FtpEncryptionMode.Explicit;
            client.SslProtocols = SslProtocols.Tls;
            client.ValidateAnyCertificate = true;
            client.DataConnectionType = FtpDataConnectionType.PASV;
            client.DownloadDataType = FtpDataType.Binary;
            client.RetryAttempts = 5;
            client.SocketPollInterval = 1000;
            client.ConnectTimeout = 2000;
            client.ReadTimeout = 2000;
            client.DataConnectionConnectTimeout = 2000;
            client.DataConnectionReadTimeout = 2000;
            client.OnLogEvent = (ev, msg) => 
            {
                if (msg.Contains("DownloadFileAsync") || msg.Contains("UploadFileAsync"))
                {
                    var matches = Regex.Matches(msg, "(?<=\").+?(?=\")");
                    var match = matches.OfType<Match>().LastOrDefault();

                    if (match != null)
                    {
                        _currentDownloadFile = match.ToString();
                    }
                }
            };

            return client;
        }

        public async Task<List<FtpResult>> DownloadWebAppFiles(IWebAppBase app, String targetFolder)
        {
            OnProgress(AzureUtilsStage.FtpDownload, $"Downloading web app files for '{app.Name}'...");

            var profile = await app.GetPublishingProfileAsync();

            using (var ftp = CreateFtpClient(profile.FtpUrl, profile.FtpUsername, profile.FtpPassword))
            {
                await ftp.ConnectAsync();
                var downloadResults = await ftp.DownloadDirectoryAsync(targetFolder, "/site/wwwroot", progress: _ftpDownloadProgress);

                foreach (var downloadResult in downloadResults)
                {
                    if (downloadResult.IsFailed)
                    {
                        throw downloadResult.Exception;
                    }
                }

                return downloadResults;
            }
        }

        public async Task<List<FtpResult>> UploadWebAppFiles(IWebAppBase app, String sourceFolder)
        {
            OnProgress(AzureUtilsStage.FtpUpload, $"Uploading web app files for '{app.Name}'...");

            var profile = await app.GetPublishingProfileAsync();

            using (var ftp = CreateFtpClient(profile.FtpUrl, profile.FtpUsername, profile.FtpPassword))
            {
                var uploadResults = await ftp.UploadDirectoryAsync(sourceFolder, "/site/wwwroot", existsMode: FtpRemoteExists.Overwrite, progress: _ftpUploadProgress);

                foreach (var uploadResult in uploadResults)
                {
                    if (uploadResult.IsFailed)
                    {
                        throw uploadResult.Exception;
                    }
                }

                return uploadResults;
            }
        }

        public async Task CopyAppFiles(IWebAppBase sourceApp, IWebAppBase targetApp)
        {
            var webAppFilesTempFolder = TemporaryManager.CreateFolder();
            var downloadResults = await DownloadWebAppFiles(sourceApp, webAppFilesTempFolder);
            var uploadResults = await UploadWebAppFiles(targetApp, webAppFilesTempFolder);
        }
    }
}