コード例 #1
0
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)
コード例 #2
0
ファイル: program.py プロジェクト: rhyolight/nupic.son
    def getSendMailFromTemplateStringTxn(self, to, subject, template_string,
                                         context):
        """Returns the transaction for sending the email

    Args:
      to: Email address to which the test messages must be sent.
      subject: Subject for the mail.
      template_string: Template string to be used to construct mail body.
      context: Context variables to render the mail body from template string.

    Returns:
      A function object for sending email in the background using task queue.
    """
        sender_name, sender = mail_dispatcher.getDefaultMailSender()

        common_context = {
            'to': to,
            'sender': sender,
            'sender_name': sender_name,
            'program_name': self.request_data.program.name,
            'subject': subject,
        }
        context.update(common_context)
        return mail_dispatcher.getSendMailFromTemplateStringTxn(
            template_string,
            context,
            parent=self.request_data.ndb_user,
            transactional=True)
コード例 #3
0
def sendApplicationProcessedNotification(entity, status, module_name,
                                         mail_templates):
  """Sends out email about the processed Organization Application. If the 
  application is accepted a Notification is also generated.

  Args:
    entity: OrgAppRecord entity
    status: the new status of the OrgAppRecord entity
    module_name: The name of the module the Organization entity is in
    mail_templates: dictionary containing accepted and rejected keys mapping
        to the location of the mail template to be used iff status is equal to
        that key
  """

  from soc.logic import accounts
  from soc.logic import mail_dispatcher
  from soc.logic.helper import notifications

  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 = entity.main_admin
  backup_entity = entity.backup_admin

  context = {
      'sender': sender,
      'sender_name': sender_name,
      'program_name': entity.survey.scope.name,
      'org_app_name': entity.name
      }

  if status == 'accepted':
    # use the accepted template and subject
    template = mail_templates['accepted']
    context['subject'] = 'Congratulations!'
  elif status == 'rejected':
    # use the rejected template and subject
    template = mail_templates['rejected']
    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)

  # send out the notifications about what to do next to the accepted ones
  if status == 'accepted':
    notifications.sendNewOrganizationNotification(entity, module_name)
コード例 #4
0
def sendRequestTaskNotification(org_admins, message):
  """Sends notifications to org admins that there is a student who requested
  more tasks from them.

  Args:
    org_admins: a list of org admins who the notification should be sent to
    message: a short message that will be included to the notification
  """

  from soc.logic.models.site import logic as site_logic

  # get the default mail sender
  default_sender = mail_dispatcher.getDefaultMailSender()

  if not default_sender:
    # no valid sender found, abort
    return
  else:
    (sender_name, sender) = default_sender

  # get site name
  site_entity = site_logic.getSingleton()
  template = DEF_TASK_REQUEST_TEMPLATE

  properties = {
      'message': message,
      'sender_name': sender_name,
      }

  for org_admin in org_admins:
    to = org_admin.user
    properties['to'] = to
    properties['to_name'] = to.name

    notifications.sendNotification(to, None, properties, subject, template)
コード例 #5
0
def dispatchOrgMemberWelcomeEmail(
    profile, program, program_messages, site, parent=None):
  """Dispatches a task to send organization member welcome email for
  the program to the specified profile.

  Args:
    profile: profile_model.Profile entity to which the email should be sent.
    program: program_model.Program entity.
    program_messages: program_model.ProgramMessages entity.
    site: site_model.Site entity.
    parent: Optional entity to use as the parent of the entity which is
      created during the process. If not specified, the specified profile
      entity is used.
  """
  if program_messages.mentor_welcome_msg:
    sender_name, sender = mail_dispatcher.getDefaultMailSender(site=site)

    parent = parent or profile

    context = {
        'to': profile.contact.email,
        'sender': sender,
        'sender_name': sender_name,
        'subject': _DEF_ORG_MEMBER_WELCOME_MAIL_SUBJECT,
        'program_name': program.name,
        'to_name': profile.public_name,
    }
    mail_dispatcher.getSendMailFromTemplateStringTxn(
        program_messages.mentor_welcome_msg, context, parent=parent)()
