123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915 |
- # -*-coding:utf-8-*-
- #
- # Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
- #
- # Licensed under the Apache License, Version 2.0 (the "License");
- # you may not use this file except in compliance with the License.
- # You may obtain a copy of the License at
- #
- # http://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing, software
- # distributed under the License is distributed on an "AS IS" BASIS,
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- # See the License for the specific language governing permissions and
- # limitations under the License.
- import numbers
- import re
- import six
- class Message(object):
- """A message that can be sent Huawei Cloud Messaging.
- Args:
- data: A string value.
- notification: An instance of ``messaging.Notification`` (optional).
- android: An instance of ``messaging.Android`` (optional).
- apns: APSN related message definition
- web_push: Web Push related message definition
- token: token list, must be tuple (optional).
- topic: message topic, must be string (optional).
- condition: message condition, must be string (optional).
- """
- def __init__(self, data=None, notification=None, android=None, apns=None, web_push=None, token=None,
- topic=None, condition=None):
- MessageValidator.check_message(data, notification, android, apns, web_push, token, topic, condition)
- self.data = data
- self.notification = notification
- self.android = android
- self.apns = apns
- self.web_push = web_push
- self.token = token
- self.topic = topic
- self.condition = condition
- class Notification(object):
- """A notification that can be included in a message.
- Args:
- title: Title of the notification (optional).
- body: Body of the notification (optional).
- """
- def __init__(self, title=None, body=None, image=None):
- MessageValidator.check_notification(title, body, image)
- self.title = title
- self.body = body
- self.image = image
- # ----------------------------------------------------------------------------------------------------------------------
- class APNsConfig(object):
- """
- Please refer to the Apple APNS API reference:
- https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/\
- CommunicatingwithAPNs.html
- """
- def __init__(self, headers=None, payload=None, apns_hms_options=None):
- MessageValidator.check_apns_config(headers=headers, payload=payload, apns_hms_options=apns_hms_options)
- self.headers = headers
- self.payload = payload
- self.apns_hms_options = apns_hms_options
- class APNsHeader(object):
- """
- authorization
- apns-id
- apns-expiration
- apns-priority
- apns-topic
- apns-collapse-id
- """
- HEAD_AUTHORIZATION = "authorization"
- HEAD_APNs_ID = "apns-id"
- HEAD_APNs_EXPIRATION = "apns-expiration"
- HEAD_APNs_PRIORITY = "apns-priority"
- HEAD_APNs_TOPIC = "pns-topic"
- HEAD_APNs_COLLAPSE_ID = "apns-collapse-id"
- class APNsPayload(object):
- """
- APNs payload definition
- """
- def __init__(self, aps, **kwargs):
- MessageValidator.check_apns_payload(aps=aps)
- self.aps = aps
- self.custom_data = kwargs
- class APNsAps(object):
- """
- APNs aps definition: https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual\
- /RemoteNotificationsPG/PayloadKeyReference.html#//apple_ref/doc/uid/TP40008194-CH17-SW1
- one sample is as follows:
- {
- "aps" : {
- "alert" : {
- "title" : "Game Request",
- "body" : "Bob wants to play poker",
- "action-loc-key" : "PLAY"
- "loc-key" : "GAME_PLAY_REQUEST_FORMAT",
- "loc-args" : [ "Jenna", "Frank"],
- "content-available" : 1
- },
- "badge" : 5,
- "sound" : "bingbong.aiff",
- },
- "acme1" : "bar",
- "acme2" : [ "bang", "whiz" ]
- }
- """
- def __init__(self, alert=None, badge=None, sound=None, content_available=None, category=None,
- thread_id=None, mutable_content=None, custom_data=None):
- MessageValidator.check_apns_payload_aps(alert=alert, badge=badge, sound=sound,
- content_available=content_available, category=category,
- thread_id=thread_id, mutable_content=mutable_content,
- custom_data=custom_data)
- self.alert = alert
- self.badge = badge
- self.sound = sound
- self.content_available = content_available
- self.category = category
- self.thread_id = thread_id
- self.mutable_content = mutable_content
- self.custom_data = custom_data
- class APNsAlert(object):
- """An alert that can be included in ``messaging.Aps``.
- Args:
- """
- def __init__(self, title=None, body=None, loc_key=None, loc_args=None,
- title_loc_key=None, title_loc_args=None, action_loc_key=None, launch_image=None,
- custom_data=None):
- MessageValidator.check_apns_payload_aps_alert(title=title, body=body, loc_key=loc_key, loc_args=loc_args,
- title_loc_key=title_loc_key, title_loc_args=title_loc_args,
- action_loc_key=action_loc_key, launch_image=launch_image,
- custom_data=custom_data)
- self.title = title
- self.body = body
- self.loc_key = loc_key
- self.loc_args = loc_args
- self.title_loc_key = title_loc_key
- self.title_loc_args = title_loc_args
- self.action_loc_key = action_loc_key
- self.launch_image = launch_image
- self.custom_data = custom_data
- class APNsHMSOptions(object):
- """Options for features provided by the FCM SDK for iOS.
- Args:
- target_user_type: Developer or Commercial enviroment
- """
- def __init__(self, target_user_type=None):
- MessageValidator.check_apns_hms_options(target_user_type=target_user_type)
- self.target_user_type = target_user_type
- # ----------------------------------------------------------------------------------------------------------------------
- class WebPushConfig(object):
- """
- Web push-specific options that can be included in a message.
- For Web Push Specification Reference: https://tools.ietf.org/html/rfc8030#section-5
- For mozilla implementation: https://developer.mozilla.org/en-US/docs/Web/API/notification
- """
- TTL_HEADER = "ttl"
- URGENCY_HEADER = "urgency"
- TOPIC_HEADER = "topic"
- def __init__(self, headers=None, data=None, notification=None, hms_options=None):
- """
- :param headers: A dictionary of headers (optional). Refer `Web push Specification`_ for supported headers.
- :param notification: A ``messaging.WebPushNotification`` to be included in the message (optional).
- :param hms_options: A ``WebPushHMSOptions`` instance to be included in the message(optional).
- """
- MessageValidator.check_webpush_config(headers, data, notification, hms_options)
- """ Refer to https://tools.ietf.org/html/rfc7240 """
- self.headers = headers
- """ message deliver to the end application directly """
- self.data = data
- """ Refer to WebPushNotification """
- self.notification = notification
- """ Refer to WebPushHMSOptions"""
- self.hms_options = hms_options
- class WebPushHeader(object):
- """
- Web Push Header, refer to: https://tools.ietf.org/html/rfc7240
- """
- def __init__(self, ttl=None, urgency=None, topic=None):
- MessageValidator.check_webpush_header(ttl, urgency, topic)
- self.ttl = ttl
- self.urgency = urgency
- self.topic = topic
- class WebPushNotification(object):
- """
- Web Push Notification
- """
- def __init__(self, title=None, body=None, icon=None, actions=None, badge=None, data=None, dir=None,
- image=None, lang=None, renotify=None, require_interaction=None, silent=None, tag=None,
- timestamp=None, vibrate=None):
- MessageValidator.check_webpush_notification(title=title, body=body, icon=icon, actions=actions, badge=badge,
- data=data, dir=dir, image=image, lang=lang,
- renotify=renotify, require_interaction=require_interaction,
- silent=silent, tag=tag, timestamp=timestamp, vibrate=vibrate)
- self.title = title
- self.body = body
- """ Refer to WebPushNotificationAction """
- self.actions = actions
- self.badge = badge
- self.data = data
- self.dir = dir
- self.icon = icon
- self.image = image
- self.lang = lang
- self.renotify = renotify
- self.require_interaction = require_interaction
- self.silent = silent
- self.tag = tag
- self.timestamp = timestamp
- self.vibrate = vibrate
- class WebPushNotificationAction(object):
- """
- The action for web push notification
- """
- def __init__(self, action=None, title=None, icon=None):
- """
- :param action:
- :param title:
- :param icon:
- """
- MessageValidator.check_webpush_notification_action(action=action, title=title, icon=icon)
- self.action = action
- self.icon = icon
- self.title = title
- class WebPushHMSOptions(object):
- """
- optional link option
- """
- def __init__(self, link=None):
- MessageValidator.check_webpush_hms_options(link)
- self.link = link
- # ----------------------------------------------------------------------------------------------------------------------
- class AndroidConfig(object):
- HIGH_PRIORITY = "HIGH"
- NORMAL_PRIORITY = "NORMAL"
- """
- Android-specific options that can be included in a message.
- """
- def __init__(self, collapse_key=None, urgency='NORMAL', ttl=None, bi_tag=None
- , fast_app_target=None, notification=None, data=None, category=None):
- MessageValidator.check_android_config(collapse_key, urgency, ttl, bi_tag, fast_app_target
- , notification, data)
- self.collapse_key = collapse_key
- self.urgency = urgency
- self.ttl = ttl
- self.bi_tag = bi_tag
- self.fast_app_target = fast_app_target
- self.notification = notification
- self.data = data
- self.category = category
- class AndroidNotification(object):
- PRIORITY_LOW = "LOW"
- PRIORITY_DEFAULT = "NORMAL"
- PRIORITY_HIGH = "HIGH"
- VISIBILITY_UNSPECIFIED = "VISIBILITY_UNSPECIFIED"
- PRIVATE = "PRIVATE"
- PUBLIC = "PUBLIC"
- SECRET = "SECRET"
- """
- Android-specific notification parameters.
- """
- def __init__(self, title=None, body=None, icon=None, color=None, sound=None, default_sound=None, tag=None,
- click_action=None, body_loc_key=None, body_loc_args=None, title_loc_key=None,
- title_loc_args=None, multi_lang_key=None, channel_id=None, notify_summary=None, image=None,
- style=None, big_title=None, big_body=None, auto_clear=None, notify_id=None, group=None, badge=None,
- ticker=None, auto_cancel=None, when=None, importance=None, use_default_vibrate=True,
- use_default_light=True, vibrate_config=None, visibility=None, light_settings=None, foreground_show=False):
- MessageValidator.check_android(title=title, body=body, icon=icon, color=color, sound=sound,
- default_sound=default_sound, tag=tag, click_action=click_action,
- body_loc_key=body_loc_key, body_loc_args=body_loc_args,
- title_loc_key=title_loc_key, title_loc_args=title_loc_args,
- multi_lang_key=multi_lang_key, channel_id=channel_id,
- notify_summary=notify_summary,
- image=image, style=style, big_title=big_title, big_body=big_body,
- auto_clear=auto_clear, notify_id=notify_id,
- group=group, badge=badge, ticker=ticker, auto_cancel=auto_cancel, when=when,
- importance=importance,
- use_default_vibrate=use_default_vibrate,
- use_default_light=use_default_light, vibrate_config=vibrate_config,
- visibility=visibility, light_settings=light_settings,
- foreground_show=foreground_show)
- self.title = title
- self.body = body
- self.icon = icon
- self.color = color
- self.sound = sound
- self.default_sound = default_sound
- self.tag = tag
- self.click_action = click_action
- self.body_loc_key = body_loc_key
- self.body_loc_args = body_loc_args
- self.title_loc_key = title_loc_key
- self.title_loc_args = title_loc_args
- self.multi_lang_key = multi_lang_key
- self.channel_id = channel_id
- self.notify_summary = notify_summary
- self.image = image
- self.style = style
- self.big_title = big_title
- self.big_body = big_body
- self.auto_clear = auto_clear
- self.notify_id = notify_id
- self.group = group
- self.badge = badge
- self.ticker = ticker
- self.auto_cancel = auto_cancel
- self.when = when
- self.importance = importance
- self.use_default_vibrate = use_default_vibrate
- self.use_default_light = use_default_light
- self.vibrate_config = vibrate_config
- self.visibility = visibility
- self.light_settings = light_settings
- self.foreground_show = foreground_show
- class AndroidClickAction(object):
- """A ClickAction that can be included in a message.android.notification.
- Args:
- action_type: type of the android.notification (optional).
- intent: intent of the android.notification (optional).
- url: url of the android.notification (optional).
- action: action definition for push message
- 1: to specific activity of application
- 2: specific URL
- 3: to specific application
- """
- def __init__(self, action_type=None, intent=None, action=None, url=None):
- MessageValidator.check_click_action(action_type=action_type, intent=intent, action=action, url=url)
- self.action_type = action_type
- self.intent = intent
- self.action = action
- self.url = url
- class AndroidBadgeNotification(object):
- """A BadgeNotification that can be included in a message.android.notification.
- Args:
- add_num: message number of badge notification in the android.notification (optional).
- set_num: set the specific number of badge notification (optional).
- clazz: message class of badge notification in the android.notification (optional).
- """
- def __init__(self, add_num=None, set_num=None, clazz=None):
- MessageValidator.check_badge_notification(add_num=add_num, set_num=set_num, clazz=clazz)
- self.add_num = add_num
- self.set_num = set_num
- self.clazz = clazz
- class AndroidLightSettings(object):
- """
- light_settings":{
- "color":{
- "alpha":0,
- "red":0,
- "green":1,
- "blue":1
- },
- "light_on_duration":"3.5",
- "light_off_duration":"5S"
- }
- """
- def __init__(self, color=None, light_on_duration=None, light_off_duration=None):
- MessageValidator.check_light_settings(color=color, light_on_duration=light_on_duration, light_off_duration=light_off_duration)
- self.color = color
- self.light_on_duration = light_on_duration
- self.light_off_duration = light_off_duration
- class AndroidLightSettingsColor(object):
- """
- "color":{
- "alpha":0,
- "red":0,
- "green":1,
- "blue":1
- }
- """
- def __init__(self, alpha=None, red=None, green=None, blue=None):
- MessageValidator.check_light_settings_color(alpha=alpha, red=red, green=green, blue=blue)
- self.alpha = alpha
- self.red = red
- self.green = green
- self.blue = blue
- # --------------------------------------------------------------------------------------------------------------------
- class MessageValidator(object):
- """
- message validation utilities.
- Methods provided in this class raise ValueErrors if any validations fail.
- """
- @classmethod
- def check_https_url(cls, hint, value):
- cls.check_string(hint, value)
- if value is not None and not re.match(r"^https:/{2}\w.+$", value):
- raise ValueError('{0} must be a valid https url.'.format(hint))
- @classmethod
- def check_string(cls, hint, value, non_empty=False):
- """Checks if the given value is a string."""
- if value is None:
- return None
- if not isinstance(value, six.string_types):
- if non_empty:
- raise ValueError('{0} must be a non-empty string.'.format(hint))
- else:
- raise ValueError('{0} must be a string.'.format(hint))
- if non_empty and not value:
- raise ValueError('{0} must be a non-empty string.'.format(hint))
- return value
- @classmethod
- def assert_string_values(cls, hint, value, *args):
- """
- Check the class value should be an instance of string, and related values should be within *args
- :param hint: prompt message
- :param value: the real value
- :param args: the specific value list
- :return:
- """
- if value is None:
- return None
- if not isinstance(value, six.string_types):
- raise ValueError('{0} must be a string.'.format(hint))
- for v in args:
- if value.__eq__(v):
- return value
- raise ValueError('{} must be a value within{}.'.format(hint, args))
- @classmethod
- def check_string_list(cls, label, value):
- """Checks if the given value is a list comprised only of strings."""
- if value is None or value == []:
- return None
- if not isinstance(value, list):
- raise ValueError('{0} must be a list of strings.'.format(label))
- non_str = [k for k in value if not isinstance(k, six.string_types)]
- if non_str:
- raise ValueError('{0} must not contain non-string values.'.format(label))
- return value
- @classmethod
- def check_boolean(cls, hint, value):
- """Checks if the given value is a string."""
- if value is None:
- return None
- if not isinstance(value, bool):
- raise ValueError('{0} must be a boolean.'.format(hint))
- return value
- @classmethod
- def count_boolean(cls, *args):
- count = 0
- for v in args:
- if v:
- count += 1
- return count
- @classmethod
- def check_not_all_none(cls, hint, *args):
- total_size = len(args)
- count = 0
- for data in args:
- if data is None:
- count += 1
- if total_size == count:
- raise ValueError(hint)
- @classmethod
- def check_type(cls, class_obj, class_type, hint):
- if (class_obj is not None) and (not isinstance(class_obj, class_type)):
- raise ValueError(hint)
- @classmethod
- def check_type_list(cls, label, value, cls_type):
- """Checks if the given value is a list comprised only of numbers."""
- if value is None or value == []:
- return None
- if not isinstance(value, list):
- raise ValueError('{0} must be a list of {1}.'.format(label, cls_type))
- non_number = [k for k in value if not isinstance(k, cls_type)]
- if non_number:
- raise ValueError('{0} must not contain non-{1} values.'.format(label, cls_type))
- return value
- @classmethod
- def check_number(cls, label, value):
- if value is None:
- return None
- if not isinstance(value, numbers.Number):
- raise ValueError('{0} must be a number.'.format(label))
- return value
- @classmethod
- def check_number_span(cls, label, value, min, max):
- if value is None:
- return None
- if not isinstance(value, numbers.Number):
- raise ValueError('{0} must be a number.'.format(label))
- if value < min or value > max:
- raise ValueError('{0} must be within {1} to {2}.'.format(label, min, max))
- return value
- @classmethod
- def assert_integer_values(cls, hint, value, *args):
- """
- Check the class value should be an instance of string, and related values should be within *args
- :param hint: prompt message
- :param value: the real value
- :param args: the specific value list
- :return:
- """
- if value is None:
- return None
- if not isinstance(value, six.integer_types):
- raise ValueError('{0} must be a integer.'.format(hint))
- for v in args:
- if value == v:
- return value
- raise ValueError('{} must be a value within{}.'.format(hint, args))
- @classmethod
- def check_number_list(cls, label, value):
- if value is None or value == []:
- return None
- if not isinstance(value, list):
- raise ValueError('{0} must be a list of numbers.'.format(label))
- non_number = [k for k in value if not isinstance(k, numbers.Number)]
- if non_number:
- raise ValueError('{0} must not contain non-number values.'.format(label))
- return value
- @classmethod
- def check_string_dict(cls, label, value):
- if value is None or value == {}:
- return None
- if not isinstance(value, dict):
- raise ValueError('{0} must be a dictionary.'.format(label))
- non_str = [k for k in value if not isinstance(k, six.string_types)]
- if non_str:
- raise ValueError('{0} must not contain non-string keys.'.format(label))
- return value
- # ------------------------------------------------------------------------------------------------------------------
- @classmethod
- def check_message(cls, data, notification, android, apns, web_push, token, topic, condition):
- """
- Check whether the message parameter is valid or not
- :param data:
- :param notification:
- :param android:
- :param apns:
- :param web_push:
- :param token:
- :param topic:
- :param condition:
- :return:
- """
- # data must be string
- cls.check_string(hint="Message.data", value=data)
- # notification
- if (notification is not None) and (not isinstance(notification, Notification)):
- raise ValueError('notification must be an instance of Notification class')
- # android / APNs / Web Push
- # if notification message(data is None), one of android / APNs / Web Push must be present
- if data is None:
- cls.check_not_all_none('Message.data is None, one of Message.android/Message.apns/Message.webpush \
- must be present', android, apns, web_push)
- cls.check_type(android, AndroidConfig, 'android must be an instance of AndroidConfig class')
- cls.check_type(apns, APNsConfig, 'apns must be an instance of APNsConfig class')
- cls.check_type(web_push, WebPushConfig, 'web_push must be an instance of WebPushConfig class')
- """token, topic, condition"""
- # [token, topic, condition] only one not None
- target_count = cls.count_boolean(token is not None, topic is not None, condition is not None)
- if target_count != 1:
- raise ValueError('Exactly one of token, topic or condition must be specified.')
- # token must be tuple or list
- if token is not None:
- if not isinstance(token, tuple) and not isinstance(token, list):
- raise ValueError('token must be a tuple or a list')
- if len(token) > 1000:
- raise ValueError('token must not contain more than 1000 tokens')
- cls.check_string(hint="Message.topic", value=topic)
- cls.check_string(hint="Message.condition", value=condition)
- @classmethod
- def check_notification(cls, title, body, image):
- cls.check_string(hint="Notification.title", value=title)
- cls.check_string(hint="Notification.body", value=body)
- cls.check_https_url(hint="Notification.image", value=image)
- @classmethod
- def check_android_config(cls, collapse_key, urgency, ttl, bi_tag, fast_app_target, notification, data):
- # collapse_key
- cls.check_number('AndroidConfig.collapse_key', collapse_key)
- # urgency
- cls.assert_string_values("AndroidConfig.urgency", urgency, AndroidConfig.HIGH_PRIORITY,
- AndroidConfig.NORMAL_PRIORITY)
- # ttl
- cls.check_string(hint="AndroidConfig.ttl", value=ttl)
- # bi_tag
- cls.check_string(hint="AndroidConfig.bi_tag", value=bi_tag)
- # fast_app_target
- cls.check_number_span("AndroidConfig.fast_app_target", fast_app_target, 1, 2)
- # notification
- cls.check_type(notification, AndroidNotification,
- hint='notification must be an instance of AndroidNotification')
- # data
- cls.check_string(hint="AndroidConfig.data", value=data)
- @classmethod
- def check_android(cls, title, body, icon, color, sound, default_sound, tag, click_action, body_loc_key, body_loc_args,
- title_loc_key, title_loc_args, multi_lang_key, channel_id, notify_summary, image,
- style, big_title, big_body, auto_clear, notify_id, group, badge,
- ticker, auto_cancel, when, importance,
- use_default_vibrate, use_default_light, vibrate_config, visibility, light_settings,
- foreground_show):
- # title
- cls.check_string(hint="AndroidNotification.title", value=title)
- # body
- cls.check_string(hint="AndroidNotification.body", value=body)
- # icon
- cls.check_string(hint="AndroidNotification.icon", value=icon)
- # color
- cls.check_string(hint="AndroidNotification.color", value=color)
- # sound
- cls.check_string(hint="AndroidNotification.sound", value=sound)
- # default_sound
- cls.check_boolean(hint="AndroidNotification.default_sound", value=default_sound)
- # tag
- cls.check_string(hint="AndroidNotification.tag", value=tag)
- # click_action
- cls.check_type(click_action, AndroidClickAction,
- hint='click_action must be an instance of AndroidClickAction')
- # body_loc_key
- cls.check_string(hint="AndroidNotification.body_loc_key", value=body_loc_key)
- # body_loc_args
- if (body_loc_args is not None) and (not isinstance(body_loc_args, tuple)) and (not isinstance(body_loc_args, list)):
- raise ValueError('AndroidNotification.body_loc_args must be an instance of tuple or list')
- # title_loc_key
- cls.check_string(hint="AndroidNotification.title_loc_key", value=title_loc_key)
- # title_loc_args
- if (title_loc_args is not None) and (not isinstance(title_loc_args, tuple) and not isinstance(title_loc_args, list)):
- raise ValueError('AndroidNotification.title_loc_args must be an instance of tuple or list')
- # multi_lang_key
- if multi_lang_key is not None:
- if not isinstance(multi_lang_key, dict):
- raise ValueError('AndroidNotification.multi_lang_key must be a dict.')
- # channel_id
- cls.check_string(hint="AndroidNotification.channel_id", value=channel_id)
- # notify_summary
- cls.check_string(hint="AndroidNotification.notify_summary", value=notify_summary)
- #
- # image
- cls.check_https_url(hint="AndroidNotification.image", value=image)
- # style
- if style is not None:
- if style not in [0, 1, 2]:
- raise ValueError('AndroidNotification.style must in [0, 1, 2]')
- # big_title, big_body
- if style == 1:
- if (big_title is None) or (not isinstance(big_title, str)):
- raise ValueError('AndroidNotification.big_title must be valid string when style is 1')
- if (big_body is None) and (not isinstance(big_body, str)):
- raise ValueError('AndroidNotification.big_body must be valid string when style is 1')
- # auto_clear
- cls.check_number(label='AndroidNotification.auto_clear ', value=auto_clear)
- # notify_id
- cls.check_number(label='AndroidNotification.notify_id ', value=notify_id)
- # group
- cls.check_string(hint="AndroidNotification.group", value=group)
- # badge
- cls.check_type(badge, AndroidBadgeNotification, "badge should be an instance of AndroidBadgeNotification")
- # ticker
- cls.check_string(hint="AndroidNotification.ticker", value=ticker)
- # auto_cancel
- cls.check_boolean(hint="AndroidNotification.auto_cancel", value=auto_cancel)
- # when
- cls.check_string(hint="AndroidNotification.when", value=when)
- # importance
- cls.assert_string_values("AndroidNotification.importance", importance,
- AndroidNotification.PRIORITY_DEFAULT,
- AndroidNotification.PRIORITY_HIGH, AndroidNotification.PRIORITY_LOW)
- # use_default_vibrate
- cls.check_boolean(hint="AndroidNotification.use_default_vibrate", value=use_default_vibrate)
- # use_default_light
- cls.check_boolean(hint="AndroidNotification.use_default_light", value=use_default_light)
- # vibrate_config
- cls.check_string_list(label="AndroidNotification.vibrate_config", value=vibrate_config)
- # visibility
- cls.assert_string_values("AndroidNotification.visibility", visibility,
- AndroidNotification.PRIVATE,
- AndroidNotification.PUBLIC, AndroidNotification.SECRET,
- AndroidNotification.VISIBILITY_UNSPECIFIED)
- # light_settings
- cls.check_type(light_settings, AndroidLightSettings, "light_settings should be an instance of AndroidLightSettings")
- # foreground_show
- cls.check_boolean(hint="AndroidNotification.foreground_show", value=foreground_show)
- @classmethod
- def check_badge_notification(cls, add_num, set_num, clazz):
- # add_num must be int
- cls.check_number_span(label="AndroidBadgeNotification.add_num", value=add_num, min=0, max=100)
- # set_num must be int
- cls.check_number_span(label="AndroidBadgeNotification.set_num", value=set_num, min=0, max=100)
- # clazz
- cls.check_string(hint="AndroidBadgeNotification.clazz", value=clazz)
- @classmethod
- def check_click_action(cls, action_type, intent, action, url):
- # type must be in [1, 4]
- if (action_type is None) or (action_type not in [1, 2, 3, 4]):
- raise ValueError('ClickAction.type must be in [1, 2, 3, 4]')
- # intent, if type is 1, intent or action must be present or both
- if action_type == 1:
- count = cls.count_boolean(isinstance(intent, str), isinstance(action, str))
- if count <= 0:
- raise ValueError('ClickAction.intent or ClickAction.action must be present or both when click_type is 1')
- # url, if type is 2, url must
- if action_type == 2:
- if not isinstance(url, str):
- raise ValueError('ClickAction.url must when ClickAction.type is 2')
- if not url.upper().startswith('HTTPS'):
- raise ValueError('ClickAction.url must be https prefix when ClickAction.type is 2')
- @classmethod
- def check_light_settings(cls, color, light_on_duration, light_off_duration):
- cls.check_type(color, AndroidLightSettingsColor, "color must be an instance of AndroidLightSettingsColor")
- cls.check_string(hint="AndroidLightSettings.light_on_duration", value=light_on_duration)
- cls.check_string(hint="AndroidLightSettings.light_off_duration", value=light_off_duration)
- @classmethod
- def check_light_settings_color(cls, alpha, red, green, blue):
- cls.check_number("AndroidLightSettingsColor.alpha", alpha)
- cls.check_number("AndroidLightSettingsColor.red", red)
- cls.check_number("AndroidLightSettingsColor.green", green)
- cls.check_number("AndroidLightSettingsColor.blue", blue)
- @classmethod
- def check_webpush_config(cls, headers, data, notification, hms_options):
- # headers
- cls.check_type(headers, WebPushHeader, "headers must be an instance of WebPushHeader")
- cls.check_string(hint="WebPushConfig.headers", value=data)
- cls.check_type(notification, WebPushNotification, "notification must be an instance of WebPushNotification")
- cls.check_type(hms_options, WebPushHMSOptions, "hms_options must be an instance of WebPushHMSOptions")
- @classmethod
- def check_webpush_header(cls, ttl=None, urgency=None, topic=None):
- cls.check_string(hint="WebPushHeader.ttl", value=ttl)
- cls.check_string(hint="WebPushHeader.urgency", value=urgency)
- cls.check_string(hint="WebPushHeader.topic", value=topic)
- @classmethod
- def check_webpush_notification(cls, title=None, body=None, icon=None, actions=None, badge=None,
- data=None, dir=None, image=None, lang=None, renotify=None,
- require_interaction=None, silent=None, tag=None, timestamp=None, vibrate=None):
- cls.check_string(hint="WebPushNotification.title", value=title)
- cls.check_string(hint="WebPushNotification.body", value=body)
- cls.check_string(hint="WebPushNotification.icon", value=icon)
- cls.check_string(hint="WebPushNotification.data", value=data)
- cls.check_type_list("WebPushNotificationAction.actions", actions, WebPushNotificationAction)
- cls.check_string(hint="WebPushNotification.image", value=image)
- cls.check_string(hint="WebPushNotification.lang", value=lang)
- cls.check_string(hint="WebPushNotification.tag", value=tag)
- cls.check_string(hint="WebPushNotification.badge", value=badge)
- cls.assert_string_values("WebPushNotification.dir", dir, "auto", "ltr", "rtl")
- cls.check_number_list("WebPushNotification.vibrate", vibrate)
- cls.check_boolean("WebPushNotification.renotify", renotify)
- cls.check_boolean("WebPushNotification.require_interaction", require_interaction)
- cls.check_boolean("WebPushNotification.silent", silent)
- cls.check_number("WebPushNotification.timestamp", timestamp)
- @classmethod
- def check_webpush_notification_action(cls, action=None, title=None, icon=None):
- cls.check_string(hint="WebPushNotificationAction.action", value=action)
- cls.check_string(hint="WebPushNotificationAction.title", value=title)
- cls.check_string(hint="WebPushNotificationAction.icon", value=icon)
- @classmethod
- def check_webpush_hms_options(cls, link):
- cls.check_string(hint="WebPushHMSOptions.link", value=link)
- @classmethod
- def check_apns_config(cls, headers=None, payload=None, apns_hms_options=None):
- cls.check_string_dict("APNsConfig.headers", headers)
- cls.check_type(payload, APNsPayload, "payload must be an instance of APNsPayload")
- cls.check_type(apns_hms_options, APNsHMSOptions, "apns_hms_options must be an instance of APNsHMSOptions")
- @classmethod
- def check_apns_payload(cls, aps=None):
- cls.check_type(aps, APNsAps, "aps must be an instance of APNsAps")
- pass
- @classmethod
- def check_apns_payload_aps(cls, alert, badge, sound, content_available, category, thread_id, mutable_content,
- custom_data):
- # alert: Dictionary or String
- if alert is not None:
- if not isinstance(alert, six.string_types):
- cls.check_type(alert, APNsAlert, "alert must be an instance of String or APNsAlert class")
- # badge: Number
- cls.check_number("APNsAps.badge", badge)
- # sound: String
- cls.check_string("APNsAps.sound", sound)
- # content_available: number
- cls.check_number("APNsAps.content_available", content_available)
- # category: String
- cls.check_string("APNsAps.category", category)
- # thread_id: String
- cls.check_string("APNsAps.thread_id", thread_id)
- # mutable_content
- cls.check_boolean("APNsAps.mutable_content", mutable_content)
- # custom_data
- if custom_data is not None:
- if not isinstance(custom_data, dict):
- raise ValueError('APNsAps.custom_data must be a dict.')
- @classmethod
- def check_apns_payload_aps_alert(cls, title, body, loc_key, loc_args, title_loc_key, title_loc_args, action_loc_key,
- launch_image, custom_data):
- # title: String
- cls.check_string("APNsAlert.title", title)
- # body: String
- cls.check_string("APNsAlert.body", body)
- # loc_key: String
- cls.check_string("APNsAlert.loc_key", loc_key)
- # loc_args: Array of strings
- cls.check_string_list("APNsAlert.loc_args", loc_args)
- # title_loc_key: String or null
- cls.check_string("APNsAlert.title_loc_key", title_loc_key)
- # title_loc_args: Array of strings or null
- cls.check_string_list("APNsAlert.title_loc_args", title_loc_args)
- # action_loc_key: String or null
- cls.check_string("APNsAlert.action_loc_key", action_loc_key)
- # launch_image: String
- cls.check_string("APNsAlert.launch_image", launch_image)
- # custom_data
- if custom_data is not None:
- if not isinstance(custom_data, dict):
- raise ValueError('APNsAlert.custom_data must be a dict.')
- @classmethod
- def check_apns_hms_options(cls, target_user_type):
- cls.assert_integer_values("APNsHMSOptions.target_user_type", target_user_type, 1, 2, 3)
|