diumenge, 20 de novembre del 2011

Groovy i HSQLDB

Groovy aporta classes per al treball amb bases de dades que permeten un increment de la productivitat en el desenvolupament de codi d'aplicacions que en facin us.

Dit d'una altre forma: Groovy permet simplificar el codi de les aplicacions de bases de dades.  Res millor que un exemple.

En l'exercici que es proposa faré us de la base de dades HSQLDB, que és el motor de base de dades que es fa servir, per exemple,  a les suites ofimàtiques OpenOffice.org i LibreOffice.

Per a poder utilitzar HSQLDB des de Groovy cal afegir el hsqldb.jar a les llibreries que es carreguen a l'inici. En el cas que m'ocupa, un Groovy sobre Linux Ubuntu, cal revisar el fitxer $GROOVY_HOME/conf/groovy-starter.conf en el que es pot trobar el següent:

    # load user specific libraries
    load !{user.home}/.groovy/lib/*.jar

Tinc l'HSQLDB instal·lat a una carpeta apart. Per tant, per evitar duplicitats, en comptes de posar l'hsqldb.jar a $HOME/.groovy/lib, el que faig és posar en aquesta carpeta un enllaç simbòlic al jar que hi ha a la carpeta on està desplegat el motor de la base de dades.

A continuació, creo una base de dades del tipus fitxer i standalone. Cal dir que HSQLDB pot funcionar en "mode servidor" o  bé en "mode standalone". A més, també pot funcionar o bé mantenint les dades en un fitxer, o bé "mantenint" les dades en memòria (evidentment, només es "mantenen" mentre el procés és viu).

Per a crear la taula es pot fer servir, per exemple, l'OpenOffice.org/LibreOffice Base. En aquest cas caldria afegir hsqldb.jar al classpath de l'OOo/LO (eines - opcions - java)


i camí a les classes:



i, a continuació, crearia una base de dades del tipus Jdbc.



En el meu cas, la base de dades la fico a Documentes/databases/hsqldb/prova.db, per tant la URL JDBC que he de fer servir és:


jdbc:hsqldb:/home/albert/Documents/databases/hsqldb/prova.db

i el driver:

org.hsqldb.jdbc.JDBCDriver


(canviar aquesta imatge)

Això em permetrà fer servir l'assistent de l'OOo/LO per a definir la taula i els tipus de dades. Creo una taula diccionari amb tres columnes: id (enter), nom (varchar de 100) i valor (varchar de 100).


I  un cop creada la taula, la informo amb algunes dades de prova:



Probablement la classe més útil de Groovy per al treball amb bases de dades sigui groovy.sql.Sql.  Aquesta classe és una mena de navalla suïssa que proporciona una varietat de mètodes per a fer gairebé totes les tasques comuns amb taules.

La pàgina de la documentació de groovy.sql.Sql ens explica les possibilitats d'aquesta navalla suïssa.

Per a utilitzar-la  cal importar-la

import groovy.sql.Sql


A continuació puc configurar la connexió a la base de dades que he creat fa un moment:

def ds = [url:'jdbc:hsqldb:/home/albert/Documents/databases/hsqldb/prova.db', 
          user:'sa', 
          password:'', 
          driver:'org.hsqldb.jdbc.JDBCDriver']
def sql = Sql.newInstance(ds.url, ds.user, ds.password, ds.driver)


Consulto la taula que he creat amb el OOo/LO amb el potent mètode eachRow, adonem-nos com la fila en curs és accessible amb 'it':

sql.eachRow("select * from public.\"diccionari\" where \"id\" >= 3") {
    println "id = ${it.id}; nom = ${it.nom}; valor = ${it.valor}"
}


i el resultat és

albert@athena:~/Workspace/wk-groovy/prova-jdbc$ groovy provabd.groovy 
id = 3; nom = nom3; valor = valor3
id = 4; nom = nom4; valor = valor3
id = 5; nom = nom5; valor = valor5


Creo una nova taula i la informo amb dades. Cal tenir en compte algunes particularitats de l'SQL de  l'HSQLDB: els noms de les taules han d'anar precedides de l'esquema; els noms de taules, columnes i  d'altres objectes van entre cometes dobles; els literals van entre comentes simples.

sql.execute '''
create table public.\"traductor\" (
   \"id\" integer not null,
   \"catala\" varchar(100),
   \"castella\" varchar(100),
)
'''


Faig insert de dades amb diferents mètodes:

- fent servir la sintaxi amb '''
sql.execute '''
insert into public.\"traductor\"(\"id\",\"catala\",\"castella\") values (1, 'catala 1','castella 1') 
'''
println "inserta fila 1"

-  fent servir la sintaxi de preparedStatement de JDBC
def params = [2, 'catala 2', 'castella 2']
sql.execute("insert into public.\"traductor\" (\"id\", \"catala\", \"castella\") values (?, ?, ?)", params)
println "inserta fila 2"


params = [3, 'catala 3', 'castella 3']
sql.execute("insert into public.\"traductor\" (\"id\", \"catala\", \"castella\") values (?, ?, ?)", params)
println "inserta fila 3"

- fent servir la sintaxi GString
def map = [id:4, catala:'català 4', castella:'castellà 4']
sql.execute("insert into public.\"traductor\" (\"id\", \"catala\", \"castella\") values ($map.id, $map.catala, $map.castella)")
println "inserta fila 4"


Visualitzo els resultats amb eachRow, ara fent servir el paràmetre fila a la closure, en comptes d'it.

sql.eachRow("select * from public.\"traductor\"") {fila ->
    println "id = $fila.id; català = $fila.catala; castellà = $fila.castella"
}

Després d'aquestes accions, tinc les dues taules amb dades, com puc veure amb l'OOo/LO




He fet inserts, evidentment també es poden fer update, delete... fent servir execute, o millor  executeUpdate, que em retorna una llista de les files afectades.

eachRow admet paginació. He afegit algunes dades més a la taula traductor i la visualitzo, primer tota i després mostrant només quatre files a partir de la fila tres:

println "mostra la taula \"traductor\""
sql.eachRow("select * from public.\"traductor\"") {fila ->
    println "id = $fila.id; català = $fila.catala; castellà = $fila.castella"
}


println "mostra 4 files de la taula \"traductor\" a partir de la fila 3"
sql.eachRow("select * from public.\"traductor\"", 3, 4 ) {fila ->
    println "id = $fila.id; català = $fila.catala; castellà = $fila.castella"
}


El resultat és:
mostra la taula "traductor"

id = 1; català = catala 1; castellà = castella 1
id = 2; català = catala 2; castellà = castella 2
id = 3; català = catala 3; castellà = castella 3
id = 4; català = català 4; castellà = castellà 4
id = 5; català = catala 5; castellà = castella 5
id = 6; català = catala 6; castellà = castella 6
id = 7; català = catala 7; castellà = castella 7
id = 8; català = català 8; castellà = castellà 8
mostra 4 files de la taula "traductor" a partir de la fila 3
id = 3; català = catala 3; castellà = castella 3
id = 4; català = català 4; castellà = castellà 4
id = 5; català = catala 5; castellà = castella 5
id = 6; català = catala 6; castellà = castella 6

La classe groovy.sql.Sql té altres mètodes que també permeten augmentar la productivitat del desenvolupament, que s'afegeixen al fet que els scripts en Groovy no requereixen compilació. 

groovy.sql.Sql també té mètodes que retornen ResultSet de jdbc, permetent el tractament típic de Java.

El package groovy.sql també inclou la classe  DataSet que deriva de groovy.sql.Sql i que permet fer queries a la base de dades fent servir operadors i noms de camps de Groovy en comptes de crides a API JDBC i noms de taules i columnes. Un petit exemple:

Primer de tot, cal importar DataSet
import groovy.sql.DataSet

i ja el puc fer servir:

primer mostro el contingut de la taula amb eachRow d'Sql i després fa la query amb DataSet

println "mostra la taula \"traductor\""
sql.eachRow("select * from public.\"traductor\"") {fila ->
    println "id = $fila.id; català = $fila.catala; castellà = $fila.castella"
}

println "mostra valors amb id entre 3 i 7 fent servir la classe DataSet"
def traduccions = sql.dataSet("public.\"traductor\"")
def filtrat = traduccions.findAll {it."\"id\"" >= 3 && it."\"id\"" <= 7 }
filtrat.each { fila ->
    println "id = $fila.id; català = $fila.catala; castellà = $fila.castella"
}

El resultat és el següent

mostra la taula "traductor"
id = 1; català = catala 1; castellà = castella 1
id = 2; català = catala 2; castellà = castella 2
id = 3; català = catala 3; castellà = castella 3
id = 4; català = català 4; castellà = castellà 4
id = 5; català = catala 5; castellà = castella 5
id = 6; català = catala 6; castellà = castella 6
id = 7; català = catala 7; castellà = castella 7
id = 8; català = català 8; castellà = castellà 8

mostra valors amb id entre 3 i 7 fent servir la classe DataSet
id = 3; català = catala 3; castellà = castella 3
id = 4; català = català 4; castellà = castellà 4
id = 5; català = catala 5; castellà = castella 5
id = 6; català = catala 6; castellà = castella 6
id = 7; català = catala 7; castellà = castella 7

En aquest exemple les particularitats de HSQLDB pel que fa als noms de taules i columnes entre cometes  no permeten aprofitar la simplificació de fer servir els noms de les columnes com si fossin noms de camps Groovy de l'objecte it. Però, si més no, es permet veure l'ús de l'operador && per a construir el "where" del Dataset

I finalment, per acabar...

// tanca la connexió
sql.close()




dimarts, 1 de novembre del 2011

Un "Piulador" amb Twitter4J amb gestió de l'autenticació

En el post anterior vaig fer un "piulador" personal que em permet enviar tweets (o piulades) al compte associat a l'Access Token.

Per obtenir l'Access Token i l'Access Token Secret va caldre demanar-los a la web de Twitter. Els valors que em va proporcionar Twitter  els vaig fer servir posant-los a l'objecte de la classe ConfigurationBuilder que passava com argument al constructor de l'objecte de la classe Twitter que és el que permet l'operació.

Un cop obtinguts l'Access Token i l'Access Token Secretm aquests dos valors els podrà fer servir el Piulador indefinidament. L'usuari pot, però, forçar que se'n generin de nous des de la web de Twitter. 

Per a que el "Piulador" el pugui fer servir tothom que tingui un compte a Twitter cal que sigui el mateix piulador qui el demani i en gestioni l'obtenció. Això és el que faré avui.

El codi del partida és el Piulador del post anterior:

package com.sticipl.proves;

import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.conf.ConfigurationBuilder;

public final class ProvaTwitter {
    /**
     * Usage: java twitter4j.examples.tweets.UpdateStatus [text]
     *
     * @param args message
     */
    public static void main(String[] args) {
        try {
         ConfigurationBuilder cb = new ConfigurationBuilder();
         cb.setDebugEnabled(true)
             .setOAuthConsumerKey("[El consumer Key obtingut]")
             .setOAuthConsumerSecret("[el consumer secret obtingut]")
             .setOAuthAccessToken("[l'access token obtingut]")
             .setOAuthAccessTokenSecret("[l'access token secret obtingut]");
         TwitterFactory tf = new TwitterFactory(cb.build());
         Twitter twitter = tf.getInstance();
            
            Status status = twitter.updateStatus("Aquest és el missatge enviat des de l'aplicació #Java de prova fent us de #Twitter4J");
            System.out.println("Actualitzat status a [" + status.getText() + "].");
            System.exit(0);
        } catch (TwitterException te) {
            te.printStackTrace();
            System.out.println("Excepció de Twitter: " + te.getMessage());
            System.exit(-1);
        }
    }
}

