def api_put_district(api_version, country_id): c = Country.query.filter(Country.id == country_id).first() if c is None: return make_404("Country does not exist") try: data = request.get_json() if "data" in data: data = data["data"] modified_data = [] try: for district in data: a = District.query.filter( District.country_id == country_id, District.id == district.get('id', None)).one() a.label = district.get("label") db.session.add(a) modified_data.append(a) db.session.commit() except Exception as e: db.session.rollback() print(str(e)) return make_409(str(e)) return make_200([d.serialize() for d in modified_data]) else: return make_400("no data") except NoResultFound: return make_404("District not found")
def view_document_translation(api_version, doc_id, user_id=None): if user_id is not None: forbid = forbid_if_nor_teacher_nor_admin_and_wants_user_data(current_app, user_id) if forbid: return forbid tr = get_translation(doc_id, user_id) else: tr = get_reference_translation(doc_id) if tr is None: return make_404() if user_id is None: user_id = tr.user_id _tr = tr.serialize_for_user(user_id) from app.api.transcriptions.routes import add_notes_refs_to_text _content = add_notes_refs_to_text(_tr["content"], _tr["notes"]) return make_200({ "doc_id": tr.doc_id, "user_id": tr.user_id, "content": Markup(_content) if tr.content is not None else "", "notes": {"{:010d}".format(n["id"]): n["content"] for n in _tr["notes"]} })
def api_delete_documents_transcriptions_alignments_images( api_version, doc_id, anno_id): """ :param api_version: :param doc_id: :param user_id: :return: """ transcription = get_reference_transcription(doc_id) if transcription is None: return make_404() manifest_url = Image.query.filter( Image.doc_id == doc_id).first().manifest_url alignments = AlignmentImage.query.filter( AlignmentImage.transcription_id == transcription.id, AlignmentImage.user_id == transcription.user_id, AlignmentImage.manifest_url == manifest_url, AlignmentImage.zone_id == anno_id).all() if len(alignments) > 0: try: for al in alignments: db.session.delete(al) db.session.commit() except Exception as e: db.session.rollback() print(str(e)) return make_400(str(e)) return make_200()
def api_documents_transcriptions_alignments_discours(api_version, doc_id, user_id=None): """ If user_id is None: get the reference translation (if any) to find the alignment :param api_version: :param doc_id: :param user_id: :return: """ transcription = get_reference_transcription(doc_id) if transcription is None: return make_404() if user_id is None: user_id = transcription.user_id else: forbid = forbid_if_nor_teacher_nor_admin_and_wants_user_data( current_app, user_id) if forbid: return forbid alignments = AlignmentDiscours.query.filter( AlignmentDiscours.transcription_id == transcription.id, AlignmentDiscours.user_id == user_id).all() if len(alignments) == 0: return make_404() return make_200(data=[al.serialize() for al in alignments])
def view_document_commentaries(api_version, doc_id, user_id=None): if user_id is not None: forbid = forbid_if_nor_teacher_nor_admin_and_wants_user_data( current_app, user_id) if forbid: return forbid coms = get_commentaries(doc_id, user_id) else: coms = get_reference_commentaries(doc_id) if coms is None or len(coms) == 0: return make_404() _coms = [c.serialize() for c in coms] _coms_content = [ add_notes_refs_to_text(c["content"], c["notes"]) for c in _coms ] commentaries = zip(_coms, _coms_content) return make_200( data=[{ "doc_id": com["doc_id"], "user_id": com["user_id"], "type": com["type"], "content": Markup(annotated) if annotated is not None else "", "notes": {"{:010d}".format(n["id"]): n["content"] for n in com["notes"]} } for com, annotated in commentaries])
def api_get_alignment_translation_from_user(api_version, doc_id, user_id): from app.api.transcriptions.routes import get_reference_transcription from app.api.translations.routes import get_translation forbid = forbid_if_nor_teacher_nor_admin_and_wants_user_data( current_app, user_id) if forbid: return forbid transcription = get_reference_transcription(doc_id) if transcription is None: return make_404(details="No transcription available") translation = get_translation(doc_id=doc_id, user_id=user_id) if translation is None: return make_404(details="No translation available") alignments = AlignmentTranslation.query.filter( AlignmentTranslation.transcription_id == transcription.id, AlignmentTranslation.translation_id == translation.id).all() ptrs = [(a.ptr_transcription_start, a.ptr_transcription_end, a.ptr_translation_start, a.ptr_translation_end) for a in alignments] return make_200(data=ptrs)
def api_delete_speechparts_alignments(api_version, doc_id, user_id): from app.api.transcriptions.routes import get_reference_transcription forbid = forbid_if_nor_teacher_nor_admin_and_wants_user_data( current_app, user_id) if forbid: return forbid transcription = get_reference_transcription(doc_id) if transcription is None: return make_404(details="Transcription not found") try: # TRUNCATE for old_al in AlignmentDiscours.query.filter( AlignmentDiscours.transcription_id == transcription.id, AlignmentDiscours.user_id == user_id).all(): db.session.delete(old_al) db.session.commit() except Exception as e: db.session.rollback() print(str(e)) return make_400(str(e)) return make_200(data=[])
def api_put_acte_type(api_version): try: data = request.get_json() if "data" in data: data = data["data"] try: modified_data = [] for acte_type in data: a = ActeType.query.filter(ActeType.id == acte_type.get('id')).one() a.label = acte_type.get("label") a.description = acte_type.get("description") db.session.add(a) modified_data.append(a) db.session.commit() except Exception as e: db.session.rollback() return make_409(str(e)) return make_200([d.serialize() for d in modified_data]) else: return make_400("no data") except NoResultFound: return make_404("ActeType not found")
def api_put_speech_part_type(api_version): try: data = request.get_json() if "data" in data: data = data["data"] try: modified_data = [] for speech_part_type in data: a = SpeechPartType.query.filter( SpeechPartType.id == speech_part_type.get('id')).one() a.label = speech_part_type.get("label") a.lang_code = speech_part_type.get("lang_code") a.description = speech_part_type.get("description") db.session.add(a) modified_data.append(a) db.session.commit() except Exception as e: print(str(e), speech_part_type) db.session.rollback() return make_409(str(e)) return make_200([d.serialize() for d in modified_data]) else: return make_400("no data") except NoResultFound: return make_404("SpeechPartType not found")
def api_documents_delete_annotation(api_version, doc_id, zone_id): """ :param api_version: :param doc_id: :param zone_id: :return: """ try: img = Image.query.filter(Image.doc_id == doc_id).first() anno_to_delete = ImageZone.query.filter( ImageZone.zone_id == zone_id, ImageZone.manifest_url == img.manifest_url, ImageZone.canvas_idx == img.canvas_idx, ImageZone.img_idx == img.img_idx ).first() print('anno to delete', anno_to_delete) if anno_to_delete is None: raise Exception('annotation %s not found ' % zone_id) db.session.delete(anno_to_delete) db.session.commit() except Exception as e: db.session.rollback() return make_400(details="Cannot delete the annotation %s : %s" % (zone_id, str(e))) return make_200()
def api_put_country(api_version): try: data = request.get_json() if "data" in data: data = data["data"] try: modified_data = [] for country in data: a = Country.query.filter( Country.id == country.get('id', None)).one() a.label = country.get("label") a.ref = country.get("ref") db.session.add(a) modified_data.append(a) db.session.commit() except Exception as e: db.session.rollback() return make_409(str(e)) return make_200([d.serialize() for d in modified_data]) else: return make_400("no data") except NoResultFound: return make_404("Country not found")
def api_put_language(api_version): try: data = request.get_json() if "data" in data: data = data["data"] modified_data = [] try: for language in data: a = Language.query.filter( Language.code == language.get('code', None)).one() a.label = language.get("label") db.session.add(a) modified_data.append(a) db.session.commit() except Exception as e: db.session.rollback() return make_409(str(e)) return make_200([d.serialize() for d in modified_data]) else: return make_400("no data") except NoResultFound: return make_404("Language not found")
def api_put_institution(api_version): try: data = request.get_json() if "data" in data: data = data["data"] modified_data = [] try: for institution in data: a = Institution.query.filter( Institution.id == institution.get('id')).one() a.ref = institution.get("ref") a.name = institution.get("name") db.session.add(a) modified_data.append(a) db.session.commit() except Exception as e: db.session.rollback() return make_409(str(e)) return make_200([d.serialize() for d in modified_data]) else: return make_400("no data") except NoResultFound: return make_404("Institution not found")
def api_put_tradition(api_version): try: data = request.get_json() if "data" in data: data = data["data"] modified_data = [] try: for tradition in data: a = Tradition.query.filter( Tradition.id == tradition.get('id', None)).one() a.label = tradition.get("label") db.session.add(a) modified_data.append(a) db.session.commit() except Exception as e: db.session.rollback() return make_409(str(e)) return make_200([d.serialize() for d in modified_data]) else: return make_400("no data") except NoResultFound: return make_404("Tradition not found")
def api_documents_translations_from_user(api_version, doc_id, user_id=None): forbid = forbid_if_nor_teacher_nor_admin_and_wants_user_data(current_app, user_id) if forbid: return forbid tr = get_translation(doc_id, user_id) if tr is None: return make_404() return make_200(data=tr.serialize_for_user(user_id))
def api_documents_translations_users(api_version, doc_id): users = [] try: translations = Translation.query.filter(Translation.doc_id == doc_id).all() users = User.query.filter(User.id.in_(set([tr.user_id for tr in translations]))).all() users = [{"id": user.id, "username": user.username} for user in users] except NoResultFound: pass return make_200(data=users)
def api_users_roles(api_version, user_id): access_is_forbidden = forbid_if_nor_teacher_nor_admin_and_wants_user_data(current_app, user_id) if access_is_forbidden: return access_is_forbidden target_user = User.query.filter(User.id == user_id).first() if target_user is not None: return make_200(data=[r.serialize() for r in target_user.roles]) else: return make_404()
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 invite_user(api_version): json = request.get_json(force=True) email = json.get('email', None) role = json.get('role', 'student') if email is None: print("Email unknown") return make_401("Email unknown") username = email.split('@')[0] password = ''.join(choice(string.ascii_letters) for i in range(5)) + str(randint(1, 100)).zfill(3) msg = Message('Contribute to Adele', sender=current_app.config['MAIL_USERNAME'], recipients=[email]) msg.body = "Vous avez été invité(e) à contribuer au projet Adele (" \ "https://dev.chartes.psl.eu/adele/profile).\nIdentifiant: %s\nMot de passe: %s\nN'oubliez pas de " \ "changer votre mot de passe après votre première connexion !" % (email, password) print(email, role) print(msg.body) try: new_user = User(username=username, password=generate_password_hash(password), email=email, first_name=username, last_name=username, active=True, email_confirmed_at=datetime.datetime.now()) print('checkpassword:'******'student', 'teacher', 'admin'): role = 'student' if role == 'admin': new_user.roles = Role.query.filter(Role.id >= 1).all() elif role == 'student': new_user.roles = Role.query.filter(Role.id == 2).all() elif role == 'teacher': new_user.roles = Role.query.filter(Role.id >= 2).all() db.session.add(new_user) db.session.commit() except Exception as e: print(f'cannot invite user ({username}, {email}): {str(e)}') db.session.rollback() return make_400("Cannot invite user: %s" % str(e)) mail.send(msg) return make_200(msg)
def api_tradition(api_version, tradition_id=None): if tradition_id is None: traditions = Tradition.query.order_by(Tradition.label).all() else: # single at = Tradition.query.filter(Tradition.id == tradition_id).first() if at is None: return make_404("Tradition {0} not found".format(tradition_id)) else: traditions = [at] return make_200([a.serialize() for a in traditions])
def api_country(api_version, country_id=None): if country_id is None: countries = Country.query.order_by(Country.label).all() else: # single at = Country.query.filter(Country.id == country_id).first() if at is None: return make_404("Country {0} not found".format(country_id)) else: countries = [at] return make_200([a.serialize() for a in countries])
def api_language(api_version, language_code=None): if language_code is None: languages = Language.query.order_by(Language.label).all() else: # single at = Language.query.filter(Language.code == language_code).first() if at is None: return make_404("Language {0} not found".format(language_code)) else: languages = [at] return make_200([a.serialize() for a in languages])
def api_acte_type(api_version, acte_type_id=None): if acte_type_id is None: acte_types = ActeType.query.all() else: # single at = ActeType.query.filter(ActeType.id == acte_type_id).first() if at is None: return make_404("ActeType {0} not found".format(acte_type_id)) else: acte_types = [at] return make_200([a.serialize() for a in acte_types])
def api_institution(api_version, institution_id=None): if institution_id is None: institutions = Institution.query.order_by(Institution.name).all() else: # single at = Institution.query.filter(Institution.id == institution_id).first() if at is None: return make_404("Institution {0} not found".format(institution_id)) else: institutions = [at] return make_200([a.serialize() for a in institutions])
def api_editor(api_version, editor_id=None): if editor_id is None: editors = Editor.query.all() else: # single at = Editor.query.filter(Editor.id == editor_id).first() if at is None: return make_404("Editor {0} not found".format(editor_id)) else: editors = [at] return make_200([a.serialize() for a in editors])
def api_post_translation_alignments(api_version, doc_id, user_id): """ NB: Posting alignment has a 'TRUNCATE AND REPLACE' effect """ from app.api.transcriptions.routes import get_reference_transcription from app.api.translations.routes import get_translation forbid = forbid_if_nor_teacher_nor_admin_and_wants_user_data( current_app, user_id) if forbid: return forbid transcription = get_reference_transcription(doc_id) if transcription is None: return make_404(details="Transcription not found") translation = get_translation(doc_id=doc_id, user_id=user_id) if translation is None: return make_404(details="Translation not found") data = request.get_json() data = data.get("data", []) ptrs = [] try: # TRUNCATE for old_al in AlignmentTranslation.query.filter( AlignmentTranslation.transcription_id == transcription.id, AlignmentTranslation.translation_id == translation.id).all(): db.session.delete(old_al) # INSERT for (ptr_transcription_start, ptr_transcription_end, ptr_translation_start, ptr_translation_end) in data: new_al = AlignmentTranslation( transcription_id=transcription.id, translation_id=translation.id, ptr_transcription_start=ptr_transcription_start, ptr_transcription_end=ptr_transcription_end, ptr_translation_start=ptr_translation_start, ptr_translation_end=ptr_translation_end) db.session.add(new_al) ptrs.append( (new_al.ptr_transcription_start, new_al.ptr_transcription_end, new_al.ptr_translation_start, new_al.ptr_translation_end)) db.session.commit() except Exception as e: db.session.rollback() print(str(e)) return make_400(str(e)) return make_200(data=ptrs)
def api_speech_part_type(api_version, speech_part_type_id=None): if speech_part_type_id is None: speech_part_types = SpeechPartType.query.all() else: # single at = SpeechPartType.query.filter( SpeechPartType.id == speech_part_type_id).first() if at is None: return make_404( "SpeechPartType {0} not found".format(speech_part_type_id)) else: speech_part_types = [at] return make_200([a.serialize() for a in speech_part_types])
def api_commentary_type(api_version, commentary_type_id=None): if commentary_type_id is None: commentary_types = CommentaryType.query.all() else: # single at = CommentaryType.query.filter( CommentaryType.id == commentary_type_id).first() if at is None: return make_404( "CommentaryType {0} not found".format(commentary_type_id)) else: commentary_types = [at] return make_200([a.serialize() for a in commentary_types])
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 api_delete_language(api_version, language_code=None): if language_code is None: languages = Language.query.all() else: languages = Language.query.filter(Language.code == language_code).all() for a in languages: db.session.delete(a) try: db.session.commit() return make_200([]) except Exception as e: db.session.rollback() return make_400(str(e))