Remote Webservice

From Tera-WURFL

(Difference between revisions)
Jump to: navigation, search
(Created page with '==Introduction== Tera-WURFL 2.1.1 introduced a full-featured webservice and remote client for many languages. Some reasons to use the remote webservice to query Tera-WURFL are: …')
 
(24 intermediate revisions not shown)
Line 2: Line 2:
Tera-WURFL 2.1.1 introduced a full-featured webservice and remote client for many languages.  Some reasons to use the remote webservice to query Tera-WURFL are:
Tera-WURFL 2.1.1 introduced a full-featured webservice and remote client for many languages.  Some reasons to use the remote webservice to query Tera-WURFL are:
* You want to share your Tera-WURFL database over multiple installations or servers, so you just install Tera-WURFL once in the '''backend''' and use the remote client on all the '''frontend''' servers (you only need one file for the remote client).
* You want to share your Tera-WURFL database over multiple installations or servers, so you just install Tera-WURFL once in the '''backend''' and use the remote client on all the '''frontend''' servers (you only need one file for the remote client).
-
* You want to query Tera-WURFL from a language other than PHP, like JavaScript, ActionScript 3, Perl, VBScript, .NET, ruby, etc...  Any language that can retrieve a remote file and parse it as XML can use the webservice.
+
* You want to query Tera-WURFL from a language other than PHP, like JavaScript, ActionScript 3, Perl, Python, VBScript, .NET, ruby, etc...  Any language that can retrieve a remote file and parse it as XML can use the webservice.
* You want to provide managed mobile device detection capabilities to your customers without giving them access to the Tera-WURFL library itself.
* You want to provide managed mobile device detection capabilities to your customers without giving them access to the Tera-WURFL library itself.
==Backend Files==
==Backend Files==
===TeraWurflWebservice.php===
===TeraWurflWebservice.php===
-
This file defines the '''TeraWurflWebservice''' class and provides the functionality to parse an incoming request, query Tera-WURFL and return the results in XML form.
+
This file defines the '''TeraWurflWebservice''' class and provides the functionality to parse an incoming request, query Tera-WURFL and return the results in XML form. This class could easily be extended to support other transports like JSON or SOAP.
 +
 
