Page 1 of 1

Twitter from FWH apps

PostPosted: Tue Feb 12, 2013 12:43 pm
by Antonio Linares
These are the first steps towards a Class Twitter for FWH based on Curl :-)

Based on this example:
http://www.barattalo.it/2010/09/09/how-to-change-twitter-status-with-php-and-curl-without-oauth/

and using the curl library for Harbour, available from here:
http://code.google.com/p/harbour-and-xharbour-builds/downloads/detail?name=hbcurl.zip&can=2&q=

This is the first test:
Code: Select all  Expand view
#include "FiveWin.ch"
#include "hbcurl.ch"

function Main()

   local hCurl, cPage := Space( 200 )

   curl_global_init()

   if ! Empty( hCurl := curl_easy_init() )
      curl_easy_setopt( hCurl, HB_CURLOPT_URL, "https://mobile.twitter.com/session/new" )
      curl_easy_setopt( hCurl, HB_CURLOPT_SSL_VERIFYPEER, .F. )
      curl_easy_setopt( hCurl, HB_CURLOPT_FAILONERROR, 1 )
      curl_easy_setopt( hCurl, HB_CURLOPT_FOLLOWLOCATION, 1 )
      // curl_easy_setopt( hCurl, HB_CURLOPT_RETURNTRANSFER, 1 )
      curl_easy_setopt( hCurl, HB_CURLOPT_TIMEOUT, 5 )
      curl_easy_setopt( hCurl, HB_CURLOPT_COOKIEJAR, "my_cookies.txt" )
      curl_easy_setopt( hCurl, HB_CURLOPT_COOKIEFILE, "my_cookies.txt" )
      curl_easy_setopt( hCurl, HB_CURLOPT_USERAGENT, "Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543a Safari/419.3 " )
        curl_easy_setopt( hCurl, HB_CURLOPT_ERRORBUFFER, @cPage )
       
        MsgInfo( curl_easy_perform( hCurl ) )
      MsgInfo( curl_easy_dl_buff_get( hCurl ) )
       
      curl_easy_reset( hCurl )
   endif

   curl_global_cleanup()

return nil


We need to find the value for CURLOPT_RETURNTRANSFER. It is not available in Harbour's hbcurl.ch

Re: Twitter from FWH apps

PostPosted: Tue Feb 12, 2013 12:56 pm
by Antonio Linares
Found :-)

#define HB_CURLOPT_RETURNTRANSFER 500

Re: Twitter from FWH apps

PostPosted: Tue Feb 12, 2013 1:26 pm
by Antonio Linares
This version already retrieves the Twitter web page :-)

Code: Select all  Expand view
#include "FiveWin.ch"
#include "hbcurl.ch"

function Main()

   local hCurl

   curl_global_init()

   if ! Empty( hCurl := curl_easy_init() )
      curl_easy_setopt( hCurl, HB_CURLOPT_URL, "https://mobile.twitter.com/session/new" )
      curl_easy_setopt( hCurl, HB_CURLOPT_SSL_VERIFYPEER, .F. )
      curl_easy_setopt( hCurl, HB_CURLOPT_FAILONERROR, 1 )
      curl_easy_setopt( hCurl, HB_CURLOPT_FOLLOWLOCATION, 1 )
      curl_easy_setopt( hCurl, HB_CURLOPT_TIMEOUT, 5 )
      curl_easy_setopt( hCurl, HB_CURLOPT_COOKIEJAR, "my_cookies.txt" )
      curl_easy_setopt( hCurl, HB_CURLOPT_COOKIEFILE, "my_cookies.txt" )
      curl_easy_setopt( hCurl, HB_CURLOPT_USERAGENT, "Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543a Safari/419.3 " )
       
        curl_easy_setopt( hCurl, HB_CURLOPT_DL_FILE_SETUP, "twitter.html" )
        curl_easy_perform( hCurl )
       
      curl_easy_reset( hCurl )
      MsgInfo( MemoRead( "twitter.html" ) )
   endif

   curl_global_cleanup()

return nil  
 

Re: Twitter from FWH apps

PostPosted: Tue Feb 12, 2013 2:31 pm
by Antonio Linares
A further step:

Code: Select all  Expand view
#include "FiveWin.ch"
#include "hbcurl.ch"

function Main()

   local hCurl, aMatch, cPage, cAction

   curl_global_init()

   if ! Empty( hCurl := curl_easy_init() )
      curl_easy_setopt( hCurl, HB_CURLOPT_URL, "https://mobile.twitter.com/session/new" )
      curl_easy_setopt( hCurl, HB_CURLOPT_SSL_VERIFYPEER, .F. )
      curl_easy_setopt( hCurl, HB_CURLOPT_FAILONERROR, 1 )
      curl_easy_setopt( hCurl, HB_CURLOPT_FOLLOWLOCATION, 1 )
      curl_easy_setopt( hCurl, HB_CURLOPT_TIMEOUT, 5 )
      curl_easy_setopt( hCurl, HB_CURLOPT_COOKIEJAR, "my_cookies.txt" )
      curl_easy_setopt( hCurl, HB_CURLOPT_COOKIEFILE, "my_cookies.txt" )
      curl_easy_setopt( hCurl, HB_CURLOPT_USERAGENT, "Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543a Safari/419.3 " )
       
      curl_easy_setopt( hCurl, HB_CURLOPT_DL_FILE_SETUP, "twitter.html" )
      curl_easy_perform( hCurl )
       
      curl_easy_reset( hCurl )
     
      cPage = MemoRead( "twitter.html" )
     
      aMatch  = HB_RegExAll( 'form action="(.*?)" method="(.*?)"', cPage, .F., .T. )
      cPage   = aMatch[ 1 ][ 2 ]
      cAction = aMatch[ 1 ][ 3 ]
     
      MsgInfo( cAction )
   endif

   curl_global_cleanup()

return nil  
 

Re: Twitter from FWH apps

PostPosted: Tue Feb 12, 2013 2:55 pm
by Antonio Linares
Retrieving the authenticity token:

Code: Select all  Expand view
#include "FiveWin.ch"
#include "hbcurl.ch"

function Main()

   local hCurl, aMatch, cPage, cURL, cAction

   curl_global_init()

   if ! Empty( hCurl := curl_easy_init() )
      curl_easy_setopt( hCurl, HB_CURLOPT_URL, "https://mobile.twitter.com/session/new" )
      curl_easy_setopt( hCurl, HB_CURLOPT_SSL_VERIFYPEER, .F. )
      curl_easy_setopt( hCurl, HB_CURLOPT_FAILONERROR, 1 )
      curl_easy_setopt( hCurl, HB_CURLOPT_FOLLOWLOCATION, 1 )
      curl_easy_setopt( hCurl, HB_CURLOPT_TIMEOUT, 5 )
      curl_easy_setopt( hCurl, HB_CURLOPT_COOKIEJAR, "my_cookies.txt" )
      curl_easy_setopt( hCurl, HB_CURLOPT_COOKIEFILE, "my_cookies.txt" )
      curl_easy_setopt( hCurl, HB_CURLOPT_USERAGENT, "Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543a Safari/419.3 " )
       
      curl_easy_setopt( hCurl, HB_CURLOPT_DL_FILE_SETUP, "twitter.html" )
      curl_easy_perform( hCurl )
       
      curl_easy_reset( hCurl )
     
      cPage = MemoRead( "twitter.html" )
     
      aMatch  = HB_RegExAll( 'form action="(.*?)" method="(.*?)"', cPage, .F., .T. )
      cURL    = aMatch[ 1 ][ 2 ]
      cAction = aMatch[ 1 ][ 3 ]
      aMatch  = HB_RegExAll( 'type="hidden" value="(.*?)"', cPage, .F., .T. )
      cAuthenticity_token = aMatch[ 1 ][ 2 ]
     
      MsgInfo( cAuthenticity_token )
   endif

   curl_global_cleanup()

return nil  

Re: Twitter from FWH apps

PostPosted: Wed Feb 13, 2013 1:30 pm
by Antonio Linares
This version already login into twitter :-)

UrlEncode() has been copied from tip_urlencode(), but I have included it so we don't need to link hbtip.

If you open, with your web browser, the file twitter.html that this app creates, you will see that you are already logged into your twitter account :-)

twitter.prg
Code: Select all  Expand view
#include "FiveWin.ch"
#include "hbcurl.ch"

function Main()

   TwitterSetStatus( cUserName, cPassword )

return nil

