2020-03-09 00:40:16 +08:00
class ProjectsController < ApplicationController
include ApplicationHelper
include OperateProjectAbilityAble
2020-06-29 16:05:22 +08:00
include ProjectsHelper
2021-04-29 18:35:57 +08:00
include Acceleratorable
2021-10-28 14:21:42 +08:00
before_action :require_login , except : % i [ index branches branches_slice group_type_list simple show fork_users praise_users watch_users recommend banner_recommend about menu_list ]
2021-08-31 18:00:54 +08:00
before_action :require_profile_completed , only : [ :create , :migrate ]
2021-10-27 14:20:27 +08:00
before_action :load_repository , except : % i [ index group_type_list migrate create recommend banner_recommend ]
2020-03-09 00:40:16 +08:00
before_action :authorizate_user_can_edit_project! , only : % i [ update ]
2020-07-17 18:17:51 +08:00
before_action :project_public? , only : % i [ fork_users praise_users watch_users ]
2020-03-09 00:40:16 +08:00
2021-03-17 11:52:36 +08:00
def menu_list
menu = [ ]
2022-05-05 10:00:02 +08:00
user_is_admin = current_user . admin? || @project . manager? ( current_user )
2021-03-17 11:52:36 +08:00
menu . append ( menu_hash_by_name ( " home " ) )
2021-03-28 19:56:11 +08:00
menu . append ( menu_hash_by_name ( " code " ) ) if @project . has_menu_permission ( " code " )
2021-03-17 11:52:36 +08:00
menu . append ( menu_hash_by_name ( " issues " ) ) if @project . has_menu_permission ( " issues " )
2021-12-09 15:54:21 +08:00
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?
2021-03-17 11:52:36 +08:00
menu . append ( menu_hash_by_name ( " versions " ) ) if @project . has_menu_permission ( " versions " )
2021-12-13 11:45:58 +08:00
menu . append ( menu_hash_by_name ( " wiki " ) ) if @project . has_menu_permission ( " wiki " ) && @project . forge?
2021-12-09 15:54:21 +08:00
menu . append ( menu_hash_by_name ( " resources " ) ) if @project . has_menu_permission ( " resources " ) && @project . forge?
2021-03-17 11:52:36 +08:00
menu . append ( menu_hash_by_name ( " activity " ) )
2022-05-05 10:00:02 +08:00
menu . append ( menu_hash_by_name ( " settings " ) ) if user_is_admin && @project . forge?
menu . append ( menu_hash_by_name ( " quit " ) ) if ! user_is_admin && @project . member ( current_user . id ) && @project . forge?
2021-03-28 19:56:11 +08:00
2021-03-17 11:52:36 +08:00
render json : menu
end
2020-03-09 00:40:16 +08:00
def index
2022-09-14 09:19:11 +08:00
scope = current_user . logged? ? Projects :: ListQuery . call ( params . merge ( exclude_forked : " true " ) , current_user . id ) : Projects :: ListQuery . call ( params . merge ( exclude_forked : " true " ) )
recommend_scope = current_user . logged? ? Projects :: ListQuery . call ( params . merge ( recommend : " true " ) , current_user . id ) : Projects :: ListQuery . call ( params . merge ( recommend : " true " ) )
forked_scope = current_user . logged? ? Projects :: ListQuery . call ( params . merge ( exclude_forked : " false " ) , current_user . id ) : Projects :: ListQuery . call ( params . merge ( exclude_forked : " false " ) )
2022-09-14 09:23:22 +08:00
scope = Project . from ( " ( select * from ( #{ recommend_scope . reorder ( " recommend_index desc " ) . to_sql } limit 10000000 ) as t1 UNION select * from ( #{ scope . to_sql } limit 10000000 ) as t2 UNION select * from ( #{ forked_scope . to_sql } limit 10000000 ) as t3 ) AS projects " )
2021-10-27 14:20:27 +08:00
@projects = kaminari_paginate ( scope . includes ( :project_category , :project_language , :repository , :project_educoder , :owner , :project_units ) )
# @projects = paginate scope.includes(:project_category, :project_language, :repository, :project_educoder, :owner, :project_units)
2022-09-14 09:23:22 +08:00
# @rand_projects = params[:page].to_i == 1 ? ([Project.find_by(id: 477)] | @projects) - [nil] : @projects
2022-09-14 09:24:14 +08:00
@rand_projects = @projects
2020-10-23 00:07:26 +08:00
category_id = params [ :category_id ]
2021-01-28 14:45:33 +08:00
@total_count = @projects . total_count
2020-10-23 00:07:26 +08:00
if category_id . blank?
2022-11-08 17:18:04 +08:00
# ps = ProjectStatistic.first
# ps.common_projects_count + ps.mirror_projects_count unless ps.blank?
@projects . total_count
2020-10-23 00:07:26 +08:00
else
cate = ProjectCategory . find_by ( id : category_id )
cate & . projects_count || 0
end
2020-03-09 00:40:16 +08:00
end
def create
ActiveRecord :: Base . transaction do
Projects :: CreateForm . new ( project_params ) . validate!
@project = Projects :: CreateService . new ( current_user , project_params ) . call
2020-05-18 18:25:01 +08:00
2020-03-09 00:40:16 +08:00
end
rescue Exception = > e
uid_logger_error ( e . message )
tip_exception ( e . message )
end
def migrate
2020-06-23 11:57:24 +08:00
Projects :: MigrateForm . new ( mirror_params ) . validate!
2021-04-29 18:35:57 +08:00
@project =
2022-02-14 16:53:29 +08:00
if EduSetting . get ( " mirror_address " ) . to_s . include? ( " github " ) && enable_accelerator? ( mirror_params [ :clone_addr ] )
2021-04-29 18:35:57 +08:00
source_clone_url = mirror_params [ :clone_addr ]
2022-02-11 16:27:22 +08:00
uid_logger ( " # # # # # # # # # # 已动加速器 # # # # # # # # # # " )
result = Gitea :: Accelerator :: MigrateService . call ( mirror_params )
if result [ :status ] == :success
Rails . logger . info " # # # # # # # # # # 加速镜像成功 # # # # # # # # # # "
Projects :: MigrateService . call ( current_user ,
mirror_params . merge ( source_clone_url : source_clone_url ,
clone_addr : accelerator_url ( mirror_params [ :repository_name ] ) ) )
else
Projects :: MigrateService . call ( current_user , mirror_params )
end
2022-02-14 16:53:29 +08:00
elsif EduSetting . get ( " mirror_address " ) . to_s . include? ( " cnpmjs " ) && mirror_params [ :clone_addr ] . include? ( " github.com " )
2021-04-29 18:35:57 +08:00
source_clone_url = mirror_params [ :clone_addr ]
2022-01-11 10:48:29 +08:00
clone_url = source_clone_url . gsub ( 'github.com' , 'github.com.cnpmjs.org' )
uid_logger ( " # # # # # # # # # # 更改clone_addr # # # # # # # # # # " )
Projects :: MigrateService . call ( current_user , mirror_params . merge ( source_clone_url : source_clone_url , clone_addr : clone_url ) )
2021-04-29 18:35:57 +08:00
else
Projects :: MigrateService . call ( current_user , mirror_params )
end
2020-03-09 00:40:16 +08:00
rescue Exception = > e
uid_logger_error ( e . message )
tip_exception ( e . message )
end
def branches
2021-03-28 19:56:11 +08:00
return @branches = [ ] unless @project . forge?
2022-01-07 15:41:50 +08:00
# result = Gitea::Repository::Branches::ListService.call(@owner, @project.identifier)
2022-04-26 17:15:59 +08:00
result = Gitea :: Repository :: Branches :: ListNameService . call ( @owner , @project . identifier , params [ :name ] )
2022-01-07 15:41:50 +08:00
@branches = result . is_a? ( Hash ) ? ( result . key? ( :status ) ? [ ] : result [ " branch_name " ] ) : result
2020-03-09 00:40:16 +08:00
end
2021-09-07 18:39:11 +08:00
def branches_slice
return @branches = [ ] unless @project . forge?
slice_result = Gitea :: Repository :: Branches :: ListSliceService . call ( @owner , @project . identifier )
@branches_slice = slice_result . is_a? ( Hash ) && slice_result . key? ( :status ) ? [ ] : slice_result
2020-03-09 00:40:16 +08:00
end
def group_type_list
2020-04-22 10:00:47 +08:00
# if current_user&.logged?
2020-04-03 17:00:58 +08:00
# projects = Project.list_user_projects(current_user.id)
# else
# projects = Project.visible
# end
2020-12-25 16:17:46 +08:00
projects = Project . no_anomory_projects . secret_and_visible
2020-09-11 18:32:42 +08:00
language_lists = projects . joins ( :project_language ) . group ( " project_languages.name " , " project_languages.id " ) . size . keys . sort . to_h
@project_group_list = language_lists . delete_if { | k , v | k . blank? }
2020-03-09 00:40:16 +08:00
end
def update
ActiveRecord :: Base . transaction do
2021-05-15 10:19:25 +08:00
# TODO:
# 临时特殊处理修改website、lesson_url操作方法
2021-08-03 14:14:06 +08:00
if project_params . has_key? ( " website " )
2021-05-15 10:19:25 +08:00
@project . update ( project_params )
2021-08-03 14:14:06 +08:00
elsif project_params . has_key? ( " default_branch " )
@project . update ( project_params )
gitea_params = {
default_branch : @project . default_branch
}
2020-11-19 10:30:18 +08:00
Gitea :: Repository :: UpdateService . call ( @owner , @project . identifier , gitea_params )
2021-05-15 10:19:25 +08:00
else
validate_params = project_params . slice ( :name , :description ,
2021-10-14 14:25:00 +08:00
:project_category_id , :project_language_id , :private , :identifier )
2021-05-15 10:19:25 +08:00
2022-03-07 10:25:05 +08:00
Projects :: UpdateForm . new ( validate_params . merge ( user_id : @project . user_id , project_identifier : @project . identifier , project_name : @project . name ) ) . validate!
2021-05-15 10:19:25 +08:00
2021-06-29 17:36:15 +08:00
private = @project . forked_from_project . present? ? ! @project . forked_from_project . is_public : params [ :private ] || false
2021-05-15 10:19:25 +08:00
new_project_params = project_params . except ( :private ) . merge ( is_public : ! private )
@project . update_attributes! ( new_project_params )
2021-06-29 18:05:37 +08:00
@project . forked_projects . update_all ( is_public : @project . is_public )
2021-05-15 10:19:25 +08:00
gitea_params = {
private : private ,
default_branch : @project . default_branch ,
2021-10-12 17:08:25 +08:00
website : @project . website ,
name : @project . identifier
2021-05-15 10:19:25 +08:00
}
2021-10-12 17:15:50 +08:00
gitea_repo = Gitea :: Repository :: UpdateService . call ( @owner , @project & . repository & . identifier , gitea_params )
@project . repository . update_attributes ( { hidden : gitea_repo [ " private " ] , identifier : gitea_repo [ " name " ] } )
2022-11-15 14:25:35 +08:00
# 更新对应所属分类下的项目数量(私有)
before_is_public = @project . previous_changes [ :is_public ] . present? ? @project . previous_changes [ :is_public ] [ 0 ] : @project . is_public
after_is_public = @project . previous_changes [ :is_public ] . present? ? @project . previous_changes [ :is_public ] [ 1 ] : @project . is_public
before_pc_id = @project . previous_changes [ :project_category_id ] . present? ? @project . previous_changes [ :project_category_id ] [ 0 ] : @project . project_category_id
after_pc_id = @project . previous_changes [ :project_category_id ] . present? ? @project . previous_changes [ :project_category_id ] [ 1 ] : @project . project_category_id
before_pc = ProjectCategory . find_by_id ( before_pc_id )
after_pc = ProjectCategory . find_by_id ( after_pc_id )
before_pc . decrement! ( :private_projects_count , 1 ) if before_pc . present? && ! before_is_public
after_pc . increment! ( :private_projects_count , 1 ) if after_pc . present? && ! after_is_public
2020-03-09 00:40:16 +08:00
end
2021-10-21 11:23:12 +08:00
SendTemplateMessageJob . perform_later ( 'ProjectSettingChanged' , current_user . id , @project & . id , @project . previous_changes . slice ( :name , :description , :project_category_id , :project_language_id , :is_public , :identifier ) ) if Site . has_notice_menu?
2020-03-09 00:40:16 +08:00
end
rescue Exception = > e
uid_logger_error ( e . message )
tip_exception ( e . message )
end
def show
end
def destroy
2021-03-30 17:27:50 +08:00
if current_user . admin? || @project . manager? ( current_user )
2020-03-09 00:40:16 +08:00
ActiveRecord :: Base . transaction do
Gitea :: Repository :: DeleteService . new ( @project . owner , @project . identifier ) . call
@project . destroy!
2021-06-29 18:05:37 +08:00
@project . forked_projects . update_all ( forked_from_project_id : nil )
2022-11-15 14:25:35 +08:00
# 如果该项目有所属的项目分类以及为私有项目,需要更新对应数量
@project . project_category . decrement! ( :private_projects_count , 1 ) if @project . project_category . present? && ! @project . is_public
2020-03-09 00:40:16 +08:00
render_ok
end
else
render_forbidden ( '你没有权限操作' )
end
rescue Exception = > e
uid_logger_error ( e . message )
tip_exception ( e . message )
2020-05-07 18:27:19 +08:00
end
2020-03-09 00:40:16 +08:00
2022-05-05 10:00:02 +08:00
def quit
user_is_admin = current_user . admin? || @project . manager? ( current_user )
if ! user_is_admin && @project . member ( current_user . id ) && @project . forge?
ActiveRecord :: Base . transaction do
Projects :: DeleteMemberInteractor . call ( @project . owner , @project , current_user )
SendTemplateMessageJob . perform_later ( 'ProjectMemberLeft' , current_user . id , current_user . id , @project . id ) if Site . has_notice_menu?
render_ok
end
else
render_forbidden ( '你不能退出该仓库' )
end
rescue Exception = > e
uid_logger_error ( e . message )
tip_exception ( e . message )
end
2020-05-15 17:05:53 +08:00
def watch_users
2020-06-08 09:55:54 +08:00
watchers = @project . watchers . includes ( :user ) . order ( " watchers.created_at desc " ) . distinct
2020-05-18 12:06:00 +08:00
@watchers_count = watchers . size
2020-05-15 17:05:53 +08:00
@watchers = paginate ( watchers )
end
2020-05-15 17:31:53 +08:00
def praise_users
2020-06-08 09:55:54 +08:00
praises = @project . praise_treads . includes ( :user ) . order ( " praise_treads.created_at desc " ) . distinct
2020-05-18 12:06:00 +08:00
@praises_count = praises . size
2020-05-15 17:05:53 +08:00
@praises = paginate ( praises )
end
2020-06-03 11:18:46 +08:00
def fork_users
2022-05-07 11:57:58 +08:00
fork_users = @project . fork_users . includes ( :owner , :project , :fork_project ) . order ( " fork_users.created_at desc " ) . distinct
2020-05-18 12:06:00 +08:00
@forks_count = fork_users . size
2020-05-15 17:05:53 +08:00
@fork_users = paginate ( fork_users )
end
2020-06-29 16:05:22 +08:00
def simple
2021-10-26 15:22:42 +08:00
# 为了缓存活跃项目的基本信息,后续删除
2021-11-01 16:20:52 +08:00
Cache :: V2 :: ProjectCommonService . new ( @project . id ) . read
2020-09-08 15:29:19 +08:00
json_response ( @project , current_user )
2020-06-29 16:05:22 +08:00
end
2020-10-04 12:01:26 +08:00
def recommend
2021-06-04 11:33:21 +08:00
@projects = Project . recommend . includes ( :repository , :project_category , :owner ) . order ( visits : :desc )
2020-10-04 12:01:26 +08:00
end
2021-10-27 14:20:27 +08:00
def banner_recommend
@projects = Project . recommend . where . not ( recommend_index : 0 ) . includes ( :project_category , :owner , :project_language ) . order ( recommend_index : :desc )
2020-10-04 12:01:26 +08:00
end
2020-10-04 17:32:37 +08:00
def about
@project_detail = @project . project_detail
@attachments = Array ( @project_detail & . attachments ) if request . get?
ActiveRecord :: Base . transaction do
if request . post?
2020-10-09 11:40:20 +08:00
require_login
2020-10-04 17:32:37 +08:00
authorizate_user_can_edit_project!
unless @project_detail . present?
@project_detail = ProjectDetail . new (
content : params [ :content ] ,
project_id : @project . id )
else
@project_detail . content = params [ :content ]
end
if @project_detail . save!
attachment_ids = Array ( params [ :attachment_ids ] )
2020-10-05 17:41:28 +08:00
@attachments = Attachment . where ( id : attachment_ids )
2020-10-04 17:32:37 +08:00
@attachments . update_all (
container_id : @project_detail . id ,
container_type : @project_detail . model_name . name ,
author_id : current_user . id ,
description : " " )
end
end
end
2020-06-29 16:05:22 +08:00
end
2020-08-12 10:38:45 +08:00
2020-03-09 00:40:16 +08:00
private
def project_params
2021-10-12 16:41:01 +08:00
params . permit ( :user_id , :name , :description , :repository_name , :website , :lesson_url , :default_branch , :identifier ,
2020-12-28 12:31:05 +08:00
:project_category_id , :project_language_id , :license_id , :ignore_id , :private )
2020-03-09 00:40:16 +08:00
end
def mirror_params
2020-05-18 18:25:01 +08:00
params . permit ( :user_id , :name , :description , :repository_name , :is_mirror , :auth_username ,
:auth_password , :project_category_id , :project_language_id , :clone_addr , :private )
2020-03-09 00:40:16 +08:00
end
2020-05-15 17:05:53 +08:00
2020-06-03 11:18:46 +08:00
def project_public?
2020-08-12 10:58:16 +08:00
return if @project . is_public?
2020-07-17 18:17:51 +08:00
if current_user
return if current_user . admin? || @project . member? ( current_user . id )
render_forbidden ( '你没有权限访问.' )
else
render_unauthorized ( '你还未登录.' )
2020-05-15 17:05:53 +08:00
end
end
2020-03-09 00:40:16 +08:00
end