===webservice.php===
===webservice.php===
The '''webservice.php''' file takes the raw request from the remote client and decodes it if necessary, then passes it to the TeraWurflWebService class for processing.  The file then sends the response back to the client that requested it.
The '''webservice.php''' file takes the raw request from the remote client and decodes it if necessary, then passes it to the TeraWurflWebService class for processing.  The file then sends the response back to the client that requested it.
==Frontend Files==
==Frontend Files==
-
===TeraWurflRemoteClient.php===
+
The Remote Webservice clients require you to pass a list of capabilities that you would like to retrieve.  To see the available capabilities for any device in the WURFL, you can use the [http://www.tera-wurfl.com/explore/ Tera-WURFL Explorer].
-
This file defines '''TeraWurflRemoteClient''' which is a stand-alone Tera-WURFL remote client (available from the '''TeraWurflRemoteClient/''' folder.  The TeraWurflRemoteClient has similar usage to the main Tera-WURFL library, as shown below.
+
 
-
<pre>
+
===PHP===
 +
For PHP, there is a full-blown client API that mimics the standalone API called '''TeraWurflRemoteClient'''. The remote client (available from the '''TeraWurflRemoteClient/''' folder) can be moved to any location, even a different server, and used to query your Tera-WURFL installation. Just include '''TeraWurflRemoteClient.php''' in your scripts and use it as follows:
 +
<geshi lang=php lines=0>
require_once('../TeraWurflRemoteClient.php');
require_once('../TeraWurflRemoteClient.php');
$wurflObj = new TeraWurflRemoteClient('http://localhost/Tera-Wurfl/webservice.php');
$wurflObj = new TeraWurflRemoteClient('http://localhost/Tera-Wurfl/webservice.php');
-
$capabilities = array("product_info","fake_capability");
+
// The groups or capabilities you want to use
-
$wurflObj->getCapabilitiesFromAgent(TeraWurflRemoteClient::getUserAgent(),$capabilities);                
+
$capabilities = array("is_wireless_device|brand_name|model_name|playback|tera_wurfl");
-
if($wurflObj->errors){
+
$wurflObj->getCapabilitiesFromAgent(TeraWurflRemoteClient::getUserAgent(),$capabilities);
-
foreach($wurflObj->errors as $name => $error){
+
echo "You are on a {$wurflObj->getDeviceCapability('brand_name')} {$wurflObj->getDeviceCapability('model_name')}<br/>";
-
echo "$name: $error<br/>";
+
$text = $wurflObj->getDeviceCapability('is_wireless_device')? "This device is wireless": "This device is a desktop web browser";
 +
echo $text;
 +
</geshi>
 +
 
 +
The PHP TeraWurflRemoteClient constructor takes many optional arguments:
 +
<geshi lang=php lines=0>
 +
// The URL of your Tera-WURFL server's webservice.php
 +
$url = 'http://localhost/Tera-WURFL/webservice.php';
 +
 
 +
// The return format of the data to use (either $FORMAT_JSON [default] or $FORMAT_XML)
 +
 
 +
$data_format = TeraWurflRemoteClient::$FORMAT_JSON;
 +
 
 +
// The timeout in seconds to wait for the server to respond before giving up
 +
$timeout = 1;
 +
 
 +
// The HTTP client method to use (either $METHOD_URL_WRAPPER [default] or $METHOD_CURL)
 +
$method = TeraWurflRemoteClient::$METHOD_CURL;
 +
 
 +
// Instantiate the TeraWurflRemoteClient object
 +
$wurflObj = new TeraWurflRemoteClient($url,$data_format,$timeout,$method);
 +
</geshi>
 +
 
 +
===Perl===
 +
The Perl client uses URI, LWP::Simple and XML::Simple to request the webservice and process the response.  Although I've been programming in Perl since 1996, I haven't used it much for web applications or XML.  If there is a more efficient, readable way to do this, please let me know!
 +
<geshi lang=perl lines=0>
 +
#!/usr/bin/perl
 +
 
 +
use strict;
 +
use URI;
 +
use LWP::Simple;
 +
use XML::Simple;
 +
 
 +
# Location of Tera-WURFL webservice
 +
my $webservice = URI->new("http://localhost/Tera-Wurfl/webservice.php");
 +
 
 +
# The User Agent you would like to check
 +
my $user_agent = "Mozilla/5.0 (Linux; U; Android 1.0; en-us; dream) AppleWebKit/525.10+ (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2";
 +
 
 +
# Capabilities and Groups you want to find
 +
my $search = "brand_name|model_name|marketing_name|is_wireless_device|device_claims_web_support|tera_wurfl";
 +
 
 +
# Build the query String
 +
$webservice->query_form(
 +
"ua" => $user_agent,
 +
"search" => $search
 +
);
 +
 
 +
# Make webservice request
 +
my $xml_response = get $webservice;
 +
# Parse webserver response
 +
my $xml_parser = new XML::Simple(forcearray => 1, keyattr => ['key']);
 +
my $xml_object = $xml_parser->XMLin($xml_response);
 +
# Convert XML Object into Perl Hash
 +
my %capabilities;
 +
foreach(@{$xml_object->{device}[0]->{capability}}){
 +
$capabilities{$_->{name}}=$_->{value};
 +
}
 +
# Make top-level properties available in hash
 +
my %properties = (
 +
"apiVersion", $xml_object->{device}[0]->{apiVersion},
 +
"id", $xml_object->{device}[0]->{id},
 +
"user_agent", $xml_object->{device}[0]->{useragent}
 +
);
 +
 
 +
# Tera-WURFL proccessing is finished, capabilities are available in %capabilities, properties in %properties
 +
 
 +
print "-- Response from Tera-WURFL $properties{apiVersion}\n";
 +
print "-- Device Detected as: $capabilities{brand_name} $capabilities{model_name} $capabilities{marketing_name}\n";
 +
 
 +
my($name,$value);
 +
while(($name,$value) = each(%capabilities)){
 +
print "$name: $value\n";
 +
}
 +
</geshi>
 +
 
 +
===Python===
 +
I don't use Python, but I learned enough of it to make this client/example.  If one of you Python gurus want to clean it up for me and explain your changes, please send it my way and I will be glad to include it in a future release.
 +
* [http://www.ghd-uksale.com ghd sale]  
 +
* [http://www.ghds-uk.net  ghd uk] 
 +
* [http://www.juicycouture-uksale.com Juicy Couture]
 +
 
 +
<geshi lang=python lines=0>
 +
# -*- coding: utf-8 -*-
 +
# Python
 +
 
 +
from urllib import quote
 +
from urllib import urlopen
 +
from xml.dom.minidom import parseString
 +
 
 +
# Location of Tera-WURFL webservice
 +
webservice = "http://localhost/Tera-Wurfl/webservice.php"
 +
 
 +
# The User Agent you would like to check
 +
user_agent = "Mozilla/5.0 (Linux; U; Android 1.0; en-us; dream) AppleWebKit/525.10+ (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2"
 +
 
 +
# Capabilities and Groups you want to find
 +
search = "brand_name|model_name|marketing_name|is_wireless_device|device_claims_web_support|tera_wurfl"
 +
 
 +
querystring = "?ua=" + quote(user_agent) + "&search=" + search
 +
xml_response = urlopen(webservice + querystring).read()
 +
xml_object = parseString(xml_response)
 +
deviceNode = xml_object.firstChild.childNodes[1]
 +
errorsNode = xml_object.firstChild.childNodes[3]
 +
capabilitiesNodes = deviceNode.getElementsByTagName("capability");
 +
 
 +
# Setup Top Level Properties
 +
properties = {
 +
"apiVersion": deviceNode.attributes['apiVersion'].value,
 +
"id": deviceNode.attributes['id'].value,
 +
"useragent": deviceNode.attributes['useragent'].value
 +
}
 +
# Setup Capabilities
 +
capabilities = {}
 +
for capNode in capabilitiesNodes:
 +
# print capNode.toxml() + capNode.attributes['name'].value + capNode.attributes['value'].value + "\n"
 +
capabilities[capNode.attributes['name'].value] = capNode.attributes['value'].value
 +
 
 +
 
 +
# Tera-WURFL processing is finished,  properties and capabilities dictionaries are now filled with data
 +
 
 +
print "Response from Tera-WURFL " + properties['apiVersion'];
 +
for name, value in capabilities.items():
 +
print name + ": " + value
 +
 
 +
 
 +
</geshi>
 +
 
 +
===ActionScript===
 +
The complete usage example with a Flash FLA is included in the distribution under TeraWurflRemoteClient/examples/ActionScript.  I've done a lot of work in AS1, AS2, AS3, Flash, and Flex so I plan to develop a full-featured client like the PHP TeraWurflRemoteClient.  Now I just need to figure out what people would really need an ActionScript Tera-WURFL client for!  If you have a use for this client, please let me know what you use it for!
 +
<geshi lang=actionscript lines=0>
 +
btnDetect.addEventListener(MouseEvent.CLICK,startDetection);
 +
function startDetection(event:Event):void {
 +
var xml:XML;
 +
 +
var urlRequest:URLRequest = new URLRequest("http://localhost/Tera-Wurfl/webservice.php?ua=" + escape(txtUA.text) + "&search=" + txtCapabilities.text);
 +
 +
var urlLoader:URLLoader = new URLLoader();
 +
urlLoader.addEventListener(Event.COMPLETE, urlLoader_complete);
 +
urlLoader.load(urlRequest);
 +
}
 +
function urlLoader_complete(evt:Event):void {
 +
txtResult.text = 'Result:\n';
 +
    var xml = new XML(evt.currentTarget.data);
 +
for each( var i:Object in xml..capability){
 +
txtResult.appendText(i.@name + ": " + i.@value + "\n");
 +
}
 +
}
 +
</geshi>
 +
 
 +
===JavaScript===
 +
The following is the Tera-WURFL Remote Client for JavaScript included in Tera-WURFL 2.1.1.  '''TeraWurflRemoteClient.js'''
 +
<geshi lang=javascript lines=0>
 +
/**
 +
* Tera-WURFL remote webservice client for JavaScript
 +
*
 +
* Tera-WURFL was written by Steve Kamerman, and is based on the
 +
* Java WURFL Evolution package by Luca Passani and WURFL PHP Tools by Andrea Trassati.
 +
* This version uses a MySQL database to store the entire WURFL file, multiple patch
 +
* files, and a persistent caching mechanism to provide extreme performance increases.
 +
*
 +
* @author Steve Kamerman <stevekamerman AT gmail.com>
 +
* @version Stable 2.1.1 (2010/02/21 17:41:47)
 +
* @license http://www.mozilla.org/MPL/ MPL Vesion 1.1
 +
*
 +
* Documentation is available at http://www.tera-wurfl.com
 +
*/
 +
function TeraWurflRemoteClient(webservice){
 +
// Properties
 +
this.webservice = webservice;
 +
this.capabilities = new Array();
 +
this.errors = new Array();
 +
this.xmlHttpReq = false;
 +
var self = this;
 +
 
 +
// Methods
 +
this.getCapabilitiesFromAgent = function(userAgent,capabilities_search){
 +
this.userAgent = userAgent;
 +
this.search = capabilities_search.join('|');
 +
this.fullURL = this.webservice + '?ua=' + this.urlencode(this.userAgent) + '&search=' + this.search;
 +
 +
if(window.XMLHttpRequest) {
 +
self.xmlHttpReq = new XMLHttpRequest();
 +
}else if (window.ActiveXObject) {
 +
try{
 +
self.xmlHttpReq = new ActiveXObject("Msxml2.XMLHTTP");
 +
}catch(e){
 +
try{
 +
self.xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
 +
}catch(e){}
 +
}
 +
}
 +
self.xmlHttpReq.open('GET', this.fullURL, true);
 +
self.xmlHttpReq.onreadystatechange = this.handleResponse;
 +
self.xmlHttpReq.send(null);
 +
}
 +
 
 +
this.handleResponse = function(){
 +
if(self.xmlHttpReq.readyState != 4) return;
 +
if(self.xmlHttpReq.status == 12029 || self.xmlHttpReq.status == 12007){
 +
alert("Error: Could not connect to remote webservice");
 +
return;
 +
}
 +
if (window.ActiveXObject) { // for IE
 +
var doc = self.xmlHttpReq.responseXML;
 +
}else{ // code for Mozilla, Firefox, Opera, etc.
 +
var parser=new DOMParser();
 +
var doc=parser.parseFromString(self.xmlHttpReq.responseText,"text/xml");
 +
}
 +
try{
 +
var data  = "";
 +
if(doc.documentElement){ //Response from webservice
 +
data = doc.documentElement;
 +
self.receivedRemoteCapabilities(data);
 +
}else{
 +
data = self.xmlHttpReq.responseText; //from web page
 +
alert("No XML:\nresponseText["+data+"]\nresponseXML["+self.xmlHttpReq.responseXML+"]\nAll Headers:\n["+self.xmlHttpReq.getAllResponseHeaders()+"]");
 +
}
 +
}catch(e) {}
 +
}
 +
 +
this.receivedRemoteCapabilities = function(xml_response){
 +
this.devices = xml_response.getElementsByTagName('device');
 +
this.capabilitiesXML = xml_response.getElementsByTagName('capability');
 +
this.errorsXML = xml_response.getElementsByTagName('error');
 +
var name, value, i;
 +
// Put capabilities into an object / associative array
 +
for(i=0;i<this.capabilitiesXML.length;i++){
 +
name = this.capabilitiesXML[i].getAttribute('name');
 +
value = this.capabilitiesXML[i].getAttribute('value');
 +
this.capabilities[name] = value;
 +
}
 +
// Put errors into an array
 +
for(i=0;i<this.errorsXML.length;i++){
 +
errname = this.errorsXML[i].getAttribute('name');
 +
errdesc = this.errorsXML[i].getAttribute('description');
 +
this.errors[i] = {name: errname, description: errdesc};
 +
}
 +
this.onUpdate(this.capabilities,this.errors);
 +
}
 +
 +
this.urlencode = function(str){
 +
str = (str+'').toString();
 +
return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/\*/g, '%2A').replace(/%20/g, '+');
 +
}
 +
}
 +
</geshi>
 +
 
 +
Here is a client usage example. '''example.html'''
 +
 
 +
<geshi lang=javascript lines=0>
 +
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 +
<html xmlns="http://www.w3.org/1999/xhtml">
 +
<head>
 +
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 +
<title>Tera-WURFL Remote Client</title>
 +
<style type="text/css">
 +
.error {
 +
color: #D00;
 +
font-weight: bold;
 +
padding-left: 10px;
 +
}
 +
</style>
 +
<script src="TeraWurflRemoteClient.js"></script>
 +
<script type="text/javascript">
 +
/**
 +
* Tera-WURFL Remote Client for JavaScript Example
 +
*/
 +
 +
// The URL to your Tera-WURFL installation's webservice.php
 +
var webserviceURL = 'http://www.tera-wurfl.com/Tera-Wurfl/webservice.php';
 +
 +
function callTeraWurfl(){
 +
document.getElementById('result').innerHTML = "Loading...";
 +
document.getElementById('device_model').innerHTML = "&nbsp";
 +
 +
// The user agent you are looking for.  In Javascript this is 'navigator.userAgent' for the client
 +
var userAgent = document.getElementById('user_agent').value;
 +
// The capabilities you are looking for, in an array, example: search = ['product_info','tera_wurfl','playback'];
 +
var search = document.getElementById('capabilities').value.split('|');
 +
// Create new TeraWurfl Object
 +
wurflObj = new TeraWurflRemoteClient(webserviceURL);
 +
// Define callback option
 +
wurflObj.onUpdate = handleResults;
 +
// Call Tera-WURFL via the webservice
 +
wurflObj.getCapabilitiesFromAgent(userAgent,search);
 +
return false;
 +
}
 +
 +
// This is the callback function that I've specified above; yours needs to receive 2 arrays like this one:
 +
function handleResults(capabilities,errors){
 +
// Clear results
 +
document.getElementById('result').innerHTML = "&nbsp;";
 +
// Check for Errors
 +
if(errors.length > 0){
 +
errorstring = '<div class="error">The following errors were encountered:<br/>';
 +
for (var i=0; i<errors.length;i++) {
 +
// Display errors
 +
errorstring += errors[i].name + ': ' +  errors[i].description + '<br/>';
 +
}
 +
errorstring += '</div>';
 +
document.getElementById('result').innerHTML += errorstring;
 +
}
 +
// Display model name
 +
document.getElementById('device_model').innerHTML += "<h3>"+capabilities['brand_name']+" "+capabilities['model_name']+" "+capabilities['marketing_name']+"</h3>";
 +
// Display all capabilities.  Access individual capabilities like this: capabilities.is_wireless_device **OR** capabilities['is_wireless_device']
 +
for (var name in capabilities) {
 +
if (name != "length") {
 +
document.getElementById('result').innerHTML += "<br/>"+name+": "+capabilities[name];
 +
}
}
}
}
}
-
</pre>
+
 +
</script>
 +
 +
</head>
 +
<body onload="callTeraWurfl();">
 +
<h2>Tera-WURFL Remote Client (Javascript)</h2>
 +
<p>Paste a user agent to see its capabilities: </p>
 +
<form>
 +
<p>
 +
  <label>User Agent:
 +
    <input name="user_agent" type="text" id="user_agent" value="Mozilla/5.0 (Linux; U; Android 1.5; en-us; T-Mobile G1 Build/CRC1) AppleWebKit/528.5+ (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20.1" size="150" />
 +
  </label>
 +
</p>
 +
<p>
 +
  <label>Capabilities:
 +
    <input name="capabilities" type="text" id="capabilities" size="150" value="product_info|tera_wurfl|playback" />
 +
  </label>
 +
</p>
 +
<p>
 +
<input type="submit" name="detect_button" id="detect_button" value="Detect User Agent" onclick="javascript:return callTeraWurfl();"/>
 +
</p>
 +
<center><div id="device_model">&nbsp;</div></center>
 +
<div id="result" name="result" style="font-family:'Courier New', Courier, monospace">Loading...</div>
 +
</form>
 +
</body>
 +
</html>
 +
</geshi>
 +
[http://www.lnstock.com click here]
 +
[http://www.airjordan-clubs.com/ air jordan shoes]

Latest revision as of 01:00, 30 May 2012

Contents

Introduction

Tera-WURFL 2.1.1 introduced a full-featured webservice and remote client for many languages. Some reasons to use the remote webservice to query Tera-WURFL are:

Backend Files

TeraWurflWebservice.php

This file defines the TeraWurflWebservice class and provides the functionality to parse an incoming request, query Tera-WURFL and return the results in XML form. This class could easily be extended to support other transports like JSON or SOAP.

webservice.php

The webservice.php file takes the raw request from the remote client and decodes it if necessary, then passes it to the TeraWurflWebService class for processing. The file then sends the response back to the client that requested it.

Frontend Files

The Remote Webservice clients require you to pass a list of capabilities that you would like to retrieve. To see the available capabilities for any device in the WURFL, you can use the Tera-WURFL Explorer.

PHP

For PHP, there is a full-blown client API that mimics the standalone API called TeraWurflRemoteClient. The remote client (available from the TeraWurflRemoteClient/ folder) can be moved to any location, even a different server, and used to query your Tera-WURFL installation. Just include TeraWurflRemoteClient.php in your scripts and use it as follows:

require_once('../TeraWurflRemoteClient.php');
$wurflObj = new TeraWurflRemoteClient('http://localhost/Tera-Wurfl/webservice.php');
// The groups or capabilities you want to use
$capabilities = array("is_wireless_device|brand_name|model_name|playback|tera_wurfl");
$wurflObj->getCapabilitiesFromAgent(TeraWurflRemoteClient::getUserAgent(),$capabilities);
echo "You are on a {$wurflObj->getDeviceCapability('brand_name')} {$wurflObj->getDeviceCapability('model_name')}<br/>";
$text = $wurflObj->getDeviceCapability('is_wireless_device')? "This device is wireless": "This device is a desktop web browser";
echo $text;

The PHP TeraWurflRemoteClient constructor takes many optional arguments:

// The URL of your Tera-WURFL server's webservice.php
$url = 'http://localhost/Tera-WURFL/webservice.php';
 
// The return format of the data to use (either $FORMAT_JSON [default] or $FORMAT_XML)
 
$data_format = TeraWurflRemoteClient::$FORMAT_JSON;
 
// The timeout in seconds to wait for the server to respond before giving up
$timeout = 1;
 
// The HTTP client method to use (either $METHOD_URL_WRAPPER [default] or $METHOD_CURL)
$method = TeraWurflRemoteClient::$METHOD_CURL;
 
// Instantiate the TeraWurflRemoteClient object
$wurflObj = new TeraWurflRemoteClient($url,$data_format,$timeout,$method);

Perl

The Perl client uses URI, LWP::Simple and XML::Simple to request the webservice and process the response. Although I've been programming in Perl since 1996, I haven't used it much for web applications or XML. If there is a more efficient, readable way to do this, please let me know!

#!/usr/bin/perl
 
use strict;
use URI;
use LWP::Simple;
use XML::Simple;
 
# Location of Tera-WURFL webservice
my $webservice = URI->new("http://localhost/Tera-Wurfl/webservice.php");
 
# The User Agent you would like to check
my $user_agent = "Mozilla/5.0 (Linux; U; Android 1.0; en-us; dream) AppleWebKit/525.10+ (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2";
 
# Capabilities and Groups you want to find
my $search = "brand_name|model_name|marketing_name|is_wireless_device|device_claims_web_support|tera_wurfl";
 
# Build the query String
$webservice->query_form(
	"ua" => $user_agent,
	"search" => $search
);
 
# Make webservice request
my $xml_response = get $webservice;
# Parse webserver response
my $xml_parser = new XML::Simple(forcearray => 1, keyattr => ['key']);
my $xml_object = $xml_parser->XMLin($xml_response);
# Convert XML Object into Perl Hash
my %capabilities;
foreach(@{$xml_object->{device}[0]->{capability}}){
	$capabilities{$_->{name}}=$_->{value};
}
# Make top-level properties available in hash
my %properties = (
	"apiVersion", $xml_object->{device}[0]->{apiVersion},
	"id", $xml_object->{device}[0]->{id},
	"user_agent", $xml_object->{device}[0]->{useragent}
);
 
# Tera-WURFL proccessing is finished, capabilities are available in %capabilities, properties in %properties
 
print "-- Response from Tera-WURFL $properties{apiVersion}\n";
print "-- Device Detected as: $capabilities{brand_name} $capabilities{model_name} $capabilities{marketing_name}\n";
 
my($name,$value);
while(($name,$value) = each(%capabilities)){
	print "$name: $value\n";
}

Python

I don't use Python, but I learned enough of it to make this client/example. If one of you Python gurus want to clean it up for me and explain your changes, please send it my way and I will be glad to include it in a future release.

# -*- coding: utf-8 -*-
# Python
 
from urllib import quote
from urllib import urlopen
from xml.dom.minidom import parseString
 
# Location of Tera-WURFL webservice
webservice = "http://localhost/Tera-Wurfl/webservice.php"
 
# The User Agent you would like to check
user_agent = "Mozilla/5.0 (Linux; U; Android 1.0; en-us; dream) AppleWebKit/525.10+ (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2"
 
# Capabilities and Groups you want to find
search = "brand_name|model_name|marketing_name|is_wireless_device|device_claims_web_support|tera_wurfl"
 
querystring = "?ua=" + quote(user_agent) + "&search=" + search
xml_response = urlopen(webservice + querystring).read()
xml_object = parseString(xml_response)
deviceNode = xml_object.firstChild.childNodes[1]
errorsNode = xml_object.firstChild.childNodes[3]
capabilitiesNodes = deviceNode.getElementsByTagName("capability");
 
# Setup Top Level Properties
properties = {
	"apiVersion": deviceNode.attributes['apiVersion'].value,
	"id": deviceNode.attributes['id'].value,
	"useragent": deviceNode.attributes['useragent'].value
}
# Setup Capabilities
capabilities = {}
for capNode in capabilitiesNodes:
#	print capNode.toxml() + capNode.attributes['name'].value + capNode.attributes['value'].value + "\n"
	capabilities[capNode.attributes['name'].value] = capNode.attributes['value'].value
 
 
# Tera-WURFL processing is finished,  properties and capabilities dictionaries are now filled with data
 
print "Response from Tera-WURFL " + properties['apiVersion'];
for name, value in capabilities.items():
	print name + ": " + value

ActionScript

The complete usage example with a Flash FLA is included in the distribution under TeraWurflRemoteClient/examples/ActionScript. I've done a lot of work in AS1, AS2, AS3, Flash, and Flex so I plan to develop a full-featured client like the PHP TeraWurflRemoteClient. Now I just need to figure out what people would really need an ActionScript Tera-WURFL client for! If you have a use for this client, please let me know what you use it for!

btnDetect.addEventListener(MouseEvent.CLICK,startDetection);
function startDetection(event:Event):void {
	var xml:XML;
 
	var urlRequest:URLRequest = new URLRequest("http://localhost/Tera-Wurfl/webservice.php?ua=" + escape(txtUA.text) + "&search=" + txtCapabilities.text);
 
	var urlLoader:URLLoader = new URLLoader();
	urlLoader.addEventListener(Event.COMPLETE, urlLoader_complete);
	urlLoader.load(urlRequest);
}
function urlLoader_complete(evt:Event):void {
	txtResult.text = 'Result:\n';
    var xml = new XML(evt.currentTarget.data);
	for each( var i:Object in xml..capability){
		txtResult.appendText(i.@name + ": " + i.@value + "\n");
	}
}

JavaScript

The following is the Tera-WURFL Remote Client for JavaScript included in Tera-WURFL 2.1.1. TeraWurflRemoteClient.js

/**
 * Tera-WURFL remote webservice client for JavaScript
 * 
 * Tera-WURFL was written by Steve Kamerman, and is based on the
 * Java WURFL Evolution package by Luca Passani and WURFL PHP Tools by Andrea Trassati.
 * This version uses a MySQL database to store the entire WURFL file, multiple patch
 * files, and a persistent caching mechanism to provide extreme performance increases.
 * 
 * @author Steve Kamerman <stevekamerman AT gmail.com>
 * @version Stable 2.1.1 (2010/02/21 17:41:47)
 * @license http://www.mozilla.org/MPL/ MPL Vesion 1.1
 * 
 * Documentation is available at http://www.tera-wurfl.com
 */
function TeraWurflRemoteClient(webservice){
	// Properties
	this.webservice = webservice;
	this.capabilities = new Array();
	this.errors = new Array();
	this.xmlHttpReq = false;
	var self = this;
 
	// Methods
	this.getCapabilitiesFromAgent = function(userAgent,capabilities_search){
		this.userAgent = userAgent;
		this.search = capabilities_search.join('|');
		this.fullURL = this.webservice + '?ua=' + this.urlencode(this.userAgent) + '&search=' + this.search;
 
		if(window.XMLHttpRequest) {
			self.xmlHttpReq = new XMLHttpRequest();
		}else if (window.ActiveXObject) {
			try{
				self.xmlHttpReq = new ActiveXObject("Msxml2.XMLHTTP");
			}catch(e){
				try{
					self.xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
				}catch(e){}
			}
		}
		self.xmlHttpReq.open('GET', this.fullURL, true);
		self.xmlHttpReq.onreadystatechange = this.handleResponse;
		self.xmlHttpReq.send(null);
	}
 
	this.handleResponse = function(){
		if(self.xmlHttpReq.readyState != 4) return;
		if(self.xmlHttpReq.status == 12029 || self.xmlHttpReq.status == 12007){
			alert("Error: Could not connect to remote webservice");
			return;
		}
		if (window.ActiveXObject) { // for IE
			var doc = self.xmlHttpReq.responseXML;
		}else{ // code for Mozilla, Firefox, Opera, etc.
			var parser=new DOMParser();
			var doc=parser.parseFromString(self.xmlHttpReq.responseText,"text/xml");
		}
		try{
			var data  = "";
			if(doc.documentElement){ //Response from webservice
				data = doc.documentElement;
				self.receivedRemoteCapabilities(data);
			}else{
				data = self.xmlHttpReq.responseText; //from web page
				alert("No XML:\nresponseText["+data+"]\nresponseXML["+self.xmlHttpReq.responseXML+"]\nAll Headers:\n["+self.xmlHttpReq.getAllResponseHeaders()+"]"); 
			}
		}catch(e) {}
	}
 
	this.receivedRemoteCapabilities = function(xml_response){
		this.devices = xml_response.getElementsByTagName('device');
		this.capabilitiesXML = xml_response.getElementsByTagName('capability');
		this.errorsXML = xml_response.getElementsByTagName('error');
		var name, value, i;
		// Put capabilities into an object / associative array
		for(i=0;i<this.capabilitiesXML.length;i++){
			name = this.capabilitiesXML[i].getAttribute('name');
			value = this.capabilitiesXML[i].getAttribute('value');
			this.capabilities[name] = value;
		}
		// Put errors into an array
		for(i=0;i<this.errorsXML.length;i++){
			errname = this.errorsXML[i].getAttribute('name');
			errdesc = this.errorsXML[i].getAttribute('description');
			this.errors[i] = {name: errname, description: errdesc};
		}
		this.onUpdate(this.capabilities,this.errors);
	}
 
	this.urlencode = function(str){
		str = (str+'').toString();
		return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/\*/g, '%2A').replace(/%20/g, '+');
	}
}

Here is a client usage example. example.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Tera-WURFL Remote Client</title>
<style type="text/css"> 
.error {
	color: #D00;
	font-weight: bold;
	padding-left: 10px;
}
</style>
<script src="TeraWurflRemoteClient.js"></script>
<script type="text/javascript"> 
/**
 * Tera-WURFL Remote Client for JavaScript Example
 */
 
// The URL to your Tera-WURFL installation's webservice.php
var webserviceURL = 'http://www.tera-wurfl.com/Tera-Wurfl/webservice.php';
 
function callTeraWurfl(){
	document.getElementById('result').innerHTML = "Loading...";
	document.getElementById('device_model').innerHTML = "&nbsp";
 
	// The user agent you are looking for.  In Javascript this is 'navigator.userAgent' for the client
	var userAgent = document.getElementById('user_agent').value;
	// The capabilities you are looking for, in an array, example: search = ['product_info','tera_wurfl','playback'];
	var search = document.getElementById('capabilities').value.split('|');
	// Create new TeraWurfl Object
	wurflObj = new TeraWurflRemoteClient(webserviceURL);
	// Define callback option
	wurflObj.onUpdate = handleResults;
	// Call Tera-WURFL via the webservice
	wurflObj.getCapabilitiesFromAgent(userAgent,search);
	return false;
}
 
// This is the callback function that I've specified above; yours needs to receive 2 arrays like this one:
function handleResults(capabilities,errors){
	// Clear results
	document.getElementById('result').innerHTML = "&nbsp;";
	// Check for Errors
	if(errors.length > 0){
		errorstring = '<div class="error">The following errors were encountered:<br/>';
		for (var i=0; i<errors.length;i++) {
			// Display errors
			errorstring += errors[i].name + ': ' +  errors[i].description + '<br/>';
		}
		errorstring += '</div>';
		document.getElementById('result').innerHTML += errorstring;
	}
	// Display model name
	document.getElementById('device_model').innerHTML += "<h3>"+capabilities['brand_name']+" "+capabilities['model_name']+" "+capabilities['marketing_name']+"</h3>";
	// Display all capabilities.  Access individual capabilities like this: capabilities.is_wireless_device **OR** capabilities['is_wireless_device']
	for (var name in capabilities) {
		if (name != "length") {
			document.getElementById('result').innerHTML += "<br/>"+name+": "+capabilities[name];
		}
	}
}
 
</script>
 
</head>
<body onload="callTeraWurfl();">
<h2>Tera-WURFL Remote Client (Javascript)</h2>
<p>Paste a user agent to see its capabilities: </p>
<form>
<p>
  <label>User Agent:
    <input name="user_agent" type="text" id="user_agent" value="Mozilla/5.0 (Linux; U; Android 1.5; en-us; T-Mobile G1 Build/CRC1) AppleWebKit/528.5+ (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20.1" size="150" />
  </label>
</p>
<p>
  <label>Capabilities:
    <input name="capabilities" type="text" id="capabilities" size="150" value="product_info|tera_wurfl|playback" />
  </label>
</p>
<p>
<input type="submit" name="detect_button" id="detect_button" value="Detect User Agent" onclick="javascript:return callTeraWurfl();"/>
</p>
<center><div id="device_model">&nbsp;</div></center>
<div id="result" name="result" style="font-family:'Courier New', Courier, monospace">Loading...</div>
</form>
</body>
</html>

click here air jordan shoes

Personal tools
Namespaces
Variants
Actions
WURFL DBAPI
Toolbox