コード例 #6
0
def sendFeedItemEmailNotifications(entity, acting_user, update_type, 
  payload,  context = {}, **kwargs):
  """
   Sends e-mail notification to user about new feed item. 
   Private payload info can be included in this message
   (while it is not included in the Atom feed)
  
  Params:
         entity - entity being updated
         acting_user - use who performed feed action (or None)
         update_type - type of update (created, updated, deleted)
         payload - extra information for message
         context - template dict
         
  """  


  if acting_user: 
    sender_name = acting_user.name
    sender = acting_user
  else:
    sender_name, sender  = mail_dispatcher.getDefaultMailSender()
  if getattr(entity, 'title', None):
    entity_title = entity.title
  else: 
    entity_title  = entity.key().name()
  
  subject = "%s - %s (%s) has been %s" % (
  os.environ['APPLICATION_ID'].capitalize(),
  entity_title, entity.kind(), update_type)
  
    
  # this should be a user query function and there should be
  # an access check for the receiver and then a check against a 
  # no_subscribe ListProperty for user for both sender and recevier.
  to_users = subscriptions_logic.getSubscribedUsersForFeedItem(entity)
  logging.info(to_users)
  # get site name
  site_entity = model_logic.site.logic.getSingleton()
  site_name = site_entity.site_name
   
  for to_user in to_users:
    messageProperties = {
        # message configuration
        'to_name': to_user.name,
        'to': accounts.denormalizeAccount(to_user.account).email(),  
        'sender_name': sender_name,
        'sender': accounts.denormalizeAccount(sender.account).email(),
        # feed item info
        'acting_user': acting_user,
        'entity': entity,
        'payload': payload,
        'subject': subject,
        'url': news_feed.linkToEntity(entity),
        'site_location': 'http://%s' % os.environ['HTTP_HOST']
        }
    logging.info(messageProperties)
    # send out the message using the news_feed template
    mail_dispatcher.sendMailFromTemplate(
    'soc/mail/news_feed_notification.html', messageProperties)
コード例 #7
0
ファイル: notifications.py プロジェクト: rhyolight/nupic.son
def getDefaultContext(request_data, emails, subject, extra_context=None):
  """Generate a dictionary with a default context.

  Returns:
    A dictionary with the default context for the emails that are sent
    in this module.
  """
  default_context = {}
  default_context['sender_name'] = 'The %s Team' % (
      request_data.site.site_name)
  default_context['program_name'] = request_data.program.name
  default_context['subject'] = subject

  sender_name, sender = mail_dispatcher.getDefaultMailSender(
      site=request_data.site)
  default_context['sender_name'] = sender_name
  default_context['sender'] = sender

  if len(emails) == 1:
    default_context['to'] = emails[0]
  else:
    default_context['bcc'] = emails

  if extra_context:
    default_context.update(extra_context)

  return default_context
コード例 #8
0
def getDefaultContext(request_data, emails, subject, extra_context=None):
    """Generate a dictionary with a default context.

  Returns:
    A dictionary with the default context for the emails that are sent
    in this module.
  """
    default_context = {}
    default_context['sender_name'] = 'The %s Team' % (
        request_data.site.site_name)
    default_context['program_name'] = request_data.program.name
    default_context['subject'] = subject

    sender_name, sender = mail_dispatcher.getDefaultMailSender(
        site=request_data.site)
    default_context['sender_name'] = sender_name
    default_context['sender'] = sender

    if len(emails) == 1:
        default_context['to'] = emails[0]
    else:
        default_context['bcc'] = emails

    if extra_context:
        default_context.update(extra_context)

    return default_context
