def testGetHostName(self): """Tests that a correct host name is returned. """ test_data = RequestData() test_site = site.Site(link_id='test', hostname='test_host') test_data.site = test_site try: expected_host = os.environ['HTTP_HOST'] = 'some.testing.host.tld' self.assertEqual(system.getHostname(), expected_host) finally: if self.default_host is None: del os.environ['HTTP_HOST'] else: os.environ['HTTP_HOST'] = self.default_host #test a data object expected_host = 'test_host' self.assertEqual(system.getHostname(data=test_data), expected_host) test_data.site.hostname = '' try: expected_host = os.environ['HTTP_HOST'] = 'some.testing.host.tld' self.assertEqual(system.getHostname(data=test_data), expected_host) finally: if self.default_host is None: del os.environ['HTTP_HOST'] else: os.environ['HTTP_HOST'] = self.default_host
def sendNewOrganizationNotification(entity, module_name): """Sends out an invite notification to the applicant of the Organization. Args: entity : An accepted OrgAppRecord """ program_entity = entity.survey.scope url = 'http://%(host)s%(redirect)s' % { 'redirect': redirects.getApplicantRedirect(entity, {'url_name': '%s/org' % module_name, 'program': program_entity}), 'host': system.getHostname(), } message_properties = { 'org_name': entity.name, 'program_name': program_entity.name, 'url': url } subject = DEF_NEW_ORG_MSG_FMT % { 'group_name': entity.name, } template = DEF_NEW_ORG_TEMPLATE for to in [entity.main_admin, entity.backup_admin]: if not to: continue sendNotification(to, None, message_properties, subject, template)
def getFirstTaskConfirmationContext(student): """Sends notification to the GCI student, when he or she completes their first task. Args: student: the student who should receive the confirmation """ user = student.parent() to = accounts.denormalizeAccount(user.account).email() subject = DEF_FIRST_TASK_CONFIRMATION_SUBJECT program = student.scope kwargs = { 'sponsor': program.scope_path, 'program': program.link_id } url = reverse('gci_student_form_upload', kwargs=kwargs) protocol = 'http' hostname = system.getHostname() context = { 'student_forms_link': '%s://%s%s' % (protocol, hostname, url), } template = DEF_FIRST_TASK_CONFIRMATION_TEMPLATE body = loader.render_to_string(template, context) return mailer.getMailContext(to=to, subject=subject, html=body, bcc=[])
def sendNewReviewNotification(to_user, review, reviewed_name, redirect_url): """Sends out a notification to alert the user of a new Review. Args: to_user: The user who should receive a notification review: The review which triggers this notification reviewed_name: Name of the entity reviewed redirect_url: URL to which the follower should be sent for more information """ review_notification_url = 'http://%(host)s%(redirect_url)s' % { 'host' : system.getHostname(), 'redirect_url': redirect_url} message_properties = {'review_notification_url': review_notification_url, 'reviewer_name': review.author_name(), 'reviewed_name': reviewed_name, 'review_content': review.content, 'review_visibility': 'public' if review.is_public else 'private', } # determine the subject review_type = 'public' if review.is_public else 'private' subject = DEF_NEW_REVIEW_SUBJECT_FMT % (review_type, reviewed_name) template = DEF_NEW_REVIEW_NOTIFICATION_TEMPLATE # send the notification from the system # TODO(srabbelier): do this in a task instead sendNotification(to_user, None, message_properties, subject, template)
def sendInviteNotification(entity): """Sends out an invite notification to the user the request is for. Args: entity : A request containing the information needed to create the message """ from soc.logic.models.user import logic as user_logic from soc.views.models.role import ROLE_VIEWS invitation_url = 'http://%(host)s%(index)s' % { 'host' : system.getHostname(), 'index': redirects.getInviteProcessRedirect(entity, None), } role_params = ROLE_VIEWS[entity.role].getParams() message_properties = { 'role_verbose' : role_params['name'], 'group': entity.group.name, 'invitation_url': invitation_url, } subject = DEF_INVITATION_MSG_FMT % { 'role_verbose' : role_params['name'], 'group' : entity.group.name } template = DEF_GROUP_INVITE_NOTIFICATION_TEMPLATE from_user = user_logic.getCurrentUser() sendNotification(entity.user, from_user, message_properties, subject, template)
def sendNewRequestNotification(request_entity): """Sends out a notification to the persons who can process this Request. Args: request_entity: an instance of Request model """ from soc.logic.helper import notifications from soc.logic.models.role import ROLE_LOGICS from soc.views.models.role import ROLE_VIEWS # get the users who should get the notification to_users = [] # retrieve the Role Logics which we should query on role_logic = ROLE_LOGICS[request_entity.role] role_logics_to_notify = role_logic.getRoleLogicsToNotifyUponNewRequest() # the scope of the roles is the same as the scope of the Request entity fields = {'scope': request_entity.group, 'status': 'active'} for role_logic in role_logics_to_notify: roles = role_logic.getForFields(fields) for role_entity in roles: # TODO: this might lead to double notifications to_users.append(role_entity.user) # get the user the request is from user_entity = request_entity.user role_params = ROLE_VIEWS[request_entity.role].getParams() request_url = 'http://%(host)s%(redirect)s' % { 'host': system.getHostname(), 'redirect': redirects.getProcessRequestRedirect(request_entity, None), } message_properties = { 'requester': user_entity.name, 'role_verbose': role_params['name'], 'group': request_entity.group.name, 'request_url': request_url } subject = DEF_NEW_REQUEST_MSG_FMT % { 'requester': user_entity.name, 'role_verbose' : role_params['name'], 'group' : request_entity.group.name } template = DEF_NEW_REQUEST_NOTIFICATION_TEMPLATE for to_user in to_users: notifications.sendNotification(to_user, None, message_properties, subject, template)
def key(entity): """Returns the memcache key for an entities homepage. """ host = system.getHostname() version = system.getAppVersion() kind = entity.kind() key = entity.key().id_or_name() return 'homepage_for_%s_%s_%s_%s' % (host, version, kind, key)
def isReferrerSelf(request, expected_prefix=None, suffix=None, url_name=None): """Returns True if HTTP referrer path starts with the HTTP request path. Args: request: the Django HTTP request object; request.path is used if expected_path is not supplied (the most common usage) expected_prefix: optional HTTP path to use instead of the one in request.path; default is None (use request.path) suffix: suffix to remove from the HTTP request path before comparing it to the HTTP referrer path in the HTTP request object headers (this is often an link ID, for example, that may be changing from a POST referrer to a GET redirect target) url_name: url name of the entity that is being created Returns: True if HTTP referrer path begins with the HTTP request path (either request.path or expected_prefix instead if it was supplied), after any suffix was removed from that request path False otherwise """ http_from = request.META.get('HTTP_REFERER') if not http_from: # no HTTP referrer, so cannot possibly start with expected prefix return False http_host = 'http://%s/%s' % (system.getHostname(), url_name) if http_from.startswith(http_host): return True from_path = urlparse.urlparse(http_from).path if not expected_prefix: # use HTTP request path, since expected_prefix was not supplied expected_prefix = request.path if suffix: # remove suffix (such as a link ID) before comparison chars_to_remove = len(suffix) if not suffix.startswith('/'): chars_to_remove = chars_to_remove + 1 expected_prefix = expected_prefix[:-chars_to_remove] if not from_path.startswith(expected_prefix): # expected prefix did not match first part of HTTP referrer path return False # HTTP referrer started with (possibly truncated) expected prefix return True
def isReferrerSelf(request, expected_prefix=None, suffix=None, url_name=None): """Returns True if HTTP referrer path starts with the HTTP request path. Args: request: the Django HTTP request object; request.path is used if expected_path is not supplied (the most common usage) expected_prefix: optional HTTP path to use instead of the one in request.path; default is None (use request.path) suffix: suffix to remove from the HTTP request path before comparing it to the HTTP referrer path in the HTTP request object headers (this is often an link ID, for example, that may be changing from a POST referrer to a GET redirect target) url_name: url name of the entity that is being created Returns: True if HTTP referrer path begins with the HTTP request path (either request.path or expected_prefix instead if it was supplied), after any suffix was removed from that request path False otherwise """ http_from = request.META.get('HTTP_REFERER') if not http_from: # no HTTP referrer, so cannot possibly start with expected prefix return False http_host = 'http://%s/%s' % (system.getHostname(), url_name) if http_from.startswith(http_host): return True from_path = urlparse.urlparse(http_from).path if not expected_prefix: # use HTTP request path, since expected_prefix was not supplied expected_prefix = request.path if suffix: # remove suffix (such as a link ID) before comparison chars_to_remove = len(suffix) if not suffix.startswith('/'): chars_to_remove = chars_to_remove + 1 expected_prefix = expected_prefix[:-chars_to_remove] if not from_path.startswith(expected_prefix): # expected prefix did not match first part of HTTP referrer path return False # HTTP referrer started with (possibly truncated) expected prefix return True
def assignSlots(self, request, access_type, page_name=None, params=None, **kwargs): """View that allows to assign slots to orgs. """ from soc.modules.gsoc.views.models.organization import view as org_view program_entity = program_logic.getFromKeyFieldsOr404(kwargs) description = self.DEF_SLOTS_ALLOCATION_MSG org_params = org_view.getParams().copy() org_params['list_description'] = description org_params['list_template'] = "modules/gsoc/program/list/allocation.html" org_params['public_field_props'] = { "link_id": { "hidden": True, } } org_params['public_row_action'] = {} org_params['public_row_extra'] = lambda entity: {} org_params['public_conf_extra'] = { "rowNum": -1, "rowList": [], } org_params['public_field_keys'] = [ "name", "slots_desired", "nr_applications", "nr_mentors", "locked", "slots_ass", "slots", "link_id", ] org_params['public_field_names'] = [ "Name", "Desired", "#Proposals", "#Mentors", "Locked?", "Slots Assigned", "Slots Visible to Org", "Link ID", ] fields = { 'scope': program_entity, 'status': ['new', 'active', 'inactive'] } return_url = "http://%(host)s%(index)s" % { 'host' : system.getHostname(), 'index': redirects.getSlotsRedirect(program_entity, params) } context = { 'total_slots': program_entity.slots, 'uses_json': True, 'uses_slot_allocator': True, 'return_url': return_url, } return self.list(request, 'allow', page_name=page_name, params=org_params, filter=fields, context=context)
def sendNewNotificationMessage(notification_entity): """Sends an email to a user about a new notification. Args: notification_entity: Notification about which the message should be sent """ from soc.logic.models.site import logic as site_logic from soc.views.models.notification import view as notification_view # create the url to show this notification notification_url = 'http://%(host)s%(index)s' % { 'host' : system.getHostname(), 'index': redirects.getPublicRedirect(notification_entity, notification_view.getParams())} sender = mail_dispatcher.getDefaultMailSender() site_entity = site_logic.getSingleton() site_name = site_entity.site_name # get the default mail sender default_sender = mail_dispatcher.getDefaultMailSender() if not default_sender: # no valid sender found, abort logging.error('No default sender') return else: (sender_name, sender) = default_sender to = accounts.denormalizeAccount(notification_entity.scope.account).email() subject = DEF_NEW_NOTIFICATION_MSG_SUBJECT_FMT % notification_entity.subject # create the message contents messageProperties = { 'to_name': notification_entity.scope.name, 'sender_name': sender_name, 'to': to, 'sender': sender, 'site_name': site_name, 'subject': force_unicode(subject), 'notification' : notification_entity, 'notification_url' : notification_url } # send out the message using the default new notification template mail_dispatcher.sendMailFromTemplate('soc/mail/new_notification.html', messageProperties)
def _fullUrl(self, url, full, secure): """Returns the full version of the url iff full. The full version starts with http:// and includes getHostname(). """ if (not full) and (system.isLocal() or not secure): return url if secure: protocol = 'https' hostname = system.getSecureHostname() else: protocol = 'http' hostname = system.getHostname(self._data) return '%s://%s%s' % (protocol, hostname, url)
def _review(self, request, params, app_entity, status, **kwargs): """Sends out an email if an org_app has been accepted or rejected. For params see group_app.View._review(). """ if status == 'accepted' or status == 'rejected': default_sender = mail_dispatcher.getDefaultMailSender() if not default_sender: # no default sender abort return else: (sender_name, sender) = default_sender # construct the contents of the email admin_entity = app_entity.applicant backup_entity = app_entity.backup_admin context = { 'sender': sender, 'sender_name': sender_name, 'program_name': app_entity.scope.name, 'org_app_name': app_entity.name } if status == 'accepted': # use the accepted template and subject template = params['accepted_mail_template'] context['subject'] = 'Congratulations!' context['HTTP_host'] = 'http://%s' % (system.getHostname()) elif status == 'rejected': # use the rejected template and subject template = params['rejected_mail_template'] context['subject'] = 'Thank you for your application' for to in [admin_entity, backup_entity]: if not to: continue email = accounts.denormalizeAccount(to.account).email() context['to'] = email context['to_name'] = to.name # send out the constructed email mail_dispatcher.sendMailFromTemplate(template, context)
def sendWelcomeMessage(user_entity): """Sends out a welcome message to a user. Args: user_entity: User entity which the message should be send to """ from soc.logic.models.site import logic as site_logic # get site name site_entity = site_logic.getSingleton() site_name = site_entity.site_name # get the default mail sender default_sender = mail_dispatcher.getDefaultMailSender() if not default_sender: # no valid sender found, should not happen but abort anyway logging.error('No default sender') return else: sender_name, sender = default_sender to = accounts.denormalizeAccount(user_entity.account).email() # create the message contents messageProperties = { 'to_name': user_entity.name, 'sender_name': sender_name, 'to': to, 'sender': sender, 'subject': DEF_WELCOME_MSG_FMT % { 'site_name': site_name, 'name': user_entity.name }, 'site_name': site_name, 'site_location': 'http://%s' % system.getHostname(), } # send out the message using the default welcome template mail_dispatcher.sendMailFromTemplate('soc/mail/welcome.html', messageProperties)
def assignSlots(self, request, access_type, page_name=None, params=None, **kwargs): """View that allows to assign slots to orgs. """ from soc.modules.gsoc.views.models.organization import view as org_view org_params = org_view.getParams().copy() org_params['list_template'] = 'soc/program/allocation/allocation.html' org_params['list_heading'] = 'soc/program/allocation/heading.html' org_params['list_row'] = 'soc/program/allocation/row.html' org_params['list_pagination'] = 'soc/list/no_pagination.html' program_entity = program_logic.getFromKeyFieldsOr404(kwargs) description = self.DEF_SLOTS_ALLOCATION_MSG content = self._getOrgsWithProfilesList(program_entity, org_view, description, False) contents = [content] return_url = "http://%(host)s%(index)s" % { 'host': system.getHostname(), 'index': redirects.getSlotsRedirect(program_entity, params) } context = { 'total_slots': program_entity.slots, 'uses_json': True, 'uses_slot_allocator': True, 'return_url': return_url, } return self._list(request, org_params, contents, page_name, context)
def getTaskCommentContext(task, comment, to_emails): """Sends out notifications to the subscribers. Args: task: task entity that comment made on. comment: comment entity. to_emails: list of recepients for the notification. """ url_kwargs = { 'sponsor': task.program.scope_path, 'program': task.program.link_id, 'id': task.key().id(), } task_url = 'http://%(host)s%(task)s' % { 'host': system.getHostname(), 'task': reverse('gci_view_task', kwargs=url_kwargs)} commented_by = comment.created_by.name if comment.created_by else "Melange" message_properties = { 'commented_by': commented_by, 'comment_title': comment.title, 'comment_content': comment.content, 'group': task.org.name, 'program_name': task.program.name, 'sender_name': 'The %s Team' % site.singleton().site_name, 'task_title': task.title, 'task_url': task_url, } subject = DEF_NEW_TASK_COMMENT_SUBJECT % message_properties template = DEF_NEW_TASK_COMMENT_NOTIFICATION_TEMPLATE body = loader.render_to_string(template, dictionary=message_properties) return mailer.getMailContext(to=[], subject=subject, html=body, bcc=to_emails)
def sendSurveyReminderForProject(request, *args, **kwargs): """Sends a reminder mail for a given StudentProject and Survey. A reminder is only send if no record is on file for the given Survey and StudentProject. Expects the following to be present in the POST dict: survey_key: specifies the key name for the ProjectSurvey to send reminders for survey_type: either project or grading depending on the type of Survey project_key: key which specifies the project to send a reminder for Args: request: Django Request object """ from soc.logic import mail_dispatcher from soc.logic.models.site import logic as site_logic from soc.views.helper import redirects from soc.modules.gsoc.logic.models.org_admin import logic as org_admin_logic from soc.modules.gsoc.logic.models.student_project import logic as \ student_project_logic from soc.modules.gsoc.logic.models.survey import grading_logic from soc.modules.gsoc.logic.models.survey import project_logic post_dict = request.POST project_key = post_dict.get('project_key') survey_key = post_dict.get('survey_key') survey_type = post_dict.get('survey_type') if not (project_key and survey_key and survey_type): # invalid task data, log and return OK return error_handler.logErrorAndReturnOK( 'Invalid sendSurveyReminderForProject data: %s' % post_dict) # set logic depending on survey type specified in POST if survey_type == 'project': survey_logic = project_logic elif survey_type == 'grading': survey_logic = grading_logic # retrieve the project and survey student_project = student_project_logic.getFromKeyName(project_key) if not student_project: # no existing project found, log and return OK return error_handler.logErrorAndReturnOK( 'Invalid project specified %s:' % project_key) survey = survey_logic.getFromKeyName(survey_key) if not survey: # no existing survey found, log and return OK return error_handler.logErrorAndReturnOK( 'Invalid survey specified %s:' % survey_key) # try to retrieve an existing record record_logic = survey_logic.getRecordLogic() fields = {'project': student_project, 'survey': survey} record_entity = record_logic.getForFields(fields, unique=True) if not record_entity: # send reminder email because we found no record student_entity = student_project.student site_entity = site_logic.getSingleton() if survey_type == 'project': survey_redirect = redirects.getTakeSurveyRedirect( survey,{'url_name': 'gsoc/project_survey'}) to_role = student_entity mail_template = 'soc/project_survey/mail/reminder_gsoc.html' elif survey_type == 'grading': survey_redirect = redirects.getTakeSurveyRedirect( survey,{'url_name': 'gsoc/grading_project_survey'}) to_role = student_project.mentor mail_template = 'soc/grading_project_survey/mail/reminder_gsoc.html' survey_url = "http://%(host)s%(redirect)s" % { 'redirect': survey_redirect, 'host': system.getHostname(), } # set the context for the mail template mail_context = { 'student_name': student_entity.name(), 'project_title': student_project.title, 'survey_url': survey_url, 'survey_end': survey.survey_end, 'to_name': to_role.name(), 'site_name': site_entity.site_name, } # set the sender (_, sender_address) = mail_dispatcher.getDefaultMailSender() mail_context['sender'] = sender_address # set the receiver and subject mail_context['to'] = to_role.email mail_context['subject'] = 'Evaluation Survey "%s" Reminder' %(survey.title) # find all org admins for the project's organization org_entity = student_project.scope fields = {'scope': org_entity, 'status': 'active'} org_admin_entities = org_admin_logic.getForFields(fields) # collect email addresses for all found org admins org_admin_addresses = [] for org_admin_entity in org_admin_entities: org_admin_addresses.append(org_admin_entity.email) if org_admin_addresses: mail_context['cc'] = org_admin_addresses # send out the email mail_dispatcher.sendMailFromTemplate(mail_template, mail_context) # return OK return http.HttpResponse()
def assignSlots(self, request, access_type, page_name=None, params=None, **kwargs): """View that allows to assign slots to orgs. """ from soc.modules.gsoc.views.models.organization import view as org_view program_entity = program_logic.getFromKeyFieldsOr404(kwargs) description = self.DEF_SLOTS_ALLOCATION_MSG org_params = org_view.getParams().copy() org_params['list_description'] = description org_params[ 'list_template'] = "modules/gsoc/program/list/allocation.html" org_params['public_field_props'] = { "link_id": { "hidden": True, } } org_params['public_row_action'] = {} org_params['public_row_extra'] = lambda entity: {} org_params['public_conf_extra'] = { "rowNum": -1, "rowList": [], } org_params['public_field_keys'] = [ "name", "slots_desired", "nr_applications", "nr_mentors", "locked", "slots_ass", "slots", "link_id", ] org_params['public_field_names'] = [ "Name", "Desired", "#Proposals", "#Mentors", "Locked?", "Slots Assigned", "Slots Visible to Org", "Link ID", ] fields = { 'scope': program_entity, 'status': ['new', 'active', 'inactive'] } return_url = "http://%(host)s%(index)s" % { 'host': system.getHostname(), 'index': redirects.getSlotsRedirect(program_entity, params) } context = { 'total_slots': program_entity.slots, 'uses_json': True, 'uses_slot_allocator': True, 'return_url': return_url, } return self.list(request, 'allow', page_name=page_name, params=org_params, filter=fields, context=context)
def sendSurveyReminderForProject(self, request, *args, **kwargs): """Sends a reminder mail for a given StudentProject and Survey. A reminder is only send if no record is on file for the given Survey and StudentProject. Expects the following to be present in the POST dict: survey_key: specifies the key name for the ProjectSurvey to send reminders for survey_type: either project or grading depending on the type of Survey project_key: encoded Key which specifies the project to send a reminder for Args: request: Django Request object """ post_dict = request.POST project_key = post_dict.get('project_key') survey_key = post_dict.get('survey_key') survey_type = post_dict.get('survey_type') if not (project_key and survey_key and survey_type): # invalid task data, log and return OK return error_handler.logErrorAndReturnOK( 'Invalid sendSurveyReminderForProject data: %s' % post_dict) # set model depending on survey type specified in POST if survey_type == 'project': survey_model = ProjectSurvey record_model = GSoCProjectSurveyRecord elif survey_type == 'grading': survey_model = GradingProjectSurvey record_model = GSoCGradingProjectSurveyRecord else: return error_handler.logErrorAndReturnOK( '%s is an invalid survey_type' %survey_type) # retrieve the project and survey project_key = db.Key(project_key) project = GSoCProject.get(project_key) if not project: # no existing project found, log and return OK return error_handler.logErrorAndReturnOK( 'Invalid project specified %s:' % project_key) survey = survey_model.get_by_key_name(survey_key) if not survey: # no existing survey found, log and return OK return error_handler.logErrorAndReturnOK( 'Invalid survey specified %s:' % survey_key) # try to retrieve an existing record q = record_model.all() q.filter('project', project) q.filter('survey', survey) record = q.get() if not record: # send reminder email because we found no record student_profile = project.parent() site_entity = site.singleton() if survey_type == 'project': url_name = 'gsoc_take_student_evaluation' to_name = student_profile.name() to_address = student_profile.email mail_template = 'v2/modules/gsoc/reminder/student_eval_reminder.html' elif survey_type == 'grading': url_name = 'gsoc_take_mentor_evaluation' mentors = db.get(project.mentors) to_address = [m.email for m in mentors] to_name = 'mentor(s) for project "%s"' %(project.title) mail_template = \ 'v2/modules/gsoc/reminder/mentor_eval_reminder.html' program = project.program hostname = system.getHostname() url_kwargs = { 'sponsor': program.scope.link_id, 'program': program.link_id, 'survey': survey.link_id, 'user': student_profile.link_id, 'id': str(project.key().id()), } url = reverse(url_name, kwargs=url_kwargs) survey_url = '%s://%s%s' % ('http', hostname, url) # set the context for the mail template mail_context = { 'student_name': student_profile.name(), 'project_title': project.title, 'survey_url': survey_url, 'survey_end': survey.survey_end, 'to_name': to_name, 'site_name': site_entity.site_name, 'sender_name': "The %s Team" % site_entity.site_name, } # set the sender (_, sender_address) = mail_dispatcher.getDefaultMailSender() mail_context['sender'] = sender_address # set the receiver and subject mail_context['to'] = to_address mail_context['subject'] = \ 'Evaluation Survey "%s" Reminder' %(survey.title) # find all org admins for the project's organization org = project.org q = GSoCProfile.all() q.filter('status', 'active') q.filter('org_admin_for', org) org_admins = q.fetch(1000) # collect email addresses for all found org admins org_admin_addresses = [] for org_admin in org_admins: org_admin_addresses.append(org_admin.email) if org_admin_addresses: mail_context['cc'] = org_admin_addresses # send out the email mail_dispatcher.sendMailFromTemplate(mail_template, mail_context) # return OK return http.HttpResponse()
def sendSurveyReminderForProject(request, *args, **kwargs): """Sends a reminder mail for a given StudentProject and Survey. A reminder is only send if no record is on file for the given Survey and StudentProject. Expects the following to be present in the POST dict: survey_key: specifies the key name for the ProjectSurvey to send reminders for survey_type: either project or grading depending on the type of Survey project_key: key which specifies the project to send a reminder for Args: request: Django Request object """ from soc.logic import mail_dispatcher from soc.logic.models.site import logic as site_logic from soc.views.helper import redirects from soc.modules.gsoc.logic.models.org_admin import logic as org_admin_logic from soc.modules.gsoc.logic.models.student_project import logic as \ student_project_logic from soc.modules.gsoc.logic.models.survey import grading_logic from soc.modules.gsoc.logic.models.survey import project_logic post_dict = request.POST project_key = post_dict.get('project_key') survey_key = post_dict.get('survey_key') survey_type = post_dict.get('survey_type') if not (project_key and survey_key and survey_type): # invalid task data, log and return OK return error_handler.logErrorAndReturnOK( 'Invalid sendSurveyReminderForProject data: %s' % post_dict) # set logic depending on survey type specified in POST if survey_type == 'project': survey_logic = project_logic elif survey_type == 'grading': survey_logic = grading_logic # retrieve the project and survey student_project = student_project_logic.getFromKeyName(project_key) if not student_project: # no existing project found, log and return OK return error_handler.logErrorAndReturnOK( 'Invalid project specified %s:' % project_key) survey = survey_logic.getFromKeyName(survey_key) if not survey: # no existing survey found, log and return OK return error_handler.logErrorAndReturnOK( 'Invalid survey specified %s:' % survey_key) # try to retrieve an existing record record_logic = survey_logic.getRecordLogic() fields = {'project': student_project, 'survey': survey} record_entity = record_logic.getForFields(fields, unique=True) if not record_entity: # send reminder email because we found no record student_entity = student_project.student site_entity = site_logic.getSingleton() if survey_type == 'project': survey_redirect = redirects.getTakeSurveyRedirect( survey, {'url_name': 'gsoc/project_survey'}) to_role = student_entity mail_template = 'soc/project_survey/mail/reminder_gsoc.html' elif survey_type == 'grading': survey_redirect = redirects.getTakeSurveyRedirect( survey, {'url_name': 'gsoc/grading_project_survey'}) to_role = student_project.mentor mail_template = 'soc/grading_project_survey/mail/reminder_gsoc.html' survey_url = "http://%(host)s%(redirect)s" % { 'redirect': survey_redirect, 'host': system.getHostname(), } # set the context for the mail template mail_context = { 'student_name': student_entity.name(), 'project_title': student_project.title, 'survey_url': survey_url, 'survey_end': survey.survey_end, 'to_name': to_role.name(), 'site_name': site_entity.site_name, } # set the sender (_, sender_address) = mail_dispatcher.getDefaultMailSender() mail_context['sender'] = sender_address # set the receiver and subject mail_context['to'] = to_role.email mail_context['subject'] = 'Evaluation Survey "%s" Reminder' % ( survey.title) # find all org admins for the project's organization org_entity = student_project.scope fields = {'scope': org_entity, 'status': 'active'} org_admin_entities = org_admin_logic.getForFields(fields) # collect email addresses for all found org admins org_admin_addresses = [] for org_admin_entity in org_admin_entities: org_admin_addresses.append(org_admin_entity.email) if org_admin_addresses: mail_context['cc'] = org_admin_addresses # send out the email mail_dispatcher.sendMailFromTemplate(mail_template, mail_context) # return OK return http.HttpResponse()
def sendCommentNotificationMail(self, request, *args, **kwargs): """Appengine task that sends mail to the subscribed users. Expects the following to be present in the POST dict: comment_key: Specifies the comment id for which to send the notifications Args: request: Django Request object """ # TODO(ljvderijk): If all mails are equal we can sent one big bcc mail # set default batch size batch_size = 10 post_dict = request.POST comment_key = post_dict.get("comment_key") if not comment_key: # invalid task data, log and return OK return error_handler.logErrorAndReturnOK("Invalid createNotificationMail data: %s" % post_dict) comment_key = db.Key(comment_key) comment = GCIComment.get(comment_key) if not comment: # invalid comment specified, log and return OK return error_handler.logErrorAndReturnOK("Invalid comment specified: %s" % (comment_key)) task = comment.parent() subscription = GCITaskSubscription.all().ancestor(task).fetch(1) # check and retrieve the subscriber_start_key that has been done last idx = int(post_dict.get("subscriber_start_index", 0)) subscribers = db.get(subscription.subscribers[idx : idx + batch_size]) url_kwargs = { "sponsor": task.program.scope_path, "program": task.program.link_id, "id": task.key().id_or_name(), } task_url = "http://%(host)s%(task)s" % { "host": system.getHostname(), "task": reverse("gci_view_task", kwargs=url_kwargs), } # create the data for the mail to be sent message_properties = { "task_url": task_url, "redirect_url": "%(task_url)s#c%(cid)d" % {"task_url": task_url, "cid": comment.key().id_or_name()}, "comment_entity": comment, "task_entity": task, } subject = self.DEF_TASK_UPDATE_SUBJECT % {"program_name": task.program.short_name, "title": task.title} for subscriber in subscribers: # TODO(ljvderijk): enable sending of mail after template fixes # gci_notifications.sendTaskUpdateMail(subscriber, subject, # message_properties) pass if len(subscribers) == batch_size: # spawn task for sending out notifications to next set of subscribers next_start = idx + batch_size task_params = {"comment_key": str(comment_key), "subscriber_start_index": next_start} task_url = "/tasks/gci/task/mail/comment" new_task = taskqueue.Task(params=task_params, url=task_url) new_task.add("mail") # return OK return http.HttpResponse()
def createNotificationMail(request, *args, **kwargs): """Appengine task that sends mail to the subscribed users. Expects the following to be present in the POST dict: comment_key: Specifies the comment id for which to send the notifications task_key: Specifies the task key name for which the comment belongs to Args: request: Django Request object """ from soc.modules.gci.logic.helper import notifications as gci_notifications from soc.modules.gci.logic.models import comment as gci_comment_logic from soc.modules.gci.logic.models import task_subscription as \ gci_task_subscription_logic # set default batch size batch_size = 10 post_dict = request.POST comment_key = post_dict.get('comment_key') task_key = post_dict.get('task_key') if not (comment_key and task_key): # invalid task data, log and return OK return error_handler.logErrorAndReturnOK( 'Invalid createNotificationMail data: %s' % post_dict) comment_key = long(comment_key) # get the task entity under which the specified comment was made task_entity = gci_task_logic.logic.getFromKeyName(task_key) # get the comment for the given id comment_entity = gci_comment_logic.logic.getFromID(comment_key, task_entity) if not comment_entity: # invalid comment specified, log and return OK return error_handler.logErrorAndReturnOK( 'Invalid comment specified: %s/%s' % (comment_key, task_key)) # check and retrieve the subscriber_start_key that has been done last idx = post_dict.get('subscriber_start_index', '') subscriber_start_index = int(idx) if idx.isdigit() else 0 # get all subscribers to GCI task fields = { 'task': task_entity, } ts_entity = gci_task_subscription_logic.logic.getForFields(fields, unique=True) subscribers = db.get( ts_entity.subscribers[subscriber_start_index:subscriber_start_index + batch_size]) task_url = "http://%(host)s%(task)s" % { 'host': system.getHostname(), 'task': redirects.getPublicRedirect(task_entity, {'url_name': 'gci/task'}), } # create the data for the mail to be sent message_properties = { 'task_url': task_url, 'redirect_url': "%(task_url)s#c%(cid)d" % { 'task_url': task_url, 'cid': comment_entity.key().id_or_name() }, 'comment_entity': comment_entity, 'task_entity': task_entity, } subject = DEF_TASK_UPDATE_SUBJECT_FMT % { 'program_name': task_entity.program.short_name, 'title': task_entity.title, } for subscriber in subscribers: gci_notifications.sendTaskUpdateMail(subscriber, subject, message_properties) if len(subscribers) == batch_size: # spawn task for sending out notifications to next set of subscribers next_start = subscriber_start_index + batch_size task_params = { 'comment_key': comment_key, 'task_key': task_key, 'subscriber_start_index': next_start } task_url = '/tasks/gci/task/mail/create' new_task = taskqueue.Task(params=task_params, url=task_url) new_task.add('mail') # return OK return http.HttpResponse()
def createNotificationMail(request, *args, **kwargs): """Appengine task that sends mail to the subscribed users. Expects the following to be present in the POST dict: comment_key: Specifies the comment id for which to send the notifications task_key: Specifies the task key name for which the comment belongs to Args: request: Django Request object """ from soc.modules.gci.logic.helper import notifications as gci_notifications from soc.modules.gci.logic.models import comment as gci_comment_logic from soc.modules.gci.logic.models import task_subscription as \ gci_task_subscription_logic # set default batch size batch_size = 10 post_dict = request.POST comment_key = post_dict.get('comment_key') task_key = post_dict.get('task_key') if not (comment_key and task_key): # invalid task data, log and return OK return error_handler.logErrorAndReturnOK( 'Invalid createNotificationMail data: %s' % post_dict) comment_key = long(comment_key) # get the task entity under which the specified comment was made task_entity = gci_task_logic.logic.getFromKeyName(task_key) # get the comment for the given id comment_entity = gci_comment_logic.logic.getFromID( comment_key, task_entity) if not comment_entity: # invalid comment specified, log and return OK return error_handler.logErrorAndReturnOK( 'Invalid comment specified: %s/%s' % (comment_key, task_key)) # check and retrieve the subscriber_start_key that has been done last idx = post_dict.get('subscriber_start_index', '') subscriber_start_index = int(idx) if idx.isdigit() else 0 # get all subscribers to GCI task fields = { 'task': task_entity, } ts_entity = gci_task_subscription_logic.logic.getForFields( fields, unique=True) subscribers = db.get(ts_entity.subscribers[ subscriber_start_index:subscriber_start_index+batch_size]) task_url = "http://%(host)s%(task)s" % { 'host': system.getHostname(), 'task': redirects.getPublicRedirect( task_entity, {'url_name': 'gci/task'}), } # create the data for the mail to be sent message_properties = { 'task_url': task_url, 'redirect_url': "%(task_url)s#c%(cid)d" % { 'task_url': task_url, 'cid': comment_entity.key().id_or_name() }, 'comment_entity': comment_entity, 'task_entity': task_entity, } subject = DEF_TASK_UPDATE_SUBJECT_FMT % { 'program_name': task_entity.program.short_name, 'title': task_entity.title, } for subscriber in subscribers: gci_notifications.sendTaskUpdateMail(subscriber, subject, message_properties) if len(subscribers) == batch_size: # spawn task for sending out notifications to next set of subscribers next_start = subscriber_start_index + batch_size task_params = { 'comment_key': comment_key, 'task_key': task_key, 'subscriber_start_index': next_start } task_url = '/tasks/gci/task/mail/create' new_task = taskqueue.Task(params=task_params, url=task_url) new_task.add('mail') # return OK return http.HttpResponse()