aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mediagoblin/db/migrations.py16
-rw-r--r--mediagoblin/db/models.py1
-rw-r--r--mediagoblin/edit/forms.py2
-rw-r--r--mediagoblin/edit/views.py4
-rw-r--r--mediagoblin/notifications/__init__.py18
-rw-r--r--mediagoblin/notifications/routing.py4
-rw-r--r--mediagoblin/notifications/views.py29
-rw-r--r--mediagoblin/static/js/notifications.js13
-rw-r--r--mediagoblin/templates/mediagoblin/base.html3
-rw-r--r--mediagoblin/templates/mediagoblin/fragments/header_notifications.html4
-rw-r--r--mediagoblin/tests/test_notifications.py53
11 files changed, 133 insertions, 14 deletions
diff --git a/mediagoblin/db/migrations.py b/mediagoblin/db/migrations.py
index 374ab4c8..d542d7b9 100644
--- a/mediagoblin/db/migrations.py
+++ b/mediagoblin/db/migrations.py
@@ -425,7 +425,7 @@ class RequestToken_v0(declarative_base()):
callback = Column(Unicode, nullable=False, default=u"oob")
created = Column(DateTime, nullable=False, default=datetime.datetime.now)
updated = Column(DateTime, nullable=False, default=datetime.datetime.now)
-
+
class AccessToken_v0(declarative_base()):
"""
Model for representing the access tokens
@@ -438,7 +438,7 @@ class AccessToken_v0(declarative_base()):
request_token = Column(Unicode, ForeignKey(RequestToken_v0.token))
created = Column(DateTime, nullable=False, default=datetime.datetime.now)
updated = Column(DateTime, nullable=False, default=datetime.datetime.now)
-
+
class NonceTimestamp_v0(declarative_base()):
"""
@@ -460,3 +460,15 @@ def create_oauth1_tables(db):
NonceTimestamp_v0.__table__.create(db.bind)
db.commit()
+
+
+@RegisterMigration(15, MIGRATIONS)
+def wants_notifications(db):
+ """Add a wants_notifications field to User model"""
+ metadata = MetaData(bind=db.bind)
+ user_table = inspect_table(metadata, "core__users")
+
+ col = Column('wants_notifications', Boolean, default=True)
+ col.create(user_table)
+
+ db.commit()
diff --git a/mediagoblin/db/models.py b/mediagoblin/db/models.py
index 9cb39ff4..4341e086 100644
--- a/mediagoblin/db/models.py
+++ b/mediagoblin/db/models.py
@@ -69,6 +69,7 @@ class User(Base, UserMixin):
# Intented to be nullable=False, but migrations would not work for it
# set to nullable=True implicitly.
wants_comment_notification = Column(Boolean, default=True)
+ wants_notifications = Column(Boolean, default=True)
license_preference = Column(Unicode)
is_admin = Column(Boolean, default=False, nullable=False)
url = Column(Unicode)
diff --git a/mediagoblin/edit/forms.py b/mediagoblin/edit/forms.py
index 85c243a0..5de1bf96 100644
--- a/mediagoblin/edit/forms.py
+++ b/mediagoblin/edit/forms.py
@@ -67,6 +67,8 @@ class EditAccountForm(wtforms.Form):
normalize_user_or_email_field(allow_user=False)])
wants_comment_notification = wtforms.BooleanField(
description=_("Email me when others comment on my media"))
+ wants_notifications = wtforms.BooleanField(
+ description=_("Enable/Disable insite notifications"))
license_preference = wtforms.SelectField(
_('License preference'),
[
diff --git a/mediagoblin/edit/views.py b/mediagoblin/edit/views.py
index 6aa2acd9..a11cb932 100644
--- a/mediagoblin/edit/views.py
+++ b/mediagoblin/edit/views.py
@@ -228,10 +228,12 @@ def edit_account(request):
user = request.user
form = forms.EditAccountForm(request.form,
wants_comment_notification=user.wants_comment_notification,
- license_preference=user.license_preference)
+ license_preference=user.license_preference,
+ wants_notifications=user.wants_notifications)
if request.method == 'POST' and form.validate():
user.wants_comment_notification = form.wants_comment_notification.data
+ user.wants_notifications = form.wants_notifications.data
user.license_preference = form.license_preference.data
diff --git a/mediagoblin/notifications/__init__.py b/mediagoblin/notifications/__init__.py
index ed9f8d78..b6f9f478 100644
--- a/mediagoblin/notifications/__init__.py
+++ b/mediagoblin/notifications/__init__.py
@@ -17,7 +17,8 @@
import logging
from mediagoblin.db.models import Notification, \
- CommentNotification, CommentSubscription
+ CommentNotification, CommentSubscription, User
+from mediagoblin.notifications.task import email_notification_task
from mediagoblin.notifications.tools import generate_comment_message
_log = logging.getLogger(__name__)
@@ -121,6 +122,12 @@ NOTIFICATION_FETCH_LIMIT = 100
def get_notifications(user_id, only_unseen=True):
query = Notification.query.filter_by(user_id=user_id)
+ wants_notifications = User.query.filter_by(id=user_id).first()\
+ .wants_notifications
+
+ # If the user does not want notifications, don't return any
+ if not wants_notifications:
+ return None
if only_unseen:
query = query.filter_by(seen=False)
@@ -130,12 +137,19 @@ def get_notifications(user_id, only_unseen=True):
return notifications
+
def get_notification_count(user_id, only_unseen=True):
query = Notification.query.filter_by(user_id=user_id)
+ wants_notifications = User.query.filter_by(id=user_id).first()\
+ .wants_notifications
if only_unseen:
query = query.filter_by(seen=False)
- count = query.count()
+ # If the user doesn't want notifications, don't show any
+ if not wants_notifications:
+ count = None
+ else:
+ count = query.count()
return count
diff --git a/mediagoblin/notifications/routing.py b/mediagoblin/notifications/routing.py
index e57956d3..cd7bbc21 100644
--- a/mediagoblin/notifications/routing.py
+++ b/mediagoblin/notifications/routing.py
@@ -23,3 +23,7 @@ add_route('mediagoblin.notifications.subscribe_comments',
add_route('mediagoblin.notifications.silence_comments',
'/u/<string:user>/m/<string:media>/notifications/silence/',
'mediagoblin.notifications.views:silence_comments')
+
+add_route('mediagoblin.notifications.mark_all_comment_notifications_seen',
+ '/notifications/comments/mark_all_seen/',
+ 'mediagoblin.notifications.views:mark_all_comment_notifications_seen')
diff --git a/mediagoblin/notifications/views.py b/mediagoblin/notifications/views.py
index d275bc92..cfe66b2e 100644
--- a/mediagoblin/notifications/views.py
+++ b/mediagoblin/notifications/views.py
@@ -14,19 +14,15 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-from mediagoblin.tools.response import render_to_response, render_404, redirect
+from mediagoblin.tools.response import redirect
from mediagoblin.tools.translate import pass_to_ugettext as _
-from mediagoblin.decorators import (uses_pagination, get_user_media_entry,
- get_media_entry_by_id,
- require_active_login, user_may_delete_media, user_may_alter_collection,
- get_user_collection, get_user_collection_item, active_user_from_url)
-
+from mediagoblin.decorators import get_user_media_entry, require_active_login
from mediagoblin import messages
-from mediagoblin.notifications import add_comment_subscription, \
- silence_comment_subscription
+from mediagoblin.notifications import (add_comment_subscription,
+ silence_comment_subscription, mark_comment_notification_seen,
+ get_notifications)
-from werkzeug.exceptions import BadRequest
@get_user_media_entry
@require_active_login
@@ -41,6 +37,7 @@ def subscribe_comments(request, media):
return redirect(request, location=media.url_for_self(request.urlgen))
+
@get_user_media_entry
@require_active_login
def silence_comments(request, media):
@@ -52,3 +49,17 @@ def silence_comments(request, media):
' %s.') % media.title)
return redirect(request, location=media.url_for_self(request.urlgen))
+
+
+@require_active_login
+def mark_all_comment_notifications_seen(request):
+ """
+ Marks all comment notifications seen.
+ """
+ for comment in get_notifications(request.user.id):
+ mark_comment_notification_seen(comment.subject_id, request.user)
+
+ if request.GET.get('next'):
+ return redirect(request, location=request.GET.get('next'))
+ else:
+ return redirect(request, 'index')
diff --git a/mediagoblin/static/js/notifications.js b/mediagoblin/static/js/notifications.js
index 0153463a..78694f59 100644
--- a/mediagoblin/static/js/notifications.js
+++ b/mediagoblin/static/js/notifications.js
@@ -33,4 +33,17 @@ var notifications = {};
$(document).ready(function () {
notifications.init();
+
+ var mark_all_comments_seen = document.getElementById('mark_all_comments_seen');
+
+ if (mark_all_comments_seen) {
+ mark_all_comments_seen.href = '#';
+ mark_all_comments_seen.onclick = function() {
+ $.ajax({
+ type: 'GET',
+ url: mark_all_comments_seen_url,
+ success: function(res, status, xhr) { window.location.reload(); },
+ });
+ }
+ }
});
diff --git a/mediagoblin/templates/mediagoblin/base.html b/mediagoblin/templates/mediagoblin/base.html
index f7e2dff0..f9deb2ad 100644
--- a/mediagoblin/templates/mediagoblin/base.html
+++ b/mediagoblin/templates/mediagoblin/base.html
@@ -37,6 +37,9 @@
src="{{ request.staticdirect('/js/header_dropdown.js') }}"></script>
<script type="text/javascript"
src="{{ request.staticdirect('/js/notifications.js') }}"></script>
+ <script>
+ var mark_all_comments_seen_url = "{{ request.urlgen('mediagoblin.notifications.mark_all_comment_notifications_seen') }}"
+ </script>
{# For clarification, the difference between the extra_head.html template
# and the head template hook is that the former should be used by
diff --git a/mediagoblin/templates/mediagoblin/fragments/header_notifications.html b/mediagoblin/templates/mediagoblin/fragments/header_notifications.html
index 70d7935a..55759a39 100644
--- a/mediagoblin/templates/mediagoblin/fragments/header_notifications.html
+++ b/mediagoblin/templates/mediagoblin/fragments/header_notifications.html
@@ -36,5 +36,9 @@
</li>
{% endfor %}
</ul>
+ <a href="{{ request.urlgen('mediagoblin.notifications.mark_all_comment_notifications_seen') }}?next={{
+ request.base_url|urlencode }}" id="mark_all_comments_seen">
+ {% trans %}Mark all read{% endtrans %}
+ </a>
</div>
{% endif %}
diff --git a/mediagoblin/tests/test_notifications.py b/mediagoblin/tests/test_notifications.py
index d52b8d5a..e075d475 100644
--- a/mediagoblin/tests/test_notifications.py
+++ b/mediagoblin/tests/test_notifications.py
@@ -149,3 +149,56 @@ otherperson@example.com\n\nSGkgb3RoZXJwZXJzb24sCmNocmlzIGNvbW1lbnRlZCBvbiB5b3VyI
# User should not have been notified
assert len(notifications) == 1
+
+ def test_mark_all_comment_notifications_seen(self):
+ """ Test that mark_all_comments_seen works"""
+
+ user = fixture_add_user('otherperson', password='nosreprehto')
+
+ media_entry = fixture_media_entry(uploader=user.id, state=u'processed')
+
+ fixture_comment_subscription(media_entry)
+
+ media_uri_id = '/u/{0}/m/{1}/'.format(user.username,
+ media_entry.id)
+
+ # add 2 comments
+ self.test_app.post(
+ media_uri_id + 'comment/add/',
+ {
+ 'comment_content': u'Test comment #43'
+ }
+ )
+
+ self.test_app.post(
+ media_uri_id + 'comment/add/',
+ {
+ 'comment_content': u'Test comment #44'
+ }
+ )
+
+ notifications = Notification.query.filter_by(
+ user_id=user.id).all()
+
+ assert len(notifications) == 2
+
+ # both comments should not be marked seen
+ assert notifications[0].seen == False
+ assert notifications[1].seen == False
+
+ # login with other user to mark notifications seen
+ self.logout()
+ self.login('otherperson', 'nosreprehto')
+
+ # mark all comment notifications seen
+ res = self.test_app.get('/notifications/comments/mark_all_seen/')
+ res.follow()
+
+ assert urlparse.urlsplit(res.location)[2] == '/'
+
+ notifications = Notification.query.filter_by(
+ user_id=user.id).all()
+
+ # both notifications should be marked seen
+ assert notifications[0].seen == True
+ assert notifications[1].seen == True