ibcadmin 发表于 2019-9-12 16:22:21

实现一个基于码云的Storage

<h1 id="实现一个简单的基于码云gitee-的-storage">实现一个简单的基于码云(Gitee) 的 Storage</h1>
<h2 id="intro">Intro</h2>
<p>上次在 asp.net core 从单机到集群 一文中提到存储还不支持分布式,并立了一个 flag</p>
<blockquote>
<p>基于 github 大概 开源中国的码云实现一个 storage</p>
</blockquote>
<p>于是这两天就来填坑了。。</p>
<p>实现了一个简单的基于开源中国的码云的 storage</p>
<h2 id="准备工作">准备工作</h2>
<p>码云官方有 API 接口列表 https://gitee.com/api/v5/swagger</p>
<p>上传文件API: https://gitee.com/api/v5/swagger#/postV5ReposOwnerRepoContentsPath</p>
<p><div align="center"></div></p>
<p>新建一个仓库来存我们要生存的文件,新建的时间分支模型选择默认的单分支模型即可,只要master分支即可 ,最好直接创建 readme 大概新加一个文件以创建分支:</p>
<p>然后必要创建一个 accessToken,在 设置里的私人令牌设置中新建一个token,必要 <code>projects</code> 权限</p>
<p><div align="center"></div></p>
<h2 id="storage-简单实现">Storage 简单实现</h2>
<p>参考上面 Gitee 提供的 API 接口,自己实现了一个简单的 <code>GiteeStorageProvider</code> ,Github 完整源码:https://github.com/WeihanLi/ActivityReservation/blob/dev/ActivityReservation.Common/StorageProvider.cs</p>
<code>/// <summary>
/// 码云存储
/// </summary>
public class GiteeStorageProvider : IStorageProvider
{
    private const string PostFileApiUrlFormat = "https://gitee.com/api/v5/repos/{0}/{1}/contents{2}";
    private const string RawFileUrlFormat = "https://gitee.com/{0}/{1}/raw/master{2}";

    private readonly HttpClient _httpClient;
    private readonly ILogger _logger;
    private readonly GiteeStorageOptions _options;

    public GiteeStorageProvider(HttpClient httpClient, ILogger<GiteeStorageProvider> logger, IOptions<GiteeStorageOptions> options)
    {
      _logger = logger;
      _httpClient = httpClient;
      _options = options.Value;
    }

    public async Task<string> SaveBytes(byte[] bytes, string filePath)
    {
      var base64Str = Convert.ToBase64String(bytes);
      using (var response = await _httpClient.PostAsFormAsync(PostFileApiUrlFormat.FormatWith(_options.UserName, _options.RepositoryName, filePath),
            new Dictionary<string, string>
            {
                { "access_token", _options.AccessToken },
                { "content", base64Str },
                { "message" , $"add file" }
            }))
      {
            if (response.IsSuccessStatusCode)
            {
                return RawFileUrlFormat
                  .FormatWith(_options.UserName, _options.RepositoryName, filePath);
            }

            var result = await response.Content.ReadAsStringAsync();
            _logger.LogWarning($"post file error, response: {result}");

            return null;
      }
    }
}

public class GiteeStorageOptions
{
    public string UserName { get; set; }

    public string RepositoryName { get; set; }

    public string AccessToken { get; set; }
}
</code>
<p>服务注册,这里用了 <code>HttpClientFactory</code> 来利用 <code>HttpClient</code>,个人比力喜好用强范例的 HttpClient,假如喜好利用通过 <code>IHttpClientFactory</code> 来表现创建,也可以注入一个 <code>IHttpClientFactory</code> ,在内部创建 <code>HttpClient</code></p>
<code>services.Configure<GiteeStorageOptions>(Configuration.GetSection("Storage:Gitee"));
services.AddHttpClient<IStorageProvider, GiteeStorageProvider>();
services.TryAddSingleton<IStorageProvider, GiteeStorageProvider>();</code>
<p>设置示例:</p>
<code>{
"Storage":{
    "Gitee":{
      "UserName": "weihanli",
      "RepositoryName": "storage",
      "AccessToken": "xxx"
    }
}
}</code>
<h2 id="利用结果">利用结果</h2>
<p><div align="center"></div></p>
<p>可以看到上传的图片已经上传到我们新建的仓库了,到仓库里看一下:</p>
<p><div align="center"></div></p>
<h2 id="more">More</h2>
<p>只实现了上传,原来想也加一个列出某个目次下的所有文件及子目次,但是看似乎没有接口,假如要实现的话,大概只能基于 git 去实现,从 git 信息里获取,临时不怎么用到,先不管了,临时搁置吧,</p>
<h2 id="reference">Reference</h2>
<ul>
<li>https://www.jianshu.com/p/224954dadcaf</li>
<li>https://gitee.com/weihanli/storage</li>
<li>https://github.com/WeihanLi/ActivityReservation</li>
</ul><br><br/><br/><br/><br/><br/>来源:<a href="https://www.cnblogs.com/weihanli/archive/2019/09/10/implement-a-storage-provider-based-on-gitee.html" target="_blank">https://www.cnblogs.com/weihanli/archive/2019/09/10/implement-a-storage-provider-based-on-gitee.html</a>
页: [1]
查看完整版本: 实现一个基于码云的Storage