| @@ -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,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 | |||||
| @@ -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}" | ||||
| @@ -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)) | ||||
| @@ -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 | ||||
| @@ -9,7 +9,7 @@ module CustomRegexp | |||||
| URL = /\Ahttps?:\/\/[-A-Za-z0-9+&@#\/%?=~_|!:,.;]+[-A-Za-z0-9+&@#\/%=~_|]\z/ | URL = /\Ahttps?:\/\/[-A-Za-z0-9+&@#\/%?=~_|!:,.;]+[-A-Za-z0-9+&@#\/%=~_|]\z/ | ||||
| IP = /^((\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.){3}(\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])$/ | IP = /^((\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.){3}(\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])$/ | ||||
| URL_REGEX = /\A(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?\z/i | |||||
| URL_REGEX = /\A(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?\z/i | |||||
| # REPOSITORY_NAME_REGEX = /^[a-zA-Z0-9][a-zA-Z0-9\-\_\.]+[a-zA-Z0-9]$/ #只含有数字、字母、下划线不能以下划线开头和结尾 | # REPOSITORY_NAME_REGEX = /^[a-zA-Z0-9][a-zA-Z0-9\-\_\.]+[a-zA-Z0-9]$/ #只含有数字、字母、下划线不能以下划线开头和结尾 | ||||
| REPOSITORY_NAME_REGEX = /^[a-zA-Z0-9\-\_\.]+[a-zA-Z0-9]$/ #只含有数字、字母、下划线不能以下划线开头和结尾 | REPOSITORY_NAME_REGEX = /^[a-zA-Z0-9\-\_\.]+[a-zA-Z0-9]$/ #只含有数字、字母、下划线不能以下划线开头和结尾 | ||||
| MD_REGEX = /^.+(\.[m|M][d|D])$/ | MD_REGEX = /^.+(\.[m|M][d|D])$/ | ||||
| @@ -137,6 +137,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} | ||||
| @@ -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,7 +1,8 @@ | |||||
| 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 attachment.is_pdf? ? download_url(attachment,disposition:"inline") : download_url(attachment) | 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") | |||||
| json.created_on attachment.created_on.strftime("%Y-%m-%d %H:%M:%S") | |||||
| json.content_type attachment.content_type | json.content_type attachment.content_type | ||||
| @@ -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 | |||||
| @@ -78,6 +78,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 | ||||
| @@ -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 | |||||