Add notifications

Fixes #28
This commit is contained in:
rubenwardy 2018-05-13 17:55:28 +01:00
parent f3c433de06
commit 4fdafefcd5
No known key found for this signature in database
GPG Key ID: A1E29D52FF81513C
8 changed files with 99 additions and 5 deletions

View File

@ -88,8 +88,11 @@ class User(db.Model, UserMixin):
display_name = db.Column(db.String(100), nullable=False, server_default="")
# Content
packages = db.relationship("Package", backref="author", lazy="dynamic")
requests = db.relationship("EditRequest", backref="author", lazy="dynamic")
notifications = db.relationship("Notification", primaryjoin="User.id==Notification.user_id")
# causednotifs = db.relationship("Notification", backref="causer", lazy="dynamic")
packages = db.relationship("Package", backref="author", lazy="dynamic")
requests = db.relationship("EditRequest", backref="author", lazy="dynamic")
def __init__(self, username):
import datetime
@ -119,6 +122,24 @@ class User(db.Model, UserMixin):
else:
raise Exception("Permission {} is not related to users".format(perm.name))
class Notification(db.Model):
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey("user.id"))
causer_id = db.Column(db.Integer, db.ForeignKey("user.id"))
user = db.relationship("User", foreign_keys=[user_id])
causer = db.relationship("User", foreign_keys=[causer_id])
title = db.Column(db.String(100), nullable=False)
url = db.Column(db.String(200), nullable=True)
def __init__(self, us, cau, titl, ur):
self.user = us
self.causer = cau
self.title = titl
self.url = ur
class License(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50), nullable=False, unique=True)

View File

@ -40,6 +40,7 @@
</ul>
<ul class="nav navbar-nav navbar-right">
{% if current_user.is_authenticated %}
<li><a href="{{ url_for('notifications_page') }}">({{ current_user.notifications | length }})</a></li>
<li><a href="{{ url_for('user_profile_page', username=current_user.username) }}">{{ current_user.display_name }}</a></li>
<li><a href="{{ url_for('user.logout') }}">Sign out</a></li>
{% else %}

View File

@ -0,0 +1,17 @@
{% extends "base.html" %}
{% block title %}
Notifications
{% endblock %}
{% block content %}
<ul>
{% for n in current_user.notifications %}
<li><a href="{{ n.url }}">
{{ n.title}} [{{ n.causer.display_name }}]
</a></li>
{% else %}
<li><i>No notifications</i></ul>
{% endfor %}
</ul>
{% endblock %}

View File

@ -30,4 +30,4 @@ def home_page():
packages = Package.query.filter_by(approved=True).all()
return render_template("index.html", packages=packages)
from . import users, githublogin, packages, sass, tasks, admin
from . import users, githublogin, packages, sass, tasks, admin, notifications

View File

@ -0,0 +1,9 @@
from flask import *
from flask_user import current_user, login_required
from app import app
from app.models import *
@app.route("/notifications/")
@login_required
def notifications_page():
return render_template("notifications/list.html")

View File