El que cal fer és canviar el bloc de codi del ConfigurationBuilder per un bloc de codi que en gestioni l'obtenció del parell Access Token / Access Token Secret.

Al post anterior vaig dir que el Consumer ha de demanar l'autorització de l'usuari amb un Request Token i que aquest Request Token es bescanvia per l'Access Token.  Com es fa això? A la secció dels exemples de codi de la web Twitter4J expliquen com:

    With OAuth authorization scheme, an application can access the user account without userid/password combination given. You need to register your application athttp://twitter.com/oauth_clients/new to acquire consumer key, and consumer secret in advance. key / secret pair can be set via Twitter#setOAuthConsumer(), or following system properties:

    -Dtwitter4j.oauth.consumerKey=[consumer key]
    -Dtwitter4j.oauth.consumerSecret=[consumer secret]

    Initially, you don't have a permission to access the user's account and need to acquire access token by redirecting the user to an authorization URL as follows:

      public static void main(String args[]) thrwos Exception{
        // The factory instance is re-useable and thread safe.
        Twitter twitter = new TwitterFactory().getInstance();
        twitter.setOAuthConsumer("[consumer key]", "[consumer secret]");
        RequestToken requestToken = twitter.getOAuthRequestToken();
        AccessToken accessToken = null;
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        while (null == accessToken) {
          System.out.println("Open the following URL and grant access to your account:");
          System.out.println(requestToken.getAuthorizationURL());
          System.out.print("Enter the PIN(if aviailable) or just hit enter.[PIN]:");
          String pin = br.readLine();
          try{
             if(pin.length() > 0){
               accessToken = twitter.getOAuthAccessToken(requestToken, pin);
             }else{
               accessToken = twitter.getOAuthAccessToken();
             }
          } catch (TwitterException te) {
            if(401 == te.getStatusCode()){
              System.out.println("Unable to get the access token.");
            }else{
              te.printStackTrace();
            }
          }
        }
        //persist to the accessToken for future reference.
        storeAccessToken(twitter.verifyCredentials().getId() , accessToken);
        Status status = twitter.updateStatus(args[0]);
        System.out.println("Successfully updated the status to [" + status.getText() + "].");
        System.exit(0);
      }
      private static void storeAccessToken(int useId, AccessToken accessToken){
        //store accessToken.getToken()
        //store accessToken.getTokenSecret()
      }

