mirror of
				https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque.git
				synced 2025-11-04 04:12:45 +00:00 
			
		
		
		
	Avatar Update
This commit is contained in:
		@@ -1,5 +1,5 @@
 | 
			
		||||
from flask import flash, redirect, render_template, url_for
 | 
			
		||||
from flask_login import login_required, login_user
 | 
			
		||||
from flask_login import current_user, login_required, login_user
 | 
			
		||||
from app.auth.forms import LoginForm
 | 
			
		||||
from app.models import User
 | 
			
		||||
from . import bp
 | 
			
		||||
@@ -27,7 +27,11 @@ def faq():
 | 
			
		||||
@bp.route('/dashboard')
 | 
			
		||||
@login_required
 | 
			
		||||
def dashboard():
 | 
			
		||||
    return render_template('main/dashboard.html.j2', title='Dashboard')
 | 
			
		||||
    users = [
 | 
			
		||||
        u.to_json_serializeable(filter_by_privacy_settings=True, include_avatar_relationship=True) for u
 | 
			
		||||
        in User.query.filter(User.is_public == True, User.id != current_user.id).all()
 | 
			
		||||
    ]
 | 
			
		||||
    return render_template('main/dashboard.html.j2', title='Dashboard', users=users)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@bp.route('/user_manual')
 | 
			
		||||
 
 | 
			
		||||
@@ -254,7 +254,7 @@ class Avatar(HashidMixin, FileMixin, db.Model):
 | 
			
		||||
    # Primary key
 | 
			
		||||
    id = db.Column(db.Integer, primary_key=True)
 | 
			
		||||
    # Foreign keys
 | 
			
		||||
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
 | 
			
		||||
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), unique=True)
 | 
			
		||||
    
 | 
			
		||||
    @property
 | 
			
		||||
    def path(self):
 | 
			
		||||
@@ -266,6 +266,12 @@ class Avatar(HashidMixin, FileMixin, db.Model):
 | 
			
		||||
        except OSError as e:
 | 
			
		||||
            current_app.logger.error(e)
 | 
			
		||||
        db.session.delete(self)
 | 
			
		||||
 | 
			
		||||
    def to_json_serializeable(self, backrefs=False, relationships=False):
 | 
			
		||||
        json_serializeable = {
 | 
			
		||||
            'id': self.id
 | 
			
		||||
        }
 | 
			
		||||
        return json_serializeable
 | 
			
		||||
    
 | 
			
		||||
class User(HashidMixin, UserMixin, db.Model):
 | 
			
		||||
    __tablename__ = 'users'
 | 
			
		||||
@@ -273,7 +279,6 @@ class User(HashidMixin, UserMixin, db.Model):
 | 
			
		||||
    id = db.Column(db.Integer, primary_key=True)
 | 
			
		||||
    # Foreign keys
 | 
			
		||||
    role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
 | 
			
		||||
    # privacy_id = db.Column(db.Integer, db.ForeignKey('privacies.id'))
 | 
			
		||||
    # Fields
 | 
			
		||||
    email = db.Column(db.String(254), index=True, unique=True)
 | 
			
		||||
    username = db.Column(db.String(64), index=True, unique=True)
 | 
			
		||||
