Exemplo n.º 1
0
class ModuloApertura(Modulo):

    """ Modulo de Apertura de votos.

        Este módulo permite generar el acta de apertura de una mesa.
        El usuario debe ingresar el acta en la maquina, agregar y confirmar sus
        datos e imprimirla.
    """

    def __init__(self):
        """Constructor"""
        self.es_modulo_web = True
        self.web_template = "apertura"
        self.rampa = RampaApertura(self)
        self.controller = ControllerInteraccion(self, modulo=MODULO_APERTURA)
        self._mensaje = None

        Modulo.__init__(self)

        self.ret_code = MODULO_APERTURA
        self.estado = E_INICIAL
        self._cargar_ui_apertura()

    def _cargar_ui_apertura(self):
        pass
        #self.controller._inicializa_pantalla()

    def reiniciar_modulo(self):
        self.estado = E_INICIAL
        self.controller.estado = E_INGRESO_ACTA
        self.controller._inicializa_pantalla()

    def cargar_datos(self, apertura=None):
        """ Callback de salida del estado inicial, que indica que se obtuvo un
            tag de apertura.  Ahora se pasa al estado de carga de datos,
            solicita el ingreso de datos del Presidente de Mesa.
        """
        self.estado = E_CARGA
        self.controller.estado = E_INGRESO_DATOS

        hora = None
        autoridades = None
        if apertura is not None:
            hora = apertura.hora
            autoridades = [(autoridad.a_dict()) for autoridad in \
                           apertura.autoridades]

        self.controller.set_pantalla({"hora": hora,
                                      "autoridades": autoridades})

    def _configurar_mesa(self, datos_tag):
        """
        Configura la mesa con los datos que contiene el tag.
        """
        apertura = Apertura.desde_tag(datos_tag)
        if apertura.mesa is not None:
            sesion.apertura = apertura
            sesion.mesa = apertura.mesa
            sesion.impresora.expulsar_boleta()
            sesion.impresora.consultar_tarjeta(lambda x: self.salir())

    def crear_objeto(self, autoridades, hora):
        """
        Recibe un instancia de Presidente de Mesa y del suplente con los datos
        que cargo el usuario.
        """
        self.apertura = Apertura(sesion.mesa, autoridades, hora)
        self.estado = E_CONFIRMACION
        self.controller.estado = E_CONFIRMACION
        imagen_acta = self.apertura.a_imagen(svg=True, de_muestra=True)
        imagen_data = quote(imagen_acta.encode("utf-8"))
        self.controller.set_pantalla_confirmacion(imagen_data)

    def confirmar_apertura(self):
        if self.__guardar_e_imprimir():
            self.estado = E_REGISTRANDO

            def _inner(printer_status=None):
                sesion.impresora.remover_boleta_expulsada()
                sesion.impresora.remover_insertando_papel()
                self.salir()

            if USA_ARMVE:
                sesion.impresora.registar_boleta_expulsada(_inner)
            else:
                sesion.impresora.registrar_insertando_papel(_inner)
        else:
            tag = self.rampa.datos_tag
            self.controller.msg_error_apertura(tag)

    def __guardar_e_imprimir(self):
        """ Función que se encarga primero de guardar los datos y corroborar
            que esté todo ok.
            Si es así imprime y devuelve True o False en cualquier caso
            contrario
        """
        tag = self.rampa.datos_tag
        if not tag or not sesion.impresora:
            return False

        # Chequeo que el tag esté vacío
        datos_tag = tag['datos']
        if datos_tag != '':
            return False

        # Todo ok, guardo el acta de apertura, si devuelve True, imprimo.
        if self._guardar_apertura():
            sesion.apertura = self.apertura
            self._imprimir_acta()

            def esperar_vacia(tiene_tarjeta):
                if not tiene_tarjeta:
                    sesion.impresora.remover_consultar_tarjeta()
                    self.salir()
            sesion.impresora.consultar_tarjeta(esperar_vacia)
            return True
        else:
            return False

    def _guardar_apertura(self):
        """ Guarda los datos en el tag, lo vuelve a leer y compara los dos
            strings para verificar la correcta escritura.
            Devuelve True si el guardado y la comprobación están correctos,
            False en caso contrario.
        """
        guardado_ok = False

        if USA_ARMVE:
            datos = self.apertura.a_tag()
            marcar_ro = QUEMA
            guardado_ok = sesion.lector.guardar_tag(TAG_APERTURA, datos,
                                                    marcar_ro)
        else:
            datos1 = self.apertura.a_tag()
            tag_grabado = self._guarda_tag(datos1)

            if tag_grabado:
                datos2 = self._lee_tag()
                if datos1 == datos2:
                    guardado_ok = True
        return guardado_ok

    def _guarda_tag(self, datos):
        """ Esta función guarda los datos en el tag """
        # Intenta guardar el tag devolviendo True o False si pudo o no.
        # Ciclo hasta encontrar un tag
        tag = self.rampa.datos_tag
        if not tag:
            return False
        # No puedo grabar si el tag ya tiene algo
        if tag['datos'] != '':
            return False
        # Intento grabar, si algo sale mal salgo con error.
        try:
            #datos = datos.encode('utf-8')
            sesion.lector.escribe_datos(tag, datos, TAG_APERTURA)
        except Exception as e:
            sesion.logger.exception(e)
            return False
        # Si llegue hasta aca, es porque pude guardar los datos sin problemas.
        return True

    def _lee_tag(self):
        """ Función para obtener un tag y devolver sus datos o vacío """
        if USA_ARMVE:
            tag = self.rampa.datos_tag
        else:
            tag = sesion.lector.get_tag()
        datos = tag['datos']

        return datos

    def _imprimir_acta(self):
        tipo_tag = self.apertura.__class__.__name__
        tag = self.apertura.a_tag()
        sesion.impresora.posicionar_al_inicio()
        sesion.impresora.imprimir_serializado(tipo_tag, b64encode(tag))
        if not USA_ARMVE:
            time.sleep(15)

    def mensaje_inicial(self):
        self.apertura = None
        self.controller.mensaje_inicial()

    def volver(self, apertura):
        """Vuelve a la pantalla de inicial"""
        self.cargar_datos(apertura)

    def salir(self):
        """ Sale del módulo de apertura, vuelve al comienzo con la maquina
            desconfigurada
        """
        if hasattr(self, 'pantalla') and self.pantalla is not None:
            self.pantalla.destroy()
        if self.browser is not None:
            self.ventana.remove(self.browser)
        sesion.lector.remover_consultar_lector()
        self.ret_code = MODULO_ADMIN
        self.quit()

    def procesar_tag(self, tag_dict):
        read_only = tag_dict.get("read_only")
        if tag_dict['datos'] == '' and not read_only:
            if self.controller.estado == E_INGRESO_ACTA:
                self.cargar_datos()
        else:
            self.controller.set_mensaje(_("acta_contiene_informacion"))
            sesion.impresora.expulsar_boleta()