@ -96,6 +96,8 @@ def package_page(author, name):
if shouldReturnJson():
return jsonify(package.getAsDictionary(app.config["BASE_URL"]))
else:
clearNotifications(package.getDetailsURL())
releases = getReleases(package)
requests = [r for r in package.requests if r.status == 0]
return render_template("packages/view.html", package=package, releases=releases, requests=requests)
@ -168,7 +170,9 @@ def create_edit_package_page(author=None, name=None):
if not package:
package = Package()
package.author = author
# package.approved = package.checkPerm(current_user, Permission.APPROVE_NEW)
else:
triggerNotif(package.author, current_user,
"{} edited".format(package.title), package.getDetailsURL())
form.populate_obj(package) # copy to row
@ -194,8 +198,10 @@ def approve_package_page(author=None, name=None):
else:
package.approved = True
db.session.commit()
triggerNotif(package.author, current_user,
"{} approved".format(package.title), package.getDetailsURL())
db.session.commit()
return redirect(package.getDetailsURL())
@ -222,6 +228,10 @@ def create_screenshot_page(author, name):
ss.title = form["title"].data
ss.url = uploadedPath
db.session.add(ss)
msg = "{}: Screenshot added {}" \
.format(package.title, ss.title)
triggerNotif(package.author, current_user, msg, erequest.getURL())
db.session.commit()
return redirect(package.getDetailsURL())
@ -292,6 +302,10 @@ def create_edit_editrequest_page(pauthor, name, id=None):
wasChangeMade = True
if wasChangeMade:
msg = "{}: Edit request #{} {}" \
.format(package.title, erequest.id, "created" if id is None else "edited")
triggerNotif(package.author, current_user, msg, erequest.getURL())
triggerNotif(erequest.author, current_user, msg, erequest.getURL())
db.session.commit()
return redirect(erequest.getURL())
else:
@ -311,6 +325,7 @@ def view_editrequest_page(pauthor, name, id):
if erequest is None:
abort(404)
clearNotifications(erequest.getURL())
return render_template("packages/editrequest_view.html", package=package, request=erequest)
@ -331,6 +346,10 @@ def approve_editrequest_page(pauthor, name, id):
else:
erequest.status = 1
erequest.applyAll(package)
msg = "{}: Edit request #{} merged".format(package.title, erequest.id)
triggerNotif(erequest.author, current_user, msg, erequest.getURL())
triggerNotif(package.author, current_user, msg, erequest.getURL())
db.session.commit()
return redirect(package.getDetailsURL())
@ -351,6 +370,10 @@ def reject_editrequest_page(pauthor, name, id):
else:
erequest.status = 2
msg = "{}: Edit request #{} rejected".format(package.title, erequest.id)
triggerNotif(erequest.author, current_user, msg, erequest.getURL())
triggerNotif(package.author, current_user, msg, erequest.getURL())
db.session.commit()
return redirect(package.getDetailsURL())
@ -389,6 +412,9 @@ def create_release_page(author, name):
db.session.commit()
rel.task_id = makeVCSRelease.delay(rel.id, form["vcsLabel"].data).id
msg = "{}: Release {} created".format(package.title, rel.title)
triggerNotif(package.author, current_user, msg, rel.getEditURL())
db.session.commit()
return redirect(url_for("check_task", id=rel.task_id, r=package.getDetailsURL()))
@ -400,6 +426,9 @@ def create_release_page(author, name):
rel.title = form["title"].data
rel.url = uploadedPath
db.session.add(rel)
msg = "{}: Release {} created".format(package.title, rel.title)
triggerNotif(package.author, current_user, msg, erequest.getURL())
db.session.commit()
return redirect(package.getDetailsURL())
@ -420,6 +449,8 @@ def edit_release_page(author, name, id):
if package.name != name or package.author.username != author:
abort(404)
clearNotifications(release.getEditURL())
canEdit = package.checkPerm(current_user, Permission.MAKE_RELEASE)
canApprove = package.checkPerm(current_user, Permission.APPROVE_RELEASE)
if not (canEdit or canApprove):

View File

@ -91,3 +91,14 @@ def rank_required(rank):
return decorated_function
return decorator
def triggerNotif(owner, causer, title, url):
if owner.rank.atLeast(UserRank.NEW_MEMBER) and owner != causer:
Notification.query.filter_by(user=owner, url=url).delete()
notif = Notification(owner, causer, title, url)
db.session.add(notif)
def clearNotifications(url):
if current_user.is_authenticated:
Notification.query.filter_by(user=current_user, url=url).delete()
db.session.commit()

View File

@ -21,12 +21,16 @@ if not os.path.isfile("db.sqlite"):
ruben.rank = UserRank.ADMIN
db.session.add(ruben)
ez = User("Shara")
ez.github_username = "Ezhh"
ez.forums_username = "Shara"
ez.rank = UserRank.EDITOR
db.session.add(ez)
not1 = Notification(ruben, ez, "Awards approved", "/packages/rubenwardy/awards/")
db.session.add(not1)
jeija = User("Jeija")
jeija.github_username = "Jeija"
db.session.add(jeija)