mirror of
				https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque.git
				synced 2025-11-04 12:22:47 +00:00 
			
		
		
		
	make is_administrator a property, add back db events
This commit is contained in:
		@@ -77,7 +77,7 @@ def delete_job(job_id):
 | 
				
			|||||||
    job = Job.query.get(job_id)
 | 
					    job = Job.query.get(job_id)
 | 
				
			||||||
    if job is None:
 | 
					    if job is None:
 | 
				
			||||||
        abort(404)
 | 
					        abort(404)
 | 
				
			||||||
    if not (job.user == current_user or current_user.is_administrator()):
 | 
					    if not (job.user == current_user or current_user.is_administrator):
 | 
				
			||||||
        abort(403)
 | 
					        abort(403)
 | 
				
			||||||
    try:
 | 
					    try:
 | 
				
			||||||
        job.delete()
 | 
					        job.delete()
 | 
				
			||||||
@@ -97,6 +97,6 @@ def get_job(job_id):
 | 
				
			|||||||
    job = Job.query.get(job_id)
 | 
					    job = Job.query.get(job_id)
 | 
				
			||||||
    if job is None:
 | 
					    if job is None:
 | 
				
			||||||
        abort(404)
 | 
					        abort(404)
 | 
				
			||||||
    if not (job.user == current_user or current_user.is_administrator()):
 | 
					    if not (job.user == current_user or current_user.is_administrator):
 | 
				
			||||||
        abort(403)
 | 
					        abort(403)
 | 
				
			||||||
    return job
 | 
					    return job
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -60,7 +60,7 @@ def delete_user(user_id):
 | 
				
			|||||||
    user = User.query.get(user_id)
 | 
					    user = User.query.get(user_id)
 | 
				
			||||||
    if user is None:
 | 
					    if user is None:
 | 
				
			||||||
        abort(404)
 | 
					        abort(404)
 | 
				
			||||||
    if not (user == current_user or current_user.is_administrator()):
 | 
					    if not (user == current_user or current_user.is_administrator):
 | 
				
			||||||
        abort(403)
 | 
					        abort(403)
 | 
				
			||||||
    user.delete()
 | 
					    user.delete()
 | 
				
			||||||
    db.session.commit()
 | 
					    db.session.commit()
 | 
				
			||||||
