From 0dd062ce1c294f34b653bd0ebe971b3aad728481 Mon Sep 17 00:00:00 2001 From: yystopf Date: Fri, 15 Jul 2022 17:03:18 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E:=20blobs=E5=92=8C=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E6=A0=91=E6=8E=A5=E5=8F=A3=E5=8F=8A=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/api/v1/base_controller.rb | 7 + .../api/v1/projects/git_controller.rb | 12 + .../slate/source/includes/_repositories.md | 116 ++++++- .../api/v1/projects/git/blobs_service.rb | 30 ++ .../api/v1/projects/git/trees_service.rb | 50 +++ .../api/v1/projects/git/blobs.json.jbuilder | 4 + .../api/v1/projects/git/trees.json.jbuilder | 9 + config/routes/api.rb | 2 + public/docs/api.html | 286 ++++++++++++++++-- 9 files changed, 483 insertions(+), 33 deletions(-) create mode 100644 app/controllers/api/v1/projects/git_controller.rb create mode 100644 app/services/api/v1/projects/git/blobs_service.rb create mode 100644 app/services/api/v1/projects/git/trees_service.rb create mode 100644 app/views/api/v1/projects/git/blobs.json.jbuilder create mode 100644 app/views/api/v1/projects/git/trees.json.jbuilder diff --git a/app/controllers/api/v1/base_controller.rb b/app/controllers/api/v1/base_controller.rb index 9832ee112..a66bfc528 100644 --- a/app/controllers/api/v1/base_controller.rb +++ b/app/controllers/api/v1/base_controller.rb @@ -19,6 +19,13 @@ class Api::V1::BaseController < ApplicationController # User.find(doorkeeper_token.resource_owner_id) if doorkeeper_token # end # end + + def limit + params.fetch(:limit, 15) + end + def page + params.fetch(:page, 1) + end # 具有对仓库的管理权限 def require_manager_above diff --git a/app/controllers/api/v1/projects/git_controller.rb b/app/controllers/api/v1/projects/git_controller.rb new file mode 100644 index 000000000..f30dce1a9 --- /dev/null +++ b/app/controllers/api/v1/projects/git_controller.rb @@ -0,0 +1,12 @@ +class Api::V1::Projects::GitController < Api::V1::BaseController + before_action :require_public_and_member_above, only: [:trees, :blobs] + + def trees + @result_object = Api::V1::Projects::Git::TreesService.call(@project, params[:sha], {recursive: params[:recursive], page: page, limit: limit}, current_user&.gitea_token) + end + + def blobs + @result_object = Api::V1::Projects::Git::BlobsService.call(@project, params[:sha], current_user&.gitea_token) + end + +end \ No newline at end of file diff --git a/app/docs/slate/source/includes/_repositories.md b/app/docs/slate/source/includes/_repositories.md index 624afd5b1..7da740efb 100644 --- a/app/docs/slate/source/includes/_repositories.md +++ b/app/docs/slate/source/includes/_repositories.md @@ -472,7 +472,10 @@ await octokit.request('GET /api/v1/yystopf/csfjkkj/branches/all.json') > 示例: ```shell -curl -X POST http://localhost:3000/api/v1/yystopf/csfjkkj/branches.json +curl -X POST \ +-d "new_branch_name=ceshi_branch_1" \ +-d "old_branch_name=master" \ +http://localhost:3000/api/v1/yystopf/csfjkkj/branches.json ``` ```javascript @@ -487,8 +490,8 @@ await octokit.request('POST /api/v1/yystopf/csfjkkj/branches.json') --------- | ------- | ------- | -------- | ---------- |owner |是| |string |用户登录名 | |repo |是| |string |项目标识identifier | -|new_branch_name|是||string| 新分支名称| -|old_branch_name|否||string| 来源分支名称| +|new_branch_name|是||string| 新分支名称| +|old_branch_name|否||string| 来源分支名称| ### 返回字段说明: 参数 | 类型 | 字段说明 @@ -1303,6 +1306,113 @@ await octokit.request('GET /api/yystopf/csfjkkj/readme.json') Success Data. + +## 获取文件树列表 +根据分支、标签、commit ID获取仓库文件树列表 + +> 示例: + +```shell +curl -X GET \ +-d "recursive=true" \ +-d "page=1" \ +-d "limit=1" \ +http://localhost:3000/api/v1/yystopf/csfjkkj/git/trees/80dd40214a58622312393b2ae693756a4781fab2.json +``` + +```javascript +await octokit.request('GET /api/v1/yystopf/csfjkkj/git/trees/80dd40214a58622312393b2ae693756a4781fab2.json') +``` + +### HTTP 请求 +`GET /api/v1/:owner/:repo/git/trees/:sha.json` + +### 请求参数: +参数 | 必选 | 默认 | 类型 | 字段说明 +--------- | ------- | ------- | -------- | ---------- +|owner |是| | string |用户登录名 | +|repo |是| | string |项目标识identifier | +|sha |是| | string |分支名称、tag名称或是提交记录id | +|recursive|否| | bool |是否显示目录| +|page |否|1 | int |页码| +|limit |否|15| int |分页个数| +### 返回字段说明: +参数 | 类型 | 字段说明 +--------- | ----------- | ----------- +|total_count |int |文件树数量| +|sha |string |查询分支、标签、commit_id最后一次提交的ID | +|entries.name |string |文件树名称| +|entries.mode |string |文件树权限| +|entries.type |string |文件树类型, file:文件,dir: 文件夹| +|entries.size |int |文件树大小| +|entries.sha |string |文件树commit_ID| + + +> 返回的JSON示例: + +```json +{ + "total_count": 13, + "sha": "80dd40214a58622312393b2ae693756a4781fab2", + "entries": [ + { + "name": "README.md", + "mode": "100644", + "type": "file", + "size": 14, + "sha": "b2f7b457fd8ca55f2274032cbb2abcb7dd8cd57e" + } + ] +} +``` + + +## 获取仓库blobs内容 +根据commit ID获取仓库blobs内容 + +> 示例: + +```shell +curl -X GET http://localhost:3000/api/v1/yystopf/csfjkkj/git/blobs/80dd40214a58622312393b2ae693756a4781fab2.json +``` + +```javascript +await octokit.request('GET /api/v1/yystopf/csfjkkj/git/blobs/80dd40214a58622312393b2ae693756a4781fab2.json') +``` + +### HTTP 请求 +`GET /api/v1/:owner/:repo/git/blobs/:sha.json` + +### 请求参数: +参数 | 必选 | 默认 | 类型 | 字段说明 +--------- | ------- | ------- | -------- | ---------- +|owner|是| | string |用户登录名 | +|repo |是| | string |项目标识identifier | +|sha |是| | string |提交记录id | +### 返回字段说明: +参数 | 类型 | 字段说明 +--------- | ----------- | ----------- +|sha |string |提交ID | +|size |int |blobs大小| +|encoding |string |内容编码模式| +|content |string |blobs内容| + +> 返回的JSON示例: + +```json +{ + "sha": "80dd40214a58622312393b2ae693756a4781fab2", + "size": 247, + "encoding": "base64", + "content": "dHJlZSAyN2JjYjI2ZDQ5YmU1M2RmOGZmYTk5NDc3MjRkYmI3YzIzZWI4MjY4CnBhcmVudCA3ZTRkOGJiM2MyOGUyNGQ0Y2Q2YjIwNWYyZWVkMzI1MTNlOTM3NTI0CmF1dGhvciB5eXN0b3BmIDx5eXN0b3BmQDE2My5jb20+IDE2NTc3MDYwNTUgKzAwMDAKY29tbWl0dGVyIHl5c3RvcGYgPHl5c3RvcGZAMTYzLmNvbT4gMTY1NzcwNjA1NSArMDAwMAoKeOaLn+WingoKU2lnbmVkLW9mZi1ieTogeXlzdG9wZiA8eXlzdG9wZkAxNjMuY29tPg==" +} +``` + + ## 获取仓库贡献者 获取仓库贡献者 diff --git a/app/services/api/v1/projects/git/blobs_service.rb b/app/services/api/v1/projects/git/blobs_service.rb new file mode 100644 index 000000000..0b197c106 --- /dev/null +++ b/app/services/api/v1/projects/git/blobs_service.rb @@ -0,0 +1,30 @@ +class Api::V1::Projects::Git::BlobsService < ApplicationService + include ActiveModel::Model + + attr_accessor :project, :sha, :token, :owner, :repo + attr_accessor :gitea_data + + validates :sha, presence: :true + + + def initialize(project, sha, token=nil) + @project = project + @owner = project&.owner.login + @repo = project&.identifier + @sha = sha + @token = token + end + + def call + $gitea_client.token = token unless token.blank? + load_gitea_data + + $gitea_client.token = nil unless token.blank? + gitea_data + end + + private + def load_gitea_data + @gitea_data = $gitea_client.get_repos_git_blobs_by_owner_repo_sha(owner, repo, sha) + end +end \ No newline at end of file diff --git a/app/services/api/v1/projects/git/trees_service.rb b/app/services/api/v1/projects/git/trees_service.rb new file mode 100644 index 000000000..2a72c11a5 --- /dev/null +++ b/app/services/api/v1/projects/git/trees_service.rb @@ -0,0 +1,50 @@ +class Api::V1::Projects::Git::TreesService < ApplicationService + include ActiveModel::Model + + attr_accessor :project, :token, :sha, :recursive, :page, :limit, :owner, :repo + attr_accessor :gitea_data + + validates :sha, presence: :true + validates :recursive, inclusion: {in: [nil, '', true, false]} + + def initialize(project, sha, params, token=nil) + @project = project + @owner = project&.owner.login + @repo = project&.identifier + @token = token + @sha = sha + @recursive = params[:recursive] + @page = params[:page] || 1 + @limit = params[:limit] || 15 + end + + def call + raise Error, errors.full_messages.join(", ") unless valid? + $gitea_client.token = token unless token.blank? + load_gitea_data + + $gitea_client.token = nil unless token.blank? + gitea_data + end + + private + def request_query + if recursive.present? + { + recursive: recursive, + page: page, + per_page: limit + } + else + { + page: page, + per_page: limit + } + end + end + + def load_gitea_data + @gitea_data = $gitea_client.get_repos_git_trees_by_owner_repo_sha(owner, repo, sha, {query: request_query}) + raise Error, '获取文件树列表失败!' unless @gitea_data.is_a?(Hash) + end +end \ No newline at end of file diff --git a/app/views/api/v1/projects/git/blobs.json.jbuilder b/app/views/api/v1/projects/git/blobs.json.jbuilder new file mode 100644 index 000000000..e5397e925 --- /dev/null +++ b/app/views/api/v1/projects/git/blobs.json.jbuilder @@ -0,0 +1,4 @@ +json.sha @result_object['sha'] +json.size @result_object['size'] +json.encoding @result_object['encoding'] +json.content @result_object['content'] \ No newline at end of file diff --git a/app/views/api/v1/projects/git/trees.json.jbuilder b/app/views/api/v1/projects/git/trees.json.jbuilder new file mode 100644 index 000000000..0eb08f048 --- /dev/null +++ b/app/views/api/v1/projects/git/trees.json.jbuilder @@ -0,0 +1,9 @@ +json.total_count @result_object['total_count'] +json.sha @result_object['sha'] +json.entries @result_object['tree'].each do |entry| + json.name entry['path'] + json.mode entry['mode'] + json.type entry['type'] === 'blob' ? 'file' : 'dir' + json.size entry['size'] + json.sha entry['sha'] +end \ No newline at end of file diff --git a/config/routes/api.rb b/config/routes/api.rb index c969302ba..99684e6d9 100644 --- a/config/routes/api.rb +++ b/config/routes/api.rb @@ -28,6 +28,8 @@ defaults format: :json do get :all end end + get '/git/blobs/:sha', to: 'git#blobs' + get '/git/trees/:sha', to: 'git#trees' end end diff --git a/public/docs/api.html b/public/docs/api.html index e9091591e..6fedc946e 100644 --- a/public/docs/api.html +++ b/public/docs/api.html @@ -547,6 +547,12 @@
  • 获取仓库README文件
  • +
  • + 获取文件树列表 +
  • +
  • + 获取仓库blobs内容 +
  • 获取仓库贡献者
  • @@ -7895,7 +7901,10 @@ http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects/organizat

    示例:

    -
    curl -X POST http://localhost:3000/api/v1/yystopf/csfjkkj/branches.json
    +
    curl -X POST \
    +-d "new_branch_name=ceshi_branch_1" \
    +-d "old_branch_name=master" \
    +http://localhost:3000/api/v1/yystopf/csfjkkj/branches.json
     
    await octokit.request('POST /api/v1/yystopf/csfjkkj/branches.json')
     

    HTTP 请求

    POST /api/v1/:owner/:repo/branches.json

    @@ -7925,17 +7934,17 @@ http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects/organizat new_branch_name -是||string +是 + +string 新分支名称 - - old_branch_name -否| +否 + string 来源分支名称 -

    返回字段说明:

    @@ -9436,6 +9445,223 @@ http://localhost:3000/api/yystopf/csfjkkj/readme.json +

    获取文件树列表

    +

    根据分支、标签、commit ID获取仓库文件树列表

    + +
    +

    示例:

    +
    +
    curl -X GET \
    +-d "recursive=true" \
    +-d "page=1" \
    +-d "limit=1" \
    +http://localhost:3000/api/v1/yystopf/csfjkkj/git/trees/80dd40214a58622312393b2ae693756a4781fab2.json
    +
    await octokit.request('GET /api/v1/yystopf/csfjkkj/git/trees/80dd40214a58622312393b2ae693756a4781fab2.json')
    +

    HTTP 请求

    +

    GET /api/v1/:owner/:repo/git/trees/:sha.json

    +

    请求参数:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    参数必选默认类型字段说明
    ownerstring用户登录名
    repostring项目标识identifier
    shastring分支名称、tag名称或是提交记录id
    recursivebool是否显示目录
    page1int页码
    limit15int分页个数
    +

    返回字段说明:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    参数类型字段说明
    total_countint文件树数量
    shastring查询分支、标签、commit_id最后一次提交的ID
    entries.namestring文件树名称
    entries.modestring文件树权限
    entries.typestring文件树类型, file:文件,dir: 文件夹
    entries.sizeint文件树大小
    entries.shastring文件树commit_ID
    + +
    +

    返回的JSON示例:

    +
    +
    {
    +    "total_count": 13,
    +    "sha": "80dd40214a58622312393b2ae693756a4781fab2",
    +    "entries": [
    +        {
    +            "name": "README.md",
    +            "mode": "100644",
    +            "type": "file",
    +            "size": 14,
    +            "sha": "b2f7b457fd8ca55f2274032cbb2abcb7dd8cd57e"
    +        }
    +    ]
    +}
    +
    + +

    获取仓库blobs内容

    +

    根据commit ID获取仓库blobs内容

    + +
    +

    示例:

    +
    +
    curl -X GET http://localhost:3000/api/v1/yystopf/csfjkkj/git/blobs/80dd40214a58622312393b2ae693756a4781fab2.json
    +
    await octokit.request('GET /api/v1/yystopf/csfjkkj/git/blobs/80dd40214a58622312393b2ae693756a4781fab2.json')
    +

    HTTP 请求

    +

    GET /api/v1/:owner/:repo/git/blobs/:sha.json

    +

    请求参数:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    参数必选默认类型字段说明
    ownerstring用户登录名
    repostring项目标识identifier
    shastring提交记录id
    +

    返回字段说明:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    参数类型字段说明
    shastring提交ID
    sizeintblobs大小
    encodingstring内容编码模式
    contentstringblobs内容
    + +
    +

    返回的JSON示例:

    +
    +
    {
    +    "sha": "80dd40214a58622312393b2ae693756a4781fab2",
    +    "size": 247,
    +    "encoding": "base64",
    +    "content": "dHJlZSAyN2JjYjI2ZDQ5YmU1M2RmOGZmYTk5NDc3MjRkYmI3YzIzZWI4MjY4CnBhcmVudCA3ZTRkOGJiM2MyOGUyNGQ0Y2Q2YjIwNWYyZWVkMzI1MTNlOTM3NTI0CmF1dGhvciB5eXN0b3BmIDx5eXN0b3BmQDE2My5jb20+IDE2NTc3MDYwNTUgKzAwMDAKY29tbWl0dGVyIHl5c3RvcGYgPHl5c3RvcGZAMTYzLmNvbT4gMTY1NzcwNjA1NSArMDAwMAoKeOaLn+WingoKU2lnbmVkLW9mZi1ieTogeXlzdG9wZiA8eXlzdG9wZkAxNjMuY29tPg=="
    +}
    +
    +

    获取仓库贡献者

    获取仓库贡献者

    @@ -9447,9 +9673,9 @@ http://localhost:3000/api/yystopf/csfjkkj/readme.json -d "filepath=lib" \ http://localhost:3000/api/yystopf/csfjkkj/contributors.json
    await octokit.request('GET /api/yystopf/csfjkkj/contributors.json')
    -

    HTTP 请求

    +

    HTTP 请求

    GET /api/:owner/:repo/contributors.json

    -

    请求参数:

    +

    请求参数:

    @@ -9488,7 +9714,7 @@ http://localhost:3000/api/yystopf/csfjkkj/contributors.json
    参数子目录名称,默认为空
    -

    返回字段说明:

    +

    返回字段说明:

    @@ -9563,9 +9789,9 @@ http://localhost:3000/api/yystopf/csfjkkj/contributors.json
    curl -X GET \
     http://localhost:3000/api/v1/yystopf/ceshi/webhooks.json
     
    await octokit.request('GET /api/v1/yystopf/ceshi/webhooks.json')
    -

    HTTP 请求

    +

    HTTP 请求

    GET /api/v1/:owner/:repo/webhooks.json

    -

    请求参数:

    +

    请求参数:

    参数
    @@ -9590,7 +9816,7 @@ http://localhost:3000/api/v1/yystopf/ceshi/webhooks.json
    参数项目标识identifier
    -

    返回字段说明:

    +

    返回字段说明:

    @@ -9683,9 +9909,9 @@ http://localhost:3000/api/v1/yystopf/ceshi/webhooks.json
    curl -X GET \
     http://localhost:3000/api/v1/yystopf/ceshi/webhooks/3.json
     
    await octokit.request('GET /api/v1/yystopf/ceshi/webhooks/3.json')
    -

    HTTP 请求

    +

    HTTP 请求

    GET /api/v1/:owner/:repo/webhooks/:id.json

    -

    请求参数:

    +

    请求参数:

    参数
    @@ -9717,7 +9943,7 @@ http://localhost:3000/api/v1/yystopf/ceshi/webhooks/3.json
    参数webhook ID
    -

    返回字段说明:

    +

    返回字段说明:

    @@ -9840,9 +10066,9 @@ http://localhost:3000/api/v1/yystopf/ceshi/webhooks/3.json
    curl -X POST \
     http://localhost:3000/api/v1/yystopf/ceshi/webhooks.json
     
    await octokit.request('POST /api/v1/yystopf/ceshi/webhooks.json')
    -

    HTTP 请求

    +

    HTTP 请求

    POST /api/v1/:owner/:repo/webhooks.json

    -

    请求参数:

    +

    请求参数:

    参数
    @@ -9967,7 +10193,7 @@ http://localhost:3000/api/v1/yystopf/ceshi/webhooks.json "branch_filter": "*", "events": ["push"] } -

    返回字段说明:

    +

    返回字段说明:

    参数
    @@ -10046,9 +10272,9 @@ http://localhost:3000/api/v1/yystopf/ceshi/webhooks.json
    curl -X PATCH \
     http://localhost:3000/api/v1/yystopf/ceshi/webhooks/7.json
     
    await octokit.request('PATCH /api/v1/yystopf/ceshi/webhooks/7.json')
    -

    HTTP 请求

    +

    HTTP 请求

    PATCH /api/v1/:owner/:repo/webhooks/68.json

    -

    请求参数:

    +

    请求参数:

    参数
    @@ -10180,7 +10406,7 @@ http://localhost:3000/api/v1/yystopf/ceshi/webhooks/7.json "branch_filter": "*", "events": ["push"] } -

    返回字段说明:

    +

    返回字段说明:

    返回的JSON示例:

    @@ -10215,9 +10441,9 @@ http://localhost:3000/api/v1/yystopf/ceshi/webhooks/7.json
    curl -X DELETE \
     http://localhost:3000/api/v1/yystopf/ceshi/webhooks/7.json
     
    await octokit.request('DELETE /api/v1/yystopf/ceshi/webhooks/7.json')
    -

    HTTP 请求

    +

    HTTP 请求

    DELETE /api/v1/:owner/:repo/webhooks/:id.json

    -

    请求参数:

    +

    请求参数:

    参数
    @@ -10249,7 +10475,7 @@ http://localhost:3000/api/v1/yystopf/ceshi/webhooks/7.json
    参数webhook id
    -

    返回字段说明:

    +

    返回字段说明:

    返回的JSON示例:

    @@ -10270,9 +10496,9 @@ http://localhost:3000/api/v1/yystopf/ceshi/webhooks/7.json
    curl -X GET \
     http://localhost:3000/api/v1/yystopf/ceshi/webhooks/3/hooktasks.json
     
    await octokit.request('GET /api/v1/yystopf/ceshi/webhooks/3/hooktasks.json')
    -

    HTTP 请求

    +

    HTTP 请求

    GET /api/v1/:owner/:repo/webhooks/:id/hooktasks.json

    -

    请求参数:

    +

    请求参数:

    @@ -10304,7 +10530,7 @@ http://localhost:3000/api/v1/yystopf/ceshi/webhooks/3/hooktasks.json
    参数webhook ID
    -

    返回字段说明:

    +

    返回字段说明:

    @@ -10541,9 +10767,9 @@ http://localhost:3000/api/v1/yystopf/ceshi/webhooks/3/hooktasks.json
    curl -X POST \
     http://localhost:3000/api/v1/yystopf/ceshi/webhooks/3/tests.json
     
    await octokit.request('POST /api/v1/yystopf/ceshi/webhooks/3/tests.json')
    -

    HTTP 请求

    +

    HTTP 请求

    POST /api/v1/:owner/:repo/webhooks/:id/tests.json

    -

    请求参数:

    +

    请求参数:

    参数
    @@ -10575,7 +10801,7 @@ http://localhost:3000/api/v1/yystopf/ceshi/webhooks/3/tests.json
    参数webhook ID
    -

    返回字段说明:

    +

    返回字段说明:

    返回的JSON示例: