Avatar Update

This commit is contained in:
Inga Kirschnick 2022-12-19 12:46:18 +01:00
parent 61a6ddd4be
commit d9699b9c6d
8 changed files with 131 additions and 13 deletions

View File

@ -1,5 +1,5 @@
from flask import flash, redirect, render_template, url_for 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.auth.forms import LoginForm
from app.models import User from app.models import User
from . import bp from . import bp
@ -27,7 +27,11 @@ def faq():
@bp.route('/dashboard') @bp.route('/dashboard')
@login_required @login_required
def dashboard(): 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') @bp.route('/user_manual')

View File

@ -254,7 +254,7 @@ class Avatar(HashidMixin, FileMixin, db.Model):
# Primary key # Primary key
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
# Foreign keys # 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 @property
def path(self): def path(self):
@ -267,13 +267,18 @@ class Avatar(HashidMixin, FileMixin, db.Model):
current_app.logger.error(e) current_app.logger.error(e)
db.session.delete(self) 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): class User(HashidMixin, UserMixin, db.Model):
__tablename__ = 'users' __tablename__ = 'users'
# Primary key # Primary key
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
# Foreign keys # Foreign keys
role_id = db.Column(db.Integer, db.ForeignKey('roles.id')) role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
# privacy_id = db.Column(db.Integer, db.ForeignKey('privacies.id'))
# Fields # Fields
email = db.Column(db.String(254), index=True, unique=True) email = db.Column(db.String(254), index=True, unique=True)
username = db.Column(db.String(64), 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 self.profile_privacy_settings = 0
#endregion Profile Privacy settings #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 = { json_serializeable = {
'id': self.hashid, 'id': self.hashid,
'confirmed': self.confirmed, 'confirmed': self.confirmed,
@ -555,28 +569,43 @@ class User(HashidMixin, UserMixin, db.Model):
'show_email': self.has_profile_privacy_setting(ProfilePrivacySettings.SHOW_EMAIL), 'show_email': self.has_profile_privacy_setting(ProfilePrivacySettings.SHOW_EMAIL),
'show_last_seen': self.has_profile_privacy_setting(ProfilePrivacySettings.SHOW_LAST_SEEN), 'show_last_seen': self.has_profile_privacy_setting(ProfilePrivacySettings.SHOW_LAST_SEEN),
'show_member_since': self.has_profile_privacy_setting(ProfilePrivacySettings.SHOW_MEMBER_SINCE) 'show_member_since': self.has_profile_privacy_setting(ProfilePrivacySettings.SHOW_MEMBER_SINCE)
} }
if backrefs: if backrefs:
json_serializeable['role'] = \ json_serializeable['role'] = \
self.role.to_json_serializeable(backrefs=True) self.role.to_json_serializeable(backrefs=True)
if relationships: if relationships or include_corpus_relationships:
json_serializeable['corpora'] = { json_serializeable['corpora'] = {
x.hashid: x.to_json_serializeable(relationships=True) x.hashid: x.to_json_serializeable(relationships=True)
for x in self.corpora for x in self.corpora
} }
if relationships or include_job_relationships:
json_serializeable['jobs'] = { json_serializeable['jobs'] = {
x.hashid: x.to_json_serializeable(relationships=True) x.hashid: x.to_json_serializeable(relationships=True)
for x in self.jobs for x in self.jobs
} }
if relationships or include_tesseract_ocr_pipeline_model_relationships:
json_serializeable['tesseract_ocr_pipeline_models'] = { json_serializeable['tesseract_ocr_pipeline_models'] = {
x.hashid: x.to_json_serializeable(relationships=True) x.hashid: x.to_json_serializeable(relationships=True)
for x in self.tesseract_ocr_pipeline_models for x in self.tesseract_ocr_pipeline_models
} }
if relationships or include_spacy_nlp_pipeline_model_relationships:
json_serializeable['spacy_nlp_pipeline_models'] = { json_serializeable['spacy_nlp_pipeline_models'] = {
x.hashid: x.to_json_serializeable(relationships=True) x.hashid: x.to_json_serializeable(relationships=True)
for x in self.spacy_nlp_pipeline_models 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 return json_serializeable
class TesseractOCRPipelineModel(FileMixin, HashidMixin, db.Model): class TesseractOCRPipelineModel(FileMixin, HashidMixin, db.Model):

View File

@ -54,7 +54,6 @@ def delete_avatar(avatar_id, user_id):
def _delete_avatar(app, avatar_id): def _delete_avatar(app, avatar_id):
with app.app_context(): with app.app_context():
avatar_file = Avatar.query.get(avatar_id) avatar_file = Avatar.query.get(avatar_id)
print(avatar_file)
avatar_file.delete() avatar_file.delete()
db.session.commit() db.session.commit()
thread = Thread( thread = Thread(

View 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;
}
}
}
}

View File

@ -11,6 +11,7 @@ class RessourceList {
JobInputList.autoInit(); JobInputList.autoInit();
JobResultList.autoInit(); JobResultList.autoInit();
PublicCorporaList.autoInit(); PublicCorporaList.autoInit();
PublicUserList.autoInit();
SpaCyNLPPipelineModelList.autoInit(); SpaCyNLPPipelineModelList.autoInit();
TesseractOCRPipelineModelList.autoInit(); TesseractOCRPipelineModelList.autoInit();
UserList.autoInit(); UserList.autoInit();

View File

@ -25,6 +25,7 @@
'js/RessourceLists/JobInputList.js', 'js/RessourceLists/JobInputList.js',
'js/RessourceLists/JobResultList.js', 'js/RessourceLists/JobResultList.js',
'js/RessourceLists/PublicCorporaList.js', 'js/RessourceLists/PublicCorporaList.js',
'js/RessourceLists/PublicUserList.js',
'js/RessourceLists/SpacyNLPPipelineModelList.js', 'js/RessourceLists/SpacyNLPPipelineModelList.js',
'js/RessourceLists/TesseractOCRPipelineModelList.js', 'js/RessourceLists/TesseractOCRPipelineModelList.js',
'js/RessourceLists/UserList.js' 'js/RessourceLists/UserList.js'

View File

@ -22,11 +22,7 @@
{% block scripts %} {% block scripts %}
{{ super() }} {{ super() }}
<script> <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')); let userList = new UserList(document.querySelector('.user-list'));
userList.init(app.data.users); userList._init({{ json_users|tojson }});
</script> </script>
{% endblock scripts %} {% endblock scripts %}

View File

@ -49,6 +49,7 @@
<div class="card-content"> <div class="card-content">
<span class="card-title">Other users and groups</span> <span class="card-title">Other users and groups</span>
<p>Find other users and follow them to see their corpora and groups.</p> <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> </div>
</div> </div>
@ -115,3 +116,11 @@
</div> </div>
</div> </div>
{% endblock modals %} {% endblock modals %}
{% block scripts %}
{{ super() }}
<script>
let publicUserList = new PublicUserList(document.querySelector('.public-user-list'));
publicUserList._init({{ users|tojson }});
</script>
{% endblock scripts %}