diff --git a/djangoproject/core/models.py b/djangoproject/core/models.py index 5bd51165..11656824 100644 --- a/djangoproject/core/models.py +++ b/djangoproject/core/models.py @@ -303,6 +303,7 @@ def to_json(self): return json.dumps({ 'id': self.id, 'name': self.name, + 'description': self.description, 'homeURL': self.homeURL, 'trackerURL': self.trackerURL, 'image3x1': self.image3x1.url if self.image3x1 else None, diff --git a/djangoproject/core/services/bitcoin_frespo_services.py b/djangoproject/core/services/bitcoin_frespo_services.py index ed4326e4..ad26f073 100644 --- a/djangoproject/core/services/bitcoin_frespo_services.py +++ b/djangoproject/core/services/bitcoin_frespo_services.py @@ -107,7 +107,7 @@ def _notify_payment_finished_if_applicable(payment_id): break if is_finished: payment.offer.paid() - watches = watch_services.find_issue_watches(payment.offer.issue) + watches = watch_services.find_issue_and_project_watches(payment.offer.issue) mail_services.notify_payment_parties_and_watchers_paymentconfirmed(payment, watches) ActionLog.log_pay(payment) msg = 'payment_id=%s, value=%s, issue=%s' % ( diff --git a/djangoproject/core/services/issue_services.py b/djangoproject/core/services/issue_services.py index 28f04454..67a5cf0c 100644 --- a/djangoproject/core/services/issue_services.py +++ b/djangoproject/core/services/issue_services.py @@ -82,7 +82,7 @@ def sponsor_existing_issue(issue_id, dict, user): issue.is_public_suggestion = False issue.save() issue.update_redundant_fields() - watches = watch_services.find_issue_watches(issue) + watches = watch_services.find_issue_and_project_watches(issue) notifyWatchers_offeradded(offer, watches) msg = "offer: " + str(offer.price) + "\n
" +\ "issue key: " + offer.issue.key + "\n
" +\ @@ -107,7 +107,7 @@ def change_existing_offer(offer_id, offerdict, user): offer.issue.update_redundant_fields() old_offer = offer.clone() offer.changeOffer(offerdict) - watches = watch_services.find_issue_watches(offer.issue) + watches = watch_services.find_issue_and_project_watches(offer.issue) notifyWatchers_offerchanged(old_offer, offer, watches) return offer @@ -126,7 +126,7 @@ def add_solution_to_existing_issue(issue_id, comment_content, accepting_payments if(comment_content): comment = IssueComment.newComment(issue, user, comment_content) comment.save() - watches = watch_services.find_issue_watches(solution.issue) + watches = watch_services.find_issue_and_project_watches(solution.issue) notifyWatchers_workbegun(solution, comment, watches) if(accepting_payments): notifyWatchers_acceptingpayments(solution, watches) @@ -143,7 +143,7 @@ def abort_existing_solution(solution_id, comment_content, user): if(comment_content): comment = IssueComment.newComment(solution.issue, user, comment_content) comment.save() - watches = watch_services.find_issue_watches(solution.issue) + watches = watch_services.find_issue_and_project_watches(solution.issue) notifyWatchers_workstopped(solution, comment, watches) return solution, comment @@ -159,7 +159,7 @@ def revoke_existing_offer(offer_id, comment_content, user): if(comment_content): comment = IssueComment.newComment(offer.issue, user, comment_content) comment.save() - watches = watch_services.find_issue_watches(offer.issue) + watches = watch_services.find_issue_and_project_watches(offer.issue) notifyWatchers_offerrevoked(offer, comment, watches) return offer, comment @@ -174,7 +174,7 @@ def resolve_existing_solution(solution_id, comment_content, user): if(comment_content): comment = IssueComment.newComment(solution.issue, user, comment_content) comment.save() - watches = watch_services.find_issue_watches(solution.issue) + watches = watch_services.find_issue_and_project_watches(solution.issue) notifyWatchers_workdone(solution, comment, watches) return solution, comment diff --git a/djangoproject/core/services/mail_services.py b/djangoproject/core/services/mail_services.py index baaea918..4c28fc36 100644 --- a/djangoproject/core/services/mail_services.py +++ b/djangoproject/core/services/mail_services.py @@ -1,3 +1,4 @@ +import json import logging from django.core.mail import EmailMultiAlternatives @@ -66,6 +67,26 @@ def send_func(watch): _notify_watchers(send_func, watches) +def notifyWatchers_project_edited(user, project, old_json, watches): + old_dic = json.loads(old_json) + changed_description = old_dic['description'] != project.description + changed_image = old_dic['image3x1'] != project.image3x1.url + def send_func(watch): + if watch.user.id != user.id: + _send_mail_to_user(user=watch.user, + subject=user.getUserInfo().screenName + " edited project [%s]" % project.name, + templateName='email/project_edited.html', + contextData={"project": project, + "user": user, + "you": watch.user, + "SITE_HOME": settings.SITE_HOME, + "changed_description": changed_description, + "changed_image": changed_image, + "old_dic": old_dic}, + whentrue='receiveEmail_issue_work') + _notify_watchers(send_func, watches) + + def notifyWatchers_acceptingpayments(solution, watches): def send_func(watch): if(watch.user.id != solution.programmer.id): diff --git a/djangoproject/core/services/paypal_services.py b/djangoproject/core/services/paypal_services.py index 69489e2d..a05283ad 100644 --- a/djangoproject/core/services/paypal_services.py +++ b/djangoproject/core/services/paypal_services.py @@ -34,7 +34,7 @@ def process_ipn_return(paykey, status, tracking_id): payment.confirm_ipn() payment.offer.paid() payment.offer.issue.touch() - watches = watch_services.find_issue_watches(payment.offer.issue) + watches = watch_services.find_issue_and_project_watches(payment.offer.issue) notify_payment_parties_and_watchers_paymentconfirmed(payment, watches) notify_admin_payment_confirmed(payment) ActionLog.log_pay(payment) diff --git a/djangoproject/core/services/watch_services.py b/djangoproject/core/services/watch_services.py index 87f834bf..b20b9167 100644 --- a/djangoproject/core/services/watch_services.py +++ b/djangoproject/core/services/watch_services.py @@ -8,6 +8,20 @@ def find_issue_watches(issue): return Watch.objects.filter(entity='ISSUE', objid=issue.id) +def find_project_watches(project): + return Watch.objects.filter(entity='PROJECT', objid=project.id) + + +def find_issue_and_project_watches(issue): + iwatches = Watch.objects.filter(entity='ISSUE', objid=issue.id) + watches = [] + watches.extend(iwatches) + user_ids = set([w.user.id for w in watches]) + pwatches = Watch.objects.filter(entity='PROJECT', objid=issue.project.id) + watches.extend([w for w in pwatches if not w.user.id in user_ids]) + return watches + + def watch_issue(user, issue_id, reason): watch = _findWatchOrNone(user, 'ISSUE', issue_id) if not watch: diff --git a/djangoproject/core/views/project_views.py b/djangoproject/core/views/project_views.py index 6d2c8b2a..1a5bc9ee 100644 --- a/djangoproject/core/views/project_views.py +++ b/djangoproject/core/views/project_views.py @@ -2,7 +2,7 @@ from django.shortcuts import render_to_response, redirect from django.template import RequestContext from core.models import Project, ActionLog -from core.services import stats_services, issue_services, watch_services +from core.services import stats_services, issue_services, watch_services, mail_services from core.views import template_folder from django.contrib.auth.decorators import login_required @@ -49,6 +49,8 @@ def edit(request): project.image3x1 = request.FILES['image3x1'] project.description = request.POST.get('description') project.save() + watches = watch_services.find_project_watches(project) + mail_services.notifyWatchers_project_edited(request.user, project, old_json, watches) ActionLog.log_edit_project(project=project, user=request.user, old_json=old_json) return redirect('core.views.project_views.view', project_id=project.id) diff --git a/djangoproject/templates/email/project_edited.html b/djangoproject/templates/email/project_edited.html new file mode 100644 index 00000000..c9261492 --- /dev/null +++ b/djangoproject/templates/email/project_edited.html @@ -0,0 +1,27 @@ +{% extends "email/base.html" %} +{% block mainContent%} +Hello {{ you.getUserInfo.screenName }}
+ + {{ user.getUserInfo.screenName }} + +has edited the +{{ project.name }} +project. Details below

+ +Old project settings +
+ description: {{old_dic.description|linebreaks}}
+ image: {{old_dic.image3x1}} +
+New project settings +
+ description: {{project.description|linebreaks}}
+ image: {{project.image3x1.url}} +
+We will let you know if there are any updates. + +

+{% include 'email/include/email_settings_notice.html' %} + +{% endblock mainContent%} +