These are changes for issue #405, add email comment notification.

This commit is contained in:
Derek Moore 2012-03-15 16:38:56 -07:00
parent 20a3e278bc
commit 252eaf21d5
8 changed files with 133 additions and 19 deletions

View File

@ -153,3 +153,10 @@ def convert_video_media_data(database):
assert len(document['media_data']) == 1 assert len(document['media_data']) == 1
document['media_data'] = document['media_data']['video'] document['media_data'] = document['media_data']['video']
collection.save(document) collection.save(document)
@RegisterMigration(11)
def user_add_wants_comment_notification(database):
"""
Add wants_comment_notification to user model
"""
add_table_field(database, 'users', 'wants_comment_notification', True)

View File

@ -62,6 +62,8 @@ class User(Document, UserMixin):
we'll change this to a boolean with a key of 'active' and have a we'll change this to a boolean with a key of 'active' and have a
separate field for a reason the user's been disabled if that's separate field for a reason the user's been disabled if that's
appropriate... email_verified is already separate, after all.) appropriate... email_verified is already separate, after all.)
- wants_comment_notification: The user has selected that they want to be
notified when comments are posted on their media.
- verification_key: If the user is awaiting email verification, the user - verification_key: If the user is awaiting email verification, the user
will have to provide this key (which will be encoded in the presented will have to provide this key (which will be encoded in the presented
URL) in order to confirm their email as active. URL) in order to confirm their email as active.
@ -80,6 +82,7 @@ class User(Document, UserMixin):
'pw_hash': unicode, 'pw_hash': unicode,
'email_verified': bool, 'email_verified': bool,
'status': unicode, 'status': unicode,
'wants_comment_notification': bool,
'verification_key': unicode, 'verification_key': unicode,
'is_admin': bool, 'is_admin': bool,
'url': unicode, 'url': unicode,
@ -93,6 +96,7 @@ class User(Document, UserMixin):
default_values = { default_values = {
'created': datetime.datetime.utcnow, 'created': datetime.datetime.utcnow,
'email_verified': False, 'email_verified': False,
'wants_comment_notification': True,
'status': u'needs_email_verification', 'status': u'needs_email_verification',
'is_admin': False} 'is_admin': False}

View File

@ -70,6 +70,11 @@ class EditAccountForm(wtforms.Form):
wtforms.validators.Length(min=6, max=30)], wtforms.validators.Length(min=6, max=30)],
id="password") id="password")
wants_comment_notification = wtforms.BooleanField(
_('Comment notification?'),
[wtforms.validators.Required()],
description=_("Check this box to be emailed when someone else comments on your media."))
class EditAttachmentsForm(wtforms.Form): class EditAttachmentsForm(wtforms.Form):
attachment_name = wtforms.TextField( attachment_name = wtforms.TextField(

View File

@ -188,29 +188,39 @@ def edit_account(request):
edit_username = request.GET.get('username') edit_username = request.GET.get('username')
user = request.user user = request.user
form = forms.EditAccountForm(request.POST) form = forms.EditAccountForm(request.POST,
wants_comment_notification=user.wants_comment_notification)
if request.method == 'POST' and form.validate(): if request.method == 'POST':
password_matches = auth_lib.bcrypt_check_password( #save status of comment checkbox first, so user does not need to
request.POST['old_password'], #change their password as well.
user.pw_hash) user.wants_comment_notification = request.POST.get(
'wants_comment_notification', False) == u'y'
if (request.POST['old_password'] or request.POST['new_password']) and not \
password_matches:
form.old_password.errors.append(_('Wrong password'))
return render_to_response(
request,
'mediagoblin/edit/edit_account.html',
{'user': user,
'form': form})
if password_matches:
user.pw_hash = auth_lib.bcrypt_gen_password_hash(
request.POST['new_password'])
user.save() user.save()
#check remaining fields for validation
if form.validate():
password_matches = auth_lib.bcrypt_check_password(
request.POST['old_password'],
user.pw_hash)
if (request.POST['old_password'] or \
request.POST['new_password']) and not \
password_matches:
form.old_password.errors.append(_('Wrong password'))
return render_to_response(
request,
'mediagoblin/edit/edit_account.html',
{'user': user,
'form': form})
if password_matches:
user.pw_hash = auth_lib.bcrypt_gen_password_hash(
request.POST['new_password'])
user.save()
messages.add_message(request, messages.add_message(request,
messages.SUCCESS, messages.SUCCESS,
_("Account settings saved")) _("Account settings saved"))

View File

@ -0,0 +1,26 @@
{#
# GNU MediaGoblin -- federated, autonomous media hosting
# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# 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/>.
-#}
{% trans username=username, comment_author=comment_author -%}
Hi {{ username }},
{{ comment_author }} commented on your post ({{ comment_url }}) at GNU MediaGoblin:
{% endtrans %}
{{ comment_content }}
GNU MediaGoblin

View File

@ -37,6 +37,7 @@ def test_change_password(test_app):
'/edit/account/', { '/edit/account/', {
'old_password': 'toast', 'old_password': 'toast',
'new_password': '123456', 'new_password': '123456',
'wants_comment_notification': 'y'
}) })
# test_user has to be fetched again in order to have the current values # test_user has to be fetched again in order to have the current values

View File

@ -0,0 +1,54 @@
# GNU MediaGoblin -- federated, autonomous media hosting
# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# 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.mail import send_email
from mediagoblin.tools.template import render_template
from mediagoblin import mg_globals
def send_comment_email(user, comment, media, request):
"""
Sends comment email to user when a comment is made on their media.
Args:
- user: the user object to whom the email is sent
- comment: the comment object referencing user's media
- media: the media object the comment is about
- request: the request
"""
comment_url = u'http://{host}{comment_uri}'.format(
host=request.host,
comment_uri=request.urlgen(
'mediagoblin.user_pages.media_home.view_comment',
comment = comment._id,
user = media.get_uploader.username,
media = media.slug_or_id) + '#comment')
comment_author = comment.get_author['username']
rendered_email = render_template(
request, 'mediagoblin/user_pages/comment_email.txt',
{'username':user.username,
'comment_author':comment_author,
'comment_content':comment.content,
'comment_url':comment_url})
send_email(
mg_globals.app_config['email_sender_address'],
[user.email],
'GNU MediaGoblin - {comment_author} commented on your post'.format(
comment_author=comment_author),
rendered_email)

View File

@ -23,6 +23,7 @@ from mediagoblin.tools.translate import pass_to_ugettext as _
from mediagoblin.tools.pagination import Pagination from mediagoblin.tools.pagination import Pagination
from mediagoblin.tools.files import delete_media_files from mediagoblin.tools.files import delete_media_files
from mediagoblin.user_pages import forms as user_forms from mediagoblin.user_pages import forms as user_forms
from mediagoblin.user_pages.lib import send_comment_email
from mediagoblin.decorators import (uses_pagination, get_user_media_entry, from mediagoblin.decorators import (uses_pagination, get_user_media_entry,
require_active_login, user_may_delete_media) require_active_login, user_may_delete_media)
@ -158,6 +159,12 @@ def media_post_comment(request, media):
request, messages.SUCCESS, request, messages.SUCCESS,
_('Your comment has been posted!')) _('Your comment has been posted!'))
media_uploader = media.get_uploader
#don't send email if you comment on your own post
if (comment.author != media_uploader and
media_uploader['wants_comment_notification']):
send_comment_email(media_uploader, comment, media, request)
return exc.HTTPFound( return exc.HTTPFound(
location=media.url_for_self(request.urlgen)) location=media.url_for_self(request.urlgen))