El que faig és adaptar aquest codi al meu piulador:


package com.sticipl.proves;

import java.io.BufferedReader;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.io.PrintWriter;

import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.auth.AccessToken;
import twitter4j.auth.RequestToken;

public final class ProvaTwitter {
private Twitter twitter;
private BufferedReader br;
    /**
     * Usage: java twitter4j.examples.tweets.UpdateStatus [text]
     *
     * @param args message
     */
    public static void main(String[] args) {
        new ProvaTwitter();
    }
    
public ProvaTwitter() {
try {
            twitter = new TwitterFactory().getInstance();
            AutenticaConsumer();
            Status status = twitter.updateStatus("Aquest és el missatge enviat des de l'aplicació #Java de prova fent us de #Twitter4J. Versió 2");
            System.out.println("Actualitzat status a [" + status.getText() + "].");
            System.exit(0);
        } catch (TwitterException te) {
            te.printStackTrace();
            System.out.println("Excepció de Twitter: " + te.getMessage());
            System.exit(-1);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("Excepció general: " + e.getMessage());
            System.exit(-2);        
        }
}
private void AutenticaConsumer() throws Exception{
twitter.setOAuthConsumer("[consumer key]", "[consumer key secret]");
RequestToken requestToken = twitter.getOAuthRequestToken();
AccessToken accessToken = null;
br = new BufferedReader(new InputStreamReader(System.in));
while (null == accessToken) {
System.out.print("Entra el nom d'aquest perfil d'accés a Twitter:");
String sNomPerfil = br.readLine();
System.out.println("Obre la següent URL a un navegador, identifica't amb el teu compte de twitter i autoritza al piulador:");
System.out.println(requestToken.getAuthorizationURL());
System.out.print("Entra el PIN(si està disponible) i prem enter:");
String pin = br.readLine();
try {
if(pin.length() > 0) {
accessToken = twitter.getOAuthAccessToken(requestToken, pin);
} else {
accessToken = twitter.getOAuthAccessToken();
}
    
//persist to the accessToken for future reference.
storeAccessToken(sNomPerfil, twitter.verifyCredentials().getId() , accessToken);
    
} catch (TwitterException te) {
if (401 == te.getStatusCode()) {
System.out.println("No ha pogut obtenir l'Access Token.");
} else {
te.printStackTrace();
}
}
}
}
    
