def __init__(self, is_superuser=False, *args, **kwargs): super(InitiateAddSMSBackendForm, self).__init__(*args, **kwargs) backend_classes = get_available_backends() backend_choices = [] for name, klass in backend_classes.items(): if is_superuser or name == "TelerivetBackend": try: friendly_name = klass.get_generic_name() except NotImplementedError: friendly_name = name backend_choices.append((name, friendly_name)) self.fields['backend_type'].choices = backend_choices self.helper = FormHelper() self.helper.form_class = "form form-horizontal" self.helper.layout = crispy.Layout( BootstrapMultiField( _("Create Another Connection"), InlineField('action'), InlineField('backend_type'), StrictButton( mark_safe('<i class="icon-plus"></i> %s' % "Add Another Gateway"), css_class='btn-success', type='submit', style="margin-left:5px;" ), ), )
def clean_name(self): value = self.cleaned_data.get("name") if value is not None: value = value.strip().upper() if value is None or value == "": raise ValidationError(_("This field is required.")) if re.compile("\s").search(value) is not None: raise ValidationError(_("Name may not contain any spaces.")) backend_classes = get_available_backends() if self._cchq_domain is None: # Ensure name is not duplicated among other global backends backend = SMSBackend.view( "sms/global_backends", classes=backend_classes, key=[value], include_docs=True, reduce=False ).one() else: # Ensure name is not duplicated among other backends owned by this domain backend = SMSBackend.view("sms/backend_by_owner_domain", classes=backend_classes, key=[self._cchq_domain, value], include_docs=True).one() if backend is not None and backend._id != self._cchq_backend_id: raise ValidationError(_("Name is already in use.")) return value
def __init__(self, is_superuser=False, *args, **kwargs): super(InitiateAddSMSBackendForm, self).__init__(*args, **kwargs) backend_classes = get_available_backends() backend_choices = [] for name, klass in backend_classes.items(): if is_superuser or name == "TelerivetBackend": try: friendly_name = klass.get_generic_name() except NotImplementedError: friendly_name = name backend_choices.append((name, friendly_name)) self.fields['backend_type'].choices = backend_choices self.helper = FormHelper() self.helper.form_class = "form form-horizontal" self.helper.layout = crispy.Layout( BootstrapMultiField( _("Create Another Connection"), InlineField('action'), InlineField('backend_type'), StrictButton(mark_safe('<i class="icon-plus"></i> %s' % "Add Another Gateway"), css_class='btn-success', type='submit', style="margin-left:5px;"), ), )
def clean_name(self): value = self.cleaned_data.get("name") if value is not None: value = value.strip().upper() if value is None or value == "": raise ValidationError(_("This field is required.")) if re.compile("\s").search(value) is not None: raise ValidationError(_("Name may not contain any spaces.")) backend_classes = get_available_backends() if self._cchq_domain is None: # Ensure name is not duplicated among other global backends backend = SMSBackend.view("sms/global_backends", classes=backend_classes, key=[value], include_docs=True, reduce=False).one() else: # Ensure name is not duplicated among other backends owned by this domain backend = SMSBackend.view("sms/backend_by_owner_domain", classes=backend_classes, key=[self._cchq_domain, value], include_docs=True).one() if backend is not None and backend._id != self._cchq_backend_id: raise ValidationError(_("Name is already in use.")) return value
def arbitrary_fees_by_backend_instance(backend_ids): fees = {} for direction in DIRECTIONS: fees_by_backend = {} for backend in get_available_backends().values(): fees_by_backend[backend.get_api_id()] = (backend_ids[backend.get_api_id()], arbitrary_fee()) fees[direction] = fees_by_backend return fees
def arbitrary_fees_by_direction_and_backend(): fees = {} for direction in DIRECTIONS: fees_by_backend = {} for backend in get_available_backends().values(): fees_by_backend[backend.get_api_id()] = arbitrary_fee() fees[direction] = fees_by_backend return fees
def wrap_correctly(self): from corehq.apps.sms.util import get_available_backends backend_classes = get_available_backends() doc_type = self.doc_type if doc_type in backend_classes: return backend_classes[doc_type].wrap(self.to_json()) else: raise UnrecognizedBackendException("Backend %s has an " "unrecognized doc type." % self._id)
def arbitrary_fees_by_backend_instance(backend_ids): fees = {} for direction in DIRECTIONS: fees_by_backend = {} for backend in get_available_backends().values(): fees_by_backend[backend.get_api_id()] = ( backend_ids[backend.get_api_id()], arbitrary_fee()) fees[direction] = fees_by_backend return fees
def arbitrary_backend_ids(): backend_ids = {} for backend in get_available_backends().values(): backend_instance = data_gen.arbitrary_unique_name("back") backend_ids[backend.get_api_id()] = backend_instance sms_backend = SMSBackend() sms_backend._id = backend_instance sms_backend.is_global = True sms_backend.save() return backend_ids
def _list_backends(request, show_global=False, domain=None): backend_classes = get_available_backends() backends = [] editable_backend_ids = [] default_sms_backend_id = None if not show_global: domain_obj = Domain.get_by_name(domain, strict=True) raw_backends = [] if not show_global: raw_backends += SMSBackend.view( "sms/backend_by_domain", reduce=False, classes=backend_classes, startkey=[domain], endkey=[domain, {}], include_docs=True, ).all() if len(raw_backends) > 0 and domain_obj.default_sms_backend_id in [None, ""]: messages.error( request, _( "WARNING: You have not specified a default SMS connection. By default, the system will automatically select one of the SMS connections owned by the system when sending sms." ), ) raw_backends += SMSBackend.view( "sms/global_backends", classes=backend_classes, include_docs=True, reduce=False ).all() for backend in raw_backends: backends.append(backend_classes[backend.doc_type].wrap(backend.to_json())) if show_global or (not backend.is_global and backend.domain == domain): editable_backend_ids.append(backend._id) if not show_global and domain_obj.default_sms_backend_id == backend._id: default_sms_backend_id = backend._id instantiable_backends = [] for name, klass in backend_classes.items(): try: assert ( request.couch_user.is_superuser or show_global or name == "TelerivetBackend" ) # TODO: Remove this once domain-specific billing is sorted out klass.get_generic_name() klass.get_form_class() instantiable_backends.append((name, klass)) except Exception: pass instantiable_backends.sort(key=lambda t: t[0]) context = { "show_global": show_global, "domain": domain, "backends": backends, "editable_backend_ids": editable_backend_ids, "default_sms_backend_id": default_sms_backend_id, "instantiable_backends": instantiable_backends, } return render(request, "sms/list_backends.html", context)
def arbitrary_fees_by_country(): fees = {} for direction in DIRECTIONS: fees_by_backend = {} for backend in get_available_backends().values(): fees_by_country = {} for country in TEST_COUNTRY_CODES: fees_by_country[country] = arbitrary_fee() fees_by_backend[backend.get_api_id()] = fees_by_country fees[direction] = fees_by_backend return fees
def load(cls, backend_id): """load a mobile backend backend_id - the Couch document _id of the backend to load """ # Circular import from corehq.apps.sms.util import get_available_backends backend_classes = get_available_backends() backend = cls.get(backend_id) if backend.doc_type not in backend_classes: raise Exception("Unexpected backend doc_type found '%s' for backend '%s'" % (backend.doc_type, backend._id)) else: return backend_classes[backend.doc_type].wrap(backend.to_json())
def global_backend_map(request): backend_classes = get_available_backends() global_backends = SMSBackend.view( "sms/global_backends", classes=backend_classes, include_docs=True, reduce=False ).all() current_map = {} catchall_entry = None for entry in BackendMapping.view("sms/backend_map", startkey=["*"], endkey=["*", {}], include_docs=True).all(): if entry.prefix == "*": catchall_entry = entry else: current_map[entry.prefix] = entry if request.method == "POST": form = BackendMapForm(request.POST) if form.is_valid(): new_backend_map = form.cleaned_data.get("backend_map") new_catchall_backend_id = form.cleaned_data.get("catchall_backend_id") for prefix, entry in current_map.items(): if prefix not in new_backend_map: current_map[prefix].delete() del current_map[prefix] for prefix, backend_id in new_backend_map.items(): if prefix in current_map: current_map[prefix].backend_id = backend_id current_map[prefix].save() else: current_map[prefix] = BackendMapping(is_global=True, prefix=prefix, backend_id=backend_id) current_map[prefix].save() if new_catchall_backend_id is None: if catchall_entry is not None: catchall_entry.delete() catchall_entry = None else: if catchall_entry is None: catchall_entry = BackendMapping(is_global=True, prefix="*", backend_id=new_catchall_backend_id) else: catchall_entry.backend_id = new_catchall_backend_id catchall_entry.save() messages.success(request, _("Changes Saved.")) else: initial = { "catchall_backend_id" : catchall_entry.backend_id if catchall_entry is not None else None, "backend_map" : [{"prefix" : prefix, "backend_id" : entry.backend_id} for prefix, entry in current_map.items()], } form = BackendMapForm(initial=initial) context = { "backends" : global_backends, "form" : form, } return render(request, "sms/backend_map.html", context)
def _add_backend(request, backend_class_name, is_global, domain=None, backend_id=None): # We can remove this restriction once we implement throttling of http backends, and billing for domain-specific backends if not (request.couch_user.is_superuser or is_global or backend_class_name == "TelerivetBackend"): raise Http404 backend_classes = get_available_backends() backend_class = backend_classes[backend_class_name] backend = None if backend_id is not None: backend = backend_class.get(backend_id) if not is_global and backend.domain != domain: raise Http404 ignored_fields = ["give_other_domains_access"] if request.method == "POST": form = backend_class.get_form_class()(request.POST) form._cchq_domain = domain form._cchq_backend_id = backend._id if backend is not None else None if form.is_valid(): if backend is None: backend = backend_class(domain=domain, is_global=is_global) for key, value in form.cleaned_data.items(): if key not in ignored_fields: setattr(backend, key, value) backend.save() if is_global: return HttpResponseRedirect(reverse("list_backends")) else: return HttpResponseRedirect(reverse("list_domain_backends", args=[domain])) else: initial = {} if backend is not None: for field in backend_class.get_form_class()(): if field.name not in ignored_fields: if field.name == "authorized_domains": initial[field.name] = ",".join(backend.authorized_domains) else: initial[field.name] = getattr(backend, field.name, None) if len(backend.authorized_domains) > 0: initial["give_other_domains_access"] = True else: initial["give_other_domains_access"] = False form = backend_class.get_form_class()(initial=initial) context = { "is_global" : is_global, "domain" : domain, "form" : form, "backend_class_name" : backend_class_name, "backend_generic_name" : backend_class.get_generic_name(), "backend_id" : backend_id, } return render(request, backend_class.get_template(), context)
def load(cls, backend_id): """load a mobile backend backend_id - the Couch document _id of the backend to load """ # Circular import from corehq.apps.sms.util import get_available_backends backend_classes = get_available_backends() backend = cls.get(backend_id) if backend.doc_type not in backend_classes: raise Exception( "Unexpected backend doc_type found '%s' for backend '%s'" % (backend.doc_type, backend._id)) else: return backend_classes[backend.doc_type].wrap(backend.to_json())
def get_wrapped(cls, backend_id): from corehq.apps.sms.util import get_available_backends backend_classes = get_available_backends() try: backend = SMSBackend.get(backend_id) except ResourceNotFound: raise UnrecognizedBackendException("Backend %s not found" % backend_id) doc_type = backend.doc_type if doc_type in backend_classes: backend = backend_classes[doc_type].wrap(backend.to_json()) return backend else: raise UnrecognizedBackendException("Backend %s has an " "unrecognized doc type." % backend_id)
def setUp(self): self.currency_usd, _ = Currency.objects.get_or_create( code=settings.DEFAULT_CURRENCY, name="Default Currency", symbol="$", rate_to_default=Decimal('1.0') ) self.available_backends = get_available_backends().values() self.backend_ids = generator.arbitrary_backend_ids() self.message_logs = generator.arbitrary_messages_by_backend_and_direction(self.backend_ids) self.least_specific_fees = generator.arbitrary_fees_by_direction_and_backend() self.country_code_fees = generator.arbitrary_fees_by_country() self.instance_fees = generator.arbitrary_fees_by_backend_instance(self.backend_ids) self.most_specific_fees = generator.arbitrary_fees_by_all(self.backend_ids)
def arbitrary_fees_by_prefix(backend_ids, country_codes_and_prefixes): fees = {} for direction in DIRECTIONS: fees_by_backend = {} for backend in get_available_backends().values(): fees_by_country_code = {} for country_code, _ in country_codes_and_prefixes: fees_by_country_code[country_code] = {} for country_code, prefix in country_codes_and_prefixes: fees_by_prefix = { backend_instance: arbitrary_fee() for backend_instance in [backend_ids[backend.get_api_id()], None] } fees_by_country_code[country_code][prefix] = fees_by_prefix fees_by_backend[backend.get_api_id()] = fees_by_country_code fees[direction] = fees_by_backend return fees
def setUp(self): SmsGatewayFee.objects.all().delete() SmsGatewayFeeCriteria.objects.all().delete() self.currency_usd = init_default_currency() self.available_backends = get_available_backends().values() self.backend_ids = generator.arbitrary_backend_ids() self.message_logs = generator.arbitrary_messages_by_backend_and_direction( self.backend_ids) self.least_specific_fees = generator.arbitrary_fees_by_direction_and_backend( ) self.country_code_fees = generator.arbitrary_fees_by_country() self.instance_fees = generator.arbitrary_fees_by_backend_instance( self.backend_ids) self.most_specific_fees = generator.arbitrary_fees_by_all( self.backend_ids) self.country_code_and_prefixes = generator.arbitrary_country_code_and_prefixes( ) self.prefix_fees = generator.arbitrary_fees_by_prefix( self.backend_ids, self.country_code_and_prefixes) self.other_currency = generator.arbitrary_currency()
def backend_classes(self): return get_available_backends()
def get_opt_keywords(msg): backend_classes = get_available_backends(index_by_api_id=True) backend_class = backend_classes.get(msg.backend_api, SMSBackend) return (backend_class.get_opt_in_keywords(), backend_class.get_opt_out_keywords())
def arbitrary_backend_ids(): backend_ids = {} for backend in get_available_backends().values(): backend_ids[backend.get_api_id()] = data_gen.arbitrary_unique_name("back") return backend_ids
def arbitrary_backend_ids(): backend_ids = {} for backend in get_available_backends().values(): backend_ids[backend.get_api_id()] = data_gen.arbitrary_unique_name( "back") return backend_ids