Exemple #1
0
  def __call__(self, request, *args, **kwargs):
    """Custom call implementation that avoids looking up unneeded data."""
    try:
      data, _, _ = self.initializer.initialize(request, args, kwargs)

      self.checkMaintenanceMode(data)

      action = args[0] if args else ''

      if action == 'login':
        return data.redirect.toUrl(users.create_login_url('/'))
      elif action == 'logout':
        return data.redirect.toUrl(users.create_logout_url('/'))
      else:
        settings = site_logic.singleton()
        program = settings.active_program
        if program:
          program_url = self.linker.program(program, program.homepage_url_name)
          return http.HttpResponseRedirect(program_url)
        else:
          return data.redirect.to('edit_site_settings')
    except exception.UserError as user_error:
      return self.error_handler.handleUserError(user_error, data)
    except exception.ServerError as server_error:
      return self.error_handler.handleServerError(server_error, data)
Exemple #2
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 import site

  # 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.singleton()
  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)
Exemple #3
0
  def populate(self, redirect, request, args, kwargs):
    """Populates the fields in the RequestData object.

    Args:
      request: Django HTTPRequest object.
      args & kwargs: The args and kwargs django sends along.
    """
    self.redirect = redirect
    self.request = request
    self.args = args
    self.kwargs = kwargs
    self.GET = request.GET
    self.POST = request.POST
    self.path = request.path.encode('utf-8')
    self.full_path = request.get_full_path().encode('utf-8')
    # XSRF middleware already retrieved it for us
    if not hasattr(request, 'site'):
      request.site = site.singleton()
    self.site = request.site
    self.user = user.current()
    if users.is_current_user_admin():
      self.is_developer = True
    if self.user and self.user.is_developer:
      self.is_developer = True
    self.gae_user = users.get_current_user()
Exemple #4
0
    def __call__(self, request, *args, **kwargs):
        """Custom call implementation that avoids looking up unneeded data."""
        try:
            data, _, _ = self.initializer.initialize(request, args, kwargs)

            self.checkMaintenanceMode(data)

            action = args[0] if args else ''

            if action == 'login':
                return data.redirect.toUrl(users.create_login_url('/'))
            elif action == 'logout':
                return data.redirect.toUrl(users.create_logout_url('/'))
            else:
                settings = site_logic.singleton()
                program = settings.active_program
                if program:
                    program_url = self.linker.program(
                        program, program.homepage_url_name)
                    return http.HttpResponseRedirect(program_url)
                else:
                    return data.redirect.to('edit_site_settings')
        except exception.UserError as user_error:
            return self.error_handler.handleUserError(user_error, data)
        except exception.ServerError as server_error:
            return self.error_handler.handleServerError(server_error, data)
Exemple #5
0
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)
Exemple #6
0
def getHostname(data=None):
  """Returns the hostname, taking in account site hostname settings.
  """
  settings = data.site if data else site.singleton()

  if settings.hostname:
    return settings.hostname

  return getRawHostname()
Exemple #7
0
def isSecondaryHostname(data=None):
  """Returns if the current request is from the secondary hostname.
  """
  settings = data.site if data else site.singleton()

  if not settings.hostname:
    return False

  return getRawHostname().find(settings.hostname) >= 0
Exemple #8
0
  def site(self):
    """Returns the site field."""
    if not self._isSet(self._site):
      # XSRF middleware might have already retrieved it for us
      if not hasattr(self.request, 'site'):
        # populate site.Site singleton to request field
        self.request.site = site_logic.singleton()

      self._site = self.request.site
    return self._site
