def api_all_commentary(api_version, doc_id): if not get_doc(doc_id).is_transcription_validated: return make_403() tr = get_reference_transcription(doc_id) if tr is None: return make_404() commentaries = Commentary.query.filter( Commentary.doc_id == doc_id, Commentary.user_id == tr.user_id, ).all() return make_200(data=[c.serialize() for c in commentaries])
def api_put_commentary(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 api_version: :param doc_id: :return: """ doc = get_doc(doc_id) # teachers can still post notes in if the commentaries are validated current_user = current_app.get_current_user() if not current_user.is_teacher and doc.is_commentaries_validated: return make_403() forbid = is_closed(doc_id) if forbid: return forbid data = request.get_json() if "data" in data: data = data["data"] c = Commentary.query.filter( data["type_id"] == Commentary.type_id, doc_id == Commentary.doc_id, user_id == Commentary.user_id, ).first() if c is None: return make_404() try: if "content" in data: error = check_no_XMLParserError(data["content"]) if error: raise Exception('Commentary content is malformed: %s', str(error)) c.content = data["content"] db.session.add(c) db.session.commit() if "notes" in data: current_commentary_notes = CommentaryHasNote.query.filter( CommentaryHasNote.commentary_id == c.id).all() # remove all notes not present in the transcription anymore for current_chn in current_commentary_notes: if (current_chn.note.id, current_chn.ptr_start, current_chn.ptr_end) not in \ [(note.get('id', None), note["ptr_start"], note["ptr_end"]) for note in data["notes"]]: note = current_chn.note db.session.delete(current_chn) print("delete chn", note) db.session.flush() note.delete_if_unused() for note in data["notes"]: note_id = note.get('id', None) chn = CommentaryHasNote.query.filter( CommentaryHasNote.note_id == note_id, CommentaryHasNote.commentary_id == c.id, CommentaryHasNote.ptr_start == note["ptr_start"], CommentaryHasNote.ptr_end == note["ptr_end"]).first() if chn is None: # try to find a 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) chn = CommentaryHasNote(commentary_id=c.id, note_id=reused_note.id, ptr_start=note["ptr_start"], ptr_end=note["ptr_end"]) db.session.add(chn) db.session.flush() error = check_no_XMLParserError(note["content"]) if error: raise Exception('Note content is malformed: %s', str(error)) chn.ptr_start = note['ptr_start'] chn.ptr_end = note['ptr_end'] chn.note.content = note['content'] chn.note.type_id = note['type_id'] db.session.add(chn) db.session.add(chn.note) db.session.commit() except Exception as e: db.session.rollback() print('Error', str(e)) return make_400(str(e)) return make_200(data=c.serialize()) else: return make_400("no data")
def api_post_documents_translations(api_version, doc_id, user_id): """ at least one of "content" or "notes" is required { "data": { "content" : "My first translation" "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 # teachers can still post notes in validated translation current_user = current_app.get_current_user() if not current_user.is_teacher and get_doc(doc_id).is_translation_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('Translation content is malformed: %s', str(error)) tr = Translation(doc_id=doc_id, content=data["content"], user_id=user_id) db.session.add(tr) db.session.flush() # case 2) there's only "notes" in data if "notes" in data: tr = Translation.query.filter(Translation.doc_id == doc_id, Translation.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).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 = TranslationHasNote.query.filter(TranslationHasNote.note_id == reused_note.id, TranslationHasNote.translation_id == tr.id).first() # 1.a) the note is already present in the translation, so update its ptrs if thn is not None: raise Exception("Translation note already exists. Consider using PUT method") else: # 1.b) the note is not present on the translation side, so create it thn = TranslationHasNote(translation_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.translation_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 = TranslationHasNote(translation_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.translation_id, thn.note_id) db.session.flush() print("thn:", [thn.note.id for thn in tr.translation_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_post_commentary(api_version, doc_id, user_id): """ { "data": { "type_id": 2, "content" : "This is a commentary", "notes": [ { "content": "note1 content", "ptr_start": 5, "ptr_end": 7 } ] } } :param api_version: :param doc_id: :return: """ doc = get_doc(doc_id) if doc is None: return make_404() # teachers can still post notes in if the commentaries are validated user = current_app.get_current_user() if not user.is_teacher and doc.is_commentaries_validated: return make_403() data = request.get_json() if "data" in data: data = data["data"] data["user_id"] = user_id # user.id try: c = None # case 1) "content" in data if "content" in data: error = check_no_XMLParserError(data["content"]) if error: raise Exception('Commentary content is malformed: %s', str(error)) c = Commentary(doc_id=doc_id, user_id=user_id, type_id=data["type_id"], content=data["content"]) db.session.add(c) db.session.flush() # case 2) there's "notes" in data elif "notes" in data: c = Commentary.query.filter( Commentary.doc_id == doc_id, Commentary.user_id == user_id, Commentary.type_id == data["type_id"]).first() print(doc, c, user, data) if c 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 == 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() chn = CommentaryHasNote.query.filter( CommentaryHasNote.note_id == reused_note.id, CommentaryHasNote.commentary_id == c.id).first() # 1.a) the note is already present in the commentary, so update its ptrs if chn is not None: raise Exception( "Commentary note already exists. Consider using PUT method" ) else: # 1.b) the note is not present on the transcription side, so create it chn = CommentaryHasNote( commentary_id=c.id, note_id=reused_note.id, ptr_start=note["ptr_start"], ptr_end=note["ptr_end"]) db.session.add(chn) print("reuse:", chn.transcription_id, chn.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() chn = CommentaryHasNote(commentary_id=c.id, note_id=new_note.id, ptr_start=note["ptr_start"], ptr_end=note["ptr_end"]) db.session.add(chn) print("make:", chn.commentary_id, chn.note_id) db.session.flush() print("====================") db.session.add(chn) db.session.commit() except (Exception, KeyError) as e: db.session.rollback() print(str(e)) return make_400(str(e)) return make_200(c.serialize()) else: return make_400("no data")
def api_put_documents_translations(api_version, doc_id, user_id): """ { "data": { "content" : "My first translation" "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 # teachers can still update validated translation current_user = current_app.get_current_user() if not current_user.is_teacher and get_doc(doc_id).is_translation_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_translation(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('Translation content is malformed: %s', str(error)) tr.content = data["content"] db.session.add(tr) db.session.commit() if "notes" in data: current_translation_notes = TranslationHasNote.query.filter( TranslationHasNote.translation_id == tr.id).all() # remove all notes not present anymore in the translation print("current thn", current_translation_notes) for current_thn in current_translation_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 = TranslationHasNote.query.filter(TranslationHasNote.note_id == note_id, TranslationHasNote.translation_id == tr.id, TranslationHasNote.ptr_start == note["ptr_start"], TranslationHasNote.ptr_end == note["ptr_end"] ).first() if thn is None or note_id 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 translation side thn = TranslationHasNote(translation_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")