FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin for Harbour/xHarbour Twitter from FWH apps
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Twitter from FWH apps
Posted: Tue Feb 12, 2013 12:43 PM
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 (fw): Select all Collapse
#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
regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Twitter from FWH apps
Posted: Tue Feb 12, 2013 12:56 PM

Found :-)

define HB_CURLOPT_RETURNTRANSFER 500

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Twitter from FWH apps
Posted: Tue Feb 12, 2013 01:26 PM
This version already retrieves the Twitter web page :-)

Code (fw): Select all Collapse
#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
regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Twitter from FWH apps
Posted: Tue Feb 12, 2013 02:31 PM
A further step:

Code (fw): Select all Collapse
#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
regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Twitter from FWH apps
Posted: Tue Feb 12, 2013 02:55 PM
Retrieving the authenticity token:

Code (fw): Select all Collapse
#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
regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Twitter from FWH apps
Posted: Wed Feb 13, 2013 01:30 PM
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 (fw): Select all Collapse
#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
regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Twitter from FWH apps
Posted: Mon Feb 18, 2013 04:24 PM
This version should work. Your tests and feedback are welcome :-)

Code (fw): Select all Collapse
#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
regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Twitter from FWH apps
Posted: Fri Feb 22, 2013 02:54 AM
Examples to implement the Twitter search API:

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

Antonio Linares
www.fivetechsoft.com

Continue the discussion