Calling Javascript functions

BlitzMax Forums/BlitzMax Programming/Calling Javascript functions

I can get the correct page for the translation of a word from English into Greek using http://translate.google.com/translate_t?sl=en&tl=el&q=Hello

But when I try to parse the response text from that link, using libxml (looking for '<div id=result_box ...'), it yells at me for innumerable parse errors.

I can also do this:
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
    <script type="text/javascript" src="http://www.google.com/jsapi"></script>
    <script type="text/javascript">

    google.load("language", "1");

    function initialize() {
      google.language.translate("Hello", "en", "el", function(result) {
        if (!result.error) {
          var container = document.getElementById("trans");
          container.innerHTML = result.translation;
        }
      });
    }
    google.setOnLoadCallback(initialize);

    </script>
  </head>

  <body>
    <div id="trans"></div>
  </body>
</html>


But that would have to be hosted somewhere for it to work, no?

You know that the docs ( http://code.google.com/apis/ajaxlanguage/documentation/ ) explain about their JSON encoded results that are available through the non-javascript interface?

Now, if there was only a JSON parser for BlitzMax....

Awesome!
http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q=Hello&langpair=en%7Cel


http://www.blitzbasic.com/codearcs/codearcs.php?code=2066

Cheers.

Geepers, someone wrote one *in* BlitzMax...

I only went so far as to wrap one... - maybe I'm getting lazy :-p

Any idea why OpenStream keeps returning null?

SuperStrict

Framework brl.standardio
Import brl.stream
Import brl.filesystem
Import brl.LinkedList
Import brl.Map

Include "json.bmx"

Local word:String = "Hello there!"
Local Text:String = GetHTTPString("www.ajax.googleapis.com", "ajax/services/language/Translate?v=1.0&q=" + word + "&langpair=en%7Cel")


'Local json:TJSON = TJSON.Create(Text)

'Print json.GetValue("translatedText").ToString()


Function GetHTTPString:String(url:String, page:String)
  Local stream:TStream = OpenStream("tcp::" + url), data:String
  
	If stream <> Null
	   stream.WriteString("GET /" + page + "~r~n~r~n")
		
		data = LoadString(stream)
		
		SaveText(data, "text.txt")
		
	Else
		DebugLog "Failed to open " + url
		
	End If
   
   Return data
   
End Function


(Concept taken from: http://www.blitzbasic.com/Community/posts.php?topic=67848#761689)

See here for examples of how to form HTTP requests and handle the server's response*.


You'll also need to format the string to be translated to handle spaces etc, will you not?


Finally, that JSON parser seems like an awful lot of code to use if you'll only ever be looking for the text between '"translatedText":"' and '"'. :o/



*You could use a 'http::' stream directly, of course, but you'd lose some error checking.

Finally, that JSON parser seems like an awful lot of code to use if you'll only ever be looking for the text between '"translatedText":"' and '"', to me.
Yep, but I think I'll be using it for config and whatnot aswell..

Nothing I changed made a connection (using "http::" and writeline("GET /" + url + "HTTP/1.0 (or 1.1) ~r~n~r~n")), OpenStream still returns null. I think I'll be using my modified THttp type (codearcs), as it seemed to work before for getting pages.

I swear I had it getting pages just a few hours ago.. now its not working. I checked against your HTTP header code, all seems to be in place...

(See the Get method)
SuperStrict

Framework brl.standardio
Import brl.stream
Import brl.Socket
Import brl.socketstream
Import brl.retro
Import brl.filesystem
Import brl.LinkedList
Import brl.Map

Include "json.bmx"

Local word:String = "Hello there!"
Local Text:String = GetHTTPString("www.ajax.googleapis.com", "ajax/services/language/Translate?v=1.0&q=" + word + "&langpair=en%7Cel")

Print Text

'Local json:TJSON = TJSON.Create(Text)

'Print json.GetValue("translatedText").ToString()


Function GetHTTPString:String(url:String, page:String)
rem
  Local stream:TStream = OpenStream("tcp::" + url), data:String
  
	If stream <> Null
	   stream.WriteString("GET /" + page + " HTTP/1.0~r~n~r~n")
		
		data = LoadString(stream)
		
		SaveText(data, "text.txt")
		
	Else
		DebugLog "Failed to open " + url
		
	End If
   
   Return data
  endrem
	
  Local httpd:THttp = New(THttp)
	
	If httpd.open(url)
	  Local htrd:HTTPReturnData = httpd.Get(page)
		
		If htrd <> Null
			Return htrd.Content
			
		Else
		   Return Null
		   
		End If
		
	Else
	   Return Null
	   
	End If
	
End Function

Type THttp
	Field sock:TSocket
	Field stream:TStream
	Field host:String
	Field agent:String = "HTTPGET/1.0"
	Field autoClose:Int
	
		Method Open:Int(host:String, autoClose:Int = False) 
		  Self.sock = CreateTCPSocket()
			 
			If ConnectSocket(Self.sock, HostIp(host), 80) 
				Self.host = host
				Self.stream = CreateSocketStream(Self.sock) 
				Self.autoClose = autoClose
			   Return True
				
			Else
			   Return False
				
			End If
			
		End Method
		
		Method Get:HTTPReturnData(Get:String = "")
		  Local HTRD:HTTPReturnData = New(HTTPReturnData), buffer:String, rlnewline:String
			
			stream.WriteString("GET /" + Get + " HTTP/1.0~nHOST: " + host + "~r~n~r~n")
			
		   'WriteLine(stream, "GET /" + get + " HTTP/1.0~nHost: " + Self.host + "~nUser-Agent: " + Self.agent + "~n~n") 
		   'WriteLine stream, "GET /" + Get + " HTTP/1.0" ' GET / gets Default page
		   'WriteLine stream, "Host: " + host
		   'WriteLine stream, "User-Agent: " + agent
		   'WriteLine stream, "Accept: */*"
		   'WriteLine stream, ""
		
		  Local cExtType:String, cExt:String, cLength:Int
		   ReadLine(stream)
			While Not Eof(stream)
			  rlnewline = ReadLine(stream)
			  
			  Local spos:Int = Instr(rlnewline, ":")
				Select Lower(Left(rlnewline, spos - 1))
					Case "content-type"
					  Local prtmp:String = Mid(rlnewline, spos + 2, Instr(rlnewline, ";") - spos - 2), slpos:Int = Instr(prtmp, "/")
					  cExtType = Left(prtmp, slpos - 1) cExt = Right(prtmp, prtmp.Length - slpos)
						
					Case "content-length"
						cLength = Int(Right(rlnewline, rlnewline.Length - spos - 1))
						
					Case ""
					   Exit
						
				End Select
				
			Wend
			
			While Not Eof(stream) 
			  rlnewline = ReadLine(stream)
				
				buffer:+ rlnewline + "~n"
				
			Wend
			
		  HTRD.Set(Left(buffer, buffer.Length - 1), cExtType, cExt, cLength)
			
		   If autoClose Close() 
		   
		   Return HTRD
		 
		End Method
		
		Method Post:String(page:String = "", keys:String[] , values:String[] ) 
		  Local buffer:String
		  Local data:String
		  Local i:Int
			
			For i = 0 To keys.Length - 1
				data:+ UrlEncode(keys[i] ) + "=" + UrlEncode(values[i] ) + "&"
				
			Next
			
		  data = Left(data, data.Length - 1) 
			WriteLine(stream, "POST /" + page + " HTTP/1.0~nHost: " + Self.host + "~nUser-Agent: " + Self.agent + "~nContent-Length: " + data.Length + "~nContent-Type: application/x-www-form-urlencoded~n~n" + data) 
			
			While Not Eof(stream) 
				buffer:+ReadLine(stream) + "~n"
				
			Wend
			
		 If autoClose Close() 
		
		   Return Left(buffer, buffer.Length - 1) 
			
		End Method
		
		Method Close() 
			If Self.stream CloseStream(Self.stream) 
			If Self.sock CloseSocket(Self.sock) 
			
		End Method
	
		Function UrlEncode:String(url:String) 
		  Local buffer:String
		  Local Char:Int
		  Local i:Int
			
			For i = 1 To url.Length
			  Char = Asc(Mid(url, i, 1)) 
				
				If(Char >= 48 And Char <= 57) Or (Char >= 65 And Char <= 90) Or (Char >= 97 And Char <= 122) Or Char = 43 Or Char = 45 Or Char = 46 Or Char = 95
					buffer = buffer + Chr(Char) 
					
				Else
					buffer = buffer + "%" + Right(Hex(Char), 2) 
					
				End If
				
			Next
			
		   Return buffer
		
		End Function
		
		Function UrlDecode:String(url:String) 
		  Local sHex:String = "0123456789ABCDEF"
		  Local buffer:String
		  Local i:Int
			
			For i = 1 To url.Length
				If Mid(url, i, 1) = "%"
					buffer = buffer + Chr(Instr(sHex, Mid(url, i + 1, 1)) Shl 4 + Instr(sHex, Mid(url, i + 2, 1)) - 17) 
				   i:+ 2
					
				Else
					buffer = buffer + Mid(url, i, 1)
					 
				End If
				
			Next
			
		   Return buffer
		
		End Function
	
End Type

Type HTTPReturnData
	Field Content:String
	Field ContLength:Int
	
	Field ExtensionType:String
	Field Extension:String		
		
		Method Set(Cont:String, ExtType:String, Ext:String, CLen:Int)
			Content = Cont
			ContLength = CLen
			Extension = Ext
			ExtensionType = ExtType
			
		End Method
		
		Method SaveContent(File:String, useExt:Int = False)
		 
		 If useExt File:+ "." + Extension
			
			SaveText(Content, File)
			
		End Method
		
		Method ToString:String()
			Return "Content-Type: " + ExtensionType + "/" + Extension + "~nContent-Length: " + ContLength
			
		End Method
		
End Type


Nevermind. There was a space in my url (word="Hello there!").. lol!

Thanks all!

Nothing I changed made a connection (using "http::" and writeline("GET /" + url + "HTTP/1.0 (or 1.1) ~r~n~r~n")), OpenStream still returns null.
I think you're a bit confused about the difference between a tcp and a http stream...
Local stream:TStream = OpenStream("http::ajax.googleapis.com/ajax/services/language/translate?v=1.0&q=hello&langpair=en%7Cel")
Assert stream, "Couldn't establish connection"

Print stream.ReadLine()

stream.Close()


It'd probably be a good idea to check that the header returned is free from error (HTTP/1.X 200 OK).

You might also consider this part of the docs...
An area to pay special attention to relates to correctly identifying yourself in your requests. Applications MUST always include a valid and accurate http referer header in their requests.


I think you're a bit confused about the difference between a tcp and a http stream...

Ahh. That's much simpler..

Local word:String = "Hello there, mate!".Replace(" ", "+")
Local Text:String = GetHTTPString("ajax.googleapis.com/ajax/services/language/translate?v=1.0&q=" + word + "&langpair=en%7Cel")

SaveText(Text, "data.txt")

Local json:TJSON = TJSON.Create(Text)

SaveText(json.GetValue("responseData.translatedText").ToString(), "data.txt")


Function GetHTTPString:String(url:String)
  Local stream:TStream = OpenStream("http::" + url)

	If stream <> Null
	  Local result:String = stream.ReadLine()
		
		Return result
		
	Else
	   Return Null
	   
	End If
	
End Function


EDIT:
It'd probably be a good idea to check that the header returned is free from error (HTTP/1.X 200 OK).
How would you check the returned header using the code you posted? (AFAIK it just returns the content)

EDIT2: I suppose that would be {"responseData": {"translatedText":"&#915;&#949;&#953;&#940;"}, "responseDetails": null, "responseStatus": 200}??