#!/usr/bin/python
# coding: utf-8
 
#--------------------------------------------------------------------
# Fichero:  prepara.py
# Objetivo: Preparar la base de datos para hacer una encuesta
# Autor:    Pedro Reina <pedro@pedroreina.net>
# Fecha:    S.10.12.2016
# Licencia: CC0 1.0 Universal
#           https://creativecommons.org/publicdomain/zero/1.0/
#--------------------------------------------------------------------
 
#------------------------------------------------
# Variables del programa
#------------------------------------------------
 
# El archivo con las preguntas. Codificación UTF-8
Origen = 'pregunta.txt'
 
# El archivo con la base de datos
Destino = 'encuesta.db'
 
# El PDF para imprimir
Documento = 'encuesta.pdf'
 
# Primera linea del documento
Titulo = 'Encuesta sobre el profesor Pedro Reina'
 
# Web de la encuesta
Web = u'Dirección web: http://pedroreina.net/encuesta'
 
# Fecha de inicio del plazo para responder la encuesta
Inicio = '2016-12-10'
 
# Fecha de final del plazo para responder la encuesta
Final = '2016-12-21'
 
# Caracteres para generar los códigos
Validos = 'abcdefghjmnpqrstuyz23456789'
 
# Longitud de los códigos
Longitud = 6
 
# Los márgenes de la página, en centímetros
MargenIzquierdo = 2
MargenSuperior = 4
 
# La distancia entre líneas de texto, en centímetros
Interlineado = 1
 
#------------------------------------------------
# Módulos necesarios
#------------------------------------------------
 
# Another Python SQLite Wrapper
import apsw
 
# Para leer la línea de órdenes
import sys
 
# Para leer archivos en UTF-8
import codecs
 
# Para generar números aleatorios
import random
 
# Creación de PDF con ReportLab
from reportlab.pdfgen import canvas
from reportlab.lib.units import cm
from reportlab.lib.pagesizes import A4
 
#------------------------------------------------
# Variables globales
#------------------------------------------------
 
# La lista con los códigos
ListaCodigos = []
 
#------------------------------------------------
# Funciones
#------------------------------------------------
 
def IntroduceFechas (Conexion):
    Cursor = Conexion.cursor()
 
    Consulta = 'INSERT INTO plazo VALUES ("' + Inicio + '");'
    Cursor.execute (Consulta)
 
    Consulta = 'INSERT INTO plazo VALUES ("' + Final + '");'
    Cursor.execute (Consulta)
 
#------------------------------------------------
 
def IntroducePreguntas (Conexion):
    Consulta = 'INSERT INTO pregunta (texto) VALUES (:Enunciado)'
    Enunciado = ''
 
    Cursor = Conexion.cursor()
    Entrada = codecs.open (Origen, encoding='utf-8', mode='r')
 
    for Linea in Entrada:
        Linea = Linea.strip()
        if len(Linea):
            if len(Enunciado):
                Enunciado += ' ' + Linea
            else:
                Enunciado = Linea
        else:
            Cursor.execute (Consulta, locals())
            Enunciado = ''
 
    Cursor.execute (Consulta, locals())
 
#------------------------------------------------
 
def IntroduceCodigos (Conexion):
    Consulta = 'INSERT INTO codigo (clave) VALUES (:Clave)'
    Obtenidos = 0
 
    Cursor = Conexion.cursor()
 
    # Generamos tantos códigos como nos pidan
    while Obtenidos < Numero:
        Clave = GeneraCodigo (Longitud)
        if not Clave in ListaCodigos:
            ListaCodigos.append (Clave)
            Obtenidos += 1
 
    # Los almacenamos en la base de datos
    for Clave in ListaCodigos:
        Cursor.execute (Consulta, locals())
 
#------------------------------------------------
 
def GeneraCodigo (Longitud):
    # Seleccionamos al azar el número de caracteres pedido
    Seleccion = random.sample(Validos, Longitud)
 
    # Creamos una cadena con los caracteres seleccionados
    Codigo = ''.join(Seleccion)
 
    # Ese es el código que hemos generado
    return Codigo
 
#------------------------------------------------
 
def GeneraDocumento():
    # Preparamos el pdf
    Pdf = canvas.Canvas (Documento, pagesize=A4)
    Pdf.setAuthor ('Pedro Reina')
    Pdf.setTitle (u'Códigos para encuesta')
 
    # Guardamos las dimensiones de la página
    Anchura, Altura = A4
 
    Registro = 1
    for Clave in ListaCodigos:
        if Registro % 2 == 1:
            Linea = Altura - MargenSuperior
        else:
            Linea = Altura / 2 - MargenSuperior
        Pdf.setFont ('Helvetica', 18)
        Pdf.drawString (MargenIzquierdo, Linea, Titulo)
        Linea -= Interlineado
        Pdf.setFont ('Times-Roman', 16)
        Texto = ('Fecha de inicio: ' + Inicio +
                 u'. Fecha de finalización: ' + Final)
        Pdf.drawString (MargenIzquierdo, Linea, Texto)
        Linea -= Interlineado
        Pdf.setFont ('Courier', 16)
        Pdf.drawString (MargenIzquierdo, Linea, Web)
        Linea -= Interlineado
        Pdf.setFont ('Times-Roman', 18)
        Pdf.drawString (MargenIzquierdo, Linea, u'Código de acceso: ' + Clave)
        if Registro % 2 == 0: Pdf.showPage()
        Registro += 1
 
    # Escribimos el PDF
    Pdf.save()
 
#------------------------------------------------
# El programa
#------------------------------------------------
 
# Si no nos pasan dos argumentos (nombre del programa y un
# número entero), nos quejamos y paramos
if len (sys.argv) != 2:
    sys.exit ("Hace falta el número de códigos que generar")
 
# El número de códigos que hay que generar lo tomamos de la
# línea de órdenes
Numero = int (sys.argv[1])
 
# Informamos al usuario
print 'Origen: ' + Origen
print 'Destino: ' + Destino
print 'Documento: ' + Documento
print 'Número de códigos: ' + str(Numero)
print 'Preparando...'
 
# Abrimos conexión a la base de datos
Conexion = apsw.Connection (Destino)
 
# Los pasos individuales para crear la base de datos
IntroduceFechas (Conexion)
IntroducePreguntas (Conexion)
IntroduceCodigos (Conexion)
 
# Cerramos la conexión
Conexion.close (True)
 
# Conversión de medidas: todas las hemos pedido en cm
# pero se usan en puntos tipográficos
MargenIzquierdo *= cm
MargenSuperior *= cm
Interlineado *= cm
 
# Generamos el PDF
GeneraDocumento()
 
# Informamos al usuario
print 'Terminado.'