def sendPushNotifications(self): success = 0 error = 0 now = datetime.utcnow().strftime('%Y/%m/%d %H:%M') notifications = PushNotificationModel().find( query={ 'sendTime': { "$lt": now }, 'progress': ProgressState.ACTIVE }) for notification in notifications: users = [ UserModel().findOne({'_id': p['userId']}) for p in list(ProfileModel().find( query={ 'appletId': notification['applet'], 'userId': { '$exists': True } })) ] deviceIds = [ user['deviceId'] for user in users if ('deviceId' in user) and ( user.get('timezone', 0) == notification.get('timezone', 0)) ] proxy_dict = {} test_api_key = 'AAAAJOyOEz4:APA91bFudM5Cc1Qynqy7QGxDBa-2zrttoRw6ZdvE9PQbfIuAB9SFvPje7DcFMmPuX1IizR1NAa7eHC3qXmE6nmOpgQxXbZ0sNO_n1NITc1sE5NH3d8W9ld-cfN7sXNr6IAOuodtEwQy-' push_service = FCMNotification(api_key=test_api_key, proxy_dict=proxy_dict) registration_ids = deviceIds message_title = notification['head'] message_body = notification['content'] result = push_service.notify_multiple_devices( registration_ids=registration_ids, message_title=message_title, message_body=message_body) notification['attempts'] += 1 notification['progress'] = ProgressState.EMPTY if result['failure']: notification['progress'] = ProgressState.ERROR error += result['failure'] print(result['results']) if result['success']: notification['progress'] = ProgressState.SUCCESS success += result['success'] PushNotificationModel().save(notification, validate=False) return {'successed': success, 'errors': error}
def setSchedule(self, applet, schedule, **kwargs): thisUser = self.getCurrentUser() if not AppletModel().isCoordinator(applet['_id'], thisUser): raise AccessException( "Only coordinators and managers can update applet schedules.") if 'events' in schedule: for event in schedule['events']: if 'data' in event and 'useNotifications' in event[ 'data'] and event['data']['useNotifications']: if event['data']['notifications'][0]['start']: sendTime = event['data']['notifications'][0]['start'] else: sendTime = '09:00' # in case of sigle event with exact year, month, day if 'year' in event['schedule'] and 'month' in event[ 'schedule'] and 'dayOfMonth' in event['schedule']: sendTime = ( str(event['schedule']['year'][0]) + '/' + ('0' + str(event['schedule']['month'][0] + 1))[-2:] + '/' + ('0' + str(event['schedule']['dayOfMonth'][0]))[-2:] + ' ' + sendTime) existNotification = PushNotificationModel().findOne( query={ 'applet': applet['_id'], 'creator_id': thisUser['_id'], 'sendTime': str(sendTime) }) if not existNotification: PushNotificationModel().createNotification( applet['_id'], 1, event['data']['title'], event['data']['description'], str(sendTime), thisUser['_id']) # in case of daily event appletMeta = applet['meta'] if 'meta' in applet else {'applet': {}} if 'applet' not in appletMeta: appletMeta['applet'] = {} appletMeta['applet']['schedule'] = schedule AppletModel().setMetadata(applet, appletMeta) thread = threading.Thread( target=AppletModel().updateUserCacheAllUsersAllRoles, args=(applet, thisUser)) thread.start() return (appletMeta)
def __send_notification(self, notification, user_ids=None): """ Main bode to send notification :params notification: Notification which should be sent to user :params notification: dict :params user: User to send the notification to. :params user: dict """ # notification['dateSend'] = self.user_timezone_time.strftime('%Y/%m/%d') message_title = notification['head'] message_body = notification['content'] result = self.push_service.notify_multiple_devices(registration_ids=user_ids, message_title=message_title, message_body=message_body) notification['attempts'] += 1 notification['progress'] = ProgressState.ACTIVE if result['failure']: notification['progress'] = ProgressState.ERROR self.error += result['failure'] print(result['results']) if result['success']: notification['progress'] = ProgressState.SUCCESS self.success += result['success'] PushNotificationModel().save(notification, validate=False)
def get_profiles_by_notifications(self, notifications): for notification in notifications: if 'notifiedUsers' not in notification: notification.update({ 'notifiedUsers': [] }) user_ids = [profile['userId'] for profile in self.get_profiles(notification) if profile] users = list(UserModel().get_users_by_ids(user_ids)) self.set_random_date(notification) current_users = self.filter_users_by_timezone(notification, users) if current_users: notification.get('notifiedUsers') notification.update({ 'notifiedUsers': notification.get('notifiedUsers', []) + [ { '_id': user['_id'], 'dateSend': (datetime.datetime.strptime(self.current_time, '%Y/%m/%d %H:%M') \ + datetime.timedelta(hours=int(user['timezone']))).strftime('%Y/%m/%d') } for user in current_users] }) device_ids = [user['deviceId'] for user in current_users] self.__send_notification(notification, device_ids) PushNotificationModel().save(notification, validate=False)
def get_profiles(self, notification): if len(notification['users']): return list(ProfileModel().get_profiles_by_ids(notification['users'])) notification_with_applet = list(PushNotificationModel().find(query={ 'applet': notification['applet'], 'users': { '$exists': True, '$ne': [] } })) notification_with_applet = list(set(user for n in notification_with_applet for user in n['users'])) profiles = list(ProfileModel().get_profiles_by_applet_id(notification['applet'])) # exclude existed users from general schedule return [profile for profile in profiles if profile['_id'] and profile['_id'] not in notification_with_applet]
def setSchedule(self, applet, rewrite, deleted, schedule, **kwargs): thisUser = self.getCurrentUser() if not AppletModel().isCoordinator(applet['_id'], thisUser): raise AccessException( "Only coordinators and managers can update applet schedules.") assigned = {} if 'events' in schedule: for event in schedule['events']: if 'id' in event: event['id'] = ObjectId(event['id']) assigned[event['id']] = True if rewrite: original = EventsModel().getSchedule(applet['_id']) if 'events' in original: for event in original['events']: original_id = event.get('id') if original_id not in assigned: PushNotificationModel().delete_notification( original_id) EventsModel().deleteEvent(original_id) else: if isinstance(deleted, list): for event_id in deleted: PushNotificationModel().delete_notification( ObjectId(event_id)) EventsModel().deleteEvent(ObjectId(event_id)) if 'events' in schedule: # insert and update events/notifications for event in schedule['events']: savedEvent = EventsModel().upsertEvent(event, applet['_id'], event.get('id', None)) if 'data' in event and 'useNotifications' in event[ 'data'] and event['data']['useNotifications']: if 'notifications' in event['data'] and event['data'][ 'notifications'][0]['start']: # in case of daily/weekly event exist_notification = None if 'id' in event: exist_notification = PushNotificationModel( ).findOne(query={'_id': event['id']}) if exist_notification: PushNotificationModel().replaceNotification( applet['_id'], savedEvent, thisUser, exist_notification) else: PushNotificationModel().replaceNotification( applet['_id'], savedEvent, thisUser) event['id'] = savedEvent['_id'] return { "applet": { "schedule": schedule if rewrite else EventsModel().getSchedule(applet['_id']) } }
def get_notifications_by_type(self, notification_type=1): return list(PushNotificationModel().find( query={ 'notification_type': notification_type, } ))