def sendMail(context, parent=None, run=True, transactional=True): """Sends out an email using context to supply the needed information. Args: context: The context supplied to the email message (dictionary) parent: The parent entity to use for when this mail is to be sent in a transaction. run: If true the mail will be sent otherwise the function that can sent the mail will be returned. transactional: Whether the task should be created transactionally. Raises: Error that corresponds with the first problem it finds iff the message is not properly initialized. List of all possible errors: http://code.google.com/appengine/docs/mail/exceptions.html """ # construct the EmailMessage from the given context message = mail.EmailMessage(**context) message.check_initialized() # don't send out emails in non-local debug mode if not system.isLocal() and system.isDebug(): return txn = mailer.getSpawnMailTaskTxn( context=context, parent=parent, transactional=transactional) if run: return db.RunInTransaction(txn) else: return txn
def create_comment_txn(): comment = comment_form.create(commit=True, parent=data.url_proposal) context = notifications.newReviewContext(data, comment, to_emails) sub_txn = mailer.getSpawnMailTaskTxn(context, parent=comment) sub_txn() return comment
def sendMail(context, parent=None, run=True, transactional=True): """Sends out an email using context to supply the needed information. Args: context: The context supplied to the email message (dictionary) parent: The parent entity to use for when this mail is to be sent in a transaction. run: If true the mail will be sent otherwise the function that can sent the mail will be returned. transactional: Whether the task should be created transactionally. Raises: Error that corresponds with the first problem it finds iff the message is not properly initialized. List of all possible errors: http://code.google.com/appengine/docs/mail/exceptions.html """ # construct the EmailMessage from the given context message = mail.EmailMessage(**context) message.check_initialized() # don't send out emails in non-local debug mode if not system.isLocal() and system.isDebug(): return txn = mailer.getSpawnMailTaskTxn(context=context, parent=parent, transactional=transactional) if run: return db.RunInTransaction(txn) else: return txn
def reject_request_txn(): request = db.get(self.data.request_entity.key()) request.status = 'rejected' request.put() context = notifications.handledRequestContext(self.data, request.status) sub_txn = mailer.getSpawnMailTaskTxn(context, parent=request) sub_txn()
def withdraw_invite_txn(): invite = db.get(invite_key) invite.status = 'withdrawn' invite.put() context = notifications.handledInviteContext(self.data) sub_txn = mailer.getSpawnMailTaskTxn(context, parent=invite) sub_txn()
def txn(): record = db.get(record_key) record.status = new_status record.put() if context: sub_txn = mailer.getSpawnMailTaskTxn(context, parent=record) sub_txn()
def resubmit_invite_txn(): invite = db.get(invite_key) invite.status = 'pending' invite.put() context = notifications.handledInviteContext(request_data) sub_txn = mailer.getSpawnMailTaskTxn(context, parent=invite) sub_txn()
def sendFirstTaskConfirmationTxn(profile, task): """Returns a transaction which sends a confirmation email to a student who completes their first task. """ if not profile.is_student: raise ValueError('Only students can be queried for closed tasks.') context = notifications.getFirstTaskConfirmationContext(profile) return mailer.getSpawnMailTaskTxn(context, parent=task)
def sendFirstTaskConfirmationTxn(profile, task): """Returns a transaction which sends a confirmation email to a student who completes their first task. """ if not profile.student_info: raise ValueError('Only students can be queried for closed tasks.') context = notifications.getFirstTaskConfirmationContext(profile) return mailer.getSpawnMailTaskTxn(context, parent=task)
def update_proposal_txn(): proposal = db.get(proposal_key) proposal_form.instance = proposal proposal = proposal_form.save(commit=True) context = notifications.updatedProposalContext(self.data, proposal, to_emails) sub_txn = mailer.getSpawnMailTaskTxn(context, parent=proposal) sub_txn() return proposal
def update_proposal_txn(): proposal = db.get(proposal_key) proposal_form.instance = proposal proposal = proposal_form.save(commit=True) context = notifications.updatedProposalContext( data, proposal, to_emails) sub_txn = mailer.getSpawnMailTaskTxn(context, parent=proposal) sub_txn() return proposal
def create_proposal_trx(): student_info = db.get(student_info_key) student_info.number_of_proposals += 1 student_info.put() proposal = proposal_form.create(commit=True, parent=self.data.profile) context = notifications.newProposalContext(self.data, proposal, to_emails) sub_txn = mailer.getSpawnMailTaskTxn(context, parent=proposal) sub_txn() return proposal
def accept_request_txn(): request = db.get(request_key) self.data.requester_profile = profile = db.get(profile_key) request.status = 'accepted' profile.is_mentor = True profile.mentor_for.append(organization_key) profile.mentor_for = list(set(profile.mentor_for)) profile.put() request.put() context = notifications.handledRequestContext(self.data, request.status) sub_txn = mailer.getSpawnMailTaskTxn(context, parent=request) sub_txn()
def create_proposal_trx(): profile = data.ndb_profile.key.get() profile.student_data.number_of_proposals += 1 profile.put() proposal = GSoCProposal(parent=data.ndb_profile.key.to_old_key(), **proposal_properties) proposal.put() context = notifications.newProposalContext(data, proposal, to_emails) sub_txn = mailer.getSpawnMailTaskTxn(context, parent=proposal) sub_txn() return proposal
def create_proposal_trx(): profile = data.ndb_profile.key.get() profile.student_data.number_of_proposals += 1 profile.put() proposal = GSoCProposal( parent=data.ndb_profile.key.to_old_key(), **proposal_properties) proposal.put() context = notifications.newProposalContext(data, proposal, to_emails) sub_txn = mailer.getSpawnMailTaskTxn(context, parent=proposal) sub_txn() return proposal
def accept_request_txn(): request = db.get(request_key) profile = db.get(profile_key) request.status = "accepted" profile.is_mentor = True profile.mentor_for.append(organization_key) profile.mentor_for = list(set(profile.mentor_for)) profile.put() request.put() context = notifications.handledRequestContext(self.data, request.status) sub_txn = mailer.getSpawnMailTaskTxn(context, parent=request) # TODO(SRabbelier): just call as soon as we make User Request's parent db.run_in_transaction(sub_txn)
def notifyParticipantsOfMessage(message, is_reply): """Notifies participants in a conversation's participants of a new message. Args: message: Key (ndb) of GCIMessage of which to notify participants. is_reply: Whether this message is a reply to an existing conversation. """ message_ent = message.get() conversation_ent = message_ent.conversation.get() to_emails = getSubscribedEmails( message_ent.conversation, exclude=[message_ent.author]) context = notifications.getTaskConversationMessageContext( message, list(to_emails), is_reply) txn = mailer.getSpawnMailTaskTxn(context, parent=None) db.run_in_transaction(txn)
def notifyParticipantsOfMessage(message, is_reply): """Notifies participants in a conversation's participants of a new message. Args: message: Key (ndb) of GCIMessage of which to notify participants. is_reply: Whether this message is a reply to an existing conversation. """ message_ent = message.get() conversation_ent = message_ent.conversation.get() to_emails = getSubscribedEmails(message_ent.conversation, exclude=[message_ent.author]) context = notifications.getTaskConversationMessageContext( message, list(to_emails), is_reply) txn = mailer.getSpawnMailTaskTxn(context, parent=None) db.run_in_transaction(txn)
def create_or_update_slot_transfer_trx(): update = False if slot_transfer_entity: slot_transfer = db.get(slot_transfer_entity.key()) slot_transfer_form.instance = slot_transfer slot_transfer = slot_transfer_form.save(commit=True) update = True else: slot_transfer = slot_transfer_form.create( commit=True, parent=data.url_ndb_org.key.to_old_key()) context = notifications.createOrUpdateSlotTransferContext( data, slot_transfer, to_emails, update) sub_txn = mailer.getSpawnMailTaskTxn( context, parent=slot_transfer.parent()) sub_txn() return slot_transfer
def create_or_update_slot_transfer_trx(): update = False if slot_transfer_entity: slot_transfer = db.get(slot_transfer_entity.key()) slot_transfer_form.instance = slot_transfer slot_transfer = slot_transfer_form.save(commit=True) update = True else: slot_transfer = slot_transfer_form.create( commit=True, parent=data.url_ndb_org.key.to_old_key()) context = notifications.createOrUpdateSlotTransferContext( data, slot_transfer, to_emails, update) sub_txn = mailer.getSpawnMailTaskTxn(context, parent=slot_transfer.parent()) sub_txn() return slot_transfer
def storeAndNotifyTxn(comment, task=None): """Returns a method to be run in a transaction to notify subscribers. Args: comment: A GCIComment instance task: optional GCITask instance that is the parent of the specified comment """ if not task: task = comment.parent() elif task.key() != comment.parent_key(): raise ValueError( "The specified task must be the parent of the comment") if comment_model.GCIComment.created_by.get_value_for_datastore(comment): author_key = ndb.Key.from_old_key( comment_model.GCIComment.created_by.get_value_for_datastore( comment)) else: author_key = None to_emails = [] profiles = ndb.get_multi(map(ndb.Key.from_old_key, task.subscribers)) for profile in profiles: if profile and ((not author_key) or profile.key.parent() != author_key): to_emails.append(profile.contact.email) # Send out an email to an entire organization when set. org = task.org if org.notification_mailing_list: to_emails.append(org.notification_mailing_list) context = notifications.getTaskCommentContext(task, comment, to_emails) sub_txn = mailer.getSpawnMailTaskTxn(context, parent=task) def txn(): sub_txn() comment.put() return txn
def storeAndNotifyTxn(comment, task=None): """Returns a method to be run in a transaction to notify subscribers. Args: comment: A GCIComment instance task: optional GCITask instance that is the parent of the specified comment """ if not task: task = comment.parent() elif task.key() != comment.parent_key(): raise ValueError("The specified task must be the parent of the comment") if comment_model.GCIComment.created_by.get_value_for_datastore(comment): author_key = ndb.Key.from_old_key( comment_model.GCIComment.created_by.get_value_for_datastore(comment)) else: author_key = None to_emails = [] profiles = ndb.get_multi(map(ndb.Key.from_old_key, task.subscribers)) for profile in profiles: if profile and ((not author_key) or profile.key.parent() != author_key): to_emails.append(profile.contact.email) # Send out an email to an entire organization when set. org = task.org if org.notification_mailing_list: to_emails.append(org.notification_mailing_list) context = notifications.getTaskCommentContext(task, comment, to_emails) sub_txn = mailer.getSpawnMailTaskTxn(context, parent=task) def txn(): sub_txn() comment.put() return txn
def create_comment_txn(): comment = comment_form.create(commit=True, parent=self.data.proposal) context = notifications.newCommentContext(self.data, comment, to_emails) sub_txn = mailer.getSpawnMailTaskTxn(context, parent=comment) sub_txn() return comment
def setStatus(organization, program, site, program_messages, new_status, linker=None, url_names=None, org_admins=None): """Sets status of the specified organization. This function may be called to accept the organization into the program or rejected it from the program, if new status is set to ACCEPTED or REJECTED, respectively. If the optional list of organization administrators is specified along with the program specific messages, they will be sent acceptance or rejection message. Additionally, if the organization status is set to ACCEPTED and the optional list of organization administrators is specified along with the program specific messages, the administrators will be sent the organization member welcome message. Args: organization: Organization entity. program: Program entity to which organization is assigned. site: Site entity. program_messages: ProgramMessages entity that holds the message templates provided by the program admins. new_status: New status of the organization. Must be one of org_model.Status constants. linker: Instance of links.Linker class (Optional: required only for sending notifications). url_names: Instance of url_names.UrlNames (Optional: required only for sending notifications). org_admins: Optional list of organization administrators for the specified organization. Returns: The updated organization entity. """ if organization.status != new_status: organization.status = new_status organization.put() if (org_admins and new_status in [org_model.Status.ACCEPTED, org_model.Status.REJECTED]): # recipients of organization acceptance or rejection email recipients = [org_admin.contact.email for org_admin in org_admins] if new_status == org_model.Status.ACCEPTED: if not (linker and url_names): raise ValueError(DEF_LINKER_URL_NAMES_REQUIRED) notification_context = ( notifications.OrganizationAcceptedContextProvider( linker, url_names).getContext(recipients, organization, program, site, program_messages)) # organization administrators are also sent the welcome email for org_admin in org_admins: if (profile_model.MessageType.ORG_MEMBER_WELCOME_MSG not in org_admin.sent_messages): profile_logic.dispatchOrgMemberWelcomeEmail( org_admin, program, program_messages, site, parent=organization) elif new_status == org_model.Status.REJECTED: notification_context = ( notifications.OrganizationRejectedContextProvider( ).getContext(recipients, organization, program, site, program_messages)) sub_txn = mailer.getSpawnMailTaskTxn(notification_context, parent=organization) sub_txn() return organization
def create_invite_txn(): invite = invite_form.create(commit=True) context = notifications.inviteContext(self.data, invite) sub_txn = mailer.getSpawnMailTaskTxn(context, parent=invite) sub_txn() return invite
def create_request_txn(): request = request_form.create(commit=True) context = notifications.requestContext(self.data, request, admin_emails) sub_txn = mailer.getSpawnMailTaskTxn(context, parent=request) sub_txn() return request
def setStatus(organization, program, site, program_messages, new_status, linker=None, url_names=None, org_admins=None): """Sets status of the specified organization. This function may be called to accept the organization into the program or rejected it from the program, if new status is set to ACCEPTED or REJECTED, respectively. If the optional list of organization administrators is specified along with the program specific messages, they will be sent acceptance or rejection message. Additionally, if the organization status is set to ACCEPTED and the optional list of organization administrators is specified along with the program specific messages, the administrators will be sent the organization member welcome message. Args: organization: Organization entity. program: Program entity to which organization is assigned. site: Site entity. program_messages: ProgramMessages entity that holds the message templates provided by the program admins. new_status: New status of the organization. Must be one of org_model.Status constants. linker: Instance of links.Linker class (Optional: required only for sending notifications). url_names: Instance of url_names.UrlNames (Optional: required only for sending notifications). org_admins: Optional list of organization administrators for the specified organization. Returns: The updated organization entity. """ if organization.status != new_status: organization.status = new_status organization.put() if (org_admins and new_status in [org_model.Status.ACCEPTED, org_model.Status.REJECTED]): # recipients of organization acceptance or rejection email recipients = [org_admin.contact.email for org_admin in org_admins] if new_status == org_model.Status.ACCEPTED: if not (linker and url_names): raise ValueError(DEF_LINKER_URL_NAMES_REQUIRED) notification_context = ( notifications.OrganizationAcceptedContextProvider(linker, url_names) .getContext( recipients, organization, program, site, program_messages)) # organization administrators are also sent the welcome email for org_admin in org_admins: if (profile_model.MessageType.ORG_MEMBER_WELCOME_MSG not in org_admin.sent_messages): profile_logic.dispatchOrgMemberWelcomeEmail( org_admin, program, program_messages, site, parent=organization) elif new_status == org_model.Status.REJECTED: notification_context = ( notifications.OrganizationRejectedContextProvider() .getContext( recipients, organization, program, site, program_messages)) sub_txn = mailer.getSpawnMailTaskTxn( notification_context, parent=organization) sub_txn() return organization