def process(org_key):
  """Processes a single organization.

  Organization status is updated to ACCEPTED or REJECTED if the current
  status has been set to PRE_ACCEPTED or PRE_REJECTED, respectively,
  by program administrators.

  Args:
    org_key: Organization key.
  """
  context = mapreduce_context.get()
  program_key = db.Key(context.mapreduce_spec.mapper.params['program_key'])

  if program_key.kind() == 'GSoCProgram':
    url_names = soc_urls.UrlNames
  elif program_key.kind() == 'GCIProgram':
    url_names = ci_urls.UrlNames
  else:
    raise ValueError('Invalid program type %s' % program_key.kind())

  program = db.get(program_key)

  site = site_logic.singleton()

  org_key = ndb.Key.from_old_key(org_key)
  org_admins = profile_logic.getOrgAdmins(org_key)

  # We are "prefetching" the ProgramMessages entity here instead of fetching
  # it where it is required i.e. when the message templates are required
  # to build the email message body. We do this because we perform the
  # operation of fetching the ProgramMessages entity if it exists or create
  # it if it doesn't in a Appengine regular "db" transation whereas rest
  # of the updating of organization entities happen within an ndb transaction
  # because Organization model is an ndb model and such cross API nested
  # transactions are incompatible in Appengine.
  program_messages = program.getProgramMessages()

  @ndb.transactional
  def updateOrganizationStatus():
    """Transactionally updates organization status."""
    # only organizations defined for the specified program should be processed
    organization = org_key.get()
    if organization.program.to_old_key() == program_key:
      if organization.status == org_model.Status.PRE_ACCEPTED:
        org_logic.setStatus(
            organization, program, site, program_messages,
            org_model.Status.ACCEPTED, links.ABSOLUTE_LINKER, url_names,
            org_admins=org_admins)
      elif organization.status == org_model.Status.PRE_REJECTED:
        org_logic.setStatus(
            organization, program, site, program_messages,
            org_model.Status.REJECTED, links.ABSOLUTE_LINKER, url_names,
            org_admins=org_admins)

  updateOrganizationStatus()
Exemple #10
0
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)
Exemple #11
0
def _GetSecretKey(request):
    """Gets the XSRF secret key from the request context.

  This function sets the key if it is not present.

  Args:
    request: A django.http.HttpRequest.

  Returns:
    The XSRF secret key for the request.
  """
    if not hasattr(request, 'site'):
        request.site = site.singleton()
    return site.xsrfSecretKey(request.site)
Exemple #12
0
def _GetSecretKey(request):
  """Gets the XSRF secret key from the request context.

  This function sets the key if it is not present.

  Args:
    request: A django.http.HttpRequest.

  Returns:
    The XSRF secret key for the request.
  """
  if not hasattr(request, 'site'):
    request.site = site.singleton()
  return site.xsrfSecretKey(request.site)
def getDefaultMailSender(site=None):
    """Returns the sender that currently can be used to send emails.

  Args:
    site: Optional site_model.Site entity. If not supplied, it will be retrieved
      from the datastore or created.

  Returns:
    - A tuple containing (sender_name, sender_address)
  """
    if not site:
        site = site_logic.singleton()

    # check if there is a noreply email address set
    no_reply_email = system.getApplicationNoReplyEmail()

    return (site.site_name, no_reply_email)
def getDefaultMailSender(site=None):
  """Returns the sender that currently can be used to send emails.

  Args:
    site: Optional site_model.Site entity. If not supplied, it will be retrieved
      from the datastore or created.

  Returns:
    - A tuple containing (sender_name, sender_address)
  """
  if not site:
    site = site_logic.singleton()

  # check if there is a noreply email address set
  no_reply_email = system.getApplicationNoReplyEmail()

  return (site.site_name, no_reply_email)
Exemple #15
0
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)
Exemple #16
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 import site

  site_entity = site.singleton()
  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)
