Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
class ApplicationController < ActionController::API
include ActionController::HttpAuthentication::Token::ControllerMethods
include Pagy::Method

before_action :authenticate!

Expand Down
32 changes: 32 additions & 0 deletions app/controllers/submission_requests_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
class SubmissionRequestsController < ApplicationController
def index
requests = current_user.submission_requests.includes(
:submission,
validation_with_validity: :details,
)

pagy, @requests = pagy(requests.order(id: :desc))

response.headers.merge! pagy.headers_hash
end

def show
@request = current_user.submission_requests.find(params[:id])
end

def create
@request = current_user.submission_requests.create!(request_params)

ValidateDDBJRecordJob.perform_later @request

render :show, status: :accepted
end

private

def request_params
params.expect(submission_request: [
:ddbj_record
])
end
end
23 changes: 23 additions & 0 deletions app/controllers/submission_updates_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
class SubmissionUpdatesController < ApplicationController
def show
@update = current_user.submission_updates.find(params[:id])
end

def create
submission = current_user.submissions.find(params[:submission_id])

@update = submission.updates.create!(update_params)

ValidateDDBJRecordJob.perform_later @update

render :show, status: :accepted
end

private

def update_params
params.expect(submission_update: [
:ddbj_record
])
end
end
74 changes: 25 additions & 49 deletions app/controllers/submissions_controller.rb
Original file line number Diff line number Diff line change
@@ -1,65 +1,41 @@
class SubmissionsController < ApplicationController
include Pagy::Method

def index
submissions = search_submissions.order(id: :desc)

pagy, @submissions = pagy(submissions, page: params[:page])

response.headers.merge! pagy.headers_hash
rescue Pagy::OverflowError => e
render json: {
error: e.message
}, status: :bad_request
@submissions = current_user.submissions
end

def show
@submission = user_submissions.includes(accessions: :renewals).find(params.expect(:id))
@submission = current_user.submissions.includes(
:updates
).order(
'submission_updates.id DESC'
).find(params.expect(:id))
end

def create
validation = current_user.validations.find(params.require(:validation_id))
param = Database::MAPPING.fetch(validation.db).build_param(params)
@submission = Submission.create!(**submission_params, param:)

SubmitJob.perform_later @submission

render :show, status: :created
end
request = current_user.submission_requests.valid_only.joins(
:validation
).where(
validations: {
finished_at: 1.day.ago..
}
).find(params[:submission_request_id])

private
ApplySubmissionRequestJob.perform_later request

def submission_params
params.permit(:validation_id, :visibility)
head :accepted
end

def user_submissions
current_user.submissions.includes(
validation: [
:user,

objs: [
:file_blob,
:validation_details
]
]
)
end

def search_submissions
db, created_at_after, created_at_before, result = params.values_at(
:db,
:created_at_after,
:created_at_before,
:result
).map(&:presence)

submissions = user_submissions
def update
update = current_user.submission_updates.valid_only.joins(
:validation
).where(
validations: {
finished_at: 1.day.ago..
}
).find(params[:submission_update_id])

submissions = submissions.where(validations: {db: db.split(',')}) if db
submissions = submissions.where(created_at: created_at_after..created_at_before) if created_at_after || created_at_before
submissions = submissions.where(result: result.split(',')) if result
ApplySubmissionUpdateJob.perform_later update

submissions
head :accepted
end
end
73 changes: 73 additions & 0 deletions app/jobs/apply_submission_request_job.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
class ApplySubmissionRequestJob < ApplicationJob
def perform(request)
return unless request.ready_to_apply?

ActiveRecord::Base.transaction do
request.applying!
request.create_submission!
end

begin
apply request
rescue => e
Rails.error.report e

request.update!(
status: :submission_failed,
error_message: e.message
)
else
request.applied!
request.validation.write_submission_files to: request.submission.dir
end
end

private

def apply(request)
record = JSON.parse(request.ddbj_record.download, symbolize_names: true)
entries = record.dig(:sequence, :entries)

aa_count, na_count = entries.partition { aa?(it) }.map(&:size)

ActiveRecord::Base.transaction do
na_nums = Sequence.allocate!(:jpo_na, na_count)
aa_nums = Sequence.allocate!(:jpo_aa, aa_count)