    private  void storeAccessToken(String sNomPerfil, long l, AccessToken accessToken){
// guarda un fitxer amb:
    // nom del perfil a guardar
    // twitter.verifyCredentials().getId()
// guarda accessToken.getToken()
// guarda accessToken.getTokenSecret()
FileWriter fitxer = null;
PrintWriter pw = null;
try {
fitxer = new FileWriter("./twitter-access-token.txt");
pw = new PrintWriter(fitxer);
pw.println("Nom perfil: " + sNomPerfil );
pw.println("twitter.verifyCredentials().getId(): " + l );
pw.println("Access Token: " + accessToken.getToken() );
pw.println("Access Token Secret: " + accessToken.getTokenSecret() );
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != fitxer)
fitxer.close();
    } catch (Exception e2) {
     e2.printStackTrace();
    }
}      
    }    
}

I l'executo:

Des del main s'invoca al constructor , el qual, primer de tot, va al mètode AutenticaConsumer, que és el que fa la negociació OAuth. 

A AutenticaConsumer,  s'estableixen el Consumer Key i el Cosumer Key Secret i, a continuació s'obté un Request Token. 

Entra el nom d'aquest perfil d'accés a Twitter:sticipl

A continuació demana un nom de perfil d'accés al twitter per a identificar-lo en futures connexions. La idea és que guarda a un fitxer el nom del perfil i l'Access Token i l'Access Token Secret, de forma que per a futures connexions amb aquest perfil,  podria fer servir directament aquests valors emmagatzemats localment, en comptes d'haver de tornar a demanar accés.  En aquesta versió genera el fitxer, però no està implementada la  recuperació per perfil de l'Acces Token. No costaria gaire fer-ho, però potser millor amb una bd HSQLDB que amb un fitxer pla.

