def delete_document_transcription(doc_id, user_id): forbid = forbid_if_nor_teacher_nor_admin_and_wants_user_data(current_app, user_id) if forbid: return forbid is_not_allowed = forbid_if_not_in_whitelist(current_app, Document.query.filter(Document.id == doc_id).first()) if is_not_allowed: return is_not_allowed closed = is_closed(doc_id) if closed: return closed doc = Document.query.filter(Document.id == doc_id).first() if doc is None: return make_404() is_not_allowed = forbid_if_not_in_whitelist(current_app, doc) if is_not_allowed: return is_not_allowed # forbid students to delete a transcription when there is a valid transcription # user = current_app.get_current_user() # if not user.is_teacher and get_doc(doc_id).is_transcription_validated: # return make_403() tr = get_transcription(doc_id=doc_id, user_id=user_id) if tr is None: return make_404() try: for thn in tr.transcription_has_note: if thn.note.user_id == int(user_id): exist_in_translation = TranslationHasNote.query.filter( TranslationHasNote.note_id == thn.note.id ).first() if not exist_in_translation: db.session.delete(thn.note) db.session.delete(tr) doc = unvalidate_all(doc) db.session.add(doc) db.session.commit() except Exception as e: db.session.rollback() print(str(e)) return make_400(str(e)) return make_200(data=doc.validation_flags)
def clone_commentary(doc_id, user_id, type_id): com_to_be_cloned = Commentary.query.filter( Commentary.user_id == user_id, Commentary.doc_id == doc_id, Commentary.type_id == type_id).first() if not com_to_be_cloned: return make_404() is_not_allowed = forbid_if_not_in_whitelist( current_app, Document.query.filter(Document.id == doc_id).first()) if is_not_allowed: return is_not_allowed teacher = current_app.get_current_user() teacher_com = Commentary.query.filter(Commentary.user_id == teacher.id, Commentary.type_id == type_id, Commentary.doc_id == doc_id).first() if teacher_com is None: teacher_com = Commentary(doc_id=doc_id, user_id=teacher.id, content=com_to_be_cloned.content) else: # replace the teacher's com content teacher_com.content = com_to_be_cloned.content # remove the old teacher's notes # for note in teacher_com.notes: # # MUST delete commentary_has_note and not the note itself # # (since the latest might be used somewhere else)! for chn in CommentaryHasNote.query.filter( CommentaryHasNote.commentary_id == teacher_com.id).all(): db.session.delete(chn) # clone notes for chn_to_be_cloned in com_to_be_cloned.commentary_has_note: note = Note(type_id=chn_to_be_cloned.note.type_id, user_id=teacher.id, content=chn_to_be_cloned.note.content) db.session.add(note) db.session.flush() teacher_com.transcription_has_note.append( CommentaryHasNote(ptr_start=chn_to_be_cloned.ptr_start, ptr_end=chn_to_be_cloned.ptr_end, note_id=note.id, commentary_id=teacher_com.id), ) db.session.add(teacher_com) try: db.session.commit() except Exception as e: db.session.rollback() print(str(e)) return make_400(str(e)) return make_200()
def clone_translation_alignments(doc_id, old_user_id, user_id): old_tr = Transcription.query.filter( Transcription.user_id == old_user_id, Transcription.doc_id == doc_id).first() old_tl = Translation.query.filter(Translation.user_id == old_user_id, Translation.doc_id == doc_id).first() new_tr = Transcription.query.filter( Transcription.user_id == user_id, Transcription.doc_id == doc_id).first() new_tl = Translation.query.filter(Translation.user_id == user_id, Translation.doc_id == doc_id).first() if not old_tr or not old_tl or not new_tr or not new_tl: return make_404() is_not_allowed = forbid_if_not_in_whitelist( current_app, Document.query.filter(Document.id == doc_id).first()) if is_not_allowed: return is_not_allowed # clone translation alignments old_alignments = AlignmentTranslation.query.filter( AlignmentTranslation.transcription_id == old_tr.id, AlignmentTranslation.translation_id == old_tl.id, ).all() new_alignments = [ AlignmentTranslation( transcription_id=new_tr.id, translation_id=new_tl.id, ptr_transcription_start=ol.ptr_transcription_start, ptr_transcription_end=ol.ptr_transcription_end, ptr_translation_start=ol.ptr_translation_start, ptr_translation_end=ol.ptr_translation_end) for ol in old_alignments ] db.session.bulk_save_objects(new_alignments) try: db.session.commit() except Exception as e: db.session.rollback() print(str(e)) return make_400(str(e)) return make_200()
def clone_transcription(doc_id, user_id): print("cloning transcription (doc %s) from user %s" % (doc_id, user_id)) tr_to_be_cloned = Transcription.query.filter(Transcription.user_id == user_id, Transcription.doc_id == doc_id).first() if not tr_to_be_cloned: return make_404() is_not_allowed = forbid_if_not_in_whitelist(current_app, Document.query.filter(Document.id == doc_id).first()) if is_not_allowed: return is_not_allowed teacher = current_app.get_current_user() teacher_tr = Transcription.query.filter(Transcription.user_id == teacher.id, Transcription.doc_id == doc_id).first() if teacher_tr is None: teacher_tr = Transcription(doc_id=doc_id, user_id=teacher.id, content=tr_to_be_cloned.content) else: # replace the teacher's tr content teacher_tr.content = tr_to_be_cloned.content # remove the old teacher's notes for note in teacher_tr.notes: db.session.delete(note) # teacher_tr.notes = [] # clone notes for thn_to_be_cloned in tr_to_be_cloned.transcription_has_note: note = Note(type_id=thn_to_be_cloned.note.type_id, user_id=teacher.id, content=thn_to_be_cloned.note.content) db.session.add(note) db.session.flush() teacher_tr.transcription_has_note.append( TranscriptionHasNote(ptr_start=thn_to_be_cloned.ptr_start, ptr_end=thn_to_be_cloned.ptr_end, note_id=note.id, transcription_id=teacher_tr.id), ) db.session.add(teacher_tr) try: db.session.commit() except Exception as e: db.session.rollback() print(str(e)) return make_400(str(e)) return make_200()
def clone_alignment_image(doc_id, old_user_id, user_id): old_tr = Transcription.query.filter( Transcription.user_id == old_user_id, Transcription.doc_id == doc_id).first() new_tr = Transcription.query.filter( Transcription.user_id == user_id, Transcription.doc_id == doc_id).first() if not old_tr or not new_tr: return make_404() is_not_allowed = forbid_if_not_in_whitelist( current_app, Document.query.filter(Document.id == doc_id).first()) if is_not_allowed: return is_not_allowed old_alignments = AlignmentImage.query.filter( AlignmentImage.transcription_id == old_tr.id, AlignmentImage.user_id == old_user_id).all() new_alignments = [ AlignmentImage(transcription_id=new_tr.id, user_id=user_id, zone_id=ol.zone_id, manifest_url=ol.manifest_url, canvas_idx=ol.canvas_idx, img_idx=ol.img_idx, ptr_transcription_start=ol.ptr_transcription_start, ptr_transcription_end=ol.ptr_transcription_end) for ol in old_alignments ] db.session.bulk_save_objects(new_alignments) try: db.session.commit() except Exception as e: db.session.rollback() print(str(e)) return make_400(str(e)) return make_200()
def clone_speechparts(doc_id, old_user_id, user_id): old_tr = Transcription.query.filter( Transcription.user_id == old_user_id, Transcription.doc_id == doc_id).first() new_tr = Transcription.query.filter( Transcription.user_id == user_id, Transcription.doc_id == doc_id).first() if not old_tr or not new_tr: return make_404() is_not_allowed = forbid_if_not_in_whitelist( current_app, Document.query.filter(Document.id == doc_id).first()) if is_not_allowed: return is_not_allowed # clone speechparts old_alignments = AlignmentDiscours.query.filter( AlignmentDiscours.transcription_id == old_tr.id, AlignmentDiscours.user_id == old_user_id, ).all() new_alignments = [ AlignmentDiscours(transcription_id=new_tr.id, user_id=user_id, speech_part_type_id=ol.speech_part_type_id, note=ol.note, ptr_start=ol.ptr_start, ptr_end=ol.ptr_end) for ol in old_alignments ] db.session.bulk_save_objects(new_alignments) try: db.session.commit() except Exception as e: db.session.rollback() print(str(e)) return make_400(str(e)) return make_200()
def commit_document_validation(doc): is_not_allowed = forbid_if_not_in_whitelist(current_app, doc) if is_not_allowed: db.session.rollback() return is_not_allowed access_forbidden = forbid_if_nor_teacher_nor_admin_and_wants_user_data( current_app, doc.user_id) if access_forbidden: db.session.rollback() return access_forbidden try: db.session.add(doc) db.session.commit() return make_200(data={"validation_flags": doc.validation_flags}) except Exception as e: db.session.rollback() print(e) return make_400(str(e))
def api_post_documents_transcriptions(api_version, doc_id, user_id): """ at least one of "content" or "notes" is required { "data": { "content" : "My first transcription" "notes": [ { "content": "note1 content", "ptr_start": 5, "ptr_end": 7 } ] } } :param user_id: :param api_version: :param doc_id: :return: """ #forbid = forbid_if_other_user(current_app, user_id) #if forbid: # return forbid is_not_allowed = forbid_if_not_in_whitelist(current_app, Document.query.filter(Document.id == doc_id).first()) if is_not_allowed: return is_not_allowed # teachers can still post notes in validated transcription current_user = current_app.get_current_user() if not current_user.is_teacher and get_doc(doc_id).is_transcription_validated: return make_403() forbid = is_closed(doc_id) if forbid: return forbid data = request.get_json() if "data" in data: data = data["data"] try: tr = None # case 1) "content" in data if "content" in data: error = check_no_XMLParserError(data["content"]) if error: raise Exception('Transcription content is malformed: %s', str(error)) tr = Transcription(doc_id=doc_id, content=data["content"], user_id=user_id) db.session.add(tr) db.session.flush() # case 2) there's "notes" in data if "notes" in data: tr = Transcription.query.filter(Transcription.doc_id == doc_id, Transcription.user_id == user_id).first() if tr is None: return make_404() if "notes" in data: print("======= notes =======") for note in data["notes"]: # 1) simply reuse notes which come with an id note_id = note.get('id', None) if note_id is not None: reused_note = Note.query.filter(Note.id == note_id, Note.user_id == current_user.id).first() if reused_note is None: return make_400(details="Wrong note id %s" % note_id) db.session.add(reused_note) db.session.flush() thn = TranscriptionHasNote.query.filter(TranscriptionHasNote.note_id == reused_note.id, TranscriptionHasNote.transcription_id == tr.id).first() # 1.a) the note is already present in the transcription, so update its ptrs if thn is not None: raise Exception("Transcription note already exists. Consider using PUT method") else: # 1.b) the note is not present on the transcription side, so create it thn = TranscriptionHasNote(transcription_id=tr.id, note_id=reused_note.id, ptr_start=note["ptr_start"], ptr_end=note["ptr_end"]) db.session.add(thn) print("reuse:", thn.transcription_id, thn.note_id) else: # 2) make new note error = check_no_XMLParserError(note["content"]) if error: raise Exception('Note content is malformed: %s', str(error)) new_note = Note(type_id=note.get("type_id", 0), user_id=user_id, content=note["content"]) db.session.add(new_note) db.session.flush() thn = TranscriptionHasNote(transcription_id=tr.id, note_id=new_note.id, ptr_start=note["ptr_start"], ptr_end=note["ptr_end"]) db.session.add(thn) print("make:", thn.transcription_id, thn.note_id) db.session.flush() print("thn:", [thn.note.id for thn in tr.transcription_has_note]) print("====================") db.session.add(tr) db.session.commit() except Exception as e: db.session.rollback() print("Error", str(e)) return make_400(str(e)) return make_200(data=tr.serialize_for_user(user_id)) else: return make_400("no data")
def api_put_documents_transcriptions(api_version, doc_id, user_id): """ { "data": { "content" : "My first transcription" "notes": [{ "id": 1, "type_id": 0 (by default), "content": "aaa", "ptr_start": 3, "ptr_end": 12 }] } } :param user_id: :param api_version: :param doc_id: :return: """ #forbid = forbid_if_other_user(current_app, user_id) #if forbid: # return forbid is_not_allowed = forbid_if_not_in_whitelist(current_app, Document.query.filter(Document.id == doc_id).first()) if is_not_allowed: return is_not_allowed # teachers can still update validated transcription current_user = current_app.get_current_user() if not current_user.is_teacher and get_doc(doc_id).is_transcription_validated: return make_403() forbid = is_closed(doc_id) if forbid: return forbid data = request.get_json() if "data" in data: data = data["data"] tr = get_transcription(doc_id=doc_id, user_id=user_id) if tr is None: return make_404() try: if "content" in data: error = check_no_XMLParserError(data["content"]) if error: raise Exception('Transcription content is malformed: %s', str(error)) tr.content = data["content"] db.session.add(tr) db.session.commit() if "notes" in data: current_transcription_notes = TranscriptionHasNote.query.filter( TranscriptionHasNote.transcription_id == tr.id).all() # remove all notes not present in the transcription anymore for current_thn in current_transcription_notes: if (current_thn.note.id, current_thn.ptr_start, current_thn.ptr_end) not in \ [(note.get('id', None), note["ptr_start"], note["ptr_end"]) for note in data["notes"]]: note = current_thn.note db.session.delete(current_thn) print("delete thn", note) db.session.flush() note.delete_if_unused() for note in data["notes"]: note_id = note.get('id', None) thn = TranscriptionHasNote.query.filter( TranscriptionHasNote.note_id == note_id, TranscriptionHasNote.transcription_id == tr.id, TranscriptionHasNote.ptr_start == note["ptr_start"], TranscriptionHasNote.ptr_end == note["ptr_end"] ).first() if thn is None: # try to find the note in other contents reused_note = findNoteInDoc(doc_id, user_id, note_id) if reused_note is None: raise Exception('Cannot reuse note: note %s unknown' % note_id) # bind the note on the transcription side thn = TranscriptionHasNote(transcription_id=tr.id, note_id=reused_note.id, ptr_start=note["ptr_start"], ptr_end=note["ptr_end"]) db.session.add(thn) db.session.flush() error = check_no_XMLParserError(note["content"]) if error: raise Exception('Note content is malformed: %s', str(error)) thn.ptr_start = note['ptr_start'] thn.ptr_end = note['ptr_end'] thn.note.content = note['content'] thn.note.type_id = note['type_id'] db.session.add(thn) db.session.add(thn.note) db.session.commit() except Exception as e: db.session.rollback() print('Error', str(e)) return make_400(str(e)) return make_200(data=tr.serialize_for_user(user_id)) else: return make_400("no data")