@@ -533,7 +538,16 @@ class User(HashidMixin, UserMixin, db.Model):
 | 
			
		||||
        self.profile_privacy_settings = 0
 | 
			
		||||
    #endregion Profile Privacy settings
 | 
			
		||||
 | 
			
		||||
    def to_json_serializeable(self, backrefs=False, relationships=False):
 | 
			
		||||
    def to_json_serializeable(
 | 
			
		||||
        self, backrefs=False, 
 | 
			
		||||
        relationships=False, 
 | 
			
		||||
        filter_by_privacy_settings=False,
 | 
			
		||||
        include_corpus_relationships=False,
 | 
			
		||||
        include_job_relationships=False,
 | 
			
		||||
        include_tesseract_ocr_pipeline_model_relationships=False,
 | 
			
		||||
        include_spacy_nlp_pipeline_model_relationships=False,
 | 
			
		||||
        include_avatar_relationship=False
 | 
			
		||||
    ):
 | 
			
		||||
        json_serializeable = {
 | 
			
		||||
            'id': self.hashid,
 | 
			
		||||
            'confirmed': self.confirmed,
 | 
			
		||||
@@ -555,28 +569,43 @@ class User(HashidMixin, UserMixin, db.Model):
 | 
			
		||||
            'show_email': self.has_profile_privacy_setting(ProfilePrivacySettings.SHOW_EMAIL),
 | 
			
		||||
            'show_last_seen': self.has_profile_privacy_setting(ProfilePrivacySettings.SHOW_LAST_SEEN),
 | 
			
		||||
            'show_member_since': self.has_profile_privacy_setting(ProfilePrivacySettings.SHOW_MEMBER_SINCE)
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        if backrefs:
 | 
			
		||||
            json_serializeable['role'] = \
 | 
			
		||||
                self.role.to_json_serializeable(backrefs=True)
 | 
			
		||||
        if relationships:
 | 
			
		||||
        if relationships or include_corpus_relationships:
 | 
			
		||||
            json_serializeable['corpora'] = {
 | 
			
		||||
                x.hashid: x.to_json_serializeable(relationships=True)
 | 
			
		||||
                for x in self.corpora
 | 
			
		||||
            }
 | 
			
		||||
        if relationships or include_job_relationships:
 | 
			
		||||
            json_serializeable['jobs'] = {
 | 
			
		||||
                x.hashid: x.to_json_serializeable(relationships=True)
 | 
			
		||||
                for x in self.jobs
 | 
			
		||||
            }
 | 
			
		||||
        if relationships or include_tesseract_ocr_pipeline_model_relationships:
 | 
			
		||||
            json_serializeable['tesseract_ocr_pipeline_models'] = {
 | 
			
		||||
                x.hashid: x.to_json_serializeable(relationships=True)
 | 
			
		||||
                for x in self.tesseract_ocr_pipeline_models
 | 
			
		||||
            }
 | 
			
		||||
        if relationships or include_spacy_nlp_pipeline_model_relationships:
 | 
			
		||||
            json_serializeable['spacy_nlp_pipeline_models'] = {
 | 
			
		||||
                x.hashid: x.to_json_serializeable(relationships=True)
 | 
			
		||||
                for x in self.spacy_nlp_pipeline_models
 | 
			
		||||
            }
 | 
			
		||||
        if relationships or include_avatar_relationship:
 | 
			
		||||
            json_serializeable['avatar'] = (
 | 
			
		||||
                None if self.avatar is None
 | 
			
		||||
                else self.avatar.to_json_serializeable(relationships=True)
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
        if filter_by_privacy_settings:
 | 
			
		||||
            if not self.has_profile_privacy_setting(ProfilePrivacySettings.SHOW_EMAIL):
 | 
			
		||||
                json_serializeable.pop('email')
 | 
			
		||||
            if not self.has_profile_privacy_setting(ProfilePrivacySettings.SHOW_LAST_SEEN):
 | 
			
		||||
                json_serializeable.pop('last_seen')
 | 
			
		||||
            if not self.has_profile_privacy_setting(ProfilePrivacySettings.SHOW_MEMBER_SINCE):
 | 
			
		||||
                json_serializeable.pop('member_since')
 | 
			
		||||
        return json_serializeable
 | 
			
		||||
 | 
			
		||||
class TesseractOCRPipelineModel(FileMixin, HashidMixin, db.Model):
 | 
			
		||||
 
 | 
			
		||||
@@ -54,7 +54,6 @@ def delete_avatar(avatar_id, user_id):
 | 
			
		||||
    def _delete_avatar(app, avatar_id):
 | 
			
		||||
        with app.app_context():
 | 
			
		||||
            avatar_file = Avatar.query.get(avatar_id)
 | 
			
		||||
            print(avatar_file)
 | 
			
		||||
            avatar_file.delete()
 | 
			
		||||
            db.session.commit()
 | 
			
		||||
    thread = Thread(
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										79
									
								
								app/static/js/RessourceLists/PublicUserList.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								app/static/js/RessourceLists/PublicUserList.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,79 @@
 | 
			
		||||
class PublicUserList extends RessourceList {
 | 
			
		||||
  static autoInit() {
 | 
			
		||||
    for (let publicUserListElement of document.querySelectorAll('.public-user-list:not(.no-autoinit)')) {
 | 
			
		||||
      new PublicUserList(publicUserListElement);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static options = {
 | 
			
		||||
    initialHtmlGenerator: (id) => {
 | 
			
		||||
      console.log(id);
 | 
			
		||||
      return `
 | 
			
		||||
        <div class="input-field">
 | 
			
		||||
          <i class="material-icons prefix">search</i>
 | 
			
		||||
          <input id="${id}-search" class="search" type="search"></input>
 | 
			
		||||
          <label for="${id}-search">Search user</label>
 | 
			
		||||
        </div>
 | 
			
		||||
        <table>
 | 
			
		||||
          <thead>
 | 
			
		||||
            <tr>
 | 
			
		||||
              <th style="width:15%;"></th>
 | 
			
		||||
              <th>Username</th>
 | 
			
		||||
              <th></th>
 | 
			
		||||
            </tr>
 | 
			
		||||
          </thead>
 | 
			
		||||
          <tbody class="list"></tbody>
 | 
			
		||||
        </table>
 | 
			
		||||
        <ul class="pagination"></ul>
 | 
			
		||||
      `.trim();
 | 
			
		||||
    },
 | 
			
		||||
    item: `
 | 
			
		||||
      <tr class="clickable hoverable">
 | 
			
		||||
        <td><img alt="user-image" class="circle responsive-img avatar" style="width:80%"></td>
 | 
			
		||||
        <td><span class="username"></span></td>
 | 
			
		||||
        <td class="right-align">
 | 
			
		||||
          <a class="action-button btn-floating waves-effect waves-light" data-action="view"><i class="material-icons">send</i></a>
 | 
			
		||||
        </td>
 | 
			
		||||
      </tr>
 | 
			
		||||
    `.trim(),
 | 
			
		||||
    ressourceMapper: (user) => {
 | 
			
		||||
      return {
 | 
			
		||||
        'id': user.id,
 | 
			
		||||
        'member-since': user.member_since,
 | 
			
		||||
        'avatar': `/static/images/user_avatar.png`,
 | 
			
		||||
        'username': user.username
 | 
			
		||||
      };
 | 
			
		||||
    },
 | 
			
		||||
    sortArgs: ['member-since', {order: 'desc'}],
 | 
			
		||||
    valueNames: [
 | 
			
		||||
      {data: ['id']},
 | 
			
		||||
      {data: ['member-since']},
 | 
			
		||||
      {name: 'avatar', attr: 'src'},
 | 
			
		||||
      'username'
 | 
			
		||||
    ]
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  constructor(listElement, options = {}) {
 | 
			
		||||
    super(listElement, {...PublicUserList.options, ...options});
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  init(users) {
 | 
			
		||||
    super._init(Object.values(users));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  onClick(event) {
 | 
			
		||||
    let actionButtonElement = event.target.closest('.action-button');
 | 
			
		||||
    let action = actionButtonElement === null ? 'view' : actionButtonElement.dataset.action;
 | 
			
		||||
    let publicUserElement = event.target.closest('tr');
 | 
			
		||||
    let publicUserId = publicUserElement.dataset.id;
 | 
			
		||||
    switch (action) {
 | 
			
		||||
      case 'view': {
 | 
			
		||||
        window.location.href = `/profile/${publicUserId}`;
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
      default: {
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -11,6 +11,7 @@ class RessourceList {
 | 
			
		||||
    JobInputList.autoInit();
 | 
			
		||||
    JobResultList.autoInit();
 | 
			
		||||
    PublicCorporaList.autoInit();
 | 
			
		||||
    PublicUserList.autoInit();
 | 
			
		||||
    SpaCyNLPPipelineModelList.autoInit();
 | 
			
		||||
    TesseractOCRPipelineModelList.autoInit();
 | 
			
		||||
    UserList.autoInit();
 | 
			
		||||
 
 | 
			
		||||
@@ -25,6 +25,7 @@
 | 
			
		||||
  'js/RessourceLists/JobInputList.js',
 | 
			
		||||
  'js/RessourceLists/JobResultList.js',
 | 
			
		||||
  'js/RessourceLists/PublicCorporaList.js',
 | 
			
		||||
  'js/RessourceLists/PublicUserList.js',
 | 
			
		||||
  'js/RessourceLists/SpacyNLPPipelineModelList.js',
 | 
			
		||||
  'js/RessourceLists/TesseractOCRPipelineModelList.js',
 | 
			
		||||
  'js/RessourceLists/UserList.js'
 | 
			
		||||
 
 | 
			
		||||
@@ -22,11 +22,7 @@
 | 
			
		||||
{% block scripts %}
 | 
			
		||||
{{ super() }}
 | 
			
		||||
<script>
 | 
			
		||||
  for (let user of {{ json_users|tojson }}) {
 | 
			
		||||
    if (user.id in app.data.users) {continue;}
 | 
			
		||||
    app.data.users[user.id] = user;
 | 
			
		||||
  }
 | 
			
		||||
  let userList = new UserList(document.querySelector('.user-list'));
 | 
			
		||||
  userList.init(app.data.users);
 | 
			
		||||
  userList._init({{ json_users|tojson }});
 | 
			
		||||
</script>
 | 
			
		||||
{% endblock scripts %}
 | 
			
		||||
 
 | 
			
		||||
@@ -49,6 +49,7 @@
 | 
			
		||||
          <div class="card-content">
 | 
			
		||||
            <span class="card-title">Other users and groups</span>
 | 
			
		||||
            <p>Find other users and follow them to see their corpora and groups.</p>
 | 
			
		||||
            <div class="public-user-list no-autoinit"></div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
@@ -115,3 +116,11 @@
 | 
			
		||||
  </div>
 | 
			
		||||
</div>
 | 
			
		||||
{% endblock modals %}
 | 
			
		||||
 | 
			
		||||
{% block scripts %}
 | 
			
		||||
{{ super() }}
 | 
			
		||||
<script>
 | 
			
		||||
  let publicUserList = new PublicUserList(document.querySelector('.public-user-list'));
 | 
			
		||||
  publicUserList._init({{ users|tojson }});
 | 
			
		||||
</script>
 | 
			
		||||
{% endblock scripts %}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user