Exemplo n.º 2
0
class ModuloApertura(Modulo):
    """ Modulo de Apertura de votos.

        Este módulo permite generar el acta de apertura de una mesa.
        El usuario debe ingresar el acta en la maquina, agregar y confirmar sus
        datos e imprimirla.
    """
    def __init__(self):
        """Constructor"""
        self.es_modulo_web = True
        self.web_template = "apertura"
        self.rampa = RampaApertura(self)
        self.controller = ControllerInteraccion(self, modulo=MODULO_APERTURA)
        self._mensaje = None

        Modulo.__init__(self)

        self.ret_code = MODULO_APERTURA
        self.estado = E_INICIAL
        self._cargar_ui_apertura()

    def _cargar_ui_apertura(self):
        pass
        #self.controller._inicializa_pantalla()

    def reiniciar_modulo(self):
        self.estado = E_INICIAL
        self.controller.estado = E_INGRESO_ACTA
        self.controller._inicializa_pantalla()

    def cargar_datos(self, apertura=None):
        """ Callback de salida del estado inicial, que indica que se obtuvo un
            tag de apertura.  Ahora se pasa al estado de carga de datos,
            solicita el ingreso de datos del Presidente de Mesa.
        """
        self.estado = E_CARGA
        self.controller.estado = E_INGRESO_DATOS

        hora = None
        autoridades = None
        if apertura is not None:
            hora = apertura.hora
            autoridades = [(autoridad.a_dict()) for autoridad in \
                           apertura.autoridades]

        self.controller.set_pantalla({
            "hora": hora,
            "autoridades": autoridades
        })

    def _configurar_mesa(self, datos_tag):
        """
        Configura la mesa con los datos que contiene el tag.
        """
        apertura = Apertura.desde_tag(datos_tag)
        if apertura.mesa is not None:
            sesion.apertura = apertura
            sesion.mesa = apertura.mesa
            sesion.impresora.expulsar_boleta()
            sesion.impresora.consultar_tarjeta(lambda x: self.salir())

    def crear_objeto(self, autoridades, hora):
        """
        Recibe un instancia de Presidente de Mesa y del suplente con los datos
        que cargo el usuario.
        """
        self.apertura = Apertura(sesion.mesa, autoridades, hora)
        self.estado = E_CONFIRMACION
        self.controller.estado = E_CONFIRMACION
        imagen_acta = self.apertura.a_imagen(svg=True, de_muestra=True)
        imagen_data = quote(imagen_acta.encode("utf-8"))
        self.controller.set_pantalla_confirmacion(imagen_data)

    def confirmar_apertura(self):
        if self.__guardar_e_imprimir():
            self.estado = E_REGISTRANDO

            def _inner(printer_status=None):
                sesion.impresora.remover_boleta_expulsada()
                sesion.impresora.remover_insertando_papel()
                self.salir()

            if USA_ARMVE:
                sesion.impresora.registar_boleta_expulsada(_inner)
            else:
                sesion.impresora.registrar_insertando_papel(_inner)
        else:
            tag = self.rampa.datos_tag
            self.controller.msg_error_apertura(tag)

    def __guardar_e_imprimir(self):
        """ Función que se encarga primero de guardar los datos y corroborar
            que esté todo ok.
            Si es así imprime y devuelve True o False en cualquier caso
            contrario
        """
        tag = self.rampa.datos_tag
        if not tag or not sesion.impresora:
            return False

        # Chequeo que el tag esté vacío
        datos_tag = tag['datos']
        if datos_tag != '':
            return False

        # Todo ok, guardo el acta de apertura, si devuelve True, imprimo.
        if self._guardar_apertura():
            sesion.apertura = self.apertura
            self._imprimir_acta()

            def esperar_vacia(tiene_tarjeta):
                if not tiene_tarjeta:
                    sesion.impresora.remover_consultar_tarjeta()
                    self.salir()

            sesion.impresora.consultar_tarjeta(esperar_vacia)
            return True
        else:
            return False

    def _guardar_apertura(self):
        """ Guarda los datos en el tag, lo vuelve a leer y compara los dos
            strings para verificar la correcta escritura.
            Devuelve True si el guardado y la comprobación están correctos,
            False en caso contrario.
        """
        guardado_ok = False

        if USA_ARMVE:
            datos = self.apertura.a_tag()
            marcar_ro = not MODO_DEMO
            guardado_ok = sesion.lector.guardar_tag(TAG_APERTURA, datos,
                                                    marcar_ro)
        else:
            datos1 = self.apertura.a_tag()
            tag_grabado = self._guarda_tag(datos1)

            if tag_grabado:
                datos2 = self._lee_tag()
                if datos1 == datos2:
                    guardado_ok = True
        return guardado_ok

    def _guarda_tag(self, datos):
        """ Esta función guarda los datos en el tag """
        # Intenta guardar el tag devolviendo True o False si pudo o no.
        # Ciclo hasta encontrar un tag
        tag = self.rampa.datos_tag
        if not tag:
            return False
        # No puedo grabar si el tag ya tiene algo
        if tag['datos'] != '':
            return False
        # Intento grabar, si algo sale mal salgo con error.
        try:
            #datos = datos.encode('utf-8')
            sesion.lector.escribe_datos(tag, datos, TAG_APERTURA)
        except Exception as e:
            sesion.logger.exception(e)
            return False
        # Si llegue hasta aca, es porque pude guardar los datos sin problemas.
        return True

    def _lee_tag(self):
        """ Función para obtener un tag y devolver sus datos o vacío """
        if USA_ARMVE:
            tag = self.rampa.datos_tag
        else:
            tag = sesion.lector.get_tag()
        datos = tag['datos']

        return datos

    def _imprimir_acta(self):
        tipo_tag = self.apertura.__class__.__name__
        tag = self.apertura.a_tag()
        sesion.impresora.posicionar_al_inicio()
        sesion.impresora.imprimir_serializado(tipo_tag, b64encode(tag))
        if not USA_ARMVE:
            time.sleep(15)

    def mensaje_inicial(self):
        self.apertura = None
        self.controller.mensaje_inicial()

    def volver(self, apertura):
        """Vuelve a la pantalla de inicial"""
        self.cargar_datos(apertura)

    def salir(self):
        """ Sale del módulo de apertura, vuelve al comienzo con la maquina
            desconfigurada
        """
        if hasattr(self, 'pantalla') and self.pantalla is not None:
            self.pantalla.destroy()
        if self.browser is not None:
            self.ventana.remove(self.browser)
        sesion.lector.remover_consultar_lector()
        self.ret_code = MODULO_ADMIN
        self.quit()

    def procesar_tag(self, tag_dict):
        read_only = tag_dict.get("read_only")
        if tag_dict['datos'] == '' and not read_only:
            if self.controller.estado == E_INGRESO_ACTA:
                self.cargar_datos()
        else:
            self.controller.set_mensaje(_("acta_contiene_informacion"))
            sesion.impresora.expulsar_boleta()
