def test_sanea_correctamente(self):
        service = PredictorMetadataService()
        NOMBRES = [
            ["NOMBRE", "NOMBRE"],
            ["EMAIL_PERSONA", "EMAIL_PERSONA"],
            ["EMAIL_2", "EMAIL_2"],
            ["X", "X"],
            ["NOMBRE ", "NOMBRE"],
            [" NOMBRE", "NOMBRE"],
            [" NOMBRE ", "NOMBRE"],
            ["EMAIL PERSONA", "EMAIL_PERSONA"],
            ["EMAIL    PERSONA", "EMAIL_PERSONA"],
            ["FACTURA EN $", "FACTURA_EN_$"],
            ["", ""],
        ]

        for nombre_original, nombre_saneado_esperado in NOMBRES:
            resultado = service.sanear_nombre_de_columna(nombre_original)
            self.assertEquals(resultado,
                              nombre_saneado_esperado,
                              "sanear_nombre_de_columna() ha devuelto un "
                              "valor inesperado al sanear '{0}'. "
                              "Devolvio: '{1}', se esperaba '{2}'"
                              "".format(nombre_original,
                                        resultado,
                                        nombre_saneado_esperado))
    def test_infiere_ok_con_todos_los_datos(self):
        ENCABEZADO_ORIGINAL = ["telefono", "Apellido", "Nombre",
                               "Fecha Alta", "Hora Alta", ]

        ENCABEZADO_AJUSTADO = [u'TELEFONO', u'APELLIDO', u'NOMBRE',
                               u'FECHA_ALTA', u'HORA_ALTA']

        lineas = [
            ENCABEZADO_ORIGINAL,
            [TELEFONO_OK, "Napoli", "Chizo", FECHA_OK, HORA_OK, ],
            [TELEFONO_OK, "Napoli", "Chizo", FECHA_OK, HORA_OK, ],
            [TELEFONO_OK, "Napoli", "Chizo", FECHA_OK, HORA_OK, ],
            [TELEFONO_OK, "Napoli", "Chizo", FECHA_OK, HORA_OK, ],
        ]

        service = PredictorMetadataService()
        metadata = service.inferir_metadata_desde_lineas(lineas, "utf-8")

        self.assertEquals(metadata.cantidad_de_columnas, 5)
        self.assertEquals(metadata.columna_con_telefono, 0)
        self.assertEquals(metadata.columnas_con_fecha, [3])
        self.assertEquals(metadata.columnas_con_hora, [4])

        self.assertEquals(metadata.primer_fila_es_encabezado, True)
        self.assertEquals(metadata.nombres_de_columnas, ENCABEZADO_AJUSTADO)
 def inferir_metadata(self, estructura_archivo):
     try:
         predictor_metadata = PredictorMetadataService()
         return predictor_metadata.inferir_metadata_desde_lineas(
             estructura_archivo, permitir_ext_pbx=True)
     except Exception as e:
         raise (NoSePuedeInferirMetadataError(e))
    def get(self, request, *args, **kwargs):
        self.object = self.get_object()

        estructura_archivo = self.obtiene_previsualizacion_archivo(self.object)
        if estructura_archivo:
            parser = ParserCsv()
            encoding = parser.detectar_encoding_csv(estructura_archivo)
            estructura_archivo_transformada = parser.visualizar_estructura_template(
                estructura_archivo, encoding)

            try:
                error_predictor = False
                error_predictor_encabezado = False

                predictor_metadata = PredictorMetadataService()
                metadata = predictor_metadata.inferir_metadata_desde_lineas(
                    estructura_archivo, encoding)
            except NoSePuedeInferirMetadataError:
                initial_predecido_datos_extras = {}
                initial_predecido_encabezado = {}
                error_predictor = True
            except NoSePuedeInferirMetadataErrorEncabezado:
                initial_predecido_datos_extras = {}
                initial_predecido_encabezado = {}

                error_predictor_encabezado = True
            else:
                initial_predecido_datos_extras = dict([
                    ('datos-extras-{0}'.format(col),
                     BaseDatosContacto.DATO_EXTRA_FECHA)
                    for col in metadata.columnas_con_fecha
                ])

                initial_predecido_datos_extras.update(
                    dict([('datos-extras-{0}'.format(col),
                           BaseDatosContacto.DATO_EXTRA_HORA)
                          for col in metadata.columnas_con_hora]))

                initial_predecido_encabezado = {
                    'es_encabezado': metadata.primer_fila_es_encabezado
                }

            form_primer_linea_encabezado = PrimerLineaEncabezadoForm(
                initial=initial_predecido_encabezado)
            form_campos_telefonicos = CamposDeBaseDeDatosForm(
                nombres_campos=estructura_archivo[0])

            return self.render_to_response(
                self.get_context_data(
                    error_predictor_encabezado=error_predictor_encabezado,
                    error_predictor=error_predictor,
                    estructura_archivo=estructura_archivo_transformada,
                    form_primer_linea_encabezado=form_primer_linea_encabezado,
                    form_campos_telefonicos=form_campos_telefonicos))

        return redirect(reverse('nueva_base_datos_contacto'))
    def test_no_infiere_nada_sin_datos(self):
        lineas = [
            ["telefono", "Apellido", "Nombre", "Fecha Alta", "Hora Alta"],
            ["Chizo", "Napoli", "", "", ""],
            ["Chizo", "Napoli", "", "", ""],
        ]

        service = PredictorMetadataService()
        with self.assertRaises(NoSePuedeInferirMetadataError):
            service.inferir_metadata_desde_lineas(lineas, "utf-8")
    def test_con_demas_planillas_de_ejemplo(self):

        PLANILLAS = (
            "planilla-ejemplo-1.csv",
            "planilla-ejemplo-2.csv",
            "planilla-ejemplo-7-celdas-vacias.csv",
            "planilla-ejemplo-8-ultima-celda-vacia.csv",
        )

        for planilla in PLANILLAS:
            logger.debug("Procesando planilla %s", planilla)
            bd_contacto = BaseDatosContacto.objects.create(
                nombre="base-datos-contactos-{0}".format(planilla),
                archivo_importacion=self.copy_test_resource_to_mediaroot(
                    planilla),
                nombre_archivo_importacion=planilla)

            parser = ParserCsv()
            estructura_archivo = parser.previsualiza_archivo(bd_contacto)
            predictor_metadata = PredictorMetadataService()
            metadata_inferida = predictor_metadata.inferir_metadata_desde_lineas(
                estructura_archivo)

            metadata = bd_contacto.get_metadata()
            metadata._metadata = metadata_inferida._metadata
            metadata.nombres_de_columnas = [
                "COL{0}".format(num)
                for num in range(metadata.cantidad_de_columnas)
            ]
            metadata.save()

            creacion_base_datos_service = CreacionBaseDatosService()
            creacion_base_datos_service.importa_contactos(
                bd_contacto, ["Telefono"], None)
            creacion_base_datos_service.define_base_dato_contacto(bd_contacto)

            # ----- checks

            self.assertEquals(
                BaseDatosContacto.objects.get(pk=bd_contacto.id).estado,
                BaseDatosContacto.ESTADO_DEFINIDA,
                "La BD generada desde '{0}' NO ha quedado en estado ESTADO_DEFINIDA"
                "".format(planilla))

            self.assertTrue(
                Contacto.objects.filter(bd_contacto=bd_contacto.id).count() >
                0, "La BD generada desde '{0}' NO posee contactos".format(
                    planilla))
    def test_inferir_metadata_correctamente(self):

        planilla = self.copy_test_resource_to_mediaroot("planilla-ejemplo-1.csv")
        nombre_archivo = "planilla-ejemplo-10.csv"
        base_test = BaseDatosContacto.objects.create(
            nombre="test", archivo_importacion=planilla,
            nombre_archivo_importacion=nombre_archivo, metadata="")

        parser = ParserCsv()
        estructura_archivo = parser.previsualiza_archivo(base_test)

        predictor_metadata = PredictorMetadataService()
        metadata = predictor_metadata.inferir_metadata_desde_lineas(estructura_archivo, "utf-8")

        validador_nombre = ValidadorDeNombreDeCampoExtra()
        for nombre_columna in metadata.nombres_de_columnas:
            self.assertTrue(validador_nombre.validar_nombre_de_columna(
                nombre_columna), "el nombre de columna es invalido")
    def test_con_planilla_ejemplo_3(self):
        bd_contacto = BaseDatosContacto.objects.create(
            nombre="base-datos-contactos",
            archivo_importacion=self.copy_test_resource_to_mediaroot(
                "planilla-ejemplo-3-headers-con-no-ascii-y-espacios.csv"),
            nombre_archivo_importacion=
            'planilla-ejemplo-3-headers-con-no-ascii-y-espacios.csv')

        parser = ParserCsv()
        estructura_archivo = parser.previsualiza_archivo(bd_contacto)
        predictor_metadata = PredictorMetadataService()
        metadata_inferida = predictor_metadata.inferir_metadata_desde_lineas(
            estructura_archivo)

        metadata = bd_contacto.get_metadata()
        metadata._metadata = metadata_inferida._metadata
        metadata.nombres_de_columnas = ["Telefono", "NOMBRE", "FECHA", "HORA"]
        metadata.columna_con_telefono = 0
        metadata.columnas_con_telefono = [0]
        metadata.save()

        creacion_base_datos_service = CreacionBaseDatosService()
        creacion_base_datos_service.importa_contactos(bd_contacto,
                                                      ["Telefono"], None)
        creacion_base_datos_service.define_base_dato_contacto(bd_contacto)

        # ----- checks

        self.assertEquals(
            BaseDatosContacto.objects.get(pk=bd_contacto.id).estado,
            BaseDatosContacto.ESTADO_DEFINIDA,
            "La BD no ha quedado en estado ESTADO_DEFINIDA")

        nros_telefono = [
            contacto.telefono
            for contacto in Contacto.objects.filter(bd_contacto=bd_contacto.id)
        ]

        self.assertEquals(len(nros_telefono), 3, "Deberia haber 3 contactos")

        self.assertEquals(
            set(nros_telefono),
            set(['354303459865', '111534509230', '283453013491']),
            "Deberia haber 3 contactos")
    def test_detecta_pocas_lineas(self):
        service = PredictorMetadataService()

        # Ninguna linea
        with self.assertRaises(NoSePuedeInferirMetadataError):
            service.inferir_metadata_desde_lineas([], "utf-8")

        # Una linea
        with self.assertRaises(NoSePuedeInferirMetadataError):
            service.inferir_metadata_desde_lineas([[TELEFONO_OK], ], "utf-8")

        # Por las dudas chequeamos q' funcione con 2 linas
        service.inferir_metadata_desde_lineas([['telefono'], [TELEFONO_OK], ], "utf-8")
    def get(self, request, *args, **kwargs):
        self.object = self.get_object()

        estructura_archivo = self.obtiene_previsualizacion_archivo(self.object)
        if estructura_archivo:
            try:
                error_predictor = False
                error_predictor_encabezado = False

                predictor_metadata = PredictorMetadataService()
                metadata = predictor_metadata.\
                    inferir_metadata_desde_lineas_base_existente(
                        self.object, estructura_archivo)
            except NoSePuedeInferirMetadataError:
                initial_predecido_encabezado = {}

                error_predictor = True
            except NoSePuedeInferirMetadataErrorEncabezado:
                initial_predecido_encabezado = {}

                error_predictor_encabezado = True
            else:
                initial_predecido_datos_extras = dict([
                    ('datos-extras-{0}'.format(col),
                     BaseDatosContacto.DATO_EXTRA_FECHA)
                    for col in metadata.columnas_con_fecha
                ])

                initial_predecido_datos_extras.update(
                    dict([('datos-extras-{0}'.format(col),
                           BaseDatosContacto.DATO_EXTRA_HORA)
                          for col in metadata.columnas_con_hora]))

                initial_predecido_encabezado = {
                    'es_encabezado': metadata.primer_fila_es_encabezado
                }

            form_primer_linea_encabezado = PrimerLineaEncabezadoForm(
                initial=initial_predecido_encabezado)

            return self.render_to_response(
                self.get_context_data(
                    error_predictor_encabezado=error_predictor_encabezado,
                    error_predictor=error_predictor,
                    estructura_archivo=estructura_archivo,
                    form_primer_linea_encabezado=form_primer_linea_encabezado))

        return redirect(
            reverse('update_base_datos_contacto_de_campana',
                    kwargs={'pk_campana': '9'}))
 def inferir_metadata(self, estructura_archivo):
     predictor_metadata = PredictorMetadataService()
     return predictor_metadata.inferir_metadata_desde_lineas(
         estructura_archivo)