实现一个简单的基于码云(gitee) 的 storage

intro

上次在 一文中提到存储还不支持分布式,并立了一个 flag

基于 github 或者 开源中国的码云实现一个 storage

于是这两天就来填坑了。。

实现了一个简单的基于开源中国的码云的 storage

准备工作

码云官方有 api 接口列表

上传文件api: https://gitee.com/api/v5/swagger#/postv5reposownerrepocontentspath

新建一个仓库来存我们要保存的文件,新建的时候分支模型选择默认的单分支模型即可,只要master分支即可 ,最好直接创建 readme 或者新加一个文件以创建分支:

然后需要创建一个 accesstoken,在 设置里的私人令牌配置中新建一个token,需要 projects 权限

storage 简单实现

参考上面 gitee 提供的 api 接口,自己实现了一个简单的 giteestorageprovider ,github 完整源码:https://github.com/weihanli/activityreservation/blob/dev/activityreservation.common/storageprovider.cs

/// <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; }
}

服务注册,这里用了 httpclientfactory 来使用 httpclient,个人比较喜欢用强类型的 httpclient,如果喜欢使用通过 ihttpclientfactory 来显示创建,也可以注入一个 ihttpclientfactory ,在内部创建 httpclient

services.configure<giteestorageoptions>(configuration.getsection("storage:gitee"));
services.addhttpclient<istorageprovider, giteestorageprovider>();
services.tryaddsingleton<istorageprovider, giteestorageprovider>();

配置示例:

{
  "storage":{
    "gitee":{
      "username": "weihanli",
      "repositoryname": "storage",
      "accesstoken": "xxx"
    }
  }
}

使用效果

可以看到上传的图片已经上传到我们新建的仓库了,到仓库里看一下:

more

只实现了上传,本来想也加一个列出某个目录下的所有文件及子目录,但是看好像没有接口,如果要实现的话,可能只能基于 git 去实现,从 git 信息里获取,暂时不怎么用到,先不管了,暂时搁置吧,

reference

  • https://github.com/weihanli/activityreservation