Beispiel #1
0
def send_fcm_notification(title="", body="", data=None, users=None):
    """
    sends fcm notification to a single or multiple user device
    :param title: title of the notification message
    :param body: body of the notification
    :param data: any data to be sent
    :param users: list of user ids
    :return: True/False
    """
    if users:
        push_service = FCMNotification(api_key=settings.FCM_API_KEY)
        try:
            if data:
                if isinstance(users, list):
                    registration_ids = [
                        devices.registration_id
                        for devices in UserDevice.objects.filter(
                            used_id__in=users)
                    ]
                    push_service.multiple_devices_data_message(
                        registration_ids=registration_ids, data_message=data)
                else:
                    registration_id = UserDevice.objects.get(
                        user_id=users).registration_id
                    push_service.single_device_data_message(
                        registration_id=registration_id, data_message=data)
            else:
                if isinstance(users, list):
                    registration_ids = [
                        devices.registration_id
                        for devices in UserDevice.objects.filter(
                            user_id__in=users)
                    ]
                    push_service.notify_multiple_devices(
                        registration_ids=registration_ids,
                        message_title=title,
                        message_body=body)
                else:
                    registration_id = UserDevice.objects.get(
                        user_id=users).registration_id
                    push_service.notify_single_device(
                        registration_id=registration_id,
                        message_title=title,
                        message_body=body)
            return True
        except:
            return False
    else:
        return False
Beispiel #2
0
    def nueva(solicitud, lectura):
        peaje = lectura.peaje
        alerta = Alerta.objects.create(lectura=lectura)

        mensaje = {
            'alerta_id': alerta.pk,
            'latitud': str(peaje.latitud),
            'longitud': str(peaje.longitud),
            'radio': str(peaje.radio)
        }

        registration_ids = []

        patrulleros = Patrullero.objects.filter(activo=True)
        for patrullero in patrulleros:
            registration_ids.append(patrullero.token)

        push_service = FCMNotification(
            api_key="AIzaSyBCr-rmINKdZQUKT3rQmLolkeFX4iNaB7c")

        result = push_service.multiple_devices_data_message(
            registration_ids=registration_ids, data_message=mensaje)

        if result['success'] == 1:
            for patrullero in patrulleros:
                Notificacion.objects.create(alerta=alerta,
                                            patrullero=patrullero)
        else:
            Alerta.objects.filter(pk=alerta.pk).delete()
            alerta = None
            print("\nError al enviar las notificaciones\n")
            print(result)

        return alerta
    def perform_create(self, request, serializer):
        recipients_array = []
        registration_ids = []
        recipients = []
        instance_message = master_data_models.Message()

        message_date_time = serializer.data['message_date_time']
        creator = serializer.data['creator']
        message_body = serializer.data['message_body']
        subject = serializer.data['subject']
        parent_message_id = serializer.data['parent_message_id']

        instance_message.message_date_time = message_date_time
        instance_message.creator_id = creator
        instance_message.message_body = message_body
        instance_message.subject = subject
        instance_message.parent_message_id = parent_message_id
        instance_message.save()

        for val in serializer.data["message_recipients"]:
            is_read = val["is_read"]
            recipient = val["recipient"]

            recipients.append(recipient)

            instance_message_recipients = master_data_models.MessageRecipient()
            instance_message_recipients.is_read = is_read
            instance_message_recipients.message_id = instance_message.id
            instance_message_recipients.recipient_id = recipient
            instance_message_recipients.save()

            recipients_object = {"id": instance_message_recipients.id, "is_read": "false",
                                 "message_id": instance_message.id,
                                 "recipient": recipient}

            recipients_array.append(recipients_object)

        message_object = {"message_date_time": message_date_time, "creator": creator, "id": instance_message.id,
                          "message_body": "" + message_body + "", "message_recipients": recipients_array,
                          "parent_message_id": parent_message_id, "subject": "" + subject + ""}

        message_payload = {"type": "NEW_MESSAGE", "data": message_object}

        # Send the newly created message and recipients to firebase
        fcm_tokens = user_management_models.Profile.objects.filter(user_id__in=recipients)
        push_service = FCMNotification(api_key=settings.FCM_APIKEY)

        for x in fcm_tokens:
            registration_ids.append(""+x.reg_id+"")

        result = push_service.multiple_devices_data_message(registration_ids=registration_ids,
                                                            data_message=message_payload)

        print(result)

        return message_payload
