class AddressPrefixProviderSettingMiddlewareConfig(BaseMiddlewareConfig): """ Config for the address prefix provider setting middleware. """ class ConfigNormalizeMsisdn(ConfigDict): def clean(self, value): if 'country_code' not in value: self.raise_config_error( "does not contain the `country_code` key.") if 'strip_plus' not in value: value['strip_plus'] = False return super(self.__class__, self).clean(value) provider_prefixes = ConfigDict( "Mapping from address prefix to provider value. Longer prefixes are " "checked first to avoid ambiguity. If no prefix matches, the provider" " value will be set to ``None``.", required=True, static=True) normalize_msisdn = ConfigNormalizeMsisdn( "Optional MSISDN normalization config. If present, this dict should " "contain a (mandatory) ``country_code`` field and an optional boolean " "``strip_plus`` field (default ``False``). If absent, the " "``from_addr`` field will not be normalized prior to the prefix check." " (This normalization is only used for the prefix check. The " "``from_addr`` field on the message is not modified.)", static=True)
class ApiSiteConfig(Config): BACKENDS = { "memory": MemoryOptOutBackend, "riak": RiakOptOutBackend, } backend = ConfigText("Optout backend to use. One of 'memory' or 'riak'", required=True) backend_config = ConfigDict("Configuration for backend.", default={}) auth_bouncer_url = ConfigText( "URL to bounce requests to for authentication", default=None) url_path_prefix = ConfigText("URL path prefix for the optout API.", default="optouts") def post_validate(self): if self.backend not in self.BACKENDS: self.raise_config_error("Backend must be one of: %s" % ", ".join(self.BACKENDS.keys())) def create_backend(self): return self.BACKENDS[self.backend].from_config(self.backend_config) def create_auth(self): if self.auth_bouncer_url: return BouncerAuth(self.auth_bouncer_url) return RequestHeaderAuth()
class AddressTranslatorMiddlewareConfig(BaseMiddlewareConfig): """ Configuration class for the address translator middleware. """ outbound_map = ConfigDict( "Mapping of old ``to_addr`` values to new ``to_addr`` values", required=True, static=True)
class SessionLengthMiddlewareConfig(BaseMiddlewareConfig): """ Configuration class for the session length middleware. """ redis = ConfigDict("Redis config", default={}, static=True) timeout = ConfigInt("Redis key timeout (secs)", default=600, static=True) field_name = ConfigText( "Field name in message helper_metadata", default="session", static=True)
class BaseRouterWorkerConfig(BaseWorker.CONFIG_CLASS): destinations = ConfigList( "The list of configs for the configured destinations of this router", required=True, static=True) redis_manager = ConfigDict( "Redis config.", required=True, static=True) inbound_ttl = ConfigInt( "Maximum time (in seconds) allowed to reply to messages", required=True, static=True) outbound_ttl = ConfigInt( "Maximum time (in seconds) allowed for events to arrive for messages", required=True, static=True) metric_window = ConfigFloat( "Size of the buckets to use (in seconds) for metrics", required=True, static=True)
class SessionLengthMiddlewareConfig(BaseMiddlewareConfig): """ Configuration class for the session length middleware. """ redis_manager = ConfigDict("Redis config", default={}, static=True) timeout = ConfigInt("Redis key timeout (secs)", default=600, static=True) namespace_type = ConfigText( "Namespace to use to lookup and set the (address, timestamp) " "key-value pairs in redis. Possible types: " " - transport_name: the message's `transport_name` field is used." " - tag: the tag associated to the message is used. *Note*: this " " requires the `TaggingMiddleware` to be earlier in the " " middleware chain.", default='transport_name', static=True) field_name = ConfigText("Field name in message helper_metadata", default="session", static=True)
class StoringMiddlewareConfig(BaseMiddlewareConfig): """ Config class for the storing middleware. """ store_prefix = ConfigText( "Prefix for message store keys in key-value store.", default='message_store', static=True) redis_manager = ConfigDict("Redis configuration parameters", default={}, static=True) riak_manager = ConfigRiak( "Riak configuration parameters. Must contain at least a bucket_prefix" " key", required=True, static=True) store_on_consume = ConfigBool( "``True`` to store consumed messages as well as published ones, " "``False`` to store only published messages.", default=True, static=True)
class JunebugConfig(Config): interface = ConfigText( "Interface to expose the API on", default='localhost') port = ConfigInt( "Port to expose the API on", default=8080) logfile = ConfigText( "File to log to or `None` for no logging", default=None) sentry_dsn = ConfigText( "DSN to send exceptions", default=None) redis = ConfigDict( "Config to use for redis connection", default={ 'host': 'localhost', 'port': 6379, 'db': 0, 'password': None }) amqp = ConfigDict( "Config to use for amqp connection", default={ 'hostname': '127.0.0.1', 'vhost': '/', 'port': 5672, 'db': 0, 'username': '******', 'password': '******' }) inbound_message_ttl = ConfigInt( "Maximum time (in seconds) allowed to reply to messages", default=60 * 10) outbound_message_ttl = ConfigInt( "Maximum time (in seconds) allowed for events to arrive for messages", default=60 * 60 * 24 * 2) allow_expired_replies = ConfigBool( "If `True` messages with a reply_to that arrive for which the " "original inbound cannot be found (possible of the TTL expiring) are " "sent as normal outbound messages. ", default=False) channels = ConfigDict( "Mapping between channel types and python classes.", default={}) replace_channels = ConfigBool( "If `True`, replaces the default channels with `channels`. If `False`," " `channels` is added to the default channels.", default=False) routers = ConfigDict( "Mapping between router types and python classes.", default={}) replace_routers = ConfigBool( "If `True`, replaces the default routers with `routers`. If `False`," "`routers` is added to the default routers.", default=False) plugins = ConfigList( "A list of dictionaries describing all of the enabled plugins. Each " "item should have a `type` key, with the full python class name of " "the plugin.", default=[]) metric_window = ConfigFloat( "The size of the buckets (in seconds) used for metrics.", default=10.0) logging_path = ConfigText( "The path to place log files in.", default="logs/") log_rotate_size = ConfigInt( "The maximum size (in bytes) of a log file before it gets rotated.", default=1000000) max_log_files = ConfigInt( "The maximum amount of log files allowed before old files start to " "get deleted. 0 is unlimited.", default=5) max_logs = ConfigInt( "The maximum amount of logs that is allowed to be retrieved via the " "API.", default=100) rabbitmq_management_interface = ConfigText( "This should be the url string of the rabbitmq management interface." "If set, the health of each individual queue will be checked. " "This is only available for RabbitMQ", default=None)
class VoiceServerTransportConfig(Transport.CONFIG_CLASS): """ Configuration parameters for the voice transport """ to_addr = ConfigText("The ``to_addr`` to use for inbound messages.", default="freeswitchvoice", static=True) tts_type = ConfigText( "Either 'freeswitch' or 'local' to specify where TTS is executed.", default="freeswitch", static=True) tts_fs_engine = ConfigText( "Specify Freeswitch TTS engine to use (only affects tts_type" " 'freeswitch').", default="flite", static=True) tts_fs_voice = ConfigText( "Specify Freeswitch TTS voice to use (only affects tts_type" " 'freeswitch').", default="kal", static=True) tts_local_command = ConfigText( "Specify command template to use for generating voice files (only" " affects tts_type 'local'). E.g. 'flite -o {filename} -t {text}'." " Command parameters are split on whitespace (no shell-like escape" " processing is performed on the command).", default=None, static=True) tts_local_cache = ConfigText( "Specify folder to cache voice files (only affects tts_type" " 'local').", default=".", static=True) tts_local_ext = ConfigText( "Specify the file extension used for cached voice files (only affects" " tts_type 'local').", default="wav", static=True) twisted_endpoint = ConfigServerEndpoint( "The endpoint the voice transport will listen on (and that Freeswitch" " will connect to).", required=True, default="tcp:port=8084", static=True) freeswitch_endpoint = ConfigClientEndpoint( "The endpoint the voice transport will send originate commands" "to (and that Freeswitch listens on).", default=None, static=True) freeswitch_auth = ConfigText( "Password for connecting to the Freeswitch endpoint." " None means no authentication credentials are offered.", default=None, static=True) originate_parameters = ConfigDict( "The parameters to pass to the originate command when initiating" " outbound calls. This dictionary of parameters is passed to the" " originate call template:\n\n" " %(template)r\n\n" "All call parameters are required but the following defaults are" " supplied:\n\n" " %(defaults)r" % { 'template': OriginateFormatter.PROTO_TEMPLATE, 'defaults': OriginateFormatter.DEFAULT_PARAMS, }, default=None, static=True) wait_for_answer = ConfigBool( "If True, the transport waits for a ChannelAnswer event for outbound " "(originated) calls before playing any media.", default=True, static=True) @property def supports_outbound(self): return self.freeswitch_endpoint is not None def post_validate(self): super(VoiceServerTransportConfig, self).post_validate() required_outbound = (self.freeswitch_endpoint is not None, self.originate_parameters is not None) if self.supports_outbound and not all(required_outbound): raise ConfigError( "If any outbound message parameters are supplied" " (freeswitch_endpoint or originate_params), all must be" " given.") if self.originate_parameters is not None: try: OriginateFormatter(**self.originate_parameters) except OriginateMissingParameter as err: raise ConfigError(str(err))
class MetricsApiConfig(Config): backend = ConfigDict("Config for metrics backend", default={})
class JunebugConfig(Config): interface = ConfigText( "Interface to expose the API on", default='localhost') port = ConfigInt( "Port to expose the API on", default=8080) logfile = ConfigText( "File to log to or `None` for no logging", default=None) redis = ConfigDict( "Config to use for redis connection", default={ 'host': 'localhost', 'port': 6379, 'db': 0, 'password': None }) amqp = ConfigDict( "Config to use for amqp connection", default={ 'hostname': '127.0.0.1', 'vhost': '/', 'port': 5672, 'db': 0, 'username': '******', 'password': '******' }) inbound_message_ttl = ConfigInt( "Maximum time (in seconds) allowed to reply to messages", default=60 * 10) outbound_message_ttl = ConfigInt( "Maximum time (in seconds) allowed for events to arrive for messages", default=60 * 60 * 24 * 2) channels = ConfigDict( "Mapping between channel types and python classes.", default={}) replace_channels = ConfigBool( "If `True`, replaces the default channels with `channels`. If `False`," " `channels` is added to the default channels.", default=False) plugins = ConfigList( "A list of dictionaries describing all of the enabled plugins. Each " "item should have a `type` key, with the full python class name of " "the plugin.", default=[]) metric_window = ConfigFloat( "The size of the buckets (in seconds) used for metrics.", default=10.0) logging_path = ConfigText( "The path to place log files in.", default="logs/") log_rotate_size = ConfigInt( "The maximum size (in bytes) of a log file before it gets rotated.", default=1000000) max_log_files = ConfigInt( "The maximum amount of log files allowed before old files start to " "get deleted. 0 is unlimited.", default=5) max_logs = ConfigInt( "The maximum amount of logs that is allowed to be retrieved via the " "API.", default=100)