コード例 #9
0
  def getRejectProposalMailTxn(self, proposal):
    """Returns the function to sent an rejectance mail for the specified
    proposal.
    """
    sender_name, sender = mail_dispatcher.getDefaultMailSender()

    student_entity = ndb.Key.from_old_key(proposal.parent_key()).get()

    org_key = GSoCProposal.org.get_value_for_datastore(proposal)
    org = ndb.Key.from_old_key(org_key).get()

    program_entity = proposal.program

    context = {
      'to': student_entity.contact.email,
      'to_name': student_entity.first_name,
      'sender': sender,
      'sender_name': sender_name,
      'proposal_title': proposal.title,
      'program_name': program_entity.name,
      'subject': 'Thank you for applying to %s' % (program_entity.name),
      'org_entity': org,
      }

    messages = program_entity.getProgramMessages()
    template_string = messages.rejected_students_msg

    return mail_dispatcher.getSendMailFromTemplateStringTxn(
        template_string, context, parent=student_entity)
コード例 #10
0
ファイル: program.py プロジェクト: rhyolight/nupic.son
  def getSendMailFromTemplateStringTxn(
        self, to, subject, template_string, context):
    """Returns the transaction for sending the email

    Args:
      to: Email address to which the test messages must be sent.
      subject: Subject for the mail.
      template_string: Template string to be used to construct mail body.
      context: Context variables to render the mail body from template string.

    Returns:
      A function object for sending email in the background using task queue.
    """
    sender_name, sender = mail_dispatcher.getDefaultMailSender()

    common_context = {
        'to': to,
        'sender': sender,
        'sender_name': sender_name,
        'program_name': self.request_data.program.name,
        'subject': subject,
        }
    context.update(common_context)
    return mail_dispatcher.getSendMailFromTemplateStringTxn(
          template_string, context, parent=self.request_data.ndb_user,
          transactional=True)
コード例 #11
0
ファイル: org_app_survey.py プロジェクト: SRabbelier/Melange
def sendApplicationProcessedNotification(entity, status, module_name, mail_templates):
    """Sends out email about the processed Organization Application. If the 
  application is accepted a Notification is also generated.

  Args:
    entity: OrgAppRecord entity
    status: the new status of the OrgAppRecord entity
    module_name: The name of the module the Organization entity is in
    mail_templates: dictionary containing accepted and rejected keys mapping
        to the location of the mail template to be used iff status is equal to
        that key
  """

    from soc.logic import accounts
    from soc.logic import mail_dispatcher
    from soc.logic.helper import notifications

    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 = entity.main_admin
    backup_entity = entity.backup_admin

    context = {
        "sender": sender,
        "sender_name": sender_name,
        "program_name": entity.survey.scope.name,
        "org_app_name": entity.name,
    }

    if status == "accepted":
        # use the accepted template and subject
        template = mail_templates["accepted"]
        context["subject"] = "Congratulations!"
    elif status == "rejected":
        # use the rejected template and subject
        template = mail_templates["rejected"]
        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)

    # send out the notifications about what to do next to the accepted ones
    if status == "accepted":
        notifications.sendNewOrganizationNotification(entity, module_name)
