Merge branch 'pre_trustie_server' into trustie_server

This commit is contained in:
“xxq250” 2022-07-21 17:12:03 +08:00
commit de538364f4
45 changed files with 3498 additions and 476 deletions

View File

@ -135,4 +135,4 @@ gem 'doorkeeper'
gem 'doorkeeper-jwt'
gem 'gitea-client', '~> 0.8.2'
gem 'gitea-client', '~> 0.10.2'

View File

@ -1,10 +1,33 @@
class Admins::DashboardsController < Admins::BaseController
def index
@active_user_count = User.where(last_login_on: today).count
@weekly_active_user_count = User.where(last_login_on: current_week).count
@month_active_user_count = User.where(last_login_on: current_month).count
# 用户活跃数
day_user_ids = CommitLog.where(created_at: today).pluck(:project_id).uniq
weekly_user_ids = CommitLog.where(created_at: current_week).pluck(:project_id).uniq
month_user_ids = CommitLog.where(created_at: current_month).pluck(:project_id).uniq
@active_user_count = User.where(last_login_on: today).or(User.where(id: day_user_ids)).count
@weekly_active_user_count = User.where(last_login_on: current_week).or(User.where(id: weekly_user_ids)).count
@month_active_user_count = User.where(last_login_on: current_month).or(User.where(id: month_user_ids)).count
user_ids = User.where(created_on: pre_week).pluck(:id).uniq
weekly_keep_user_count = User.where(id: user_ids).where(last_login_on: current_week).count
@weekly_keep_rate = format("%.2f", user_ids.size > 0 ? weekly_keep_user_count.to_f / user_ids.size : 0)
@new_user_count = User.where(created_on: current_month).count
# 新用户注册数
@day_new_user_count = User.where(created_on: today).count
@weekly_new_user_count = User.where(created_on: current_week).count
@month_new_user_count = User.where(created_on: current_month).count
# 活跃项目数
day_project_ids = (CommitLog.where(created_at: today).pluck(:project_id).uniq + Issue.where(created_on: today).pluck(:project_id).uniq).uniq
weekly_project_ids = (CommitLog.where(created_at: current_week).pluck(:project_id).uniq + Issue.where(created_on: current_week).pluck(:project_id).uniq).uniq
month_project_ids = (CommitLog.where(created_at: current_month).pluck(:project_id).uniq + Issue.where(created_on: current_month).pluck(:project_id).uniq).uniq
@day_active_project_count = Project.where(updated_on: today).or(Project.where(id: day_project_ids)).count
@weekly_active_project_count = Project.where(updated_on: current_week).or(Project.where(id: weekly_project_ids)).count
@month_active_project_count = Project.where(updated_on: current_month).or(Project.where(id: month_project_ids)).count
# 新增项目数
@day_new_project_count = Project.where(created_on: today).count
@weekly_new_project_count = Project.where(created_on: current_week).count
@month_new_project_count = Project.where(created_on: current_month).count
end
def month_active_user
@ -16,7 +39,6 @@ class Admins::DashboardsController < Admins::BaseController
{ value: count['professional'].to_i, name: '专业人士' },
{ value: count[nil].to_i, name: '未选职业' },
]
render_ok(data: data)
end
@ -42,10 +64,14 @@ class Admins::DashboardsController < Admins::BaseController
end
def current_week
7.days.ago.beginning_of_day..Time.now.end_of_day
7.days.ago.end_of_day..Time.now.end_of_day
end
def current_month
30.days.ago.beginning_of_day..Time.now.end_of_day
30.days.ago.end_of_day..Time.now.end_of_day
end
def pre_week
14.days.ago.end_of_day..7.days.ago.end_of_day
end
end

View File

@ -20,8 +20,28 @@ class Api::V1::BaseController < ApplicationController
# end
# end
def limit
params.fetch(:limit, 15)
end
def page
params.fetch(:page, 1)
end
# 具有对仓库的管理权限
def require_manager_above
@project = load_project
return render_forbidden unless current_user.admin? && @project.manager?(current_user)
end
# 具有对仓库的操作权限
def require_operate_above
@project = load_project
return render_forbidden unless current_user.admin? && @project.operator?(current_user)
end
# 具有对仓库的访问权限
def require_public_and_member_above
@project = load_project
return render_forbidden unless @project.is_public || (current_user.admin? && @project.member?(current_user))
end
end

View File

@ -0,0 +1,18 @@
class Api::V1::Projects::BranchesController < Api::V1::BaseController
before_action :require_public_and_member_above, only: [:all]
def all
@result_object = Api::V1::Projects::Branches::AllListService.call(@project, current_user&.gitea_token)
end
before_action :require_operate_above, only: [:create]
def create
@result_object = Api::V1::Projects::Branches::CreateService.call(@project, branch_params, current_user&.gitea_token)
end
private
def branch_params
params.require(:branch).permit(:new_branch_name, :old_branch_name)
end
end

View File

@ -0,0 +1,12 @@
class Api::V1::Projects::CommitsController < Api::V1::BaseController
before_action :require_public_and_member_above, only: [:index, :diff]
def index
@result_object = Api::V1::Projects::Commits::ListService.call(@project, {page: page, limit: limit, sha: params[:sha]}, current_user&.gitea_token)
puts @result_object
end
def diff
@result_object = Api::V1::Projects::Commits::DiffService.call(@project, params[:sha], current_user&.gitea_token)
end
end

View File

@ -0,0 +1,13 @@
class Api::V1::Projects::ContentsController < Api::V1::BaseController
before_action :require_operate_above, only: [:batch]
def batch
@result_object = Api::V1::Projects::Contents::BatchCreateService.call(@project, batch_content_params, current_user&.gitea_token)
puts @result_object
end
private
def batch_content_params
params.require(:content).permit(:author_email, :author_name, :author_timeunix, :branch, :committer_email, :committer_name, :committer_timeunix, :message, :new_branch, files: [ :action_type, :content, :encoding, :file_path])
end
end

View File

@ -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

View File

@ -1,5 +1,5 @@
class Api::V1::ProjectsController < Api::V1::BaseController
before_action :load_project, only: [:show]
before_action :require_public_and_member_above, only: [:show, :compare, :blame]
def index
render_ok
@ -8,4 +8,13 @@ class Api::V1::ProjectsController < Api::V1::BaseController
def show
@result_object = Api::V1::Projects::GetService.call(@project, current_user.gitea_token)
end
def compare
@result_object = Api::V1::Projects::CompareService.call(@project, params[:from], params[:to], current_user&.gitea_token)
end
def blame
@result_object = Api::V1::Projects::BlameService.call(@project, params[:sha], params[:filepath], current_user&.gitea_token)
puts @result_object
end
end

View File

@ -8,7 +8,7 @@ module Api::ProjectHelper
@project, @owner = Project.find_with_namespace(namespace, repo)
if @project
logger.info "###########project not founded"
logger.info "###########project founded"
@project
else
logger.info "###########project not found"

View File

