Fullmenu null

 

09 April 2019

Para este post vamos a necesitar los siguientes requisitos: una cuenta en Google y una hoja de cálculo Sheet de Google. La estructura de la hoja puede ser como quieras pero para este caso vamos a usar las 3 primeras columnas con los valores "nombre", "apellido" y "email"

En este post vamos a utilizar un GroovyScript para leer una hoja Sheet de Google donde los asistentes a una charla se han registrado (tal vez con Google Form) para realizar un sorteo eligiendo a uno de ellos al azar. Si el elegido no se encuentra (o rechaza el premio) se le elimina de la lista y se vuelve a realizar el sorteo.

Consola Google

En primer lugar deberemos crear una aplicación en la consola de Google en https://console.developers.google.com

En esta aplicación habilitaremos (al menos) la API "Google Sheet API"

Así mismo deberemos crear unas credenciales de "usuario" obteniendo la posibilidad de descargarlas en un fichero JSON y que deberemos ubicar junto con el script.

Groogle

Para facilitar la parte técnica de autentificación y creación de servicios he creado un proyecto de código abierto, Groogle, disponible en https://groogle.gitlab.com/ el cual publica un artefacto en Bintray y que podremos usar en nuestros scripts simplemente incluyendo su repositorio.

@Grab(group='com.puravida.groogle', module='groogle-sheet', version='2.0.0')
import com.google.api.services.sheets.v4.SheetsScopes
import com.puravida.groogle.*
import com.puravida.groogle.sheet.*
import groovy.swing.SwingBuilder

import java.awt.BorderLayout
import java.awt.BorderLayout as BL
import javax.swing.*

Groogle nos permitirá realizar el login de nuestra aplicación y guardar la autorización en nuestro disco de tal forma que en ejecuciones posteriores no se requiera de autorizar de nuevo la aplicación (mientras no borremos el fichero con la autorización generada)

    credentials {
        applicationName 'raffle'
        withScopes SheetsScopes.SPREADSHEETS
        usingCredentials "client_secret.json"
        asService false
    }
    service(SheetServiceBuilder.build(), SheetService)
  1. client-secret.json es el fichero que hemos descargado de la consola de Google y que contiene las credenciales

  2. Groogle realiza el login y guarda la autorización en $HOME/.credentials/${applicationName}

  3. En este post únicamente requerimos acceso a Sheet para lectura

Leyendo la hoja

Mediante un bucle iremos recuperando filas en bloques de 100 hasta que no haya más elementos y los iremos añadiendo a un List

(La hoja se puede llamar como se desee, por ejemplo una hoja por cada Meetup y sería fácilmente adaptable para ser proporcionada por parámetro. En este ejemplo vamos a usar raffle-example-meetup-1 )

    withSheet 'raffle-example-meetup-1', {
        int i=2
        range = writeRange("A$i", "C${i+99}").get()
        while( range ){
            all.addAll range
            i+=99
            range = writeRange("A$i", "C${i+99}").get()
        }
    }

Presentación

Para la interface de usuario vamos a utilizar SwingBuilder , un DSL de groovy, que permite crear interfaces Swing de forma fácil.

Nuestro interface va a consistir básicamente en un JList con el array de asistentes y un botón que realizará la acción de elegir uno de ellos aleatoriamente.

Tras mostrar el elegido, si el moderador lo desea puede indicar que el asistente no está para repetir el sorteo sin él.

new SwingBuilder().edt {
    frame(title: 'GroogleRaffe',
            defaultCloseOperation: JFrame.EXIT_ON_CLOSE,
            extendedState: JFrame.MAXIMIZED_BOTH,
            show: true) {

        borderLayout()

        panel(constraints: BorderLayout.PAGE_START){
            label("Meetup Raffle")
        }

        panel(constraints: BorderLayout.PAGE_END){
            button(text:'Raffle',
                    actionPerformed: {
                        Random rnd = new Random()
                        int selected = rnd.nextInt(all.size())
                        String msg = "<html><b>Is <font color='red'>${all[selected][0]} ${all[selected][1]} here ?</font></b></html>"
                        int yepes = JOptionPane.showConfirmDialog(current,msg)
                        if( yepes != JOptionPane.YES_OPTION  ){
                            theList.model.remove(selected)
                        }
                    }, constraints:BL.SOUTH)

        }

        scrollPane(constraints: BorderLayout.CENTER){
            list(id:'theList', listData: all,
                    cellRenderer: { list, value, index, isSelected, cellHasFocus->
                        new JLabel(value[0]+" "+value[1])
                    }
            )
        }

    }
}

Ejemplo

raffle