function TwitterSetStatus( cUser, cPassword, cStatus )

   local hCurl, aMatch, cPage, cURL, cAction, cAuthenticity_token, cPost

   curl_global_init()

   if ! Empty( hCurl := curl_easy_init() )
      curl_easy_setopt( hCurl, HB_CURLOPT_URL, "https://mobile.twitter.com/session/new" )
      curl_easy_setopt( hCurl, HB_CURLOPT_SSL_VERIFYPEER, .F. )
      curl_easy_setopt( hCurl, HB_CURLOPT_FAILONERROR, 1 )
      curl_easy_setopt( hCurl, HB_CURLOPT_FOLLOWLOCATION, 1 )
      curl_easy_setopt( hCurl, HB_CURLOPT_TIMEOUT, 5 )
      curl_easy_setopt( hCurl, HB_CURLOPT_COOKIEJAR, "my_cookies.txt" )
      curl_easy_setopt( hCurl, HB_CURLOPT_COOKIEFILE, "my_cookies.txt" )
      curl_easy_setopt( hCurl, HB_CURLOPT_USERAGENT, "Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543a Safari/419.3 " )
       
      curl_easy_setopt( hCurl, HB_CURLOPT_DL_FILE_SETUP, "twitter.html" )
      curl_easy_perform( hCurl )
       
      curl_easy_reset( hCurl )
     
      cPage = MemoRead( "twitter.html" )
     
      aMatch  = HB_RegExAll( 'form action="(.*?)" method="(.*?)"', cPage, .F., .T. )
      cURL    = aMatch[ 1 ][ 2 ]
      cAction = aMatch[ 1 ][ 3 ]
      aMatch  = HB_RegExAll( 'type="hidden" value="(.*?)"', cPage, .F., .T. )
      cAuthenticity_token = aMatch[ 1 ][ 2 ]
     
      cPost = "authenticity_token=" + urlencode( cAuthenticity_token ) + ;
              "&username=" + urlencode( cUser ) + ;
              "&password=" + urlencode( cPassword )
      curl_easy_init()
      curl_easy_setopt( hCurl, HB_CURLOPT_URL, cURL )
      curl_easy_setopt( hCurl, HB_CURLOPT_SSL_VERIFYPEER, .F. )
      curl_easy_setopt( hCurl, HB_CURLOPT_FAILONERROR, 1 )
      curl_easy_setopt( hCurl, HB_CURLOPT_FOLLOWLOCATION, 1 )
      curl_easy_setopt( hCurl, HB_CURLOPT_TIMEOUT, 5 )
      curl_easy_setopt( hCurl, HB_CURLOPT_COOKIEJAR, "my_cookies.txt" )
      curl_easy_setopt( hCurl, HB_CURLOPT_COOKIEFILE, "my_cookies.txt" )
      curl_easy_setopt( hCurl, HB_CURLOPT_USERAGENT, "Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543a Safari/419.3 " )
      curl_easy_setopt( hCurl, HB_CURLOPT_POSTFIELDS, cPost )
      curl_easy_setopt( hCurl, HB_CURLOPT_DL_FILE_SETUP, "twitter.html" )
      curl_easy_perform( hCurl )
      curl_easy_reset( hCurl )
     
      cPage = MemoRead( "twitter.html" )
      MsgInfo( cPage )
   endif

   curl_global_cleanup()

return nil  

#pragma BEGINDUMP

#include <hbapi.h>
#include <hbapiitm.h>
#include <hbapierr.h>

HB_FUNC( URLENCODE )
{
   const char * cData     = hb_parc( 1 );
   HB_ISIZ      nLen      = hb_parclen( 1 );
   HB_BOOL      bComplete = hb_parldef( 2, HB_TRUE );
   char *       cRet;
   HB_ISIZ      nPos = 0, nPosRet = 0, nVal;
   char         cElem;

   if( ! cData )
   {
      hb_errRT_BASE( EG_ARG, 3012, NULL,
                     HB_ERR_FUNCNAME, 1, hb_paramError( 1 ) );
      return;
   }

   if( ! nLen )
   {
      hb_retc_null();
      return;
   }

   /* Giving maximum final length possible */
   cRet = ( char * ) hb_xgrab( nLen * 3 + 1 );

   while( nPos < nLen )
   {
      cElem = cData[ nPos ];

      if( cElem == ' ' )
      {
         cRet[ nPosRet ] = '+';
      }
      else if(
         ( cElem >= 'A' && cElem <= 'Z' ) ||
         ( cElem >= 'a' && cElem <= 'z' ) ||
         ( cElem >= '0' && cElem <= '9' ) ||
         cElem == '.' || cElem == ',' || cElem == '&' ||
         cElem == '/' || cElem == ';' || cElem == '_' )
      {
         cRet[ nPosRet ] = cElem;
      }
      else if( ! bComplete && ( cElem == ':' || cElem == '?' || cElem == '=' ) )
      {
         cRet[ nPosRet ] = cElem;
      }
      else /* encode! */
      {
         cRet[ nPosRet++ ] = '%';
         nVal = ( ( HB_UCHAR ) cElem ) >> 4;
         cRet[ nPosRet++ ] = nVal < 10 ? '0' + ( char ) nVal : 'A' + ( char ) nVal - 10;
         nVal = ( ( HB_UCHAR ) cElem ) & 0x0F;
         cRet[ nPosRet ] = nVal < 10 ? '0' + ( char ) nVal : 'A' + ( char ) nVal - 10;
      }

      nPosRet++;
      nPos++;
   }

   hb_retclen_buffer( cRet, nPosRet );
}