Exemplo n.º 3
0
class ModuloRecuento(Modulo):
    """ Modulo de Recuento de votos.

        Este módulo permite hacer el recuento de votos de una mesa.
        El usuario debe pasar el tag a ser utilizado para el recuento de la
        mesa, y a continuacion debe pasar todas las boletas por el lector.
        El sistema va a totalizarlas y una vez que el usuario confirme el
        cierre de la mesa, emite un listado con la cantidad de copias
        indicadas.

    E_INICIAL = 0
    E_SETUP = 1
    E_RECUENTO = 2
    E_RESULTADO = 3
    E_VERIFICACION = 4
    """
    controller_recuento = ControllerRecuento

    def __init__(self):
        """Constructor"""
        self.send_function = None
        # El primer controller es ControllerInteraccion porque es el que maneja
        # el ingreso de datos de mesa y pin y autoridades
        self.web_template = "recuento"
        self._cargar_controller_interaccion()
        self.es_modulo_web = True
        Modulo.__init__(self)
        self.ret_code = MODULO_RECUENTO
        self.estado = E_INICIAL
        self._intento = 0
        self._ui_web_activa = True  # Flag que indica si esta activa la ui web
        self.apertura = None
        """
        if USA_ARMVE:
            power_source = sesion.powermanager.get_power_source()
            if power_source is not None and not power_source['byte']:
                sesion.fancoolers.set_fan_auto_mode(False)
                sesion.fancoolers.set_fan_speed(100)
        """
        self.rampa = RampaRecuento(self)

    def _cargar_controller_interaccion(self):
        self.controller = ControllerInteraccion(self)

    def _cargar_ui_web(self):
        Modulo._cargar_ui_web(self)

    def _cargar_ui_recuento(self):
        Modulo._cargar_ui_web(self)
        self.ventana.show_all()

    def reiniciar_modulo(self):
        if self.rampa.tiene_papel and self.estado == E_SETUP:
            pass
        else:
            self.estado = E_INICIAL
            self.controller.estado = E_INGRESO_ACTA
            self.controller._inicializa_pantalla()

    def _inicio(self):
        """ Funcion llamada desde el controller una vez que se encuentra lista
            la interfaz web
        """
        self.controller.set_panel_estado(RECUENTO_NO_TAG)

        if self.estado == E_RECUENTO:
            #self.controller.set_pantalla_recuento()
            pass
        elif self.estado == E_VERIFICACION:
            self.print_manager.callback = self.print_manager.reset_copias
            sesion.recuento.autoridades = None
            #self.controller.set_pantalla_revision()

    def procesar_tag(self, tag_dict):
        """ Evento. Procesa el tag recibido por parametro. Cumple la funcion
            del procesar_tag() de PantallaRecuento de recuento Gtk.

            Argumentos:
            tag   -- El objeto TAG recibido.
            datos -- Los datos almacenados en el tag recibido.

            Si el tag no es ICODE se descarta el evento.
            Si su tipo no es voto, o está vacío, se devuelve error.
            Se intenta sumar los datos al recuento, si devuelve False
            es porque el tag ya fue sumado, sino está ok.
        """
        if self.estado == E_RECUENTO:
            serial = tag_dict.get('serial')
            tipo_tag = tag_dict.get('tipo')
            datos = tag_dict.get('datos')
            if None in (serial, tipo_tag, datos) or tipo_tag != TAG_VOTO:
                self.controller.set_panel_estado(RECUENTO_ERROR)
            else:
                self.controller.hide_dialogo()
                try:
                    seleccion = Seleccion.desde_tag(datos,
                                                    sesion.mesa)
                    if not sesion.recuento.serial_sumado(serial):
                        sesion.recuento.sumar_seleccion(seleccion, serial)
                        sesion.recuento.hora_fin = time.time()
                        sesion.ultima_seleccion = seleccion

                        # Dibujo boleta
                        imagen = seleccion.a_imagen(verificador=False,
                                                    solo_mostrar=True,
                                                    svg=True)
                        image_data = quote(imagen.encode("utf-8"))

                        cant_leidas = sesion.recuento.boletas_contadas()
                        self.controller.actualizar_resultados(
                            sesion.ultima_seleccion, cant_leidas, image_data)
                        gobject.timeout_add(200,
                                            self.controller.set_panel_estado,
                                            RECUENTO_OK)
                    else:
                        self.controller.set_panel_estado(
                            RECUENTO_ERROR_REPETIDO)
                except Exception as e:
                    print(e)
                    self.controller.set_panel_estado(RECUENTO_ERROR)
        elif self.controller.__class__.__name__ == "ControllerInteraccion":
            read_only = tag_dict.get("read_only")
            if self.rampa.tiene_papel and not read_only and self.estado not in \
                    (E_SETUP, E_VERIFICACION) and tag_dict['tipo'] in \
                    (TAG_VACIO, [0, 0]):
                self.estado = E_SETUP
                self.controller.estado = E_MESAYPIN
                self.controller.set_pantalla()
                self.posicion_recuento()
            elif self.estado in E_INICIAL and tag_dict['tipo'] == TAG_RECUENTO:
                sesion.recuento = Recuento.desde_tag(tag_dict['datos'])
                sesion.mesa = sesion.recuento.mesa

                def _inner():
                    if self.rampa.tiene_papel:
                        self.rampa.expulsar_boleta()
                    self.revision_recuento()
                gobject.timeout_add(1000, _inner)

            else:
                def _expulsar():
                    if self.rampa.tiene_papel and self.rampa.datos_tag and self.estado != E_SETUP:
                        self.controller.set_mensaje(_("acta_contiene_informacion"))
                        self.rampa.expulsar_boleta()
                gobject.timeout_add(300, _expulsar)

    def _show_pantalla_inicial(self):
        self.controller._inicializa_pantalla()

    def set_print_manager(self, callback):
        self.print_manager = PrintManager(self, callback)

    def revision_recuento(self):
        self.estado = E_VERIFICACION
        if not USAR_CEF:
            self._descargar_ui_web()
        self.controller = self.controller_recuento(self)
        self.set_print_manager(self.controller
                               .set_pantalla_impresion_certificados)
        self.print_manager.callback = self.print_manager.reset_copias
        self._cargar_ui_recuento()
        self.controller.set_pantalla_impresion_certificados()
        self.habilitar_impresion_certificados()
        self.copiar_certificados()
        sesion.impresora.remover_consultar_tarjeta()
        if USA_ARMVE:
            self.rampa.registrar_nuevo_papel(
                self._impresion_copias_certificados)
        else:
            self.rampa.remover_nuevo_papel()
            sesion.impresora.registrar_insertando_papel(
                self._impresion_copias_certificados)

    def ingreso_papel(self):
        self.estado = E_SETUP

    def posicion_recuento(self):
        if USA_ARMVE:
            sesion.impresora.linefeed(DESPLAZAMIENTO_BOLETA * 4)
        else:
            sesion.impresora.backfeed(DESPLAZAMIENTO_BOLETA)

    def guardar_datos_del_presidente(self, autoridades, hora):
        """
        Recibe un instancia de Presidente de Mesa, con los datos que cargo el
        usuario.
        """
        #sesion.impresora.remover_consultar_tarjeta()
        sesion.recuento = Recuento(sesion.mesa, autoridades, hora)
        sesion.mesa = sesion.recuento.mesa
        self.estado = E_RECUENTO
        if not USAR_CEF:
            self._descargar_ui_web()
        self.controller = self.controller_recuento(self)
        self.set_print_manager(self.controller.set_pantalla_asistente_cierre)
        # Cargamos la interfaz web, lo que inicia la pantalla recuento.
        self._cargar_ui_recuento()

    def ver_acta_de_cierre(self):
        """  Callback de salida del estado de recuento, es cuando el usuario
        presiona 'Terminar escrutinio'."""
        self.estado = E_RESULTADO
        self.controller.set_pantalla_confirmacion()

    def _finalizar(self):
        """ Funcion llamada desde el controller cuando se desea finalizar el
        recuento"""
        if sesion.recuento.boletas_contadas() < MINIMO_BOLETAS_RECUENTO:
            mensaje = {
                "alerta": _("pocas_boletas_alerta") % MINIMO_BOLETAS_RECUENTO,
                "pregunta": _("pocas_boletas_pregunta"),
                "aclaracion": _("pocas_boletas_aclaracion")}
            self.show_dialogo(mensaje=mensaje,
                              btn_cancelar=True,
                              btn_aceptar=True,
                              callback_aceptar=self.ver_acta_de_cierre,
                              callback_cancelar=None)
        else:
            self.ver_acta_de_cierre()

    def _imprimir(self):
        """ Pide confirmación del usuario para guardar e imprimir los
        resultados mostrados """

        mensaje = {"pregunta": _("esta_seguro_acta_cierre")}
        self.show_dialogo(mensaje=mensaje,
                          btn_cancelar=True,
                          btn_aceptar=True,
                          callback_aceptar=self._iniciar_impresion,
                          callback_cancelar=self.controller.cancelar_impresion)

    def _iniciar_impresion(self):
        """ Realiza las ultimas operaciones sobre el recuento antes de comenzar
            la impresion
        """

        def pre_impresion(tipo_acta):
            self.controller.mostrar_imprimiendo(tipo_acta)
            self.controller.hide_dialogo()

        def esperando_papel(tipo_acta):
            self.controller.pedir_acta(tipo_acta[0])

        self.print_manager.imprimir_secuencia(
            False, pre_impresion, waiting_paper_callback=esperando_papel)

    def _lee_tag(self):
        """ Función para obtener un tag y devolver sus datos o vacío """
        if USA_ARMVE:
            tag = self.rampa.datos_tag
        else:
            tag = sesion.lector.get_tag()
        try:
            datos = tag['datos']
        except:
            datos = ''
        return datos

    def set_campos_extra(self, campos_recuento):
        for lista in get_config("listas_especiales"):
            sesion.recuento.actualizar_lista_especial(lista,
                                                      campos_recuento[lista])

    def get_campos_extra(self):
        campos_extra = []
        campos_extra.append({"codigo": "",
                             "titulo": _("boletas_procesadas"),
                             "editable": False,
                             "valor": sesion.recuento.boletas_contadas()})

        for lista in get_config("listas_especiales"):
            campos_extra.append(
                {"codigo": lista,
                 "titulo": _("titulo_votos_%s" % lista[-3:]),
                 "editable": True,
                 "valor": sesion.recuento.listas_especiales[lista]})

        total = 0
        for campo in campos_extra:
            total += campo.get('valor', 0)
        campos_extra.append({"codigo": COD_TOTAL,
                             "titulo": _("total_general"),
                             "editable": False,
                             "valor": total})
        return campos_extra

    def copiar_certificados(self):
        """  Callback de salida del estado de recuento, es cuando el usuario
        comienza la copia de certificados."""
        self.estado = E_RESULTADO
        self.print_manager.callback = self.print_manager.reset_copias
        self.controller.set_pantalla_impresion_certificados()
        self.habilitar_impresion_certificados()

    def habilitar_impresion_certificados(self):
        if USA_ARMVE:
            self.rampa.registrar_nuevo_papel(
                self._impresion_copias_certificados)
        else:
            sesion.impresora.registrar_insertando_papel(
                self._impresion_copias_certificados)

    def _impresion_copias_certificados(self, datos_sensores):
        self.controller.deshabilitar_botones()
        self.controller.set_panel_estado(RECUENTO_GENERANDO)

        def _inner():
            tag = self.rampa.datos_tag
            if not tag:
                if self.estado == E_RESULTADO:
                    # Si estoy imprimiendo certificados extra despues de un
                    # recuento completo seteo los callback para dar
                    # feedback

                    def pre_impresion(tipo_acta):
                        pass

                    def post_impresion(tipo_acta):
                        pass

                    def esperando_papel(tipo_acta):
                        pass

                    self.print_manager.imprimir_secuencia(True,
                                                            pre_impresion,
                                                            post_impresion,
                                                            esperando_papel)
                else:
                    # En otro caso (levanto un recuento ya grabado) solo
                    # mando a imprimir la secuencia.
                    self.print_manager.imprimir_secuencia(True)
            else:
                self.rampa.expulsar_boleta()
                self.controller.habilitar_botones()
                self.controller.limpiar_panel_estado()
                mensaje = {"alerta": _("certificado_no_impreso_alerta"),
                            "aclaracion": _(
                                "certificado_no_impreso_aclaracion")}
                self.show_dialogo(mensaje=mensaje, btn_aceptar=True)

        gobject.timeout_add(200, _inner)

    def cargar_apertura(self, tag_dict):
        apertura = Apertura.desde_tag(tag_dict['datos'])
        if (self.controller.estado == E_INGRESO_DATOS and
                sesion.mesa.numero == apertura.mesa.numero) or \
                self.controller.estado != E_INGRESO_DATOS:
            self.apertura = apertura
            self.controller.set_pantalla({"mesa": apertura.mesa.numero})

    def salir(self):
        """ Sale del módulo de recuento, vuelve al comienzo con la maquina
        desconfigurada."""
        mensaje = {"pregunta": _("seguro_salir_recuento")}
        self.show_dialogo(mensaje=mensaje,
                          btn_aceptar=True,
                          btn_cancelar=True,
                          callback_aceptar=self.quit,
                          callback_cancelar=None,
                          error=False)

    def quit(self, w=None):
        #self._stop_audio()
        self.ret_code = MODULO_INICIO
        #self._descargar_ui_web()
        Modulo.quit(self)

    def mensaje_inicial(self):
        if hasattr(self.controller, "mensaje_inicial"):
            self.controller.mensaje_inicial()

    def volver(self, admin=False, tag=None, datos_tag=None):
        """ Callback para volver del estado de resultado al de recuento y
        seguir recontando votos."""
        if admin is True or self.estado == E_RECUENTO:
            self.administrador()
        else:
            self.estado = E_RECUENTO
            self.controller.set_pantalla_recuento()
            if tag is not None and datos_tag is not None:
                self._tag_disponible(self.TAG_DATOS, tag, datos_tag)

    def administrador(self, callback_ok=None, callback_cancel=None):
        mensaje = {"pregunta": _("seguro_salir_recuento")}
        self.show_dialogo(mensaje=mensaje,
                          btn_aceptar=True,
                          btn_cancelar=True,
                          callback_aceptar=self.salir_a_administrador,
                          callback_cancelar=None)

    def salir_a_administrador(self):
        if self._ui_web_activa:
            self._descargar_ui_web()
            #self._cargar_ui()
        self.rampa.desregistrar_eventos()
        sesion.recuento = None
        self.rampa.expulsar_boleta()
        self._stop_audio()
        self.admin()

    def _stop_audio(self):
        global _audio_player
        if _audio_player is not None:
            _audio_player.stop()

    def show_dialogo(self, mensaje=None, callback_cancelar=None,
                     callback_aceptar=None, btn_cancelar=None,
                     btn_aceptar=None, error=True):
        self.controller.show_dialogo(mensaje, callback_cancelar,
                                     callback_aceptar, btn_cancelar,
                                     btn_aceptar, error=error)
