oauth.consumerKey=XXXXXXXXXX oauth.consumerSecret=YYYYYYYYYYYYYYYYYYYYYY oauth.accessToken=527902906-asdfdsafassssssssssssssss oauth.accessTokenSecret=123mlkjdfd9sfldsjlkj
23 November 2017
Nuestra empresa ha entrado con ganas en el mundo de las redes sociales y quiere generar contenido sobre nuestros productos. Hasta hemos contratado a una persona que se va a encargar de generarlos y publicarlos en Twitter.
Esta persona querría poder compartir de una forma sencilla los "Top Ventas" de nuestros productos así que para ello todos los días te pide que le busques en las bases de datos qué 3 productos son los más vendidos y cuantas unidades hemos vendido de ellos.
Con esta información, y mediante alguna aplicación ofimática tipo Excel, es capaz de generar un gráfico de tartas, salvar la imagen a su disco, abrir Twitter, escribir un mensaje, adjuntar la imagen y twittearla. Fácil. Pesado. Laborioso.
Para poder publicar tweets de forma automática, el primer paso es crear una app en https://apps.twitter.com/ para que Twitter nos genere un conjunto de claves. Si sigues los pasos que ofrece la página al final del proceso obtendras 4 claves que deberás guardar en el fichero twitter4j.properties en el mismo directorio que resida nuestro script.
oauth.consumerKey=XXXXXXXXXX oauth.consumerSecret=YYYYYYYYYYYYYYYYYYYYYY oauth.accessToken=527902906-asdfdsafassssssssssssssss oauth.accessTokenSecret=123mlkjdfd9sfldsjlkj
Nuestro script va a necesitar las siguientes dependencias agrupadas por funcionalidad:
@GrabConfig(systemClassLoader=true)
@Grab('mysql:mysql-connector-java:5.1.6')
@Grab(group='org.groovyfx',module='groovyfx',version='8.0.0',transitive=false, noExceptions=true)
@Grab(group='org.twitter4j', module='twitter4j-core', version='4.0.6')
import groovy.sql.Sql
import static groovyx.javafx.GroovyFX.start
import javafx.application.Platform
import javafx.scene.SnapshotParameters
import javax.imageio.ImageIO
import java.awt.image.BufferedImage
import twitter4j.TwitterFactory;
import twitter4j.StatusUpdate
Básicamente:
conexión a la base de datos
librerías graficas JavaFX
librería de twitter
Para poder ajustar nuestro script de forma cómoda vamos a utilizar las siguientes variables:
String message ="""
Estamos que nos salimos!!!
Top Ventas de nuestro catálogo. Gracias a todos por elegirnos
#groovy-script
"""
String chartTitle="Top Ventas"
int width=height=400
Obtener los productos más vendidos puede ser desde una operación trivial hasta una operación compleja de agregados. Eso ya dependerá de tu negocio. Para nuestro caso vamos a suponer que disponemos de una tabla MySQL donde ya se encuentran agregados las ventas por su descripción
def data=[:] //(1)
Sql sql = Sql.newInstance( "jdbc:mysql://localhost:3306/scripts?jdbcCompliantTruncation=false",
"root",
"my-secret-pw",
"com.mysql.jdbc.Driver")
sql.eachRow("select product_name, sales from sales order by sales limit 4"){
data[it.product_name] = it.sales as double //(2)
}
Usaremos un mapa "producto"=unidades para generar el gráfico de tartas
Buscamos en la bbdd e insertamos en nuestro mapa
En esta parte podremos usar infinidad de técnicas y capacidades que nos ofrece JavaFX, como por ejemplo objetos 3D, rotaciones, hojas de estilo, etc. Por ahora a nosotros nos bastará con un gráfico de tartas donde se reflejen los productos obtenidos anteriormente y un título para el gráfico.
Una vez renderizado el gráfico nos interesará hacer una foto (snapshot) al nodo en concreto que contiene el gráfico y volcar a fichero la imagen (en formato PNG).
start {
def saveNode //(1)
stage(visible: true) { //(2)
scene(fill: BLACK, width: width, height: height) {
saveNode = tilePane() {
pieChart(data: data, title: chartTitle) //(3)
}
}
}
saveNode será una referencia al nodo que contiene el gráfico
creamos un gráfico de tartas con los datos obtenidos en la bbdd y almacenados en el mapa
asignamos la referencia para poder usarla después
Una vez que la scene JavaFX se encuentra lista realizamos el volcado. Básicamente pediremos a JavaFX que nos vuelque en un objeto Image los pixeles y así podamos convertirlos a fichero PNG
def snapshot = saveNode.snapshot(new SnapshotParameters(), null);
BufferedImage bufferedImage = new BufferedImage(saveNode.width as int, saveNode.height as int, BufferedImage.TYPE_INT_ARGB);
BufferedImage image = javafx.embed.swing.SwingFXUtils.fromFXImage(snapshot, bufferedImage)
File file = new File('screenshot.png')
ImageIO.write(image, "png", file )
Generar un tweet mediante twitter4j es tan sencillo como crear un StatusUpdate, adjuntar un fichero si así lo deseamos y enviarlo:
StatusUpdate status = new StatusUpdate(message) //(1)
status.media(file ) //(2)
TwitterFactory.singleton.updateStatus status
El mensaje que definimos en la parte de customizacion al principio
El fichero png screenshot que hemos generado en el apartado anterior
Aquí puedes ver cómo quedaría un tweet:
Por último una vez cumplida su misión simplemente indicamos a JavaFX que cierre la ventana automáticamente
Platform.exit();
System.exit(0);
//tag::dependencies[]
@GrabConfig(systemClassLoader=true)
@Grab('mysql:mysql-connector-java:5.1.6')
@Grab(group='org.groovyfx',module='groovyfx',version='8.0.0',transitive=false, noExceptions=true)
@Grab(group='org.twitter4j', module='twitter4j-core', version='4.0.6')
import groovy.sql.Sql
import static groovyx.javafx.GroovyFX.start
import javafx.application.Platform
import javafx.scene.SnapshotParameters
import javax.imageio.ImageIO
import java.awt.image.BufferedImage
import twitter4j.TwitterFactory;
import twitter4j.StatusUpdate
//end::dependencies[]
//tag::customize[]
String message ="""
Estamos que nos salimos!!!
Top Ventas de nuestro catálogo. Gracias a todos por elegirnos
#groovy-script
"""
String chartTitle="Top Ventas"
int width=height=400
//end::customize[]
//tag::business[]
def data=[:] //(1)
Sql sql = Sql.newInstance( "jdbc:mysql://localhost:3306/scripts?jdbcCompliantTruncation=false",
"root",
"my-secret-pw",
"com.mysql.jdbc.Driver")
sql.eachRow("select product_name, sales from sales order by sales limit 4"){
data[it.product_name] = it.sales as double //(2)
}
//end::business[]
//tag::vista[]
start {
def saveNode //(1)
stage(visible: true) { //(2)
scene(fill: BLACK, width: width, height: height) {
saveNode = tilePane() {
pieChart(data: data, title: chartTitle) //(3)
}
}
}
//end::vista[]
//tag::snapshot[]
def snapshot = saveNode.snapshot(new SnapshotParameters(), null);
BufferedImage bufferedImage = new BufferedImage(saveNode.width as int, saveNode.height as int, BufferedImage.TYPE_INT_ARGB);
BufferedImage image = javafx.embed.swing.SwingFXUtils.fromFXImage(snapshot, bufferedImage)
File file = new File('screenshot.png')
ImageIO.write(image, "png", file )
//end::snapshot[]
//tag::twitter[]
StatusUpdate status = new StatusUpdate(message) //(1)
status.media(file ) //(2)
TwitterFactory.singleton.updateStatus status
//end::twitter[]
//tag::exit[]
Platform.exit();
System.exit(0);
//end::exit[]
}