mirror of
https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque.git
synced 2024-11-15 01:05:42 +00:00
Merge branch 'public-corpus' of gitlab.ub.uni-bielefeld.de:sfb1288inf/nopaque into public-corpus
This commit is contained in:
commit
73cb566db2
@ -3,27 +3,24 @@ from flask_login import current_user
|
|||||||
from functools import wraps
|
from functools import wraps
|
||||||
from app.models import Corpus, CorpusFollowerAssociation
|
from app.models import Corpus, CorpusFollowerAssociation
|
||||||
|
|
||||||
def corpus_follower_permission_required(permissions):
|
def corpus_follower_permission_required(*permissions):
|
||||||
def decorator(f):
|
def decorator(f):
|
||||||
@wraps(f)
|
@wraps(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 current_user == corpus.user or current_user.is_administrator():
|
if current_user == corpus.user or current_user.is_administrator():
|
||||||
print('user or admin')
|
|
||||||
return f(*args, **kwargs)
|
return f(*args, **kwargs)
|
||||||
if not current_user.is_following_corpus(corpus):
|
if not current_user.is_following_corpus(corpus):
|
||||||
print('not following corpus')
|
|
||||||
abort(403)
|
abort(403)
|
||||||
corpus_follower_association = CorpusFollowerAssociation.query.filter_by(corpus_id=corpus_id, follower_id=current_user.id).first_or_404()
|
corpus_follower_association = CorpusFollowerAssociation.query.filter_by(corpus_id=corpus_id, follower_id=current_user.id).first_or_404()
|
||||||
for permission in permissions:
|
if not all([corpus_follower_association.role.has_permission(p) for p in permissions]):
|
||||||
if not corpus_follower_association.role.has_permission(permission):
|
|
||||||
abort(403)
|
abort(403)
|
||||||
return f(*args, **kwargs)
|
return f(*args, **kwargs)
|
||||||
return decorated_function
|
return decorated_function
|
||||||
return decorator
|
return decorator
|
||||||
|
|
||||||
def owner_or_admin_required():
|
def corpus_owner_or_admin_required():
|
||||||
def decorator(f):
|
def decorator(f):
|
||||||
@wraps(f)
|
@wraps(f)
|
||||||
def decorated_function(*args, **kwargs):
|
def decorated_function(*args, **kwargs):
|
||||||
|
@ -16,7 +16,7 @@ from flask_login import current_user, login_required
|
|||||||
from threading import Thread
|
from threading import Thread
|
||||||
import jwt
|
import jwt
|
||||||
import os
|
import os
|
||||||
from .decorators import corpus_follower_permission_required, owner_or_admin_required
|
from .decorators import corpus_follower_permission_required, corpus_owner_or_admin_required
|
||||||
from app import db, hashids
|
from app import db, hashids
|
||||||
from app.models import (
|
from app.models import (
|
||||||
Corpus,
|
Corpus,
|
||||||
@ -34,12 +34,6 @@ from .forms import (
|
|||||||
UpdateCorpusFileForm
|
UpdateCorpusFileForm
|
||||||
)
|
)
|
||||||
|
|
||||||
@bp.route('/<hashid:corpus_id>/test')
|
|
||||||
@login_required
|
|
||||||
@corpus_follower_permission_required(['VIEW', 'ADD_CORPUS_FILE'])
|
|
||||||
def test(corpus_id):
|
|
||||||
return 'ok'
|
|
||||||
|
|
||||||
@bp.route('/fake-add')
|
@bp.route('/fake-add')
|
||||||
@login_required
|
@login_required
|
||||||
def fake_add():
|
def fake_add():
|
||||||
@ -52,7 +46,7 @@ def fake_add():
|
|||||||
|
|
||||||
@bp.route('/<hashid:corpus_id>/is_public', methods=['POST'])
|
@bp.route('/<hashid:corpus_id>/is_public', methods=['POST'])
|
||||||
@login_required
|
@login_required
|
||||||
@owner_or_admin_required()
|
@corpus_owner_or_admin_required()
|
||||||
def update_corpus_is_public(corpus_id):
|
def update_corpus_is_public(corpus_id):
|
||||||
is_public = request.json
|
is_public = request.json
|
||||||
if not isinstance(is_public, bool):
|
if not isinstance(is_public, bool):
|
||||||
@ -67,7 +61,7 @@ def update_corpus_is_public(corpus_id):
|
|||||||
|
|
||||||
@bp.route('/<hashid:corpus_id>/followers/add', methods=['POST'])
|
@bp.route('/<hashid:corpus_id>/followers/add', methods=['POST'])
|
||||||
@login_required
|
@login_required
|
||||||
@owner_or_admin_required()
|
@corpus_owner_or_admin_required()
|
||||||
def add_corpus_followers(corpus_id):
|
def add_corpus_followers(corpus_id):
|
||||||
usernames = request.json
|
usernames = request.json
|
||||||
if not (isinstance(usernames, list) or all(isinstance(u, str) for u in usernames)):
|
if not (isinstance(usernames, list) or all(isinstance(u, str) for u in usernames)):
|
||||||
@ -124,7 +118,7 @@ def current_user_unfollow_corpus(corpus_id):
|
|||||||
|
|
||||||
|
|
||||||
@bp.route('/<hashid:corpus_id>/followers/<hashid:follower_id>/role', methods=['POST'])
|
@bp.route('/<hashid:corpus_id>/followers/<hashid:follower_id>/role', methods=['POST'])
|
||||||
@corpus_follower_permission_required(['REMOVE_FOLLOWER', 'UPDATE_FOLLOWER'])
|
@corpus_follower_permission_required('REMOVE_FOLLOWER', 'UPDATE_FOLLOWER')
|
||||||
def add_permission(corpus_id, follower_id):
|
def add_permission(corpus_id, follower_id):
|
||||||
corpus_follower_association = CorpusFollowerAssociation.query.filter_by(corpus_id=corpus_id, follower_id=follower_id).first_or_404()
|
corpus_follower_association = CorpusFollowerAssociation.query.filter_by(corpus_id=corpus_id, follower_id=follower_id).first_or_404()
|
||||||
if not (corpus_follower_association.corpus.user == current_user or current_user.is_administrator()):
|
if not (corpus_follower_association.corpus.user == current_user or current_user.is_administrator()):
|
||||||
@ -218,6 +212,7 @@ def generate_corpus_share_link(corpus_id):
|
|||||||
|
|
||||||
@bp.route('/<hashid:corpus_id>', methods=['DELETE'])
|
@bp.route('/<hashid:corpus_id>', methods=['DELETE'])
|
||||||
@login_required
|
@login_required
|
||||||
|
@corpus_owner_or_admin_required()
|
||||||
def delete_corpus(corpus_id):
|
def delete_corpus(corpus_id):
|
||||||
def _delete_corpus(app, corpus_id):
|
def _delete_corpus(app, corpus_id):
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
@ -226,8 +221,6 @@ def delete_corpus(corpus_id):
|
|||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
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()):
|
|
||||||
abort(403)
|
|
||||||
thread = Thread(
|
thread = Thread(
|
||||||
target=_delete_corpus,
|
target=_delete_corpus,
|
||||||
args=(current_app._get_current_object(), corpus_id)
|
args=(current_app._get_current_object(), corpus_id)
|
||||||
@ -238,12 +231,9 @@ def delete_corpus(corpus_id):
|
|||||||
|
|
||||||
@bp.route('/<hashid:corpus_id>/analyse')
|
@bp.route('/<hashid:corpus_id>/analyse')
|
||||||
@login_required
|
@login_required
|
||||||
|
@corpus_follower_permission_required('VIEW')
|
||||||
def analyse_corpus(corpus_id):
|
def analyse_corpus(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()
|
|
||||||
or current_user.is_following_corpus(corpus)):
|
|
||||||
abort(403)
|
|
||||||
return render_template(
|
return render_template(
|
||||||
'corpora/analyse_corpus.html.j2',
|
'corpora/analyse_corpus.html.j2',
|
||||||
corpus=corpus,
|
corpus=corpus,
|
||||||
@ -253,6 +243,7 @@ def analyse_corpus(corpus_id):
|
|||||||
|
|
||||||
@bp.route('/<hashid:corpus_id>/build', methods=['POST'])
|
@bp.route('/<hashid:corpus_id>/build', methods=['POST'])
|
||||||
@login_required
|
@login_required
|
||||||
|
@corpus_owner_or_admin_required()
|
||||||
def build_corpus(corpus_id):
|
def build_corpus(corpus_id):
|
||||||
def _build_corpus(app, corpus_id):
|
def _build_corpus(app, corpus_id):
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
@ -277,6 +268,7 @@ def build_corpus(corpus_id):
|
|||||||
|
|
||||||
@bp.route('/<hashid:corpus_id>/files/create', methods=['GET', 'POST'])
|
@bp.route('/<hashid:corpus_id>/files/create', methods=['GET', 'POST'])
|
||||||
@login_required
|
@login_required
|
||||||
|
@corpus_follower_permission_required('ADD_CORPUS_FILE')
|
||||||
def create_corpus_file(corpus_id):
|
def create_corpus_file(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()):
|
||||||
@ -324,10 +316,9 @@ def create_corpus_file(corpus_id):
|
|||||||
|
|
||||||
@bp.route('/<hashid:corpus_id>/files/<hashid:corpus_file_id>', methods=['GET', 'POST'])
|
@bp.route('/<hashid:corpus_id>/files/<hashid:corpus_file_id>', methods=['GET', 'POST'])
|
||||||
@login_required
|
@login_required
|
||||||
|
@corpus_follower_permission_required('ADD_CORPUS_FILE', 'UPDATE_CORPUS_FILE', 'REMOVE_CORPUS_FILE')
|
||||||
def corpus_file(corpus_id, corpus_file_id):
|
def corpus_file(corpus_id, corpus_file_id):
|
||||||
corpus_file = CorpusFile.query.filter_by(corpus_id = corpus_id, id=corpus_file_id).first_or_404()
|
corpus_file = CorpusFile.query.filter_by(corpus_id = corpus_id, id=corpus_file_id).first_or_404()
|
||||||
if not (corpus_file.corpus.user == current_user or current_user.is_administrator()):
|
|
||||||
abort(403)
|
|
||||||
form = UpdateCorpusFileForm(data=corpus_file.to_json_serializeable())
|
form = UpdateCorpusFileForm(data=corpus_file.to_json_serializeable())
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
form.populate_obj(corpus_file)
|
form.populate_obj(corpus_file)
|
||||||
@ -348,6 +339,7 @@ def corpus_file(corpus_id, corpus_file_id):
|
|||||||
|
|
||||||
@bp.route('/<hashid:corpus_id>/files/<hashid:corpus_file_id>', methods=['DELETE'])
|
@bp.route('/<hashid:corpus_id>/files/<hashid:corpus_file_id>', methods=['DELETE'])
|
||||||
@login_required
|
@login_required
|
||||||
|
@corpus_follower_permission_required('REMOVE_CORPUS_FILE')
|
||||||
def delete_corpus_file(corpus_id, corpus_file_id):
|
def delete_corpus_file(corpus_id, corpus_file_id):
|
||||||
def _delete_corpus_file(app, corpus_file_id):
|
def _delete_corpus_file(app, corpus_file_id):
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
@ -368,6 +360,7 @@ def delete_corpus_file(corpus_id, corpus_file_id):
|
|||||||
|
|
||||||
@bp.route('/<hashid:corpus_id>/files/<hashid:corpus_file_id>/download')
|
@bp.route('/<hashid:corpus_id>/files/<hashid:corpus_file_id>/download')
|
||||||
@login_required
|
@login_required
|
||||||
|
@corpus_follower_permission_required('VIEW')
|
||||||
def download_corpus_file(corpus_id, corpus_file_id):
|
def download_corpus_file(corpus_id, corpus_file_id):
|
||||||
corpus_file = CorpusFile.query.filter_by(corpus_id = corpus_id, id=corpus_file_id).first_or_404()
|
corpus_file = CorpusFile.query.filter_by(corpus_id = corpus_id, id=corpus_file_id).first_or_404()
|
||||||
if not (corpus_file.corpus.user == current_user or current_user.is_administrator()):
|
if not (corpus_file.corpus.user == current_user or current_user.is_administrator()):
|
||||||
|
@ -27,20 +27,7 @@ def faq():
|
|||||||
@bp.route('/dashboard')
|
@bp.route('/dashboard')
|
||||||
@login_required
|
@login_required
|
||||||
def dashboard():
|
def dashboard():
|
||||||
# users = [
|
return render_template('main/dashboard.html.j2', title='Dashboard')
|
||||||
# u.to_json_serializeable(filter_by_privacy_settings=True) for u
|
|
||||||
# in User.query.filter(User.is_public == True, User.id != current_user.id).all()
|
|
||||||
# ]
|
|
||||||
# corpora = [
|
|
||||||
# c.to_json_serializeable() for c
|
|
||||||
# in Corpus.query.filter(Corpus.is_public == True, Corpus.user != current_user).all()
|
|
||||||
# ]
|
|
||||||
return render_template(
|
|
||||||
'main/dashboard.html.j2',
|
|
||||||
title='Dashboard',
|
|
||||||
# users=users,
|
|
||||||
# corpora=corpora
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route('/dashboard2')
|
@bp.route('/dashboard2')
|
||||||
@ -67,3 +54,20 @@ def privacy_policy():
|
|||||||
@bp.route('/terms_of_use')
|
@bp.route('/terms_of_use')
|
||||||
def terms_of_use():
|
def terms_of_use():
|
||||||
return render_template('main/terms_of_use.html.j2', title='Terms of Use')
|
return render_template('main/terms_of_use.html.j2', title='Terms of Use')
|
||||||
|
|
||||||
|
@bp.route('/social-area')
|
||||||
|
def social_area():
|
||||||
|
users = [
|
||||||
|
u.to_json_serializeable(relationships=True, filter_by_privacy_settings=True,) for u
|
||||||
|
in User.query.filter(User.is_public == True, User.id != current_user.id).all()
|
||||||
|
]
|
||||||
|
corpora = [
|
||||||
|
c.to_json_serializeable() for c
|
||||||
|
in Corpus.query.filter(Corpus.is_public == True, Corpus.user != current_user).all()
|
||||||
|
]
|
||||||
|
return render_template(
|
||||||
|
'main/social_area.html.j2',
|
||||||
|
users=users,
|
||||||
|
corpora=corpora,
|
||||||
|
title='Social Area'
|
||||||
|
)
|
||||||
|
14
app/static/js/ResourceLists/FollowedCorpusList.js
Normal file
14
app/static/js/ResourceLists/FollowedCorpusList.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
class FollowedCorpusList extends CorpusList {
|
||||||
|
get item() {
|
||||||
|
return `
|
||||||
|
<tr class="list-item clickable hoverable">
|
||||||
|
<td><a class="btn-floating disabled"><i class="material-icons service-color darken" data-service="corpus-analysis">book</i></a></td>
|
||||||
|
<td><b class="title"></b><br><i class="description"></i></td>
|
||||||
|
<td><span class="status badge new corpus-status-color corpus-status-text" data-badge-caption=""></span></td>
|
||||||
|
<td class="right-align">
|
||||||
|
<a class="list-action-trigger btn-floating service-color darken waves-effect waves-light" data-list-action="view" data-service="corpus-analysis"><i class="material-icons">send</i></a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
`.trim();
|
||||||
|
}
|
||||||
|
}
|
@ -13,14 +13,14 @@ class UserList extends ResourceList {
|
|||||||
get item() {
|
get item() {
|
||||||
return `
|
return `
|
||||||
<tr class="list-item clickable hoverable">
|
<tr class="list-item clickable hoverable">
|
||||||
<td><img alt="user-image" class="circle responsive-img avatar" style="width:50%"></td>
|
<td><img alt="user-image" class="circle responsive-img avatar" style="width:25%"></td>
|
||||||
<td><b><span class="username"></span><b></td>
|
<td><b><span class="username"></span><b></td>
|
||||||
<td><span class="full-name"></span></td>
|
<td><span class="full-name"></span></td>
|
||||||
<td><span class="location"></span></td>
|
<td><span class="location"></span></td>
|
||||||
<td><span class="organization"></span></td>
|
<td><span class="organization"></span></td>
|
||||||
<td><span class="corpora-online"></span></td>
|
<td><span class="corpora-online"></span></td>
|
||||||
<td class="right-align">
|
<td class="right-align">
|
||||||
<a class="list-action-trigger btn-floating waves-effect waves-light" data-list-action="view"><i class="material-icons">send</i></a>
|
<a class="list-action-trigger btn-floating waves-effect waves-light" data-list-action="view" style="background-color:#D9A36D"><i class="material-icons">send</i></a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
`.trim();
|
`.trim();
|
||||||
@ -77,7 +77,7 @@ class UserList extends ResourceList {
|
|||||||
'full-name': user.full_name ? user.full_name : '',
|
'full-name': user.full_name ? user.full_name : '',
|
||||||
'location': user.location ? user.location : '',
|
'location': user.location ? user.location : '',
|
||||||
'organization': user.organization ? user.organization : '',
|
'organization': user.organization ? user.organization : '',
|
||||||
'corpora-online': '-'
|
'corpora-online': Object.values(user.corpora).filter((corpus) => corpus.is_public).length
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
'js/ResourceLists/CorpusFileList.js',
|
'js/ResourceLists/CorpusFileList.js',
|
||||||
'js/ResourceLists/PublicCorpusFileList.js',
|
'js/ResourceLists/PublicCorpusFileList.js',
|
||||||
'js/ResourceLists/CorpusList.js',
|
'js/ResourceLists/CorpusList.js',
|
||||||
|
'js/ResourceLists/FollowedCorpusList.js',
|
||||||
'js/ResourceLists/PublicCorpusList.js',
|
'js/ResourceLists/PublicCorpusList.js',
|
||||||
'js/ResourceLists/JobList.js',
|
'js/ResourceLists/JobList.js',
|
||||||
'js/ResourceLists/JobInputList.js',
|
'js/ResourceLists/JobInputList.js',
|
||||||
|
@ -6,11 +6,10 @@
|
|||||||
<div class="col s4">
|
<div class="col s4">
|
||||||
<a href="{{ url_for('users.user', user_id=current_user.id) }}">
|
<a href="{{ url_for('users.user', user_id=current_user.id) }}">
|
||||||
{% if current_user.avatar %}
|
{% if current_user.avatar %}
|
||||||
<img src="{{ url_for('users.profile_avatar', user_id=current_user.id) }}" alt="user-image" class="circle responsive-img" style="height:80%; margin-top: 20px; margin-left:-15px;">
|
<img src="{{ url_for('users.profile_avatar', user_id=current_user.id) }}" alt="user-image" class="circle responsive-img" style="height:80%; margin-top: 13px; margin-left:-15px;">
|
||||||
{% else %}
|
{% else %}
|
||||||
<img src="{{ url_for('static', filename='images/user_avatar.png') }}" alt="user-image" class="circle responsive-img" style="height:80%; margin-top: 20px; margin-left:-15px;">
|
<img src="{{ url_for('static', filename='images/user_avatar.png') }}" alt="user-image" class="circle responsive-img" style="height:80%; margin-top: 13px; margin-left:-15px;">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{# <i class="material-icons" style="color:white; font-size:3em; margin-top: 25px; margin-left:-15px;">account_circle</i></div> #}
|
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="col s8">
|
<div class="col s8">
|
||||||
@ -27,6 +26,7 @@
|
|||||||
<li><a href="{{ url_for('main.dashboard', _anchor='corpora') }}" style="padding-left: 47px;"><i class="nopaque-icons">I</i>My Corpora</a></li>
|
<li><a href="{{ url_for('main.dashboard', _anchor='corpora') }}" style="padding-left: 47px;"><i class="nopaque-icons">I</i>My Corpora</a></li>
|
||||||
<li><a href="{{ url_for('main.dashboard', _anchor='jobs') }}" style="padding-left: 47px;"><i class="nopaque-icons">J</i>My Jobs</a></li>
|
<li><a href="{{ url_for('main.dashboard', _anchor='jobs') }}" style="padding-left: 47px;"><i class="nopaque-icons">J</i>My Jobs</a></li>
|
||||||
<li><a href="{{ url_for('contributions.contributions') }}"><i class="material-icons">new_label</i>Contribute</a></li>
|
<li><a href="{{ url_for('contributions.contributions') }}"><i class="material-icons">new_label</i>Contribute</a></li>
|
||||||
|
<li><a href="{{ url_for('main.social_area') }}"><i class="material-icons">group</i>Social Area</a></li>
|
||||||
<li><div class="divider"></div></li>
|
<li><div class="divider"></div></li>
|
||||||
<li><a class="subheader">Processes & Services</a></li>
|
<li><a class="subheader">Processes & Services</a></li>
|
||||||
<li class="service-color service-color-border border-darken" data-service="file-setup-pipeline" style="border-left: 10px solid; margin-top: 5px;"><a href="{{ url_for('services.file_setup_pipeline') }}"><i class="nopaque-icons service-icons" data-service="file-setup-pipeline"></i>File setup</a></li>
|
<li class="service-color service-color-border border-darken" data-service="file-setup-pipeline" style="border-left: 10px solid; margin-top: 5px;"><a href="{{ url_for('services.file_setup_pipeline') }}"><i class="nopaque-icons service-icons" data-service="file-setup-pipeline"></i>File setup</a></li>
|
||||||
|
70
app/templates/main/social_area.html.j2
Normal file
70
app/templates/main/social_area.html.j2
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
{% extends "base.html.j2" %}
|
||||||
|
{% import "materialize/wtf.html.j2" as wtf %}
|
||||||
|
|
||||||
|
{% block main_attribs %} style="background-color:#d8c9ba86" {% endblock main_attribs %}
|
||||||
|
|
||||||
|
{% block page_content %}
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col s12">
|
||||||
|
<h1 id="title">{{ title }}</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col s12 m3 push-m9">
|
||||||
|
<div class="center-align">
|
||||||
|
<p class="hide-on-small-only"> </p>
|
||||||
|
<p class="hide-on-small-only"> </p>
|
||||||
|
<a class="btn-floating btn-large btn-scale-x2 waves-effect waves-light" style="background-color:#D9A36D">
|
||||||
|
<i class="left material-icons">group</i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col s12 m9 pull-m3">
|
||||||
|
<div class="card" style="border-top: 10px solid #D9A36D;">
|
||||||
|
<div class="card-content">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col s12">
|
||||||
|
<div class="card-panel z-depth-0">
|
||||||
|
<span class="card-title"><i class="left material-icons">layers</i>Your social area</span>
|
||||||
|
<p>Here you can network with your team and other users. You can find corpora that are public and request them or just see what other users are working on.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col s12">
|
||||||
|
<h3>Other Users</h3>
|
||||||
|
<p>Find other users and see what corpora they have made public.</p>
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-content">
|
||||||
|
<div class="user-list no-autoinit"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col s12">
|
||||||
|
<h3>Public Corpora</h3>
|
||||||
|
<p>Find public corpora.</p>
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-content">
|
||||||
|
<span class="card-title">Public Corpora</span>
|
||||||
|
<div class="public-corpus-list no-autoinit"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock page_content %}
|
||||||
|
|
||||||
|
{% block scripts %}
|
||||||
|
{{ super() }}
|
||||||
|
<script>
|
||||||
|
let userList = new UserList(document.querySelector('.user-list'));
|
||||||
|
userList.add({{ users|tojson }});
|
||||||
|
let publicCorpusList = new PublicCorpusList(document.querySelector('.public-corpus-list'));
|
||||||
|
publicCorpusList.add({{ corpora|tojson }});
|
||||||
|
</script>
|
||||||
|
{% endblock scripts %}
|
@ -26,7 +26,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col 12">
|
<div class="col 12">
|
||||||
{% if user.show_last_seen %}
|
{% if user.show_last_seen %}
|
||||||
<div class="chip">Last seen: {{ user.last_seen }}</div>
|
<div class="chip">Last seen: {{ last_seen }}</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if user.location %}
|
{% if user.location %}
|
||||||
<p><span class="material-icons" style="margin-right:20px; margin-top:20px;">location_on</span><i>{{ user.location }}</i></p>
|
<p><span class="material-icons" style="margin-right:20px; margin-top:20px;">location_on</span><i>{{ user.location }}</i></p>
|
||||||
@ -76,7 +76,7 @@
|
|||||||
</table>
|
</table>
|
||||||
<br>
|
<br>
|
||||||
{% if user.show_member_since %}
|
{% if user.show_member_since %}
|
||||||
<p><i>Member since: {{ user.member_since }}</i></p>
|
<p><i>Member since: {{ member_since }}</i></p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<p></p>
|
<p></p>
|
||||||
<br>
|
<br>
|
||||||
@ -93,7 +93,8 @@
|
|||||||
<div class="col s6">
|
<div class="col s6">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<h4>Groups</h4>
|
<h4>Followed corpora</h4>
|
||||||
|
<div class="followed-corpus-list no-autoinit"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -101,7 +102,7 @@
|
|||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<h4>Public corpora</h4>
|
<h4>Public corpora</h4>
|
||||||
<div class="public-corpora-list" data-user-id="{{ user.hashid }}"></div>
|
<div class="public-corpus-list no-autoinit"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -127,6 +128,11 @@ if ("{{ user.id }}" == "{{ current_user.hashid }}") {
|
|||||||
} else {
|
} else {
|
||||||
publicInformationBadge.remove();
|
publicInformationBadge.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let followedCorpusList = new FollowedCorpusList(document.querySelector('.followed-corpus-list'));
|
||||||
|
followedCorpusList.add({{ followed_corpora|tojson }});
|
||||||
|
let publicCorpusList = new PublicCorpusList(document.querySelector('.public-corpus-list'));
|
||||||
|
publicCorpusList.add({{ own_public_corpora|tojson }});
|
||||||
</script>
|
</script>
|
||||||
{% endblock scripts %}
|
{% endblock scripts %}
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
from datetime import datetime
|
||||||
from flask import (
|
from flask import (
|
||||||
abort,
|
abort,
|
||||||
current_app,
|
current_app,
|
||||||
@ -12,7 +13,7 @@ from flask_login import current_user, login_required
|
|||||||
from threading import Thread
|
from threading import Thread
|
||||||
import os
|
import os
|
||||||
from app import db
|
from app import db
|
||||||
from app.models import Avatar, ProfilePrivacySettings, User
|
from app.models import Avatar, Corpus, ProfilePrivacySettings, User
|
||||||
from . import bp
|
from . import bp
|
||||||
from .forms import (
|
from .forms import (
|
||||||
EditPrivacySettingsForm,
|
EditPrivacySettingsForm,
|
||||||
@ -29,10 +30,23 @@ def before_request():
|
|||||||
@login_required
|
@login_required
|
||||||
def user(user_id):
|
def user(user_id):
|
||||||
user = User.query.get_or_404(user_id)
|
user = User.query.get_or_404(user_id)
|
||||||
|
last_seen = user.last_seen.strftime('%Y-%m-%d %H:%M')
|
||||||
|
member_since = user.member_since.strftime('%Y-%m-%d')
|
||||||
|
followed_corpora = [
|
||||||
|
c.to_json_serializeable() for c in user.followed_corpora
|
||||||
|
]
|
||||||
|
own_public_corpora = [
|
||||||
|
c.to_json_serializeable() for c
|
||||||
|
in Corpus.query.filter_by(is_public = True, user = user).all()
|
||||||
|
]
|
||||||
if not user.is_public and user != current_user:
|
if not user.is_public and user != current_user:
|
||||||
abort(403)
|
abort(403)
|
||||||
return render_template(
|
return render_template(
|
||||||
'users/profile.html.j2',
|
'users/profile.html.j2',
|
||||||
|
followed_corpora=followed_corpora,
|
||||||
|
last_seen=last_seen,
|
||||||
|
member_since=member_since,
|
||||||
|
own_public_corpora=own_public_corpora,
|
||||||
user=user.to_json_serializeable(),
|
user=user.to_json_serializeable(),
|
||||||
user_id=user_id
|
user_id=user_id
|
||||||
)
|
)
|
||||||
@ -56,18 +70,6 @@ def delete_user(user_id):
|
|||||||
thread.start()
|
thread.start()
|
||||||
return {}, 202
|
return {}, 202
|
||||||
|
|
||||||
@bp.route('/<hashid:user_id>')
|
|
||||||
def profile(user_id):
|
|
||||||
user = User.query.get_or_404(user_id)
|
|
||||||
if not user.is_public and user != current_user:
|
|
||||||
abort(403)
|
|
||||||
return render_template(
|
|
||||||
'users/profile.html.j2',
|
|
||||||
user=user.to_json_serializeable(),
|
|
||||||
user_id=user_id
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route('/<hashid:user_id>/avatar')
|
@bp.route('/<hashid:user_id>/avatar')
|
||||||
def profile_avatar(user_id):
|
def profile_avatar(user_id):
|
||||||
user = User.query.get_or_404(user_id)
|
user = User.query.get_or_404(user_id)
|
||||||
@ -91,7 +93,6 @@ def delete_profile_avatar(user_id):
|
|||||||
avatar = Avatar.query.get(avatar_id)
|
avatar = Avatar.query.get(avatar_id)
|
||||||
avatar.delete()
|
avatar.delete()
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
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)
|
||||||
|
Loading…
Reference in New Issue
Block a user