ReleaseDownloader.cs 5.5 KB
Newer Older
麦壳饼's avatar
麦壳饼 已提交
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 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Mime;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace IoTSharp.Releases
{
    public class ReleaseDownloader
    {
        private readonly string _baseUri;

        private readonly string _accessToken;

        private readonly string _userAgent;

        private readonly string _releaseUri;

        private string _user;
        private string _repo;
        private string _token;


        public ReleaseDownloader(string _url, string accessToken)
        {
            var uri = new Uri(_url);
            _baseUri = $"{ GetBaseUri(uri)}/repos/{GetUserFromUri(uri)}/{GetRepoFromUri(uri)}";
            _accessToken = accessToken;
            _userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3829.0 Safari/537.36 Edg/77.0.197.1"; ;
            _releaseUri = GetReleaseUri();
        }

        private static string GetUserFromUri(Uri uri)
        {
            return !uri.LocalPath.Contains("/") ? string.Empty : uri.Segments[1].TrimEnd('/');
        }

        private static string GetRepoFromUri(Uri uri)
        {
            return !uri.LocalPath.Contains("/") ? string.Empty : uri.Segments[2].TrimEnd('/');
        }

        private static string GetBaseUri(Uri uri)
        {
            return uri.Host.Equals("github.com", StringComparison.OrdinalIgnoreCase) ? "https://api.github.com" : $"{uri.Scheme}://{uri.Host}/api/v3";
        }


        public ICollection<GithubRelease> GetDataForAllReleases()
        {
            var requestingUri = GetAccessTokenUri(_releaseUri);
            return DownloadReleases(requestingUri);
        }

        public ICollection<GithubRelease> DownloadReleases(string requestingUri)
        {

            Console.WriteLine("Requesting: {0}", requestingUri);
            var request = (HttpWebRequest)WebRequest.Create(new Uri(requestingUri));
            request.UserAgent = _userAgent;

            var response = request.GetResponse();
            Console.WriteLine(((HttpWebResponse)response).StatusDescription);
            // Get the stream containing content returned by the server.

            var responseFromServer = ReadResponseFromServer(response);

            var releases = JsonConvert.DeserializeObject<List<GithubRelease>>(responseFromServer);

            var parser = new LinkHeaderParser();

            var linkHeader = response.Headers["Link"];

            var nextUrl = parser.GetNextPageFromHeader(linkHeader);

            if (!string.IsNullOrEmpty(nextUrl))
            {
                releases.AddRange(DownloadReleases(nextUrl));
            }

            // Clean up the streams and the response.
            response.Close();
            return releases;
        }

        private string GetReleaseUri()
        {
            var releaseUri = $"{_baseUri}/releases";
            return releaseUri;
        }

        private static string ReadResponseFromServer(WebResponse response)
        {
            using (var dataStream = response.GetResponseStream())
            {
                // Open the stream using a StreamReader for easy access.
                using (var reader = new StreamReader(dataStream))
                {
                    // Read the content.
                    return reader.ReadToEnd();
                }
            }
        }

        private string GetAssetsUriForId(string id)
        {
            var assetUri = $"{_releaseUri}/assets/{id}";
            return assetUri;
        }

        private string GetAccessTokenUri(string uri)
        {
            return _accessToken == string.Empty ? uri : uri += $"?access_token={_accessToken}";
        }

        public bool DownloadAsset(string id, string path)
        {
            WebResponse response = GetAssetResponse(id);
            GetBinaryResponseFromResponse(path,response);
            return true;
        }
        public bool DownloadAsset(string id, out byte[] assetdata)
        {
            WebResponse response = GetAssetResponse(id);
            assetdata = GetBinaryResponseFromResponse(response);
            return true;
        }

        private WebResponse GetAssetResponse(string id)
        {
            var assetUri = GetAccessTokenUri(GetAssetsUriForId(id));

            var request = (HttpWebRequest)WebRequest.Create(new Uri(assetUri));
            request.Accept = "application/octet-stream";
            request.UserAgent = "mwhitis";

            var response = request.GetResponse();
            return response;
        }

        private static byte[] GetBinaryResponseFromResponse( WebResponse response)
        {
            byte[] result = null;
            long received = 0;
            byte[] buffer = new byte[1024];
            using (var ms = new  MemoryStream() )
            {
                using (var input = response.GetResponseStream())
                {
                    int size = input.Read(buffer, 0, buffer.Length);
                    while (size > 0)
                    {
                        ms.Write(buffer, 0, size);
                        received += size;

                        size = input.Read(buffer, 0, buffer.Length);
                    }
                }

                result = ms.ToArray();
            }
            return result;
        }
        private static void GetBinaryResponseFromResponse(string path, WebResponse response)
        {
            System.IO.File.WriteAllBytes(path, GetBinaryResponseFromResponse(response));
        }
    }
}