from datetime import datetime from flask import abort, current_app, request, url_for from flask_login import current_user from threading import Thread from .decorators import corpus_follower_permission_required, corpus_owner_or_admin_required from app import db, hashids from app.decorators import content_negotiation from app.models import Corpus, CorpusFollowerRole from . import bp @bp.route('/', methods=['DELETE']) @corpus_owner_or_admin_required @content_negotiation(produces='application/json') def delete_corpus(corpus_id): def _delete_corpus(app, corpus_id): with app.app_context(): corpus = Corpus.query.get(corpus_id) corpus.delete() db.session.commit() corpus = Corpus.query.get_or_404(corpus_id) thread = Thread( target=_delete_corpus, args=(current_app._get_current_object(), corpus.id) ) thread.start() response_data = { 'message': f'Corpus "{corpus.title}" marked for deletion', 'category': 'corpus' } return response_data, 200 @bp.route('//build', methods=['POST']) @corpus_owner_or_admin_required @content_negotiation(produces='application/json') def build_corpus(corpus_id): def _build_corpus(app, corpus_id): with app.app_context(): corpus = Corpus.query.get(corpus_id) corpus.build() db.session.commit() corpus = Corpus.query.get_or_404(corpus_id) if len(corpus.files.all()) == 0: abort(409) thread = Thread( target=_build_corpus, args=(current_app._get_current_object(), corpus_id) ) thread.start() response_data = { 'message': f'Corpus "{corpus.title}" marked for building', 'category': 'corpus' } return response_data, 202 @bp.route('//generate-share-link', methods=['POST']) @corpus_follower_permission_required('GENERATE_SHARE_LINK') @content_negotiation(consumes='application/json', produces='application/json') def generate_corpus_share_link(corpus_id): corpus_hashid = hashids.encode(corpus_id) data = request.json if not isinstance(data, dict): abort(400) expiration = data.get('expiration') if not isinstance(expiration, str): abort(400) role_name = data.get('role') if not isinstance(role_name, str): abort(400) expiration_date = datetime.strptime(expiration, '%b %d, %Y') cfr = CorpusFollowerRole.query.filter_by(name=role_name).first() if cfr is None: abort(400) token = current_user.generate_follow_corpus_token(corpus_hashid, role_name, expiration_date) corpus_share_link = url_for( 'corpora.follow_corpus', corpus_id=corpus_id, token=token, _external=True ) response_data = { 'message': 'Corpus share link generated', 'category': 'corpus', 'corpusShareLink': corpus_share_link } return response_data, 200 @bp.route('//is_public', methods=['PUT']) @corpus_owner_or_admin_required @content_negotiation(consumes='application/json', produces='application/json') def update_corpus_is_public(corpus_id): is_public = request.json if not isinstance(is_public, bool): abort(400) corpus = Corpus.query.get_or_404(corpus_id) corpus.is_public = is_public db.session.commit() response_data = { 'message': ( f'Corpus "{corpus.title}" is now' f' {"public" if is_public else "private"}' ), 'category': 'corpus' } return response_data, 200