#pragma ENDDUMP

Re: Twitter from FWH apps

PostPosted: Mon Feb 18, 2013 4:24 pm
by Antonio Linares
This version should work. Your tests and feedback are welcome :-)

Code: Select all  Expand view
#include "FiveWin.ch"
#include "hbcurl.ch"

function Main()

   TwitterSetStatus( "username", "password", "Testing from an app" )

return nil

function TwitterSetStatus( cUser, cPassword, cStatus )

   local hCurl, aMatch, cPage, cURL, cAction, cAuthenticity_token, cPost

   curl_global_init()

   if ! Empty( hCurl := curl_easy_init() )
      curl_easy_setopt( hCurl, HB_CURLOPT_URL, "https://mobile.twitter.com/session/new" )
      curl_easy_setopt( hCurl, HB_CURLOPT_SSL_VERIFYPEER, .F. )
      curl_easy_setopt( hCurl, HB_CURLOPT_FAILONERROR, 1 )
      curl_easy_setopt( hCurl, HB_CURLOPT_FOLLOWLOCATION, 1 )
      curl_easy_setopt( hCurl, HB_CURLOPT_TIMEOUT, 5 )
      curl_easy_setopt( hCurl, HB_CURLOPT_COOKIEJAR, "my_cookies.txt" )
      curl_easy_setopt( hCurl, HB_CURLOPT_COOKIEFILE, "my_cookies.txt" )
      curl_easy_setopt( hCurl, HB_CURLOPT_USERAGENT, "Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543a Safari/419.3 " )
       
      curl_easy_setopt( hCurl, HB_CURLOPT_DL_FILE_SETUP, "twitter.html" )
      curl_easy_perform( hCurl )
       
      curl_easy_reset( hCurl )
     
      cPage = MemoRead( "twitter.html" )
     
      aMatch  = HB_RegExAll( 'form action="(.*?)" method="(.*?)"', cPage, .F., .T. )
      cURL    = aMatch[ 1 ][ 2 ]
      cAction = aMatch[ 1 ][ 3 ]
      aMatch  = HB_RegExAll( 'type="hidden" value="(.*?)"', cPage, .F., .T. )
      cAuthenticity_token = aMatch[ 1 ][ 2 ]

      MsgInfo( cURL )
     
      cPost = "authenticity_token=" + urlencode( cAuthenticity_token ) + ;
              "&username=" + urlencode( cUser ) + ;
              "&password=" + urlencode( cPassword )
      curl_easy_init()
      curl_easy_setopt( hCurl, HB_CURLOPT_URL, cURL )
      curl_easy_setopt( hCurl, HB_CURLOPT_SSL_VERIFYPEER, .F. )
      curl_easy_setopt( hCurl, HB_CURLOPT_FAILONERROR, 1 )
      curl_easy_setopt( hCurl, HB_CURLOPT_FOLLOWLOCATION, 1 )
      curl_easy_setopt( hCurl, HB_CURLOPT_TIMEOUT, 5 )
      curl_easy_setopt( hCurl, HB_CURLOPT_COOKIEJAR, "my_cookies.txt" )
      curl_easy_setopt( hCurl, HB_CURLOPT_COOKIEFILE, "my_cookies.txt" )
      curl_easy_setopt( hCurl, HB_CURLOPT_USERAGENT, "Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543a Safari/419.3 " )
      curl_easy_setopt( hCurl, HB_CURLOPT_POSTFIELDS, cPost )
      curl_easy_setopt( hCurl, HB_CURLOPT_DL_FILE_SETUP, "twitter.html" )
      curl_easy_perform( hCurl )
      curl_easy_reset( hCurl )

      cPage = MemoRead( "twitter.html" )

      aMatch  = HB_RegExAll( 'form action="(.*?)" class="(.*?)" method="(.*?)"', cPage, .F., .T. )
      cURL    = aMatch[ 1 ][ 2 ]
      cAction = aMatch[ 1 ][ 3 ]
     
      cPage = MemoRead( "twitter.html" )
      aMatch  = HB_RegExAll( 'type="hidden" value="(.*?)"', cPage, .F., .T. )
      cAuthenticity_token = aMatch[ 1 ][ 2 ]

      cPost = "authenticity_token=" + urlencode( cAuthenticity_token ) + ;
              "&display_coordinates=" + "" + ;
              "&in_reply_to_status_id=" + "" + ;
              "&lat=" + "" + ;
              "&long=" + "" + ;
              "&place_id=" + "" + ;
              "&text=" + cStatus

      curl_easy_init()
      curl_easy_setopt( hCurl, HB_CURLOPT_URL, cURL )
      curl_easy_setopt( hCurl, HB_CURLOPT_SSL_VERIFYPEER, .F. )
      curl_easy_setopt( hCurl, HB_CURLOPT_FAILONERROR, 1 )
      curl_easy_setopt( hCurl, HB_CURLOPT_FOLLOWLOCATION, 1 )
      curl_easy_setopt( hCurl, HB_CURLOPT_TIMEOUT, 5 )
      curl_easy_setopt( hCurl, HB_CURLOPT_COOKIEJAR, "my_cookies.txt" )
      curl_easy_setopt( hCurl, HB_CURLOPT_COOKIEFILE, "my_cookies.txt" )
      curl_easy_setopt( hCurl, HB_CURLOPT_USERAGENT, "Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543a Safari/419.3 " )
      curl_easy_setopt( hCurl, HB_CURLOPT_POSTFIELDS, cPost )
      curl_easy_setopt( hCurl, HB_CURLOPT_DL_FILE_SETUP, "twitter.html" )
      curl_easy_perform( hCurl )
      curl_easy_reset( hCurl )

      MsgInfo( "done" )
   endif

   curl_global_cleanup()

