mirror of
				https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque.git
				synced 2025-11-03 20:02:47 +00:00 
			
		
		
		
	Fix link issues
This commit is contained in:
		@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -4,13 +4,9 @@
 | 
			
		||||
      <div class="background primary-color"></div>
 | 
			
		||||
      <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 %}
 | 
			
		||||
            </a>
 | 
			
		||||
          <a href="{{ url_for('users.user', user_id=current_user.id) }}">
 | 
			
		||||
            <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">
 | 
			
		||||
          <span class="white-text name">{{ current_user.username }}</span>
 | 
			
		||||
@@ -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>
 | 
			
		||||
                {% 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 %}
 | 
			
		||||
                <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 %}
 | 
			
		||||
        </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)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user