diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 843be8bbb..57b9e45ef 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -328,7 +328,7 @@ class ApplicationController < ActionController::Base def current_user # User.current - User.find_by_id 36390 + User.find_by_id 36401 end ## 默认输出json @@ -629,12 +629,12 @@ class ApplicationController < ActionController::Base def find_user @user = User.find_by_login params[:login] - render_not_found unless @user + render_not_found("未找到’#{params[:login]}’相关的用户") unless @user end def find_repository @repo = @user.repositories.find_by_identifier params[:repo_identifier] - render_not_found unless @repo + render_not_found("未找到’#{params[:repo_identifier]}’相关的项目") unless @repo end private diff --git a/app/controllers/contents_controller.rb b/app/controllers/contents_controller.rb index 151470524..411747f45 100644 --- a/app/controllers/contents_controller.rb +++ b/app/controllers/contents_controller.rb @@ -1,26 +1,32 @@ class ContentsController < ApplicationController before_action :find_user, :find_repository - before_action :require_login, only: %i[create] + before_action :require_login, only: %i[create update_file delete_file] def create - # request_params = {user: @user, repo_name: @repo.identifier, filepath: params[:filepath]} - logger.info "current_user ----> #{current_user.login}" - @user = current_user - interactor = Gitea::CreateFileInteractor.call(@user, content_params) + interactor = Gitea::CreateFileInteractor.call(current_user, content_params) if interactor.success? @file = interactor.result - logger.info "@file ========> #{@file}" else render_error(interactor.error) end end def update_file - + interactor = Gitea::UpdateFileInteractor.call(current_user, params) + if interactor.success? + @file = interactor.result + else + render_error(interactor.error) + end end def delete_file - + interactor = Gitea::DeleteFileInteractor.call(current_user, params) + if interactor.success? + @file = interactor.result + else + render_error(interactor.error) + end end private diff --git a/app/forms/contents/delete_form.rb b/app/forms/contents/delete_form.rb new file mode 100644 index 000000000..f3f060ab6 --- /dev/null +++ b/app/forms/contents/delete_form.rb @@ -0,0 +1,6 @@ +class Contents::DeleteForm < BaseForm + attr_accessor :login, :repo_identifier, :filepath, :branch, :new_branch, :sha + + validates :login, :repo_identifier, :filepath, :sha, presence: true + +end diff --git a/app/forms/contents/update_form.rb b/app/forms/contents/update_form.rb new file mode 100644 index 000000000..f5b4a2480 --- /dev/null +++ b/app/forms/contents/update_form.rb @@ -0,0 +1,13 @@ +class Contents::UpdateForm < BaseForm + attr_accessor :login, :repo_identifier, :filepath, :branch, :new_branch, :sha + + validates :login, :repo_identifier, :filepath, :sha, presence: true + + validate :check_branch + + def check_branch + raise "branch和new_branch必须存在一个 " if branch.blank? && new_branch.blank? + raise "branch和new_branch只能存在一个" if !branch.blank? && !new_branch.blank? + end + +end diff --git a/app/interactors/gitea/delete_file_interactor.rb b/app/interactors/gitea/delete_file_interactor.rb new file mode 100644 index 000000000..255ce6d97 --- /dev/null +++ b/app/interactors/gitea/delete_file_interactor.rb @@ -0,0 +1,65 @@ +module Gitea + class DeleteFileInteractor + def self.call(user, params={}) + interactor = new(user, params) + interactor.run + interactor + end + + attr_reader :error, :result + + def initialize(user, params) + @user = user + @params = params + end + + def success? + @error.nil? + end + + def result + @result + end + + def run + Contents::DeleteForm.new(valid_params).validate! + response = Gitea::Repository::Entries::DeleteService.new(user, @params[:repo_identifier], @params[:filepath], file_params).call + render_result(response) + rescue Exception => exception + fail!(exception.message) + end + + private + + attr_reader :params, :user + + def fail!(error) + puts "[exception]: error" + @error = error + end + + def render_result(response) + if response.status == 200 + @result = JSON.parse(response.body) + end + end + + def valid_params + { + login: @params[:login], + repo_identifier: @params[:repo_identifier], + filepath: @params[:filepath], + sha: @params[:sha] + } + end + + def file_params + Hash.new.merge( + branch: @params[:branch], + sha: @params[:sha], + new_branch: @params[:new_branch], + message: @params[:message], + ).compact + end + end +end diff --git a/app/interactors/gitea/update_file_interactor.rb b/app/interactors/gitea/update_file_interactor.rb new file mode 100644 index 000000000..814bc0cc7 --- /dev/null +++ b/app/interactors/gitea/update_file_interactor.rb @@ -0,0 +1,69 @@ +module Gitea + class UpdateFileInteractor + def self.call(user, params={}) + interactor = new(user, params) + interactor.run + interactor + end + + attr_reader :error, :result + + def initialize(user, params) + @user = user + @params = params + end + + def success? + @error.nil? + end + + def result + @result + end + + def run + Contents::UpdateForm.new(valid_params).validate! + response = Gitea::Repository::Entries::UpdateService.new(user, @params[:repo_identifier], @params[:filepath], file_params).call + render_result(response) + rescue Exception => exception + fail!(exception.message) + end + + private + + attr_reader :params, :user + + def fail!(error) + puts "[exception]: error" + @error = error + end + + def render_result(response) + if response.status == 200 + @result = JSON.parse(response.body) + end + end + + def valid_params + { + login: @params[:login], + repo_identifier: @params[:repo_identifier], + filepath: @params[:filepath], + branch: @params[:branch], + new_branch: @params[:new_branch], + sha: @params[:sha] + } + end + + def file_params + Hash.new.merge( + branch: @params[:branch], + sha: @params[:sha], + new_branch: @params[:new_branch], + from_path: @params[:from_path], + message: @params[:message], + content: Base64.encode64(@params[:content]) + ).compact + end + end +end diff --git a/app/services/gitea/api_service.rb b/app/services/gitea/api_service.rb deleted file mode 100644 index a849ae6c5..000000000 --- a/app/services/gitea/api_service.rb +++ /dev/null @@ -1,32 +0,0 @@ -class Gitea::APIService < ApplicationService - - def self.render_status(response) - mark = " --from gitea platform." - case response.status - when 201 - JSON.parse(response&.body) - when 401 - raise Error, "401 Unauthorized from gitea #{mark}" - when 403, 422 - body = JSON.parse(response&.body) - raise Error, body['message'] + mark - else - false - end - end - - def self.base_url - Gitea.gitea_config[:base_url] - end - - def self.domain - Gitea.gitea_config[:domain] - end - - private - - def logger - Rails.logger - end - -end diff --git a/app/services/gitea/client_service.rb b/app/services/gitea/client_service.rb index c5d7f8dfd..767754bf7 100644 --- a/app/services/gitea/client_service.rb +++ b/app/services/gitea/client_service.rb @@ -61,6 +61,14 @@ class Gitea::ClientService < ApplicationService render_status(response) end + def put(url, params={}) + puts "[gitea] put request params: #{params}" + conn(authen_params(params[:token])).put do |req| + req.url full_url(url) + req.body = params[:data].to_json + end + end + private def conn(auth={}) username = auth[:username] || access_key_id diff --git a/app/services/gitea/repository/entries/delete_service.rb b/app/services/gitea/repository/entries/delete_service.rb new file mode 100644 index 000000000..cfc79a5b6 --- /dev/null +++ b/app/services/gitea/repository/entries/delete_service.rb @@ -0,0 +1,42 @@ +class Gitea::Repository::Entries::DeleteService < Gitea::ClientService + attr_reader :user, :repo_name, :filepath, :body + + # ref: The name of the commit/branch/tag. Default the repository’s default branch (usually master) + # filepath: path of the dir, file, symlink or submodule in the repo + # repo_name: the name of repository + # body: + # { + # "author": { + # "email": "user@example.com", + # "name": "string" + # }, + # "branch": "string", + # "committer": { + # "email": "user@example.com", + # "name": "string" + # }, + # "message": "string", + # "new_branch": "string", + # "sha": "string", #require + # } + def initialize(user, repo_name, filepath, body) + @user = user + @repo_name = repo_name + @filepath = filepath + @body = body + end + + def call + delete(url, params) + end + + private + def params + Hash.new.merge(token: user.gitea_token, data: body) + end + + def url + "/repos/#{user.login}/#{repo_name}/contents/#{filepath}".freeze + end + +end diff --git a/app/services/gitea/repository/entries/update_service.rb b/app/services/gitea/repository/entries/update_service.rb new file mode 100644 index 000000000..3f0ddf944 --- /dev/null +++ b/app/services/gitea/repository/entries/update_service.rb @@ -0,0 +1,43 @@ +class Gitea::Repository::Entries::UpdateService < Gitea::ClientService + attr_reader :user, :repo_name, :filepath, :body + + # ref: The name of the commit/branch/tag. Default the repository’s default branch (usually master) + # filepath: path of the dir, file, symlink or submodule in the repo + # repo_name: the name of repository + # body: + # { + # "author": { + # "email": "user@example.com", + # "name": "string" + # }, + # "branch": "string", + # "committer": { + # "email": "user@example.com", + # "name": "string" + # }, + # "content": "string", # content must be base64 encoded + # "message": "string", + # "new_branch": "string" + # } + # + def initialize(user, repo_name, filepath, body) + @user = user + @repo_name = repo_name + @filepath = filepath + @body = body + end + + def call + put(url, params) + end + + private + def params + Hash.new.merge(token: user.gitea_token, data: body) + end + + def url + "/repos/#{user.login}/#{repo_name}/contents/#{filepath}".freeze + end + +end diff --git a/app/views/contents/delete_file.json.jbuilder b/app/views/contents/delete_file.json.jbuilder new file mode 100644 index 000000000..988dd201c --- /dev/null +++ b/app/views/contents/delete_file.json.jbuilder @@ -0,0 +1,6 @@ +json.commit do + json.sha @file['commit']['sha'] + json.message @file['commit']['message'] + json.author @file['commit']['author'] + json.committer @file['commit']['committer'] +end diff --git a/app/views/contents/update_file.json.jbuilder b/app/views/contents/update_file.json.jbuilder new file mode 100644 index 000000000..3c842dcce --- /dev/null +++ b/app/views/contents/update_file.json.jbuilder @@ -0,0 +1,10 @@ +json.name @file['content']['name'] +json.sha @file['content']['sha'] +json.size @file['content']['size'] +json.content @file['content']['content'] +json.encoding @file['content']['encoding'] +json.commit do + json.message @file['commit']['message'] + json.author @file['commit']['author'] + json.committer @file['commit']['committer'] +end diff --git a/config/routes.rb b/config/routes.rb index fbaae68ac..7926ff9a9 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -78,7 +78,7 @@ Rails.application.routes.draw do resources :repositories, path: '/:login/:repo_identifier', only: [:index] do collection do get :entries - get :sub_entries + match :sub_entries, :via => [:get, :put] get :commits get :single_commit post :files @@ -419,266 +419,6 @@ Rails.application.routes.draw do end end - resources :courses do - member do - get 'settings', :action => 'settings', :as => 'settings' - post 'set_invite_code_halt' - post 'set_public_or_private' - post 'search_teacher_candidate' - post 'add_teacher' - post 'create_graduation_group' - post 'join_graduation_group' - post 'set_course_group' - post 'change_course_admin' - post 'change_member_role' - post 'change_course_teacher' - post 'delete_course_teacher' - post 'teacher_application_review' - post 'transfer_to_course_group' - post 'delete_from_course' - post 'add_students_by_search' - post 'create_group_by_importing_file' - post 'duplicate_course' - post 'visits_plus_one' - get 'get_historical_courses' - get 'get_historical_course_students' - get 'course_group_list' - get 'add_teacher_popup' - get 'teachers' - get 'apply_teachers' - get 'graduation_group_list' - get 'top_banner' - get 'left_banner' - get 'students' - get 'all_course_groups' - get 'search_users' - get 'base_info' - get 'attahcment_category_list' - get 'export_member_scores_excel' #导出课堂信息 - get 'export_couser_info' - get 'export_member_act_score' - post 'switch_to_teacher' - post 'switch_to_assistant' - post 'switch_to_student' - post 'exit_course' - get 'informs' - post 'update_informs' - post 'new_informs' - delete 'delete_informs' - get 'online_learning' - post 'join_excellent_course' - get 'tasks_list' - post 'update_task_position' - get 'course_groups' - post 'join_course_group' - get 'work_score' - get 'act_score' - get 'statistics' - post :inform_up - post :inform_down - get :calculate_all_shixun_scores - end - - collection do - post 'apply_to_join_course' - post 'search_course_list' - get 'board_list' - get 'mine' - get 'search_slim' - end - - resources :course_stages, shallow: true do - member do - post :up_position - post :down_position - end - end - - resources :polls, only:[:index,:new,:create] do - collection do - post :publish # 立即发布 - post :end_poll # 立即截止 - post :destroys # 多个删除 - post :set_public # 设置公开 - post :join_poll_banks # 加入习题集 - get :my_polls #我的问卷题库 - get :public_polls # 公共问卷题库 - get :publish_modal # 立即发布弹窗内容 - get :end_poll_modal # 立即截止弹窗内容 - end - end - - resources :homework_commons, shallow: true do - - member do - get :group_list - post :homework_code_repeat - get :code_review_results - get :code_review_detail - post :update_explanation - get :show_comment - get :settings - post :update_settings - match 'works_list', :via => [:get, :post] - # post :works_list - get :reference_answer - get :publish_groups - get :end_groups - post :alter_name - get :update_score - get :update_student_score - end - - collection do - post 'create_shixun_homework' - match 'shixuns', via: [:get, :post] - match 'subjects', via: [:get, :post] - post 'create_subject_homework' - post 'publish_homework' - post 'end_homework' - post 'set_public' - post 'move_to_category' - get 'choose_category' - post 'multi_destroy' - post 'add_to_homework_bank' - end - - resources :student_works do - member do - get :shixun_work - get :shixun_work_report - post :adjust_review_score - get :commit_des - post :update_des - post :adjust_score - post :add_score - post :add_score_reply - delete :destroy_score - delete :destroy_score_reply - get :comment_list - get :supply_attachments - post :revise_attachment - delete :destroy_score - post :appeal_anonymous_score - post :deal_appeal_score - post :cancel_appeal - get :export_shixun_work_report - post :shixun_work_comment - delete :destroy_work_comment - end - - collection do - get :search_member_list - get :check_project - get :cancel_relate_project - post :relate_project - delete :delete_work - end - end - end - - - resources :boards, shallow: true do - resources :messages do - collection do - delete :bulk_delete - put :bulk_move - post :bulk_send - put :bulk_public - end - - member do - get :reply_list - put :sticky_top - post :reply - end - end - member do - post 'move_category' - end - end - - resources :exercises ,only:[:index,:new,:create] do - collection do - get :my_exercises #我的试卷题库 - get :public_exercises # 公共试卷题库 - get :publish_modal # 立即发布弹窗内容 - get :end_modal # 立即截止弹窗内容 - post :destroys - post :set_public # 设置公开 - post :join_exercise_banks # 加入习题集 - post :publish # 立即发布 - post :end_exercise # 立即截止 - end - end - - resources :course_groups, shallow: true do - member do - post 'rename_group' - post 'move_category' - end - - collection do - end - end - - resources :graduation_topics do - member do - post :refuse_student_topic - post :accept_student_topic - post :student_select_topic - post :student_cancel_topic - get :show_detail - get :show_comment - end - collection do - delete :destroys - post :set_public - get :export - post :add_to_bank - end - end - - resources :graduation_tasks, shallow: true do - resources :graduation_works do - collection do - post 'search_member_list' - get 'check_project' - post 'relate_project' - get 'cancel_relate_project' - post 'revise_attachment' - delete 'delete_work' - end - - member do - get 'comment_list' - post 'add_score' - post 'adjust_score' - delete 'delete_score' - get 'supply_attachments' - post 'revise_attachment' - post :assign_teacher - end - end - member do - get 'settings' - post 'update_settings' - get 'tasks_list' - get :show_comment - get :cross_comment_setting - post :assign_works - post :commit_comment_setting - end - - collection do - post 'set_public' - delete 'multi_destroy' - post 'publish_task' - post 'end_task' - post 'add_to_bank' - end - end - end resources :polls,except:[:index,:new,:create] do member do