entry_id_to_attrs = request.submission.accessions.insert_all(entries.map {|entry|
{
number: (aa?(entry) ? aa_nums : na_nums).shift,
entry_id: entry[:id]
}
}, **{
unique_by: :number,
returning: %i[entry_id number version last_updated_at]
}).index_by {
it['entry_id']
}.transform_values(&:deep_symbolize_keys)

entries.each do |entry|
entry_id_to_attrs.fetch(entry[:id]) => {number: accession, version:, last_updated_at:}

entry.update(
accession:,
locus: accession,
version:,
last_updated: Time.zone.parse(last_updated_at).iso8601
)
end

filename = request.ddbj_record.filename

request.submission.update! ddbj_record: {
io: StringIO.new(JSON.pretty_generate(record)),
filename: "#{filename.base}-submitted.#{filename.extension}",
content_type: request.ddbj_record.content_type
}
end
end

def aa?(entry)
Array(entry.dig(:source_qualifiers, :mol_type)).any? { it[:value] == 'protein' }
end
end
80 changes: 80 additions & 0 deletions app/jobs/apply_submission_update_job.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
class ApplySubmissionUpdateJob < ApplicationJob
class NoChange < StandardError; end

def perform(update)
return unless update.ready_to_apply?

update.applying!

begin
apply update
rescue NoChange
update.no_change!
rescue => e
Rails.error.report e

update.update!(
status: :application_failed,
error_message: e.message
)
else
update.applied!
update.validation.write_submission_files to: update.submission.dir
end
end

private

def apply(update)
old_record = JSON.parse(update.submission.ddbj_record.download, symbolize_names: true)
new_record = JSON.parse(update.ddbj_record.download, symbolize_names: true)
old_entries = old_record.dig(:sequence, :entries).index_by { it[:accession] }
new_entries = new_record.dig(:sequence, :entries)

changes = new_entries.select {|new_entry|
old_entry = old_entries.fetch(new_entry[:accession])

new_entry != old_entry
}

raise NoChange if changes.empty?

ActiveRecord::Base.transaction do
number_to_accession = update.submission.accessions.index_by(&:number)
now = Time.current

accession_to_attrs = update.submission.accessions.upsert_all(changes.map {|entry|
acc = number_to_accession.fetch(entry[:accession])

{
**acc.attributes,
entry_id: entry[:id],
version: acc.version.succ,
last_updated_at: now
}
}, **{
unique_by: :number,
returning: %i[number version last_updated_at]
}).index_by {
it['number']
}.transform_values(&:deep_symbolize_keys)

entries.each do |entry|
next unless attrs = accession_to_attrs[entry[:accession]]

attrs => {version:, last_updated_at:}

entry.update(
version:,
last_updated: Time.zone.parse(last_updated_at).iso8601
)
end

update.submission.update! ddbj_record: {
io: StringIO.new(JSON.pretty_generate(record)),
filename: update.ddbj_record.filename,
content_type: update.ddbj_record.content_type
}
end
end
end
2 changes: 1 addition & 1 deletion app/jobs/submit_job.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
class SubmitJob < ApplicationJob
def perform(submission)
submission.update! progress: :running, started_at: Time.current
submission.update! progress: :running

submitter = Database::MAPPING.fetch(submission.validation.db)::Submitter.new

Expand Down
5 changes: 5 additions & 0 deletions app/jobs/validate_ddbj_record_job.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class ValidateDDBJRecordJob < ApplicationJob
def perform(subject)
DDBJRecordValidator.validate subject
end
end
6 changes: 1 addition & 5 deletions app/jobs/validate_job.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
class ValidateJob < ApplicationJob
def perform(validation)
validation.update! progress: :running, started_at: Time.current
validation.update! progress: :running

ActiveRecord::Base.transaction do
validator = "Database::#{validation.db}::#{validation.via.camelize}Validator".constantize.new
Expand All @@ -10,14 +10,10 @@ def perform(validation)
rescue => e
Rails.error.report e

validation.objs.base.validity_error!

validation.objs.base.validation_details.create!(
severity: 'error',
message: e.message
)
else
validation.objs.base.validity_valid! unless validation.objs.base.validity
end

raise ActiveRecord::Rollback if validation.reload.canceled?
Expand Down
10 changes: 0 additions & 10 deletions app/models/accession_renewal.rb

This file was deleted.

3 changes: 0 additions & 3 deletions app/models/accession_renewal_validation_detail.rb

This file was deleted.

11 changes: 0 additions & 11 deletions app/models/bioproject_submission_param.rb

This file was deleted.

Loading
Loading