Ejemplo n.º 1
0
    def buildInvitations(self, limit=0, noop=False):
        invites = self._inviteDB.getInvites(limit=limit)
        
        logs.info('Number of invitations: %s' % len(invites))

        if len(invites) == 0:
            logs.debug('Aborting')
            return
        
        for invite in invites:
            if invite.user_id not in self._users:
                self._users[str(invite.user_id)] = None
        
        missingAccounts = set()
        for k, v in self._users.iteritems():
            if v is None:
                missingAccounts.add(k)
        accounts = self._accountDB.getAccounts(list(missingAccounts))
        
        for account in accounts:
            try:
                self._users[account.user_id] = account
            except Exception as e:
                logs.warning("Unable to set account %s" % account)
        
        for invite in invites:
            try:
                if self._users[str(invite.user_id)] is None:
                    raise StampedUnavailableError("User (%s) not found" % (invite.user_id))

                subject = self._users[str(invite.user_id)]
                emailAddress = invite.recipient_email
                emailAddress = validateEmail(emailAddress)

                # Add email address
                if emailAddress not in self._emailQueue:
                    self._emailQueue[emailAddress] = []

                # Build email
                email = InviteEmail(recipient=emailAddress, subject=subject, inviteId=invite.invite_id)
                
                self._emailQueue[emailAddress].append(email)

            except StampedInvalidEmailError:
                logs.debug("Invalid email address: %s" % invite.recipient_email)
            except Exception as e:
                logs.warning("An error occurred: %s" % e)
                logs.warning("Invite removed: %s" % invite)

            finally:
                if not noop:
                    self._inviteDB.removeInvite(invite.invite_id)
