mirror of
https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque.git
synced 2024-11-15 01:05:42 +00:00
Fix link issues
This commit is contained in:
parent
622d32fa45
commit
57813b4bc2
@ -14,7 +14,7 @@ from app.users.utils import (
|
||||
|
||||
@bp.route('')
|
||||
@register_breadcrumb(bp, '.', '<i class="material-icons left">admin_panel_settings</i>Administration')
|
||||
def index():
|
||||
def admin():
|
||||
return render_template(
|
||||
'admin/admin.html.j2',
|
||||
title='Administration'
|
||||
|
@ -100,6 +100,15 @@ class ProfilePrivacySettings(IntEnum):
|
||||
SHOW_LAST_SEEN = 2
|
||||
SHOW_MEMBER_SINCE = 4
|
||||
|
||||
@staticmethod
|
||||
def get(profile_privacy_setting: Union['ProfilePrivacySettings', int, str]) -> 'ProfilePrivacySettings':
|
||||
if isinstance(profile_privacy_setting, ProfilePrivacySettings):
|
||||
return profile_privacy_setting
|
||||
if isinstance(profile_privacy_setting, int):
|
||||
return ProfilePrivacySettings(profile_privacy_setting)
|
||||
if isinstance(profile_privacy_setting, str):
|
||||
return ProfilePrivacySettings[profile_privacy_setting]
|
||||
raise TypeError('profile_privacy_setting must be ProfilePrivacySettings, int, or str')
|
||||
|
||||
class CorpusFollowerPermission(IntEnum):
|
||||
VIEW = 1
|
||||
@ -227,18 +236,18 @@ class Role(HashidMixin, db.Model):
|
||||
return f'<Role {self.name}>'
|
||||
|
||||
def has_permission(self, permission: Union[Permission, int, str]):
|
||||
perm = Permission.get(permission)
|
||||
return self.permissions & perm.value == perm.value
|
||||
p = Permission.get(permission)
|
||||
return self.permissions & p.value == p.value
|
||||
|
||||
def add_permission(self, permission: Union[Permission, int, str]):
|
||||
perm = Permission.get(permission)
|
||||
if not self.has_permission(perm):
|
||||
self.permissions += perm.value
|
||||
p = Permission.get(permission)
|
||||
if not self.has_permission(p):
|
||||
self.permissions += p.value
|
||||
|
||||
def remove_permission(self, permission: Union[Permission, int, str]):
|
||||
perm = Permission.get(permission)
|
||||
if self.has_permission(perm):
|
||||
self.permissions -= perm.value
|
||||
p = Permission.get(permission)
|
||||
if self.has_permission(p):
|
||||
self.permissions -= p.value
|
||||
|
||||
def reset_permissions(self):
|
||||
self.permissions = 0
|
||||
@ -763,15 +772,18 @@ class User(HashidMixin, UserMixin, db.Model):
|
||||
|
||||
#region Profile Privacy settings
|
||||
def has_profile_privacy_setting(self, setting):
|
||||
return self.profile_privacy_settings & setting == setting
|
||||
s = ProfilePrivacySettings.get(setting)
|
||||
return self.profile_privacy_settings & s.value == s.value
|
||||
|
||||
def add_profile_privacy_setting(self, setting):
|
||||
if not self.has_profile_privacy_setting(setting):
|
||||
self.profile_privacy_settings += setting
|
||||
s = ProfilePrivacySettings.get(setting)
|
||||
if not self.has_profile_privacy_setting(s):
|
||||
self.profile_privacy_settings += s.value
|
||||
|
||||
def remove_profile_privacy_setting(self, setting):
|
||||
if self.has_profile_privacy_setting(setting):
|
||||
self.profile_privacy_settings -= setting
|
||||
s = ProfilePrivacySettings.get(setting)
|
||||
if self.has_profile_privacy_setting(s):
|
||||
self.profile_privacy_settings -= s.value
|
||||
|
||||
def reset_profile_privacy_settings(self):
|
||||
self.profile_privacy_settings = 0
|
||||
@ -838,7 +850,7 @@ class User(HashidMixin, UserMixin, db.Model):
|
||||
json_serializeable = {
|
||||
'id': self.hashid,
|
||||
'confirmed': self.confirmed,
|
||||
'avatar': url_for('users.profile_avatar', user_id=self.id),
|
||||
'avatar': url_for('users.user_avatar', user_id=self.id),
|
||||
'email': self.email,
|
||||
'last_seen': (
|
||||
None if self.last_seen is None
|
||||
|
@ -5,11 +5,7 @@
|
||||
<div class="row">
|
||||
<div class="col s4">
|
||||
<a href="{{ url_for('users.user', user_id=current_user.id) }}">
|
||||
{% 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: 13px; margin-left:-15px;">
|
||||
{% else %}
|
||||
<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 %}
|
||||
<img src="{{ url_for('users.user_avatar', user_id=current_user.id) }}" alt="user-image" class="circle responsive-img" style="height:80%; margin-top: 13px; margin-left:-15px;">
|
||||
</a>
|
||||
</div>
|
||||
<div class="col s8">
|
||||
@ -25,39 +21,72 @@
|
||||
</div>
|
||||
</li> #}
|
||||
{# <li><a href="{{ url_for('main.index') }}">nopaque</a></li> #}
|
||||
<li class="hide-on-large-only"><a href="{{ url_for('main.news') }}"><i class="material-icons left">email</i>News</a></li>
|
||||
<li class="hide-on-large-only">
|
||||
<a class="waves-effect" href="{{ url_for('main.news') }}"><i class="material-icons left">email</i>News</a>
|
||||
</li>
|
||||
{# <li><a href="{{ url_for('main.user_manual') }}"><i class="material-icons">help</i>Manual</a></li> #}
|
||||
<li><a href="{{ url_for('main.dashboard') }}" class="subheader">Dashboard</a></li>
|
||||
<li><a href="{{ url_for('main.dashboard', _anchor='corpora') }}"><i class="nopaque-icons">I</i>My Corpora</a></li>
|
||||
<li><a href="{{ url_for('main.dashboard', _anchor='jobs') }}"><i class="nopaque-icons">J</i>My Jobs</a></li>
|
||||
<li><a href="{{ url_for('main.dashboard', _anchor='contributions') }}"><i class="material-icons">new_label</i>My Contributions</a></li>
|
||||
<li>
|
||||
<a class="waves-effect" class="waves-effect" href="{{ url_for('main.dashboard') }}"><i class="material-icons">dashboard</i>Dashboard</a>
|
||||
<ul>
|
||||
<li>
|
||||
<a class="waves-effect" href="{{ url_for('main.dashboard', _anchor='corpora') }}" style="padding-left: 47px;"><i class="nopaque-icons">I</i>My Corpora</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="waves-effect" href="{{ url_for('main.dashboard', _anchor='jobs') }}" style="padding-left: 47px;"><i class="nopaque-icons">J</i>My Jobs</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="waves-effect" href="{{ url_for('main.dashboard', _anchor='contributions') }}" style="padding-left: 47px;"><i class="material-icons">new_label</i>My Contributions</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><div class="divider"></div></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="tesseract-ocr-pipeline" style="border-left: 10px solid; margin-top: 5px;"><a href="{{ url_for('services.tesseract_ocr_pipeline') }}"><i class="nopaque-icons service-icons" data-service="tesseract-ocr-pipeline"></i>OCR</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 class="waves-effect" 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="tesseract-ocr-pipeline" style="border-left: 10px solid; margin-top: 5px;">
|
||||
<a class="waves-effect" href="{{ url_for('services.tesseract_ocr_pipeline') }}"><i class="nopaque-icons service-icons" data-service="tesseract-ocr-pipeline"></i>OCR</a>
|
||||
</li>
|
||||
{% if config.NOPAQUE_TRANSKRIBUS_ENABLED %}
|
||||
<li class="service-color service-color-border border-darken" data-service="transkribus-htr-pipeline" style="border-left: 10px solid; margin-top: 5px;"><a href="{{ url_for('services.transkribus_htr_pipeline') }}"><i class="nopaque-icons service-icons" data-service="transkribus-htr-pipeline"></i>HTR</a></li>
|
||||
<li class="service-color service-color-border border-darken" data-service="transkribus-htr-pipeline" style="border-left: 10px solid; margin-top: 5px;">
|
||||
<a class="waves-effect" href="{{ url_for('services.transkribus_htr_pipeline') }}"><i class="nopaque-icons service-icons" data-service="transkribus-htr-pipeline"></i>HTR</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li class="service-color service-color-border border-darken" data-service="spacy-nlp-pipeline" style="border-left: 10px solid; margin-top: 5px;"><a href="{{ url_for('services.spacy_nlp_pipeline') }}"><i class="nopaque-icons service-icons" data-service="spacy-nlp-pipeline"></i>NLP</a></li>
|
||||
<li class="service-color service-color-border border-darken" data-service="corpus-analysis" style="border-left: 10px solid; margin-top: 5px;"><a href="{{ url_for('services.corpus_analysis') }}"><i class="nopaque-icons service-icons" data-service="corpus-analysis"></i>Corpus Analysis</a></li>
|
||||
<li class="service-color service-color-border border-darken" data-service="spacy-nlp-pipeline" style="border-left: 10px solid; margin-top: 5px;">
|
||||
<a class="waves-effect" href="{{ url_for('services.spacy_nlp_pipeline') }}"><i class="nopaque-icons service-icons" data-service="spacy-nlp-pipeline"></i>NLP</a>
|
||||
</li>
|
||||
<li class="service-color service-color-border border-darken" data-service="corpus-analysis" style="border-left: 10px solid; margin-top: 5px;">
|
||||
<a class="waves-effect" href="{{ url_for('services.corpus_analysis') }}"><i class="nopaque-icons service-icons" data-service="corpus-analysis"></i>Corpus Analysis</a>
|
||||
</li>
|
||||
<li><div class="divider"></div></li>
|
||||
<li><a class="subheader">Social Area</a></li>
|
||||
<li><a href="{{ url_for('main.social_area', _anchor='public-users') }}"><i class="material-icons">person</i>Public Users</a></li>
|
||||
<li><a href="{{ url_for('main.social_area', _anchor='public-corproa') }}"><i class="nopaque-icons">I</i>Public Corpora</a></li>
|
||||
<li>
|
||||
<a class="waves-effect" class="waves-effect" href="{{ url_for('main.social_area') }}"><i class="material-icons">rocket_launch</i>Social Area</a>
|
||||
<ul>
|
||||
<li>
|
||||
<a class="waves-effect" href="{{ url_for('main.social_area', _anchor='public-users') }}" style="padding-left: 47px;"><i class="material-icons">person</i>Public Users</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="waves-effect" href="{{ url_for('main.social_area', _anchor='public-corproa') }}" style="padding-left: 47px;"><i class="nopaque-icons">I</i>Public Corpora</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="hide-on-large-only"><div class="divider"></div></li>
|
||||
<li class="hide-on-large-only"><a class="subheader">Account</a></li>
|
||||
<li class="hide-on-large-only"><a href="{{ url_for('settings.settings') }}"><i class="material-icons left">settings</i>Settings</a></li>
|
||||
<li class="hide-on-large-only"><a href="{{ url_for('auth.logout') }}">Log out</a></li>
|
||||
<li class="hide-on-large-only">
|
||||
<a class="waves-effect" href="{{ url_for('settings.settings') }}"><i class="material-icons left">settings</i>Settings</a>
|
||||
</li>
|
||||
<li class="hide-on-large-only">
|
||||
<a class="waves-effect" href="{{ url_for('auth.logout') }}">Log out</a>
|
||||
</li>
|
||||
{% if current_user.can('ADMINISTRATE') %}
|
||||
<li><div class="divider"></div></li>
|
||||
<li><a class="subheader">Administration</a></li>
|
||||
<li><a href="{{ url_for('admin.corpora') }}"><i class="nopaque-icons">I</i>Corpora</a></li>
|
||||
<li><a href="{{ url_for('admin.corpora') }}"><i class="nopaque-icons">J</i>Jobs</a></li>
|
||||
<li><a href="{{ url_for('admin.users') }}"><i class="material-icons">group</i>Users</a></li>
|
||||
<li>
|
||||
<a class="waves-effect" href="{{ url_for('admin.admin') }}"><i class="material-icons">admin_panel_settings</i>Administration</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if current_user.can('USE_API') %}
|
||||
<li><div class="divider"></div></li>
|
||||
<li><a class="subheader">API</a></li>
|
||||
<li><a href="{{ url_for('apifairy.docs') }}"><i class="material-icons">api</i>API</a></li>
|
||||
<li>
|
||||
<a class="waves-effect" href="{{ url_for('apifairy.docs') }}"><i class="material-icons">api</i>API</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<div class="row">
|
||||
<div class="col s12 l2">
|
||||
<p> </p>
|
||||
<img src="{{ url_for('users.profile_avatar', user_id=user.id) }}" alt="user-image" class="circle responsive-img">
|
||||
<img src="{{ url_for('users.user_avatar', user_id=user.id) }}" alt="user-image" class="circle responsive-img">
|
||||
</div>
|
||||
<div class="col s12 l10">
|
||||
<h1 id="title">{{ title }}</h1>
|
||||
|
@ -48,11 +48,7 @@
|
||||
<table>
|
||||
<tr>
|
||||
<td style="width:10%; margin-top:25px;">
|
||||
{% if corpus.user.avatar %}
|
||||
<img src="{{ url_for('users.profile_avatar', user_id=corpus.user.id) }}" alt="user-image" class="circle responsive-img">
|
||||
{% else %}
|
||||
<img src="{{ url_for('static', filename='images/user_avatar.png') }}" alt="user-image" class="circle responsive-img">
|
||||
{% endif %}
|
||||
<img src="{{ url_for('users.user_avatar', user_id=corpus.user.id) }}" alt="user-image" class="circle responsive-img">
|
||||
</td>
|
||||
<td></td>
|
||||
<td>
|
||||
|
@ -114,7 +114,7 @@
|
||||
<p></p>
|
||||
<div class="row">
|
||||
<div class="col s12 m2">
|
||||
<img src="{{ url_for('users.profile_avatar', user_id=current_user.id) }}" alt="user-image" class="circle responsive-img" id="avatar">
|
||||
<img src="{{ url_for('users.user_avatar', user_id=current_user.id) }}" alt="user-image" class="circle responsive-img" id="avatar">
|
||||
</div>
|
||||
<div class="col s12 m6">
|
||||
{{ wtf.render_field(edit_public_profile_information_form.avatar, accept='image/jpeg, image/png, image/gif', placeholder='Choose an image file', id='avatar-upload') }}
|
||||
|
@ -1,6 +1,7 @@
|
||||
{% extends "base.html.j2" %}
|
||||
{% import "materialize/wtf.html.j2" as wtf %}
|
||||
|
||||
|
||||
{% block page_content %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
@ -10,9 +11,8 @@
|
||||
<div class="row">
|
||||
<div class="col s1"></div>
|
||||
<div class="col s3">
|
||||
<br>
|
||||
<br>
|
||||
<img src="{{ url_for('.profile_avatar', user_id=user_id) }}" alt="user-image" class="circle responsive-img">
|
||||
<p> </p>
|
||||
<img src="{{ url_for('.user_avatar', user_id=user.id) }}" alt="user-image" class="circle responsive-img">
|
||||
</div>
|
||||
<div class="col s1"></div>
|
||||
<div class="col s7">
|
||||
@ -27,16 +27,18 @@
|
||||
{% else %}
|
||||
<span class="chip white-text" style="background-color: #f44336;">Private Profile</span>
|
||||
{% endif %}
|
||||
{% if user.has_profile_privacy_setting('SHOW_MEMBER_SINCE') %}
|
||||
<span class="chip">Member since: {{ user.member_since.strftime('%Y-%m-%d') }}</span>
|
||||
{% endif %}
|
||||
{% if user.has_profile_privacy_setting('SHOW_LAST_SEEN') %}
|
||||
<span class="chip">Last seen: {{ user.last_seen.strftime('%Y-%m-%d') }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="col 12">
|
||||
{% if user.show_last_seen %}
|
||||
<div class="chip">Last seen: {{ last_seen }}</div>
|
||||
{% endif %}
|
||||
{% if user.location %}
|
||||
<p><span class="material-icons" style="margin-right:20px; margin-top:20px;">location_on</span><i>{{ user.location }}</i></p>
|
||||
<p> </p>
|
||||
<p><i class="material-icons left">location_on</i>{{ user.location }}</p>
|
||||
{% endif %}
|
||||
<p></p>
|
||||
<br>
|
||||
{% if user.about_me %}
|
||||
<blockquote>
|
||||
<h5>About me</h5>
|
||||
@ -59,7 +61,7 @@
|
||||
<td>{{ user.full_name }} </td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if user.show_email %}
|
||||
{% if user.has_profile_privacy_setting('SHOW_EMAIL') %}
|
||||
<tr>
|
||||
<td><span class="material-icons">email</span></td>
|
||||
<td>{{ user.email }}</td>
|
||||
@ -78,18 +80,17 @@
|
||||
</tr>
|
||||
{% endif %}
|
||||
</table>
|
||||
<br>
|
||||
{% if user.show_member_since %}
|
||||
<p><i>Member since: {{ member_since }}</i></p>
|
||||
<p> </p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% if current_user == user %}
|
||||
<div class="card-action">
|
||||
<p class="right-align">
|
||||
<a class="btn waves-effect waves-light" href="{{ url_for('settings.settings') }}">Edit profile</a>
|
||||
</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
<p></p>
|
||||
<br>
|
||||
{% if current_user.hashid == user.id %}
|
||||
<a class="waves-effect waves-light btn-small" href="{{ url_for('settings.settings') }}">Edit profile</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -119,8 +120,22 @@
|
||||
{{ super() }}
|
||||
<script>
|
||||
let followedCorpusList = new FollowedCorpusList(document.querySelector('.followed-corpus-list'));
|
||||
followedCorpusList.add({{ followed_corpora|tojson }});
|
||||
followedCorpusList.add(
|
||||
[
|
||||
{% for corpus in user.followed_corpora %}
|
||||
{{ corpus.to_json_serializeable()|tojson }}
|
||||
{% if not loop.last %},{% endif %}
|
||||
{% endfor %}
|
||||
]
|
||||
);
|
||||
let publicCorpusList = new PublicCorpusList(document.querySelector('.public-corpus-list'));
|
||||
publicCorpusList.add({{ own_public_corpora|tojson }});
|
||||
publicCorpusList.add(
|
||||
[
|
||||
{% for corpus in user.corpora if corpus.is_public %}
|
||||
{{ corpus.to_json_serializeable()|tojson }}
|
||||
{% if not loop.last %},{% endif %}
|
||||
{% endfor %}
|
||||
]
|
||||
);
|
||||
</script>
|
||||
{% endblock scripts %}
|
@ -25,32 +25,18 @@ def users():
|
||||
@login_required
|
||||
def user(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 or user == current_user or current_user.is_administrator()):
|
||||
abort(403)
|
||||
return render_template(
|
||||
'users/profile.html.j2',
|
||||
followed_corpora=followed_corpora,
|
||||
last_seen=last_seen,
|
||||
member_since=member_since,
|
||||
own_public_corpora=own_public_corpora,
|
||||
'users/user.html.j2',
|
||||
user=user,
|
||||
user_id=user_id,
|
||||
title=user.username
|
||||
)
|
||||
|
||||
|
||||
@bp.route('/<hashid:user_id>/avatar')
|
||||
@login_required
|
||||
def profile_avatar(user_id):
|
||||
def user_avatar(user_id):
|
||||
user = User.query.get_or_404(user_id)
|
||||
if not (user.is_public or user == current_user or current_user.is_administrator()):
|
||||
abort(403)
|
||||
|
Loading…
Reference in New Issue
Block a user