Amb el Request Token obté la URL d'autorització. L'usuari ha d'anar a aquesta URL, identificar-se amb el compte de Twitter amb el que vol fer servir el piulador, i autoritzar al Piulador a poder enviar missatges. 

Obre la següent URL a un navegador, identifica't amb el teu compte de twitter i autoritza al piulador:

http://api.twitter.com/oauth/authorize?oauth_token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


Dit i fet, copio la URL i l'enganxo a un navegador. Vaig a la web d'Autorització de Twitter. Com que ja estava logat a Twitter amb el compte de sticipl, aquesta és el compte per al que s'autoritzarà el Piulador. Però podria haver sortit i haver-me logat de nou amb un compte diferent :





Faig click a Authorize App i...



La pàgina de Twitter em proporciona un PIN. El piulador estava esperant a que li indiqués aquest PIN:

Entra el PIN(si està disponible) i prem enter:6865240
 
Un cop autoritzat, el mètode AutenticaConsumer invoca al mètode storeAccessToken que genera el fitxer amb l'Access Token i l'Access Token Key per a usos futurs. El fitxer generat és una cosa com aquesta:

Nom perfil: sticipl
twitter.verifyCredentials().getId(): 177894606
Access Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Access Token Secret: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

AutenticaConsumer acaba i torna al constructor, i el constructor fa la següent piulada:

Actualitzat status a [Aquest és el missatge enviat des de l'aplicació #Java de prova fent us de #Twitter4J. Versió 2]. 

Vet aquí el resultat:



Vet aquí, doncs, una versió del piulador amb autenticació OAuth gestionada des de la mateixa aplicació.

La web de Twitter4J ens ens proporciona codi d'exemple per a desenvolupar altres funcions del Twitter que aniré explorant en propers posts.

diumenge, 30 d’octubre del 2011

Un "Piulador" personal amb Twitter4J

En el post d'avui crearé un petit "Piulador": una petita aplicació que em permetrà piular al Twitter.

El primer pas es descarregar l'API per al llenguatge de desenvolupament triat del lloc dels desenvolupadors de Twitter: https://dev.twitter.com/docs/twitter-libraries

Tenim APIs per a diferents llenguatges i amb diferents orígens. En particular per a Java, PHP, Python i C++ a la mateixa web dels desenvolupadors en destaquen aquestes:

C++:  Twitcurl,  http://code.google.com/p/twitcurl/.
Java:  Twitter4J, http://twitter4j.org/.
PHP: TmhOAuth, http://github.com/themattharris/tmhOAuth.
Python: Tweepy, https://github.com/tweepy/tweepy

En el meu cas, desenvoluparé l'aplicació amb Java, així que el primer que faig és descarregar Twitter4j

A la web de Twitter4J en podem llegir algunes de les característiques d'aquesta API


"Twitter4J és una biblioteca java (jar) no oficial per a l'API de Twitter.
Amb Twitter4J, es pot integrar fàcilment una aplicació Java amb el servei de Twitter.


Twitter4J ofereix: 
✔ és Java pur 100%. Funciona a partir de la versió de plataforma Java 1.4.2
✔ Preparat per a la plataforma Android i per a Google App Engine.
✔ Sense dependències. No li cal cap jar addicional.
✔ suport OAuth inclòs
✔ suport de GZip inclòs


Requeriments de sistema
Windows o Unix amb suport de Java.
JVM: Java 1.4.2 o superior


Com utilitzar Twitter4J?
Només cal afegir twitter4j-core-2.2.5.jar al classpath de l'aplicació.
El millor lloc per on començar és llegir el JavaDoc
El millor lloc per on començar a llegir el JavaDoc és la interface twitter4j.Twitter."

Però potser el primer que cal per a poder treballar amb Twitter és conèixer el protocol per a autenticar-se amb el servei:  El protocol OAuth  (rfc5849). Podem consultar també a http://oauth.net/core/1.0/.

El document de la rfc5849  ocupa 39 pàgines. però en un primer moment no cal llegir-lo per a poder fer servir la Twitter4J, perquè els detalls del funcionament estan encapsulats a la llibreria.

El que sí que caldrà és registrar l'aplicació que estem construint al servei Twitter, per a que aquest la reconegui i sigui capaç d'identificar-ne l'origen dels tweets. Això es fa a l'adreça https://dev.twitter.com/apps/new


Al formulari de registre haurem de posar el nom de l'aplicació, la descripció, l'adreça de descàrrega de l'aplicació (si la té)...



També hi podrem posar una icona, el tipus d'accés...el registre no resulta complicat.

Un cop registrada l'aplicació obtindrem les claus per autoritzar l'aplicació al Twitter.

En el llenguatge de OAuth  un Consumer és una aplicació, o una web, que accedeix a un proveïdor de servei en representació d'un usuari. Al registrar l'aplicació obtindrem el parell de valors que ens caldran per a autenticar l'aplicació, o consumer:

Consumer Key: Un valor utilitzat per l'aplicació per a identificar-se ella mateixa enfront del servei Twitter (el "login" de l'aplicació).
Consumer Secret: Un valor secret utilitzat per l'aplicació per a certificar la propietat de la Consumer Key  (el password).

A més, se'ns proporcionarà un conjunt d'URLs a les que caldrà accedir per a que l'usuari que faci servir l'aplicació també pugui autenticar-se


Request token URL: https://api.twitter.com/oauth/request_token
Authorize URL: https://api.twitter.com/oauth/authorize
Access token URL: https://api.twitter.com/oauth/access_token


Aquestes adreces permetran el diàleg entre el consumer i el servei per a autenticar a l'usuari final.

