def withdraw_sequence(id): seq = check_seq_withdraw(id) if seq is not None: add_history(current_user, 'Published version %s withdrawn' % seq.release_version, seq, db, body = '') send_mail('Sequence %s version %d withdrawn by the IARC %s Committee' % (seq.description_id, seq.release_version, seq.species), [seq.species], 'iarc_sequence_withdrawn', reviewer=current_user, user_name=seq.maintainer, sequence=seq, comment='') seq.status = 'withdrawn' db.session.commit() seq.duplicate_sequences = list() flash('Sequence %s withdrawn' % seq.sequence_name) related_subs = [] for inf in seq.inferred_sequences: related_subs.append(inf.submission) # un-publish any related submissions that now don't have published sequences published_seqs = db.session.query(GeneDescription).filter_by(species=seq.species, status='published').all() for related_sub in related_subs: other_published = False for ps in published_seqs: for inf in ps.inferred_sequences: if inf.submission == related_sub: other_published = True break if not other_published: related_sub.submission_status = 'reviewing' related_sub.public = False add_history(current_user, 'Status changed from published to reviewing as submission %s was withdrawn.' % seq.description_id, related_sub, db, body = '') db.session.commit() return ''
def sequence_imgt_name(): if request.is_json: content = request.get_json() seq = check_seq_draft(content['id']) if seq is not None: seq.imgt_name = content['imgt_name'] add_history(current_user, 'IMGT Name updated to %s' % seq.imgt_name, seq, db, body='IMGT Name updated.') send_mail('Sequence %s version %d: IMGT name updated to %s by the IARC %s Committee' % (seq.description_id, seq.release_version, seq.imgt_name, seq.species), [seq.species], 'iarc_sequence_released', reviewer=current_user, user_name=seq.maintainer, sequence=seq, comment='IMGT Name updated to %s' % seq.imgt_name) db.session.commit() return json.dumps({'success':True}), 200, {'ContentType':'application/json'} return ''
def new_germline_set(species): if not current_user.has_role(species): return redirect('/') form = NewGermlineSetForm() form.locus.choices = ['IGH', 'IGK', 'IGL', 'TRA', 'TRB', 'TRG', 'TRD'] if request.method == 'POST': if form.cancel.data: return redirect('/germline_sets') if form.validate(): try: if db.session.query(GermlineSet).filter( and_( GermlineSet.species == species, GermlineSet.germline_set_name == form.name.data, ~GermlineSet.status.in_( ['withdrawn', 'superceded']))).count() > 0: form.new_name.errors = [ 'A germline set already exists with that name.' ] raise ValidationError() germline_set = GermlineSet() germline_set.species = species germline_set.status = 'draft' germline_set.author = current_user.name germline_set.lab_address = current_user.address germline_set.release_version = 0 germline_set.locus = form.locus.data germline_set.germline_set_name = form.name.data db.session.add(germline_set) db.session.commit() germline_set.germline_set_id = "G%05d" % germline_set.id add_history( current_user, '%s germline set %s (%s) created' % (germline_set.species, germline_set.germline_set_id, germline_set.germline_set_name), germline_set, db) db.session.commit() return redirect('/germline_sets') except ValidationError as e: return render_template('germline_set_new.html', form=form, species=species) return render_template('germline_set_new.html', form=form, species=species)
def publish_sequence(seq, notes, email): old_seq = db.session.query(GeneDescription).filter_by(description_id=seq.description_id, status='published').one_or_none() if old_seq: old_seq.status = 'superceded' old_seq.duplicate_sequences = list() seq.release_version = old_seq.release_version + 1 else: seq.release_version = 1 # Mark any referenced submissions as public for inferred_sequence in seq.inferred_sequences: sub = inferred_sequence.submission if not inferred_sequence.submission.public: inferred_sequence.submission.public = True db.session.commit() add_history(current_user, 'Submission published', sub, db) send_mail( 'Submission %s accepted and published by the IARC %s Committee' % (sub.submission_id, sub.species), [sub.submitter_email], 'user_submission_published', reviewer=current_user, user_name=sub.submitter_name, submission=sub, sequence=seq) send_mail( 'Submission %s accepted and published by the IARC %s Committee' % (sub.submission_id, sub.species), [sub.species], 'iarc_submission_published', reviewer=current_user, user_name=sub.submitter_name, submission=sub, sequence=seq) # Make a note in submission history if we haven't already title = 'Sequence %s listed in affirmation' % inferred_sequence.sequence_details.sequence_id entry = db.session.query(JournalEntry).filter_by(type='note', submission=sub, title=title).all() if not entry: add_note(current_user, title, safe_textile( '* Sequence: %s\n* Genotype: %s\n* Subject ID: %s\nis referenced in affirmation %s (sequence name %s)' % (inferred_sequence.sequence_details.sequence_id, inferred_sequence.genotype_description.genotype_name, inferred_sequence.genotype_description.genotype_subject_id, seq.description_id, seq.sequence_name)), sub, db) seq.release_date = datetime.date.today() add_history(current_user, 'Version %s published' % seq.release_version, seq, db, body=notes) if email: send_mail('Sequence %s version %d published by the IARC %s Committee' % ( seq.description_id, seq.release_version, seq.species), [seq.species], 'iarc_sequence_released', reviewer=current_user, user_name=seq.maintainer, sequence=seq, comment=notes) seq.release_description = notes seq.status = 'published' db.session.commit()
def withdraw_germline_set(id): set = check_set_withdraw(id) if set is not None: add_history(current_user, 'Published version %s withdrawn' % set.release_version, set, db, body='') send_mail( 'Germline set %s version %d withdrawn by the IARC %s Committee' % (set.germline_set_id, set.release_version, set.species), [set.species], 'iarc_germline_set_withdrawn', reviewer=current_user, user_name=set.author, germline_set=set, comment='') set.status = 'withdrawn' db.session.commit() flash('Germline set %s withdrawn' % set.germline_set_name) db.session.commit() return ''
def submission(id): sub = db.session.query(Submission).filter_by( submission_id=id).one_or_none() if sub is None or not (sub.can_see(current_user) or current_user.has_role('Admin')): flash('Submission not found') return redirect('/submissions') (form, tables) = setup_submission_view_forms_and_tables( sub, db, sub.can_see_private(current_user)) reviewer = (current_user.has_role(sub.species) or current_user in sub.delegates) if request.method == 'GET': return render_template( 'submission_view.html', sub=sub, tables=tables, form=form, reviewer=reviewer, id=id, jump="", status=sub.submission_status, attachment=len(sub.notes_entries[0].attached_files) > 0) else: if not reviewer: flash('Submission not found') return redirect('/submissions') # Check for additions/deletions to editable tables, and any errors flagged up by validation in check_add_item editable_tables = {'delegate_table': tables['delegate_table']} validation_result = process_table_updates(editable_tables, request, db) if validation_result.tag: if validation_result.valid: # rebuild tables if something has changed (form, tables) = setup_submission_view_forms_and_tables( sub, db, sub.can_see_private(current_user)) return render_template('submission_view.html', sub=sub, tables=tables, form=form, reviewer=reviewer, id=id, jump=validation_result.tag, status=sub.submission_status) if form.validate(): if form.action.data == 'draft': add_note( current_user, form.title.data, safe_textile( 'Submission returned to Submitter with the following message:\r\n\r\n' + form.body.data), sub, db) add_history(current_user, 'Submission returned to Submitter', sub, db) send_mail( 'Submission %s returned to you from the IARC %s Committee' % (sub.submission_id, sub.species), [sub.submitter_email], 'user_submission_returned', reviewer=current_user, user_name=sub.submitter_name, submission=sub, comment=form.body.data) send_mail( 'Submission %s returned to Submitter by the IARC %s Committee' % (sub.submission_id, sub.species), [sub.species], 'iarc_submission_returned', reviewer=current_user, user_name=sub.submitter_name, submission=sub, comment=form.body.data) sub.submission_status = 'draft' db.session.commit() flash('Submission returned to Submitter') return redirect('/submissions') elif form.action.data == 'complete': add_note( current_user, form.title.data, safe_textile( 'Submission completed with the following message to the Submitter:\n\n' + form.body.data), sub, db) add_history(current_user, 'Submission completed', sub, db) send_mail( 'Submission %s completed review by the IARC %s Committee' % (sub.submission_id, sub.species), [sub.submitter_email], 'user_submission_completed', reviewer=current_user, user_name=sub.submitter_name, submission=sub, comment=form.body.data) send_mail( 'Submission %s completed review by the IARC %s Committee' % (sub.submission_id, sub.species), [sub.species], 'iarc_submission_completed', reviewer=current_user, user_name=sub.submitter_name, submission=sub, comment=form.body.data) sub.submission_status = 'complete' db.session.commit() flash('Submission marked as complete') return redirect('/submissions') elif form.action.data == 'withdraw': referenced_gds = [] for inf in sub.inferred_sequences: for gd in inf.gene_descriptions: if gd.status not in ('superceded', 'withdrawn'): referenced_gds.append(gd.description_id) if len(referenced_gds) > 0: flash( 'Please remove references to this submission in sequence(s) %s first.' % ','.join(referenced_gds)) return render_template('submission_view.html', sub=sub, tables=tables, form=form, reviewer=reviewer, id=id, jump=validation_result.tag, status=sub.submission_status) add_note( current_user, form.title.data, safe_textile( 'Submission withdrawn with the following message to the Submitter:\n\n' + form.body.data), sub, db) add_history(current_user, 'Submission withdrawn', sub, db) send_mail( 'Submission %s has been marked as withdrawn by the IARC %s Committee' % (sub.submission_id, sub.species), [sub.submitter_email], 'user_submission_withdrawn', reviewer=current_user, user_name=sub.submitter_name, submission=sub, comment=form.body.data) send_mail( 'Submission %s has been marked as withdrawn by the IARC %s Committee' % (sub.submission_id, sub.species), [sub.species], 'iarc_submission_withdrawn', reviewer=current_user, user_name=sub.submitter_name, submission=sub, comment=form.body.data) sub.submission_status = 'withdrawn' db.session.commit() flash('Submission marked as withdrawn') return redirect('/submissions') elif form.action.data == 'review': add_note( current_user, form.title.data, safe_textile( 'Submission returned to IARC Review with the following message to the Submitter:\n\n' + form.body.data), sub, db) add_history(current_user, 'Submission returned to Review', sub, db) send_mail( 'Submission %s returned to review by the IARC %s Committee' % (sub.submission_id, sub.species), [sub.submitter_email], 'user_submission_re_review', reviewer=current_user, user_name=sub.submitter_name, submission=sub, comment=form.body.data) send_mail( 'Submission %s returned to review by the IARC %s Committee' % (sub.submission_id, sub.species), [sub.species], 'iarc_submission_re_review', reviewer=current_user, user_name=sub.submitter_name, submission=sub, comment=form.body.data) sub.submission_status = 'reviewing' db.session.commit() flash('Submission returned to Review') return redirect('/submissions') elif form.action.data == 'note': add_note(current_user, form.title.data, form.body.data, sub, db) db.session.commit() flash('Note Added') return redirect(url_for('submission', id=id, _anchor='review')) elif form.type.data == 'note': #reply to thread head = db.session.query(JournalEntry).filter_by( submission_id=sub.id, type='note', id=int(form.action.data)).one_or_none() add_note(current_user, head.title, form.body.data, sub, db, parent_id=int(form.action.data)) db.session.commit() flash('Note Added') return redirect(url_for('submission', id=id, _anchor='review')) else: return redirect('/submissions') else: return render_template('submission_view.html', sub=sub, tables=tables, form=form, reviewer=reviewer, id=id, jump=validation_result.tag, status=sub.submission_status)
def edit_submission(id): sub = check_sub_edit(id) if sub is None: return redirect('/submissions') (tables, form) = setup_submission_edit_forms_and_tables(sub, db) if request.method == 'GET': populate_Submission(db, sub, form) populate_Repertoire(db, sub.repertoire[0], form) form.repository_select.data = sub.repertoire[ 0].repository_name if sub.repertoire[0].repository_name in ( 'NCBI SRA', 'ENA') else 'Other' return render_template( 'submission_edit.html', form=form, id=id, tables=tables, attachment=len(sub.notes_entries[0].attached_files) > 0) validation_result = ValidationResult() try: if 'save_btn' in request.form or 'save_close_btn' or 'submit_btn' in request.form: if not form.validate(): if 'submit_btn' in request.form: raise ValidationError() # Overlook empty field errors when saving to draft nonblank_errors = False for field in form._fields: if len(form._fields[field].errors) > 0: if len(form._fields[field].data) == 0: form._fields[field].errors = [] else: nonblank_errors = True if nonblank_errors: raise ValidationError() # Check if this is an NCBI related repertoire, and, if so, validate accession number and update related fields choice = form.repository_select.data update_sra_rep_details(form) # Check for additions/deletions to editable tables, and any errors flagged up by validation in check_add_item validation_result = process_table_updates(tables, request, db) if not validation_result.valid: raise ValidationError() if 'submit_btn' in request.form: check_submission_complete(sub, validation_result) sub.submission_status = 'reviewing' add_history( current_user, 'Submission submitted to IARC %s Committee for review' % sub.species, sub, db) send_mail( 'Submission %s submitted to IARC %s Committee for review' % (sub.submission_id, sub.species), [current_user.email], 'user_submission_submitted', user=current_user, submission=sub) send_mail( 'Submission %s submitted to IARC %s Committee for review' % (sub.submission_id, sub.species), [sub.species], 'iarc_submission_received', user=current_user, submission=sub) db.session.commit() flash('Submission %s has been submitted to IARC for review.' % id) return redirect(url_for('submissions')) # We've gone too far off-piste to use form initialisation or process() to push field values into the object # The main problem is that not all object attributes are represented in the form, for example submission_id # if these were present as hidden fields, maybe we could use process() if ('save_btn' in request.form or 'save_close_btn' or 'submit_btn' in request.form or 'upload_btn' in request.form): for (k, v) in request.form.items(): if hasattr(sub, k): setattr(sub, k, v) elif hasattr(sub.repertoire[0], k): setattr(sub.repertoire[0], k, v) # update fields that may have been fetched from NCBI sub.repertoire[0].repository_name = form.repository_name.data sub.repertoire[0].dataset_url = form.dataset_url.data sub.repertoire[0].rep_title = form.rep_title.data db.session.commit() if 'notes_attachment' in request.files: for file in form.notes_attachment.data: if file.filename != '': af = None for at in sub.notes_entries[0].attached_files: if at.filename == file.filename: af = at break if af is None: af = AttachedFile() af.notes_entry = sub.notes_entries[0] af.filename = file.filename db.session.add(af) db.session.commit() dirname = attach_path + sub.submission_id try: if not isdir(dirname): mkdir(dirname) with open(dirname + '/multi_attachment_%s' % af.id, 'wb') as fo: fo.write(file.stream.read()) except: info = sys.exc_info() flash('Error saving attachment: %s' % (info[1])) app.logger.error(format_exc()) return redirect( url_for('edit_submission', id=sub.submission_id)) if 'notes_text' in request.form: sub.notes_entries[0].notes_text = request.form[ 'notes_text'].encode('utf-8') db.session.commit() form.repository_select.data = sub.repertoire[ 0].repository_name if sub.repertoire[0].repository_name in ( 'NCBI SRA', 'ENA') else 'Other' if validation_result.route: return redirect( url_for(validation_result.route, id=validation_result.id)) if validation_result.tag: return redirect( url_for('edit_submission', id=id, _anchor=validation_result.tag)) if 'save_btn' in request.form or 'upload_btn' in request.form: tag = request.form['current_tab'].split( '#')[1] if '#' in request.form['current_tab'] else '#sub' return redirect(url_for('edit_submission', id=id, _anchor=tag)) else: return redirect(url_for('submissions')) except ValidationError as e: # If we don't have a tag, find an error to jump to if not validation_result.tag: repform = type(RepertoireForm()) for subform in form.subforms: if type(subform) is repform: for field in subform: if len(field.errors) > 0: validation_result.tag = 'rep' break break if not validation_result.tag: for table in tables.values(): for field in table.form: if len(field.errors) > 0: validation_result.tag = table.name break return render_template('submission_edit.html', form=form, id=id, tables=tables, jump=validation_result.tag)
def edit_germline_set(id): germline_set = check_set_edit(id) if germline_set is None: return redirect('/germline_sets') if len(germline_set.notes_entries) == 0: germline_set.notes_entries.append(NotesEntry()) db.session.commit() update_germline_set_seqs(germline_set) db.session.commit() tables = setup_germline_set_edit_tables(db, germline_set) tables['genes'].table_id = "genetable" tables['genes'].html_attrs = {'style': 'width: 100%'} germline_set_form = GermlineSetForm(obj=germline_set) notes_entry_form = NotesEntryForm(obj=germline_set.notes_entries[0]) history_form = JournalEntryForm() hidden_return_form = HiddenReturnForm() changes = list_germline_set_changes(germline_set) form = AggregateForm(germline_set_form, notes_entry_form, history_form, hidden_return_form, tables['ack'].form, tables['pubmed_table'].form) if request.method == 'POST': form.validate() valid = True for field in form._fields: if len(form[field].errors) > 0: if field in history_form._fields and 'history_btn' not in request.form: form[field].errors = [] else: valid = False if form.action.data == 'published': if len(germline_set.gene_descriptions) < 1: flash("Please add at least one gene to the set!") form.action.data = '' valid = False for gene_description in germline_set.gene_descriptions: if gene_description.status == 'draft': publish_sequence(gene_description, form.body.data, False) if gene_description.status == 'published' and gene_description.affirmation_level == 0: flash( "Can't publish this set while gene %s is at affirmation level 0." % gene_description.sequence_name) form.action.data = '' valid = False if gene_description.status == 'withdrawn': flash( "Can't publish this set while gene %s is withdrawn." % gene_description.sequence_name) form.action.data = '' valid = False if gene_description.species_subgroup != germline_set.species_subgroup or gene_description.species_subgroup_type != germline_set.species_subgroup_type: flash( "Can't publish this set while gene %s species subgroup/subgroup type disagreees with the germline set values." % gene_description.sequence_name) form.action.data = '' valid = False if valid: try: validation_result = process_table_updates( { 'ack': tables['ack'], 'pubmed_table': tables['pubmed_table'] }, request, db) if not validation_result.valid: raise ValidationError() save_GermlineSet(db, germline_set, form) if 'add_gene_btn' in request.form: return redirect(url_for('add_gene_to_set', id=id)) if form.action.data == 'published': old_set = db.session.query(GermlineSet).filter_by( germline_set_id=germline_set.germline_set_id, status='published').one_or_none() if old_set: old_set.status = 'superceded' max_version = db.session.query(func.max(GermlineSet.release_version))\ .filter(GermlineSet.germline_set_id == germline_set.germline_set_id)\ .filter(or_(GermlineSet.status == 'withdrawn', GermlineSet.status == 'superceded'))\ .one_or_none() germline_set.release_version = max_version[ 0] + 1 if max_version[0] else 1 germline_set.release_date = datetime.date.today() hist_notes = form.body.data changes = list_germline_set_changes( germline_set) # to get updated versions if changes != '': hist_notes += Markup('<br>') + changes add_history(current_user, 'Version %s published' % (germline_set.release_version), germline_set, db, body=hist_notes) send_mail( 'Sequence %s version %d published by the IARC %s Committee' % (germline_set.germline_set_id, germline_set.release_version, germline_set.species), [germline_set.species], 'iarc_germline_set_released', reviewer=current_user, user_name=germline_set.author, germline_set=germline_set, comment=form.body.data) germline_set.status = 'published' db.session.commit() flash('Germline set published') return redirect('/germline_sets') if 'notes_attachment' in request.files: for file in form.notes_attachment.data: if file.filename != '': af = None for at in germline_set.notes_entries[ 0].attached_files: if at.filename == file.filename: af = at break if af is None: af = AttachedFile() af.notes_entry = germline_set.notes_entries[0] af.filename = file.filename db.session.add(af) db.session.commit() dirname = attach_path + germline_set.germline_set_id try: if not isdir(dirname): mkdir(dirname) with open( dirname + '/multi_attachment_%s' % af.id, 'wb') as fo: fo.write(file.stream.read()) except: info = sys.exc_info() flash('Error saving attachment: %s' % (info[1])) app.logger.error(format_exc()) return redirect( url_for('edit_submission', id=germline_set.germline_set_id)) db.session.commit() validation_result.tag = 'notes' if 'notes_text' in request.form and germline_set.notes_entries[ 0].notes_text is None or germline_set.notes_entries[ 0].notes_text != request.form['notes_text'].encode( 'utf-8'): germline_set.notes_entries[0].notes_text = request.form[ 'notes_text'].encode('utf-8') db.session.commit() except ValidationError: return render_template( 'germline_set_edit.html', form=form, germline_set_name=germline_set.germline_set_name, id=id, set_id=germline_set.germline_set_id, tables=tables, changes=changes, jump=validation_result.tag, version=germline_set.release_version) if validation_result.tag: return redirect( url_for('edit_germline_set', id=id, _anchor=validation_result.tag)) else: return redirect(url_for('germline_sets')) else: for field in tables['ack'].form: if len(field.errors) > 0: return render_template( 'germline_set_edit.html', form=form, germline_set_name=germline_set.germline_set_name, id=id, set_id=germline_set.germline_set_id, tables=tables, changes=changes, jump='ack', version=germline_set.release_version) return render_template( 'germline_set_edit.html', form=form, germline_set_name=germline_set.germline_set_name, id=id, set_id=germline_set.germline_set_id, tables=tables, version=germline_set.release_version, changes=changes, )