Exemple #17
0
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)
Exemple #18
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
  """

    site_entity = site.singleton()
    site_name = site_entity.site_name

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

    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)
Exemple #19
0
def getDefaultMailSender(data=None):
    """Returns the sender that currently can be used to send emails.

  Args:
    data: an option RequestData object

  Returns:
    - A tuple containing (sender_name, sender_address)
    Consisting of:
  """
    from soc.logic import system
    from soc.logic import site

    # check if there is a noreply email address set

    if data:
        site_entity = data.site
    else:
        site_entity = site.singleton()

    no_reply_email = system.getApplicationNoReplyEmail()

    return (site_entity.site_name, no_reply_email)
Exemple #20
0
  def __call__(self, request, *args, **kwargs):
    """Custom call implementation.

    This avoids looking up unneeded data.
    """
    self.response = Response()

    self.init(request, args, kwargs)

    action = args[0] if args else ''

    if action == 'login':
      self.redirect.toUrl(users.create_login_url('/'))
    elif action == 'logout':
      self.redirect.toUrl(users.create_logout_url('/'))
    else:
      settings = site.singleton()
      program = settings.active_program
      if program:
        self.redirect.program(program).to(program.homepage_url_name)
      else:
        self.redirect.to('edit_site_settings')

    return self.response
Exemple #21
0
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)
Exemple #22
0
 def _getSecretKey(self, request):
   """Gets the XSRF secret key from the request context."""
   if not hasattr(request, 'site'):
     request.site = site.singleton()
   return site.xsrfSecretKey(request.site)
    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 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()
Exemple #25
0
def process(org_key):
    """Processes a single organization.

  Organization status is updated to ACCEPTED or REJECTED if the current
  status has been set to PRE_ACCEPTED or PRE_REJECTED, respectively,
  by program administrators.

  Args:
    org_key: Organization key.
  """
    context = mapreduce_context.get()
    program_key = db.Key(context.mapreduce_spec.mapper.params['program_key'])

    if program_key.kind() == 'GSoCProgram':
        url_names = soc_urls.UrlNames
    elif program_key.kind() == 'GCIProgram':
        url_names = ci_urls.UrlNames
    else:
        raise ValueError('Invalid program type %s' % program_key.kind())

    program = db.get(program_key)

    site = site_logic.singleton()

    org_key = ndb.Key.from_old_key(org_key)
    org_admins = profile_logic.getOrgAdmins(org_key)

    # We are "prefetching" the ProgramMessages entity here instead of fetching
    # it where it is required i.e. when the message templates are required
    # to build the email message body. We do this because we perform the
    # operation of fetching the ProgramMessages entity if it exists or create
    # it if it doesn't in a Appengine regular "db" transation whereas rest
    # of the updating of organization entities happen within an ndb transaction
    # because Organization model is an ndb model and such cross API nested
    # transactions are incompatible in Appengine.
    program_messages = program.getProgramMessages()

    @ndb.transactional
    def updateOrganizationStatus():
        """Transactionally updates organization status."""
        # only organizations defined for the specified program should be processed
        organization = org_key.get()
        if organization.program.to_old_key() == program_key:
            if organization.status == org_model.Status.PRE_ACCEPTED:
                org_logic.setStatus(organization,
                                    program,
                                    site,
                                    program_messages,
                                    org_model.Status.ACCEPTED,
                                    links.ABSOLUTE_LINKER,
                                    url_names,
                                    org_admins=org_admins)
            elif organization.status == org_model.Status.PRE_REJECTED:
                org_logic.setStatus(organization,
                                    program,
                                    site,
                                    program_messages,
                                    org_model.Status.REJECTED,
                                    links.ABSOLUTE_LINKER,
                                    url_names,
                                    org_admins=org_admins)

    updateOrganizationStatus()
  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()
Exemple #27
0
from soc.views.helper import context as context_helper
from soc.views.helper import lists
from soc.views.helper import url_patterns as soc_url_patterns

from soc.modules.gsoc.views import forms
from soc.modules.gsoc.views.helper import url_names
from soc.modules.gsoc.views.helper import url_patterns
from soc.modules.gsoc.views.helper.url_patterns import url
from soc.modules.gsoc.views import base

from summerofcode.request import links
from summerofcode.models import shipment_tracking

# TODO(daniel): once Site has been migrated to ndb, update this to make sure
# it benefits from ndbs caching mechanisms.
site = site_logic.singleton()
decorator = OAuth2Decorator(client_id=site.google_client_id,
                            client_secret=site.google_client_secret,
                            scope='https://www.googleapis.com/auth/drive.file')

URL_FMT = ("https://docs.google.com/feeds/download/spreadsheets/Export" +
           "?key=%s&exportFormat=csv&gid=%d")


def redirect(self, uri):
    raise exception.Redirect(uri)


class CallbackPage(base.GSoCRequestHandler):
    """View with the document picker.
  """
from soc.views.helper import context as context_helper
from soc.views.helper import lists
from soc.views.helper import url_patterns as soc_url_patterns

from soc.modules.gsoc.views import forms
from soc.modules.gsoc.views.helper import url_names
from soc.modules.gsoc.views.helper import url_patterns
from soc.modules.gsoc.views.helper.url_patterns import url
from soc.modules.gsoc.views import base

from summerofcode.request import links
from summerofcode.models import shipment_tracking

# TODO(daniel): once Site has been migrated to ndb, update this to make sure
# it benefits from ndbs caching mechanisms.
site = site_logic.singleton()
decorator = OAuth2Decorator(
    client_id=site.google_client_id,
    client_secret=site.google_client_secret,
    scope='https://www.googleapis.com/auth/drive.file')

URL_FMT = ("https://docs.google.com/feeds/download/spreadsheets/Export" +
           "?key=%s&exportFormat=csv&gid=%d")


def redirect(self, uri):
  raise exception.Redirect(uri)


class CallbackPage(base.GSoCRequestHandler):
  """View with the document picker.