Merge branch 'standalone_develop' into pm_project_develop
# Conflicts: # app/models/attachment.rb # app/views/api/v1/attachments/_simple_detail.json.jbuilder
This commit is contained in:
commit
9835f4f84f
|
@ -55,6 +55,11 @@ class Api::V1::BaseController < ApplicationController
|
||||||
return render_forbidden if !current_user.admin? && !@project.operator?(current_user) && !(@project.fork_project.present? && @project.fork_project.operator?(current_user))
|
return render_forbidden if !current_user.admin? && !@project.operator?(current_user) && !(@project.fork_project.present? && @project.fork_project.operator?(current_user))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def require_member_above
|
||||||
|
@project = load_project
|
||||||
|
return render_forbidden if !current_user.admin? && !@project.member?(current_user)
|
||||||
|
end
|
||||||
|
|
||||||
# 具有对仓库的访问权限
|
# 具有对仓库的访问权限
|
||||||
def require_public_and_member_above
|
def require_public_and_member_above
|
||||||
@project = load_project
|
@project = load_project
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
class Api::V1::ProjectDatasetsController < Api::V1::BaseController
|
||||||
|
|
||||||
|
def index
|
||||||
|
return render_error("请输入正确的项目id字符串") unless params[:ids].present?
|
||||||
|
ids = params[:ids].split(",")
|
||||||
|
@project_datasets = ProjectDataset.where(project_id: ids).includes(:license, :project)
|
||||||
|
@project_datasets = kaminari_unlimit_paginate(@project_datasets)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -11,6 +11,9 @@ class Api::V1::Projects::CommitsController < Api::V1::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def recent
|
def recent
|
||||||
@result_object = Api::V1::Projects::Commits::RecentService.call(@project, {page: page, limit: limit}, current_user&.gitea_token)
|
hash = Api::V1::Projects::Commits::RecentService.call(@project, {keyword: params[:keyword], page: page, limit: limit}, current_user&.gitea_token)
|
||||||
|
@result_object = hash[:result]
|
||||||
|
@object_detail = hash[:detail]
|
||||||
|
puts @object_detail
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -0,0 +1,51 @@
|
||||||
|
class Api::V1::Projects::DatasetsController < Api::V1::BaseController
|
||||||
|
before_action :require_public_and_member_above, only: [:show]
|
||||||
|
before_action :require_member_above, only: [:create, :update]
|
||||||
|
before_action :find_dataset, only: [:update, :show]
|
||||||
|
before_action :check_menu_authorize
|
||||||
|
|
||||||
|
def create
|
||||||
|
::Projects::Datasets::CreateForm.new(dataset_params).validate!
|
||||||
|
return render_error('该项目下已存在数据集!') if @project.project_dataset.present?
|
||||||
|
@project_dataset = ProjectDataset.new(dataset_params.merge!(project_id: @project.id))
|
||||||
|
if @project_dataset.save!
|
||||||
|
render_ok
|
||||||
|
else
|
||||||
|
render_error('创建数据集失败!')
|
||||||
|
end
|
||||||
|
rescue Exception => e
|
||||||
|
uid_logger_error(e.message)
|
||||||
|
tip_exception(e.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
::Projects::Datasets::CreateForm.new(dataset_params).validate!
|
||||||
|
@project_dataset.attributes = dataset_params
|
||||||
|
if @project_dataset.save!
|
||||||
|
render_ok
|
||||||
|
else
|
||||||
|
render_error("更新数据集失败!")
|
||||||
|
end
|
||||||
|
rescue Exception => e
|
||||||
|
uid_logger_error(e.message)
|
||||||
|
tip_exception(e.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
@attachments = kaminari_paginate(@project_dataset.attachments.includes(:author))
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def dataset_params
|
||||||
|
params.permit(:title, :description, :license_id, :paper_content)
|
||||||
|
end
|
||||||
|
|
||||||
|
def find_dataset
|
||||||
|
@project_dataset = @project.project_dataset
|
||||||
|
return render_not_found unless @project_dataset.present?
|
||||||
|
end
|
||||||
|
|
||||||
|
def check_menu_authorize
|
||||||
|
return render_not_found unless @project.has_menu_permission("dataset")
|
||||||
|
end
|
||||||
|
end
|
|
@ -715,7 +715,7 @@ class ApplicationController < ActionController::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_user_with_id
|
def find_user_with_id
|
||||||
@user = User.find_by_id params[:user_id]
|
@user = User.find_by(type: 'User', id: params[:user_id])
|
||||||
# render_not_found("未找到’#{params[:login]}’相关的用户") unless @user
|
# render_not_found("未找到’#{params[:login]}’相关的用户") unless @user
|
||||||
render_error("未找到相关的用户") unless @user
|
render_error("未找到相关的用户") unless @user
|
||||||
end
|
end
|
||||||
|
|
|
@ -95,6 +95,9 @@ class AttachmentsController < ApplicationController
|
||||||
@attachment.disk_directory = month_folder
|
@attachment.disk_directory = month_folder
|
||||||
@attachment.cloud_url = remote_path
|
@attachment.cloud_url = remote_path
|
||||||
@attachment.uuid = SecureRandom.uuid
|
@attachment.uuid = SecureRandom.uuid
|
||||||
|
@attachment.description = params[:description]
|
||||||
|
@attachment.container_id = params[:container_id]
|
||||||
|
@attachment.container_type = params[:container_type]
|
||||||
@attachment.save!
|
@attachment.save!
|
||||||
else
|
else
|
||||||
logger.info "文件已存在,id = #{@attachment.id}, filename = #{@attachment.filename}"
|
logger.info "文件已存在,id = #{@attachment.id}, filename = #{@attachment.filename}"
|
||||||
|
@ -124,7 +127,7 @@ class AttachmentsController < ApplicationController
|
||||||
|
|
||||||
# 附件为视频时,点击播放
|
# 附件为视频时,点击播放
|
||||||
def preview_attachment
|
def preview_attachment
|
||||||
attachment = Attachment.find_by(id: params[:id])
|
attachment = Attachment.where_id_or_uuid(params[:id]).first
|
||||||
dir_path = "#{Rails.root}/public/preview"
|
dir_path = "#{Rails.root}/public/preview"
|
||||||
Dir.mkdir(dir_path) unless Dir.exist?(dir_path)
|
Dir.mkdir(dir_path) unless Dir.exist?(dir_path)
|
||||||
if params[:status] == "preview"
|
if params[:status] == "preview"
|
||||||
|
|
|
@ -8,7 +8,7 @@ class BindUsersController < ApplicationController
|
||||||
bind_user = User.try_to_login(params[:username], params[:password])
|
bind_user = User.try_to_login(params[:username], params[:password])
|
||||||
tip_exception '用户名或者密码错误' if bind_user.blank?
|
tip_exception '用户名或者密码错误' if bind_user.blank?
|
||||||
tip_exception '用户名或者密码错误' unless bind_user.check_password?(params[:password].to_s)
|
tip_exception '用户名或者密码错误' unless bind_user.check_password?(params[:password].to_s)
|
||||||
tip_exception '参数错误' unless ["qq", "wechat", "gitee", "github", "educoder"].include?(params[:type].to_s)
|
tip_exception '参数错误' unless ["qq", "wechat", "gitee", "github", "educoder", "acge"].include?(params[:type].to_s)
|
||||||
tip_exception '该账号已被绑定,请更换其他账号进行绑定' if bind_user.bind_open_user?(params[:type].to_s)
|
tip_exception '该账号已被绑定,请更换其他账号进行绑定' if bind_user.bind_open_user?(params[:type].to_s)
|
||||||
|
|
||||||
"OpenUsers::#{params[:type].to_s.capitalize}".constantize.create!(user: bind_user, uid: session[:unionid])
|
"OpenUsers::#{params[:type].to_s.capitalize}".constantize.create!(user: bind_user, uid: session[:unionid])
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
class Oauth::AcgeController < Oauth::BaseController
|
||||||
|
include RegisterHelper
|
||||||
|
|
||||||
|
def create
|
||||||
|
begin
|
||||||
|
uid = params['uid'].to_s.strip
|
||||||
|
tip_exception("uid不能为空") if uid.blank?
|
||||||
|
redirect_uri = params['redirect_uri'].to_s.strip
|
||||||
|
tip_exception("redirect_uri不能为空") if redirect_uri.blank?
|
||||||
|
email = params['email'].to_s.strip
|
||||||
|
tip_exception("email不能为空") if email.blank?
|
||||||
|
phone = params['phone'].to_s.strip
|
||||||
|
tip_exception("phone不能为空") if phone.blank?
|
||||||
|
name = params['name'].to_s.strip
|
||||||
|
tip_exception("name不能为空") if name.blank?
|
||||||
|
|
||||||
|
open_user = OpenUsers::Acge.find_by(uid: uid)
|
||||||
|
if open_user.present? && open_user.user.present?
|
||||||
|
successful_authentication(open_user.user)
|
||||||
|
redirect_to redirect_uri
|
||||||
|
return
|
||||||
|
else
|
||||||
|
if current_user.blank? || !current_user.logged?
|
||||||
|
session[:unionid] = uid
|
||||||
|
user = User.find_by(mail: email) || User.find_by(phone: phone)
|
||||||
|
if user.present?
|
||||||
|
OpenUsers::Acge.create!(user: user, uid: uid)
|
||||||
|
successful_authentication(user)
|
||||||
|
redirect_to redirect_uri
|
||||||
|
|
||||||
|
return
|
||||||
|
else
|
||||||
|
username = uid
|
||||||
|
password = SecureRandom.hex(4)
|
||||||
|
reg_result = autologin_register(username, email, password, 'acge', phone, name)
|
||||||
|
existing_rows = CSV.read("public/操作系统大赛用户信息.csv")
|
||||||
|
new_row = [username, email, password, phone, name]
|
||||||
|
existing_rows << new_row
|
||||||
|
CSV.open("public/操作系统大赛用户信息.csv", 'wb') do |csv|
|
||||||
|
existing_rows.each { |row| csv << row }
|
||||||
|
end
|
||||||
|
if reg_result[:message].blank?
|
||||||
|
open_user = OpenUsers::Acge.create!(user_id: reg_result[:user][:id], uid: uid)
|
||||||
|
successful_authentication(open_user.user)
|
||||||
|
redirect_to redirect_uri
|
||||||
|
|
||||||
|
return
|
||||||
|
else
|
||||||
|
render_error(reg_result[:message])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
OpenUsers::Acge.create!(user: current_user, uid: uid)
|
||||||
|
successful_authentication(current_user)
|
||||||
|
redirect_to redirect_uri
|
||||||
|
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Rails.logger.info("[OAuth2] session[:unionid] -> #{session[:unionid]}")
|
||||||
|
# redirect_to "/bindlogin/acge?redirect_uri=#{redirect_uri}"
|
||||||
|
rescue Exception => ex
|
||||||
|
render_error(ex.message)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -67,7 +67,17 @@ class Organizations::TeamsController < Organizations::BaseController
|
||||||
tip_exception("组织团队不允许被删除") if @team.owner?
|
tip_exception("组织团队不允许被删除") if @team.owner?
|
||||||
ActiveRecord::Base.transaction do
|
ActiveRecord::Base.transaction do
|
||||||
Gitea::Organization::Team::DeleteService.call(@organization.gitea_token, @team.gtid)
|
Gitea::Organization::Team::DeleteService.call(@organization.gitea_token, @team.gtid)
|
||||||
|
all_user_ids = @organization.team_users.pluck(:user_id)
|
||||||
|
team_user_ids = @team.team_users.pluck(:user_id)
|
||||||
|
# 当前删除团队中成员在其他组织其他团队不存在的成员需清除组织
|
||||||
|
remove_user_ids = team_user_ids - all_user_ids
|
||||||
@team.destroy!
|
@team.destroy!
|
||||||
|
if remove_user_ids.present?
|
||||||
|
User.where(id: remove_user_ids).each do |user|
|
||||||
|
@organization.organization_users.find_by(user_id: user.id).destroy!
|
||||||
|
Gitea::Organization::OrganizationUser::DeleteService.call(@organization.gitea_token, @organization.login, user.login)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
render_ok
|
render_ok
|
||||||
rescue Exception => e
|
rescue Exception => e
|
||||||
|
|
|
@ -21,6 +21,7 @@ class ProjectsController < ApplicationController
|
||||||
menu.append(menu_hash_by_name("issues")) if @project.has_menu_permission("issues")
|
menu.append(menu_hash_by_name("issues")) if @project.has_menu_permission("issues")
|
||||||
menu.append(menu_hash_by_name("pulls")) if @project.has_menu_permission("pulls") && @project.forge?
|
menu.append(menu_hash_by_name("pulls")) if @project.has_menu_permission("pulls") && @project.forge?
|
||||||
menu.append(menu_hash_by_name("devops")) if @project.has_menu_permission("devops") && @project.forge?
|
menu.append(menu_hash_by_name("devops")) if @project.has_menu_permission("devops") && @project.forge?
|
||||||
|
menu.append(menu_hash_by_name("dataset")) if @project.has_menu_permission("dataset") && @project.forge?
|
||||||
menu.append(menu_hash_by_name("versions")) if @project.has_menu_permission("versions")
|
menu.append(menu_hash_by_name("versions")) if @project.has_menu_permission("versions")
|
||||||
menu.append(menu_hash_by_name("wiki")) if @project.has_menu_permission("wiki") && @project.forge?
|
menu.append(menu_hash_by_name("wiki")) if @project.has_menu_permission("wiki") && @project.forge?
|
||||||
menu.append(menu_hash_by_name("services")) if @project.has_menu_permission("services") && @project.forge? && (current_user.admin? || @project.member?(current_user.id))
|
menu.append(menu_hash_by_name("services")) if @project.has_menu_permission("services") && @project.forge? && (current_user.admin? || @project.member?(current_user.id))
|
||||||
|
@ -42,7 +43,8 @@ class ProjectsController < ApplicationController
|
||||||
@total_count =
|
@total_count =
|
||||||
if category_id.blank? && params[:search].blank? && params[:topic_id].blank?
|
if category_id.blank? && params[:search].blank? && params[:topic_id].blank?
|
||||||
# 默认查询时count性能问题处理
|
# 默认查询时count性能问题处理
|
||||||
ProjectCategory.sum("projects_count") - Project.visible.joins("left join organization_extensions on organization_extensions.organization_id = projects.user_id").where("organization_extensions.visibility =2").count
|
not_category_count = Project.where(project_category_id: nil).count
|
||||||
|
ProjectCategory.sum("projects_count") - Project.visible.joins("left join organization_extensions on organization_extensions.organization_id = projects.user_id").where("organization_extensions.visibility =2").count + not_category_count
|
||||||
elsif params[:search].present? || params[:topic_id].present?
|
elsif params[:search].present? || params[:topic_id].present?
|
||||||
@projects.total_count
|
@projects.total_count
|
||||||
else
|
else
|
||||||
|
@ -58,7 +60,10 @@ class ProjectsController < ApplicationController
|
||||||
OpenProjectDevOpsJob.set(wait: 5.seconds).perform_later(@project&.id, current_user.id)
|
OpenProjectDevOpsJob.set(wait: 5.seconds).perform_later(@project&.id, current_user.id)
|
||||||
UpdateProjectTopicJob.perform_later(@project.id) if @project.id.present?
|
UpdateProjectTopicJob.perform_later(@project.id) if @project.id.present?
|
||||||
end
|
end
|
||||||
rescue Exception => e
|
rescue Gitea::Api::ServerError => ex
|
||||||
|
uid_logger_error(ex.message)
|
||||||
|
tip_exception(ex.http_code, ex.message)
|
||||||
|
rescue ApplicationService::Error => e
|
||||||
uid_logger_error(e.message)
|
uid_logger_error(e.message)
|
||||||
tip_exception(e.message)
|
tip_exception(e.message)
|
||||||
end
|
end
|
||||||
|
@ -204,7 +209,8 @@ class ProjectsController < ApplicationController
|
||||||
|
|
||||||
Projects::UpdateForm.new(validate_params.merge(user_id: @project.user_id, project_identifier: @project.identifier, project_name: @project.name)).validate!
|
Projects::UpdateForm.new(validate_params.merge(user_id: @project.user_id, project_identifier: @project.identifier, project_name: @project.name)).validate!
|
||||||
|
|
||||||
private = @project.forked_from_project.present? ? !@project.forked_from_project.is_public : params[:private] || false
|
private = params[:private].nil? ? !@project.is_public : params[:private]
|
||||||
|
private = @project.forked_from_project.present? ? !@project.forked_from_project.is_public : private
|
||||||
|
|
||||||
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)
|
||||||
|
|
|
@ -203,6 +203,7 @@ class PullRequestsController < ApplicationController
|
||||||
|
|
||||||
def pr_merge
|
def pr_merge
|
||||||
return render_forbidden("你没有权限操作.") unless @project.operator?(current_user)
|
return render_forbidden("你没有权限操作.") unless @project.operator?(current_user)
|
||||||
|
return normal_status(-1, "该分支存在冲突,无法自动合并.") unless @pull_request.conflict_files.blank?
|
||||||
|
|
||||||
if params[:do].blank?
|
if params[:do].blank?
|
||||||
normal_status(-1, "请选择合并方式")
|
normal_status(-1, "请选择合并方式")
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
class VersionReleasesController < ApplicationController
|
class VersionReleasesController < ApplicationController
|
||||||
|
include ApplicationHelper
|
||||||
before_action :load_repository
|
before_action :load_repository
|
||||||
before_action :set_user
|
before_action :set_user
|
||||||
before_action :require_login, except: [:index, :show]
|
before_action :require_login, except: [:index, :show]
|
||||||
|
@ -126,6 +127,16 @@ class VersionReleasesController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def download
|
||||||
|
tip_exception(404, '您访问的页面不存在或已被删除') if params["tag_name"].blank? || params["filename"].blank?
|
||||||
|
version = @repository.version_releases.find_by(tag_name: params["tag_name"])
|
||||||
|
attachment = version.attachments.find_by(filename: params["filename"])
|
||||||
|
tip_exception(404, '您访问的页面不存在或已被删除') if attachment.blank?
|
||||||
|
send_file(absolute_path(local_path(attachment)), filename: attachment.title, stream: false, type: attachment.content_type.presence || 'application/octet-stream')
|
||||||
|
update_downloads(attachment)
|
||||||
|
# redirect_to "/api/attachments/#{attachment.uuid}"
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
private
|
private
|
||||||
def set_user
|
def set_user
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
class Projects::Datasets::CreateForm < BaseForm
|
||||||
|
attr_accessor :title, :description, :license_id, :paper_content
|
||||||
|
|
||||||
|
|
||||||
|
validates :title, presence: true, length: { maximum: 100 }
|
||||||
|
validates :description, presence: true, length: { maximum: 500 }
|
||||||
|
validates :paper_content, length: { maximum: 500 }
|
||||||
|
|
||||||
|
validate :check_license
|
||||||
|
|
||||||
|
def check_license
|
||||||
|
raise "license_id值无效. " if license_id && License.find_by(id: license_id).blank?
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -67,6 +67,7 @@ module ProjectsHelper
|
||||||
jianmu_devops_url: jianmu_devops_url,
|
jianmu_devops_url: jianmu_devops_url,
|
||||||
cloud_ide_saas_url: cloud_ide_saas_url(user),
|
cloud_ide_saas_url: cloud_ide_saas_url(user),
|
||||||
open_blockchain: Site.has_blockchain? && project.use_blockchain,
|
open_blockchain: Site.has_blockchain? && project.use_blockchain,
|
||||||
|
has_dataset: project.project_dataset.present?,
|
||||||
ignore_id: project.ignore_id
|
ignore_id: project.ignore_id
|
||||||
}).compact
|
}).compact
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,7 @@ class Attachment < ApplicationRecord
|
||||||
scope :unified_setting, -> {where("unified_setting = ? ", 1)}
|
scope :unified_setting, -> {where("unified_setting = ? ", 1)}
|
||||||
scope :where_id_or_uuid, -> (id) { (Float(id) rescue nil).present? ? where(id: id) : where(uuid: id) }
|
scope :where_id_or_uuid, -> (id) { (Float(id) rescue nil).present? ? where(id: id) : where(uuid: id) }
|
||||||
|
|
||||||
validates_length_of :description, maximum: 100, message: "不能超过100个字符"
|
validates_length_of :description, maximum: 255, message: "不能超过255个字符"
|
||||||
|
|
||||||
DCODES = %W(2 3 4 5 6 7 8 9 a b c f e f g h i j k l m n o p q r s t u v w x y z)
|
DCODES = %W(2 3 4 5 6 7 8 9 a b c f e f g h i j k l m n o p q r s t u v w x y z)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: open_users
|
||||||
|
#
|
||||||
|
# id :integer not null, primary key
|
||||||
|
# user_id :integer
|
||||||
|
# type :string(255)
|
||||||
|
# uid :string(255)
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
# extra :text(65535)
|
||||||
|
#
|
||||||
|
# Indexes
|
||||||
|
#
|
||||||
|
# index_open_users_on_type_and_uid (type,uid) UNIQUE
|
||||||
|
# index_open_users_on_user_id (user_id)
|
||||||
|
#
|
||||||
|
|
||||||
|
class OpenUsers::Acge < OpenUser
|
||||||
|
def nickname
|
||||||
|
extra&.[]('nickname')
|
||||||
|
end
|
||||||
|
|
||||||
|
def en_type
|
||||||
|
'acge'
|
||||||
|
end
|
||||||
|
end
|
|
@ -28,7 +28,7 @@ class Page < ApplicationRecord
|
||||||
belongs_to :project
|
belongs_to :project
|
||||||
|
|
||||||
# language_frame 前端语言框架
|
# language_frame 前端语言框架
|
||||||
enum language_frame: { hugo: 0, jekyll: 1, hexo: 2}
|
enum language_frame: { hugo: 0, jekyll: 1, hexo: 2, files: 3}
|
||||||
|
|
||||||
after_create do
|
after_create do
|
||||||
PageService.genernate_user(user_id)
|
PageService.genernate_user(user_id)
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
class PageTheme < ApplicationRecord
|
class PageTheme < ApplicationRecord
|
||||||
enum language_frame: { hugo: 0, jeklly: 1, hexo: 2}
|
enum language_frame: { hugo: 0, jeklly: 1, hexo: 2, files:3}
|
||||||
validates :name, presence: {message: "主题名不能为空"}, uniqueness: {message: "主题名已存在",scope: :language_frame},length: {maximum: 255}
|
validates :name, presence: {message: "主题名不能为空"}, uniqueness: {message: "主题名已存在",scope: :language_frame},length: {maximum: 255}
|
||||||
|
|
||||||
def image
|
def image
|
||||||
|
|
|
@ -90,6 +90,8 @@ class Project < ApplicationRecord
|
||||||
include ProjectOperable
|
include ProjectOperable
|
||||||
include Dcodes
|
include Dcodes
|
||||||
|
|
||||||
|
default_scope {where.not(id: 0)}
|
||||||
|
|
||||||
# common:开源托管项目
|
# common:开源托管项目
|
||||||
# mirror:普通镜像项目,没有定时同步功能
|
# mirror:普通镜像项目,没有定时同步功能
|
||||||
# sync_mirror:同步镜像项目,有系统定时同步功能,且用户可手动同步操作
|
# sync_mirror:同步镜像项目,有系统定时同步功能,且用户可手动同步操作
|
||||||
|
@ -137,6 +139,7 @@ class Project < ApplicationRecord
|
||||||
has_many :project_topics, through: :project_topic_ralates
|
has_many :project_topics, through: :project_topic_ralates
|
||||||
has_many :commit_logs, dependent: :destroy
|
has_many :commit_logs, dependent: :destroy
|
||||||
has_many :daily_project_statistics, dependent: :destroy
|
has_many :daily_project_statistics, dependent: :destroy
|
||||||
|
has_one :project_dataset, dependent: :destroy
|
||||||
after_create :incre_user_statistic, :incre_platform_statistic
|
after_create :incre_user_statistic, :incre_platform_statistic
|
||||||
after_save :check_project_members
|
after_save :check_project_members
|
||||||
before_save :set_invite_code, :reset_unmember_followed, :set_recommend_and_is_pinned, :reset_cache_data
|
before_save :set_invite_code, :reset_unmember_followed, :set_recommend_and_is_pinned, :reset_cache_data
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: project_datasets
|
||||||
|
#
|
||||||
|
# id :integer not null, primary key
|
||||||
|
# title :string(255)
|
||||||
|
# description :text(65535)
|
||||||
|
# project_id :integer
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
# license_id :integer
|
||||||
|
# paper_content :text(65535)
|
||||||
|
#
|
||||||
|
# Indexes
|
||||||
|
#
|
||||||
|
# index_project_datasets_on_license_id (license_id)
|
||||||
|
# index_project_datasets_on_project_id (project_id)
|
||||||
|
#
|
||||||
|
|
||||||
|
class ProjectDataset < ApplicationRecord
|
||||||
|
|
||||||
|
belongs_to :project
|
||||||
|
belongs_to :license, optional: true
|
||||||
|
has_many :attachments, as: :container, dependent: :destroy
|
||||||
|
|
||||||
|
end
|
|
@ -17,7 +17,7 @@ class ProjectUnit < ApplicationRecord
|
||||||
|
|
||||||
belongs_to :project
|
belongs_to :project
|
||||||
|
|
||||||
enum unit_type: {code: 1, issues: 2, pulls: 3, wiki:4, devops: 5, versions: 6, resources: 7, services: 8}
|
enum unit_type: {code: 1, issues: 2, pulls: 3, wiki:4, devops: 5, versions: 6, resources: 7, services: 8, dataset: 9}
|
||||||
|
|
||||||
validates :unit_type, uniqueness: { scope: :project_id}
|
validates :unit_type, uniqueness: { scope: :project_id}
|
||||||
|
|
||||||
|
|
|
@ -115,7 +115,7 @@ class User < Owner
|
||||||
# trustie: 来自Trustie平台
|
# trustie: 来自Trustie平台
|
||||||
# forge: 平台本身注册的用户
|
# forge: 平台本身注册的用户
|
||||||
# military: 军科的用户
|
# military: 军科的用户
|
||||||
enumerize :platform, in: [:forge, :educoder, :trustie, :military, :github, :gitee, :qq, :wechat, :bot], default: :forge, scope: :shallow
|
enumerize :platform, in: [:forge, :educoder, :trustie, :military, :github, :gitee, :qq, :wechat, :bot, :acge], default: :forge, scope: :shallow
|
||||||
|
|
||||||
belongs_to :laboratory, optional: true
|
belongs_to :laboratory, optional: true
|
||||||
has_one :user_extension, dependent: :destroy
|
has_one :user_extension, dependent: :destroy
|
||||||
|
|
|
@ -152,7 +152,7 @@ class Api::V1::Issues::UpdateService < ApplicationService
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_previous_issue_changes
|
def build_previous_issue_changes
|
||||||
@previous_issue_changes.merge!(@updated_issue.previous_changes.slice("status_id", "priority_id", "fixed_version_id", "issue_tags_value", "branch_name", "subject", "description").symbolize_keys)
|
@previous_issue_changes.merge!(@updated_issue.previous_changes.slice("status_id", "priority_id", "fixed_version_id", "issue_tags_value", "branch_name", "subject").symbolize_keys)
|
||||||
if @updated_issue.previous_changes[:start_date].present?
|
if @updated_issue.previous_changes[:start_date].present?
|
||||||
@previous_issue_changes.merge!(start_date: [@updated_issue.previous_changes[:start_date][0].to_s, @updated_issue.previous_changes[:start_date][1].to_s])
|
@previous_issue_changes.merge!(start_date: [@updated_issue.previous_changes[:start_date][0].to_s, @updated_issue.previous_changes[:start_date][1].to_s])
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
class Api::V1::Projects::Commits::RecentService < ApplicationService
|
class Api::V1::Projects::Commits::RecentService < ApplicationService
|
||||||
|
|
||||||
attr_reader :project, :page, :limit, :owner, :repo, :token
|
attr_reader :project, :page, :limit, :keyword, :owner, :repo, :token
|
||||||
attr_accessor :gitea_data
|
attr_accessor :gitea_data, :gitea_repo_detail
|
||||||
|
|
||||||
def initialize(project, params, token=nil)
|
def initialize(project, params, token=nil)
|
||||||
@project = project
|
@project = project
|
||||||
@page = params[:page] || 1
|
@page = params[:page] || 1
|
||||||
@limit = params[:limit] || 15
|
@limit = params[:limit] || 15
|
||||||
|
@keyword = params[:keyword]
|
||||||
@owner = project&.owner&.login
|
@owner = project&.owner&.login
|
||||||
@repo = project&.identifier
|
@repo = project&.identifier
|
||||||
@token = token
|
@token = token
|
||||||
|
@ -14,8 +15,9 @@ class Api::V1::Projects::Commits::RecentService < ApplicationService
|
||||||
|
|
||||||
def call
|
def call
|
||||||
load_gitea_data
|
load_gitea_data
|
||||||
|
load_gitea_repo_detail
|
||||||
|
|
||||||
gitea_data
|
{result: gitea_data, detail:gitea_repo_detail}
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -25,6 +27,7 @@ class Api::V1::Projects::Commits::RecentService < ApplicationService
|
||||||
page: page,
|
page: page,
|
||||||
limit: limit
|
limit: limit
|
||||||
}
|
}
|
||||||
|
param.merge!(keyword: keyword) if keyword.present?
|
||||||
|
|
||||||
param
|
param
|
||||||
end
|
end
|
||||||
|
@ -34,4 +37,8 @@ class Api::V1::Projects::Commits::RecentService < ApplicationService
|
||||||
raise Error, "获取最近提交列表失败" unless @gitea_data.is_a?(Hash)
|
raise Error, "获取最近提交列表失败" unless @gitea_data.is_a?(Hash)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def load_gitea_repo_detail
|
||||||
|
@gitea_repo_detail = $gitea_client.get_repos_by_owner_repo(owner, repo, {query: {access_token: token}})
|
||||||
|
raise Error, "获取项目详情失败" unless @gitea_repo_detail.is_a?(Hash)
|
||||||
|
end
|
||||||
end
|
end
|
|
@ -47,7 +47,7 @@ class PageService
|
||||||
repo_link = project.repository.url
|
repo_link = project.repository.url
|
||||||
repo = project.repository.identifier
|
repo = project.repository.identifier
|
||||||
branch = branch
|
branch = branch
|
||||||
script_path =page.build_script_path
|
script_path = branch == "gh-pages" ? "files_build" : page.build_script_path
|
||||||
if script_path.present?
|
if script_path.present?
|
||||||
uri = URI.parse("http://gitlink.#{@deploy_domain}/gitlink_execute_script?key=#{@deploy_key}&script_path=#{script_path}&project_dir=#{project_dir}&repo=#{repo}&repo_link=#{repo_link}&branch=#{branch}&owner=#{owner}")
|
uri = URI.parse("http://gitlink.#{@deploy_domain}/gitlink_execute_script?key=#{@deploy_key}&script_path=#{script_path}&project_dir=#{project_dir}&repo=#{repo}&repo_link=#{repo_link}&branch=#{branch}&owner=#{owner}")
|
||||||
response = Net::HTTP.get_response(uri)
|
response = Net::HTTP.get_response(uri)
|
||||||
|
|
|
@ -26,9 +26,6 @@ class Projects::CreateService < ApplicationService
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@project
|
@project
|
||||||
rescue => e
|
|
||||||
puts "create project service error: #{e.message}"
|
|
||||||
raise Error, e.message
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
|
@ -33,18 +33,17 @@ class Repositories::CreateService < ApplicationService
|
||||||
end
|
end
|
||||||
repository
|
repository
|
||||||
end
|
end
|
||||||
rescue => e
|
|
||||||
puts "create repository service error: #{e.message}"
|
|
||||||
raise Error, e.message
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def create_gitea_repository
|
def create_gitea_repository
|
||||||
if project.owner.is_a?(User)
|
if project.owner.is_a?(User)
|
||||||
@gitea_repository = Gitea::Repository::CreateService.new(user.gitea_token, gitea_repository_params).call
|
# @gitea_repository = Gitea::Repository::CreateService.new(user.gitea_token, gitea_repository_params).call
|
||||||
|
@gitea_repository = $gitea_client.post_user_repos({query: {token: user.gitea_token}, body: gitea_repository_params.to_json})
|
||||||
elsif project.owner.is_a?(Organization)
|
elsif project.owner.is_a?(Organization)
|
||||||
@gitea_repository = Gitea::Organization::Repository::CreateService.call(user.gitea_token, project.owner.login, gitea_repository_params)
|
# @gitea_repository = Gitea::Organization::Repository::CreateService.call(user.gitea_token, project.owner.login, gitea_repository_params)
|
||||||
|
@gitea_repository = $gitea_client.post_orgs_repos_by_org(project.owner.login, {query: {token: user.gitea_token}, body: gitea_repository_params.to_json})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
<label>
|
<label>
|
||||||
建站工具 <span class="ml10 color-orange mr20">*</span>
|
建站工具 <span class="ml10 color-orange mr20">*</span>
|
||||||
</label>
|
</label>
|
||||||
<% state_options = [['hugo', "hugo"], ['jeklly', "jeklly"],['hexo',"hexo"]] %>
|
<% state_options = [['hugo', "hugo"], ['jeklly', "jeklly"],['hexo',"hexo"],['files',"files"]] %>
|
||||||
<%= select_tag('page_theme[language_frame]', options_for_select(state_options), class: 'form-control') %>
|
<%= select_tag('page_theme[language_frame]', options_for_select(state_options), class: 'form-control') %>
|
||||||
</div>
|
</div>
|
||||||
<% end%>
|
<% end%>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<%= form_tag(admins_page_themes_path, method: :get, class: 'form-inline search-form flex-1', remote: true) do %>
|
<%= form_tag(admins_page_themes_path, method: :get, class: 'form-inline search-form flex-1', remote: true) do %>
|
||||||
<div class="form-group mr-2">
|
<div class="form-group mr-2">
|
||||||
<label for="language_frame">建站工具:</label>
|
<label for="language_frame">建站工具:</label>
|
||||||
<% state_options = [['全部',nil], ['hugo', 0], ['jeklly', 1],['hexo',2]] %>
|
<% state_options = [['全部',nil], ['hugo', 0], ['jeklly', 1],['hexo',2],['files',3]] %>
|
||||||
<%= select_tag(:language_frame, options_for_select(state_options), class: 'form-control') %>
|
<%= select_tag(:language_frame, options_for_select(state_options), class: 'form-control') %>
|
||||||
</div>
|
</div>
|
||||||
<%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %>
|
<%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %>
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
json.id attachment.uuid
|
||||||
|
json.title attachment.title
|
||||||
|
json.description attachment.description
|
||||||
|
json.filesize number_to_human_size(attachment.filesize)
|
||||||
|
json.is_pdf attachment.is_pdf?
|
||||||
|
json.url attachment.is_pdf? ? download_url(attachment,disposition:"inline") : download_url(attachment)
|
||||||
|
json.created_on attachment.created_on.strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
json.content_type attachment.content_type
|
||||||
|
json.creator do
|
||||||
|
json.partial! "api/v1/users/simple_user", locals: {user: attachment.author}
|
||||||
|
end
|
|
@ -1,5 +1,6 @@
|
||||||
json.id attachment.id
|
json.id attachment.uuid
|
||||||
json.title attachment.title
|
json.title attachment.title
|
||||||
|
json.description attachment.description
|
||||||
json.filesize number_to_human_size(attachment.filesize)
|
json.filesize number_to_human_size(attachment.filesize)
|
||||||
json.is_pdf attachment.is_pdf?
|
json.is_pdf attachment.is_pdf?
|
||||||
json.url Rails.application.config_for(:configuration)['platform_url'] + (attachment.is_pdf? ? download_url(attachment,disposition:"inline") : download_url(attachment)).to_s
|
json.url Rails.application.config_for(:configuration)['platform_url'] + (attachment.is_pdf? ? download_url(attachment,disposition:"inline") : download_url(attachment)).to_s
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
json.total_count @project_datasets.total_count
|
||||||
|
json.project_datasets @project_datasets.each do |dataset|
|
||||||
|
json.(dataset, :id, :title, :description, :paper_content)
|
||||||
|
json.project do
|
||||||
|
json.partial! "api/v1/projects/simple_detail", project: dataset.project
|
||||||
|
end
|
||||||
|
if dataset.license.present?
|
||||||
|
json.license do
|
||||||
|
json.(dataset.license, :name, :content)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
json.license nil
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,7 +1,7 @@
|
||||||
if project.present?
|
if project.present?
|
||||||
json.type project.project_type
|
json.type project.project_type
|
||||||
json.(project,
|
json.(project,
|
||||||
:description, :forked_count, :forked_from_project_id, :identifier,
|
:id, :description, :forked_count, :forked_from_project_id, :identifier,
|
||||||
:issues_count, :pull_requests_count, :invite_code, :website, :platform,
|
:issues_count, :pull_requests_count, :invite_code, :website, :platform,
|
||||||
:name, :open_devops, :praises_count, :is_public, :status, :watchers_count,
|
:name, :open_devops, :praises_count, :is_public, :status, :watchers_count,
|
||||||
:ignore_id, :license_id, :project_category_id, :project_language_id)
|
:ignore_id, :license_id, :project_category_id, :project_language_id)
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
json.total_count @result_object[:total_data].to_i
|
json.total_count @result_object[:total_data].to_i
|
||||||
|
json.ssh_url @object_detail['ssh_url']
|
||||||
|
json.clone_url @object_detail['clone_url']
|
||||||
json.commits @result_object[:data].each do |commit|
|
json.commits @result_object[:data].each do |commit|
|
||||||
json.sha commit['sha']
|
json.sha commit['sha']
|
||||||
json.author do
|
json.author do
|
||||||
|
@ -9,5 +11,6 @@ json.commits @result_object[:data].each do |commit|
|
||||||
json.partial! 'api/v1/users/commit_user', locals: { user: render_cache_commit_author(commit['commit']['committer']), name: commit['commit']['committer']['name'] }
|
json.partial! 'api/v1/users/commit_user', locals: { user: render_cache_commit_author(commit['commit']['committer']), name: commit['commit']['committer']['name'] }
|
||||||
end
|
end
|
||||||
json.commit_message commit['commit']['message']
|
json.commit_message commit['commit']['message']
|
||||||
|
json.time_from_now time_from_now(commit['created'])
|
||||||
json.parent_shas commit['parents'].map{|x|x['sha']}
|
json.parent_shas commit['parents'].map{|x|x['sha']}
|
||||||
end
|
end
|
|
@ -0,0 +1,6 @@
|
||||||
|
json.(@project_dataset, :id, :title, :description, :license_id, :paper_content)
|
||||||
|
json.license_name @project_dataset&.license&.name
|
||||||
|
json.attachment_total_count @attachments.total_count
|
||||||
|
json.attachments @attachments do |at|
|
||||||
|
json.partial! "api/v1/attachments/detail", locals: {attachment: at}
|
||||||
|
end
|
|
@ -17,6 +17,7 @@ json.projects @projects do |project|
|
||||||
json.forked_from_project_id project.forked_from_project_id
|
json.forked_from_project_id project.forked_from_project_id
|
||||||
json.open_devops project.open_devops?
|
json.open_devops project.open_devops?
|
||||||
json.platform project.platform
|
json.platform project.platform
|
||||||
|
json.has_dataset project.has_menu_permission("dataset") && project.project_dataset.present?
|
||||||
json.author do
|
json.author do
|
||||||
if project.educoder?
|
if project.educoder?
|
||||||
project_educoder = project.project_educoder
|
project_educoder = project.project_educoder
|
||||||
|
|
|
@ -36,7 +36,8 @@ json.setting do
|
||||||
|
|
||||||
json.subject_banner_url default_setting.subject_banner_url&.[](1..-1)
|
json.subject_banner_url default_setting.subject_banner_url&.[](1..-1)
|
||||||
json.course_banner_url default_setting.course_banner_url&.[](1..-1)
|
json.course_banner_url default_setting.course_banner_url&.[](1..-1)
|
||||||
json.competition_banner_url default_setting.competition_banner_url&.[](1..-1)
|
json.competition_banner_url EduSetting.get("competition_banner_url").to_s
|
||||||
|
json.competition_banner_href EduSetting.get("competition_banner_href").to_s
|
||||||
json.moop_cases_banner_url default_setting.moop_cases_banner_url&.[](1..-1)
|
json.moop_cases_banner_url default_setting.moop_cases_banner_url&.[](1..-1)
|
||||||
json.oj_banner_url default_setting.oj_banner_url&.[](1..-1)
|
json.oj_banner_url default_setting.oj_banner_url&.[](1..-1)
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,12 @@ json.user_login user&.login
|
||||||
json.image_url user.present? ? url_to_avatar(user) : ""
|
json.image_url user.present? ? url_to_avatar(user) : ""
|
||||||
json.attachments do
|
json.attachments do
|
||||||
json.array! version.try(:attachments) do |attachment|
|
json.array! version.try(:attachments) do |attachment|
|
||||||
json.partial! "attachments/attachment_simple", locals: {attachment: attachment}
|
# json.partial! "attachments/attachment_simple", locals: {attachment: attachment}
|
||||||
|
json.id attachment.id
|
||||||
|
json.title attachment.title
|
||||||
|
json.filesize number_to_human_size attachment.filesize
|
||||||
|
json.description attachment.description
|
||||||
|
json.is_pdf attachment.is_pdf?
|
||||||
|
json.url "/#{@owner.login}/#{@repository.identifier}/releases/download/#{version&.tag_name}/#{attachment.filename}"
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -19,11 +19,13 @@ Rails.application.routes.draw do
|
||||||
get 'attachments/entries/get_file', to: 'attachments#get_file'
|
get 'attachments/entries/get_file', to: 'attachments#get_file'
|
||||||
get 'attachments/download/:id', to: 'attachments#show'
|
get 'attachments/download/:id', to: 'attachments#show'
|
||||||
get 'attachments/download/:id/:filename', to: 'attachments#show'
|
get 'attachments/download/:id/:filename', to: 'attachments#show'
|
||||||
|
get ':owner/:repo/releases/download/:tag_name/:filename', to: 'version_releases#download', constraints: { repo: /[^\/]+/, tag_name: /[^\/]+/, filename: /[^\/]+/ }
|
||||||
get 'check_pr_url',to: "settings#check_url"
|
get 'check_pr_url',to: "settings#check_url"
|
||||||
|
|
||||||
# get 'auth/qq/callback', to: 'oauth/qq#create'
|
# get 'auth/qq/callback', to: 'oauth/qq#create'
|
||||||
get 'auth/failure', to: 'oauth/base#auth_failure'
|
get 'auth/failure', to: 'oauth/base#auth_failure'
|
||||||
get 'auth/cas/callback', to: 'oauth/cas#create'
|
get 'auth/cas/callback', to: 'oauth/cas#create'
|
||||||
|
get 'auth/acge/callback', to: "oauth/acge#create"
|
||||||
get 'auth/:provider/callback', to: 'oauth/callbacks#create'
|
get 'auth/:provider/callback', to: 'oauth/callbacks#create'
|
||||||
|
|
||||||
get 'oauth/bind', to: 'oauth/educoder#bind'
|
get 'oauth/bind', to: 'oauth/educoder#bind'
|
||||||
|
|
|
@ -108,6 +108,7 @@ defaults format: :json do
|
||||||
|
|
||||||
# projects文件夹下的
|
# projects文件夹下的
|
||||||
scope module: :projects do
|
scope module: :projects do
|
||||||
|
resource :dataset, only: [:create, :update, :show]
|
||||||
resources :actions, module: 'actions' do
|
resources :actions, module: 'actions' do
|
||||||
collection do
|
collection do
|
||||||
post :disable
|
post :disable
|
||||||
|
@ -174,7 +175,7 @@ defaults format: :json do
|
||||||
|
|
||||||
resources :projects, only: [:index]
|
resources :projects, only: [:index]
|
||||||
resources :project_topics, only: [:index, :create, :destroy]
|
resources :project_topics, only: [:index, :create, :destroy]
|
||||||
|
resources :project_datasets, only: [:index]
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
class CreateProjectDatasets < ActiveRecord::Migration[5.2]
|
||||||
|
def change
|
||||||
|
create_table :project_datasets do |t|
|
||||||
|
t.string :title
|
||||||
|
t.text :description
|
||||||
|
t.references :project
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,6 @@
|
||||||
|
class AddLicenseAndPaperContentToProjectDataset < ActiveRecord::Migration[5.2]
|
||||||
|
def change
|
||||||
|
add_reference :project_datasets, :license
|
||||||
|
add_column :project_datasets, :paper_content, :text
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1 @@
|
||||||
|
lvSp9mqhewuv8zRT
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,2 @@
|
||||||
|
用户名,邮箱,密码,手机号,昵称
|
||||||
|
123456789,yystopf1@163.com,9b653a7d,15386415122,何慧
|
|
Loading…
Reference in New Issue