コード例 #12
0
ファイル: notifications.py プロジェクト: ajaksu/Melange
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
  """
  # pylint: disable-msg=W0612
  import soc.views.models.notification

  # create the url to show this notification
  notification_url = "http://%(host)s%(index)s" % {
      'host' : os.environ['HTTP_HOST'],
      'index': redirects.getPublicRedirect(notification_entity,
          model_view.notification.view.getParams())}

  sender = mail_dispatcher.getDefaultMailSender()
  site_entity = model_logic.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
    return
  else:
    (sender_name, sender) = default_sender

  to = accounts.denormalizeAccount(notification_entity.scope.account).email()

  # 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(DEF_NEW_NOTIFICATION_MSG),
      '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)
コード例 #13
0
ファイル: org_app.py プロジェクト: ajaksu/Melange
  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' % (os.environ['HTTP_HOST'])
      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)
コード例 #14
0
ファイル: org_app.py プロジェクト: praveen97uma/Melange
    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)
コード例 #15
0
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)
コード例 #16
0
def sendTaskUpdateMail(subscriber, subject, message_properties=None):
  """Sends an email to a user about an update to a Task.

    Args:
      subscriber: The user entity to whom the message must be sent
      subject: Subject of the mail
      message_properties: The mail message properties
      template: Optional django template that is used to build the message body
  """

  from soc.logic.models.site import logic as site_logic

  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
    return
  else:
    (sender_name, sender) = default_sender

  to = accounts.denormalizeAccount(subscriber.account).email()

  # create the message contents
  new_message_properties = {
      'to_name': subscriber.name,
      'sender_name': sender_name,
      'to': to,
      'sender': sender,
      'site_name': site_name,
      'subject': force_unicode(subject),
      }

  messageProperties = dicts.merge(message_properties, new_message_properties)

  template = 'modules/ghop/task/update_notification'

  # send out the message using the default new notification template
  mail_dispatcher.sendMailFromTemplate(template, messageProperties)
コード例 #17
0
def reject_proposal_email(proposal):
  """Send an reject mail for the specified proposal.
  """

  sender_name, sender = mail_dispatcher.getDefaultMailSender()

  student_entity = proposal.scope
  program_entity = proposal.program

  context = {
    'to': student_entity.email,
    'to_name': student_entity.given_name,
    'sender': sender,
    'sender_name': sender_name,
    'program_name': program_entity.name,
    'subject': 'Thank you for applying to %s' % (program_entity.name)
    }

  template = 'modules/gsoc/student_proposal/mail/rejected_gsoc2010.html'
  mail_dispatcher.sendMailFromTemplate(template, context)
コード例 #18
0
def reject_proposal_email(proposal):
    """Send an reject mail for the specified proposal.
  """

    sender_name, sender = mail_dispatcher.getDefaultMailSender()

    student_entity = proposal.scope
    program_entity = proposal.program

    context = {
        'to': student_entity.email,
        'to_name': student_entity.given_name,
        'sender': sender,
        'sender_name': sender_name,
        'program_name': program_entity.name,
        'subject': 'Thank you for applying to %s' % (program_entity.name)
    }

    template = 'modules/gsoc/student_proposal/mail/rejected_gsoc2010.html'
    mail_dispatcher.sendMailFromTemplate(template, context)
コード例 #19
0
def sendMail(to_user, subject, message_properties, template):
  """Sends an email with the specified properties and mail content

  Args:
    to_user: user entity to whom the mail should be sent
    subject: subject of the mail
    message_properties: contains those properties that need to be
                        customized
    template: template that holds the content of the mail
  """

  from soc.logic.models.site import logic as site_logic

  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
    return
  else:
    (sender_name, sender) = default_sender

  to = accounts.denormalizeAccount(to_user.account).email()

  # create the message contents
  new_message_properties = {
      'to_name': to_user.name,
      'sender_name': sender_name,
      'to': to,
      'sender': sender,
      'site_name': site_name,
      'subject': force_unicode(subject)
      }

  messageProperties = dicts.merge(message_properties, new_message_properties)

  # send out the message using the default new notification template
  mail_dispatcher.sendMailFromTemplate(template, messageProperties)
コード例 #20
0
def accept_proposal_email(proposal):
    """Send an acceptance mail for the specified proposal.
  """

    sender_name, sender = mail_dispatcher.getDefaultMailSender()

    student_entity = proposal.scope
    program_entity = proposal.program

    context = {
        'to': student_entity.email,
        'to_name': student_entity.given_name,
        'sender': sender,
        'sender_name': sender_name,
        'program_name': program_entity.name,
        'subject': 'Congratulations!',
        'proposal_title': proposal.title,
        'org_name': proposal.org.name
    }

    template = 'modules/gsoc/student_proposal/mail/accepted_gsoc2010.html'
    mail_dispatcher.sendMailFromTemplate(template, context)
コード例 #21
0
def accept_proposal_email(proposal):
  """Send an acceptance mail for the specified proposal.
  """

  sender_name, sender = mail_dispatcher.getDefaultMailSender()

  student_entity = proposal.scope
  program_entity = proposal.program

  context = {
    'to': student_entity.email,
    'to_name': student_entity.given_name,
    'sender': sender,
    'sender_name': sender_name,
    'program_name': program_entity.name,
    'subject': 'Congratulations!',
    'proposal_title': proposal.title,
    'org_name': proposal.org.name
    }

  template = 'modules/gsoc/student_proposal/mail/accepted_gsoc2010.html'
  mail_dispatcher.sendMailFromTemplate(template, context)
コード例 #22
0
  def getWelcomeMailTxn(self, proposal, transactional=True):
    """Returns the function to sent an welcome email for an accepted proposal.
    """
    sender_name, sender = mail_dispatcher.getDefaultMailSender()

    student_entity = ndb.Key.from_old_key(proposal.parent_key()).get()
    program_entity = proposal.program

    context = {
      'to': student_entity.contact.email,
      'to_name': student_entity.first_name,
      'sender': sender,
      'sender_name': sender_name,
      'program_name': program_entity.name,
      'subject': 'Welcome to %s' % program_entity.name,
      }

    messages = program_entity.getProgramMessages()
    template_string = messages.accepted_students_welcome_msg

    return mail_dispatcher.getSendMailFromTemplateStringTxn(
        template_string, context, parent=student_entity,
        transactional=transactional)
コード例 #23
0
ファイル: surveys.py プロジェクト: pombredanne/Melange-1
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()
コード例 #24
0
    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()
コード例 #25
0
  def sendMailAboutGradingRecordResult(self, request, *args, **kwargs):
    """Sends out a mail about the result of one GradingRecord.

    Expects the following to be present in the POST dict:
      record_key: Specifies the key for the record to process.

    Args:
      request: Django Request object
    """
    post_dict = request.POST

    record_key = post_dict.get('record_key')

    if not record_key:
      # no GradingRecord key specified, log and return OK
      error_handler.logErrorAndReturnOK(
          'No valid record_key specified in POST data: %s' % request.POST)

    record = GSoCGradingRecord.get(db.Key(record_key))

    if not record:
      # no valid GradingRecord key specified, log and return OK
      error_handler.logErrorAndReturnOK(
          'No valid GradingRecord key specified: %s' % record_key)

    survey_group_entity = record.grading_survey_group
    project_entity = record.parent()
    student_entity = project_entity.parent()
    org_entity = project_entity.org
    site_entity = site.singleton()

    mail_context = {
      'survey_group': survey_group_entity,
      'grading_record': record,
      'project': project_entity,
      'organization': org_entity,
      'site_name': site_entity.site_name,
      'to_name': student_entity.name()
    }

    # set the sender
    (_, sender_address) = mail_dispatcher.getDefaultMailSender()
    mail_context['sender'] = sender_address
  
    # set the receiver and subject
    mail_context['to'] = student_entity.email
    mail_context['cc'] = []
    mail_context['subject'] = '%s results processed for %s' %(
        survey_group_entity.name, project_entity.title)

    q = GSoCProfile.all()
    q.filter('org_admin_for', org_entity)
    org_admins = q.fetch(1000)

    # collect all mentors
    mentors = db.get(project_entity.mentors)

    # add them all to the cc list
    for org_member in org_admins + mentors:
      mail_context['cc'].append(org_member.email)

    # send out the email using a template
    mail_template = 'modules/gsoc/grading_record/mail/result.html'
    mail_dispatcher.sendMailFromTemplate(mail_template, mail_context)

    # return OK
    return http.HttpResponse()
コード例 #26
0
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.org_admin import logic as org_admin_logic
  from soc.logic.models.site import logic as site_logic
  from soc.logic.models.student_project import logic as student_project_logic
  from soc.logic.models.survey import grading_logic
  from soc.logic.models.survey import project_logic
  from soc.views.helper import redirects

  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': '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': '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': os.environ['HTTP_HOST'],
      }

    # 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, 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()
コード例 #27
0
  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()
コード例 #28
0
def sendStudentProposalMail(job_entity):
  """Job that will send out an email to a student that sent in a proposal
  that either got accepted or rejected.

  Args:
    job_entity: a Job entity with key_data set to [student_key]
  """

  from soc.cron.job import FatalJobError


  student_keyname = job_entity.key_data[0].name()
  student_entity = student_logic.getFromKeyName(student_keyname)

  if not student_entity:
    raise FatalJobError('The student with keyname %s does not exist!' % (
        student_keyname))

  # only students who have sent in a proposal will be mailed
  fields = {'scope': student_entity}
  proposal = proposal_logic.getForFields(fields, unique=True)

  if proposal:
    # a proposal has been found we must sent out an email
    default_sender = mail_dispatcher.getDefaultMailSender()

    if not default_sender:
      # no default sender abort
      raise FatalJobError('No valid sender address could be found, try '
                          'setting a no-reply address on the site settings '
                          'page')
    else:
      (sender_name, sender) = default_sender

    # construct the contents of the email
    student_entity = proposal.scope
    program_entity = proposal.program

    context = {
        'to': student_entity.email,
        'to_name': student_entity.given_name,
        'sender': sender,
        'sender_name': sender_name,
        'program_name': program_entity.name,
    }

    # check if the student has an accepted proposal
    fields['status'] = 'accepted'
    accepted_proposal = proposal_logic.getForFields(fields, unique=True)

    if accepted_proposal:
      org_entity = accepted_proposal.org
      # use the accepted template and subject
      template = DEF_ACCEPTED_MAIL_TEMPLATE
      context['subject'] = 'Congratulations!'
      context['proposal_title'] = accepted_proposal.title
      context['org_name'] = accepted_proposal.org.name
    else:
      # use the rejected template and subject
      template = DEF_REJECTED_MAIL_TEMPLATE
      context['subject'] = 'Thank you for applying to %s' % (
          program_entity.name)

    # send out the constructed email
    mail_dispatcher.sendMailFromTemplate(template, context)

  # we are done here
  return
コード例 #29
0
def sendStudentProposalMail(job_entity):
    """Job that will send out an email to a student that sent in a proposal
  that either got accepted or rejected.

  Args:
    job_entity: a Job entity with key_data set to [student_key]
  """

    from soc.cron.job import FatalJobError

    student_keyname = job_entity.key_data[0].name()
    student_entity = student_logic.getFromKeyName(student_keyname)

    if not student_entity:
        raise FatalJobError('The student with keyname %s does not exist!' %
                            (student_keyname))

    # only students who have sent in a proposal will be mailed
    fields = {'scope': student_entity}
    proposal = proposal_logic.getForFields(fields, unique=True)

    if proposal:
        # a proposal has been found we must sent out an email
        default_sender = mail_dispatcher.getDefaultMailSender()

        if not default_sender:
            # no default sender abort
            raise FatalJobError(
                'No valid sender address could be found, try '
                'setting a no-reply address on the site settings '
                'page')
        else:
            (sender_name, sender) = default_sender

        # construct the contents of the email
        # pylint: disable-msg=E1103
        student_entity = proposal.scope
        program_entity = proposal.program

        context = {
            'to': student_entity.email,
            'to_name': student_entity.given_name,
            'sender': sender,
            'sender_name': sender_name,
            'program_name': program_entity.name,
        }

        # check if the student has an accepted proposal
        fields['status'] = 'accepted'
        accepted_proposal = proposal_logic.getForFields(fields, unique=True)

        if accepted_proposal:
            # use the accepted template and subject
            template = DEF_ACCEPTED_MAIL_TEMPLATE
            context['subject'] = 'Congratulations!'
            context['proposal_title'] = accepted_proposal.title
            context['org_name'] = accepted_proposal.org.name
        else:
            # use the rejected template and subject
            template = DEF_REJECTED_MAIL_TEMPLATE
            context['subject'] = 'Thank you for applying to %s' % (
                program_entity.name)

        # send out the constructed email
        mail_dispatcher.sendMailFromTemplate(template, context)

    # we are done here
    return
コード例 #30
0
def sendMailAboutGradingRecordResult(request, *args, **kwargs):
  """Sends out a mail about the result of one GradingRecord.

  Expects the following to be present in the POST dict:
    record_key: Specifies the key for the record to process.

  Args:
    request: Django Request object
  """

  from soc.logic import mail_dispatcher
  from soc.logic.models.grading_record import logic as grading_record_logic
  from soc.logic.models.org_admin import logic as org_admin_logic
  from soc.logic.models.site import logic as site_logic

  post_dict = request.POST

  # check and retrieve the record_key that has been done last
  if 'record_key' in post_dict and post_dict['record_key'].isdigit():
    record_key = int(post_dict['record_key'])
  else:
    record_key = None

  if not record_key:
    # no GradingRecord key specified, log and return OK
    error_handler.logErrorAndReturnOK(
        'No valid record_key specified in POST data: %s' % request.POST)

  record_entity = grading_record_logic.getFromID(record_key)

  if not record_entity:
    # no valid GradingRecord key specified, log and return OK
    error_handler.logErrorAndReturnOK(
        'No valid GradingRecord key specified: %s' % record_key)

  survey_group_entity = record_entity.grading_survey_group
  project_entity = record_entity.project
  student_entity = project_entity.student
  mentor_entity = project_entity.mentor
  org_entity = project_entity.scope
  site_entity = site_logic.getSingleton()

  mail_context = {
    'survey_group': survey_group_entity,
    'grading_record': record_entity,
    'project': project_entity,
    'organization': org_entity,
    'site_name': site_entity.site_name,
    'to_name': student_entity.name()
  }

  # set the sender
  (sender, sender_address) = mail_dispatcher.getDefaultMailSender()
  mail_context['sender'] = sender_address

  # set the receiver and subject
  mail_context['to'] = student_entity.email
  mail_context['cc'] = [mentor_entity.email]
  mail_context['subject'] = '%s results processed for %s' %(
      survey_group_entity.name, project_entity.title)

  # find all org admins for the project's organization
  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'].extend(org_admin_addresses)

  # send out the email using a template
  mail_template = 'soc/grading_record/mail/result.html'
  mail_dispatcher.sendMailFromTemplate(mail_template, mail_context)

  # return OK
  return http.HttpResponse()
コード例 #31
0
def sendMailAboutGradingRecordResult(request, *args, **kwargs):
    """Sends out a mail about the result of one GradingRecord.

  Expects the following to be present in the POST dict:
    record_key: Specifies the key for the record to process.

  Args:
    request: Django Request object
  """

    from soc.logic import mail_dispatcher
    from soc.logic.models.grading_record import logic as grading_record_logic
    from soc.logic.models.org_admin import logic as org_admin_logic
    from soc.logic.models.site import logic as site_logic

    post_dict = request.POST

    # check and retrieve the record_key that has been done last
    if 'record_key' in post_dict and post_dict['record_key'].isdigit():
        record_key = int(post_dict['record_key'])
    else:
        record_key = None

    if not record_key:
        # no GradingRecord key specified, log and return OK
        error_handler.logErrorAndReturnOK(
            'No valid record_key specified in POST data: %s' % request.POST)

    record_entity = grading_record_logic.getFromID(record_key)

    if not record_entity:
        # no valid GradingRecord key specified, log and return OK
        error_handler.logErrorAndReturnOK(
            'No valid GradingRecord key specified: %s' % record_key)

    survey_group_entity = record_entity.grading_survey_group
    project_entity = record_entity.project
    student_entity = project_entity.student
    mentor_entity = project_entity.mentor
    org_entity = project_entity.scope
    site_entity = site_logic.getSingleton()

    mail_context = {
        'survey_group': survey_group_entity,
        'grading_record': record_entity,
        'project': project_entity,
        'organization': org_entity,
        'site_name': site_entity.site_name,
        'to_name': student_entity.name()
    }

    # set the sender
    (sender, sender_address) = mail_dispatcher.getDefaultMailSender()
    mail_context['sender'] = sender_address

    # set the receiver and subject
    mail_context['to'] = student_entity.email
    mail_context['cc'] = [mentor_entity.email]
    mail_context['subject'] = '%s results processed for %s' % (
        survey_group_entity.name, project_entity.title)

    # find all org admins for the project's organization
    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'].extend(org_admin_addresses)

    # send out the email using a template
    mail_template = 'soc/grading_record/mail/result.html'
    mail_dispatcher.sendMailFromTemplate(mail_template, mail_context)

    # return OK
    return http.HttpResponse()