Ejemplo n.º 2
0
    def buildAlerts(self, limit=0, noop=False):
        alerts = self._alertDB.getAlerts(limit=limit)
        
        logs.info('Number of alerts: %s' % len(alerts))

        if len(alerts) == 0:
            logs.debug('Aborting')
            return
        
        for alert in alerts:
            if alert.subject is not None and alert.subject not in self._users:
                self._users[str(alert.subject)] = None
            if alert.recipient_id not in self._users:
                self._users[str(alert.recipient_id)] = None
        
        missingAccounts = set()
        for k, v in self._users.iteritems():
            if v is None:
                missingAccounts.add(k)
        accounts = self._accountDB.getAccounts(list(missingAccounts))
        
        for account in accounts:
            try:
                self._users[account.user_id] = account
            except Exception as e:
                logs.warning("Unable to set account: %s" % (account))

        # Get email settings tokens
        tokens = self._auth.ensureEmailAlertTokensForUsers(self._users.keys())
        
        for alert in alerts:
            try:
                # Break if subject is not set (e.g. welcome emails). TODO: Add this later.
                if alert.subject is None:
                    continue 

                if self._users[str(alert.recipient_id)] is None or self._users[str(alert.subject)] is None:
                    msg = "Recipient (%s) or user (%s) not found" % (alert.recipient_id, alert.subject)
                    raise StampedUnavailableError(msg)

                # Check recipient settings
                recipient = self._users[str(alert.recipient_id)]
                settings = recipient.alert_settings

                if alert.verb == 'credit':
                    send_push   = settings.alerts_credits_apns
                    send_email  = settings.alerts_credits_email
                elif alert.verb == 'like':
                    send_push   = settings.alerts_likes_apns
                    send_email  = settings.alerts_likes_email
                elif alert.verb == 'todo':
                    send_push   = settings.alerts_todos_apns
                    send_email  = settings.alerts_todos_email
                elif alert.verb == 'mention':
                    send_push   = settings.alerts_mentions_apns
                    send_email  = settings.alerts_mentions_email
                elif alert.verb == 'comment':
                    send_push   = settings.alerts_comments_apns
                    send_email  = settings.alerts_comments_email
                elif alert.verb == 'reply':
                    send_push   = settings.alerts_replies_apns
                    send_email  = settings.alerts_replies_email
                elif alert.verb == 'follow':
                    send_push   = settings.alerts_followers_apns
                    send_email  = settings.alerts_followers_email
                elif alert.verb.startswith('friend_'):
                    send_push   = settings.alerts_friends_apns
                    send_email  = settings.alerts_friends_email
                elif alert.verb.startswith('action_'):
                    send_push   = settings.alerts_actions_apns
                    send_email  = settings.alerts_actions_email
                else:
                    send_push   = False
                    send_email  = False
                
                # Subject
                subject = self._users[str(alert.subject)]
                
                # Build admin list
                if recipient.screen_name in self._admins:
                    self._adminEmails.add(recipient.email)
                    for token in recipient.devices.ios_device_tokens:
                        self._adminTokens.add(token)

                # Build unread count
                if alert.recipient_id not in self._unreadCount:
                    try:
                        self._unreadCount[alert.recipient_id] = stampedAPI.getUnreadActivityCount(alert.recipient_id)
                    except Exception as e:
                        logs.warning("Unable to set unread count: %s" % e)
                        self._unreadCount[alert.recipient_id] = 0
                
                # Build APNS notifications
                if send_push:
                    try:
                        if recipient.devices is not None and recipient.devices.ios_device_tokens is not None:
                            for deviceId in recipient.devices.ios_device_tokens:
                                # Build push notification and add to queue
                                notification = PushNotification(recipient=deviceId, 
                                                                subject=subject, 
                                                                verb=alert.verb, 
                                                                unreadCount=self._unreadCount[alert.recipient_id], 
                                                                activityId=alert.activity_id)
                                if deviceId not in self._pushQueue:
                                    self._pushQueue[deviceId] = []
                                self._pushQueue[deviceId].append(notification)
                        else:
                            logs.info("No devices found for recipient '%s'" % recipient.user_id)

                    except Exception as e:
                        logs.warning("Push generation failed for alert '%s': %s" % (alert.alert_id, e))
                        logs.debug("Subject: %s" % subject.user_id)
                        logs.debug("Recipient: %s" % recipient.user_id)

                # Build email
                if send_email:
                    try:
                        if recipient.email is not None: 
                            emailAddress = validateEmail(recipient.email)

                            # Add email address
                            if recipient.email not in self._emailQueue:
                                self._emailQueue[recipient.email] = []

                            # Grab settings token
                            token = tokens[recipient.user_id]

                            # Build email
                            email = AlertEmail(recipient=recipient.email, 
                                                verb=alert.verb, 
                                                settingsToken=token, 
                                                subject=subject, 
                                                objects=alert.objects, 
                                                activityId=alert.activity_id)

                            self._emailQueue[recipient.email].append(email)
                        else:
                            logs.info("No email address found for recipient '%s'" % recipient.user_id)

                    except StampedInvalidEmailError:
                        logs.debug("Invalid email address: %s" % recipient.email)
                    except Exception as e:
                        logs.warning("Email generation failed for alert '%s': %s" % (alert.alert_id, e))
                        logs.debug("Subject: %s" % subject.user_id)
                        logs.debug("Recipient: %s" % recipient.user_id)

            except Exception as e:
                logs.warning("An error occurred: %s" % e)
                logs.warning("Alert removed: %s" % alert)

            finally:
                if not noop:
                    self._alertDB.removeAlert(alert.alert_id)

        """
        If the user doesn't have alerts enabled but we have an APNS token for them, send them a notification 
        with just the badge count. This should only occur if no other push notifications exist.
        """
        for recipientId, unreadCount in self._unreadCount.iteritems():
            try:
                if unreadCount > 0:
                    recipient = self._users[recipientId]
                    if recipient.devices is not None and recipient.devices.ios_device_tokens is not None:
                        notification = PushNotification(recipient=recipient, unreadCount=unreadCount)
                        for deviceId in recipient.devices.ios_device_tokens:
                            if deviceId not in self._pushQueue:
                                self._pushQueue[deviceId] = [ notification ]
            except Exception as e:
                logs.warning("Push count generation failed for recipient '%s': %s" % (recipientId, e))