# -*- coding: utf-8 -*- from __future__ import unicode_literals import os from django.db import models from django.core.validators import RegexValidator import requests from coin.configuration.models import Configuration FDN_ELIGIBILITY_URL = 'https://vador.fdn.fr/souscription/eligibilite.cgi' def convert_bandwidth(value): """Convert bandwidth expression to Int """ units = {'k': 1000, 'M': 1000000} if value[-1] not in units: raise ValueError('Incorrect bandwidth value: {}'.format(value)) return int(value[:-1]) * units[value[-1]] class FDNWhiteLabelError(Exception): pass class FDNWhiteLabel(Configuration): class Meta: verbose_name = 'marque blanche FDN' # If Django's default pluralisation is not satisfactory # verbose_name_plural = 'very many DSL lines' # URL namespace associated to this configuration type, to build URLs # in various view. Should also be defined in urls.py. Here, we don't # define any view, so there's no need for an URL namespace. url_namespace = "fdn" phone_number = models.CharField(max_length=20, verbose_name='phone number', help_text='Phone number associated to the ' 'DSL line') address = models.TextField( verbose_name='adresse postale', blank=True, null=True) postal_code = models.CharField(max_length=5, blank=True, null=True, validators=[ RegexValidator(regex=r'^\d{5}$', message='Code postal ' 'non valide.') ], verbose_name='code postal') city = models.CharField(max_length=200, blank=True, null=True, verbose_name='commune') ppp_login = models.CharField(max_length=200, blank=True, null=True, verbose_name='identifiant PPP') ppp_password = models.CharField(max_length=200, blank=True, null=True, verbose_name='mot de passe PPP') fdn_option = models.CharField(max_length=10, verbose_name='Option chez' ' FDN', blank=True, null=True) _fdn_bundled_line = True def is_compatible_option(self, option): if self._fdn_bundled_line: return 'opt1' in option['code_offre'] else: return 'opt1' not in option['code_offre'] def check_eligibility(self): """sends a request to FDN in order to get DSL eligibility status for that number and postal code, and returns the best option, as a tuple of offer code, and bandwidth, or raises an exception if no offer is available. TODO: add caching """ if not self.phone_number or not self.postal_code: raise AttributeError('Phone number and postal code must be ' 'defined') cert_file = os.path.join(os.getcwd(), 'fdnwhitelabel', 'cacert.crt') request_params = {'tel': self.phone_number, 'cp': self.postal_code, 'etape': 'eligibilite', 'tarif': 'blanche'} eligibility = requests\ .get(FDN_ELIGIBILITY_URL, params=request_params, verify=cert_file).json() if 'erreur' in eligibility and eligibility['erreur']: raise FDNWhiteLabelError(eligibility['message']) offers = [o for o in eligibility['offres'] if self.is_compatible_option(o)] best_offer = sorted(offers, key=lambda o: convert_bandwidth(o['debit']))[-1] return (best_offer['code_offre'], best_offer['debit']) def __unicode__(self): return self.phone_number def subnet_event(self): # Do something with self.ip_subnet.all() here. pass class FDNUnbundledWhiteLabel(FDNWhiteLabel): _fdn_bundled_line = True