Exemplo n.º 4
0
class ModuloRecuento(Modulo):
    """ Modulo de Recuento de votos.

        Este módulo permite hacer el recuento de votos de una mesa.
        El usuario debe pasar el tag a ser utilizado para el recuento de la
        mesa, y a continuacion debe pasar todas las boletas por el lector.
        El sistema va a totalizarlas y una vez que el usuario confirme el
        cierre de la mesa, emite un listado con la cantidad de copias
        indicadas.

    E_INICIAL = 0
    E_SETUP = 1
    E_RECUENTO = 2
    E_RESULTADO = 3
    E_VERIFICACION = 4
    """
    controller_recuento = ControllerRecuento

    def __init__(self):
        """Constructor"""
        self.send_function = None
        # El primer controller es ControllerInteraccion porque es el que maneja
        # el ingreso de datos de mesa y pin y autoridades
        self.web_template = "recuento"
        self._cargar_controller_interaccion()
        self.es_modulo_web = True
        Modulo.__init__(self)
        self.ret_code = MODULO_RECUENTO
        self.estado = E_INICIAL
        self._intento = 0
        self._ui_web_activa = True  # Flag que indica si esta activa la ui web
        self.apertura = None
        """
        if USA_ARMVE:
            power_source = sesion.powermanager.get_power_source()
            if power_source is not None and not power_source['byte']:
                sesion.fancoolers.set_fan_auto_mode(False)
                sesion.fancoolers.set_fan_speed(100)
        """
        self.rampa = RampaRecuento(self)

    def _cargar_controller_interaccion(self):
        self.controller = ControllerInteraccion(self)

    def _cargar_ui_web(self):
        Modulo._cargar_ui_web(self)

    def _cargar_ui_recuento(self):
        Modulo._cargar_ui_web(self)
        self.ventana.show_all()

    def reiniciar_modulo(self):
        if self.rampa.tiene_papel and self.estado == E_SETUP:
            pass
        else:
            self.estado = E_INICIAL
            self.controller.estado = E_INGRESO_ACTA
            self.controller._inicializa_pantalla()

    def _inicio(self):
        """ Funcion llamada desde el controller una vez que se encuentra lista
            la interfaz web
        """
        self.controller.set_panel_estado(RECUENTO_NO_TAG)

        if self.estado == E_RECUENTO:
            #self.controller.set_pantalla_recuento()
            pass
        elif self.estado == E_VERIFICACION:
            self.print_manager.callback = self.print_manager.reset_copias
            sesion.recuento.autoridades = None
            #self.controller.set_pantalla_revision()

    def procesar_tag(self, tag_dict):
        """ Evento. Procesa el tag recibido por parametro. Cumple la funcion
            del procesar_tag() de PantallaRecuento de recuento Gtk.

            Argumentos:
            tag   -- El objeto TAG recibido.
            datos -- Los datos almacenados en el tag recibido.

            Si el tag no es ICODE se descarta el evento.
            Si su tipo no es voto, o está vacío, se devuelve error.
            Se intenta sumar los datos al recuento, si devuelve False
            es porque el tag ya fue sumado, sino está ok.
        """
        if self.estado == E_RECUENTO:
            serial = tag_dict.get('serial')
            tipo_tag = tag_dict.get('tipo')
            datos = tag_dict.get('datos')
            if None in (serial, tipo_tag, datos) or tipo_tag != TAG_VOTO:
                self.controller.set_panel_estado(RECUENTO_ERROR)
            else:
                self.controller.hide_dialogo()
                try:
                    seleccion = Seleccion.desde_tag(datos, sesion.mesa)
                    if not sesion.recuento.serial_sumado(serial):
                        sesion.recuento.sumar_seleccion(seleccion, serial)
                        sesion.recuento.hora_fin = time.time()
                        sesion.ultima_seleccion = seleccion

                        # Dibujo boleta
                        imagen = seleccion.a_imagen(verificador=False,
                                                    solo_mostrar=True,
                                                    svg=True)
                        image_data = quote(imagen.encode("utf-8"))

                        cant_leidas = sesion.recuento.boletas_contadas()
                        self.controller.actualizar_resultados(
                            sesion.ultima_seleccion, cant_leidas, image_data)
                        gobject.timeout_add(200,
                                            self.controller.set_panel_estado,
                                            RECUENTO_OK)
                    else:
                        self.controller.set_panel_estado(
                            RECUENTO_ERROR_REPETIDO)
                except Exception as e:
                    print(e)
                    self.controller.set_panel_estado(RECUENTO_ERROR)
        elif self.controller.__class__.__name__ == "ControllerInteraccion":
            read_only = tag_dict.get("read_only")
            if self.rampa.tiene_papel and not read_only and self.estado not in \
                    (E_SETUP, E_VERIFICACION) and tag_dict['tipo'] in \
                    (TAG_VACIO, [0, 0]):
                self.estado = E_SETUP
                self.controller.estado = E_MESAYPIN
                self.controller.set_pantalla()
                self.posicion_recuento()
            elif self.estado in E_INICIAL and tag_dict['tipo'] == TAG_RECUENTO:
                sesion.recuento = Recuento.desde_tag(tag_dict['datos'])
                sesion.mesa = sesion.recuento.mesa

                def _inner():
                    if self.rampa.tiene_papel:
                        self.rampa.expulsar_boleta()
                    self.revision_recuento()

                gobject.timeout_add(1000, _inner)

            else:

                def _expulsar():
                    if self.rampa.tiene_papel and self.rampa.datos_tag and self.estado != E_SETUP:
                        self.controller.set_mensaje(
                            _("acta_contiene_informacion"))
                        self.rampa.expulsar_boleta()

                gobject.timeout_add(300, _expulsar)

    def _show_pantalla_inicial(self):
        self.controller._inicializa_pantalla()

    def set_print_manager(self, callback):
        self.print_manager = PrintManager(self, callback)

    def revision_recuento(self):
        self.estado = E_VERIFICACION
        if not USAR_CEF:
            self._descargar_ui_web()
        self.controller = self.controller_recuento(self)
        self.set_print_manager(
            self.controller.set_pantalla_impresion_certificados)
        self.print_manager.callback = self.print_manager.reset_copias
        self._cargar_ui_recuento()
        self.controller.set_pantalla_impresion_certificados()
        self.habilitar_impresion_certificados()
        self.copiar_certificados()
        sesion.impresora.remover_consultar_tarjeta()
        if USA_ARMVE:
            self.rampa.registrar_nuevo_papel(
                self._impresion_copias_certificados)
        else:
            self.rampa.remover_nuevo_papel()
            sesion.impresora.registrar_insertando_papel(
                self._impresion_copias_certificados)

    def ingreso_papel(self):
        self.estado = E_SETUP

    def posicion_recuento(self):
        if USA_ARMVE:
            sesion.impresora.linefeed(DESPLAZAMIENTO_BOLETA * 4)
        else:
            sesion.impresora.backfeed(DESPLAZAMIENTO_BOLETA)

    def guardar_datos_del_presidente(self, autoridades, hora):
        """
        Recibe un instancia de Presidente de Mesa, con los datos que cargo el
        usuario.
        """
        #sesion.impresora.remover_consultar_tarjeta()
        sesion.recuento = Recuento(sesion.mesa, autoridades, hora)
        sesion.mesa = sesion.recuento.mesa
        self.estado = E_RECUENTO
        if not USAR_CEF:
            self._descargar_ui_web()
        self.controller = self.controller_recuento(self)
        self.set_print_manager(self.controller.set_pantalla_asistente_cierre)
        # Cargamos la interfaz web, lo que inicia la pantalla recuento.
        self._cargar_ui_recuento()

    def ver_acta_de_cierre(self):
        """  Callback de salida del estado de recuento, es cuando el usuario
        presiona 'Terminar escrutinio'."""
        self.estado = E_RESULTADO
        self.controller.set_pantalla_confirmacion()

    def _finalizar(self):
        """ Funcion llamada desde el controller cuando se desea finalizar el
        recuento"""
        if sesion.recuento.boletas_contadas() < MINIMO_BOLETAS_RECUENTO:
            mensaje = {
                "alerta": _("pocas_boletas_alerta") % MINIMO_BOLETAS_RECUENTO,
                "pregunta": _("pocas_boletas_pregunta"),
                "aclaracion": _("pocas_boletas_aclaracion")
            }
            self.show_dialogo(mensaje=mensaje,
                              btn_cancelar=True,
                              btn_aceptar=True,
                              callback_aceptar=self.ver_acta_de_cierre,
                              callback_cancelar=None)
        else:
            self.ver_acta_de_cierre()

    def _imprimir(self):
        """ Pide confirmación del usuario para guardar e imprimir los
        resultados mostrados """

        mensaje = {"pregunta": _("esta_seguro_acta_cierre")}
        self.show_dialogo(mensaje=mensaje,
                          btn_cancelar=True,
                          btn_aceptar=True,
                          callback_aceptar=self._iniciar_impresion,
                          callback_cancelar=self.controller.cancelar_impresion)

    def _iniciar_impresion(self):
        """ Realiza las ultimas operaciones sobre el recuento antes de comenzar
            la impresion
        """
        def pre_impresion(tipo_acta):
            self.controller.mostrar_imprimiendo(tipo_acta)
            self.controller.hide_dialogo()

        def esperando_papel(tipo_acta):
            self.controller.pedir_acta(tipo_acta[0])

        self.print_manager.imprimir_secuencia(
            False, pre_impresion, waiting_paper_callback=esperando_papel)

    def _lee_tag(self):
        """ Función para obtener un tag y devolver sus datos o vacío """
        if USA_ARMVE:
            tag = self.rampa.datos_tag
        else:
            tag = sesion.lector.get_tag()
        try:
            datos = tag['datos']
        except:
            datos = ''
        return datos

    def set_campos_extra(self, campos_recuento):
        for lista in get_config("listas_especiales"):
            sesion.recuento.actualizar_lista_especial(lista,
                                                      campos_recuento[lista])

    def get_campos_extra(self):
        campos_extra = []
        campos_extra.append({
            "codigo": "",
            "titulo": _("boletas_procesadas"),
            "editable": False,
            "valor": sesion.recuento.boletas_contadas()
        })

        for lista in get_config("listas_especiales"):
            campos_extra.append({
                "codigo":
                lista,
                "titulo":
                _("titulo_votos_%s" % lista[-3:]),
                "editable":
                True,
                "valor":
                sesion.recuento.listas_especiales[lista]
            })

        total = 0
        for campo in campos_extra:
            total += campo.get('valor', 0)
        campos_extra.append({
            "codigo": COD_TOTAL,
            "titulo": _("total_general"),
            "editable": False,
            "valor": total
        })
        return campos_extra

    def copiar_certificados(self):
        """  Callback de salida del estado de recuento, es cuando el usuario
        comienza la copia de certificados."""
        self.estado = E_RESULTADO
        self.print_manager.callback = self.print_manager.reset_copias
        self.controller.set_pantalla_impresion_certificados()
        self.habilitar_impresion_certificados()

    def habilitar_impresion_certificados(self):
        if USA_ARMVE:
            self.rampa.registrar_nuevo_papel(
                self._impresion_copias_certificados)
        else:
            sesion.impresora.registrar_insertando_papel(
                self._impresion_copias_certificados)

    def _impresion_copias_certificados(self, datos_sensores):
        self.controller.deshabilitar_botones()
        self.controller.set_panel_estado(RECUENTO_GENERANDO)

        def _inner():
            tag = self.rampa.datos_tag
            if not tag:
                if self.estado == E_RESULTADO:
                    # Si estoy imprimiendo certificados extra despues de un
                    # recuento completo seteo los callback para dar
                    # feedback

                    def pre_impresion(tipo_acta):
                        pass

                    def post_impresion(tipo_acta):
                        pass

                    def esperando_papel(tipo_acta):
                        pass

                    self.print_manager.imprimir_secuencia(
                        True, pre_impresion, post_impresion, esperando_papel)
                else:
                    # En otro caso (levanto un recuento ya grabado) solo
                    # mando a imprimir la secuencia.
                    self.print_manager.imprimir_secuencia(True)
            else:
                self.rampa.expulsar_boleta()
                self.controller.habilitar_botones()
                self.controller.limpiar_panel_estado()
                mensaje = {
                    "alerta": _("certificado_no_impreso_alerta"),
                    "aclaracion": _("certificado_no_impreso_aclaracion")
                }
                self.show_dialogo(mensaje=mensaje, btn_aceptar=True)

        gobject.timeout_add(200, _inner)

    def cargar_apertura(self, tag_dict):
        apertura = Apertura.desde_tag(tag_dict['datos'])
        if (self.controller.estado == E_INGRESO_DATOS and
                sesion.mesa.numero == apertura.mesa.numero) or \
                self.controller.estado != E_INGRESO_DATOS:
            self.apertura = apertura
            self.controller.set_pantalla({"mesa": apertura.mesa.numero})

    def salir(self):
        """ Sale del módulo de recuento, vuelve al comienzo con la maquina
        desconfigurada."""
        mensaje = {"pregunta": _("seguro_salir_recuento")}
        self.show_dialogo(mensaje=mensaje,
                          btn_aceptar=True,
                          btn_cancelar=True,
                          callback_aceptar=self.quit,
                          callback_cancelar=None,
                          error=False)

    def quit(self, w=None):
        #self._stop_audio()
        self.ret_code = MODULO_INICIO
        #self._descargar_ui_web()
        Modulo.quit(self)

    def mensaje_inicial(self):
        if hasattr(self.controller, "mensaje_inicial"):
            self.controller.mensaje_inicial()

    def volver(self, admin=False, tag=None, datos_tag=None):
        """ Callback para volver del estado de resultado al de recuento y
        seguir recontando votos."""
        if admin is True or self.estado == E_RECUENTO:
            self.administrador()
        else:
            self.estado = E_RECUENTO
            self.controller.set_pantalla_recuento()
            if tag is not None and datos_tag is not None:
                self._tag_disponible(self.TAG_DATOS, tag, datos_tag)

    def administrador(self, callback_ok=None, callback_cancel=None):
        mensaje = {"pregunta": _("seguro_salir_recuento")}
        self.show_dialogo(mensaje=mensaje,
                          btn_aceptar=True,
                          btn_cancelar=True,
                          callback_aceptar=self.salir_a_administrador,
                          callback_cancelar=None)

    def salir_a_administrador(self):
        if self._ui_web_activa:
            self._descargar_ui_web()
            #self._cargar_ui()
        self.rampa.desregistrar_eventos()
        sesion.recuento = None
        self.rampa.expulsar_boleta()
        self._stop_audio()
        self.admin()

    def _stop_audio(self):
        global _audio_player
        if _audio_player is not None:
            _audio_player.stop()

    def show_dialogo(self,
                     mensaje=None,
                     callback_cancelar=None,
                     callback_aceptar=None,
                     btn_cancelar=None,
                     btn_aceptar=None,
                     error=True):
        self.controller.show_dialogo(mensaje,
                                     callback_cancelar,
                                     callback_aceptar,
                                     btn_cancelar,
                                     btn_aceptar,
                                     error=error)