@ -409,21 +409,21 @@ await octokit.request('GET /api/yystopf/csfjkkj/tags.json')
```
## 仓库分支列表
仓库分支列表
## 仓库所有分支列表
仓库所有分支列表
> 示例:
```shell
curl -X GET http://localhost:3000/api/yystopf/csfjkkj/branches.json
curl -X GET http://localhost:3000/api/v1/yystopf/csfjkkj/branches/all.json
```
```javascript
await octokit.request('GET /api/yystopf/csfjkkj/branches.json')
await octokit.request('GET /api/v1/yystopf/csfjkkj/branches/all.json')
```
### HTTP 请求
`GET /api/:owner/:repo/branches.json`
`GET /api/v1/:owner/:repo/branches/all.json`
### 请求参数:
参数 | 必选 | 默认 | 类型 | 字段说明
@ -466,6 +466,98 @@ await octokit.request('GET /api/yystopf/csfjkkj/branches.json')
]
```
## 仓库创建分支
为仓库创建一个新的分支
> 示例:
```shell
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
await octokit.request('POST /api/v1/yystopf/csfjkkj/branches.json')
```
### HTTP 请求
`POST /api/v1/:owner/:repo/branches.json`
### 请求参数:
参数 | 必选 | 默认 | 类型 | 字段说明
--------- | ------- | ------- | -------- | ----------
|owner |是| |string |用户登录名 |
|repo |是| |string |项目标识identifier |
|new_branch_name|是||string| 新分支名称|
|old_branch_name|否||string| 来源分支名称|
### 返回字段说明:
参数 | 类型 | 字段说明
--------- | ----------- | -----------
|name |string|分支名称|
|commit.id |string|提交ID|
|commit.message |string|提交信息|
|commit.author.id |string|提交作者ID|
|commit.author.login |string|提交作者标识|
|commit.author.name |string|提交作者名称|
|commit.author.type |string|提交作者类型|
|commit.committer.id |string|提交者ID|
|commit.committer.login |string|提交者标识|
|commit.committer.name |string|提交者名称|
|commit.committer.type |string|提交者类型|
|commit.committer.image_url|string|提交者头像|
|commit.time_ago |string|分支最新提交时间距现在时间差|
|commit.timestamp |string|分支最新提交时间|
|protected |bool |是否为保护分支|
|user_can_push |bool |当前用户是否能提交|
|user_can_merge |bool |当前用户是否能合并|
|commit_id |string|提交ID|
|commit_time_from_now |string|分支最新提交时间距现在时间差|
|commit_time |string|分支最新提交时间|
|http_url |string|分支http地址|
|zip_url |string|分支zip包下载地址|
|tar_url |string|分支tar包下载地址|
> 返回的JSON示例:
```json
{
"name": "new_branch_8",
"commit": {
"id": "80dd40214a58622312393b2ae693756a4781fab2",
"message": "x拟增\n\nSigned-off-by: yystopf <yystopf@163.com>",
"author": {
"id": "2",
"login": "yystopf",
"name": "heh",
"type": "User",
"image_url": "system/lets/letter_avatars/2/H/188_239_142/120.png"
},
"committer": {
"id": "2",
"login": "yystopf",
"name": "heh",
"type": "User",
"image_url": "system/lets/letter_avatars/2/H/188_239_142/120.png"
},
"time_ago": "1天前",
"timestamp": "2022-07-13T09:54:15Z"
},
"protected": false,
"user_can_push": true,
"user_can_merge": true,
"commit_id": "80dd40214a58622312393b2ae693756a4781fab2",
"commit_time_from_now": "1天前",
"commit_time": "2022-07-13T09:54:15Z",
"default_branch": "master",
"http_url": "http://127.0.0.1:10081/yystopf/ceshi_hook.git",
"zip_url": "http://localhost:3000/api/yystopf/ceshi_hook/archive/new_branch_8.zip",
"tar_url": "http://localhost:3000/api/yystopf/ceshi_hook/archive/new_branch_8.tar.gz"
}
```
## 仓库贡献者列表
仓库贡献者列表
@ -1001,6 +1093,138 @@ await octokit.request('GET /api/yystopf/ceshi/files.json')
]
```
## 提交文件到仓库
提交文件到仓库,支持批量
> 示例:
```shell
curl -X POST \
-d "files[][action_type]=create" \
-d "files[][content]=jfksj" \
-d "files[][encoding]=text" \
-d "files[][file_path]=heihei8" \
-d "author_email=yystopf@163.com" \
-d "author_name=yystopf" \
-d "author_timeunix=1658214400" \
-d "committer_email=yystopf@163.com" \
-d "committer_name=yystopf" \
-d "committer_timeunix=1658214400" \
-d "branch=develop" \
-d "new_branch=develop_ceshi" \
-d "message=测试提交" \
http://localhost:3000/api/v1/yystopf/ceshi/contents/batch.json
```
```javascript
await octokit.request('POST /api/v1/yystopf/ceshi/contents/batch.json')
```
### HTTP 请求
`POST /api/v1/:owner/:repo/contents/batch`
### 请求参数:
参数 | 必选 | 默认 | 类型 | 字段说明
--------- | ------- | ------- | -------- | ----------
|owner |是| |string |用户登录名 |
|repo |是| |string |项目标识identifier |
|files.action_type |是| |string|操作类型 create: 创建 update: 更新 delete: 删除|
|files.content |是| |string|文件内容|
|files.encoding |是| |string|文件编码方式 text 文本 base64 加密|
|files.file_path |是| |string|文件路径|
|author_email |是| |string|作者邮箱|
|author_name |是| |string|作者名称|
|author_timeunix |是| |int|编码时间,精确到秒|
|committer_email |是| |string|提交者邮箱|
|committer_name |是| |string|提交者名称|
|committer_timeunix|是| |int|提交时间戳,精确到秒|
|branch |是| |string|提交分支|
|new_branch |否| |string|如果需要创建新分支,这个需要填|
|message |是| |string|提交信息|
> 请求的JSON示例:
```json
{
"files": [
{
"action_type": "create",
"content": "jfksj",
"encoding": "text",
"file_path": "heihei7"
}
],
"author_email": "yystopf@163.com",
"author_name": "yystopf",
"author_timeunix": 1658214400,
"committer_email": "yystopf@163.com",
"committer_name": "yystopf",
"committer_timeunix": 1658214400,
"branch": "hh_ceshi",
"message": "测试提交"
}
```
### 返回字段说明:
参数 | 类型 | 字段说明
--------- | ----------- | -----------
|commit.sha |string |提交ID|
|commit.author |object |作者|
|commit.committer |object |提交者|
|commit.commit_message|string |提交信息|
|commit.parent_shas |array |父节点commit ID|
|commit.authored_time|int |编码时间|
|commit.commited_time|int |提交时间|
|contents.name |string |文件名称|
|contents.path |string |文件路径|
|contents.sha |string |文件标识|
|contents.type |string |文件类型|
|contents.size |int |文件大小|
|contents.url |string |文件地址|
|contents.encoding |string |编码类型 text 文本 base64 加密 |
|contents.content |string |文件内容|
> 返回的JSON示例:
```json
{
"commit": {
"sha": "7c1e25f9b974e4b7a3816bd7f5e49b441078e999",
"author": {
"id": "2",
"login": "yystopf",
"name": "heh",
"type": "User",
"image_url": "system/lets/letter_avatars/2/H/188_239_142/120.png"
},
"committer": {
"id": "2",
"login": "yystopf",
"name": "heh",
"type": "User",
"image_url": "system/lets/letter_avatars/2/H/188_239_142/120.png"
},
"commit_message": "测试提交\n",
"parent_shas": [
"9aec816d0f3600082ca77893290a14bd29d805fe"
],
"authored_time": 1658214400,
"commited_time": 1658214400
},
"contents": [
{
"name": "heihei7",
"path": "heihei7",
"sha": "f0acac8efb3021b0f6a7b13b42d033d86e076a4b",
"type": "file",
"size": 5,
"encoding": "base64",
"content": "amZrc2o="
}
]
}
```
## 获取仓库代码目录
获取仓库代码目录
@ -1214,71 +1438,665 @@ await octokit.request('GET /api/yystopf/csfjkkj/readme.json')
Success Data.
</aside>
## 获取仓库贡献者
获取仓库贡献者
## 获取文件树列表
根据分支、标签、commit ID获取仓库文件树列表
> 示例:
```shell
curl -X GET \
-d "ref=master" \
-d "filepath=lib" \
http://localhost:3000/api/yystopf/csfjkkj/contributors.json
-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/yystopf/csfjkkj/contributors.json')
await octokit.request('GET /api/v1/yystopf/csfjkkj/git/trees/80dd40214a58622312393b2ae693756a4781fab2.json')
```
### HTTP 请求
`GET /api/:owner/:repo/contributors.json`
`GET /api/v1/:owner/:repo/git/trees/:sha.json`
### 请求参数:
参数 | 必选 | 默认 | 类型 | 字段说明
--------- | ------- | ------- | -------- | ----------
|owner |是| |string |用户登录名 |
|repo |是| |string |项目标识identifier |
|ref |否| | string |分支名称、tag名称或是提交记录id默认为整个仓库 |
|filepath |否| | string |子目录名称,默认为空 |
|owner |是| | string |用户登录名 |
|repo |是| | string |项目标识identifier |
|sha |是| | string |分支名称、tag名称或是提交记录id |
|recursive|否| | bool |是否显示目录|
|page |否|1 | int |页码|
|limit |否|15| int |分页个数|
### 返回字段说明:
参数 | 类型 | 字段说明
--------- | ----------- | -----------
|total_count |integer|贡献者数量|
|contributions |integer|贡献数量|
|login |string |用户登录名 |
|type |string|用户类型 |
|name |string|用户昵称|
|image_url |string|用户头像|
|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
{
"contributors": [
"total_count": 13,
"sha": "80dd40214a58622312393b2ae693756a4781fab2",
"entries": [
{
"contributions": 5,
"login": "testforge2",
"type": "User",
"name": "testforge2",
"image_url": "system/lets/letter_avatars/2/T/236_177_85/120.png"
},
{
"contributions": 79,
"login": "yystopf",
"type": "User",
"name": "yystopf",
"image_url": "system/lets/letter_avatars/2/Y/241_125_89/120.png"
"name": "README.md",
"mode": "100644",
"type": "file",
"size": 14,
"sha": "b2f7b457fd8ca55f2274032cbb2abcb7dd8cd57e"
}
],
"total_count": 2
]
}
```
<aside class="success">
Success Data.
</aside>
## 获取仓库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=="
}
```
<aside class="success">
Success Data.
</aside>
## 获取仓库提交列表
根据分支名、标签、commit ID来获取提交列表
> 示例:
```shell
curl -X GET \
-d "sha=master" \
-d "page=1" \
-d "limit=1" \
http://localhost:3000/api/v1/yystopf/csfjkkj/commits.json
```
```javascript
await octokit.request('GET /api/v1/yystopf/csfjkkj/commits.json')
```
### HTTP 请求
`GET /api/v1/:owner/:repo/commits.json`
### 请求参数:
参数 | 必选 | 默认 | 类型 | 字段说明
--------- | ------- | ------- | -------- | ----------
|owner|是| | string |用户登录名 |
|repo |是| | string |项目标识identifier |
|sha |否| | string |分支名、标签名或Commit ID|
|page |否| | int |页码|
|limit|否| | int |每页数量|
### 返回字段说明:
参数 | 类型 | 字段说明
--------- | ----------- | -----------
|total_count|int|提交总数|
|commits.sha|string|提交ID|
|commits.author|object|提交作者|
|commits.committer|object|提交者|
|commits.commit_message|string|提交信息|
|commits.parent_shas|array|提交父节点ID|
|commits.files|array|提交文件|
|commits.commit_date|string|提交日期|
|commits.commit_time|string|提交时间|
|commits.branch|string|提交分支|
> 返回的JSON示例:
```json
{
"total_count": 12,
"commits": [
{
"sha": "86c62a1e91c07b58b8aa6c89b94856d89c0f7e55",
"author": {
"id": null,
"login": "viletyy",
"name": "viletyy",
"type": null,
"image_url": "system/lets/letter_avatars/2/V/39_141_222/120.png"
},
"committer": {
"id": null,
"login": "viletyy",
"name": "viletyy",
"type": null,
"image_url": "system/lets/letter_avatars/2/V/39_141_222/120.png"
},
"commit_message": "fix\n",
"parent_shas": [
"411e4d259785241f1bd14faf99ca24fd1b802f2a"
],
"files": [
"hd.txt"
],
"commit_date": "2022-07-05",
"commit_time": "2022-07-05 11:00:45",
"branch": "hh_ceshi"
}
]
}
```
<aside class="success">
Success Data.
</aside>
## 获取单个提交的blame信息
根据commit ID获取blame信息
> 示例:
```shell
curl -X GET http://localhost:3000/api/v1/yystopf/csfjkkj/commits/80dd40214a58622312393b2ae693756a4781fab2/diff.json
```
```javascript
await octokit.request('GET /api/v1/yystopf/csfjkkj/commits/80dd40214a58622312393b2ae693756a4781fab2/diff.json')
```
### HTTP 请求
`GET /api/v1/:owner/:repo/commits/:sha/diff.json`
### 请求参数:
参数 | 必选 | 默认 | 类型 | 字段说明
--------- | ------- | ------- | -------- | ----------
|owner|是| | string |用户登录名 |
|repo |是| | string |项目标识identifier |
|sha |是| | string |提交记录id |
### 返回字段说明:
参数 | 类型 | 字段说明
--------- | ----------- | -----------
|file_nums|int|文件数量|
|total_addition|int|新增行数|
|total_deletion|int|删除行数|
|files.name|string|文件名称|
|files.oldname|string|文件修改前名称|
|files.addition|int|文件新增行数|
|files.deletion|int|文件删除行数|
|files.type|int|文件类型 1: 新增 2: 更改 3: 删除 4: 重命名 5: 复制|
|files.is_created|bool|是否为新建文件|
|files.is_deleted|bool|是否为删除文件|
|files.is_bin|bool|是否为二进制文件|
|files.is_lfs_file|bool||
|files.is_renamed|bool|是否重命名|
|files.is_ambiguous|bool||
|files.is_submodule|bool|是否为子模块|
|files.sections.file_name|string|文件名称|
|files.sections.name|string||
|files.sections.lines.left_index|int||
|files.sections.lines.right_index|int||
|files.sections.lines.match|int||
|files.sections.lines.type|int||
|files.sections.lines.content|string||
|files.sections.lines.section_path|string||
|files.sections.lines.section_last_left_index|int||
|files.sections.lines.section_last_right_index|int||
|files.sections.lines.section_left_index|int||
|files.sections.lines.section_right_index|int||
|files.sections.lines.section_left_hunk_size|int||
|files.sections.lines.section_right_hunk_size|int||
> 返回的JSON示例:
```json
{
"file_nums": 1,
"total_addition": 1,
"total_deletion": 0,
"files": [
{
"name": "xinzeng3",
"oldname": "xinzeng3",
"addition": 1,
"deletion": 0,
"type": 1,
"is_created": true,
"is_deleted": false,
"is_bin": false,
"is_lfs_file": false,
"is_renamed": false,
"is_ambiguous": false,
"is_submodule": false,
"sections": [
{
"file_name": "xinzeng3",
"name": "",
"lines": [
{
"left_index": 0,
"right_index": 0,
"match": 0,
"type": 4,
"content": "@@ -0,0 +1 @@",
"section_path": "xinzeng3",
"section_last_left_index": 0,
"section_last_right_index": 0,
"section_left_index": 0,
"section_right_index": 1,
"section_left_hunk_size": 0,
"section_right_hunk_size": 0
},
{
"left_index": 0,
"right_index": 1,
"match": -1,
"type": 2,
"content": "+1111122222"
}
]
}
],
"is_incomplete": false,
"is_incomplete_line_too_long": false,
"is_protected": false
}
]
}
```
<aside class="success">
Success Data.
</aside>
## 获取单个文件的blame信息
根据分支、标签、commitID获取某个文件的blame信息
> 示例:
```shell
curl -X GET \
-d "sha=master" \
-d "filepath=hd.txt" \
http://localhost:3000/api/v1/yystopf/csfjkkj/blame.json
```
```javascript
await octokit.request('GET /api/v1/yystopf/csfjkkj/blame.json')
```
### HTTP 请求
`GET /api/v1/:owner/:repo/blame.json`
### 请求参数:
参数 | 必选 | 默认 | 类型 | 字段说明
--------- | ------- | ------- | -------- | ----------
|owner |是| | string |用户登录名 |
|repo |是| | string |项目标识identifier |
|sha |是| | string |分支、标签或提交记录id |
|filepath|是| | string |文件路径|
### 返回字段说明:
参数 | 类型 | 字段说明
--------- | ----------- | -----------
|file_size|int|文件大小|
|file_name|string|文件名称|
|num_lines|int|文件总行数|
|blame_parts.commit|object|提交|
|blame_parts.current_number|int|当前行数|
|blame_parts.effect_line|int|影响的行数|
|blame_parts.lines|array|行内容|
> 返回的JSON示例:
```json
{
"file_size": 32,
"file_name": "hd.txt",
"num_lines": 12,
"blame_parts": [
{
"commit": {
"sha": "40f76e80bf5bc41fcc94c28ca8a6eab506c15215",
"author": {
"id": null,
"login": "viletyy",
"name": "viletyy",
"type": null,
"image_url": "system/lets/letter_avatars/2/V/39_141_222/120.png"
},
"committer": {
"id": null,
"login": "viletyy",
"name": "viletyy",
"type": null,
"image_url": "system/lets/letter_avatars/2/V/39_141_222/120.png"
},
"commit_message": "fix\n",
"authored_time": "2022-07-04 18:41:25",
"committed_time": "2022-07-04 18:41:25",
"created_time": "2022-07-04 18:41:25"
},
"current_number": 1,
"effect_line": 5,
"lines": [
"dkfj",
"s",
"324",
"234",
"2"
]
},
{
"commit": {
"sha": "86c62a1e91c07b58b8aa6c89b94856d89c0f7e55",
"author": {
"id": null,
"login": "viletyy",
"name": "viletyy",
"type": null,
"image_url": "system/lets/letter_avatars/2/V/39_141_222/120.png"
},
"committer": {
"id": null,
"login": "viletyy",
"name": "viletyy",
"type": null,
"image_url": "system/lets/letter_avatars/2/V/39_141_222/120.png"
},
"commit_message": "fix\n",
"authored_time": "2022-07-05 11:00:45",
"committed_time": "2022-07-05 11:00:45",
"created_time": "2022-07-05 11:00:45"
},
"current_number": 6,
"effect_line": 1,
"lines": [
"dd"
]
},
{
"commit": {
"sha": "40f76e80bf5bc41fcc94c28ca8a6eab506c15215",
"author": {
"id": null,
"login": "viletyy",
"name": "viletyy",
"type": null,
"image_url": "system/lets/letter_avatars/2/V/39_141_222/120.png"
},
"committer": {
"id": null,
"login": "viletyy",
"name": "viletyy",
"type": null,
"image_url": "system/lets/letter_avatars/2/V/39_141_222/120.png"
},
"commit_message": "fix\n",
"authored_time": "2022-07-04 18:41:25",
"committed_time": "2022-07-04 18:41:25",
"created_time": "2022-07-04 18:41:25"
},
"current_number": 7,
"effect_line": 3,
"lines": [
"23",
"4",
"23"
]
},
{
"commit": {
"sha": "86c62a1e91c07b58b8aa6c89b94856d89c0f7e55",
"author": {
"id": null,
"login": "viletyy",
"name": "viletyy",
"type": null,
"image_url": "system/lets/letter_avatars/2/V/39_141_222/120.png"
},
"committer": {
"id": null,
"login": "viletyy",
"name": "viletyy",
"type": null,
"image_url": "system/lets/letter_avatars/2/V/39_141_222/120.png"
},
"commit_message": "fix\n",
"authored_time": "2022-07-05 11:00:45",
"committed_time": "2022-07-05 11:00:45",
"created_time": "2022-07-05 11:00:45"
},
"current_number": 10,
"effect_line": 1,
"lines": [
"s1"
]
},
{
"commit": {
"sha": "40f76e80bf5bc41fcc94c28ca8a6eab506c15215",
"author": {
"id": null,
"login": "viletyy",
"name": "viletyy",
"type": null,
"image_url": "system/lets/letter_avatars/2/V/39_141_222/120.png"
},
"committer": {
"id": null,
"login": "viletyy",
"name": "viletyy",
"type": null,
"image_url": "system/lets/letter_avatars/2/V/39_141_222/120.png"
},
"commit_message": "fix\n",
"authored_time": "2022-07-04 18:41:25",
"committed_time": "2022-07-04 18:41:25",
"created_time": "2022-07-04 18:41:25"
},
"current_number": 11,
"effect_line": 1,
"lines": [
""
]
}
]
}
```
<aside class="success">
Success Data.
</aside>
## 获取比较提交blame
根据分支名、标签、commit ID来获取代码对比blame
> 示例:
```shell
curl -X GET \
-d "from=hh_ceshi" \
-d "to=master" \
http://localhost:3000/api/v1/yystopf/csfjkkj/compare.json
```
```javascript
await octokit.request('GET /api/v1/yystopf/csfjkkj/compare.json')
```
### HTTP 请求
`GET /api/v1/:owner/:repo/compare.json`
### 请求参数:
参数 | 必选 | 默认 | 类型 | 字段说明
--------- | ------- | ------- | -------- | ----------
|owner|是| | string |用户登录名 |
|repo |是| | string |项目标识identifier |
|from |是| | string |源分支、标签、commitID |
|to|是||string|目标分支、标签、commitID|
### 返回字段说明:
参数 | 类型 | 字段说明
--------- | ----------- | -----------
|commits_count|int|提交数量|
|commits.branch|string|提交分支|
|commits.author|object|提交作者|
|commits.committer|object|提交者|
|commits.commit_message|string|提交信息|
|commits.sha|string|提交ID|
|commits.parent_shas|array|提交父节点ID|
|diff.file_nums|int|文件数量|
|diff.total_addition|int|新增行数|
|diff.total_deletion|int|删除行数|
|diff.files.name|string|文件名称|
|diff.files.oldname|string|文件修改前名称|
|diff.files.addition|int|文件新增行数|
|diff.files.deletion|int|文件删除行数|
|diff.files.type|int|文件类型 1: 新增 2: 更改 3: 删除 4: 重命名 5: 复制|
|diff.files.is_created|bool|是否为新建文件|
|diff.files.is_deleted|bool|是否为删除文件|
|diff.files.is_bin|bool|是否为二进制文件|
|diff.files.is_lfs_file|bool||
|diff.files.is_renamed|bool|是否重命名|
|diff.files.is_ambiguous|bool||
|diff.files.is_submodule|bool|是否为子模块|
|diff.files.sections.file_name|string|文件名称|
|diff.files.sections.name|string||
|diff.files.sections.lines.left_index|int||
|diff.files.sections.lines.right_index|int||
|diff.files.sections.lines.match|int||
|diff.files.sections.lines.type|int||
|diff.files.sections.lines.content|string||
|diff.files.sections.lines.section_path|string||
|diff.files.sections.lines.section_last_left_index|int||
|diff.files.sections.lines.section_last_right_index|int||
|diff.files.sections.lines.section_left_index|int||
|diff.files.sections.lines.section_right_index|int||
|diff.files.sections.lines.section_left_hunk_size|int||
|diff.files.sections.lines.section_right_hunk_size|int||
> 返回的JSON示例:
```json
{
"commits_count": 1,
"last_commit_sha": "80dd40214a58622312393b2ae693756a4781fab2",
"commits": [
{
"author": {
"id": "2",
"login": "yystopf",
"name": "heh",
"type": "User",
"image_url": "system/lets/letter_avatars/2/H/188_239_142/120.png"
},
"committer": {
"id": "2",
"login": "yystopf",
"name": "heh",
"type": "User",
"image_url": "system/lets/letter_avatars/2/H/188_239_142/120.png"
},
"branch": "",
"commit_message": "x拟增\n\nSigned-off-by: yystopf <yystopf@163.com>",
"sha": "7e4d8bb3c28e24d4cd6b205f2eed32513e937524",
"parent_shas": null
}
],
"diff": {
"file_nums": 1,
"total_addition": 1,
"total_deletion": 0,
"files": [
{
"name": "ceshi123",
"oldname": "ceshi123",
"addition": 1,
"deletion": 0,
"type": 1,
"is_created": true,
"is_deleted": false,
"is_bin": false,
"is_lfs_file": false,
"is_renamed": false,
"is_ambiguous": false,
"is_submodule": false,
"sections": [
{
"file_name": "ceshi123",
"name": "",
"lines": [
{
"left_index": 0,
"right_index": 0,
"match": 0,
"type": 4,
"content": "@@ -0,0 +1 @@",
"section_path": "ceshi123",
"section_last_left_index": 0,
"section_last_right_index": 0,
"section_left_index": 0,
"section_right_index": 1,
"section_left_hunk_size": 0,
"section_right_hunk_size": 0
},
{
"left_index": 0,
"right_index": 1,
"match": -1,
"type": 2,
"content": "+1111122222"
}
]
}
],
"is_incomplete": false,
"is_incomplete_line_too_long": false,
"is_protected": false
}
]
}
}
```
<aside class="success">
Success Data.
</aside>
## 获取仓库webhooks列表
获取仓库webhooks列表

View File

@ -10,7 +10,7 @@ module RepositoriesHelper
end
def download_type(str)
default_type = %w(xlsx xls ppt pptx pdf zip 7z rar exe pdb obj idb RData rdata doc docx mpp vsdx dot otf eot ttf woff woff2 mp4 mov wmv flv mpeg avi avchd webm mkv)
default_type = %w(xlsx xls ppt pptx pdf zip 7z rar exe pdb obj idb RData rdata doc docx mpp vsdx dot otf eot ttf woff woff2 mp4 mov wmv flv mpeg avi avchd webm mkv apk)
default_type.include?(str&.downcase) || str.blank?
end

View File

@ -0,0 +1,38 @@
class Api::V1::Projects::BlameService < ApplicationService
include ActiveModel::Model
attr_reader :project, :sha, :filepath, :owner, :repo, :token
attr_accessor :gitea_data
validates :sha, :filepath, presence: true
def initialize(project, sha, filepath, token=nil)
@project = project
@owner = project&.owner.login
@repo = project&.identifier
@sha = sha
@filepath = filepath
@token = token
end
def call
raise Error, errors.full_messages.join(",") unless valid?
load_gitea_data
gitea_data
end
private
def request_params
{
access_token: token,
sha: sha,
filepath: filepath
}
end
def load_gitea_data
@gitea_data = $gitea_client.get_repos_blame_by_owner_repo(owner, repo, {query: request_params})
raise Error, '获取项目blame失败' unless @gitea_data.is_a?(Hash)
end
end

View File

@ -0,0 +1,30 @@
class Api::V1::Projects::Branches::AllListService < ApplicationService
attr_accessor :project, :token, :owner, :repo
attr_accessor :gitea_data
def initialize(project, token=nil)
@project = project
@owner = project&.owner.login
@repo = project&.identifier
@token = token
end
def call
load_gitea_data
gitea_data
end
private
def request_params
{
access_token: token
}
end
def load_gitea_data
@gitea_data = $gitea_client.get_repos_branch_name_set_by_owner_repo(owner, repo, {query: request_params}) rescue nil
raise Error, '获取所有分支失败!' unless @gitea_data.is_a?(Hash)
end
end

View File

@ -0,0 +1,51 @@
class Api::V1::Projects::Branches::CreateService < ApplicationService
include ActiveModel::Model
attr_accessor :project, :token, :owner, :repo, :old_branch_name, :new_branch_name
attr_accessor :gitea_data
validates :new_branch_name, :old_branch_name, presence: true
def initialize(project, params, token=nil)
@project = project
@owner = project&.owner.login
@repo = project&.identifier
@new_branch_name = params[:new_branch_name]
@old_branch_name = params[:old_branch_name]
@token = token
end
def call
raise Error, errors.full_messages.join(",") unless valid?
check_new_branch_exist
excute_data_to_gitea
gitea_data
end
private
def request_params
{
access_token: token
}
end
def request_body
{
new_branch_name: new_branch_name,
old_branch_name: old_branch_name,
}
end
def excute_data_to_gitea
@gitea_data = $gitea_client.post_repos_branches_by_owner_repo(owner, repo, {body: request_body.to_json, query: request_params}) rescue nil
raise Error, '创建分支失败!' unless @gitea_data.is_a?(Hash)
end
def check_new_branch_exist
result = $gitea_client.get_repos_branch_name_set_by_owner_repo(owner, repo, {query: request_params}) rescue nil
raise Error, '查询分支名称失败!' unless result.is_a?(Hash)
raise Error, '分支已存在!' if result['branch_name'].include?(@new_branch_name)
end
end

View File

@ -0,0 +1,36 @@
class Api::V1::Projects::Commits::DiffService < 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
@sha = sha
@owner = project&.owner.login
@repo = project&.identifier
@token = token
end
def call
raise Error, errors.full_messages.join(",") unless valid?
load_gitea_data
gitea_data
end
private
def request_params
{
access_token: token
}
end
def load_gitea_data
@gitea_data = $gitea_client.get_repos_commits_diff_by_owner_repo_sha(owner, repo, sha, {query: request_params}) rescue nil
raise Error, '获取提交对比失败!' unless @gitea_data.is_a?(Hash)
end
end

View File

@ -0,0 +1,38 @@
class Api::V1::Projects::Commits::ListService < ApplicationService
attr_reader :project, :sha, :page, :limit, :owner, :repo, :token
attr_accessor :gitea_data
def initialize(project, params, token=nil)
@project = project
@sha = params[:sha]
@page = params[:page] || 1
@limit = params[:limit] || 15
@owner = project&.owner.login
@repo = project&.identifier
@token = token
end
def call
load_gitea_data
gitea_data
end
private
def request_params
param = {
access_token: token,
page: page,
limit: limit
}
param.merge!(sha: sha) if sha.present?
param
end
def load_gitea_data
@gitea_data = $gitea_client.get_repos_commits_by_owner_repo(owner, repo, {query: request_params}) rescue nil
raise Error, '获取提交列表失败!' unless @gitea_data.is_a?(Hash)
end
end

View File

@ -0,0 +1,34 @@
class Api::V1::Projects::CompareService < ApplicationService
include ActiveModel::Model
attr_reader :project, :from, :to, :token, :owner, :repo
attr_accessor :gitea_data
validates :from, :to, presence: true
def initialize(project, from, to, token=nil)
@project = project
@owner = project&.owner.login
@repo = project&.identifier
@from = from
@to = to
@token = token
end
def call
raise Error, errors.full_messages.join(",") unless valid?
load_gitea_data
raise Error, '获取对比信息失败!' unless gitea_data.is_a?(Hash)
gitea_data
end
private
def request_params
{
access_token: token
}
end
def load_gitea_data
@gitea_data = $gitea_client.get_repos_compare_by_owner_repo_from_to(owner, repo, from, to, {query: request_params}) rescue nil
end
end

View File

@ -0,0 +1,91 @@
class Api::V1::Projects::Contents::BatchCreateService < ApplicationService
include ActiveModel::Model
attr_reader :project, :owner, :repo, :token
attr_reader :files, :author_email, :author_name, :author_timeunix, :branch, :committer_email, :committer_name, :committer_timeunix, :message, :new_branch
attr_accessor :gitea_data
validates :author_email, :committer_email, presence: true, format: { with: CustomRegexp::EMAIL }
validates :author_name, :committer_name, presence: true, format: { with: /\A(?!_)(?!.*?_$)[a-zA-Z0-9_-]{4,15}\z/ }
validates :author_timeunix, :committer_timeunix, presence: true
validates :branch, presence: true
validates :message, presence: true
def initialize(project, params, token=nil)
puts params
@project = project
@owner = project&.owner.login
@repo = project&.identifier
@token = token
@files = params[:files]
@author_email = params[:author_email]
@author_name = params[:author_name]
@author_timeunix = params[:author_timeunix]
@branch = params[:branch]
@committer_email = params[:committer_email]
@committer_name = params[:committer_name]
@committer_timeunix = params[:committer_timeunix]
@message = params[:message]
@new_branch = params[:new_branch]
end
def call
raise Error, '请输入正确的文件参数Files' unless valid_files?
raise Error, errors.full_messages.join(", ") unless valid?
check_branch_exist
excute_data_to_gitea
gitea_data
end
private
def request_params
{
access_token: token
}
end
def request_body
{
files: files,
header: {
author: {
email: author_email,
name: author_name
},
committer: {
email: committer_email,
name: committer_name
},
dates: {
author: Time.at(author_timeunix.to_i),
committer: Time.at(committer_timeunix.to_i)
},
message: message,
new_branch: new_branch,
signoff: false
}
}
end
def valid_files?
return false unless files.is_a?(Array) && !files.blank?
files.each do |file|
return false unless file.has_key?(:action_type) && file.has_key?(:content) && file.has_key?(:encoding) && file.has_key?(:file_path)
end
end
def excute_data_to_gitea
@gitea_data = $gitea_client.post_repos_contents_batch_by_owner_repo(owner, repo, {body: request_body.to_json, query: request_params}) rescue nil
raise Error, '创建文件失败!' unless @gitea_data.is_a?(Hash)
end
def check_branch_exist
result = $gitea_client.get_repos_branch_name_set_by_owner_repo(owner, repo, {query: request_params} ) rescue nil
raise Error, '查询分支名称失败!' unless result.is_a?(Hash)
raise Error, '分支不存在!' unless result['branch_name'].include?(branch)
raise Error, '分支已存在!' if result['branch_name'].include?(new_branch) && new_branch.nil?
end
end

View File

@ -11,18 +11,20 @@ class Api::V1::Projects::GetService < ApplicationService
end
def call
$gitea_client.token = token unless token.blank?
load_gitea_data
load_gitea_branch_tag_count
$gitea_client.token = nil unless token.blank?
result_object
rescue
raise Error, "服务器错误,请联系系统管理员!"
end
private
def request_params
{
access_token: token
}
end
def result_object
{
@ -39,10 +41,10 @@ class Api::V1::Projects::GetService < ApplicationService
end
def load_gitea_data
@gitea_data = $gitea_client.get_repos_by_owner_repo(owner, repo)
@gitea_data = $gitea_client.get_repos_by_owner_repo(owner, repo, {query: request_params}) rescue nil
end
def load_gitea_branch_tag_count
@gitea_branch_tag_count = $gitea_client.get_repos_branch_tag_count_by_owner_repo(owner, repo)
@gitea_branch_tag_count = $gitea_client.get_repos_branch_tag_count_by_owner_repo(owner, repo, {query: request_params}) rescue nil
end
end

View File

@ -0,0 +1,34 @@
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
load_gitea_data
gitea_data
end
private
def request_params
{
access_token: token
}
end
def load_gitea_data
@gitea_data = $gitea_client.get_repos_git_blobs_by_owner_repo_sha(owner, repo, sha, {query: request_params}) rescue nil
end
end

View File

@ -0,0 +1,52 @@
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,
access_token: token
}
else
{
page: page,
per_page: limit,
access_token: token
}
end
end
def load_gitea_data
@gitea_data = $gitea_client.get_repos_git_trees_by_owner_repo_sha(owner, repo, sha, {query: request_query}) rescue nil
raise Error, '获取文件树列表失败!' unless @gitea_data.is_a?(Hash)
end
end

View File

@ -26,12 +26,8 @@ class Api::V1::Projects::Webhooks::CreateService < ApplicationService
def call
raise Error, errors.full_messages.join(",") unless valid?
begin
$gitea_client.token = token unless token.blank?
excute_data_to_gitea
$gitea_client.token = nil unless token.blank?
gitea_data
rescue
raise Error, "服务器错误,请联系系统管理员!"
@ -39,6 +35,12 @@ class Api::V1::Projects::Webhooks::CreateService < ApplicationService
end
private
def request_params
{
access_token: token
}
end
def request_body
{
active: active,
@ -55,6 +57,6 @@ class Api::V1::Projects::Webhooks::CreateService < ApplicationService
end
def excute_data_to_gitea
@gitea_data = $gitea_client.post_repos_hooks_by_owner_repo(owner, repo, {body: request_body.to_json})
@gitea_data = $gitea_client.post_repos_hooks_by_owner_repo(owner, repo, {body: request_body.to_json, query: request_params}) rescue nil
end
end

View File

@ -12,19 +12,21 @@ class Api::V1::Projects::Webhooks::DeleteService < ApplicationService
end
def call
$gitea_client.token = token unless token.blank?
excute_data_to_gitea
$gitea_client.token = nil unless token.blank?
gitea_data
rescue
raise Error, "服务器错误,请联系系统管理员!"
end
private
def request_params
{
access_token: token
}
end
def excute_data_to_gitea
@gitea_data = $gitea_client.delete_repos_hooks_by_owner_repo_id(owner, repo, id)
@gitea_data = $gitea_client.delete_repos_hooks_by_owner_repo_id(owner, repo, id, {query: request_params}) rescue nil
end
end

View File

@ -12,10 +12,8 @@ class Api::V1::Projects::Webhooks::GetService < ApplicationService
end
def call
$gitea_client.token = token unless token.blank?
load_gitea_data
$gitea_client.token = nil unless token.blank?
gitea_data
rescue
@ -23,8 +21,13 @@ class Api::V1::Projects::Webhooks::GetService < ApplicationService
end
private
def request_params
{
access_token: token
}
end
def load_gitea_data
@gitea_data = $gitea_client.get_repos_hooks_by_owner_repo_id(owner, repo, id)
@gitea_data = $gitea_client.get_repos_hooks_by_owner_repo_id(owner, repo, id, {query: request_params}) rescue nil
end
end

View File

@ -23,8 +23,13 @@ class Api::V1::Projects::Webhooks::ListService < ApplicationService
end
private
def request_params
{
access_token: token
}
end
def load_gitea_data
@gitea_data = $gitea_client.get_repos_hooks_hooktasks_by_owner_repo(owner, repo, id)
@gitea_data = $gitea_client.get_repos_hooks_hooktasks_by_owner_repo(owner, repo, id, {query: request_params}) rescue nil
end
end

View File

@ -11,19 +11,21 @@ class Api::V1::Projects::Webhooks::ListService < ApplicationService
end
def call
$gitea_client.token = token unless token.blank?
load_gitea_data
$gitea_client.token = nil unless token.blank?
gitea_data
rescue
raise Error, "服务器错误,请联系系统管理员!"
end
private
def request_params
{
access_token: token
}
end
def load_gitea_data
@gitea_data = $gitea_client.get_repos_hooks_by_owner_repo(owner, repo)
@gitea_data = $gitea_client.get_repos_hooks_by_owner_repo(owner, repo, {query: request_params}) rescue nil
end
end

View File

@ -12,19 +12,21 @@ class Api::V1::Projects::Webhooks::TestsService < ApplicationService
end
def call
$gitea_client.token = token unless token.blank?
excute_data_to_gitea
$gitea_client.token = nil unless token.blank?
gitea_data
rescue
raise Error, "服务器错误,请联系系统管理员!"
end
private
def request_params
{
access_token: token
}
end
def excute_data_to_gitea
@gitea_data = $gitea_client.post_repos_hooks_tests_by_owner_repo_id(owner, repo, id)
@gitea_data = $gitea_client.post_repos_hooks_tests_by_owner_repo_id(owner, repo, id, {query: request_params}) rescue nil
end
end

View File

@ -27,12 +27,8 @@ class Api::V1::Projects::Webhooks::UpdateService < ApplicationService
def call
raise Error, errors.full_messages.join(",") unless valid?
begin
$gitea_client.token = token unless token.blank?
excute_data_to_gitea
$gitea_client.token = nil unless token.blank?
gitea_data
rescue
raise Error, "服务器错误,请联系系统管理员!"
@ -40,6 +36,12 @@ class Api::V1::Projects::Webhooks::UpdateService < ApplicationService
end
private
def request_params
{
access_token: token
}
end
def request_body
{
active: active,
@ -56,6 +58,6 @@ class Api::V1::Projects::Webhooks::UpdateService < ApplicationService
end
def excute_data_to_gitea
@gitea_data = $gitea_client.patch_repos_hooks_by_owner_repo_id(owner, repo, id, {body: request_body.to_json})
@gitea_data = $gitea_client.patch_repos_hooks_by_owner_repo_id(owner, repo, id, {body: request_body.to_json, query: request_params}) rescue nil
end
end

View File

@ -2,217 +2,57 @@
<% add_admin_breadcrumb('概览', admins_path) %>
<% end %>
<div class="header bg-gradient-primary pb-8 pt-md-8">
<div class="container-fluid">
<div class="header-body">
<!-- Card stats -->
<div class="row">
<div class="col-xl-3 col-lg-6">
<div class="card card-stats mb-4 mb-xl-0">
<div class="card-body">
<div class="row">
<div class="col">
<h5 class="card-title text-uppercase text-muted mb-0">当日活跃用户</h5>
<span class="h2 font-weight-bold mb-0"><%= @active_user_count %></span>
</div>
<div class="col-auto">
<div class="icon icon-shape rounded-circle shadow">
<i class="fa fa-users"></i>
</div>
</div>
</div>
<!-- <p class="mt-3 mb-0 text-muted text-sm">-->
<!-- <span class="text-success mr-2"><i class="fa fa-arrow-up"></i> 3.48%</span>-->
<!-- <span class="text-nowrap">Since last month</span>-->
<!-- </p>-->
</div>
</div>
</div>
<div class="col-xl-3 col-lg-6">
<div class="card card-stats mb-4 mb-xl-0">
<div class="card-body">
<div class="row">
<div class="col">
<h5 class="card-title text-uppercase text-muted mb-0">7天内活跃用户数</h5>
<span class="h2 font-weight-bold mb-0"><%= @weekly_active_user_count %></span>
</div>
<div class="col-auto">
<div class="icon icon-shape rounded-circle shadow">
<i class="fa fa-users"></i>
</div>
</div>
</div>
<!-- <p class="mt-3 mb-0 text-muted text-sm">-->
<!-- <span class="text-danger mr-2"><i class="fas fa-arrow-down"></i> 3.48%</span>-->
<!-- <span class="text-nowrap">Since last week</span>-->
<!-- </p>-->
</div>
</div>
</div>
<div class="col-xl-3 col-lg-6">
<div class="card card-stats mb-4 mb-xl-0">
<div class="card-body">
<div class="row">
<div class="col">
<h5 class="card-title text-uppercase text-muted mb-0">30天内活跃用户数</h5>
<span class="h2 font-weight-bold mb-0"><%= @month_active_user_count %></span>
</div>
<div class="col-auto">
<div class="icon icon-shape rounded-circle shadow">
<i class="fa fa-users"></i>
</div>
</div>
</div>
<!-- <p class="mt-3 mb-0 text-muted text-sm">-->
<!-- <span class="text-warning mr-2"><i class="fas fa-arrow-down"></i> 1.10%</span>-->
<!-- <span class="text-nowrap">Since yesterday</span>-->
<!-- </p>-->
</div>
</div>
</div>
<div class="col-xl-3 col-lg-6">
<div class="card card-stats mb-4 mb-xl-0">
<div class="card-body">
<div class="row">
<div class="col">
<h5 class="card-title text-uppercase text-muted mb-0">30天内新增用户数</h5>
<span class="h2 font-weight-bold mb-0"><%= @new_user_count %></span>
</div>
<div class="col-auto">
<div class="icon icon-shape rounded-circle shadow">
<i class="fa fa-user-plus"></i>
</div>
</div>
</div>
<!-- <p class="mt-3 mb-0 text-muted text-sm">-->
<!-- <span class="text-success mr-2"><i class="fas fa-arrow-up"></i> 12%</span>-->
<!-- <span class="text-nowrap">Since last month</span>-->
<!-- </p>-->
</div>
</div>
</div>
</div>
</div>
</div>
<div class="box admin-list-container project-language-list-container">
<table class="table table-hover text-center subject-list-table">
<thead class="thead-light">
<tr>
<th width="20%">指标名称</th>
<th width="20%">当日数</th>
<th width="20%">七日内</th>
<th width="20%">30日内</th>
<th width="20%">周用户留存率</th>
</tr>
</thead>
<tbody>
<tr class="">
<td>
<button type="button" class="btn btn-primary" style="font-size:14px;width:85px;padding: 0; height:36px;background-color:#5475fb;border-radius:4px;border-color: #5475fb;">活跃用户</button>
</td>
<td><%=@active_user_count %></td>
<td><%=@weekly_active_user_count %></td>
<td><%=@month_active_user_count %></td>
<td><%="#{@weekly_keep_rate.to_f * 100 }%" %></td>
</td>
</tr>
<tr>
<td>
<button type="button" class="btn btn-primary" style="font-size:14px;width:85px;padding: 0; height:36px;background-color:#36cfc9;border-radius:4px; border-color: #36cfc9;">新注册用户</button>
</td>
<td><%=@day_new_user_count %></td>
<td><%=@weekly_new_user_count %></td>
<td><%=@month_new_user_count %></td>
<td><%="--" %></td>
</tr>
<tr>
<td>
<button type="button" class="btn btn-primary" style="font-size:14px;width:85px;padding: 0; height:36px;background-color:#f89422;border-radius:4px; border-color: #f89422;">活跃项目</button>
</td>
<td><%=@day_active_project_count %></td>
<td><%=@weekly_active_project_count %></td>
<td><%=@month_active_project_count %></td>
<td><%="--" %></td>
</tr>
<tr>
<td>
<button type="button" class="btn btn-primary" style="font-size:14px;width:85px;padding: 0; height:36px;background-color:#9d74ff;border-radius:4px; border-color: #9d74ff;">新增项目</button>
</td>
<td><%=@day_new_project_count %></td>
<td><%=@weekly_new_project_count %></td>
<td><%=@month_new_project_count %></td>
<td><%="--" %></td>
</tr>
</tbody>
</table>
</div>
<div class="container-fluid mt--7 pie-statistic">
<div class="row mt-5">
<div class="col-xl-8 mb-5 mb-xl-0">
<div class="card shadow">
<!-- <div class="card-header border-0">-->
<!-- <div class="row align-items-center">-->
<!-- <h5 class="mb-0">近7天评测次数</h5>-->
<!-- </div>-->
<!-- </div>-->
<!-- <div class="table-responsive">-->
<!-- <div id="evaluate-pie" class="pie"></div>-->
<!-- </div>-->
</div>
</div>
<div class="col-xl-4">
<div class="card shadow">
<div class="card-header border-0">
<div class="row align-items-center">
<h5 class="mb-0">30天内新增用户</h5>
</div>
</div>
<div class="table-responsive">
<div id="month-active-user" class="pie"></div>
</div>
</div>
</div>
</div>
<div id="project-language-modals">
</div>
<!--<div class="container-fluid mt--7">-->
<!-- <div class="row mt-5">-->
<!-- <div class="col-xl-8 mb-5 mb-xl-0">-->
<!-- <div class="card shadow">-->
<!-- <div class="card-header border-0">-->
<!-- <div class="row align-items-center">-->
<!-- <div class="col">-->
<!-- <h3 class="mb-0">Page visits</h3>-->
<!-- </div>-->
<!-- <div class="col text-right">-->
<!-- <a href="#!" class="btn btn-sm btn-primary">Test</a>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<!-- <div class="table-responsive">-->
<!-- <table class="table align-items-center table-flush">-->
<!-- <thead class="thead-light">-->
<!-- <tr>-->
<!-- <th scope="col">Test</th>-->
<!-- <th scope="col">Test</th>-->
<!-- <th scope="col">Test</th>-->
<!-- <th scope="col">Test</th>-->
<!-- </tr>-->
<!-- </thead>-->
<!-- <tbody>-->
<%# 5.times do %>
<!-- <tr>-->
<!-- <th scope="row">/test/</th>-->
<!-- <td>4,569</td>-->
<!-- <td>340</td>-->
<!-- <td>-->
<!-- <i class="fas fa-arrow-up text-success mr-3"></i> 46,53%-->
<!-- </td>-->
<!-- </tr>-->
<%# end %>
<!-- </tbody>-->
<!-- </table>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<!-- <div class="col-xl-4">-->
<!-- <div class="card shadow">-->
<!-- <div class="card-header border-0">-->
<!-- <div class="row align-items-center">-->
<!-- <div class="col">-->
<!-- <h3 class="mb-0">Test</h3>-->
<!-- </div>-->
<!-- <div class="col text-right">-->
<!-- <a href="#!" class="btn btn-sm btn-primary">Test</a>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<!-- <div class="table-responsive">-->
<!-- <table class="table align-items-center table-flush">-->
<!-- <thead class="thead-light">-->
<!-- <tr>-->
<!-- <th scope="col">Test</th>-->
<!-- <th scope="col">Test</th>-->
<!-- <th scope="col"></th>-->
<!-- </tr>-->
<!-- </thead>-->
<!-- <tbody>-->
<%# 5.times do %>
<!-- <tr>-->
<!-- <th scope="row">-->
<!-- Test-->
<!-- </th>-->
<!-- <td>-->
<!-- 1,480-->
<!-- </td>-->
<!-- <td>-->
<!-- <div class="d-flex align-items-center">-->
<!-- <span class="mr-2">60%</span>-->
<!-- <div>-->
<!-- <div class="progress">-->
<!-- <div class="progress-bar bg-gradient-danger" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 60%;"></div>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<!-- </td>-->
<!-- </tr>-->
<%# end %>
<!-- </tbody>-->
<!-- </table>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<!--</div>-->

View File

@ -0,0 +1,40 @@
json.file_nums diff['NumFiles']
json.total_addition diff['TotalAddition']
json.total_deletion diff['TotalDeletion']
json.files diff['Files'].each do |file|
json.name file['Name']
json.oldname file['OldName']
json.addition file['Addition']
json.deletion file['Deletion']
json.type file['Type']
json.is_created file['IsCreated']
json.is_deleted file['IsDeleted']
json.is_bin file['IsBin']
json.is_lfs_file file['IsLFSFile']
json.is_renamed file['IsRenamed']
json.is_ambiguous file['IsAmbiguous']
json.is_submodule file['IsSubmodule']
json.sections file['Sections'] do |section|
json.file_name section['FileName']
json.name section['Name']
json.lines section['Lines'] do |line|
json.left_index line['LeftIdx']
json.right_index line['RightIdx']
json.match line['Match']
json.type line['Type']
json.content line['Content']
unless line['SectionInfo'].blank?
json.section_path line['SectionInfo']['Path']
json.section_last_left_index line['SectionInfo']['LastLeftIdx']
json.section_last_right_index line['SectionInfo']['LastRightIdx']
json.section_left_index line['SectionInfo']['LeftIdx']
json.section_right_index line['SectionInfo']['RightIdx']
json.section_left_hunk_size line['SectionInfo']['LeftHunkSize']
json.section_right_hunk_size line['SectionInfo']['RightHunkSize']
end
end
end
json.is_incomplete file['IsIncomplete']
json.is_incomplete_line_too_long file['IsIncompleteLineTooLong']
json.is_protected file['IsProtected']
end

View File

@ -0,0 +1,22 @@
json.file_size @result_object['file_size']
json.file_name @result_object['file_name']
json.num_lines @result_object['num_lines']
json.blame_parts @result_object['blame_parts'] do |part|
json.commit do
json.sha part['commit']['id']
json.author do
json.partial! 'api/v1/users/commit_user', locals: { user: render_cache_commit_author(part['commit']['author']), name: part['commit']['author']['Name'] }
end
json.committer do
json.partial! 'api/v1/users/commit_user', locals: { user: render_cache_commit_author(part['commit']['commiter']), name: part['commit']['commiter']['Name'] }
end
json.commit_message part['commit']['commit_message']
json.authored_time render_unix_time(part['commit']['authored_time'])
json.committed_time render_unix_time(part['commit']['committed_time'])
json.created_time render_unix_time(part['commit']['created_time'])
end
json.current_number part['current_number']
json.effect_line part['effect_line']
json.lines part['lines']
end

View File

@ -0,0 +1,4 @@
json.name branch
json.http_url render_http_url(@project)
json.zip_url render_zip_url(@owner, @project.repository, branch)
json.tar_url render_tar_url(@owner, @project.repository, branch)

View File

@ -0,0 +1,26 @@
json.name branch['name']
json.commit do
json.id branch['commit']['id']
json.message branch['commit']['message']
json.author do
json.partial! 'api/v1/users/commit_user', locals: { user: render_cache_commit_author(branch['commit']['author']), name: branch['commit']['author']['name'] }
end
json.committer do
json.partial! 'api/v1/users/commit_user', locals: { user: render_cache_commit_author(branch['commit']['committer']), name: branch['commit']['committer']['name'] }
end
json.time_ago time_from_now(branch['commit']['timestamp'].to_time)
json.timestamp branch['commit']['timestamp']
end
json.protected branch['protected']
json.user_can_push branch['user_can_push']
json.user_can_merge branch['user_can_merge']
json.commit_id branch['commit_id']
json.commit_time_from_now time_from_now(branch['commit_time'].to_time)
json.commit_time branch['commit_time']
json.default_branch branch['default_branch']
json.http_url render_http_url(@project)
json.zip_url render_zip_url(@owner, @project.repository, branch['name'])
json.tar_url render_tar_url(@owner, @project.repository, branch['name'])

View File

@ -0,0 +1,3 @@
json.array! @result_object["branch_name"] do |branch|
json.partial! "api/v1/projects/branches/simple_detail", branch: branch
end

View File

@ -0,0 +1 @@
json.partial! "api/v1/projects/branches/simple_gitea_detail", branch: @result_object

View File

@ -0,0 +1,10 @@
json.sha commit['sha']
json.author do
json.partial! 'api/v1/users/commit_user', locals: { user: render_cache_commit_author(commit['author']), name: commit['author']['name'] }
end
json.committer do
json.partial! 'api/v1/users/commit_user', locals: { user: render_cache_commit_author(commit['committer']), name: commit['committer']['name'] }
end
json.commit_message commit['message']
json.parent_shas commit['parents'].map{|x|x['sha']}

View File

@ -0,0 +1 @@
json.partial! "api/v1/projects/simple_gitea_diff_detail", diff: @result_object

View File

@ -0,0 +1,17 @@
json.total_count @result_object[:total_data].to_i
json.commits @result_object[:data].each do |commit|
json.sha commit['sha']
json.author do
json.partial! 'api/v1/users/commit_user', locals: { user: render_cache_commit_author(commit['commit']['author']), name: commit['commit']['author']['name'] }
end
json.committer do
json.partial! 'api/v1/users/commit_user', locals: { user: render_cache_commit_author(commit['commit']['committer']), name: commit['commit']['committer']['name'] }
end
json.commit_message commit['commit']['message']
json.parent_shas commit['parents'].map{|x|x['sha']}
json.files commit['files'].map{|f|f['filename']}
json.commit_date commit['commit_date']
json.commit_time render_unix_time(commit['commit']['committer']['date'])
json.branch commit['branch']
end

View File

@ -0,0 +1,18 @@
json.commits_count @result_object['CommitsCount']
json.last_commit_sha @result_object['LatestSha']
json.commits @result_object['Commits'] do |commit|
json.author do
json.partial! 'api/v1/users/commit_user', locals: { user: render_cache_commit_author(commit['Author']), name: commit['Author']['Name'] }
end
json.committer do
json.partial! 'api/v1/users/commit_user', locals: { user: render_cache_commit_author(commit['Committer']), name: commit['Committer']['Name'] }
end
json.branch commit['Branch']
json.commit_message commit['CommitMessage']
json.sha commit['Sha']
json.parent_shas commit['Sha']['ParentShas']
end
json.diff do
json.partial! "api/v1/projects/simple_gitea_diff_detail", diff: @result_object['Diff']
end

View File

@ -0,0 +1,14 @@
json.commit do
json.partial! "api/v1/projects/commits/simple_gitea_detail", commit: @result_object['commit']
json.authored_time render_unix_time(@result_object['commit']['author']['date'])
json.commited_time render_unix_time(@result_object['commit']['committer']['date'])
end
json.contents @result_object['contents'].each do |content|
json.name content['name']
json.path content['path']
json.sha content['sha']
json.type content['type']
json.size content['size']
json.encoding content['encoding']
json.content content['content']
end

View File

@ -0,0 +1,4 @@
json.sha @result_object['sha']
json.size @result_object['size']
json.encoding @result_object['encoding']
json.content @result_object['content']

View File

@ -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

View File

@ -0,0 +1,21 @@
if user.present?
if user.is_a?(Hash)
json.id user["id"]
json.login user["login"]
json.name user["name"]
json.type user["type"]
json.image_url user["avatar_url"]
else
json.id user.id
json.login user.login
json.name user.real_name
json.type user&.type
json.image_url url_to_avatar(user)
end
else
json.id nil
json.login name
json.name name
json.type nil
json.image_url User::Avatar.get_letter_avatar_url(name)
end

View File

@ -9,7 +9,12 @@ defaults format: :json do
scope ':repo' do
# projects
resource :projects, path: '/', only: [:show, :update, :edit, :destroy]
resource :projects, path: '/', only: [:show, :update, :edit, :destroy] do
collection do
get :compare
get :blame
end
end
# projects文件夹下的
scope module: :projects do
@ -23,6 +28,21 @@ defaults format: :json do
get :hooktasks
end
end
resources :branches, only:[:index, :create] do
collection do
get :all
end
end
resources :commits, only: [:index]
get '/commits/:sha/diff', to: 'commits#diff'
get '/git/blobs/:sha', to: 'git#blobs'
get '/git/trees/:sha', to: 'git#trees'
resources :contents, only: [:index] do
collection do
post :batch
end
end
end
end

File diff suppressed because it is too large Load Diff