Request Token: és un valor utilitzat pel Consumer per a obtenir autorització de l'usuari i que es tradueix en un Access Token.
Access Token: és un valor utilitzat pel Consumer per a obtenir accés als Protected Resources (en el cas del Twitter, als tweets emesos o adreçats a l'usuari) en representació de l'usuari, en comptes de fer servir les pròpies credencials de l'usuari al Servei. És dir, l'aplicació no fa servir directament el login i el password de twitter de l'usuari. Podriem dir que l'Access Token és un login temporal.
Access Token Secret: un valor secret utilitzat pel Consumer per a certificar la propietat de l'Access Token (seria el password temporal corresponent al login temporal).

En la pàgina que es registra l'aplicació també podem obtenir un Acces Token i un Access Token Secret que es poden fer servir directament a l'aplicació per a piular des del propi compte de Twitter.

Guardem molt bé els diferents tokens rebuts. I mantinguem en secret els "passwords"
 Finalment, un cop registrada l'aplicació, podrem veure la nova aplicació registrada (i totes aquelles altres que puguem tenir) a https://dev.twitter.com/apps






A la pàgina de Twitter4J ens diuen com fer servir aquests parells.

Amb un  fitxer de propietats estàndard:  twitter4j.properties. Cal que el fitxer "twitter4j.properties" es trobi a les rutes del classpath.

debug=true
oauth.consumerKey=*********************
oauth.consumerSecret=******************************************
oauth.accessToken=**************************************************
oauth.accessTokenSecret=******************************************

Amb un objecte ConfigurationBuilder

ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setDebugEnabled(true)
    .setOAuthConsumerKey("*********************")
    .setOAuthConsumerSecret("******************************************")
    .setOAuthAccessToken("**************************************************")
    .setOAuthAccessTokenSecret("******************************************");
TwitterFactory tf = new TwitterFactory(cb.build());
Twitter twitter = tf.getInstance();

O amb variables de sistema passades a la JVM.

$ java -Dtwitter4j.debug=true
    -Dtwitter4j.oauth.consumerKey=*********************
    -Dtwitter4j.oauth.consumerSecret=******************************************
    -Dtwitter4j.oauth.accessToken=**************************************************
    -Dtwitter4j.oauth.accessTokenSecret=******************************************
    -cp twitter4j-core-2.2.5.jar:yourApp.jar yourpackage.Main

Arribats a aquest punt, un cop obtinguts els parells Consumer Key, Consumer Secret i Access Token i Access Token Secret ja estic en condicions de fer una petita aplicació amb java que "Piuli" al twitter en nom del meu compte.

Una cosa tan senzilla com això:

package com.sticipl.proves;


import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.conf.ConfigurationBuilder;




public final class ProvaTwitter {
    /**
     * Usage: java twitter4j.examples.tweets.UpdateStatus [text]
     *
     * @param args message
     */
    public static void main(String[] args) {
        try {
        ConfigurationBuilder cb = new ConfigurationBuilder();
        cb.setDebugEnabled(true)
           .setOAuthConsumerKey("[El consumer Key obtingut]")
           .setOAuthConsumerSecret("[el consumer secret obtingut]")
           .setOAuthAccessToken("[l'access token obtingut]")
           .setOAuthAccessTokenSecret("[l'access token secret obtingut]");
        TwitterFactory tf = new TwitterFactory(cb.build());
        Twitter twitter = tf.getInstance();
            
            Status status = twitter.updateStatus("Aquest és el missatge enviat des de l'aplicació #Java de prova fent us de #Twitter4J");
            System.out.println("Actualitzat status a [" + status.getText() + "].");
            System.exit(0);
        } catch (TwitterException te) {
            te.printStackTrace();
            System.out.println("Excepció de Twitter: " + te.getMessage());
            System.exit(-1);
        }
    }
}

En executar aquesta mini-aplicació, obtinc:

Actualitzat status a [Aquest és el missatge enviat des de l'aplicació #Java de prova fent us de #Twitter4J].
I en anar a Twitter puc comprovar que, efectivament, així és:



En aquesta primera aproximació a Twitter4J he fet un petit "piulador" personal. En un proper post presentaré un "Piulador" general.