| @@ -74,6 +74,7 @@ vendor/bundle/ | |||||
| /log | /log | ||||
| /public/admin | /public/admin | ||||
| /mysql_data | /mysql_data | ||||
| /public/repo/ | |||||
| .generators | .generators | ||||
| @@ -770,7 +770,7 @@ class ApplicationController < ActionController::Base | |||||
| end | end | ||||
| def base_url | def base_url | ||||
| request.base_url | |||||
| Rails.application.config_for(:configuration)['platform_url'] || request.base_url | |||||
| end | end | ||||
| def convert_image! | def convert_image! | ||||
| @@ -6,26 +6,48 @@ class CompareController < ApplicationController | |||||
| end | end | ||||
| def show | def show | ||||
| load_compare_params | |||||
| compare | compare | ||||
| @merge_status, @merge_message = get_merge_message | |||||
| end | end | ||||
| private | private | ||||
| def get_merge_message | |||||
| if @base.blank? || @head.blank? | |||||
| return -2, "请选择分支" | |||||
| else | |||||
| if @head.include?(":") | |||||
| fork_project = @project.forked_projects.joins(:owner).where(users: {login: @head.to_s.split("/")[0]}).take | |||||
| return -2, "请选择正确的仓库" unless fork_project.present? | |||||
| @exist_pullrequest = @project.pull_requests.where(is_original: true, head: @head.to_s.split(":")[1], base: @base, status: 0, fork_project_id: fork_project.id).take | |||||
| else | |||||
| @exist_pullrequest = @project.pull_requests.where(is_original: false, head: @base, base: @head, status: 0).take | |||||
| end | |||||
| if @exist_pullrequest.present? | |||||
| return -2, "在这些分支之间的合并请求已存在:<a href='/projects/#{@owner.login}/#{@project.identifier}/pulls/#{@exist_pullrequest.id}/Messagecount'>#{@exist_pullrequest.try(:title)}</a>" | |||||
| else | |||||
| if @compare_result["Commits"].blank? && @compare_result["Diff"].blank? | |||||
| return -2, "分支内容相同,无需创建合并请求" | |||||
| end | |||||
| end | |||||
| end | |||||
| return 0, "可以合并" | |||||
| end | |||||
| def compare | def compare | ||||
| base, head = compare_params | |||||
| # TODO: 处理fork的项目向源项目发送PR的base、head参数问题 | # TODO: 处理fork的项目向源项目发送PR的base、head参数问题 | ||||
| @compare_result ||= | @compare_result ||= | ||||
| head.include?(":") ? gitea_compare(base, head) : gitea_compare(head, base) | |||||
| @head.include?(":") ? gitea_compare(@base, @head) : gitea_compare(@head, @base) | |||||
| end | end | ||||
| def compare_params | |||||
| base = Addressable::URI.unescape(params[:base]) | |||||
| head = params[:head].include?('json') ? params[:head]&.split('.json')[0] : params[:head] | |||||
| def load_compare_params | |||||
| @base = Addressable::URI.unescape(params[:base]) | |||||
| @head = params[:head].include?('json') ? params[:head]&.split('.json')[0] : params[:head] | |||||
| [base, head] | |||||
| end | end | ||||
| def gitea_compare(base, head) | def gitea_compare(base, head) | ||||
| Gitea::Repository::Commits::CompareService.call(@owner.login, @project.identifier, base, head) | |||||
| Gitea::Repository::Commits::CompareService.call(@owner.login, @project.identifier, base, head, current_user.gitea_token) | |||||
| end | end | ||||
| end | end | ||||
| @@ -3,6 +3,7 @@ class IssuesController < ApplicationController | |||||
| before_action :load_project | before_action :load_project | ||||
| before_action :set_user | before_action :set_user | ||||
| before_action :check_issue_permission | before_action :check_issue_permission | ||||
| before_action :operate_issue_permission, only:[:create, :update, :destroy, :clean, :series_update, :copy] | |||||
| before_action :check_project_public, only: [:index ,:show, :copy, :index_chosen, :close_issue] | before_action :check_project_public, only: [:index ,:show, :copy, :index_chosen, :close_issue] | ||||
| before_action :set_issue, only: [:edit, :update, :destroy, :show, :copy, :close_issue, :lock_issue] | before_action :set_issue, only: [:edit, :update, :destroy, :show, :copy, :close_issue, :lock_issue] | ||||
| @@ -230,7 +231,7 @@ class IssuesController < ApplicationController | |||||
| end | end | ||||
| def show | def show | ||||
| @user_permission = current_user.present? && current_user.logged? && (!@issue.is_lock || @project.member?(current_user) || current_user.admin? || @issue.user == current_user) | |||||
| @user_permission = current_user.present? && current_user.logged? && (@project.member?(current_user) || current_user.admin? || @issue.user == current_user) | |||||
| @issue_attachments = @issue.attachments | @issue_attachments = @issue.attachments | ||||
| @issue_user = @issue.user | @issue_user = @issue.user | ||||
| @issue_assign_to = @issue.get_assign_user | @issue_assign_to = @issue.get_assign_user | ||||
| @@ -303,7 +304,7 @@ class IssuesController < ApplicationController | |||||
| if issue_ids.present? | if issue_ids.present? | ||||
| if update_hash.blank? | if update_hash.blank? | ||||
| normal_status(-1, "请选择批量更新内容") | normal_status(-1, "请选择批量更新内容") | ||||
| elsif Issue.where(id: issue_ids).update_all(update_hash) | |||||
| elsif Issue.where(id: issue_ids)&.update(update_hash) | |||||
| normal_status(0, "批量更新成功") | normal_status(0, "批量更新成功") | ||||
| else | else | ||||
| normal_status(-1, "批量更新失败") | normal_status(-1, "批量更新失败") | ||||
| @@ -315,6 +316,7 @@ class IssuesController < ApplicationController | |||||
| def copy | def copy | ||||
| @new_issue = @issue.dup | @new_issue = @issue.dup | ||||
| @new_issue.author_id = current_user.id | |||||
| if @new_issue.save | if @new_issue.save | ||||
| issue_tags = @issue.issue_tags.pluck(:id) | issue_tags = @issue.issue_tags.pluck(:id) | ||||
| if issue_tags.present? | if issue_tags.present? | ||||
| @@ -412,6 +414,10 @@ class IssuesController < ApplicationController | |||||
| end | end | ||||
| end | end | ||||
| def operate_issue_permission | |||||
| return render_forbidden("您没有权限进行此操作.") unless current_user.admin? || @project.member?(current_user) | |||||
| end | |||||
| def export_issues(issues) | def export_issues(issues) | ||||
| @table_columns = %w(ID 类型 标题 描述 状态 指派给 优先级 标签 发布人 创建时间 里程碑 开始时间 截止时间 完成度 分类 金额 属于) | @table_columns = %w(ID 类型 标题 描述 状态 指派给 优先级 标签 发布人 创建时间 里程碑 开始时间 截止时间 完成度 分类 金额 属于) | ||||
| @export_issues = [] | @export_issues = [] | ||||
| @@ -4,4 +4,7 @@ class Projects::BaseController < ApplicationController | |||||
| before_action :load_project | before_action :load_project | ||||
| before_action :load_repository | before_action :load_repository | ||||
| def require_manager! | |||||
| return render_forbidden('你没有权限操作') unless current_user.admin? || @project.manager?(current_user) | |||||
| end | |||||
| end | end | ||||
| @@ -0,0 +1,116 @@ | |||||
| class Projects::WebhooksController < Projects::BaseController | |||||
| before_action :require_manager! | |||||
| before_action :find_webhook, only:[:edit, :update, :destroy, :tasks, :test] | |||||
| def index | |||||
| @webhooks = @project.webhooks | |||||
| @webhooks = kaminari_paginate(@webhooks) | |||||
| end | |||||
| def create | |||||
| ActiveRecord::Base.transaction do | |||||
| return render_error("webhooks数量已到上限!请删除暂不使用的webhooks以进行添加操作") if @project.webhooks.size > 19 | |||||
| return render_error("参数错误.") unless webhook_params.present? | |||||
| form = Projects::Webhooks::CreateForm.new(webhook_params) | |||||
| return render json: {status: -1, message: form.errors} unless form.validate! | |||||
| response = Gitea::Repository::Webhooks::CreateService.new(operating_token, @project&.owner&.login, @project&.identifier, gitea_webhooks_params).call | |||||
| if response[0] == 201 | |||||
| @webhook = response[2] | |||||
| else | |||||
| render_error("创建失败.") | |||||
| end | |||||
| end | |||||
| rescue Exception => e | |||||
| uid_logger_error(e.message) | |||||
| tip_exception(e.message) | |||||
| end | |||||
| def edit | |||||
| end | |||||
| def update | |||||
| return render_error("参数错误.") unless webhook_params.present? | |||||
| form = Projects::Webhooks::CreateForm.new(webhook_params) | |||||
| return render json: {status: -1, message: form.errors} unless form.validate! | |||||
| response = Gitea::Repository::Webhooks::UpdateService.call(operating_token, @project&.owner&.login, @project&.identifier, @webhook.id, gitea_webhooks_params) | |||||
| if response[0] == 200 | |||||
| @webhook = response[2] | |||||
| render_ok | |||||
| else | |||||
| render_error("更新失败.") | |||||
| end | |||||
| rescue Exception => e | |||||
| uid_logger_error(e.message) | |||||
| tip_exception(e.message) | |||||
| end | |||||
| def destroy | |||||
| response = Gitea::Repository::Webhooks::DeleteService.call(operating_token, @project&.owner&.login, @project&.identifier, @webhook.id) | |||||
| if response[0] == 204 | |||||
| @webhook = response[2] | |||||
| render_ok | |||||
| else | |||||
| render_error("删除失败.") | |||||
| end | |||||
| rescue Exception => e | |||||
| uid_logger_error(e.message) | |||||
| tip_exception(e.message) | |||||
| end | |||||
| def tasks | |||||
| @tasks = @webhook.tasks.where(is_delivered: true).order("delivered desc") | |||||
| @tasks = kaminari_paginate(@tasks) | |||||
| end | |||||
| def test | |||||
| ActiveRecord::Base.transaction do | |||||
| response = Gitea::Repository::Webhooks::TestService.call(operating_token, @project&.owner&.login, @project&.identifier, @webhook.id) | |||||
| if response[0] == 204 | |||||
| render_ok | |||||
| else | |||||
| render_error("测试推送失败.") | |||||
| end | |||||
| end | |||||
| rescue Exception => e | |||||
| uid_logger_error(e.message) | |||||
| tip_exception(e.message) | |||||
| end | |||||
| private | |||||
| def find_webhook | |||||
| @webhook = @project.webhooks.find_by_id(params[:id]) | |||||
| return render_not_found if @webhook.nil? | |||||
| end | |||||
| def webhook_params | |||||
| params.require(:webhook).permit(:url, :type, :http_method, :content_type, :secret, :active, :branch_filter, events: []) | |||||
| end | |||||
| def webhook_type | |||||
| webhook_params.fetch(:type, "gitea") | |||||
| end | |||||
| def webhook_branch_filter | |||||
| webhook_params.fetch(:branch_filter, "*") | |||||
| end | |||||
| def gitea_webhooks_params | |||||
| { | |||||
| active: webhook_params[:active], | |||||
| branch_filter: webhook_branch_filter, | |||||
| config: { | |||||
| content_type: webhook_params[:content_type], | |||||
| url: webhook_params[:url], | |||||
| http_method: webhook_params[:http_method], | |||||
| secret: webhook_params[:secret] | |||||
| }, | |||||
| events: webhook_params[:events], | |||||
| type: webhook_type, | |||||
| } | |||||
| end | |||||
| def operating_token | |||||
| @project.member?(current_user) ? current_user.gitea_token : @project&.owner&.gitea_token | |||||
| end | |||||
| end | |||||
| @@ -5,7 +5,7 @@ class ProjectsController < ApplicationController | |||||
| include Acceleratorable | include Acceleratorable | ||||
| before_action :require_login, except: %i[index branches group_type_list simple show fork_users praise_users watch_users recommend about menu_list] | before_action :require_login, except: %i[index branches group_type_list simple show fork_users praise_users watch_users recommend about menu_list] | ||||
| before_action :load_project, except: %i[index group_type_list migrate create recommend] | |||||
| before_action :load_repository, except: %i[index group_type_list migrate create recommend] | |||||
| before_action :authorizate_user_can_edit_project!, only: %i[update] | before_action :authorizate_user_can_edit_project!, only: %i[update] | ||||
| before_action :project_public?, only: %i[fork_users praise_users watch_users] | before_action :project_public?, only: %i[fork_users praise_users watch_users] | ||||
| @@ -116,10 +116,11 @@ class ProjectsController < ApplicationController | |||||
| Projects::UpdateForm.new(validate_params).validate! | Projects::UpdateForm.new(validate_params).validate! | ||||
| private = params[:private] || false | |||||
| private = @project.forked_from_project.present? ? !@project.forked_from_project.is_public : params[:private] || false | |||||
| new_project_params = project_params.except(:private).merge(is_public: !private) | new_project_params = project_params.except(:private).merge(is_public: !private) | ||||
| @project.update_attributes!(new_project_params) | @project.update_attributes!(new_project_params) | ||||
| @project.forked_projects.update_all(is_public: @project.is_public) | |||||
| gitea_params = { | gitea_params = { | ||||
| private: private, | private: private, | ||||
| default_branch: @project.default_branch, | default_branch: @project.default_branch, | ||||
| @@ -144,6 +145,7 @@ class ProjectsController < ApplicationController | |||||
| ActiveRecord::Base.transaction do | ActiveRecord::Base.transaction do | ||||
| Gitea::Repository::DeleteService.new(@project.owner, @project.identifier).call | Gitea::Repository::DeleteService.new(@project.owner, @project.identifier).call | ||||
| @project.destroy! | @project.destroy! | ||||
| @project.forked_projects.update_all(forked_from_project_id: nil) | |||||
| render_ok | render_ok | ||||
| end | end | ||||
| else | else | ||||
| @@ -0,0 +1,64 @@ | |||||
| class PublicKeysController < ApplicationController | |||||
| before_action :require_login | |||||
| before_action :find_public_key, only: [:destroy] | |||||
| def index | |||||
| @public_keys = current_user.public_keys | |||||
| @public_keys = kaminari_paginate(@public_keys) | |||||
| rescue Exception => e | |||||
| uid_logger_error(e.message) | |||||
| tip_exception(e.message) | |||||
| end | |||||
| def create | |||||
| return render_error("参数错误") if public_key_params.blank? | |||||
| return render_ok({status: 10002, message: "请输入密钥"}) if public_key_params[:key].blank? | |||||
| return render_ok({status: 10001, message: "请输入标题"}) if public_key_params[:title].blank? | |||||
| @gitea_response = Gitea::User::Keys::CreateService.call(current_user.gitea_token, public_key_params) | |||||
| if @gitea_response[0] == 201 | |||||
| @public_key = @gitea_response[2] | |||||
| else | |||||
| return render_error("创建ssh key失败") if @gitea_response[2].blank? | |||||
| return render_ok({status: 10002, message: "密钥格式不正确"}) if @gitea_response[2]["message"].starts_with?("Invalid key content") | |||||
| exist_public_key = Gitea::PublicKey.find_by(content: public_key_params[:key]) | |||||
| return render_ok({status: 10002, message: "密钥已被占用"}) if @gitea_response[2]["message"].starts_with?("Key content has been used as non-deploy key") && exist_public_key.present? && exist_public_key&.owner_id != current_user.gitea_uid | |||||
| return render_ok({status: 10002, message: "密钥已存在,请勿重复添加"}) if @gitea_response[2]["message"].starts_with?("Key content has been used as non-deploy key") | |||||
| @public_key = nil | |||||
| end | |||||
| rescue Exception => e | |||||
| uid_logger_error(e.message) | |||||
| tip_exception(e.message) | |||||
| end | |||||
| def destroy | |||||
| return render_not_found unless @public_key.present? | |||||
| result = Gitea::User::Keys::DeleteService.call(current_user.gitea_token, @public_key.id) | |||||
| if result[0] == 204 | |||||
| render_ok | |||||
| else | |||||
| render_error | |||||
| end | |||||
| rescue Exception => e | |||||
| uid_logger_error(e.message) | |||||
| tip_exception(e.message) | |||||
| end | |||||
| private | |||||
| def page | |||||
| params[:page].to_i.zero? ? 1 : params[:page].to_i | |||||
| end | |||||
| def limit | |||||
| limit = params[:limit] || params[:per_page] | |||||
| limit = (limit.to_i.zero? || limit.to_i > 15) ? 15 : limit.to_i | |||||
| end | |||||
| def public_key_params | |||||
| params.require(:public_key).permit(:key, :title) | |||||
| end | |||||
| def find_public_key | |||||
| @public_key = current_user.public_keys.find_by_id(params[:id]) | |||||
| end | |||||
| end | |||||
| @@ -56,7 +56,7 @@ class PullRequestsController < ApplicationController | |||||
| ActiveRecord::Base.transaction do | ActiveRecord::Base.transaction do | ||||
| @pull_request, @gitea_pull_request = PullRequests::CreateService.call(current_user, @owner, @project, params) | @pull_request, @gitea_pull_request = PullRequests::CreateService.call(current_user, @owner, @project, params) | ||||
| if @gitea_pull_request[:status] == :success | if @gitea_pull_request[:status] == :success | ||||
| @pull_request.bind_gitea_pull_request!(@gitea_pull_request[:body]["number"]) | |||||
| @pull_request.bind_gitea_pull_request!(@gitea_pull_request[:body]["number"], @gitea_pull_request[:body]["id"]) | |||||
| render_ok | render_ok | ||||
| else | else | ||||
| render_error("create pull request error: #{@gitea_pull_request[:status]}") | render_error("create pull request error: #{@gitea_pull_request[:status]}") | ||||
| @@ -91,7 +91,7 @@ class PullRequestsController < ApplicationController | |||||
| if @issue.update_attributes(@issue_params) | if @issue.update_attributes(@issue_params) | ||||
| if @pull_request.update_attributes(@local_params.compact) | if @pull_request.update_attributes(@local_params.compact) | ||||
| gitea_pull = Gitea::PullRequest::UpdateService.call(@owner.login, @repository.identifier, | gitea_pull = Gitea::PullRequest::UpdateService.call(@owner.login, @repository.identifier, | ||||
| @pull_request.gpid, @requests_params, current_user.gitea_token) | |||||
| @pull_request.gitea_number, @requests_params, current_user.gitea_token) | |||||
| if gitea_pull[:status] === :success | if gitea_pull[:status] === :success | ||||
| if params[:issue_tag_ids].present? | if params[:issue_tag_ids].present? | ||||
| @@ -139,7 +139,7 @@ class PullRequestsController < ApplicationController | |||||
| @issue_user = @issue.user | @issue_user = @issue.user | ||||
| @issue_assign_to = @issue.get_assign_user | @issue_assign_to = @issue.get_assign_user | ||||
| @gitea_pull = Gitea::PullRequest::GetService.call(@owner.login, | @gitea_pull = Gitea::PullRequest::GetService.call(@owner.login, | ||||
| @repository.identifier, @pull_request.gpid, current_user&.gitea_token) | |||||
| @repository.identifier, @pull_request.gitea_number, current_user&.gitea_token) | |||||
| end | end | ||||
| def pr_merge | def pr_merge | ||||
| @@ -150,9 +150,16 @@ class PullRequestsController < ApplicationController | |||||
| else | else | ||||
| ActiveRecord::Base.transaction do | ActiveRecord::Base.transaction do | ||||
| begin | begin | ||||
| result = PullRequests::MergeService.call(@owner, @repository, @pull_request, current_user, params) | |||||
| @gitea_pull = Gitea::PullRequest::GetService.call(@owner.login, @repository.identifier, @pull_request.gitea_number, current_user&.gitea_token) | |||||
| if result.status == 200 && @pull_request.merge! | |||||
| if @gitea_pull["merged_by"].present? | |||||
| success_condition = true | |||||
| else | |||||
| result = PullRequests::MergeService.call(@owner, @repository, @pull_request, current_user, params) | |||||
| success_condition = result.status == 200 | |||||
| end | |||||
| if success_condition && @pull_request.merge! | |||||
| @pull_request.project_trend_status! | @pull_request.project_trend_status! | ||||
| @issue&.custom_journal_detail("merge", "", "该合并请求已被合并", current_user&.id) | @issue&.custom_journal_detail("merge", "", "该合并请求已被合并", current_user&.id) | ||||
| normal_status(1, "合并成功") | normal_status(1, "合并成功") | ||||
| @@ -191,12 +198,12 @@ class PullRequestsController < ApplicationController | |||||
| def files | def files | ||||
| @files_result = Gitea::PullRequest::FilesService.call(@owner.login, @project.identifier, @pull_request.gpid, current_user&.gitea_token) | |||||
| @files_result = Gitea::PullRequest::FilesService.call(@owner.login, @project.identifier, @pull_request.gitea_number, current_user&.gitea_token) | |||||
| # render json: @files_result | # render json: @files_result | ||||
| end | end | ||||
| def commits | def commits | ||||
| @commits_result = Gitea::PullRequest::CommitsService.call(@owner.login, @project.identifier, @pull_request.gpid, current_user&.gitea_token) | |||||
| @commits_result = Gitea::PullRequest::CommitsService.call(@owner.login, @project.identifier, @pull_request.gitea_number, current_user&.gitea_token) | |||||
| # render json: @commits_result | # render json: @commits_result | ||||
| end | end | ||||
| @@ -5,9 +5,9 @@ class RepositoriesController < ApplicationController | |||||
| before_action :require_login, only: %i[edit update create_file update_file delete_file sync_mirror] | before_action :require_login, only: %i[edit update create_file update_file delete_file sync_mirror] | ||||
| before_action :load_repository | before_action :load_repository | ||||
| before_action :authorizate!, except: [:sync_mirror, :tags, :commit] | |||||
| before_action :authorizate!, except: [:sync_mirror, :tags, :commit, :archive] | |||||
| before_action :authorizate_user_can_edit_repo!, only: %i[sync_mirror] | before_action :authorizate_user_can_edit_repo!, only: %i[sync_mirror] | ||||
| before_action :get_ref, only: %i[entries sub_entries top_counts file] | |||||
| before_action :get_ref, only: %i[entries sub_entries top_counts file archive] | |||||
| before_action :get_latest_commit, only: %i[entries sub_entries top_counts] | before_action :get_latest_commit, only: %i[entries sub_entries top_counts] | ||||
| before_action :get_statistics, only: %i[top_counts] | before_action :get_statistics, only: %i[top_counts] | ||||
| @@ -192,6 +192,19 @@ class RepositoriesController < ApplicationController | |||||
| render json: languages_precentagable | render json: languages_precentagable | ||||
| end | end | ||||
| def archive | |||||
| domain = Gitea.gitea_config[:domain] | |||||
| api_url = Gitea.gitea_config[:base_url] | |||||
| archive_url = "/repos/#{@owner.login}/#{@repository.identifier}/archive/#{params[:archive]}" | |||||
| file_path = [domain, api_url, archive_url].join | |||||
| file_path = [file_path, "access_token=#{current_user&.gitea_token}"].join("?") if @repository.hidden? | |||||
| return render_not_found if !request.format.zip? && !request.format.gzip? | |||||
| redirect_to file_path | |||||
| end | |||||
| private | private | ||||
| def find_project | def find_project | ||||
| @@ -266,7 +279,7 @@ class RepositoriesController < ApplicationController | |||||
| # uploadPushInfo | # uploadPushInfo | ||||
| end | end | ||||
| def create_new_pr(params) | def create_new_pr(params) | ||||
| if params[:new_branch].present? && params[:new_branch] != params[:branch] | if params[:new_branch].present? && params[:new_branch] != params[:branch] | ||||
| local_params = { | local_params = { | ||||
| @@ -303,7 +316,7 @@ class RepositoriesController < ApplicationController | |||||
| local_requests = PullRequest.new(local_params.merge(user_id: current_user.try(:id), project_id: @project.id, issue_id: @pull_issue.id)) | local_requests = PullRequest.new(local_params.merge(user_id: current_user.try(:id), project_id: @project.id, issue_id: @pull_issue.id)) | ||||
| if local_requests.save | if local_requests.save | ||||
| gitea_request = Gitea::PullRequest::CreateService.new(current_user.try(:gitea_token), @owner.login, @project.try(:identifier), requests_params).call | gitea_request = Gitea::PullRequest::CreateService.new(current_user.try(:gitea_token), @owner.login, @project.try(:identifier), requests_params).call | ||||
| if gitea_request[:status] == :success && local_requests.update_attributes(gpid: gitea_request["body"]["number"]) | |||||
| if gitea_request[:status] == :success && local_requests.update_attributes(gitea_number: gitea_request["body"]["number"]) | |||||
| local_requests.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: "create") | local_requests.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: "create") | ||||
| end | end | ||||
| end | end | ||||
| @@ -25,17 +25,13 @@ class VersionsController < ApplicationController | |||||
| end | end | ||||
| def show | def show | ||||
| version_issues = @version.issues.issue_includes | |||||
| version_issues = @version.issues.issue_issue.issue_includes | |||||
| status_type = params[:status_type] || "1" | status_type = params[:status_type] || "1" | ||||
| # @close_issues_size = version_issues.where(status_id: 5).size | # @close_issues_size = version_issues.where(status_id: 5).size | ||||
| # @open_issues_size = version_issues.size - @close_issues_size | # @open_issues_size = version_issues.size - @close_issues_size | ||||
| if status_type.to_s == "1" #表示开启中的 | |||||
| version_issues = version_issues.where.not(status_id: 5) | |||||
| else | |||||
| version_issues = version_issues.where(status_id: 5) | |||||
| end | |||||
| version_issues = version_issues.where(author_id: params[:author_id]) if params[:author_id].present? && params[:author_id].to_s != "all" | version_issues = version_issues.where(author_id: params[:author_id]) if params[:author_id].present? && params[:author_id].to_s != "all" | ||||
| version_issues = version_issues.where(assigned_to_id: params[:assigned_to_id]) if params[:assigned_to_id].present? && params[:assigned_to_id].to_s != "all" | version_issues = version_issues.where(assigned_to_id: params[:assigned_to_id]) if params[:assigned_to_id].present? && params[:assigned_to_id].to_s != "all" | ||||
| version_issues = version_issues.where(tracker_id: params[:tracker_id]) if params[:tracker_id].present? && params[:tracker_id].to_s != "all" | version_issues = version_issues.where(tracker_id: params[:tracker_id]) if params[:tracker_id].present? && params[:tracker_id].to_s != "all" | ||||
| @@ -47,10 +43,26 @@ class VersionsController < ApplicationController | |||||
| version_issues = version_issues.joins(:issue_tags).where(issue_tags: {id: params[:issue_tag_id].to_i}) if params[:issue_tag_id].present? && params[:issue_tag_id].to_s != "all" | version_issues = version_issues.joins(:issue_tags).where(issue_tags: {id: params[:issue_tag_id].to_i}) if params[:issue_tag_id].present? && params[:issue_tag_id].to_s != "all" | ||||
| version_issues = version_issues.reorder("#{order_name} #{order_type}") | version_issues = version_issues.reorder("#{order_name} #{order_type}") | ||||
| has_filter_params = (params[:author_id].present? && params[:author_id].to_s != "all") || | |||||
| (params[:assigned_to_id].present? && params[:assigned_to_id].to_s != "all") || | |||||
| (params[:tracker_id].present? && params[:tracker_id].to_s != "all") || | |||||
| (params[:status_id].present? && params[:status_id].to_s != "all") || | |||||
| (params[:priority_id].present? && params[:priority_id].to_s != "all") || | |||||
| (params[:fixed_version_id].present? && params[:fixed_version_id].to_s != "all") || | |||||
| (params[:done_ratio].present? && params[:done_ratio].to_s != "all") || | |||||
| (params[:issue_type].present? && params[:issue_type].to_s != "all") || | |||||
| (params[:issue_tag_id].present? && params[:issue_tag_id].to_s != "all") | |||||
| @version_close_issues_size = has_filter_params ? version_issues.closed.size : @version.issues.issue_issue.issue_includes.closed.size | |||||
| @version_issues_size = has_filter_params ? version_issues.size : @version.issues.issue_issue.issue_includes.size | |||||
| if status_type.to_s == "1" #表示开启中的 | |||||
| version_issues = version_issues.where.not(status_id: 5) | |||||
| else | |||||
| version_issues = version_issues.where(status_id: 5) | |||||
| end | |||||
| @page = params[:page] || 1 | @page = params[:page] || 1 | ||||
| @limit = params[:limit] || 15 | @limit = params[:limit] || 15 | ||||
| @version_issues_size = version_issues.size | |||||
| # @version_issues_size = version_issues.size | |||||
| @version_issues = version_issues.page(@page).per(@limit) | @version_issues = version_issues.page(@page).per(@limit) | ||||
| end | end | ||||
| @@ -12,6 +12,7 @@ toc_footers: | |||||
| includes: | includes: | ||||
| - licenses | - licenses | ||||
| - gitignores | - gitignores | ||||
| - public_keys | |||||
| - users | - users | ||||
| - projects | - projects | ||||
| - repositories | - repositories | ||||
| @@ -0,0 +1,158 @@ | |||||
| <!-- | |||||
| * @Date: 2021-07-14 15:10:29 | |||||
| * @LastEditors: viletyy | |||||
| * @LastEditTime: 2021-07-14 15:37:23 | |||||
| * @FilePath: /forgeplus/app/docs/slate/source/includes/_public_keys.md | |||||
| --> | |||||
| # PublicKeys | |||||
| ## public_keys列表 | |||||
| 获取public_keys列表,支持分页 | |||||
| > 示例: | |||||
| ```shell | |||||
| curl -X GET \ | |||||
| http://localhost:3000/api/public_keys.json | |||||
| ``` | |||||
| ```javascript | |||||
| await octokit.request('GET /api/public_keys.json') | |||||
| ``` | |||||
| ### HTTP 请求 | |||||
| `GET api/public_keys.json` | |||||
| ### 请求参数 | |||||
| 参数 | 必选 | 默认 | 类型 | 字段说明 | |||||
| --------- | ------- | ------- | -------- | ---------- | |||||
| page |否| 1 | int | 页码 | | |||||
| limit |否| 15 | int | 每页数量 | | |||||
| ### 返回字段说明 | |||||
| 参数 | 类型 | 字段说明 | |||||
| --------- | ----------- | ----------- | |||||
| total_count |int |总数 | | |||||
| public_keys.id |int |ID| | |||||
| public_keys.name |string|密钥标题| | |||||
| public_keys.content |string|密钥内容| | |||||
| public_keys.fingerprint |string|密钥标识| | |||||
| public_keys.created_time |string|密钥创建时间| | |||||
| > 返回的JSON示例: | |||||
| ```json | |||||
| { | |||||
| "total_count": 1, | |||||
| "public_keys": [ | |||||
| { | |||||
| "id": 16, | |||||
| "name": "xxx", | |||||
| "content": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDe5ETOTB5PcmcYJkIhfF7+mxmJQDCLg7/LnMoKHpKoo/jYUnFU9OjfsxVo3FTNUvh2475WXMAur5KsFoNKjK9+JHxvoXyJKmyVPWgXU/NRxQyaWPnPLPK8qPRF5ksJE6feBOqtsdxsvBiHs2r1NX/U26Ecnpr6avudD0cmyrEfbYMWbupLrhsd39dswPT73f3W5jc7B9Y47Ioiv8UOju3ABt1+kpuAjaaVC6VtUQoEFiZb1y33yBnyePya7dvFyApyD4ILyyIG2rtZWK7l53YFnwZDuFsTWjEEEQD0U4FBSFdH5wtwx0WQLMSNyTtaFBSG0kJ+uiQQIrxlvikcm63df7zbC3/rWLPsKgW122Zt966dcpFqiCiJNDKZPPw3qpg8TBL6X+qIZ+FxVEk/16/zScpyEfoxQp0GvgxI7hPLErmfkC5tMsib8MAXYBNyvJXna0vg/wOaNNIaI4SAH9Ksh3f/TtalYVjp6WxIwVBfnbq51WnmlnEXePtX6XjAGL+GbF2VQ1nv/IzrY09tNbTV6wQsrSIP3VDzYQxdJ1rdsVNMoJB0H2Pu0NdcSz53Wx45N+myD0QnE05ss+zDp5StY90OYsx2aCo6qAA8Qn2jUjdta7MQWwkPfKrta4tTQ0XbWMjx4/E1+l3J5liwZkl2XOGOwhfXdRsBjaEziZ18kQ== yystopf@163.com", | |||||
| "fingerprint": "SHA256:cU8AK/+roqUUyiaYXIdS2Nj4+Rb2p6rqWSeRDc+aqKM", | |||||
| "created_unix": 1626246596, | |||||
| "created_time": "2021/07/14 15:09" | |||||
| } | |||||
| ] | |||||
| } | |||||
| ``` | |||||
| <aside class="success"> | |||||
| Success — a happy kitten is an authenticated kitten! | |||||
| </aside> | |||||
| ## 创建public_key | |||||
| 创建public_key | |||||
| > 示例: | |||||
| ```shell | |||||
| curl -X POST \ | |||||
| http://localhost:3000/api/public_keys.json | |||||
| ``` | |||||
| ```javascript | |||||
| await octokit.request('POST /api/public_keys.json') | |||||
| ``` | |||||
| ### HTTP 请求 | |||||
| `POST api/public_keys.json` | |||||
| ### 请求参数 | |||||
| 参数 | 必选 | 默认 | 类型 | 字段说明 | |||||
| --------- | ------- | ------- | -------- | ---------- | |||||
| key |是 | 否 | string | 密钥 | | |||||
| title |是 | 否 | string | 密钥标题 | | |||||
| > 请求的JSON示例: | |||||
| ```json | |||||
| { | |||||
| "public_key": { | |||||
| "key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDe5ETOTB5PcmcYJkIhfF7+mxmJQDCLg7/LnMoKHpKoo/jYUnFU9OjfsxVo3FTNUvh2475WXMAur5KsFoNKjK9+JHxvoXyJKmyVPWgXU/NRxQyaWPnPLPK8qPRF5ksJE6feBOqtsdxsvBiHs2r1NX/U26Ecnpr6avudD0cmyrEfbYMWbupLrhsd39dswPT73f3W5jc7B9Y47Ioiv8UOju3ABt1+kpuAjaaVC6VtUQoEFiZb1y33yBnyePya7dvFyApyD4ILyyIG2rtZWK7l53YFnwZDuFsTWjEEEQD0U4FBSFdH5wtwx0WQLMSNyTtaFBSG0kJ+uiQQIrxlvikcm63df7zbC3/rWLPsKgW122Zt966dcpFqiCiJNDKZPPw3qpg8TBL6X+qIZ+FxVEk/16/zScpyEfoxQp0GvgxI7hPLErmfkC5tMsib8MAXYBNyvJXna0vg/wOaNNIaI4SAH9Ksh3f/TtalYVjp6WxIwVBfnbq51WnmlnEXePtX6XjAGL+GbF2VQ1nv/IzrY09tNbTV6wQsrSIP3VDzYQxdJ1rdsVNMoJB0H2Pu0NdcSz53Wx45N+myD0QnE05ss+zDp5StY90OYsx2aCo6qAA8Qn2jUjdta7MQWwkPfKrta4tTQ0XbWMjx4/E1+l3J5liwZkl2XOGOwhfXdRsBjaEziZ18kQ== yystopf@163.com", | |||||
| "title": "xxx" | |||||
| } | |||||
| } | |||||
| ``` | |||||
| ### 返回字段说明 | |||||
| 参数 | 类型 | 字段说明 | |||||
| --------- | ----------- | ----------- | |||||
| total_count |int |总数 | | |||||
| id |int |ID| | |||||
| name |string|密钥标题| | |||||
| content |string|密钥内容| | |||||
| fingerprint |string|密钥标识| | |||||
| created_time |string|密钥创建时间| | |||||
| > 返回的JSON示例: | |||||
| ```json | |||||
| { | |||||
| "id": 17, | |||||
| "name": "xxx", | |||||
| "content": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDe5ETOTB5PcmcYJkIhfF7+mxmJQDCLg7/LnMoKHpKoo/jYUnFU9OjfsxVo3FTNUvh2475WXMAur5KsFoNKjK9+JHxvoXyJKmyVPWgXU/NRxQyaWPnPLPK8qPRF5ksJE6feBOqtsdxsvBiHs2r1NX/U26Ecnpr6avudD0cmyrEfbYMWbupLrhsd39dswPT73f3W5jc7B9Y47Ioiv8UOju3ABt1+kpuAjaaVC6VtUQoEFiZb1y33yBnyePya7dvFyApyD4ILyyIG2rtZWK7l53YFnwZDuFsTWjEEEQD0U4FBSFdH5wtwx0WQLMSNyTtaFBSG0kJ+uiQQIrxlvikcm63df7zbC3/rWLPsKgW122Zt966dcpFqiCiJNDKZPPw3qpg8TBL6X+qIZ+FxVEk/16/zScpyEfoxQp0GvgxI7hPLErmfkC5tMsib8MAXYBNyvJXna0vg/wOaNNIaI4SAH9Ksh3f/TtalYVjp6WxIwVBfnbq51WnmlnEXePtX6XjAGL+GbF2VQ1nv/IzrY09tNbTV6wQsrSIP3VDzYQxdJ1rdsVNMoJB0H2Pu0NdcSz53Wx45N+myD0QnE05ss+zDp5StY90OYsx2aCo6qAA8Qn2jUjdta7MQWwkPfKrta4tTQ0XbWMjx4/E1+l3J5liwZkl2XOGOwhfXdRsBjaEziZ18kQ== yystopf@163.com", | |||||
| "fingerprint": "SHA256:cU8AK/+roqUUyiaYXIdS2Nj4+Rb2p6rqWSeRDc+aqKM", | |||||
| "created_time": "2021/07/14 15:26" | |||||
| } | |||||
| ``` | |||||
| <aside class="success"> | |||||
| Success — a happy kitten is an authenticated kitten! | |||||
| </aside> | |||||
| ## 删除public_key | |||||
| 删除public_key | |||||
| > 示例: | |||||
| ```shell | |||||
| curl -X DELETE \ | |||||
| http://localhost:3000/api/public_keys/:id.json | |||||
| ``` | |||||
| ```javascript | |||||
| await octokit.request('DELETE /api/public_keys/:id.json') | |||||
| ``` | |||||
| ### HTTP 请求 | |||||
| `DELETE api/public_keys/:id.json` | |||||
| ### 请求参数 | |||||
| 参数 | 必选 | 默认 | 类型 | 字段说明 | |||||
| --------- | ------- | ------- | -------- | ---------- | |||||
| id |是 | 否 | int | 密钥ID | | |||||
| > 返回的JSON示例: | |||||
| ```json | |||||
| { | |||||
| "status": 0, | |||||
| "message": "success" | |||||
| } | |||||
| ``` | |||||
| <aside class="success"> | |||||
| Success — a happy kitten is an authenticated kitten! | |||||
| </aside> | |||||
| @@ -867,3 +867,674 @@ await octokit.request('GET /api/jasder/jasder_test/sub_entries.json') | |||||
| <aside class="success"> | <aside class="success"> | ||||
| Success Data. | Success Data. | ||||
| </aside> | </aside> | ||||
| ## 获取仓库webhooks列表 | |||||
| 获取仓库webhooks列表 | |||||
| > 示例: | |||||
| ```shell | |||||
| curl -X GET \ | |||||
| http://localhost:3000/api/yystopf/ceshi/webhooks.json | |||||
| ``` | |||||
| ```javascript | |||||
| await octokit.request('GET /api/yystopf/ceshi/webhooks.json') | |||||
| ``` | |||||
| ### HTTP 请求 | |||||
| `GET /api/:owner/:repo/webhooks.json` | |||||
| ### 请求参数: | |||||
| 参数 | 必选 | 默认 | 类型 | 字段说明 | |||||
| --------- | ------- | ------- | -------- | ---------- | |||||
| |owner |是| |string |用户登录名 | | |||||
| |repo |是| |string |项目标识identifier | | |||||
| ### 返回字段说明: | |||||
| 参数 | 类型 | 字段说明 | |||||
| --------- | ----------- | ----------- | |||||
| |id |int |id | | |||||
| |url |string|地址| | |||||
| |http_method |string|请求方式| | |||||
| |is_active |bool |是否激活| | |||||
| |type |string|类型| | |||||
| |last_status |string|最后一次推送的状态| | |||||
| |create_time |string|创建时间| | |||||
| > 返回的JSON示例: | |||||
| ```json | |||||
| { | |||||
| "total_count": 4, | |||||
| "webhooks": [ | |||||
| { | |||||
| "id": 2, | |||||
| "url": "https://oapi.dingtalk.com/robot/send?access_token=7e1e19d0eddb6a5e33c5c2c4e66f4c88f9437184b9ed2c2653194c6374c7d513", | |||||
| "http_method": "", | |||||
| "is_active": true, | |||||
| "type": "dingtalk", | |||||
| "last_status": "succeed", | |||||
| "create_time": "2021-07-12 10:50:07" | |||||
| }, | |||||
| { | |||||
| "id": 3, | |||||
| "url": "http://localhost:3000", | |||||
| "http_method": "GET", | |||||
| "is_active": true, | |||||
| "type": "gitea", | |||||
| "last_status": "succeed", | |||||
| "create_time": "2021-07-26 10:03:45" | |||||
| }, | |||||
| { | |||||
| "id": 4, | |||||
| "url": "http://localhost:10081", | |||||
| "http_method": "POST", | |||||
| "is_active": true, | |||||
| "type": "gitea", | |||||
| "last_status": "waiting", | |||||
| "create_time": "2021-07-26 16:56:53" | |||||
| }, | |||||
| { | |||||
| "id": 5, | |||||
| "url": "http://localhost:3001", | |||||
| "http_method": "POST", | |||||
| "is_active": true, | |||||
| "type": "gitea", | |||||
| "last_status": "fail", | |||||
| "create_time": "2021-07-26 16:58:23" | |||||
| } | |||||
| ] | |||||
| } | |||||
| ``` | |||||
| <aside class="success"> | |||||
| Success Data. | |||||
| </aside> | |||||
| ## 获取仓库单个webhook | |||||
| 获取仓库单个webhook | |||||
| > 示例: | |||||
| ```shell | |||||
| curl -X GET \ | |||||
| http://localhost:3000/api/yystopf/ceshi/webhooks/3/edit.json | |||||
| ``` | |||||
| ```javascript | |||||
| await octokit.request('GET /api/yystopf/ceshi/webhooks/3/edit.json') | |||||
| ``` | |||||
| ### HTTP 请求 | |||||
| `GET /api/:owner/:repo/webhooks/:id/edit.json` | |||||
| ### 请求参数: | |||||
| 参数 | 必选 | 默认 | 类型 | 字段说明 | |||||
| --------- | ------- | ------- | -------- | ---------- | |||||
| |owner |是| |string |用户登录名 | | |||||
| |repo |是| |string |项目标识identifier | | |||||
| |id |是||integer|webhook ID| | |||||
| ### 返回字段说明: | |||||
| 参数 | 类型 | 字段说明 | |||||
| --------- | ----------- | ----------- | |||||
| |id |int |id | | |||||
| |url |string|地址| | |||||
| |content_type |string|POST Content Type| | |||||
| |http_method |string|请求方式| | |||||
| |secret| |string|密钥| | |||||
| |is_active |bool |是否激活| | |||||
| |type |string|类型| | |||||
| |last_status |string|最后一次推送的状态, waiting 等待,fail 失败,succeed 成功| | |||||
| |branch_filter |string|分支过滤| | |||||
| |events |string|触发条件| | |||||
| |create_time |string|创建时间| | |||||
| 参数| 含义| | |||||
| --------- | ------- | ------- | | |||||
| |create|创建分支或标签| | |||||
| |delete|分支或标签删除| | |||||
| |fork|仓库被fork| | |||||
| |push|git仓库推送| | |||||
| |issue|易修已打开、已关闭、已重新打开或编辑| | |||||
| |issue_assign|易修被指派| | |||||
| |issue_label|易修标签被更新或删除| | |||||
| |issue_milestone|易修被收入里程碑| | |||||
| |issue_comment|易修评论| | |||||
| |pull_request|合并请求| | |||||
| |pull_request_assign|合并请求被指派| | |||||
| |pull_request_label|合并请求被贴上标签| | |||||
| |pull_request_milestone|合并请求被记录于里程碑中| | |||||
| |pull_request_comment|合并请求被评论| | |||||
| |pull_request_review_approved|合并请求被批准| | |||||
| |pull_request_review_rejected|合并请求被拒绝| | |||||
| |pull_request_review_comment|合并请求被提出审查意见| | |||||
| |pull_request_sync|合并请求被同步| | |||||
| |repository|创建或删除仓库| | |||||
| |release|版本发布| | |||||
| > 返回的JSON示例: | |||||
| ```json | |||||
| { | |||||
| "id": 3, | |||||
| "http_method": "GET", | |||||
| "content_type": "form", | |||||
| "url": "http://localhost:3000", | |||||
| "secret": "123456", | |||||
| "last_status": "succeed", | |||||
| "is_active": true, | |||||
| "type": "gitea", | |||||
| "create_time": "2021-07-26 10:03:45", | |||||
| "branch_filter": "*", | |||||
| "events": [ | |||||
| "create", | |||||
| "delete", | |||||
| "fork", | |||||
| "issues", | |||||
| "issue_assign", | |||||
| "issue_label", | |||||
| "issue_milestone", | |||||
| "issue_comment", | |||||
| "push", | |||||
| "pull_request", | |||||
| "pull_request_assign", | |||||
| "pull_request_label", | |||||
| "pull_request_milestone", | |||||
| "pull_request_comment", | |||||
| "pull_request_review", | |||||
| "pull_request_sync", | |||||
| "repository", | |||||
| "release" | |||||
| ] | |||||
| } | |||||
| ``` | |||||
| <aside class="success"> | |||||
| Success Data. | |||||
| </aside> | |||||
| ## 添加仓库webhook | |||||
| 添加仓库webhook | |||||
| > 示例: | |||||
| ```shell | |||||
| curl -X POST \ | |||||
| http://localhost:3000/api/yystopf/ceshi/webhooks.json | |||||
| ``` | |||||
| ```javascript | |||||
| await octokit.request('POST /api/yystopf/ceshi/webhooks.json') | |||||
| ``` | |||||
| ### HTTP 请求 | |||||
| `POST /api/:owner/:repo/webhooks.json` | |||||
| ### 请求参数: | |||||
| 参数 | 必选 | 默认 | 类型 | 字段说明 | |||||
| --------- | ------- | ------- | -------- | ---------- | |||||
| |owner |是| | string |用户登录名 | | |||||
| |repo |是| | string |项目标识identifier | | |||||
| |webhook.url |是| | string |目标url | | |||||
| |webhook.type |否| | string |类型| | |||||
| |webhook.http_method |是| | string | http方法, POST和GET | | |||||
| |webhook.content_type |是| | string | POST Content Type | | |||||
| |webhook.secret |否| | string |密钥文本| | |||||
| |webhook.active |是| | bool | 是否激活| | |||||
| |webhook.branch_filter|否| |string|分支过滤| | |||||
| |webhook.events |否| |array|触发事件| | |||||
| 触发事件字段说明 | |||||
| 参数| 含义| | |||||
| --------- | ------- | ------- | | |||||
| |create|创建分支或标签| | |||||
| |delete|分支或标签删除| | |||||
| |fork|仓库被fork| | |||||
| |push|git仓库推送| | |||||
| |issue|易修已打开、已关闭、已重新打开或编辑| | |||||
| |issue_assign|易修被指派| | |||||
| |issue_label|易修标签被更新或删除| | |||||
| |issue_milestone|易修被收入里程碑| | |||||
| |issue_comment|易修评论| | |||||
| |pull_request|合并请求| | |||||
| |pull_request_assign|合并请求被指派| | |||||
| |pull_request_label|合并请求被贴上标签| | |||||
| |pull_request_milestone|合并请求被记录于里程碑中| | |||||
| |pull_request_comment|合并请求被评论| | |||||
| |pull_request_review_approved|合并请求被批准| | |||||
| |pull_request_review_rejected|合并请求被拒绝| | |||||
| |pull_request_review_comment|合并请求被提出审查意见| | |||||
| |pull_request_sync|合并请求被同步| | |||||
| |repository|创建或删除仓库| | |||||
| |release|版本发布| | |||||
| > 请求的JSON示例: | |||||
| ```json | |||||
| { | |||||
| "active": true, | |||||
| "content_type": "json", | |||||
| "http_method": "GET", | |||||
| "secret": "123456", | |||||
| "url": "http://localhost:10000", | |||||
| "branch_filter": "*", | |||||
| "events": ["push"] | |||||
| } | |||||
| ``` | |||||
| ### 返回字段说明: | |||||
| 参数 | 类型 | 字段说明 | |||||
| --------- | ----------- | ----------- | |||||
| |id |int |id | | |||||
| |url |string|地址| | |||||
| |content_type |string|POST Content Type| | |||||
| |is_active |bool |是否激活| | |||||
| |type |string|类型| | |||||
| |events | array|触发事件 | | |||||
| |create_time |string|创建时间| | |||||
| > 返回的JSON示例: | |||||
| ```json | |||||
| { | |||||
| "id": 18, | |||||
| "type": "gitea", | |||||
| "content_type": "json", | |||||
| "url": "http://localhost:10000", | |||||
| "events": [ | |||||
| "push" | |||||
| ], | |||||
| "active": true, | |||||
| "create_time": "2021-07-26 18:53:43" | |||||
| } | |||||
| ``` | |||||
| <aside class="success"> | |||||
| Success Data. | |||||
| </aside> | |||||
| ## 更新仓库webhook | |||||
| 更新仓库webhook | |||||
| > 示例: | |||||
| ```shell | |||||
| curl -X PATCH \ | |||||
| http://localhost:3000/api/yystopf/ceshi/webhooks/7.json | |||||
| ``` | |||||
| ```javascript | |||||
| await octokit.request('PATCH /api/yystopf/ceshi/webhooks/7.json') | |||||
| ``` | |||||
| ### HTTP 请求 | |||||
| `PATCH /api/:owner/:repo/webhooks/:id.json` | |||||
| ### 请求参数: | |||||
| 参数 | 必选 | 默认 | 类型 | 字段说明 | |||||
| --------- | ------- | ------- | -------- | ---------- | |||||
| |owner |是| | string |用户登录名 | | |||||
| |repo |是| | string |项目标识identifier | | |||||
| |id |是| | string |webhook id | | |||||
| |webhook.url |是| | string |目标url | | |||||
| |webhook.type |否| | string |类型| | |||||
| |webhook.http_method |是| | string | http方法, POST和GET | | |||||
| |webhook.content_type |是| | string | POST Content Type | | |||||
| |webhook.secret |否| | string |密钥文本| | |||||
| |webhook.active |是| | bool | 是否激活| | |||||
| |webhook.branch_filter|否| |string|分支过滤| | |||||
| |webhook.events |否| |array|触发事件| | |||||
| 触发事件字段说明 | |||||
| 参数| 含义| | |||||
| --------- | ------- | ------- | | |||||
| |create|创建分支或标签| | |||||
| |delete|分支或标签删除| | |||||
| |fork|仓库被fork| | |||||
| |push|git仓库推送| | |||||
| |issue|易修已打开、已关闭、已重新打开或编辑| | |||||
| |issue_assign|易修被指派| | |||||
| |issue_label|易修标签被更新或删除| | |||||
| |issue_milestone|易修被收入里程碑| | |||||
| |issue_comment|易修评论| | |||||
| |pull_request|合并请求| | |||||
| |pull_request_assign|合并请求被指派| | |||||
| |pull_request_label|合并请求被贴上标签| | |||||
| |pull_request_milestone|合并请求被记录于里程碑中| | |||||
| |pull_request_comment|合并请求被评论| | |||||
| |pull_request_review_approved|合并请求被批准| | |||||
| |pull_request_review_rejected|合并请求被拒绝| | |||||
| |pull_request_review_comment|合并请求被提出审查意见| | |||||
| |pull_request_sync|合并请求被同步| | |||||
| |repository|创建或删除仓库| | |||||
| |release|版本发布| | |||||
| > 请求的JSON示例: | |||||
| ```json | |||||
| { | |||||
| "active": true, | |||||
| "content_type": "json", | |||||
| "http_method": "GET", | |||||
| "secret": "123456", | |||||
| "url": "http://localhost:10000", | |||||
| "branch_filter": "*", | |||||
| "events": ["push"] | |||||
| } | |||||
| ``` | |||||
| ### 返回字段说明: | |||||
| > 返回的JSON示例: | |||||
| ```json | |||||
| { | |||||
| "status": 0, | |||||
| "message": "success" | |||||
| } | |||||
| ``` | |||||
| <aside class="success"> | |||||
| Success Data. | |||||
| </aside> | |||||
| ## 删除仓库webhook | |||||
| 删除仓库webhook | |||||
| > 示例: | |||||
| ```shell | |||||
| curl -X DELETE \ | |||||
| http://localhost:3000/api/yystopf/ceshi/webhooks/7.json | |||||
| ``` | |||||
| ```javascript | |||||
| await octokit.request('DELETE /api/yystopf/ceshi/webhooks/7.json') | |||||
| ``` | |||||
| ### HTTP 请求 | |||||
| `DELETE /api/:owner/:repo/webhooks/:id.json` | |||||
| ### 请求参数: | |||||
| 参数 | 必选 | 默认 | 类型 | 字段说明 | |||||
| --------- | ------- | ------- | -------- | ---------- | |||||
| |owner |是| | string |用户登录名 | | |||||
| |repo |是| | string |项目标识identifier | | |||||
| |id |是| | string |webhook id | | |||||
| ### 返回字段说明: | |||||
| > 返回的JSON示例: | |||||
| ```json | |||||
| { | |||||
| "status": 0, | |||||
| "message": "success" | |||||
| } | |||||
| ``` | |||||
| <aside class="success"> | |||||
| Success Data. | |||||
| </aside> | |||||
| ## 获取仓库webhook的历史推送列表 | |||||
| 获取仓库webhook的历史推送列表 | |||||
| > 示例: | |||||
| ```shell | |||||
| curl -X GET \ | |||||
| http://localhost:3000/api/yystopf/ceshi/webhooks/3/tasks.json | |||||
| ``` | |||||
| ```javascript | |||||
| await octokit.request('GET /api/yystopf/ceshi/webhooks/3/tasks.json') | |||||
| ``` | |||||
| ### HTTP 请求 | |||||
| `GET /api/:owner/:repo/webhooks/:id/tasks.json` | |||||
| ### 请求参数: | |||||
| 参数 | 必选 | 默认 | 类型 | 字段说明 | |||||
| --------- | ------- | ------- | -------- | ---------- | |||||
| |owner |是| |string |用户登录名 | | |||||
| |repo |是| |string |项目标识identifier | | |||||
| |id |是| |integer |webhook ID| | |||||
| ### 返回字段说明: | |||||
| 参数 | 类型 | 字段说明 | |||||
| --------- | ----------- | ----------- | |||||
| |id |int |id | | |||||
| |uuid |string|推送uuid| | |||||
| |type |string|类型| | |||||
| |is_succeed |bool|是否推送成功| | |||||
| |is_delivered |bool|是否完成推送| | |||||
| |payload_content |json|请求主体内容| | |||||
| |request_content |json|请求内容,头部等等| | |||||
| |reponse_content |json|响应内容,状态,头部,主体等等| | |||||
| |delivered_time |string|推送时间| | |||||
| > 返回的JSON示例: | |||||
| ```json | |||||
| { | |||||
| "total_count": 6, | |||||
| "tasks": [ | |||||
| { | |||||
| "id": 20, | |||||
| "type": "gitea", | |||||
| "uuid": "99aa2c23-6884-4c44-9020-5469320aa408", | |||||
| "is_succeed": true, | |||||
| "is_delivered": true, | |||||
| "payload_content": { | |||||
| "secret": "123456", | |||||
| "ref": "refs/heads/master", | |||||
| "before": "feb48e31362787a7620b53d4df3c4effddbb6f0b", | |||||
| "after": "feb48e31362787a7620b53d4df3c4effddbb6f0b", | |||||
| "compare_url": "", | |||||
| "commits": [ | |||||
| { | |||||
| "id": "feb48e31362787a7620b53d4df3c4effddbb6f0b", | |||||
| "message": "fix\n", | |||||
| "url": "http://localhost:10081/yystopf/ceshi/commit/feb48e31362787a7620b53d4df3c4effddbb6f0b", | |||||
| "author": { | |||||
| "name": "viletyy", | |||||
| "email": "yystopf@163.com", | |||||
| "username": "root" | |||||
| }, | |||||
| "committer": { | |||||
| "name": "viletyy", | |||||
| "email": "yystopf@163.com", | |||||
| "username": "root" | |||||
| }, | |||||
| "verification": { | |||||
| "verified": false, | |||||
| "reason": "gpg.error.not_signed_commit", | |||||
| "signature": "", | |||||
| "signer": null, | |||||
| "payload": "" | |||||
| }, | |||||
| "timestamp": "2021-07-26T13:52:13+08:00", | |||||
| "added": null, | |||||
| "removed": null, | |||||
| "modified": null | |||||
| } | |||||
| ], | |||||
| "head_commit": null, | |||||
| "repository": { | |||||
| "id": 2, | |||||
| "owner": { | |||||
| "id": 3, | |||||
| "login": "yystopf", | |||||
| "full_name": "", | |||||
| "email": "yystopf@forge.com", | |||||
| "avatar_url": "http://localhost:10081/user/avatar/yystopf/-1", | |||||
| "language": "zh-CN", | |||||
| "is_admin": true, | |||||
| "last_login": "2021-07-21T18:38:21+08:00", | |||||
| "created": "2021-06-03T14:50:25+08:00", | |||||
| "username": "yystopf" | |||||
| }, | |||||
| "name": "ceshi", | |||||
| "full_name": "yystopf/ceshi", | |||||
| "description": "", | |||||
| "empty": false, | |||||
| "private": false, | |||||
| "fork": false, | |||||
| "template": false, | |||||
| "parent": null, | |||||
| "mirror": false, | |||||
| "size": 3846, | |||||
| "html_url": "http://localhost:10081/yystopf/ceshi", | |||||
| "ssh_url": "virus@localhost:10081:yystopf/ceshi.git", | |||||
| "clone_url": "http://localhost:10081/yystopf/ceshi.git", | |||||
| "original_url": "", | |||||
| "website": "", | |||||
| "stars_count": 0, | |||||
| "forks_count": 1, | |||||
| "watchers_count": 1, | |||||
| "open_issues_count": 0, | |||||
| "open_pr_counter": 0, | |||||
| "release_counter": 0, | |||||
| "default_branch": "master", | |||||
| "archived": false, | |||||
| "created_at": "2021-06-03T15:15:30+08:00", | |||||
| "updated_at": "2021-07-26T13:52:16+08:00", | |||||
| "permissions": { | |||||
| "admin": false, | |||||
| "push": false, | |||||
| "pull": false | |||||
| }, | |||||
| "has_issues": true, | |||||
| "internal_tracker": { | |||||
| "enable_time_tracker": true, | |||||
| "allow_only_contributors_to_track_time": true, | |||||
| "enable_issue_dependencies": true | |||||
| }, | |||||
| "has_wiki": true, | |||||
| "has_pull_requests": true, | |||||
| "ignore_whitespace_conflicts": false, | |||||
| "allow_merge_commits": true, | |||||
| "allow_rebase": true, | |||||
| "allow_rebase_explicit": true, | |||||
| "allow_squash_merge": true, | |||||
| "avatar_url": "", | |||||
| "internal": false | |||||
| }, | |||||
| "pusher": { | |||||
| "id": 0, | |||||
| "login": "yystopf", | |||||
| "full_name": "", | |||||
| "email": "yystopf@forge.com", | |||||
| "avatar_url": "http://localhost:10081/user/avatar/yystopf/-1", | |||||
| "language": "", | |||||
| "is_admin": false, | |||||
| "last_login": "0001-01-01T00:00:00Z", | |||||
| "created": "2021-06-03T14:50:25+08:00", | |||||
| "username": "yystopf" | |||||
| }, | |||||
| "sender": { | |||||
| "id": 0, | |||||
| "login": "yystopf", | |||||
| "full_name": "", | |||||
| "email": "yystopf@forge.com", | |||||
| "avatar_url": "http://localhost:10081/user/avatar/yystopf/-1", | |||||
| "language": "", | |||||
| "is_admin": false, | |||||
| "last_login": "0001-01-01T00:00:00Z", | |||||
| "created": "2021-06-03T14:50:25+08:00", | |||||
| "username": "yystopf" | |||||
| } | |||||
| }, | |||||
| "request_content": { | |||||
| "headers": { | |||||
| "X-GitHub-Delivery": "99aa2c23-6884-4c44-9020-5469320aa408", | |||||
| "X-GitHub-Event": "push", | |||||
| "X-Gitea-Delivery": "99aa2c23-6884-4c44-9020-5469320aa408", | |||||
| "X-Gitea-Event": "push", | |||||
| "X-Gitea-Signature": "34a01edcd952ff6410ff6ebc946471161bde74aff86171f21621d2c2c4130f66", | |||||
| "X-Gogs-Delivery": "99aa2c23-6884-4c44-9020-5469320aa408", | |||||
| "X-Gogs-Event": "push", | |||||
| "X-Gogs-Signature": "34a01edcd952ff6410ff6ebc946471161bde74aff86171f21621d2c2c4130f66" | |||||
| } | |||||
| }, | |||||
| "response_content": { | |||||
| "status": 200, | |||||
| "headers": { | |||||
| "Cache-Control": "no-store, must-revalidate, private, max-age=0", | |||||
| "Content-Length": "2556", | |||||
| "Content-Type": "text/html; charset=utf-8", | |||||
| "Referrer-Policy": "strict-origin-when-cross-origin", | |||||
| "Set-Cookie": "__profilin=p%3Dt; path=/; HttpOnly", | |||||
| "Vary": "Origin", | |||||
| "X-Content-Type-Options": "nosniff", | |||||
| "X-Download-Options": "noopen", | |||||
| "X-Frame-Options": "SAMEORIGIN", | |||||
| "X-Miniprofiler-Ids": "9ynvpncz5xm0rpgorb5y,hgggd9mv6lr4a9drcrlr,j7zqlx2vy5aji2vtgoba,f1ktsmh3jxvq0z2hf612,mih3dvgvlqhi3zy8lf2x,5k1qbkvbnru8mye9cest,tj6ern8w6awqf2zsimbr,9isaehvubivd52wo5p9v,1rzfhtq1nhuwbgy9p76g,z0xzidzyywna0y7a69m0,hzoklky92ycjqt42gi0s,y0ai7y0t28mcn8x0py2x,322il7nadinp51mw2r5m,m6dukftfsh6tjcxzp1gq,667wlqbytfwbrirnmma1,jcehj3dl8lkw8gk510cr", | |||||
| "X-Miniprofiler-Original-Cache-Control": "max-age=0, private, must-revalidate", | |||||
| "X-Permitted-Cross-Domain-Policies": "none", | |||||
| "X-Request-Id": "08bff080-bbb5-4183-b845-81de3d47120a", | |||||
| "X-Runtime": "0.394766", | |||||
| "X-Xss-Protection": "1; mode=block" | |||||
| }, | |||||
| "body": "<!doctype html><html lang=\"zh-CN\" class=\"notranslate translated-ltr\" translate=\"no\"><head><meta charset=\"utf-8\"><meta name=\"”Keywords”\" content=\"”trustie,trustieforge,forge,确实让创建更美好,协同开发平台″\"><meta name=\"”Keywords”\" content=\"”TrustieOpenSourceProject″\"><meta name=\"”Keywords”\" content=\"”issue,bug,tracker,软件工程,课程实践″\"><meta name=\"”Description”\" content=\"”持续构建协同、共享、可信的软件创建生态开源创作与软件生产相结合,支持大规模群体开展软件协同创新活动”\"><meta name=\"theme-color\" content=\"#000000\"><link rel=\"manifest\" href=\"/react/build//manifest.json\"><link rel=\"stylesheet\" href=\"/react/build/css/iconfont.css\"><link rel=\"stylesheet\" href=\"/react/build/css/edu-purge.css\"><link rel=\"stylesheet\" href=\"/react/build/css/editormd.min.css\"><link rel=\"stylesheet\" href=\"/react/build/css/merge.css\"><link href=\"/react/build/static/css/main.07f7e90c.chunk.css\" rel=\"stylesheet\"></head><body><div id=\"md_div\" style=\"display:none\"></div><div id=\"root\" class=\"page -layout-v -fit widthunit\"></div><div id=\"picture_display\" style=\"display:none\"></div><script src=\"/react/build/js/jquery-1.8.3.min.js\"></script><script src=\"/react/build/js/js_min_all.js\"></script><script src=\"/react/build/js/codemirror/codemirror.js\"></script><script src=\"/react/build/js/editormd/editormd.min.js\"></script><script src=\"/react/build/js/codemirror/merge/merge.js\"></script><script src=\"/react/build/./static/js/runtime~main.3d644966.js\"></script><script src=\"/react/build/./static/js/main.e46872e3.chunk.js\"></script><script async type=\"text/javascript\" id=\"mini-profiler\" src=\"/mini-profiler-resources/includes.js?v=67dd1c2571ced7fc74ae7f1813e47bdf\" data-version=\"67dd1c2571ced7fc74ae7f1813e47bdf\" data-path=\"/mini-profiler-resources/\" data-current-id=\"9ynvpncz5xm0rpgorb5y\" data-ids=\"9ynvpncz5xm0rpgorb5y,hgggd9mv6lr4a9drcrlr,j7zqlx2vy5aji2vtgoba,f1ktsmh3jxvq0z2hf612,mih3dvgvlqhi3zy8lf2x,5k1qbkvbnru8mye9cest,tj6ern8w6awqf2zsimbr,9isaehvubivd52wo5p9v,1rzfhtq1nhuwbgy9p76g,z0xzidzyywna0y7a69m0,hzoklky92ycjqt42gi0s,y0ai7y0t28mcn8x0py2x,322il7nadinp51mw2r5m,m6dukftfsh6tjcxzp1gq,667wlqbytfwbrirnmma1,jcehj3dl8lkw8gk510cr\" data-horizontal-position=\"left\" data-vertical-position=\"top\" data-trivial=\"false\" data-children=\"false\" data-max-traces=\"20\" data-controls=\"false\" data-total-sql-count=\"false\" data-authorized=\"true\" data-toggle-shortcut=\"alt+p\" data-start-hidden=\"false\" data-collapse-results=\"true\" data-html-container=\"body\"></script>\n</body></html>" | |||||
| }, | |||||
| "delivered_time": "2021-07-28 11:47:29" | |||||
| } | |||||
| ] | |||||
| } | |||||
| ``` | |||||
| <aside class="success"> | |||||
| Success Data. | |||||
| </aside> | |||||
| ## 仓库webhook测试推送 | |||||
| 仓库webhook测试推送 | |||||
| > 示例: | |||||
| ```shell | |||||
| curl -X POST \ | |||||
| http://localhost:3000/api/yystopf/ceshi/webhooks/3/test.json | |||||
| ``` | |||||
| ```javascript | |||||
| await octokit.request('POST /api/yystopf/ceshi/webhooks/3/test.json') | |||||
| ``` | |||||
| ### HTTP 请求 | |||||
| `POST /api/:owner/:repo/webhooks/:id/test.json` | |||||
| ### 请求参数: | |||||
| 参数 | 必选 | 默认 | 类型 | 字段说明 | |||||
| --------- | ------- | ------- | -------- | ---------- | |||||
| |owner |是| | string |用户登录名 | | |||||
| |repo |是| | string |项目标识identifier | | |||||
| |id |是| | integer|webhook ID| | |||||
| ### 返回字段说明: | |||||
| > 返回的JSON示例: | |||||
| ```json | |||||
| { | |||||
| "status": 0, | |||||
| "message": "success" | |||||
| } | |||||
| ``` | |||||
| <aside class="success"> | |||||
| Success Data. | |||||
| </aside> | |||||
| @@ -0,0 +1,8 @@ | |||||
| class Projects::Webhooks::CreateForm < BaseForm | |||||
| attr_accessor :type, :url, :http_method, :content_type, :secret, :events, :active, :branch_filter | |||||
| validates :url, format: { with: URI::regexp(%w[http https]), message: "请输入正确的地址" } | |||||
| validates :active, inclusion: {in: [true, false]} | |||||
| validates :http_method, inclusion: { in: %w(POST GET), message: "请输入正确的请求方式"} | |||||
| validates :content_type, inclusion: { in: %w(json form), message: "请输入正确的Content Type"} | |||||
| end | |||||
| @@ -13,12 +13,12 @@ module ProjectsHelper | |||||
| end | end | ||||
| end | end | ||||
| def render_zip_url(project, archive_name) | |||||
| [gitea_domain, project.owner.login, project.identifier, "archive", "#{archive_name}.zip"].join('/') | |||||
| def render_zip_url(owner, repository, archive) | |||||
| [base_url, archive_repositories_path(owner&.login, repository, "#{archive}.zip")].join | |||||
| end | end | ||||
| def render_tar_url(project, archive_name) | |||||
| [gitea_domain, project.owner.login, project.identifier, "archive", "#{archive_name}.tar.gz"].join('/') | |||||
| def render_tar_url(owner, repository, archive) | |||||
| [base_url, archive_repositories_path(owner&.login, repository, "#{archive}.tar.gz")].join | |||||
| end | end | ||||
| def render_http_url(project) | def render_http_url(project) | ||||
| @@ -10,12 +10,12 @@ module RepositoriesHelper | |||||
| end | end | ||||
| def download_type(str) | def download_type(str) | ||||
| default_type = %w(xlsx xls ppt pptx pdf zip 7z rar exe pdb obj idb png jpg gif tif psd svg RData rdata doc docx mpp vsdx dot) | |||||
| default_type = %w(xlsx xls ppt pptx pdf zip 7z rar exe pdb obj idb png jpg gif tif psd svg RData rdata doc docx mpp vsdx dot otf eot ttf woff woff2) | |||||
| default_type.include?(str&.downcase) | default_type.include?(str&.downcase) | ||||
| end | end | ||||
| def image_type?(str) | def image_type?(str) | ||||
| default_type = %w(png jpg gif tif psd svg) | |||||
| default_type = %w(png jpg gif tif psd svg gif bmp webp jpeg) | |||||
| default_type.include?(str&.downcase) | default_type.include?(str&.downcase) | ||||
| end | end | ||||
| @@ -81,9 +81,47 @@ module RepositoriesHelper | |||||
| content = Gitea::Repository::Entries::GetService.call(owner, repo.identifier, entry['path'], ref: ref)['content'] | content = Gitea::Repository::Entries::GetService.call(owner, repo.identifier, entry['path'], ref: ref)['content'] | ||||
| readme_render_decode64_content(content, path) | readme_render_decode64_content(content, path) | ||||
| else | else | ||||
| file_type = entry['name'].to_s.split(".").last | |||||
| return entry['content'] if download_type(file_type) | |||||
| file_type = File.extname(entry['name'].to_s)[1..-1] | |||||
| if download_type(file_type) | |||||
| return entry['content'].nil? ? Gitea::Repository::Entries::GetService.call(owner, repo.identifier, entry['path'], ref: ref)['content'] : entry['content'] | |||||
| end | |||||
| render_decode64_content(entry['content']) | render_decode64_content(entry['content']) | ||||
| end | end | ||||
| end | end | ||||
| def base64_to_image(path, content) | |||||
| # generate to https://git.trusite.net/pawm36ozq/-/raw/branch/master/entrn.png" | |||||
| content = Base64.decode64(content) | |||||
| File.open(path, 'wb') { |f| f.write(content) } | |||||
| end | |||||
| def render_download_image_url(dir_path, file_path, content) | |||||
| full_path = file_path.starts_with?("/") ? [dir_path, file_path].join("") : [dir_path, file_path].join("/") | |||||
| file_name = full_path.split("/")[-1] | |||||
| # 用户名/项目标识/文件路径 | |||||
| dir_path = generate_dir_path(full_path.split("/"+file_name)[0]) | |||||
| file_path = [dir_path, file_name].join('/') | |||||
| puts "##### render_download_image_url file_path: #{file_path}" | |||||
| base64_to_image(file_path, content) | |||||
| file_path = file_path[6..-1] | |||||
| File.join(base_url, file_path) | |||||
| end | |||||
| def generate_dir_path(dir_path) | |||||
| # tmp_dir_path | |||||
| # eg: jasder/forgeplus/raw/branch/ref | |||||
| dir_path = ["public", tmp_dir, dir_path].join('/') | |||||
| puts "#### dir_path: #{dir_path}" | |||||
| unless Dir.exists?(dir_path) | |||||
| FileUtils.mkdir_p(dir_path) ##不成功这里会抛异常 | |||||
| end | |||||
| dir_path | |||||
| end | |||||
| def tmp_dir | |||||
| "repo" | |||||
| end | |||||
| end | end | ||||
| @@ -2,6 +2,7 @@ class ResetUserCacheJob < ApplicationJob | |||||
| queue_as :cache | queue_as :cache | ||||
| def perform(user) | def perform(user) | ||||
| return if user.nil? | |||||
| Cache::UserFollowCountService.new(user).reset | Cache::UserFollowCountService.new(user).reset | ||||
| Cache::UserIssueCountService.new(user).reset | Cache::UserIssueCountService.new(user).reset | ||||
| Cache::UserProjectCountService.new(user).reset | Cache::UserProjectCountService.new(user).reset | ||||
| @@ -1,19 +1,26 @@ | |||||
| # == Schema Information | # == Schema Information | ||||
| # | # | ||||
| # Table name: applied_messages | |||||
| # Table name: forge_applied_messages | |||||
| # | # | ||||
| # id :integer not null, primary key | # id :integer not null, primary key | ||||
| # user_id :integer | # user_id :integer | ||||
| # applied_id :integer | |||||
| # applied_type :string(255) | # applied_type :string(255) | ||||
| # applied_id :integer | |||||
| # viewed :integer default("0") | # viewed :integer default("0") | ||||
| # status :integer default("0") | # status :integer default("0") | ||||
| # created_at :datetime not null | |||||
| # updated_at :datetime not null | |||||
| # name :string(255) | # name :string(255) | ||||
| # applied_user_id :integer | # applied_user_id :integer | ||||
| # role :integer | # role :integer | ||||
| # project_id :integer | # project_id :integer | ||||
| # created_at :datetime not null | |||||
| # updated_at :datetime not null | |||||
| # | |||||
| # Indexes | |||||
| # | |||||
| # index_forge_applied_messages_on_applied_type_and_applied_id (applied_type,applied_id) | |||||
| # index_forge_applied_messages_on_applied_user_id (applied_user_id) | |||||
| # index_forge_applied_messages_on_project_id (project_id) | |||||
| # index_forge_applied_messages_on_user_id (user_id) | |||||
| # | # | ||||
| class AppliedMessage < ApplicationRecord | class AppliedMessage < ApplicationRecord | ||||
| @@ -1,14 +1,19 @@ | |||||
| # == Schema Information | # == Schema Information | ||||
| # | # | ||||
| # Table name: applied_projects | |||||
| # Table name: forge_applied_projects | |||||
| # | # | ||||
| # id :integer not null, primary key | # id :integer not null, primary key | ||||
| # project_id :integer not null | |||||
| # user_id :integer not null | |||||
| # project_id :integer | |||||
| # user_id :integer | |||||
| # role :integer default("0") | # role :integer default("0") | ||||
| # status :integer default("0") | # status :integer default("0") | ||||
| # created_at :datetime | |||||
| # updated_at :datetime | |||||
| # created_at :datetime not null | |||||
| # updated_at :datetime not null | |||||
| # | |||||
| # Indexes | |||||
| # | |||||
| # index_forge_applied_projects_on_project_id (project_id) | |||||
| # index_forge_applied_projects_on_user_id (user_id) | |||||
| # | # | ||||
| class AppliedProject < ApplicationRecord | class AppliedProject < ApplicationRecord | ||||
| @@ -1,41 +1,42 @@ | |||||
| # == Schema Information | |||||
| # | |||||
| # Table name: attachments | |||||
| # | |||||
| # id :integer not null, primary key | |||||
| # container_id :integer | |||||
| # container_type :string(30) | |||||
| # filename :string(255) default(""), not null | |||||
| # disk_filename :string(255) default(""), not null | |||||
| # filesize :integer default("0"), not null | |||||
| # content_type :string(255) default("") | |||||
| # digest :string(60) default(""), not null | |||||
| # downloads :integer default("0"), not null | |||||
| # author_id :integer default("0"), not null | |||||
| # created_on :datetime | |||||
| # description :text(65535) | |||||
| # disk_directory :string(255) | |||||
| # attachtype :integer default("1") | |||||
| # is_public :integer default("1") | |||||
| # copy_from :integer | |||||
| # quotes :integer default("0") | |||||
| # is_publish :integer default("1") | |||||
| # publish_time :datetime | |||||
| # resource_bank_id :integer | |||||
| # unified_setting :boolean default("1") | |||||
| # cloud_url :string(255) default("") | |||||
| # course_second_category_id :integer default("0") | |||||
| # delay_publish :boolean default("0") | |||||
| # | |||||
| # Indexes | |||||
| # | |||||
| # index_attachments_on_author_id (author_id) | |||||
| # index_attachments_on_container_id_and_container_type (container_id,container_type) | |||||
| # index_attachments_on_course_second_category_id (course_second_category_id) | |||||
| # index_attachments_on_created_on (created_on) | |||||
| # index_attachments_on_is_public (is_public) | |||||
| # index_attachments_on_quotes (quotes) | |||||
| # | |||||
| # == Schema Information | |||||
| # | |||||
| # Table name: attachments | |||||
| # | |||||
| # id :integer not null, primary key | |||||
| # container_id :integer | |||||
| # container_type :string(30) | |||||
| # filename :string(255) default(""), not null | |||||
| # disk_filename :string(255) default(""), not null | |||||
| # filesize :integer default("0"), not null | |||||
| # content_type :string(255) default("") | |||||
| # digest :string(60) default(""), not null | |||||
| # downloads :integer default("0"), not null | |||||
| # author_id :integer default("0"), not null | |||||
| # created_on :datetime | |||||
| # description :text(65535) | |||||
| # disk_directory :string(255) | |||||
| # attachtype :integer default("1") | |||||
| # is_public :integer default("1") | |||||
| # copy_from :string(255) | |||||
| # quotes :integer default("0") | |||||
| # is_publish :integer default("1") | |||||
| # publish_time :datetime | |||||
| # resource_bank_id :integer | |||||
| # unified_setting :boolean default("1") | |||||
| # cloud_url :string(255) default("") | |||||
| # course_second_category_id :integer default("0") | |||||
| # delay_publish :boolean default("0") | |||||
| # link :string(255) | |||||
| # clone_id :integer | |||||
| # | |||||
| # Indexes | |||||
| # | |||||
| # index_attachments_on_author_id (author_id) | |||||
| # index_attachments_on_clone_id (clone_id) | |||||
| # index_attachments_on_container_id_and_container_type (container_id,container_type) | |||||
| # index_attachments_on_created_on (created_on) | |||||
| # | |||||
| class Attachment < ApplicationRecord | class Attachment < ApplicationRecord | ||||
| @@ -39,17 +39,15 @@ | |||||
| # business :boolean default("0") | # business :boolean default("0") | ||||
| # profile_completed :boolean default("0") | # profile_completed :boolean default("0") | ||||
| # laboratory_id :integer | # laboratory_id :integer | ||||
| # platform :string(255) default("0") | |||||
| # gitea_token :string(255) | |||||
| # gitea_uid :integer | |||||
| # is_shixun_marker :boolean default("0") | # is_shixun_marker :boolean default("0") | ||||
| # admin_visitable :boolean default("0") | |||||
| # collaborator :boolean default("0") | |||||
| # gitea_uid :integer | |||||
| # is_sync_pwd :boolean default("1") | # is_sync_pwd :boolean default("1") | ||||
| # watchers_count :integer default("0") | # watchers_count :integer default("0") | ||||
| # devops_step :integer default("0") | # devops_step :integer default("0") | ||||
| # sponsor_certification :integer default("0") | |||||
| # sponsor_num :integer default("0") | |||||
| # sponsored_num :integer default("0") | |||||
| # award_time :datetime | |||||
| # gitea_token :string(255) | |||||
| # platform :string(255) | |||||
| # | # | ||||
| # Indexes | # Indexes | ||||
| # | # | ||||
| @@ -57,8 +55,9 @@ | |||||
| # index_users_on_homepage_engineer (homepage_engineer) | # index_users_on_homepage_engineer (homepage_engineer) | ||||
| # index_users_on_homepage_teacher (homepage_teacher) | # index_users_on_homepage_teacher (homepage_teacher) | ||||
| # index_users_on_laboratory_id (laboratory_id) | # index_users_on_laboratory_id (laboratory_id) | ||||
| # index_users_on_login (login) | |||||
| # index_users_on_mail (mail) | |||||
| # index_users_on_login (login) UNIQUE | |||||
| # index_users_on_mail (mail) UNIQUE | |||||
| # index_users_on_phone (phone) UNIQUE | |||||
| # index_users_on_type (type) | # index_users_on_type (type) | ||||
| # | # | ||||
| @@ -65,7 +65,7 @@ module ProjectOperable | |||||
| if owner.is_a?(User) | if owner.is_a?(User) | ||||
| managers.exists?(user_id: user.id) | managers.exists?(user_id: user.id) | ||||
| elsif owner.is_a?(Organization) | elsif owner.is_a?(Organization) | ||||
| managers.exists?(user_id: user.id) || owner.is_only_admin?(user.id) | |||||
| managers.exists?(user_id: user.id) || owner.is_owner?(user.id) || owner.is_only_admin?(user.id) | |||||
| else | else | ||||
| false | false | ||||
| end | end | ||||
| @@ -94,7 +94,7 @@ module ProjectOperable | |||||
| end | end | ||||
| def operator?(user) | def operator?(user) | ||||
| user.admin? || !reporter?(user) | |||||
| user.admin? || (member?(user.id) && !reporter?(user)) | |||||
| end | end | ||||
| def set_developer_role(member, role_name) | def set_developer_role(member, role_name) | ||||
| @@ -1,4 +1,6 @@ | |||||
| class Gitea::Base < Gitea::Database | |||||
| self.abstract_class = true | |||||
| class Gitea::Base < ApplicationRecord | |||||
| db_config = Rails.configuration.database_configuration[Rails.env]["gitea_server"] | |||||
| raise 'gitea database config missing' if db_config.blank? | |||||
| establish_connection db_config | |||||
| end | end | ||||
| @@ -0,0 +1,9 @@ | |||||
| class Gitea::PublicKey < Gitea::Base | |||||
| self.inheritance_column = nil # FIX The single-table inheritance mechanism failed | |||||
| # establish_connection :gitea_db | |||||
| self.table_name = "public_key" | |||||
| belongs_to :user, class_name: '::User', primary_key: :gitea_uid, foreign_key: :owner_id, optional: true | |||||
| end | |||||
| @@ -0,0 +1,44 @@ | |||||
| # == Schema Information | |||||
| # | |||||
| # Table name: pull_request | |||||
| # | |||||
| # id :integer not null, primary key | |||||
| # type :integer | |||||
| # status :integer | |||||
| # conflicted_files :text(65535) | |||||
| # commits_ahead :integer | |||||
| # commits_behind :integer | |||||
| # changed_protected_files :text(65535) | |||||
| # issue_id :integer | |||||
| # index :integer | |||||
| # head_repo_id :integer | |||||
| # base_repo_id :integer | |||||
| # head_branch :string(255) | |||||
| # base_branch :string(255) | |||||
| # merge_base :string(40) | |||||
| # has_merged :boolean | |||||
| # merged_commit_id :string(40) | |||||
| # merger_id :integer | |||||
| # merged_unix :integer | |||||
| # | |||||
| # Indexes | |||||
| # | |||||
| # IDX_pull_request_base_repo_id (base_repo_id) | |||||
| # IDX_pull_request_has_merged (has_merged) | |||||
| # IDX_pull_request_head_repo_id (head_repo_id) | |||||
| # IDX_pull_request_issue_id (issue_id) | |||||
| # IDX_pull_request_merged_unix (merged_unix) | |||||
| # IDX_pull_request_merger_id (merger_id) | |||||
| # | |||||
| class Gitea::Pull < Gitea::Base | |||||
| self.inheritance_column = nil # FIX The single-table inheritance mechanism failed | |||||
| # establish_connection :gitea_db | |||||
| self.table_name = "pull_request" | |||||
| serialize :conflicted_files, Array | |||||
| belongs_to :pull_request, class_name: '::PullRequest', foreign_key: :id, primary_key: :gitea_id, optional: true | |||||
| end | |||||
| @@ -0,0 +1,13 @@ | |||||
| class Gitea::Webhook < Gitea::Base | |||||
| serialize :events, JSON | |||||
| self.inheritance_column = nil | |||||
| self.table_name = 'webhook' | |||||
| has_many :tasks, class_name: "Gitea::WebhookTask", foreign_key: :hook_id | |||||
| belongs_to :project, class_name: "::Project", primary_key: :gpid, foreign_key: :repo_id, optional: true | |||||
| enum hook_task_type: {gogs: 1, slack: 2, gitea: 3, discord: 4, dingtalk: 5, telegram: 6, msteams: 7, feishu: 8, matrix: 9} | |||||
| enum last_status: {waiting: 0, succeed: 1, fail: 2} | |||||
| enum content_type: {json: 1, form: 2} | |||||
| end | |||||
| @@ -0,0 +1,13 @@ | |||||
| class Gitea::WebhookTask < Gitea::Base | |||||
| serialize :payload_content, JSON | |||||
| serialize :request_content, JSON | |||||
| serialize :response_content, JSON | |||||
| self.inheritance_column = nil | |||||
| self.table_name = 'hook_task' | |||||
| belongs_to :webhook, class_name: "Gitea::Webhook", foreign_key: :hook_id | |||||
| enum type: {gogs: 1, slack: 2, gitea: 3, discord: 4, dingtalk: 5, telegram: 6, msteams: 7, feishu: 8, matrix: 9} | |||||
| end | |||||
| @@ -10,6 +10,7 @@ | |||||
| # sync_course :boolean default("0") | # sync_course :boolean default("0") | ||||
| # sync_subject :boolean default("0") | # sync_subject :boolean default("0") | ||||
| # sync_shixun :boolean default("0") | # sync_shixun :boolean default("0") | ||||
| # is_local :boolean default("0") | |||||
| # | # | ||||
| # Indexes | # Indexes | ||||
| # | # | ||||
| @@ -7,7 +7,6 @@ | |||||
| # content :text(65535) | # content :text(65535) | ||||
| # created_at :datetime not null | # created_at :datetime not null | ||||
| # updated_at :datetime not null | # updated_at :datetime not null | ||||
| # is_secret :boolean default("0") | |||||
| # | # | ||||
| class License < ApplicationRecord | class License < ApplicationRecord | ||||
| @@ -11,7 +11,6 @@ | |||||
| # course_group_id :integer default("0") | # course_group_id :integer default("0") | ||||
| # is_collect :integer default("1") | # is_collect :integer default("1") | ||||
| # graduation_group_id :integer default("0") | # graduation_group_id :integer default("0") | ||||
| # is_apply_signature :boolean default("0") | |||||
| # | # | ||||
| # Indexes | # Indexes | ||||
| # | # | ||||
| @@ -39,17 +39,15 @@ | |||||
| # business :boolean default("0") | # business :boolean default("0") | ||||
| # profile_completed :boolean default("0") | # profile_completed :boolean default("0") | ||||
| # laboratory_id :integer | # laboratory_id :integer | ||||
| # platform :string(255) default("0") | |||||
| # gitea_token :string(255) | |||||
| # gitea_uid :integer | |||||
| # is_shixun_marker :boolean default("0") | # is_shixun_marker :boolean default("0") | ||||
| # admin_visitable :boolean default("0") | |||||
| # collaborator :boolean default("0") | |||||
| # gitea_uid :integer | |||||
| # is_sync_pwd :boolean default("1") | # is_sync_pwd :boolean default("1") | ||||
| # watchers_count :integer default("0") | # watchers_count :integer default("0") | ||||
| # devops_step :integer default("0") | # devops_step :integer default("0") | ||||
| # sponsor_certification :integer default("0") | |||||
| # sponsor_num :integer default("0") | |||||
| # sponsored_num :integer default("0") | |||||
| # award_time :datetime | |||||
| # gitea_token :string(255) | |||||
| # platform :string(255) | |||||
| # | # | ||||
| # Indexes | # Indexes | ||||
| # | # | ||||
| @@ -57,8 +55,9 @@ | |||||
| # index_users_on_homepage_engineer (homepage_engineer) | # index_users_on_homepage_engineer (homepage_engineer) | ||||
| # index_users_on_homepage_teacher (homepage_teacher) | # index_users_on_homepage_teacher (homepage_teacher) | ||||
| # index_users_on_laboratory_id (laboratory_id) | # index_users_on_laboratory_id (laboratory_id) | ||||
| # index_users_on_login (login) | |||||
| # index_users_on_mail (mail) | |||||
| # index_users_on_login (login) UNIQUE | |||||
| # index_users_on_mail (mail) UNIQUE | |||||
| # index_users_on_phone (phone) UNIQUE | |||||
| # index_users_on_type (type) | # index_users_on_type (type) | ||||
| # | # | ||||
| @@ -1,79 +1,79 @@ | |||||
| # == Schema Information | |||||
| # | |||||
| # Table name: projects | |||||
| # | |||||
| # id :integer not null, primary key | |||||
| # name :string(255) default(""), not null | |||||
| # description :text(4294967295) | |||||
| # homepage :string(255) default("") | |||||
| # is_public :boolean default("1"), not null | |||||
| # parent_id :integer | |||||
| # created_on :datetime | |||||
| # updated_on :datetime | |||||
| # identifier :string(255) | |||||
| # status :integer default("1"), not null | |||||
| # lft :integer | |||||
| # rgt :integer | |||||
| # inherit_members :boolean default("0"), not null | |||||
| # project_type :integer default("0") | |||||
| # hidden_repo :boolean default("0"), not null | |||||
| # attachmenttype :integer default("1") | |||||
| # user_id :integer | |||||
| # dts_test :integer default("0") | |||||
| # enterprise_name :string(255) | |||||
| # organization_id :integer | |||||
| # project_new_type :integer | |||||
| # gpid :integer | |||||
| # forked_from_project_id :integer | |||||
| # forked_count :integer default("0") | |||||
| # publish_resource :integer default("0") | |||||
| # visits :integer default("0") | |||||
| # hot :integer default("0") | |||||
| # invite_code :string(255) | |||||
| # qrcode :string(255) | |||||
| # qrcode_expiretime :integer default("0") | |||||
| # script :text(65535) | |||||
| # training_status :integer default("0") | |||||
| # rep_identifier :string(255) | |||||
| # project_category_id :integer | |||||
| # project_language_id :integer | |||||
| # license_id :integer | |||||
| # ignore_id :integer | |||||
| # praises_count :integer default("0") | |||||
| # watchers_count :integer default("0") | |||||
| # issues_count :integer default("0") | |||||
| # pull_requests_count :integer default("0") | |||||
| # language :string(255) | |||||
| # versions_count :integer default("0") | |||||
| # issue_tags_count :integer default("0") | |||||
| # closed_issues_count :integer default("0") | |||||
| # open_devops :boolean default("0") | |||||
| # gitea_webhook_id :integer | |||||
| # open_devops_count :integer default("0") | |||||
| # recommend :boolean default("0") | |||||
| # platform :integer default("0") | |||||
| # default_branch :string(255) default("master") | |||||
| # website :string(255) | |||||
| # order_index :integer default("0") | |||||
| # lesson_url :string(255) | |||||
| # | |||||
| # Indexes | |||||
| # | |||||
| # index_projects_on_forked_from_project_id (forked_from_project_id) | |||||
| # index_projects_on_identifier (identifier) | |||||
| # index_projects_on_invite_code (invite_code) | |||||
| # index_projects_on_is_public (is_public) | |||||
| # index_projects_on_lft (lft) | |||||
| # index_projects_on_name (name) | |||||
| # index_projects_on_platform (platform) | |||||
| # index_projects_on_project_type (project_type) | |||||
| # index_projects_on_recommend (recommend) | |||||
| # index_projects_on_rgt (rgt) | |||||
| # index_projects_on_status (status) | |||||
| # index_projects_on_updated_on (updated_on) | |||||
| # | |||||
| # == Schema Information | |||||
| # | |||||
| # Table name: projects | |||||
| # | |||||
| # id :integer not null, primary key | |||||
| # name :string(255) default(""), not null | |||||
| # description :text(4294967295) | |||||
| # homepage :string(255) default("") | |||||
| # is_public :boolean default("1"), not null | |||||
| # parent_id :integer | |||||
| # created_on :datetime | |||||
| # updated_on :datetime | |||||
| # identifier :string(255) | |||||
| # status :integer default("1"), not null | |||||
| # lft :integer | |||||
| # rgt :integer | |||||
| # inherit_members :boolean default("0"), not null | |||||
| # project_type :integer default("0") | |||||
| # hidden_repo :boolean default("0"), not null | |||||
| # attachmenttype :integer default("1") | |||||
| # user_id :integer | |||||
| # dts_test :integer default("0") | |||||
| # enterprise_name :string(255) | |||||
| # organization_id :integer | |||||
| # project_new_type :integer | |||||
| # gpid :integer | |||||
| # forked_from_project_id :integer | |||||
| # forked_count :integer default("0") | |||||
| # publish_resource :integer default("0") | |||||
| # visits :integer default("0") | |||||
| # hot :integer default("0") | |||||
| # invite_code :string(255) | |||||
| # qrcode :string(255) | |||||
| # qrcode_expiretime :integer default("0") | |||||
| # script :text(65535) | |||||
| # training_status :integer default("0") | |||||
| # rep_identifier :string(255) | |||||
| # project_category_id :integer | |||||
| # project_language_id :integer | |||||
| # praises_count :integer default("0") | |||||
| # watchers_count :integer default("0") | |||||
| # issues_count :integer default("0") | |||||
| # pull_requests_count :integer default("0") | |||||
| # language :string(255) | |||||
| # versions_count :integer default("0") | |||||
| # issue_tags_count :integer default("0") | |||||
| # closed_issues_count :integer default("0") | |||||
| # open_devops :boolean default("0") | |||||
| # gitea_webhook_id :integer | |||||
| # open_devops_count :integer default("0") | |||||
| # recommend :boolean default("0") | |||||
| # platform :integer default("0") | |||||
| # license_id :integer | |||||
| # ignore_id :integer | |||||
| # default_branch :string(255) default("master") | |||||
| # website :string(255) | |||||
| # lesson_url :string(255) | |||||
| # | |||||
| # Indexes | |||||
| # | |||||
| # index_projects_on_forked_from_project_id (forked_from_project_id) | |||||
| # index_projects_on_identifier (identifier) | |||||
| # index_projects_on_invite_code (invite_code) | |||||
| # index_projects_on_is_public (is_public) | |||||
| # index_projects_on_lft (lft) | |||||
| # index_projects_on_license_id (license_id) | |||||
| # index_projects_on_name (name) | |||||
| # index_projects_on_platform (platform) | |||||
| # index_projects_on_project_category_id (project_category_id) | |||||
| # index_projects_on_project_language_id (project_language_id) | |||||
| # index_projects_on_project_type (project_type) | |||||
| # index_projects_on_recommend (recommend) | |||||
| # index_projects_on_rgt (rgt) | |||||
| # index_projects_on_status (status) | |||||
| # index_projects_on_updated_on (updated_on) | |||||
| # | |||||
| class Project < ApplicationRecord | class Project < ApplicationRecord | ||||
| @@ -98,10 +98,12 @@ class Project < ApplicationRecord | |||||
| belongs_to :organization_extension, foreign_key: :user_id, primary_key: :organization_id, optional: true, counter_cache: :num_projects | belongs_to :organization_extension, foreign_key: :user_id, primary_key: :organization_id, optional: true, counter_cache: :num_projects | ||||
| belongs_to :project_category, optional: true , :counter_cache => true | belongs_to :project_category, optional: true , :counter_cache => true | ||||
| belongs_to :project_language, optional: true , :counter_cache => true | belongs_to :project_language, optional: true , :counter_cache => true | ||||
| belongs_to :forked_from_project, class_name: 'Project', optional: true, foreign_key: :forked_from_project_id | |||||
| has_many :project_trends, dependent: :destroy | has_many :project_trends, dependent: :destroy | ||||
| has_many :watchers, as: :watchable, dependent: :destroy | has_many :watchers, as: :watchable, dependent: :destroy | ||||
| has_many :fork_users, dependent: :destroy | has_many :fork_users, dependent: :destroy | ||||
| has_many :forked_users, class_name: 'ForkUser', foreign_key: :fork_project_id, dependent: :destroy | has_many :forked_users, class_name: 'ForkUser', foreign_key: :fork_project_id, dependent: :destroy | ||||
| has_many :forked_projects, class_name: 'Project', foreign_key: :forked_from_project_id | |||||
| has_one :project_educoder, dependent: :destroy | has_one :project_educoder, dependent: :destroy | ||||
| has_one :project_score, dependent: :destroy | has_one :project_score, dependent: :destroy | ||||
| @@ -120,6 +122,7 @@ class Project < ApplicationRecord | |||||
| has_one :applied_transfer_project,-> { order created_at: :desc }, dependent: :destroy | has_one :applied_transfer_project,-> { order created_at: :desc }, dependent: :destroy | ||||
| has_many :pinned_projects, dependent: :destroy | has_many :pinned_projects, dependent: :destroy | ||||
| has_many :has_pinned_users, through: :pinned_projects, source: :user | has_many :has_pinned_users, through: :pinned_projects, source: :user | ||||
| has_many :webhooks, class_name: "Gitea::Webhook", primary_key: :gpid, foreign_key: :repo_id | |||||
| after_save :check_project_members, :reset_cache_data | after_save :check_project_members, :reset_cache_data | ||||
| before_save :set_invite_code | before_save :set_invite_code | ||||
| @@ -8,11 +8,6 @@ | |||||
| # projects_count :integer default("0") | # projects_count :integer default("0") | ||||
| # created_at :datetime not null | # created_at :datetime not null | ||||
| # updated_at :datetime not null | # updated_at :datetime not null | ||||
| # ancestry :string(255) | |||||
| # | |||||
| # Indexes | |||||
| # | |||||
| # index_project_categories_on_ancestry (ancestry) | |||||
| # | # | ||||
| class ProjectCategory < ApplicationRecord | class ProjectCategory < ApplicationRecord | ||||
| @@ -37,6 +37,7 @@ class PullRequest < ApplicationRecord | |||||
| has_many :pull_request_tags, foreign_key: :pull_request_id | has_many :pull_request_tags, foreign_key: :pull_request_id | ||||
| has_many :project_trends, as: :trend, dependent: :destroy | has_many :project_trends, as: :trend, dependent: :destroy | ||||
| has_many :attachments, as: :container, dependent: :destroy | has_many :attachments, as: :container, dependent: :destroy | ||||
| has_one :gitea_pull, foreign_key: :id, primary_key: :gitea_id, class_name: 'Gitea::Pull' | |||||
| scope :merged_and_closed, ->{where.not(status: 0)} | scope :merged_and_closed, ->{where.not(status: 0)} | ||||
| scope :opening, -> {where(status: 0)} | scope :opening, -> {where(status: 0)} | ||||
| @@ -53,8 +54,10 @@ class PullRequest < ApplicationRecord | |||||
| Project.find_by(id: self.fork_project_id) | Project.find_by(id: self.fork_project_id) | ||||
| end | end | ||||
| def bind_gitea_pull_request!(gitea_pull_number) | |||||
| update_column(:gpid, gitea_pull_number) | |||||
| def bind_gitea_pull_request!(gitea_pull_number, gitea_pull_id) | |||||
| update_columns( | |||||
| gitea_number: gitea_pull_number, | |||||
| gitea_id: gitea_pull_id) | |||||
| end | end | ||||
| def merge! | def merge! | ||||
| @@ -67,19 +70,26 @@ class PullRequest < ApplicationRecord | |||||
| # TODO: sync educoder platform repo's for update some statistics count | # TODO: sync educoder platform repo's for update some statistics count | ||||
| def self.update_some_count | def self.update_some_count | ||||
| PullRequest.includes(:user, :project).select(:id, :user_id, :gpid, :project_id, :fork_project_id).each do |pr| | |||||
| PullRequest.includes(:user, :project).select(:id, :user_id, :gitea_number, :project_id, :fork_project_id).each do |pr| | |||||
| puts pr.id | puts pr.id | ||||
| next if pr.gpid.blank? | |||||
| next if pr.gitea_number.blank? | |||||
| project = pr.project | project = pr.project | ||||
| next if project.blank? | next if project.blank? | ||||
| user = project.owner | user = project.owner | ||||
| next if pr.gpid === 6 || pr.gpid === 7 | |||||
| files_result = Gitea::PullRequest::FilesService.call(user.login, project.identifier, pr.gpid) | |||||
| next if pr.gitea_number === 6 || pr.gitea_number === 7 | |||||
| files_result = Gitea::PullRequest::FilesService.call(user.login, project.identifier, pr.gitea_number) | |||||
| pr.update_column(:files_count, files_result['NumFiles']) unless files_result.blank? | pr.update_column(:files_count, files_result['NumFiles']) unless files_result.blank? | ||||
| commits_result = Gitea::PullRequest::CommitsService.call(user.login, project.identifier, pr.gpid) | |||||
| commits_result = Gitea::PullRequest::CommitsService.call(user.login, project.identifier, pr.gitea_number) | |||||
| pr.update_column(:commits_count, commits_result.size) unless commits_result.blank? | pr.update_column(:commits_count, commits_result.size) unless commits_result.blank? | ||||
| end | end | ||||
| end | end | ||||
| def conflict_files | |||||
| file_names = self&.gitea_pull&.conflicted_files | |||||
| return [] if file_names.blank? | |||||
| JSON.parse file_names | |||||
| end | |||||
| end | end | ||||
| @@ -27,7 +27,6 @@ | |||||
| # | # | ||||
| # Indexes | # Indexes | ||||
| # | # | ||||
| # index_repositories_on_identifier (identifier) | |||||
| # index_repositories_on_project_id (project_id) | # index_repositories_on_project_id (project_id) | ||||
| # index_repositories_on_user_id (user_id) | # index_repositories_on_user_id (user_id) | ||||
| # | # | ||||
| @@ -39,17 +39,15 @@ | |||||
| # business :boolean default("0") | # business :boolean default("0") | ||||
| # profile_completed :boolean default("0") | # profile_completed :boolean default("0") | ||||
| # laboratory_id :integer | # laboratory_id :integer | ||||
| # platform :string(255) default("0") | |||||
| # gitea_token :string(255) | |||||
| # gitea_uid :integer | |||||
| # is_shixun_marker :boolean default("0") | # is_shixun_marker :boolean default("0") | ||||
| # admin_visitable :boolean default("0") | |||||
| # collaborator :boolean default("0") | |||||
| # gitea_uid :integer | |||||
| # is_sync_pwd :boolean default("1") | # is_sync_pwd :boolean default("1") | ||||
| # watchers_count :integer default("0") | # watchers_count :integer default("0") | ||||
| # devops_step :integer default("0") | # devops_step :integer default("0") | ||||
| # sponsor_certification :integer default("0") | |||||
| # sponsor_num :integer default("0") | |||||
| # sponsored_num :integer default("0") | |||||
| # award_time :datetime | |||||
| # gitea_token :string(255) | |||||
| # platform :string(255) | |||||
| # | # | ||||
| # Indexes | # Indexes | ||||
| # | # | ||||
| @@ -57,8 +55,9 @@ | |||||
| # index_users_on_homepage_engineer (homepage_engineer) | # index_users_on_homepage_engineer (homepage_engineer) | ||||
| # index_users_on_homepage_teacher (homepage_teacher) | # index_users_on_homepage_teacher (homepage_teacher) | ||||
| # index_users_on_laboratory_id (laboratory_id) | # index_users_on_laboratory_id (laboratory_id) | ||||
| # index_users_on_login (login) | |||||
| # index_users_on_mail (mail) | |||||
| # index_users_on_login (login) UNIQUE | |||||
| # index_users_on_mail (mail) UNIQUE | |||||
| # index_users_on_phone (phone) UNIQUE | |||||
| # index_users_on_type (type) | # index_users_on_type (type) | ||||
| # | # | ||||
| @@ -171,6 +170,7 @@ class User < Owner | |||||
| accepts_nested_attributes_for :is_pinned_projects | accepts_nested_attributes_for :is_pinned_projects | ||||
| has_many :issues, dependent: :destroy, foreign_key: :author_id | has_many :issues, dependent: :destroy, foreign_key: :author_id | ||||
| has_many :pull_requests, dependent: :destroy | has_many :pull_requests, dependent: :destroy | ||||
| has_many :public_keys, class_name: "Gitea::PublicKey",primary_key: :gitea_uid, foreign_key: :owner_id, dependent: :destroy | |||||
| # Groups and active users | # Groups and active users | ||||
| scope :active, lambda { where(status: [STATUS_ACTIVE, STATUS_EDIT_INFO]) } | scope :active, lambda { where(status: [STATUS_ACTIVE, STATUS_EDIT_INFO]) } | ||||
| @@ -187,7 +187,7 @@ class User < Owner | |||||
| :show_email, :show_location, :show_department, | :show_email, :show_location, :show_department, | ||||
| :technical_title, :province, :city, :custom_department, to: :user_extension, allow_nil: true | :technical_title, :province, :city, :custom_department, to: :user_extension, allow_nil: true | ||||
| before_save :update_hashed_password | |||||
| before_save :update_hashed_password, :set_lastname | |||||
| after_create do | after_create do | ||||
| SyncTrustieJob.perform_later("user", 1) if allow_sync_to_trustie? | SyncTrustieJob.perform_later("user", 1) if allow_sync_to_trustie? | ||||
| end | end | ||||
| @@ -792,6 +792,10 @@ class User < Owner | |||||
| self.laboratory = Laboratory.current if laboratory_id.blank? | self.laboratory = Laboratory.current if laboratory_id.blank? | ||||
| end | end | ||||
| def set_lastname | |||||
| self.lastname = self.nickname if changes[:nickname].present? | |||||
| end | |||||
| end | end | ||||
| @@ -12,7 +12,9 @@ | |||||
| # | # | ||||
| # Indexes | # Indexes | ||||
| # | # | ||||
| # index_user_actions_on_ip (ip) | |||||
| # index_user_actions_on_ip (ip) | |||||
| # index_user_actions_on_user_id (user_id) | |||||
| # index_user_actions_on_user_id_and_action_type (user_id,action_type) | |||||
| # | # | ||||
| class UserAction < ApplicationRecord | class UserAction < ApplicationRecord | ||||
| @@ -10,10 +10,13 @@ | |||||
| # updated_at :datetime not null | # updated_at :datetime not null | ||||
| # register_status :integer default("0") | # register_status :integer default("0") | ||||
| # action_status :integer default("0") | # action_status :integer default("0") | ||||
| # is_delete :boolean default("0") | |||||
| # user_id :integer | |||||
| # | # | ||||
| # Indexes | # Indexes | ||||
| # | # | ||||
| # index_user_agents_on_ip (ip) UNIQUE | |||||
| # index_user_agents_on_ip (ip) | |||||
| # index_user_agents_on_user_id (user_id) | |||||
| # | # | ||||
| class UserAgent < ApplicationRecord | class UserAgent < ApplicationRecord | ||||
| @@ -22,6 +22,9 @@ | |||||
| # school_id :integer | # school_id :integer | ||||
| # description :string(255) default("") | # description :string(255) default("") | ||||
| # department_id :integer | # department_id :integer | ||||
| # honor :text(65535) | |||||
| # edu_background :integer | |||||
| # edu_entry_year :integer | |||||
| # province :string(255) | # province :string(255) | ||||
| # city :string(255) | # city :string(255) | ||||
| # custom_department :string(255) | # custom_department :string(255) | ||||
| @@ -46,11 +46,11 @@ class Cache::PlatformProjectLanguagesCountService < ApplicationService | |||||
| def reset_platform_project_language_count_by_key | def reset_platform_project_language_count_by_key | ||||
| return if key.nil? | return if key.nil? | ||||
| $redis_cache.hset(platform_project_language_count_key, key, Project.joins(:project_language).where(project_languages: {name: key}).count) | |||||
| $redis_cache.hset(platform_project_language_count_key, key, ProjectLanguage.where(name: key).projects_count) | |||||
| end | end | ||||
| def reset_platform_project_language_count | def reset_platform_project_language_count | ||||
| Project.joins(:project_language).group("project_languages.name").count.each do |k, v| | |||||
| ProjectLanguage.where.not(projects_count: 0).group("project_languages.name").sum(:projects_count).each do |k, v| | |||||
| $redis_cache.hset(platform_project_language_count_key, k, v) | $redis_cache.hset(platform_project_language_count_key, k, v) | ||||
| end | end | ||||
| end | end | ||||
| @@ -108,6 +108,7 @@ class Gitea::ClientService < ApplicationService | |||||
| def full_url(api_rest, action='post') | def full_url(api_rest, action='post') | ||||
| url = [api_url, api_rest].join('').freeze | url = [api_url, api_rest].join('').freeze | ||||
| url = action === 'get' ? url : URI.escape(url) | url = action === 'get' ? url : URI.escape(url) | ||||
| url = URI.escape(url) unless url.ascii_only? | |||||
| puts "[gitea] request url: #{url}" | puts "[gitea] request url: #{url}" | ||||
| return url | return url | ||||
| end | end | ||||
| @@ -8,7 +8,7 @@ class Gitea::PullRequest::CloseService < Gitea::PullRequest::UpdateService | |||||
| # number: number of pull request | # number: number of pull request | ||||
| # token: token of gitea user | # token: token of gitea user | ||||
| # eq: | # eq: | ||||
| # Gitea::PullRequest::CloseService.call(owner.login, repo.identifier, pull.gpid, pull.base, current_user.gitea_token) | |||||
| # Gitea::PullRequest::CloseService.call(owner.login, repo.identifier, pull.gitea_number, pull.base, current_user.gitea_token) | |||||
| def initialize(owner, repo, number, base,token=nil) | def initialize(owner, repo, number, base,token=nil) | ||||
| colse_pull_params = Hash.new.merge(base: base, state: 'closed').compact | colse_pull_params = Hash.new.merge(base: base, state: 'closed').compact | ||||
| @@ -3,7 +3,7 @@ class Gitea::PullRequest::GetService < Gitea::ClientService | |||||
| attr_reader :owner, :repo, :number, :token | attr_reader :owner, :repo, :number, :token | ||||
| #eq: | #eq: | ||||
| # Gitea::PullRequest::GetService.call(user.login, repository.identifier, pull.gpid, user.gitea_token) | |||||
| # Gitea::PullRequest::GetService.call(user.login, repository.identifier, pull.gitea_number, user.gitea_token) | |||||
| def initialize(owner, repo, number, token=nil) | def initialize(owner, repo, number, token=nil) | ||||
| @owner = owner | @owner = owner | ||||
| @repo = repo | @repo = repo | ||||
| @@ -8,7 +8,7 @@ class Gitea::PullRequest::OpenService < Gitea::PullRequest::UpdateService | |||||
| # number: number of pull request | # number: number of pull request | ||||
| # token: token of gitea user | # token: token of gitea user | ||||
| # eq: | # eq: | ||||
| # Gitea::PullRequest::OpenService.new(owner.login, repo.identifier, pr.gpid, pr.base, current_user.gitea_token) | |||||
| # Gitea::PullRequest::OpenService.new(owner.login, repo.identifier, pr.gitea_number, pr.base, current_user.gitea_token) | |||||
| def initialize(owner, repo, number, base, token=nil) | def initialize(owner, repo, number, base, token=nil) | ||||
| open_pull_params = Hash.new.merge(base: base, state: 'open').compact | open_pull_params = Hash.new.merge(base: base, state: 'open').compact | ||||
| @@ -0,0 +1,40 @@ | |||||
| class Gitea::Repository::ArchiveService < Gitea::ClientService | |||||
| attr_reader :owner, :repo, :archive, :token | |||||
| def initialize(owner, repo, archive, token=nil) | |||||
| @owner = owner | |||||
| @repo = repo | |||||
| @archive = archive | |||||
| @token = token | |||||
| end | |||||
| def call | |||||
| response = get(url, params) | |||||
| response_payload(response) | |||||
| end | |||||
| private | |||||
| def params | |||||
| Hash.new.merge(token: token) | |||||
| end | |||||
| def url | |||||
| "/repos/#{owner}/#{repo}/archive/#{archive}".freeze | |||||
| end | |||||
| def response_payload(response) | |||||
| status = response.status | |||||
| body = response&.body | |||||
| log_error(status, body) | |||||
| status_payload(status, body) | |||||
| end | |||||
| def status_payload(status, body) | |||||
| case status | |||||
| when 200 then success | |||||
| when 404 then error("你操作的链接不存在!") | |||||
| else error("系统错误!") | |||||
| end | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,23 @@ | |||||
| class Gitea::Repository::Webhooks::CreateService < Gitea::ClientService | |||||
| attr_reader :token, :owner, :repo, :params | |||||
| def initialize(token, owner, repo, params) | |||||
| @token = token | |||||
| @owner = owner | |||||
| @repo = repo | |||||
| @params = params | |||||
| end | |||||
| def call | |||||
| response = post(url, request_params) | |||||
| render_response(response) | |||||
| end | |||||
| private | |||||
| def request_params | |||||
| Hash.new.merge({token: token, data: params}) | |||||
| end | |||||
| def url | |||||
| "/repos/#{owner}/#{repo}/hooks".freeze | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,24 @@ | |||||
| class Gitea::Repository::Webhooks::DeleteService < Gitea::ClientService | |||||
| attr_reader :token, :owner, :repo, :id | |||||
| def initialize(token, owner, repo, id) | |||||
| @token = token | |||||
| @owner = owner | |||||
| @repo = repo | |||||
| @id = id | |||||
| end | |||||
| def call | |||||
| response = delete(url, params) | |||||
| render_response(response) | |||||
| end | |||||
| private | |||||
| def params | |||||
| Hash.new.merge(token: token) | |||||
| end | |||||
| def url | |||||
| "/repos/#{owner}/#{repo}/hooks/#{id}".freeze | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,27 @@ | |||||
| class Gitea::Repository::Webhooks::TasksService < Gitea::ClientService | |||||
| attr_reader :token, :owner, :repo, :webhook_id | |||||
| # ref: The name of the commit/branch/tag. Default the repository’s default branch (usually master) | |||||
| # repo_name: the name of repository | |||||
| def initialize(token, owner, repo, webhook_id) | |||||
| @token = token | |||||
| @owner = owner | |||||
| @repo = repo | |||||
| @webhook_id = webhook_id | |||||
| end | |||||
| def call | |||||
| response = get(url, params) | |||||
| render_response(response) | |||||
| end | |||||
| private | |||||
| def params | |||||
| Hash.new.merge(token: user.gitea_token) | |||||
| end | |||||
| def url | |||||
| "/repos/#{owner}/#{repo}/hooks/#{webhook_id}/hook_tasks".freeze | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,24 @@ | |||||
| class Gitea::Repository::Webhooks::TestService < Gitea::ClientService | |||||
| attr_reader :token, :owner, :repo, :webhook_id | |||||
| def initialize(token, owner, repo, webhook_id) | |||||
| @token = token | |||||
| @owner = owner | |||||
| @repo = repo | |||||
| @webhook_id = webhook_id | |||||
| end | |||||
| def call | |||||
| response = post(url, request_params) | |||||
| render_response(response) | |||||
| end | |||||
| private | |||||
| def request_params | |||||
| Hash.new.merge({token: token}) | |||||
| end | |||||
| def url | |||||
| "/repos/#{owner}/#{repo}/hooks/#{webhook_id}/tests".freeze | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,24 @@ | |||||
| class Gitea::Repository::Webhooks::UpdateService < Gitea::ClientService | |||||
| attr_reader :token, :owner, :repo, :id, :params | |||||
| def initialize(token, owner, repo, id, params) | |||||
| @token = token | |||||
| @owner = owner | |||||
| @repo = repo | |||||
| @id = id | |||||
| @params = params | |||||
| end | |||||
| def call | |||||
| response = patch(url, data_params) | |||||
| render_response(response) | |||||
| end | |||||
| private | |||||
| def url | |||||
| "/repos/#{owner}/#{repo}/hooks/#{id}" | |||||
| end | |||||
| def data_params | |||||
| Hash.new.merge(token: token, data: params).compact | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,21 @@ | |||||
| class Gitea::User::Keys::CreateService < Gitea::ClientService | |||||
| attr_reader :token, :params | |||||
| def initialize(token, params) | |||||
| @token = token | |||||
| @params = params | |||||
| end | |||||
| def call | |||||
| response = post(url, request_params) | |||||
| render_response(response) | |||||
| end | |||||
| private | |||||
| def request_params | |||||
| Hash.new.merge({token: token, data: params}) | |||||
| end | |||||
| def url | |||||
| '/user/keys'.freeze | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,23 @@ | |||||
| class Gitea::User::Keys::DeleteService < Gitea::ClientService | |||||
| attr_reader :token, :key_id | |||||
| def initialize(token, key_id) | |||||
| @token = token | |||||
| @key_id = key_id | |||||
| end | |||||
| def call | |||||
| response = delete(url, params) | |||||
| render_response(response) | |||||
| end | |||||
| private | |||||
| def params | |||||
| Hash.new.merge(token: token) | |||||
| end | |||||
| def url | |||||
| "/user/keys/#{key_id}".freeze | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,22 @@ | |||||
| class Gitea::User::Keys::GetService < Gitea::ClientService | |||||
| attr_reader :token, :key_id | |||||
| def initialize(token, key_id) | |||||
| @token = token | |||||
| @key_id = key_id | |||||
| end | |||||
| def call | |||||
| response = get(url, params) | |||||
| render_response(response) | |||||
| end | |||||
| private | |||||
| def params | |||||
| Hash.new.merge({token: token}) | |||||
| end | |||||
| def url | |||||
| "/user/keys/#{key_id}".freeze | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,26 @@ | |||||
| class Gitea::User::Keys::ListService < Gitea::ClientService | |||||
| attr_reader :token, :page, :limit, :fingerprint | |||||
| def initialize(token, page, limit, fingerprint="") | |||||
| @token = token | |||||
| @page = page | |||||
| @limit = limit | |||||
| @fingerprint = fingerprint | |||||
| end | |||||
| def call | |||||
| response = get(url, params) | |||||
| render_response(response) | |||||
| end | |||||
| private | |||||
| def params | |||||
| Hash.new.merge({token: token, fingerprint: fingerprint, page: page, limit: limit}) | |||||
| end | |||||
| def url | |||||
| '/user/keys'.freeze | |||||
| end | |||||
| end | |||||
| @@ -8,6 +8,7 @@ class Projects::CreateService < ApplicationService | |||||
| def call | def call | ||||
| Rails.logger.info("#############__________project_params______###########{project_params}") | Rails.logger.info("#############__________project_params______###########{project_params}") | ||||
| raise Error, "user_id不正确." unless authroize_user_id_success | |||||
| @project = Project.new(project_params) | @project = Project.new(project_params) | ||||
| ActiveRecord::Base.transaction do | ActiveRecord::Base.transaction do | ||||
| @@ -27,6 +28,10 @@ class Projects::CreateService < ApplicationService | |||||
| private | private | ||||
| def authroize_user_id_success | |||||
| (user.id == params[:user_id].to_i) || (user.organizations.find_by_id(params[:user_id]).present?) | |||||
| end | |||||
| def project_params | def project_params | ||||
| { | { | ||||
| name: params[:name], | name: params[:name], | ||||
| @@ -8,6 +8,8 @@ class Projects::MigrateService < ApplicationService | |||||
| end | end | ||||
| def call | def call | ||||
| raise Error, "user_id不正确." unless authroize_user_id_success | |||||
| @project = Project.new(project_params) | @project = Project.new(project_params) | ||||
| if @project.save! | if @project.save! | ||||
| ProjectUnit.init_types(@project.id, project.project_type) | ProjectUnit.init_types(@project.id, project.project_type) | ||||
| @@ -24,6 +26,9 @@ class Projects::MigrateService < ApplicationService | |||||
| end | end | ||||
| private | private | ||||
| def authroize_user_id_success | |||||
| (user.id == params[:user_id].to_i) || (user.organizations.find_by_id(params[:user_id]).present?) | |||||
| end | |||||
| def project_params | def project_params | ||||
| { | { | ||||
| @@ -23,7 +23,7 @@ class PullRequests::CloseService < ApplicationService | |||||
| def close_gitea_pull | def close_gitea_pull | ||||
| Gitea::PullRequest::CloseService.call(@owner.login, @repo.identifier, | Gitea::PullRequest::CloseService.call(@owner.login, @repo.identifier, | ||||
| @pull.gpid, @pull.base, current_user.gitea_token) | |||||
| @pull.gitea_number, @pull.base, current_user.gitea_token) | |||||
| end | end | ||||
| def update_pull_status! | def update_pull_status! | ||||
| @@ -22,7 +22,7 @@ class PullRequests::MergeService < ApplicationService | |||||
| def gitea_pull_merge! | def gitea_pull_merge! | ||||
| result = Gitea::PullRequest::MergeService.call(@current_user.gitea_token, @owner.login, | result = Gitea::PullRequest::MergeService.call(@current_user.gitea_token, @owner.login, | ||||
| @repo.identifier, @pull.gpid, gitea_merge_pull_params) | |||||
| @repo.identifier, @pull.gitea_number, gitea_merge_pull_params) | |||||
| @status, @message = result | @status, @message = result | ||||
| end | end | ||||
| @@ -23,7 +23,7 @@ class PullRequests::OpenService < ApplicationService | |||||
| def open_gitea_pull | def open_gitea_pull | ||||
| Gitea::PullRequest::OpenService.call(@owner.login, @repo.identifier, | Gitea::PullRequest::OpenService.call(@owner.login, @repo.identifier, | ||||
| @pull.gpid, @pull.base, @current_user.gitea_token) | |||||
| @pull.gitea_number, @pull.base, @current_user.gitea_token) | |||||
| end | end | ||||
| def update_pull_status! | def update_pull_status! | ||||
| @@ -83,3 +83,5 @@ json.diff do | |||||
| end | end | ||||
| end | end | ||||
| json.status @merge_status | |||||
| json.message @merge_message | |||||
| @@ -2,6 +2,6 @@ json.total_count @owners.size | |||||
| json.owners @owners.each do |owner| | json.owners @owners.each do |owner| | ||||
| json.id owner.id | json.id owner.id | ||||
| json.type owner.type | json.type owner.type | ||||
| json.name owner.login | |||||
| json.name owner&.show_real_name | |||||
| json.avatar_url url_to_avatar(owner) | json.avatar_url url_to_avatar(owner) | ||||
| end | end | ||||
| @@ -4,8 +4,8 @@ json.array! @branches do |branch| | |||||
| json.user_can_merge branch['user_can_merge'] | json.user_can_merge branch['user_can_merge'] | ||||
| json.protected branch['protected'] | json.protected branch['protected'] | ||||
| json.http_url render_http_url(@project) | json.http_url render_http_url(@project) | ||||
| json.zip_url render_zip_url(@project, branch['name']) | |||||
| json.tar_url render_tar_url(@project, branch['name']) | |||||
| json.zip_url render_zip_url(@owner, @repository, branch['name']) | |||||
| json.tar_url render_tar_url(@owner, @repository, branch['name']) | |||||
| json.last_commit do | json.last_commit do | ||||
| json.sha branch['commit']['id'] | json.sha branch['commit']['id'] | ||||
| json.message branch['commit']['message'] | json.message branch['commit']['message'] | ||||
| @@ -1 +1,2 @@ | |||||
| json.extract! @project, :id, :name,:identifier | json.extract! @project, :id, :name,:identifier | ||||
| json.login @project&.owner.login | |||||
| @@ -0,0 +1,4 @@ | |||||
| json.(webhook, :id, :url, :http_method, :is_active) | |||||
| json.type webhook.hook_task_type | |||||
| json.last_status webhook.last_status | |||||
| json.create_time Time.at(webhook.created_unix).strftime("%Y-%m-%d %H:%M:%S") | |||||
| @@ -0,0 +1,7 @@ | |||||
| json.id @webhook["id"] | |||||
| json.type @webhook["type"] | |||||
| json.content_type @webhook["config"]["content_type"] | |||||
| json.url @webhook["config"]["url"] | |||||
| json.events @webhook["events"] | |||||
| json.active @webhook["active"] | |||||
| json.create_time @webhook["created_at"].to_time.strftime("%Y-%m-%d %H:%M:%S") | |||||
| @@ -0,0 +1,11 @@ | |||||
| json.id @webhook.id | |||||
| json.(@webhook, :id, :http_method, :content_type, :url, :secret, :last_status, :is_active) | |||||
| json.type @webhook.hook_task_type | |||||
| json.create_time Time.at(@webhook.created_unix).strftime("%Y-%m-%d %H:%M:%S") | |||||
| event = @webhook.events | |||||
| json.branch_filter event["branch_filter"] | |||||
| if event["send_everything"] | |||||
| json.events event["events"].keys.collect{|i| i == "pull_request" ? i + "_only" : i} | |||||
| else | |||||
| json.events event["events"].select{|k, v| v}.keys.collect{|i| i == "pull_request" ? i + "_only" : i} | |||||
| end | |||||
| @@ -0,0 +1,4 @@ | |||||
| json.total_count @webhooks.total_count | |||||
| json.webhooks @webhooks.each do |webhook| | |||||
| json.partial! 'detail', webhook: webhook | |||||
| end | |||||
| @@ -0,0 +1,5 @@ | |||||
| json.total_count @tasks.total_count | |||||
| json.tasks @tasks.each do |task| | |||||
| json.(task, :id, :type, :uuid, :is_succeed, :is_delivered, :payload_content, :request_content, :response_content) | |||||
| json.delivered_time Time.at(task.delivered*10**-9).strftime("%Y-%m-%d %H:%M:%S") | |||||
| end | |||||
| @@ -0,0 +1,8 @@ | |||||
| if @public_key.present? | |||||
| json.status 0 | |||||
| json.id @public_key["id"] | |||||
| json.name @public_key["title"] | |||||
| json.content @public_key["key"] | |||||
| json.fingerprint @public_key["fingerprint"] | |||||
| json.created_time @public_key["created_at"].to_time.strftime("%Y/%m/%d %H:%M") | |||||
| end | |||||
| @@ -0,0 +1,5 @@ | |||||
| json.total_count @public_keys.total_count | |||||
| json.public_keys @public_keys do |public_key| | |||||
| json.(public_key, :id, :name, :content, :fingerprint, :created_unix) | |||||
| json.created_time Time.at(public_key.created_unix).strftime("%Y/%m/%d %H:%M") | |||||
| end | |||||
| @@ -32,3 +32,5 @@ json.issue do | |||||
| json.version @issue.version.try(:name) | json.version @issue.version.try(:name) | ||||
| json.issue_tags @issue.get_issue_tags | json.issue_tags @issue.get_issue_tags | ||||
| end | end | ||||
| json.conflict_files @pull_request.conflict_files | |||||
| @@ -1,6 +1,6 @@ | |||||
| if @project.forge? | if @project.forge? | ||||
| file_name = entry['name'] | file_name = entry['name'] | ||||
| file_type = file_name.to_s.split(".").last | |||||
| file_type = File.extname(file_name.to_s)[1..-1] | |||||
| direct_download = download_type(file_type) | direct_download = download_type(file_type) | ||||
| image_type = image_type?(file_type) | image_type = image_type?(file_type) | ||||
| json.name file_name | json.name file_name | ||||
| @@ -11,7 +11,16 @@ if @project.forge? | |||||
| json.content decode64_content(entry, @owner, @repository, @ref) | json.content decode64_content(entry, @owner, @repository, @ref) | ||||
| json.target entry['target'] | json.target entry['target'] | ||||
| json.download_url entry['download_url'] | |||||
| download_url = | |||||
| if image_type | |||||
| dir_path = [@owner.login, @repository.identifier, "raw/branch", @ref].join('/') | |||||
| render_download_image_url(dir_path, entry['path'], decode64_content(entry, @owner, @repository, @ref)) | |||||
| else | |||||
| entry['download_url'] | |||||
| end | |||||
| json.download_url download_url | |||||
| json.direct_download direct_download | json.direct_download direct_download | ||||
| json.image_type image_type | json.image_type image_type | ||||
| json.is_readme_file is_readme?(entry['type'], entry['name']) | json.is_readme_file is_readme?(entry['type'], entry['name']) | ||||
| @@ -42,8 +42,9 @@ if @project.forge? | |||||
| #json.tags_count @tags_count | #json.tags_count @tags_count | ||||
| #json.branches_count @branches_count | #json.branches_count @branches_count | ||||
| json.commits_count @commits_count | json.commits_count @commits_count | ||||
| json.zip_url render_zip_url(@project, @ref) | |||||
| json.tar_url render_tar_url(@project, @ref) | |||||
| # json.zip_url archive_repositories_path(@owner&.login, @repository, @ref) | |||||
| json.zip_url render_zip_url(@owner, @repository, @ref) | |||||
| json.tar_url render_tar_url(@owner, @repository, @ref) | |||||
| json.entries do | json.entries do | ||||
| json.array! @entries do |entry| | json.array! @entries do |entry| | ||||
| json.name entry['name'] | json.name entry['name'] | ||||
| @@ -2,8 +2,8 @@ json.array! @tags do |tag| | |||||
| if tag.present? | if tag.present? | ||||
| json.name tag['name'] | json.name tag['name'] | ||||
| json.id tag['id'] | json.id tag['id'] | ||||
| json.zipball_url tag['zipball_url'] | |||||
| json.tarball_url tag['tarball_url'] | |||||
| json.zipball_url render_zip_url(@owner, @repository, tag['name']) | |||||
| json.tarball_url render_tar_url(@owner, @repository, tag['name']) | |||||
| json.commit do | json.commit do | ||||
| json.sha tag['commit']['sha'] | json.sha tag['commit']['sha'] | ||||
| end | end | ||||
| @@ -14,8 +14,8 @@ json.releases do | |||||
| json.name re["name"] | json.name re["name"] | ||||
| json.body re["body"] | json.body re["body"] | ||||
| json.url re["url"] | json.url re["url"] | ||||
| json.tarball_url re["tarball_url"] | |||||
| json.zipball_url re["zipball_url"] | |||||
| json.tarball_url render_tar_url(@owner, @repository, re["tag_name"]) | |||||
| json.zipball_url render_zip_url(@owner, @repository, re["tag_name"]) | |||||
| json.draft re["draft"] ? "草稿" : (re["prerelease"] ? "预发行" : "稳定") | json.draft re["draft"] ? "草稿" : (re["prerelease"] ? "预发行" : "稳定") | ||||
| json.created_at format_time(version.created_at.to_s.to_time) | json.created_at format_time(version.created_at.to_s.to_time) | ||||
| json.published_at format_time(version.created_at.to_s.to_time) | json.published_at format_time(version.created_at.to_s.to_time) | ||||
| @@ -30,8 +30,8 @@ json.releases do | |||||
| json.name re["name"] | json.name re["name"] | ||||
| json.body re["body"] | json.body re["body"] | ||||
| json.url re["url"] | json.url re["url"] | ||||
| json.tarball_url re["tarball_url"] | |||||
| json.zipball_url re["zipball_url"] | |||||
| json.tarball_url render_tar_url(@owner, @repository, re["tag_name"]) | |||||
| json.zipball_url render_zip_url(@owner, @repository, re["tag_name"]) | |||||
| json.draft re["draft"] ? "草稿" : (re["prerelease"] ? "预发行" : "稳定") | json.draft re["draft"] ? "草稿" : (re["prerelease"] ? "预发行" : "稳定") | ||||
| json.created_at format_time(version.created_at.to_s.to_time) | json.created_at format_time(version.created_at.to_s.to_time) | ||||
| json.published_at format_time(version.created_at.to_s.to_time) | json.published_at format_time(version.created_at.to_s.to_time) | ||||
| @@ -7,8 +7,8 @@ json.versions do | |||||
| json.array! @versions.each.to_a do |version| | json.array! @versions.each.to_a do |version| | ||||
| json.extract! version, :id, :name, :description, :effective_date,:status,:percent | json.extract! version, :id, :name, :description, :effective_date,:status,:percent | ||||
| json.open_issues_count (version.issues_count - version.closed_issues_count) | |||||
| json.close_issues_count version.closed_issues_count | |||||
| json.open_issues_count (version.issues.issue_issue.size - version.issues.issue_issue.closed.size) | |||||
| json.close_issues_count version.issues.issue_issue.closed.size | |||||
| json.created_at format_time(version.created_on) | json.created_at format_time(version.created_on) | ||||
| json.updated_at format_time(version.updated_on) | json.updated_at format_time(version.updated_on) | ||||
| json.user_name version.version_user.try(:show_real_name) | json.user_name version.version_user.try(:show_real_name) | ||||
| @@ -1,7 +1,7 @@ | |||||
| json.partial! "commons/success" | json.partial! "commons/success" | ||||
| json.issues_count @version.issues_count | |||||
| json.open_issues_count @version.issues_count - @version.closed_issues_count | |||||
| json.close_issues_count @version.closed_issues_count | |||||
| json.issues_count @version_issues_size | |||||
| json.open_issues_count @version_issues_size - @version_close_issues_size | |||||
| json.close_issues_count @version_close_issues_size | |||||
| json.limit @limit | json.limit @limit | ||||
| json.user_name @version.version_user.try(:show_real_name) | json.user_name @version.version_user.try(:show_real_name) | ||||
| json.user_login @version.version_user.try(:login) | json.user_login @version.version_user.try(:login) | ||||
| @@ -1,6 +1,7 @@ | |||||
| default: &default | default: &default | ||||
| # 用户登入的时候设置/登出的时候清空 | # 用户登入的时候设置/登出的时候清空 | ||||
| autologin_cookie_name: 'autologin_trustie' | autologin_cookie_name: 'autologin_trustie' | ||||
| platform_url: 'http://localhost:3000' | |||||
| #附件上传路径 | #附件上传路径 | ||||
| @@ -17,6 +17,13 @@ default: &default | |||||
| username: root | username: root | ||||
| password: 123456 | password: 123456 | ||||
| # socket: /var/run/mysqld/mysqld.sock | # socket: /var/run/mysqld/mysqld.sock | ||||
| gitea_server: | |||||
| aadapter: mysql2 | |||||
| database: gitea_development | |||||
| host: 127.0.0.1 | |||||
| username: root | |||||
| password: "123456" | |||||
| encoding: utf8 | |||||
| development: | development: | ||||
| <<: *default | <<: *default | ||||
| @@ -4,5 +4,5 @@ | |||||
| # Rails.application.config.session_store :active_record_store | # Rails.application.config.session_store :active_record_store | ||||
| # Be sure to restart your server when you modify this file. | # Be sure to restart your server when you modify this file. | ||||
| Rails.application.config.session_store :cache_store, :expire_after => 24.hours, :httponly => false, :secure => false, key: '_educoder_session', domain: :all | |||||
| Rails.application.config.session_store :cache_store, :expire_after => 24.hours, :httponly => true, :secure => false, key: '_educoder_session', domain: :all | |||||
| @@ -71,6 +71,8 @@ Rails.application.routes.draw do | |||||
| # end | # end | ||||
| end | end | ||||
| resources :public_keys, only: [:index, :create, :destroy] | |||||
| resources :statistic, only: [:index] do | resources :statistic, only: [:index] do | ||||
| collection do | collection do | ||||
| get :platform_profile | get :platform_profile | ||||
| @@ -417,7 +419,6 @@ Rails.application.routes.draw do | |||||
| member do | member do | ||||
| get :files | get :files | ||||
| get :detail | get :detail | ||||
| get :archive | |||||
| get :entries | get :entries | ||||
| match :sub_entries, :via => [:get, :put] | match :sub_entries, :via => [:get, :put] | ||||
| get :commits | get :commits | ||||
| @@ -432,6 +433,7 @@ Rails.application.routes.draw do | |||||
| get 'commits/:sha', to: 'repositories#commit', as: 'commit' | get 'commits/:sha', to: 'repositories#commit', as: 'commit' | ||||
| get 'readme' | get 'readme' | ||||
| get 'languages' | get 'languages' | ||||
| get 'archive/:archive', to: 'repositories#archive', as: "archive", constraints: { archive: /.+/, format: /(zip|gzip)/ } | |||||
| end | end | ||||
| end | end | ||||
| @@ -570,6 +572,12 @@ Rails.application.routes.draw do | |||||
| post :cancel | post :cancel | ||||
| end | end | ||||
| end | end | ||||
| resources :webhooks, except: [:show, :new] do | |||||
| member do | |||||
| get :tasks | |||||
| post :test | |||||
| end | |||||
| end | |||||
| scope do | scope do | ||||
| get( | get( | ||||
| '/blob/*id/diff', | '/blob/*id/diff', | ||||
| @@ -0,0 +1,7 @@ | |||||
| class AddProjectLanguageIndexToProjects < ActiveRecord::Migration[5.2] | |||||
| def change | |||||
| add_index :projects, :project_category_id | |||||
| add_index :projects, :project_language_id | |||||
| add_index :projects, :license_id | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,22 @@ | |||||
| class ChangeColumnsNameFromPullRequests < ActiveRecord::Migration[5.2] | |||||
| def change | |||||
| rename_column :pull_requests, :pull_request_id, :gitea_id | |||||
| rename_column :pull_requests, :gpid, :gitea_number | |||||
| PullRequest.find_each do |pr| | |||||
| next if pr.gitea_number.blank? | |||||
| project = pr.project | |||||
| next if project.blank? | |||||
| owner = project&.owner | |||||
| gitea_pull = Gitea::PullRequest::GetService.call(owner.login, project.identifier, pr.gitea_number, owner&.gitea_token) | |||||
| next if gitea_pull.blank? | |||||
| pr.update_column(:gitea_id, gitea_pull["id"]) | |||||
| end | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,26 @@ | |||||
| namespace :sync_projects_by_forked_project do | |||||
| desc "sync projects is_public by forked project" | |||||
| task is_public: :environment do | |||||
| count = 0 | |||||
| Project.where.not(forked_from_project_id: nil).group(:forked_from_project_id).count.each do |k, _| | |||||
| project = Project.find_by_id(k) | |||||
| need_update_forked_projects = Project.where(forked_from_project_id: k) | |||||
| need_update_forked_projects.update_all(is_public: project&.is_public) | |||||
| need_update_forked_repositories = Repository.where(project_id: need_update_forked_projects.ids) | |||||
| need_update_forked_repositories.update_all(hidden: !project&.is_public) | |||||
| count +=need_update_forked_projects.size | |||||
| end | |||||
| puts "共同步了#{count}个项目" | |||||
| end | |||||
| task destroy: :environment do | |||||
| count = 0 | |||||
| Project.where.not(forked_from_project_id: nil).find_each do |project| | |||||
| if project.forked_from_project.nil? | |||||
| project.update(forked_from_project_id: nil) | |||||
| count +=1 | |||||
| end | |||||
| end | |||||
| puts "共同步了#{count}个项目" | |||||
| end | |||||
| end | |||||