def send_user_a_push_notification(request):
    registration_ids = []

    if request.method == "POST":

        recipients = request.POST["recipients"].split(',')
        form = ComposeMessageForm(request.POST)

        if form.is_valid():
            form.full_clean()
            instance = form.save(commit=False)
            instance.message_date_time = datetime.now().timestamp()
            instance.creator = request.user
            instance.save()

            # Message object elements
            recipients_array = []
            message_time_stamp = int(datetime.now().timestamp()) * 1000
            creator_id = request.user.id
            message_body = form.cleaned_data['message_body']
            subject = form.cleaned_data['subject']
            message_id = instance.id

            for x in range(len(recipients)):
                instance_message_recipients = master_data_models.MessageRecipient()
                instance_message_recipients.message_id = instance.id
                instance_message_recipients.recipient_id = recipients[x]
                instance_message_recipients.save()

                recipients_object = {"id":instance_message_recipients.id, "is_read": "false", "message_id": message_id,
                                     "recipient": recipients[x]}

                recipients_array.append(recipients_object)

            message_object = {"message_date_time": message_time_stamp, "creator": creator_id, "id": message_id,
                              "message_body": "" + message_body + "", "message_recipients": recipients_array,
                              "parent_message_id": 0, "subject": "" + subject + ""}

            message_payload = {"type": "NEW_MESSAGE", "data": message_object}

            # Send the newly created message and recipients to firebase
            fcm_tokens = user_management_models.Profile.objects.filter(user_id__in=recipients)
            push_service = FCMNotification(api_key=settings.FCM_APIKEY)

            for x in fcm_tokens:
                # if x.reg_id is not None:
                #     x.send_message(json.dumps(message_payload))
                registration_ids.append("" + x.reg_id + "")

            result = push_service.multiple_devices_data_message(registration_ids=registration_ids,
                                                                data_message=message_payload)

        return redirect(request.META['HTTP_REFERER'])
    def update(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        message_recipient = request.data.get("id")
        deleted_from_mail_box = request.data.get("deleted_from_mail_box")
        recipient_array = []
        registration_ids = []

        if serializer.is_valid:
            queryset = master_data_models.MessageRecipient.objects.all()
            instance = queryset.get(id=message_recipient)
            instance.deleted_from_mail_box = deleted_from_mail_box
            instance.save()

            query_all_recipients = master_data_models.MessageRecipient.objects.filter(
                message_id=instance.message_id)

            for x in query_all_recipients:
                recipients_object = {"id": message_recipient, "deleted_from_mail_box": deleted_from_mail_box,
                                     "message_id": instance.message_id,
                                     "recipient": x.recipient_id}

                recipient_array.append(recipients_object)

            # Send the newly created message and recipients to firebase
            query_message_recipients = master_data_models.MessageRecipient.objects.filter \
                (message_id=instance.message_id).values("recipient_id")

            query_message = master_data_models.Message.objects.get(id=instance.message_id)
            creator_id = query_message.creator_id

            fcm_tokens = user_management_models.Profile.objects.filter(user_id__in=query_message_recipients)
            # creator_fcm_token = user_management_models.Profile.objects.get(user_id=creator_id)

            message_payload = {"type": "NEW_MESSAGE",
                               "data": recipient_array}

            # Send notification to creator
            # creator_fcm_token.send_message(json.dumps(message_payload))

            # Send the newly created message and recipients to firebase
            push_service = FCMNotification(api_key=settings.FCM_APIKEY)

            for x in fcm_tokens:
                registration_ids.append("" + x.reg_id + "")

            result = push_service.multiple_devices_data_message(registration_ids=registration_ids,
                                                                data_message=message_payload)

            print(result)

            return Response("Success.", status=status.HTTP_200_OK)

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def send_thread_message(request):
    if request.method == "POST":
        message_id = request.POST["message_id"]
        message = request.POST["message"]
        registration_ids = []
        recipients_array = []

        message_time_stamp = int(datetime.now().timestamp()) * 1000

        instance = master_data_models.Message()
        instance.message_date_time = datetime.now().timestamp()
        instance.message_body = message
        instance.parent_message_id = message_id
        instance.creator_id = request.user.id
        instance.save()

        query_parent_recipients = master_data_models.MessageRecipient.objects.filter(message_id=message_id)

        for x in query_parent_recipients:
            instance_recipients = master_data_models.MessageRecipient()
            instance_recipients.message_id = instance.id
            instance_recipients.recipient_id = x.recipient_id
            instance_recipients.save()

            recipients_array.append(x.recipient_id)

        # insert the creator as a recipient too
        query_original_message = master_data_models.Message.objects.get(id=message_id, parent_message_id=0)
        instance_recipients = master_data_models.MessageRecipient()

        instance_recipients.message_id = instance.id
        instance_recipients.recipient_id = query_original_message.creator_id
        instance_recipients.save()

        message_object = {"message_date_time": message_time_stamp, "creator": request.user.id, "id": message_id,
                          "message_body": "" + message + "", "message_recipients": recipients_array,
                          "parent_message_id": message_id, "subject": ""}

        message_payload = {"type": "THREAD_MESSAGE", "data": message_object}

        # Send the newly created message and recipients to firebase
        recipients = master_data_models.MessageRecipient.objects.filter(message_id=message_id).values("recipient")
        fcm_tokens = user_management_models.Profile.objects.filter(user_id__in=recipients)
        push_service = FCMNotification(api_key=settings.FCM_APIKEY)

        for x in fcm_tokens:
            registration_ids.append("" + x.reg_id + "")

        result = push_service.multiple_devices_data_message(registration_ids=registration_ids,
                                                            data_message=message_payload)
    return redirect(request.META['HTTP_REFERER'])
Beispiel #7
0
def send_notify(title, message, action, payload):
    push_service = FCMNotification(api_key=API_KEY)

    # OR initialize with proxies

    # proxy_dict = {
    #           "http"  : "http://127.0.0.1",
    #           "https" : "http://127.0.0.1",
    #         }
    # push_service = FCMNotification(api_key="<api-key>", proxy_dict=proxy_dict)

    # Your api-key can be gotten from:  https://console.firebase.google.com/project/<project-name>/settings/cloudmessaging

    # registration_id = "dHgoSI8XRc-b4oqhGiOHgu:APA91bEQVjg-ZEYOyT2LqGZGkwuE4mQStwk7wSMBWJPpqxIterzzftnleW7SQuCRspdfoIxT1E2zGcExJettfZXj9K5dtHWj8gCop3A8yfwY1XoACXmvMqhKNVV704YtEgkt345W8xNp"

    # result = push_service.notify_single_device(registration_id=registration_id,
    #                                            message_title=title,
    #                                            message_body=message)

    # Send to multiple devices by passing a list of ids.

    registration_ids = device.get_all_device_id()

    # Sending a notification with data message payload
    data_message = {
        "title": title,
        "message": message,
        "action": action,
        "payload": payload
    }
    # To multiple devices
    result = push_service.multiple_devices_data_message(
        registration_ids=registration_ids, data_message=data_message)

    print(result)
    return result
Beispiel #8
0
def fcm_send_bulk_data_messages(api_key,
                                registration_ids=None,
                                condition=None,
                                collapse_key=None,
                                delay_while_idle=False,
                                time_to_live=None,
                                restricted_package_name=None,
                                low_priority=False,
                                dry_run=False,
                                data_message=None,
                                content_available=None,
                                timeout=5,
                                json_encoder=None):
    """
    Arguments correspond to those from pyfcm/fcm.py.

    Sends push message to multiple devices,
    can send to over 1000 devices

    Args:
        api_key
        registration_ids (list): FCM device registration IDs.
        data_message (dict): Data message payload to send alone or with the notification message

    Keyword Args:
        collapse_key (str, optional): Identifier for a group of messages
            that can be collapsed so that only the last message gets sent
            when delivery can be resumed. Defaults to ``None``.
        delay_while_idle (bool, optional): If ``True`` indicates that the
            message should not be sent until the device becomes active.
        time_to_live (int, optional): How long (in seconds) the message
            should be kept in FCM storage if the device is offline. The
            maximum time to live supported is 4 weeks. Defaults to ``None``
            which uses the FCM default of 4 weeks.
        low_priority (boolean, optional): Whether to send notification with
            the low priority flag. Defaults to ``False``.
        restricted_package_name (str, optional): Package name of the
            application where the registration IDs must match in order to
            receive the message. Defaults to ``None``.
        dry_run (bool, optional): If ``True`` no message will be sent but
            request will be tested.
    Returns:
        :tuple:`multicast_id(long), success(int), failure(int), canonical_ids(int), results(list)`:
        Response from FCM server.

    Raises:
        AuthenticationError: If :attr:`api_key` is not set or provided or there is an error authenticating the sender.
        FCMServerError: Internal server error or timeout error on Firebase cloud messaging server
        InvalidDataError: Invalid data provided
        InternalPackageError: JSON parsing error, mostly from changes in the response of FCM, create a new github issue to resolve it.
    """
    push_service = FCMNotification(
        api_key=SETTINGS.get("FCM_SERVER_KEY") if api_key is None else api_key,
        json_encoder=json_encoder,
    )
    return push_service.multiple_devices_data_message(
        registration_ids=registration_ids,
        condition=condition,
        collapse_key=collapse_key,
        delay_while_idle=delay_while_idle,
        time_to_live=time_to_live,
        restricted_package_name=restricted_package_name,
        low_priority=low_priority,
        dry_run=dry_run,
        data_message=data_message,
        content_available=content_available,
        timeout=timeout)
Beispiel #9
0
class fcm(object):
    def __init__(self, config):
        self.config = config
        self.api_key = self.config.get('api_key')
        # FCM guarantees best-effort delivery with TTL 0
        self.ttl = self.config.get('ttl', 0)
        self.timeout = self.config.get('timeout', 10)
        self.default_notification = self.config.get('notification_title')
        self.proxy = None
        if 'proxy' in self.config:
            host = self.config['proxy']['host']
            port = self.config['proxy']['port']
            self.proxy = {
                'http': 'http://%s:%s' % (host, port),
                'https': 'https://%s:%s' % (host, port)
            }
        self.client = FCMNotification(api_key=self.api_key,
                                      proxy_dict=self.proxy)

    def send_push(self, message):
        # Tracking message have no target, skip sending push notification
        if 'target' not in message:
            return
        connection = db.engine.raw_connection()
        cursor = connection.cursor()
        cursor.execute(
            '''SELECT `registration_id`, `platform`
                          FROM `device` WHERE `user_id` =
                          (SELECT `id` FROM `target` WHERE `name` = %s
                          AND `type_id` = (SELECT `id` FROM `target_type` WHERE `name` = 'user'))''',
            message['target'])
        registration_ids = cursor.fetchall()
        android_ids = [
            row[0] for row in registration_ids if row[1] == 'Android'
        ]
        ios_ids = [row[0] for row in registration_ids if row[1] == 'iOS']
        invalid_ids = []
        failed_ids = []
        # Handle iOS and Android ids separately. Mobile app requires different formats for
        # correct behavior on both platforms (esp with respect to action buttons)
        if ios_ids:
            try:
                data_message = {'incident_id': message.get('incident_id')}
                response = self.client.notify_multiple_devices(
                    registration_ids=ios_ids,
                    message_title=message.get('subject',
                                              self.default_notification),
                    message_body=message.get('body', ''),
                    sound='default',
                    time_to_live=self.ttl,
                    data_message=data_message,
                    timeout=self.timeout,
                    click_action='incident')
                for idx, result in enumerate(response['results']):
                    error = result.get('error')
                    if error == 'NotRegistered':
                        invalid_ids.append(ios_ids[idx])
                    elif error is not None:
                        failed_ids.append((ios_ids[idx], error))
            except Exception:
                logger.exception('FCM request failed for message id %s',
                                 message.get('message_id'))
        if android_ids:
            try:
                data_message = {
                    'incident_id':
                    message.get('incident_id'),
                    'title':
                    message.get('subject', self.default_notification),
                    'message':
                    message.get('body', ''),
                    'actions': [{
                        'title': 'Claim',
                        'callback': 'claimIncident',
                        'foreground': True
                    }]
                }
                response = self.client.multiple_devices_data_message(
                    registration_ids=android_ids,
                    time_to_live=self.ttl,
                    data_message=data_message,
                    timeout=self.timeout)
                for idx, result in enumerate(response['results']):
                    error = result.get('error')
                    if error == 'NotRegistered':
                        invalid_ids.append(android_ids[idx])
                    elif error is not None:
                        failed_ids.append((android_ids[idx], error))
            except Exception:
                logger.exception('FCM request failed for message id %s',
                                 message.get('message_id'))
        # Clean invalidated push notification IDs
        if invalid_ids:
            cursor.execute(
                '''DELETE FROM `device` WHERE `registration_id` IN %s''',
                (invalid_ids, ))
            connection.commit()
        if failed_ids:
            logger.exception('FCM requests failed: %s', failed_ids)
        cursor.close()
        connection.close()
Beispiel #10
0
# FCM Notification을 위한 모듈. 원랜 firebase 측으로 HTTP request를 전송해야 하지만
# 어떤 개발자가 이게 불편하다고 느꼈는지 pyfcm을 만들어 두었다

fcm = FCMNotification(api_key='')
# FCM 서버 키를 통해 객체를 만들자

# 클라이언트 하나에 보내기, 여러 곳에 보내기, topic subscriber에 보내기가 대표적인 메소드다
fcm.notify_single_device(registration_id='',
                         message_title='제목이야',
                         message_body='body다')

fcm.notify_multiple_devices(registration_ids=['', ''],
                            message_title='제-목',
                            message_body='배고파')
# 여러 클라이언트에 보내는 메소드. registration_ids 파라미터로 리스트 형태의 클라이언트 키들을 전달한다

fcm.notify_topic_subscribers(topic_name='',
                             message_title='제-목',
                             message_body='body!')
# 특정 topic을 subscribe하고 있는 디바이스에 보내기

# fcm 푸쉬 메시지는 data message를 전송할 수 있다. 일반적으로 JSON이며 pyfcm 측에서는 data_message 인자로 딕셔너리를 전달하면 알아서 직렬화 처리해준다

data = {'key1': 123, 'key2': 1234}
fcm.notify_single_device(registration_id='', data_message=data)
# notify_*** 메소드에도 data_message 파라미터가 있지만, pyfcm 측에서 data messaging을 위한 메소드를 만들어 두었다

fcm.single_device_data_message(registration_id='', data_message=data)
fcm.multiple_devices_data_message(registration_ids=['', '', ''],
                                  data_message=data)
class Helpers:
    def __init__(self, flask_app):
        self.logger = flask_app.logger
        apikey = "AAAAgOfyS6s:APA91bH0GGnd4Xvw_pWMDpGmsQrR79CU8_bOmDj2QsHyrpua89dwV_UUAcJNRELByd_uikq4Hd5oI-ik6uWoW9i4w3qgtdqqg8TYKwwhAg-HllaBKoIdAy9yF1tvIGaAUvXGLtdIzTqF"  # api key from FCM for the app
        self.push_service = FCMNotification(api_key=apikey)
        self.STATUS_YES = 'Y'
        self.STATUS_NO = 'N'
        self.all_days = [
            'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday',
            'Sunday'
        ]
        self.config = json.load(open(CONFIG_PATH))
        self.client_id = self.get_config('basic', 'client_id')

    def get_config(self, *args):
        ret = self.config
        for i in range(len(args)):
            ret = ret[args[i]]
        return ret

    def build_url(self, addr, *args):
        '''
    
        :param addr: Address
        :param args: list of components in the url. Will be appended with '/'
        :return:   returns the formatted url
        '''
        comp = ''

        for i in range(len(args) - 1):
            comp += args[i] + '/'
        comp += args[len(args) - 1]

        url = urllib.parse.urljoin("http://" + addr, comp)
        logger.debug('Built url : ', url)
        return url

    def get_request(self, url, data=None):
        '''
    
        :param url: url to send the get request
        :param params: params to append to the query
        :return: response from the server
        '''
        response = None

        try:
            self.logger.debug('GET request : %s', url)
            params = json.dumps(data)
            self.logger.debug(str(params))
            response = requests.get(url, params=params)

        except Exception as e:
            print(e)

        return response

    def query_installs(self, request, cur_session):
        '''
        
        queries Install table according to all ids supplied
        in request object
        :param request: current request context
        :param cur_session: current database session object
        :returns: List of matching entries if present, None otherwise
        '''
        u_id = self.read_user_id(request.args.get('u_id', None))
        i_id = request.args.get('i_id', None)
        p_id = request.args.get('p_id', None)

        return self.get_all_installs(cur_session, u_id, i_id, p_id)

    def get_all_installs(self, cur_session, u_id=None, i_id=None, p_id=None):
        if i_id is None and p_id is None and u_id is None:
            return None

        if i_id is not None:
            cur_installs = cur_session.query(Install).filter(
                Install.install_id == i_id).all()
        elif u_id is not None:
            cur_installs = cur_session.query(Install).filter(
                Install.user_id == u_id).all()
        else:
            cur_installs = cur_session.query(Install).filter(
                Install.push_id == p_id).all()

        if len(cur_installs) == 0:
            return None
        return cur_installs

    def get_all_medications(self,
                            cur_session,
                            m_id=None,
                            m_name=None,
                            u_id=None,
                            d_id=None):
        if m_id is None and u_id is None and d_id is None and m_name is None:
            return None

        if m_id is not None:
            cur_meds = cur_session.query(Medication).filter(
                Medication.med_id == m_id).all()
        elif u_id is not None:
            cur_meds = cur_session.query(Medication).filter(
                Medication.user_id == u_id).all()
        elif m_name is not None:
            cur_meds = cur_session.query(Medication).filter(
                Medication.med_name == m_name).all()
        else:
            cur_meds = cur_session.query(Medication).filter(
                Medication.dosage_id == d_id).all()

        if len(cur_meds) == 0:
            return None
        return cur_meds

    def keygen(self, cur_session, cur_table, table_attr):
        key = np.random.randint(0, 2**31)
        prev_entry = cur_session.query(cur_table).filter(
            table_attr == key).first()
        if prev_entry is not None:
            return self.keygen(cur_session, cur_table, table_attr)
        return key

    def stringify(self, lst):
        ret = ''
        for s in lst:
            if len(s) == 0:
                continue
            ret += ',' + s
        return ret[1:]

    def send_push_notification(self, reg_id_list, data_message=None):
        '''
        : param reg_id_list: list of registration ids
        : param data_message: optional payload with custom key-value pairs
        : returns: Sends out push notification to multiple devices.response data from pyFCM 
        '''
        if len(reg_id_list) == 0:
            self.logger.debug(
                'No registration ids to send push notification to')
            return
        if len(reg_id_list) == 1:
            self.logger.debug('Making call to FCM for single Data Message...')
            try:
                result = self.push_service.single_device_data_message(
                    registration_id=reg_id_list[0], data_message=data_message)
            except Exception as e:
                self.logger.debug(e)
                return None
        else:
            self.logger.debug(
                'Making call to FCM for multiple Data Messages...')
            try:
                result = self.push_service.multiple_devices_data_message(
                    registration_ids=reg_id_list, data_message=data_message)
            except Exception as e:
                self.logger.debug(e)
                return None

        return result

    # Is there a better way to do this?
    def get_clean_data_array(self, shape):

        #        ret = np.empty(shape, dtype=object)
        # This has problems : https://stackoverflow.com/questions/33983053/how-to-create-a-numpy-array-of-lists
        #        ret.fill([])
        '''
        IMPORTANT! The first element (index 0) will be None. Use lists starting from 1
        '''

        linear_size = 1
        for s in shape:
            linear_size *= s
        ret = np.empty((linear_size, ), dtype=object)
        for i, v in enumerate(ret):
            ret[i] = list([])
        # finally, reshape the matrix
        ret = ret.reshape(shape)
        return ret

    def read_user_id(self, u_id):
        if u_id is None or u_id == '':
            return ''

        algorithm = sha2()
        algorithm.update(u_id.encode())
        return algorithm.hexdigest().upper()

    def validate_intakes(self, med, dose, cur_session):
        # Oh boy...
        validation_date = parser.parse(med.validation_date)
        start_date = validation_date + timedelta(days=1)
        med.validation_date = (datetime.now() - timedelta(days=1)).isoformat()

        intakes = cur_session.query(Intake).filter(
            Intake.med_id == med.med_id).filter(
                Intake.planned_date > validation_date).all()
        ideal_intake_dates = self.get_ideal_intake_dates(dose, start_date)
        intake_dates_present = set(
            [parser.parse(x.planned_date) for x in intakes])
        missed_intake_dates = [
            x for x in ideal_intake_dates if x not in intake_dates_present
        ]

        missed_intakes = [
            Intake(med_id=med.med_id,
                   planned_date=x.isoformat(),
                   intake_status=3) for x in missed_intake_dates
        ]

        cur_session.add_all(missed_intakes)
        cur_session.commit()

    def get_ideal_intake_dates(self, dose, start_date):
        ideal_intakes = []

        def get_prev_dosage_date(days, cur_date):
            cur_day_idx = cur_date.weekday()
            prev_day_idx = -1
            for i in range(len(days) - 1, -1, -1):
                if days[i] < cur_day_idx:
                    prev_day_idx = i
                    break
            prev_day_delta = (cur_day_idx - days[prev_day_idx] + 7) % 7
            td = timedelta(days=prev_day_delta)
            return cur_date - td

        dosage_days = [self.all_days.index(x) for x in dose.get_days()]

        ideal_times = [
            get_prev_dosage_date(dosage_days, parser.parse(tim))
            for tim in dose.get_times()
        ]
        ideal_times.reverse()
        while ideal_times[0].date() >= start_date.date():
            ideal_intakes.extend(ideal_times)
            ideal_times = [
                get_prev_dosage_date(dosage_days, tim) for tim in ideal_times
            ]

        return reversed(ideal_intakes)

    def get_intake_status(self, planned_date, actual_date):
        p_date = parser.parse(planned_date)
        a_date = parser.parse(actual_date)

        delta = time.mktime(a_date.utctimetuple()) - time.mktime(
            p_date.utctimetuple())
        four_hours = 1000 * 60 * 60 * 4

        if delta < 0:
            return 1
        elif delta > four_hours:
            return 2

        return 0
Beispiel #12
0
def fcm_send_bulk_data_messages(
            api_key,
            registration_ids=None,
            condition=None,
            collapse_key=None,
            delay_while_idle=False,
            time_to_live=None,
            restricted_package_name=None,
            low_priority=False,
            dry_run=False,
            data_message=None,
            content_available=None,
            timeout=5,
            json_encoder=None):
    """
    Arguments correspond to those from pyfcm/fcm.py.

    Sends push message to multiple devices,
    can send to over 1000 devices

    Args:
        api_key
        registration_ids (list): FCM device registration IDs.
        data_message (dict): Data message payload to send alone or with the notification message

    Keyword Args:
        collapse_key (str, optional): Identifier for a group of messages
            that can be collapsed so that only the last message gets sent
            when delivery can be resumed. Defaults to ``None``.
        delay_while_idle (bool, optional): If ``True`` indicates that the
            message should not be sent until the device becomes active.
        time_to_live (int, optional): How long (in seconds) the message
            should be kept in FCM storage if the device is offline. The
            maximum time to live supported is 4 weeks. Defaults to ``None``
            which uses the FCM default of 4 weeks.
        low_priority (boolean, optional): Whether to send notification with
            the low priority flag. Defaults to ``False``.
        restricted_package_name (str, optional): Package name of the
            application where the registration IDs must match in order to
            receive the message. Defaults to ``None``.
        dry_run (bool, optional): If ``True`` no message will be sent but
            request will be tested.
    Returns:
        :tuple:`multicast_id(long), success(int), failure(int), canonical_ids(int), results(list)`:
        Response from FCM server.

    Raises:
        AuthenticationError: If :attr:`api_key` is not set or provided or there is an error authenticating the sender.
        FCMServerError: Internal server error or timeout error on Firebase cloud messaging server
        InvalidDataError: Invalid data provided
        InternalPackageError: JSON parsing error, mostly from changes in the response of FCM, create a new github issue to resolve it.
    """
    push_service = FCMNotification(
        api_key=SETTINGS.get("FCM_SERVER_KEY") if api_key is None else api_key,
        json_encoder=json_encoder,
    )
    return push_service.multiple_devices_data_message(
        registration_ids=registration_ids,
        condition=condition,
        collapse_key=collapse_key,
        delay_while_idle=delay_while_idle,
        time_to_live=time_to_live,
        restricted_package_name=restricted_package_name,
        low_priority=low_priority,
        dry_run=dry_run,
        data_message=data_message,
        content_available=content_available,
        timeout=timeout
    )
Beispiel #13
0
def multiple_devices_data_message(registration_ids: RegistrationIds,
                                  data_message: dict, **kwargs):
    push_service = FCMNotification(api_key=settings.FCM_API_KEY)
    return push_service.multiple_devices_data_message(
        registration_ids=registration_ids, data_message=data_message, **kwargs)