def testGetHostName(self): """Tests that a correct host name is returned.""" test_data = request_data.RequestData(None, None, None) test_data._site = site_model.Site(link_id='test', hostname='test_host') try: expected_host = os.environ['HTTP_HOST'] = 'some.testing.host.tld' self.assertEqual(site.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(site.getHostname(data=test_data), expected_host) test_data.site.hostname = '' try: expected_host = os.environ['HTTP_HOST'] = 'some.testing.host.tld' self.assertEqual(site.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 testGetHostName(self): """Tests that a correct host name is returned.""" test_data = request_data.RequestData(None, None, None) test_data._site = site_model.Site(link_id="test", hostname="test_host") try: expected_host = os.environ["HTTP_HOST"] = "some.testing.host.tld" self.assertEqual(site.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(site.getHostname(data=test_data), expected_host) test_data.site.hostname = "" try: expected_host = os.environ["HTTP_HOST"] = "some.testing.host.tld" self.assertEqual(site.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 getTaskConversationMessageContext(message, to_emails, is_reply): """Sends out notifications to the conversation's participants. Args: message: Key (ndb) of GCIMessage to send. to_emails: List of recipients for the notification. is_reply: Whether this message is a reply to an existing conversation. Returns: Context dictionary for a mailer task. """ message_ent = message.get() conversation_ent = message_ent.conversation.get() program_ent = db.get(ndb.Key.to_old_key(conversation_ent.program)) author_ent = message_ent.author.get() url_kwargs = { 'sponsor': program_logic.getSponsorKey(program_ent).name(), 'program': program_ent.link_id, 'id': conversation_ent.key.integer_id(), } conversation_url = 'http://%(host)s%(conversation)s' % { 'host': site.getHostname(), 'conversation': reverse(url_names.GCI_CONVERSATION, kwargs=url_kwargs) } message_url = 'http://%(host)s%(conversation)s#m%(message_id)s' % { 'host': site.getHostname(), 'conversation': reverse(url_names.GCI_CONVERSATION, kwargs=url_kwargs), 'message_id': message.integer_id() } message_by = author_ent.user_id if author_ent else 'Melange' message_properties = { 'author_name': message_by, 'conversation_subject': conversation_ent.subject, 'message_content': message_ent.content, 'sender_name': 'The %s Team' % site.singleton().site_name, 'conversation_url': conversation_url, 'message_url': message_url, 'program_name': program_ent.name, 'is_reply': is_reply, } subject = ((DEF_NEW_MESSAGE_SUBJECT if is_reply else DEF_NEW_CONVERSATION_SUBJECT) % message_properties) template = (DEF_NEW_MESSAGE_NOTIFICATION_TEMPLATE if is_reply else DEF_NEW_CONVERSATION_NOTIFICATION_TEMPLATE) body = loader.render_to_string(template, dictionary=message_properties) return mailer.getMailContext(to=[], subject=subject, html=body, bcc=to_emails)
def getTaskConversationMessageContext(message, to_emails, is_reply): """Sends out notifications to the conversation's participants. Args: message: Key (ndb) of GCIMessage to send. to_emails: List of recipients for the notification. is_reply: Whether this message is a reply to an existing conversation. Returns: Context dictionary for a mailer task. """ message_ent = message.get() conversation_ent = message_ent.conversation.get() program_ent = db.get(ndb.Key.to_old_key(conversation_ent.program)) author_ent = message_ent.author.get() url_kwargs = { 'sponsor': program_logic.getSponsorKey(program_ent).name(), 'program': program_ent.link_id, 'id': conversation_ent.key.integer_id(), } conversation_url = 'http://%(host)s%(conversation)s' % { 'host': site.getHostname(), 'conversation': reverse(url_names.GCI_CONVERSATION, kwargs=url_kwargs)} message_url = 'http://%(host)s%(conversation)s#m%(message_id)s' % { 'host': site.getHostname(), 'conversation': reverse(url_names.GCI_CONVERSATION, kwargs=url_kwargs), 'message_id': message.integer_id()} message_by = author_ent.user_id if author_ent else 'Melange' message_properties = { 'author_name': message_by, 'conversation_subject': conversation_ent.subject, 'message_content': message_ent.content, 'sender_name': 'The %s Team' % site.singleton().site_name, 'conversation_url': conversation_url, 'message_url': message_url, 'program_name': program_ent.name, 'is_reply': is_reply, } subject = (( DEF_NEW_MESSAGE_SUBJECT if is_reply else DEF_NEW_CONVERSATION_SUBJECT) % message_properties) template = ( DEF_NEW_MESSAGE_NOTIFICATION_TEMPLATE if is_reply else DEF_NEW_CONVERSATION_NOTIFICATION_TEMPLATE) body = loader.render_to_string(template, dictionary=message_properties) return mailer.getMailContext(to=[], subject=subject, html=body, bcc=to_emails)
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 """ to = student.contact.email subject = DEF_FIRST_TASK_CONFIRMATION_SUBJECT program_key = student.program kwargs = { 'sponsor': profile_model.getSponsorId(student.key), 'program': profile_model.getProgramId(student.key) } url = reverse('gci_student_form_upload', kwargs=kwargs) protocol = 'http' hostname = site.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 _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 # TODO(nathaniel): consider using scheme-relative urls here? protocol = 'https' if secure else 'http' hostname = site_logic.getHostname(self._data) return '%s://%s%s' % (protocol, hostname, url)
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': program_logic.getSponsorKey(task.program).name(), 'program': task.program.link_id, 'id': task.key().id(), } task_url = 'http://%(host)s%(task)s' % { 'host': site.getHostname(), 'task': reverse('gci_view_task', kwargs=url_kwargs) } author_key = ( comment_model.GCIComment.created_by.get_value_for_datastore(comment)) author = ndb.Key.from_old_key(author_key).get() if author_key else None commented_by = author.user_id if author 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 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': program_logic.getSponsorKey(task.program).name(), 'program': task.program.link_id, 'id': task.key().id(), } task_url = 'http://%(host)s%(task)s' % { 'host': site.getHostname(), 'task': reverse('gci_view_task', kwargs=url_kwargs)} author_key = ( comment_model.GCIComment.created_by .get_value_for_datastore(comment)) author = ndb.Key.from_old_key(author_key).get() if author_key else None commented_by = author.user_id if author 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)
url_name: The name with which a URL was registered with Django. secure: Whether the returned URL should support HTTPS or not. Returns: The URL of the page matching the given name for the given org key. """ relative_url = self._linker.organization(org_key, url_name) return getAbsoluteUrl(relative_url, self._hostname, secure=secure) def userId(self, profile_key, entity_id, url_name, secure=False): """Returns the absolute URL of a page whose address contains parts associated with the specified profile and numeric identifier of some other entity. Args: profile: Profile key. entity_id: Numeric ID of entity. url_name: The name with which a URL was registered with Django. secure: Whether the returned URL should support HTTPS or not. Returns: The URL of the page matching the given names for the given profile and organization. """ relative_url = self._linker.userId(profile_key, entity_id, url_name) return getAbsoluteUrl(relative_url, self._hostname, secure=secure) # TODO(daniel): hostname should not be obtained via interaction with database # at module loading time. ABSOLUTE_LINKER = AbsoluteLinker(LINKER, site_logic.getHostname())
def sendSurveyReminderForProject(self, request, *args, **kwargs): """Sends a reminder mail for a given GSoCProject and Survey. A reminder is only send if no record is on file for the given Survey and GSoCProject. 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 = ndb.Key.from_old_key(project.parent_key()).get() site_entity = site.singleton() if survey_type == 'project': url_name = 'gsoc_take_student_evaluation' to_name = student.public_name to_address = student.contact.email mail_template = 'modules/gsoc/reminder/student_eval_reminder.html' elif survey_type == 'grading': url_name = 'gsoc_take_mentor_evaluation' mentors = ndb.get_multi(map(ndb.Key.from_old_key, project.mentors)) to_address = [mentor.contact.email for mentor in mentors] to_name = 'mentor(s) for project "%s"' % (project.title) mail_template = ( 'modules/gsoc/reminder/mentor_eval_reminder.html') program = project.program hostname = site.getHostname() url_kwargs = { 'sponsor': program_logic.getSponsorKey(program).name(), 'program': program.link_id, 'survey': survey.link_id, 'user': student.profile_id, 'id': str(project.key().id()), } url_path_and_query = reverse(url_name, kwargs=url_kwargs) survey_url = '%s://%s%s' % ('http', hostname, url_path_and_query) # set the context for the mail template mail_context = { 'student_name': student.public_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 "%s" Reminder' % survey.title) # find all org admins for the project's organization org_key = ndb.Key.from_old_key( GSoCProject.org.get_value_for_datastore(project)) org_admins = profile_logic.getOrgAdmins(org_key) # collect email addresses for all found org admins org_admin_addresses = [] for org_admin in org_admins: org_admin_addresses.append(org_admin.contact.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(self, request, *args, **kwargs): """Sends a reminder mail for a given GSoCProject and Survey. A reminder is only send if no record is on file for the given Survey and GSoCProject. 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 = ndb.Key.from_old_key(project.parent_key()).get() site_entity = site.singleton() if survey_type == 'project': url_name = 'gsoc_take_student_evaluation' to_name = student.public_name to_address = student.contact.email mail_template = 'modules/gsoc/reminder/student_eval_reminder.html' elif survey_type == 'grading': url_name = 'gsoc_take_mentor_evaluation' mentors = ndb.get_multi( map(ndb.Key.from_old_key, project.mentors)) to_address = [mentor.contact.email for mentor in mentors] to_name = 'mentor(s) for project "%s"' % (project.title) mail_template = ( 'modules/gsoc/reminder/mentor_eval_reminder.html') program = project.program hostname = site.getHostname() url_kwargs = { 'sponsor': program_logic.getSponsorKey(program).name(), 'program': program.link_id, 'survey': survey.link_id, 'user': student.profile_id, 'id': str(project.key().id()), } url_path_and_query = reverse(url_name, kwargs=url_kwargs) survey_url = '%s://%s%s' % ('http', hostname, url_path_and_query) # set the context for the mail template mail_context = { 'student_name': student.public_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 "%s" Reminder' % survey.title) # find all org admins for the project's organization org_key = ndb.Key.from_old_key( GSoCProject.org.get_value_for_datastore(project)) org_admins = profile_logic.getOrgAdmins(org_key) # collect email addresses for all found org admins org_admin_addresses = [] for org_admin in org_admins: org_admin_addresses.append(org_admin.contact.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()
secure: Whether the returned URL should support HTTPS or not. Returns: The URL of the page matching the given name for the given org key. """ relative_url = self._linker.organization(org_key, url_name) return getAbsoluteUrl(relative_url, self._hostname, secure=secure) def userId(self, profile_key, entity_id, url_name, secure=False): """Returns the absolute URL of a page whose address contains parts associated with the specified profile and numeric identifier of some other entity. Args: profile: Profile key. entity_id: Numeric ID of entity. url_name: The name with which a URL was registered with Django. secure: Whether the returned URL should support HTTPS or not. Returns: The URL of the page matching the given names for the given profile and organization. """ relative_url = self._linker.userId(profile_key, entity_id, url_name) return getAbsoluteUrl(relative_url, self._hostname, secure=secure) # TODO(daniel): hostname should not be obtained via interaction with database # at module loading time. ABSOLUTE_LINKER = AbsoluteLinker(LINKER, site_logic.getHostname())