return nil  

#pragma BEGINDUMP

#include <hbapi.h>
#include <hbapiitm.h>
#include <hbapierr.h>

HB_FUNC( URLENCODE )
{
   const char * cData     = hb_parc( 1 );
   HB_ISIZ      nLen      = hb_parclen( 1 );
   HB_BOOL      bComplete = hb_parldef( 2, HB_TRUE );
   char *       cRet;
   HB_ISIZ      nPos = 0, nPosRet = 0, nVal;
   char         cElem;

   if( ! cData )
   {
      hb_errRT_BASE( EG_ARG, 3012, NULL,
                     HB_ERR_FUNCNAME, 1, hb_paramError( 1 ) );
      return;
   }

   if( ! nLen )
   {
      hb_retc_null();
      return;
   }

   /* Giving maximum final length possible */
   cRet = ( char * ) hb_xgrab( nLen * 3 + 1 );

   while( nPos < nLen )
   {
      cElem = cData[ nPos ];

      if( cElem == ' ' )
      {
         cRet[ nPosRet ] = '+';
      }
      else if(
         ( cElem >= 'A' && cElem <= 'Z' ) ||
         ( cElem >= 'a' && cElem <= 'z' ) ||
         ( cElem >= '0' && cElem <= '9' ) ||
         cElem == '.' || cElem == ',' || cElem == '&' ||
         cElem == '/' || cElem == ';' || cElem == '_' )
      {
         cRet[ nPosRet ] = cElem;
      }
      else if( ! bComplete && ( cElem == ':' || cElem == '?' || cElem == '=' ) )
      {
         cRet[ nPosRet ] = cElem;
      }
      else /* encode! */
      {
         cRet[ nPosRet++ ] = '%';
         nVal = ( ( HB_UCHAR ) cElem ) >> 4;
         cRet[ nPosRet++ ] = nVal < 10 ? '0' + ( char ) nVal : 'A' + ( char ) nVal - 10;
         nVal = ( ( HB_UCHAR ) cElem ) & 0x0F;
         cRet[ nPosRet ] = nVal < 10 ? '0' + ( char ) nVal : 'A' + ( char ) nVal - 10;
      }

      nPosRet++;
      nPos++;
   }

   hb_retclen_buffer( cRet, nPosRet );
}

#pragma ENDDUMP

Re: Twitter from FWH apps

PostPosted: Fri Feb 22, 2013 2:54 am
by Antonio Linares
Examples to implement the Twitter search API:

http://www.desarrolloweb.com/articulos/api-twitter-php-curl.html