@@ -78,7 +78,7 @@ def get_user(user_id):
 | 
				
			|||||||
    user = User.query.get(user_id)
 | 
					    user = User.query.get(user_id)
 | 
				
			||||||
    if user is None:
 | 
					    if user is None:
 | 
				
			||||||
        abort(404)
 | 
					        abort(404)
 | 
				
			||||||
    if not (user == current_user or current_user.is_administrator()):
 | 
					    if not (user == current_user or current_user.is_administrator):
 | 
				
			||||||
        abort(403)
 | 
					        abort(403)
 | 
				
			||||||
    return user
 | 
					    return user
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -94,6 +94,6 @@ def get_user_by_username(username):
 | 
				
			|||||||
    user = User.query.filter(User.username == username).first()
 | 
					    user = User.query.filter(User.username == username).first()
 | 
				
			||||||
    if user is None:
 | 
					    if user is None:
 | 
				
			||||||
        abort(404)
 | 
					        abort(404)
 | 
				
			||||||
    if not (user == current_user or current_user.is_administrator()):
 | 
					    if not (user == current_user or current_user.is_administrator):
 | 
				
			||||||
        abort(403)
 | 
					        abort(403)
 | 
				
			||||||
    return user
 | 
					    return user
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,7 +17,7 @@ def delete_spacy_model(spacy_nlp_pipeline_model_id):
 | 
				
			|||||||
            db.session.commit()
 | 
					            db.session.commit()
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    snpm = SpaCyNLPPipelineModel.query.get_or_404(spacy_nlp_pipeline_model_id)
 | 
					    snpm = SpaCyNLPPipelineModel.query.get_or_404(spacy_nlp_pipeline_model_id)
 | 
				
			||||||
    if not (snpm.user == current_user or current_user.is_administrator()):
 | 
					    if not (snpm.user == current_user or current_user.is_administrator):
 | 
				
			||||||
        abort(403)
 | 
					        abort(403)
 | 
				
			||||||
    thread = Thread(
 | 
					    thread = Thread(
 | 
				
			||||||
        target=_delete_spacy_model,
 | 
					        target=_delete_spacy_model,
 | 
				
			||||||
@@ -39,7 +39,7 @@ def update_spacy_nlp_pipeline_model_is_public(spacy_nlp_pipeline_model_id):
 | 
				
			|||||||
    if not isinstance(is_public, bool):
 | 
					    if not isinstance(is_public, bool):
 | 
				
			||||||
        abort(400)
 | 
					        abort(400)
 | 
				
			||||||
    snpm = SpaCyNLPPipelineModel.query.get_or_404(spacy_nlp_pipeline_model_id)
 | 
					    snpm = SpaCyNLPPipelineModel.query.get_or_404(spacy_nlp_pipeline_model_id)
 | 
				
			||||||
    if not (snpm.user == current_user or current_user.is_administrator()):
 | 
					    if not (snpm.user == current_user or current_user.is_administrator):
 | 
				
			||||||
        abort(403)
 | 
					        abort(403)
 | 
				
			||||||
    snpm.is_public = is_public
 | 
					    snpm.is_public = is_public
 | 
				
			||||||
    db.session.commit()
 | 
					    db.session.commit()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -58,7 +58,7 @@ def create_spacy_nlp_pipeline_model():
 | 
				
			|||||||
@register_breadcrumb(bp, '.spacy_nlp_pipeline_models.entity', '', dynamic_list_constructor=spacy_nlp_pipeline_model_dlc)
 | 
					@register_breadcrumb(bp, '.spacy_nlp_pipeline_models.entity', '', dynamic_list_constructor=spacy_nlp_pipeline_model_dlc)
 | 
				
			||||||
def spacy_nlp_pipeline_model(spacy_nlp_pipeline_model_id):
 | 
					def spacy_nlp_pipeline_model(spacy_nlp_pipeline_model_id):
 | 
				
			||||||
    snpm = SpaCyNLPPipelineModel.query.get_or_404(spacy_nlp_pipeline_model_id)
 | 
					    snpm = SpaCyNLPPipelineModel.query.get_or_404(spacy_nlp_pipeline_model_id)
 | 
				
			||||||
    if not (snpm.user == current_user or current_user.is_administrator()):
 | 
					    if not (snpm.user == current_user or current_user.is_administrator):
 | 
				
			||||||
        abort(403)
 | 
					        abort(403)
 | 
				
			||||||
    form = UpdateSpaCyNLPPipelineModelForm(data=snpm.to_json_serializeable())
 | 
					    form = UpdateSpaCyNLPPipelineModelForm(data=snpm.to_json_serializeable())
 | 
				
			||||||
    if form.validate_on_submit():
 | 
					    if form.validate_on_submit():
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,7 +17,7 @@ def delete_tesseract_model(tesseract_ocr_pipeline_model_id):
 | 
				
			|||||||
            db.session.commit()
 | 
					            db.session.commit()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    topm = TesseractOCRPipelineModel.query.get_or_404(tesseract_ocr_pipeline_model_id)
 | 
					    topm = TesseractOCRPipelineModel.query.get_or_404(tesseract_ocr_pipeline_model_id)
 | 
				
			||||||
    if not (topm.user == current_user or current_user.is_administrator()):
 | 
					    if not (topm.user == current_user or current_user.is_administrator):
 | 
				
			||||||
        abort(403)
 | 
					        abort(403)
 | 
				
			||||||
    thread = Thread(
 | 
					    thread = Thread(
 | 
				
			||||||
        target=_delete_tesseract_ocr_pipeline_model,
 | 
					        target=_delete_tesseract_ocr_pipeline_model,
 | 
				
			||||||
@@ -39,7 +39,7 @@ def update_tesseract_ocr_pipeline_model_is_public(tesseract_ocr_pipeline_model_i
 | 
				
			|||||||
    if not isinstance(is_public, bool):
 | 
					    if not isinstance(is_public, bool):
 | 
				
			||||||
        abort(400)
 | 
					        abort(400)
 | 
				
			||||||
    topm = TesseractOCRPipelineModel.query.get_or_404(tesseract_ocr_pipeline_model_id)
 | 
					    topm = TesseractOCRPipelineModel.query.get_or_404(tesseract_ocr_pipeline_model_id)
 | 
				
			||||||
    if not (topm.user == current_user or current_user.is_administrator()):
 | 
					    if not (topm.user == current_user or current_user.is_administrator):
 | 
				
			||||||
        abort(403)
 | 
					        abort(403)
 | 
				
			||||||
    topm.is_public = is_public
 | 
					    topm.is_public = is_public
 | 
				
			||||||
    db.session.commit()
 | 
					    db.session.commit()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -57,7 +57,7 @@ def create_tesseract_ocr_pipeline_model():
 | 
				
			|||||||
@register_breadcrumb(bp, '.tesseract_ocr_pipeline_models.entity', '', dynamic_list_constructor=tesseract_ocr_pipeline_model_dlc)
 | 
					@register_breadcrumb(bp, '.tesseract_ocr_pipeline_models.entity', '', dynamic_list_constructor=tesseract_ocr_pipeline_model_dlc)
 | 
				
			||||||
def tesseract_ocr_pipeline_model(tesseract_ocr_pipeline_model_id):
 | 
					def tesseract_ocr_pipeline_model(tesseract_ocr_pipeline_model_id):
 | 
				
			||||||
    topm = TesseractOCRPipelineModel.query.get_or_404(tesseract_ocr_pipeline_model_id)
 | 
					    topm = TesseractOCRPipelineModel.query.get_or_404(tesseract_ocr_pipeline_model_id)
 | 
				
			||||||
    if not (topm.user == current_user or current_user.is_administrator()):
 | 
					    if not (topm.user == current_user or current_user.is_administrator):
 | 
				
			||||||
        abort(403)
 | 
					        abort(403)
 | 
				
			||||||
    form = UpdateTesseractOCRPipelineModelForm(data=topm.to_json_serializeable())
 | 
					    form = UpdateTesseractOCRPipelineModelForm(data=topm.to_json_serializeable())
 | 
				
			||||||
    if form.validate_on_submit():
 | 
					    if form.validate_on_submit():
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -99,7 +99,7 @@ class CQiNamespace(Namespace):
 | 
				
			|||||||
            return {'code': 404, 'msg': 'Not Found'}
 | 
					            return {'code': 404, 'msg': 'Not Found'}
 | 
				
			||||||
        if not (db_corpus.user == current_user
 | 
					        if not (db_corpus.user == current_user
 | 
				
			||||||
                or current_user.is_following_corpus(db_corpus)
 | 
					                or current_user.is_following_corpus(db_corpus)
 | 
				
			||||||
                or current_user.is_administrator()):
 | 
					                or current_user.is_administrator):
 | 
				
			||||||
            return {'code': 403, 'msg': 'Forbidden'}
 | 
					            return {'code': 403, 'msg': 'Forbidden'}
 | 
				
			||||||
        if db_corpus.status not in [
 | 
					        if db_corpus.status not in [
 | 
				
			||||||
            CorpusStatus.BUILT,
 | 
					            CorpusStatus.BUILT,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,7 +10,7 @@ def corpus_follower_permission_required(*permissions):
 | 
				
			|||||||
        def decorated_function(*args, **kwargs):
 | 
					        def decorated_function(*args, **kwargs):
 | 
				
			||||||
            corpus_id = kwargs.get('corpus_id')
 | 
					            corpus_id = kwargs.get('corpus_id')
 | 
				
			||||||
            corpus = Corpus.query.get_or_404(corpus_id)
 | 
					            corpus = Corpus.query.get_or_404(corpus_id)
 | 
				
			||||||
            if not (corpus.user == current_user or current_user.is_administrator()):
 | 
					            if not (corpus.user == current_user or current_user.is_administrator):
 | 
				
			||||||
                cfa = CorpusFollowerAssociation.query.filter_by(corpus_id=corpus_id, follower_id=current_user.id).first()
 | 
					                cfa = CorpusFollowerAssociation.query.filter_by(corpus_id=corpus_id, follower_id=current_user.id).first()
 | 
				
			||||||
                if cfa is None:
 | 
					                if cfa is None:
 | 
				
			||||||
                    abort(403)
 | 
					                    abort(403)
 | 
				
			||||||
@@ -26,7 +26,7 @@ def corpus_owner_or_admin_required(f):
 | 
				
			|||||||
    def decorated_function(*args, **kwargs):
 | 
					    def decorated_function(*args, **kwargs):
 | 
				
			||||||
        corpus_id = kwargs.get('corpus_id')
 | 
					        corpus_id = kwargs.get('corpus_id')
 | 
				
			||||||
        corpus = Corpus.query.get_or_404(corpus_id)
 | 
					        corpus = Corpus.query.get_or_404(corpus_id)
 | 
				
			||||||
        if not (corpus.user == current_user or current_user.is_administrator()):
 | 
					        if not (corpus.user == current_user or current_user.is_administrator):
 | 
				
			||||||
            abort(403)
 | 
					            abort(403)
 | 
				
			||||||
        return f(*args, **kwargs)
 | 
					        return f(*args, **kwargs)
 | 
				
			||||||
    return decorated_function
 | 
					    return decorated_function
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,7 @@ def get_corpus(corpus_hashid):
 | 
				
			|||||||
    if not (
 | 
					    if not (
 | 
				
			||||||
        corpus.is_public
 | 
					        corpus.is_public
 | 
				
			||||||
        or corpus.user == current_user
 | 
					        or corpus.user == current_user
 | 
				
			||||||
        or current_user.is_administrator()
 | 
					        or current_user.is_administrator
 | 
				
			||||||
    ):
 | 
					    ):
 | 
				
			||||||
        return {'options': {'status': 403, 'statusText': 'Forbidden'}}
 | 
					        return {'options': {'status': 403, 'statusText': 'Forbidden'}}
 | 
				
			||||||
    return {
 | 
					    return {
 | 
				
			||||||
@@ -38,7 +38,7 @@ def subscribe_corpus(corpus_hashid):
 | 
				
			|||||||
    if not (
 | 
					    if not (
 | 
				
			||||||
        corpus.is_public
 | 
					        corpus.is_public
 | 
				
			||||||
        or corpus.user == current_user
 | 
					        or corpus.user == current_user
 | 
				
			||||||
        or current_user.is_administrator()
 | 
					        or current_user.is_administrator
 | 
				
			||||||
    ):
 | 
					    ):
 | 
				
			||||||
        return {'options': {'status': 403, 'statusText': 'Forbidden'}}
 | 
					        return {'options': {'status': 403, 'statusText': 'Forbidden'}}
 | 
				
			||||||
    join_room(f'/corpora/{corpus.hashid}')
 | 
					    join_room(f'/corpora/{corpus.hashid}')
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -58,7 +58,7 @@ def delete_corpus_follower(corpus_id, follower_id):
 | 
				
			|||||||
        current_user.id == follower_id
 | 
					        current_user.id == follower_id
 | 
				
			||||||
        or current_user == cfa.corpus.user 
 | 
					        or current_user == cfa.corpus.user 
 | 
				
			||||||
        or CorpusFollowerAssociation.query.filter_by(corpus_id=corpus_id, follower_id=current_user.id).first().role.has_permission('MANAGE_FOLLOWERS')
 | 
					        or CorpusFollowerAssociation.query.filter_by(corpus_id=corpus_id, follower_id=current_user.id).first().role.has_permission('MANAGE_FOLLOWERS')
 | 
				
			||||||
        or current_user.is_administrator()):
 | 
					        or current_user.is_administrator):
 | 
				
			||||||
        abort(403)
 | 
					        abort(403)
 | 
				
			||||||
    if current_user.id == follower_id:
 | 
					    if current_user.id == follower_id:
 | 
				
			||||||
        flash(f'You are no longer following "{cfa.corpus.title}"', 'corpus')
 | 
					        flash(f'You are no longer following "{cfa.corpus.title}"', 'corpus')
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -55,13 +55,13 @@ def corpus(corpus_id):
 | 
				
			|||||||
    users = User.query.filter(User.is_public == True, User.id != current_user.id, User.id != corpus.user.id, User.role_id < 4).all()
 | 
					    users = User.query.filter(User.is_public == True, User.id != current_user.id, User.id != corpus.user.id, User.role_id < 4).all()
 | 
				
			||||||
    cfa = CorpusFollowerAssociation.query.filter_by(corpus_id=corpus_id, follower_id=current_user.id).first()
 | 
					    cfa = CorpusFollowerAssociation.query.filter_by(corpus_id=corpus_id, follower_id=current_user.id).first()
 | 
				
			||||||
    if cfa is None:
 | 
					    if cfa is None:
 | 
				
			||||||
        if corpus.user == current_user or current_user.is_administrator():
 | 
					        if corpus.user == current_user or current_user.is_administrator:
 | 
				
			||||||
            cfr = CorpusFollowerRole.query.filter_by(name='Administrator').first()
 | 
					            cfr = CorpusFollowerRole.query.filter_by(name='Administrator').first()
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            cfr = CorpusFollowerRole.query.filter_by(name='Anonymous').first()
 | 
					            cfr = CorpusFollowerRole.query.filter_by(name='Anonymous').first()
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
        cfr = cfa.role
 | 
					        cfr = cfa.role
 | 
				
			||||||
    if corpus.user == current_user or current_user.is_administrator():
 | 
					    if corpus.user == current_user or current_user.is_administrator:
 | 
				
			||||||
        return render_template(
 | 
					        return render_template(
 | 
				
			||||||
            'corpora/corpus.html.j2',
 | 
					            'corpora/corpus.html.j2',
 | 
				
			||||||
            title=corpus.title,
 | 
					            title=corpus.title,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,7 +17,7 @@ def delete_job(job_id):
 | 
				
			|||||||
            db.session.commit()
 | 
					            db.session.commit()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    job = Job.query.get_or_404(job_id)
 | 
					    job = Job.query.get_or_404(job_id)
 | 
				
			||||||
    if not (job.user == current_user or current_user.is_administrator()):
 | 
					    if not (job.user == current_user or current_user.is_administrator):
 | 
				
			||||||
        abort(403)
 | 
					        abort(403)
 | 
				
			||||||
    thread = Thread(
 | 
					    thread = Thread(
 | 
				
			||||||
        target=_delete_job,
 | 
					        target=_delete_job,
 | 
				
			||||||
@@ -56,7 +56,7 @@ def restart_job(job_id):
 | 
				
			|||||||
            db.session.commit()
 | 
					            db.session.commit()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    job = Job.query.get_or_404(job_id)
 | 
					    job = Job.query.get_or_404(job_id)
 | 
				
			||||||
    if not (job.user == current_user or current_user.is_administrator()):
 | 
					    if not (job.user == current_user or current_user.is_administrator):
 | 
				
			||||||
        abort(403)
 | 
					        abort(403)
 | 
				
			||||||
    if job.status == JobStatus.FAILED:
 | 
					    if job.status == JobStatus.FAILED:
 | 
				
			||||||
        response = {'errors': {'message': 'Job status is not "failed"'}}
 | 
					        response = {'errors': {'message': 'Job status is not "failed"'}}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,7 +22,7 @@ def corpora():
 | 
				
			|||||||
@register_breadcrumb(bp, '.entity', '', dynamic_list_constructor=job_dlc)
 | 
					@register_breadcrumb(bp, '.entity', '', dynamic_list_constructor=job_dlc)
 | 
				
			||||||
def job(job_id):
 | 
					def job(job_id):
 | 
				
			||||||
    job = Job.query.get_or_404(job_id)
 | 
					    job = Job.query.get_or_404(job_id)
 | 
				
			||||||
    if not (job.user == current_user or current_user.is_administrator()):
 | 
					    if not (job.user == current_user or current_user.is_administrator):
 | 
				
			||||||
        abort(403)
 | 
					        abort(403)
 | 
				
			||||||
    return render_template(
 | 
					    return render_template(
 | 
				
			||||||
        'jobs/job.html.j2',
 | 
					        'jobs/job.html.j2',
 | 
				
			||||||
@@ -34,7 +34,7 @@ def job(job_id):
 | 
				
			|||||||
@bp.route('/<hashid:job_id>/inputs/<hashid:job_input_id>/download')
 | 
					@bp.route('/<hashid:job_id>/inputs/<hashid:job_input_id>/download')
 | 
				
			||||||
def download_job_input(job_id, job_input_id):
 | 
					def download_job_input(job_id, job_input_id):
 | 
				
			||||||
    job_input = JobInput.query.filter_by(job_id=job_id, id=job_input_id).first_or_404()
 | 
					    job_input = JobInput.query.filter_by(job_id=job_id, id=job_input_id).first_or_404()
 | 
				
			||||||
    if not (job_input.job.user == current_user or current_user.is_administrator()):
 | 
					    if not (job_input.job.user == current_user or current_user.is_administrator):
 | 
				
			||||||
        abort(403)
 | 
					        abort(403)
 | 
				
			||||||
    return send_from_directory(
 | 
					    return send_from_directory(
 | 
				
			||||||
        job_input.path.parent,
 | 
					        job_input.path.parent,
 | 
				
			||||||
@@ -48,7 +48,7 @@ def download_job_input(job_id, job_input_id):
 | 
				
			|||||||
@bp.route('/<hashid:job_id>/results/<hashid:job_result_id>/download')
 | 
					@bp.route('/<hashid:job_id>/results/<hashid:job_result_id>/download')
 | 
				
			||||||
def download_job_result(job_id, job_result_id):
 | 
					def download_job_result(job_id, job_result_id):
 | 
				
			||||||
    job_result = JobResult.query.filter_by(job_id=job_id, id=job_result_id).first_or_404()
 | 
					    job_result = JobResult.query.filter_by(job_id=job_id, id=job_result_id).first_or_404()
 | 
				
			||||||
    if not (job_result.job.user == current_user or current_user.is_administrator()):
 | 
					    if not (job_result.job.user == current_user or current_user.is_administrator):
 | 
				
			||||||
        abort(403)
 | 
					        abort(403)
 | 
				
			||||||
    return send_from_directory(
 | 
					    return send_from_directory(
 | 
				
			||||||
        job_result.path.parent,
 | 
					        job_result.path.parent,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,6 @@
 | 
				
			|||||||
 | 
					from enum import Enum
 | 
				
			||||||
 | 
					from app import db, login, mail, socketio
 | 
				
			||||||
 | 
					from app.email import create_message
 | 
				
			||||||
from .avatar import *
 | 
					from .avatar import *
 | 
				
			||||||
from .corpus_file import *
 | 
					from .corpus_file import *
 | 
				
			||||||
from .corpus_follower_association import *
 | 
					from .corpus_follower_association import *
 | 
				
			||||||
@@ -11,7 +14,132 @@ from .spacy_nlp_pipeline_model import *
 | 
				
			|||||||
from .tesseract_ocr_pipeline_model import *
 | 
					from .tesseract_ocr_pipeline_model import *
 | 
				
			||||||
from .token import *
 | 
					from .token import *
 | 
				
			||||||
from .user import *
 | 
					from .user import *
 | 
				
			||||||
from app import login
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@db.event.listens_for(Corpus, 'after_delete')
 | 
				
			||||||
 | 
					@db.event.listens_for(CorpusFile, 'after_delete')
 | 
				
			||||||
 | 
					@db.event.listens_for(Job, 'after_delete')
 | 
				
			||||||
 | 
					@db.event.listens_for(JobInput, 'after_delete')
 | 
				
			||||||
 | 
					@db.event.listens_for(JobResult, 'after_delete')
 | 
				
			||||||
 | 
					@db.event.listens_for(SpaCyNLPPipelineModel, 'after_delete')
 | 
				
			||||||
 | 
					@db.event.listens_for(TesseractOCRPipelineModel, 'after_delete')
 | 
				
			||||||
 | 
					def resource_after_delete(mapper, connection, resource):
 | 
				
			||||||
 | 
					    print('[START] resource_after_delete')
 | 
				
			||||||
 | 
					    jsonpatch = [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            'op': 'remove',
 | 
				
			||||||
 | 
					            'path': resource.jsonpatch_path
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					    room = f'/users/{resource.user_hashid}'
 | 
				
			||||||
 | 
					    print('[EMIT] PATCH', jsonpatch)
 | 
				
			||||||
 | 
					    socketio.emit('PATCH', jsonpatch, room=room)
 | 
				
			||||||
 | 
					    print('[END] resource_after_delete')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@db.event.listens_for(CorpusFollowerAssociation, 'after_delete')
 | 
				
			||||||
 | 
					def cfa_after_delete_handler(mapper, connection, cfa):
 | 
				
			||||||
 | 
					    jsonpatch_path = f'/users/{cfa.corpus.user.hashid}/corpora/{cfa.corpus.hashid}/corpus_follower_associations/{cfa.hashid}'
 | 
				
			||||||
 | 
					    jsonpatch = [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            'op': 'remove',
 | 
				
			||||||
 | 
					            'path': jsonpatch_path
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					    room = f'/users/{cfa.corpus.user.hashid}'
 | 
				
			||||||
 | 
					    socketio.emit('PATCH', jsonpatch, room=room)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@db.event.listens_for(Corpus, 'after_insert')
 | 
				
			||||||
 | 
					@db.event.listens_for(CorpusFile, 'after_insert')
 | 
				
			||||||
 | 
					@db.event.listens_for(Job, 'after_insert')
 | 
				
			||||||
 | 
					@db.event.listens_for(JobInput, 'after_insert')
 | 
				
			||||||
 | 
					@db.event.listens_for(JobResult, 'after_insert')
 | 
				
			||||||
 | 
					@db.event.listens_for(SpaCyNLPPipelineModel, 'after_insert')
 | 
				
			||||||
 | 
					@db.event.listens_for(TesseractOCRPipelineModel, 'after_insert')
 | 
				
			||||||
 | 
					def resource_after_insert_handler(mapper, connection, resource):
 | 
				
			||||||
 | 
					    jsonpatch_value = resource.to_json_serializeable()
 | 
				
			||||||
 | 
					    for attr in mapper.relationships:
 | 
				
			||||||
 | 
					        jsonpatch_value[attr.key] = {}
 | 
				
			||||||
 | 
					    jsonpatch = [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            'op': 'add',
 | 
				
			||||||
 | 
					            'path': resource.jsonpatch_path,
 | 
				
			||||||
 | 
					            'value': jsonpatch_value
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					    room = f'/users/{resource.user_hashid}'
 | 
				
			||||||
 | 
					    socketio.emit('PATCH', jsonpatch, room=room)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@db.event.listens_for(CorpusFollowerAssociation, 'after_insert')
 | 
				
			||||||
 | 
					def cfa_after_insert_handler(mapper, connection, cfa):
 | 
				
			||||||
 | 
					    jsonpatch_value = cfa.to_json_serializeable()
 | 
				
			||||||
 | 
					    jsonpatch_path = f'/users/{cfa.corpus.user.hashid}/corpora/{cfa.corpus.hashid}/corpus_follower_associations/{cfa.hashid}'
 | 
				
			||||||
 | 
					    jsonpatch = [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            'op': 'add',
 | 
				
			||||||
 | 
					            'path': jsonpatch_path,
 | 
				
			||||||
 | 
					            'value': jsonpatch_value
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					    room = f'/users/{cfa.corpus.user.hashid}'
 | 
				
			||||||
 | 
					    socketio.emit('PATCH', jsonpatch, room=room)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@db.event.listens_for(Corpus, 'after_update')
 | 
				
			||||||
 | 
					@db.event.listens_for(CorpusFile, 'after_update')
 | 
				
			||||||
 | 
					@db.event.listens_for(Job, 'after_update')
 | 
				
			||||||
 | 
					@db.event.listens_for(JobInput, 'after_update')
 | 
				
			||||||
 | 
					@db.event.listens_for(JobResult, 'after_update')
 | 
				
			||||||
 | 
					@db.event.listens_for(SpaCyNLPPipelineModel, 'after_update')
 | 
				
			||||||
 | 
					@db.event.listens_for(TesseractOCRPipelineModel, 'after_update')
 | 
				
			||||||
 | 
					def resource_after_update_handler(mapper, connection, resource):
 | 
				
			||||||
 | 
					    jsonpatch = []
 | 
				
			||||||
 | 
					    for attr in db.inspect(resource).attrs:
 | 
				
			||||||
 | 
					        if attr.key in mapper.relationships:
 | 
				
			||||||
 | 
					            continue
 | 
				
			||||||
 | 
					        if not attr.load_history().has_changes():
 | 
				
			||||||
 | 
					            continue
 | 
				
			||||||
 | 
					        jsonpatch_path = f'{resource.jsonpatch_path}/{attr.key}'
 | 
				
			||||||
 | 
					        if isinstance(attr.value, datetime):
 | 
				
			||||||
 | 
					            jsonpatch_value = f'{attr.value.isoformat()}Z'
 | 
				
			||||||
 | 
					        elif isinstance(attr.value, Enum):
 | 
				
			||||||
 | 
					            jsonpatch_value = attr.value.name
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            jsonpatch_value = attr.value
 | 
				
			||||||
 | 
					        jsonpatch.append(
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                'op': 'replace',
 | 
				
			||||||
 | 
					                'path': jsonpatch_path,
 | 
				
			||||||
 | 
					                'value': jsonpatch_value
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					    if jsonpatch:
 | 
				
			||||||
 | 
					        room = f'/users/{resource.user_hashid}'
 | 
				
			||||||
 | 
					        socketio.emit('PATCH', jsonpatch, room=room)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@db.event.listens_for(Job, 'after_update')
 | 
				
			||||||
 | 
					def job_after_update_handler(mapper, connection, job):
 | 
				
			||||||
 | 
					    for attr in db.inspect(job).attrs:
 | 
				
			||||||
 | 
					        if attr.key != 'status':
 | 
				
			||||||
 | 
					            continue
 | 
				
			||||||
 | 
					        if not attr.load_history().has_changes():
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					        if job.user.setting_job_status_mail_notification_level == UserSettingJobStatusMailNotificationLevel.NONE:
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					        if job.user.setting_job_status_mail_notification_level == UserSettingJobStatusMailNotificationLevel.END:
 | 
				
			||||||
 | 
					            if job.status not in [JobStatus.COMPLETED, JobStatus.FAILED]:
 | 
				
			||||||
 | 
					                return
 | 
				
			||||||
 | 
					        msg = create_message(
 | 
				
			||||||
 | 
					            job.user.email,
 | 
				
			||||||
 | 
					            f'Status update for your Job "{job.title}"',
 | 
				
			||||||
 | 
					            'tasks/email/notification',
 | 
				
			||||||
 | 
					            job=job
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        mail.send(msg)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@login.user_loader
 | 
					@login.user_loader
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -132,6 +132,10 @@ class User(HashidMixin, UserMixin, db.Model):
 | 
				
			|||||||
    def __repr__(self):
 | 
					    def __repr__(self):
 | 
				
			||||||
        return f'<User {self.username}>'
 | 
					        return f'<User {self.username}>'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def is_administrator(self):
 | 
				
			||||||
 | 
					        return self.can(Permission.ADMINISTRATE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def jsonpatch_path(self):
 | 
					    def jsonpatch_path(self):
 | 
				
			||||||
        return f'/users/{self.hashid}'
 | 
					        return f'/users/{self.hashid}'
 | 
				
			||||||
@@ -294,9 +298,6 @@ class User(HashidMixin, UserMixin, db.Model):
 | 
				
			|||||||
            algorithm='HS256'
 | 
					            algorithm='HS256'
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def is_administrator(self):
 | 
					 | 
				
			||||||
        return self.can(Permission.ADMINISTRATE)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def ping(self):
 | 
					    def ping(self):
 | 
				
			||||||
        self.last_seen = datetime.utcnow()
 | 
					        self.last_seen = datetime.utcnow()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -120,7 +120,7 @@
 | 
				
			|||||||
{% block modals %}
 | 
					{% block modals %}
 | 
				
			||||||
{{ super() }}
 | 
					{{ super() }}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{% if current_user == corpus.user or current_user.is_administrator() %}
 | 
					{% if current_user == corpus.user or current_user.is_administrator %}
 | 
				
			||||||
<div class="modal" id="publishing-modal">
 | 
					<div class="modal" id="publishing-modal">
 | 
				
			||||||
  <div class="modal-content">
 | 
					  <div class="modal-content">
 | 
				
			||||||
    <h4>Change your Corpus publishing status</h4>
 | 
					    <h4>Change your Corpus publishing status</h4>
 | 
				
			||||||
@@ -247,7 +247,7 @@
 | 
				
			|||||||
  });
 | 
					  });
 | 
				
			||||||
{% endif %}
 | 
					{% endif %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{% if current_user == corpus.user or current_user.is_administrator() %}
 | 
					{% if current_user == corpus.user or current_user.is_administrator %}
 | 
				
			||||||
// #region Publishing
 | 
					// #region Publishing
 | 
				
			||||||
let publishingModalIsPublicSwitchElement = document.querySelector('#publishing-modal-is-public-switch');
 | 
					let publishingModalIsPublicSwitchElement = document.querySelector('#publishing-modal-is-public-switch');
 | 
				
			||||||
publishingModalIsPublicSwitchElement.addEventListener('change', (event) => {
 | 
					publishingModalIsPublicSwitchElement.addEventListener('change', (event) => {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -77,7 +77,7 @@
 | 
				
			|||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <div class="card-action right-align">
 | 
					        <div class="card-action right-align">
 | 
				
			||||||
          {% if current_user.is_administrator()  %}
 | 
					          {% if current_user.is_administrator %}
 | 
				
			||||||
          <a class="action-button btn disabled waves-effect waves-light modal-trigger" data-action="get-log-request" id="job-log-button" href="#job-log-modal"><i class="material-icons left">text_snippet</i>Log</a>
 | 
					          <a class="action-button btn disabled waves-effect waves-light modal-trigger" data-action="get-log-request" id="job-log-button" href="#job-log-modal"><i class="material-icons left">text_snippet</i>Log</a>
 | 
				
			||||||
          {% endif %}
 | 
					          {% endif %}
 | 
				
			||||||
          <a class="btn disabled waves-effect waves-light modal-trigger" href="#restart-job-modal"><i class="material-icons left">repeat</i>Restart</a>
 | 
					          <a class="btn disabled waves-effect waves-light modal-trigger" href="#restart-job-modal"><i class="material-icons left">repeat</i>Restart</a>
 | 
				
			||||||
@@ -159,7 +159,7 @@
 | 
				
			|||||||
      nopaque.requests.jobs.entity.restart({{ job.hashid|tojson }});
 | 
					      nopaque.requests.jobs.entity.restart({{ job.hashid|tojson }});
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ({{ current_user.is_administrator()|tojson }}) {
 | 
					  if ({{ current_user.is_administrator|tojson }}) {
 | 
				
			||||||
    let jobLogButtonElement = document.querySelector('#job-log-button');
 | 
					    let jobLogButtonElement = document.querySelector('#job-log-button');
 | 
				
			||||||
    jobLogButtonElement.addEventListener('click', (event) => {
 | 
					    jobLogButtonElement.addEventListener('click', (event) => {
 | 
				
			||||||
      nopaque.requests.jobs.entity.log({{ job.hashid|tojson }})
 | 
					      nopaque.requests.jobs.entity.log({{ job.hashid|tojson }})
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,7 +12,7 @@ def get_user(user_hashid):
 | 
				
			|||||||
    user = User.query.get(user_id)
 | 
					    user = User.query.get(user_id)
 | 
				
			||||||
    if user is None:
 | 
					    if user is None:
 | 
				
			||||||
        return {'status': 404, 'statusText': 'Not found'}
 | 
					        return {'status': 404, 'statusText': 'Not found'}
 | 
				
			||||||
    if not (user == current_user or current_user.is_administrator()):
 | 
					    if not (user == current_user or current_user.is_administrator):
 | 
				
			||||||
        return {'status': 403, 'statusText': 'Forbidden'}
 | 
					        return {'status': 403, 'statusText': 'Forbidden'}
 | 
				
			||||||
    return {
 | 
					    return {
 | 
				
			||||||
        'body': user.to_json_serializeable(backrefs=True, relationships=True),
 | 
					        'body': user.to_json_serializeable(backrefs=True, relationships=True),
 | 
				
			||||||
@@ -28,7 +28,7 @@ def subscribe_user(user_hashid):
 | 
				
			|||||||
    user = User.query.get(user_id)
 | 
					    user = User.query.get(user_id)
 | 
				
			||||||
    if user is None:
 | 
					    if user is None:
 | 
				
			||||||
        return {'status': 404, 'statusText': 'Not found'}
 | 
					        return {'status': 404, 'statusText': 'Not found'}
 | 
				
			||||||
    if not (user == current_user or current_user.is_administrator()):
 | 
					    if not (user == current_user or current_user.is_administrator):
 | 
				
			||||||
        return {'status': 403, 'statusText': 'Forbidden'}
 | 
					        return {'status': 403, 'statusText': 'Forbidden'}
 | 
				
			||||||
    join_room(f'/users/{user.hashid}')
 | 
					    join_room(f'/users/{user.hashid}')
 | 
				
			||||||
    return {'status': 200, 'statusText': 'OK'}
 | 
					    return {'status': 200, 'statusText': 'OK'}
 | 
				
			||||||
@@ -41,7 +41,7 @@ def unsubscribe_user(user_hashid):
 | 
				
			|||||||
    user = User.query.get(user_id)
 | 
					    user = User.query.get(user_id)
 | 
				
			||||||
    if user is None:
 | 
					    if user is None:
 | 
				
			||||||
        return {'status': 404, 'statusText': 'Not found'}
 | 
					        return {'status': 404, 'statusText': 'Not found'}
 | 
				
			||||||
    if not (user == current_user or current_user.is_administrator()):
 | 
					    if not (user == current_user or current_user.is_administrator):
 | 
				
			||||||
        return {'status': 403, 'statusText': 'Forbidden'}
 | 
					        return {'status': 403, 'statusText': 'Forbidden'}
 | 
				
			||||||
    leave_room(f'/users/{user.hashid}')
 | 
					    leave_room(f'/users/{user.hashid}')
 | 
				
			||||||
    return {'status': 200, 'statusText': 'OK'}
 | 
					    return {'status': 200, 'statusText': 'OK'}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,7 +17,7 @@ def delete_user(user_id):
 | 
				
			|||||||
            db.session.commit()
 | 
					            db.session.commit()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    user = User.query.get_or_404(user_id)
 | 
					    user = User.query.get_or_404(user_id)
 | 
				
			||||||
    if not (user == current_user or current_user.is_administrator()):
 | 
					    if not (user == current_user or current_user.is_administrator):
 | 
				
			||||||
        abort(403)
 | 
					        abort(403)
 | 
				
			||||||
    thread = Thread(
 | 
					    thread = Thread(
 | 
				
			||||||
        target=_delete_user,
 | 
					        target=_delete_user,
 | 
				
			||||||
@@ -44,7 +44,7 @@ def delete_user_avatar(user_id):
 | 
				
			|||||||
    user = User.query.get_or_404(user_id)
 | 
					    user = User.query.get_or_404(user_id)
 | 
				
			||||||
    if user.avatar is None:
 | 
					    if user.avatar is None:
 | 
				
			||||||
        abort(404)
 | 
					        abort(404)
 | 
				
			||||||
    if not (user == current_user or current_user.is_administrator()):
 | 
					    if not (user == current_user or current_user.is_administrator):
 | 
				
			||||||
        abort(403)
 | 
					        abort(403)
 | 
				
			||||||
    thread = Thread(
 | 
					    thread = Thread(
 | 
				
			||||||
        target=_delete_avatar,
 | 
					        target=_delete_avatar,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -33,7 +33,7 @@ def get_user(user_hashid):
 | 
				
			|||||||
    user = User.query.get(user_id)
 | 
					    user = User.query.get(user_id)
 | 
				
			||||||
    if user is None:
 | 
					    if user is None:
 | 
				
			||||||
        return {'options': {'status': 404, 'statusText': 'Not found'}}
 | 
					        return {'options': {'status': 404, 'statusText': 'Not found'}}
 | 
				
			||||||
    if not (user == current_user or current_user.is_administrator()):
 | 
					    if not (user == current_user or current_user.is_administrator):
 | 
				
			||||||
        return {'options': {'status': 403, 'statusText': 'Forbidden'}}
 | 
					        return {'options': {'status': 403, 'statusText': 'Forbidden'}}
 | 
				
			||||||
    return {
 | 
					    return {
 | 
				
			||||||
        'body': user.to_json_serializable(),
 | 
					        'body': user.to_json_serializable(),
 | 
				
			||||||
@@ -52,7 +52,7 @@ def subscribe_user(user_hashid):
 | 
				
			|||||||
    user = User.query.get(user_id)
 | 
					    user = User.query.get(user_id)
 | 
				
			||||||
    if user is None:
 | 
					    if user is None:
 | 
				
			||||||
        return {'options': {'status': 404, 'statusText': 'Not found'}}
 | 
					        return {'options': {'status': 404, 'statusText': 'Not found'}}
 | 
				
			||||||
    if not (user == current_user or current_user.is_administrator()):
 | 
					    if not (user == current_user or current_user.is_administrator):
 | 
				
			||||||
        return {'options': {'status': 403, 'statusText': 'Forbidden'}}
 | 
					        return {'options': {'status': 403, 'statusText': 'Forbidden'}}
 | 
				
			||||||
    join_room(f'/users/{user.hashid}')
 | 
					    join_room(f'/users/{user.hashid}')
 | 
				
			||||||
    return {'options': {'status': 200, 'statusText': 'OK'}}
 | 
					    return {'options': {'status': 200, 'statusText': 'OK'}}
 | 
				
			||||||
@@ -89,7 +89,7 @@ def get_user(user_hashid):
 | 
				
			|||||||
    user = User.query.filter_by(id=user_id, is_public=True).first()
 | 
					    user = User.query.filter_by(id=user_id, is_public=True).first()
 | 
				
			||||||
    if user is None:
 | 
					    if user is None:
 | 
				
			||||||
        return {'options': {'status': 404, 'statusText': 'Not found'}}
 | 
					        return {'options': {'status': 404, 'statusText': 'Not found'}}
 | 
				
			||||||
    if not (user == current_user or current_user.is_administrator()):
 | 
					    if not (user == current_user or current_user.is_administrator):
 | 
				
			||||||
        return {'options': {'status': 403, 'statusText': 'Forbidden'}}
 | 
					        return {'options': {'status': 403, 'statusText': 'Forbidden'}}
 | 
				
			||||||
    return {
 | 
					    return {
 | 
				
			||||||
        'body': user.to_json_serializable(filter_by_privacy_settings=True),
 | 
					        'body': user.to_json_serializable(filter_by_privacy_settings=True),
 | 
				
			||||||
@@ -108,7 +108,7 @@ def subscribe_user(user_hashid):
 | 
				
			|||||||
    user = User.query.filter_by(id=user_id, is_public=True).first()
 | 
					    user = User.query.filter_by(id=user_id, is_public=True).first()
 | 
				
			||||||
    if user is None:
 | 
					    if user is None:
 | 
				
			||||||
        return {'options': {'status': 404, 'statusText': 'Not found'}}
 | 
					        return {'options': {'status': 404, 'statusText': 'Not found'}}
 | 
				
			||||||
    if not (user == current_user or current_user.is_administrator()):
 | 
					    if not (user == current_user or current_user.is_administrator):
 | 
				
			||||||
        return {'options': {'status': 403, 'statusText': 'Forbidden'}}
 | 
					        return {'options': {'status': 403, 'statusText': 'Forbidden'}}
 | 
				
			||||||
    join_room(f'/public_users/{user.hashid}')
 | 
					    join_room(f'/public_users/{user.hashid}')
 | 
				
			||||||
    return {'options': {'status': 200, 'statusText': 'OK'}}
 | 
					    return {'options': {'status': 200, 'statusText': 'OK'}}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,7 +22,7 @@ def users():
 | 
				
			|||||||
@register_breadcrumb(bp, '.entity', '', dynamic_list_constructor=user_dlc)
 | 
					@register_breadcrumb(bp, '.entity', '', dynamic_list_constructor=user_dlc)
 | 
				
			||||||
def user(user_id):
 | 
					def user(user_id):
 | 
				
			||||||
    user = User.query.get_or_404(user_id)
 | 
					    user = User.query.get_or_404(user_id)
 | 
				
			||||||
    if not (user.is_public or user == current_user or current_user.is_administrator()):
 | 
					    if not (user.is_public or user == current_user or current_user.is_administrator):
 | 
				
			||||||
        abort(403)
 | 
					        abort(403)
 | 
				
			||||||
    return render_template(
 | 
					    return render_template(
 | 
				
			||||||
        'users/user.html.j2',
 | 
					        'users/user.html.j2',
 | 
				
			||||||
@@ -34,7 +34,7 @@ def user(user_id):
 | 
				
			|||||||
@bp.route('/<hashid:user_id>/avatar')
 | 
					@bp.route('/<hashid:user_id>/avatar')
 | 
				
			||||||
def user_avatar(user_id):
 | 
					def user_avatar(user_id):
 | 
				
			||||||
    user = User.query.get_or_404(user_id)
 | 
					    user = User.query.get_or_404(user_id)
 | 
				
			||||||
    if not (user.is_public or user == current_user or current_user.is_administrator()):
 | 
					    if not (user.is_public or user == current_user or current_user.is_administrator):
 | 
				
			||||||
        abort(403)
 | 
					        abort(403)
 | 
				
			||||||
    if user.avatar is None:
 | 
					    if user.avatar is None:
 | 
				
			||||||
        return redirect(url_for('static', filename='images/user_avatar.png'))
 | 
					        return redirect(url_for('static', filename='images/user_avatar.png'))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,7 +10,7 @@ from . import bp
 | 
				
			|||||||
@content_negotiation(consumes='application/json', produces='application/json')
 | 
					@content_negotiation(consumes='application/json', produces='application/json')
 | 
				
			||||||
def update_user_profile_privacy_setting_is_public(user_id):
 | 
					def update_user_profile_privacy_setting_is_public(user_id):
 | 
				
			||||||
    user = User.query.get_or_404(user_id)
 | 
					    user = User.query.get_or_404(user_id)
 | 
				
			||||||
    if not (user == current_user or current_user.is_administrator()):
 | 
					    if not (user == current_user or current_user.is_administrator):
 | 
				
			||||||
        abort(403)
 | 
					        abort(403)
 | 
				
			||||||
    enabled = request.json
 | 
					    enabled = request.json
 | 
				
			||||||
    if not isinstance(enabled, bool):
 | 
					    if not isinstance(enabled, bool):
 | 
				
			||||||
@@ -32,7 +32,7 @@ def update_user_profile_privacy_settings(user_id, profile_privacy_setting_name):
 | 
				
			|||||||
        profile_privacy_setting = ProfilePrivacySettings[profile_privacy_setting_name]
 | 
					        profile_privacy_setting = ProfilePrivacySettings[profile_privacy_setting_name]
 | 
				
			||||||
    except KeyError:
 | 
					    except KeyError:
 | 
				
			||||||
        abort(404)
 | 
					        abort(404)
 | 
				
			||||||
    if not (user == current_user or current_user.is_administrator()):
 | 
					    if not (user == current_user or current_user.is_administrator):
 | 
				
			||||||
        abort(403)
 | 
					        abort(403)
 | 
				
			||||||
    enabled = request.json
 | 
					    enabled = request.json
 | 
				
			||||||
    if not isinstance(enabled, bool):
 | 
					    if not isinstance(enabled, bool):
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,7 +18,7 @@ from .forms import (
 | 
				
			|||||||
@register_breadcrumb(bp, '.entity.settings', '<i class="material-icons left">settings</i>Settings', endpoint_arguments_constructor=user_eac)
 | 
					@register_breadcrumb(bp, '.entity.settings', '<i class="material-icons left">settings</i>Settings', endpoint_arguments_constructor=user_eac)
 | 
				
			||||||
def settings(user_id):
 | 
					def settings(user_id):
 | 
				
			||||||
    user = User.query.get_or_404(user_id)
 | 
					    user = User.query.get_or_404(user_id)
 | 
				
			||||||
    if not (user == current_user or current_user.is_administrator()):
 | 
					    if not (user == current_user or current_user.is_administrator):
 | 
				
			||||||
        abort(403)
 | 
					        abort(403)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    redirect_location_on_post = g.pop(
 | 
					    redirect_location_on_post = g.pop(
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										58
									
								
								wsgi.py
									
									
									
									
									
								
							
							
						
						
									
										58
									
								
								wsgi.py
									
									
									
									
									
								
							@@ -3,23 +3,25 @@
 | 
				
			|||||||
import eventlet
 | 
					import eventlet
 | 
				
			||||||
eventlet.monkey_patch()
 | 
					eventlet.monkey_patch()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from app import create_app, db, scheduler, socketio  # noqa
 | 
					
 | 
				
			||||||
from app.models import (
 | 
					 | 
				
			||||||
    Avatar,
 | 
					 | 
				
			||||||
    Corpus,
 | 
					 | 
				
			||||||
    CorpusFile,
 | 
					 | 
				
			||||||
    CorpusFollowerAssociation,
 | 
					 | 
				
			||||||
    CorpusFollowerRole,
 | 
					 | 
				
			||||||
    Job,
 | 
					 | 
				
			||||||
    JobInput,
 | 
					 | 
				
			||||||
    JobResult,
 | 
					 | 
				
			||||||
    Role,
 | 
					 | 
				
			||||||
    TesseractOCRPipelineModel,
 | 
					 | 
				
			||||||
    SpaCyNLPPipelineModel,
 | 
					 | 
				
			||||||
    User
 | 
					 | 
				
			||||||
)  # noqa
 | 
					 | 
				
			||||||
from flask import Flask  # noqa
 | 
					from flask import Flask  # noqa
 | 
				
			||||||
from typing import Any, Dict  # noqa
 | 
					from typing import Any, Dict  # noqa
 | 
				
			||||||
 | 
					from app import create_app, db, scheduler, socketio  # noqa
 | 
				
			||||||
 | 
					from app import models  # noqa
 | 
				
			||||||
 | 
					# from app.models import (
 | 
				
			||||||
 | 
					#     Avatar,
 | 
				
			||||||
 | 
					#     Corpus,
 | 
				
			||||||
 | 
					#     CorpusFile,
 | 
				
			||||||
 | 
					#     CorpusFollowerAssociation,
 | 
				
			||||||
 | 
					#     CorpusFollowerRole,
 | 
				
			||||||
 | 
					#     Job,
 | 
				
			||||||
 | 
					#     JobInput,
 | 
				
			||||||
 | 
					#     JobResult,
 | 
				
			||||||
 | 
					#     Role,
 | 
				
			||||||
 | 
					#     TesseractOCRPipelineModel,
 | 
				
			||||||
 | 
					#     SpaCyNLPPipelineModel,
 | 
				
			||||||
 | 
					#     User
 | 
				
			||||||
 | 
					# )  # noqa
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
app: Flask = create_app()
 | 
					app: Flask = create_app()
 | 
				
			||||||
@@ -30,25 +32,25 @@ def make_shell_context() -> Dict[str, Any]:
 | 
				
			|||||||
    ''' Adds variables to the shell context. '''
 | 
					    ''' Adds variables to the shell context. '''
 | 
				
			||||||
    return {
 | 
					    return {
 | 
				
			||||||
        'db': db,
 | 
					        'db': db,
 | 
				
			||||||
        'Avatar': Avatar,
 | 
					        'Avatar': models.Avatar,
 | 
				
			||||||
        'Corpus': Corpus,
 | 
					        'Corpus': models.Corpus,
 | 
				
			||||||
        'CorpusFile': CorpusFile,
 | 
					        'CorpusFile': models.CorpusFile,
 | 
				
			||||||
        'CorpusFollowerAssociation': CorpusFollowerAssociation,
 | 
					        'CorpusFollowerAssociation': models.CorpusFollowerAssociation,
 | 
				
			||||||
        'CorpusFollowerRole': CorpusFollowerRole,
 | 
					        'CorpusFollowerRole': models.CorpusFollowerRole,
 | 
				
			||||||
        'Job': Job,
 | 
					        'Job': models.Job,
 | 
				
			||||||
        'JobInput': JobInput,
 | 
					        'JobInput': models.JobInput,
 | 
				
			||||||
        'JobResult': JobResult,
 | 
					        'JobResult': models.JobResult,
 | 
				
			||||||
        'Role': Role,
 | 
					        'Role': models.Role,
 | 
				
			||||||
        'TesseractOCRPipelineModel': TesseractOCRPipelineModel,
 | 
					        'TesseractOCRPipelineModel': models.TesseractOCRPipelineModel,
 | 
				
			||||||
        'SpaCyNLPPipelineModel': SpaCyNLPPipelineModel,
 | 
					        'SpaCyNLPPipelineModel': models.SpaCyNLPPipelineModel,
 | 
				
			||||||
        'User': User
 | 
					        'User': models.User
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def main():
 | 
					def main():
 | 
				
			||||||
    with app.app_context():
 | 
					    with app.app_context():
 | 
				
			||||||
        if app.config['NOPAQUE_IS_PRIMARY_INSTANCE']:
 | 
					        if app.config['NOPAQUE_IS_PRIMARY_INSTANCE']:
 | 
				
			||||||
            for corpus in Corpus.query.filter(Corpus.num_analysis_sessions > 0).all():
 | 
					            for corpus in models.Corpus.query.filter(models.Corpus.num_analysis_sessions > 0).all():
 | 
				
			||||||
                corpus.num_analysis_sessions = 0
 | 
					                corpus.num_analysis_sessions = 0
 | 
				
			||||||
            db.session.commit()
 | 
					            db.session.commit()
 | 
				
			||||||
        scheduler.start()
 | 
					        scheduler.start()
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user