Friday 20 September 2013

[Android] Displaying Graphical Chart and Playing Video

In this article, we will talk about how to display a graphical chart and play mp4 video in Android app.

1) Display Graphical Chart from XML data

Imagine you receive the XML data from Web Service, as shown below:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<FahrenheitToCelsiusResponse xmlns="http://tempuri.org/">
<FahrenheitToCelsiusResult>-11.6666666666667</FahrenheitToCelsiusResult>
</FahrenheitToCelsiusResponse>
</soap:Body>
</soap:Envelope>

Now you will call the web service, receive the XML data, parse the XML data, and display a graphical chart based on the data received through the web service.

  • Calling the web service:
private static String URL1 = "http://xxxx/webservice/service";
private String SOAP_ACTION = "http://192.168.10.1/methods/soap-api";
...
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL1);
androidHttpTransport.debug = true;
androidHttpTransport.call(SOAP_ACTION, envelope);

  • Receiving the data:

String Data = androidHttpTransport.responseDump;

  • Parsing the data:
A few important points is highlighted below.
the start element and end element are FahrenheitToCelsiusResponse.
the tag comparison is using FahrenheitToCelsiusResult.
use the javax xml parsers and org xml sax helpers.

import javax.xml.parsers.SAXParser;
import org.xml.sax.helpers.DefaultHandler;

List<TemperatureData> Data_List;

String DataStr="";
InputStream is = new ByteArrayInputStream(Data.getBytes("UTF-8"));
Data_List = SAXParseXML.readXML(is);

  • Copy the parsed data to a string:

        for(int i =0;i<Data_List.size();i++) {                                                    
            //use integer i as the index
            Index = Integer.toString(i);
            //Get Fahrenheit from the edit text field
            //Fahrenheit = Data_List.get(i).Fahrenheit;
            Fahrenheit = txtFar.getText().toString();
            Celsius = Data_List.get(i).Celsius;                                             
            DataStr+= "["+Index+","+Fahrenheit+","+Celsius+"]";
            if (i!=Data_List.size()-1)
               DataStr+= ",\n";
            else
               break;
       }

  • Format the string into html format, plot the chart using Google Charts:

final String chartHtml = getChartHtml(DataStr);

public static String getChartHtml(String Data)

{
         String chartHtml = null;
         try{
              // Generating html content.
              chartHtml = URLDecoder.decode(
                     "<html><head>" +
                     "<script type=\"text/javascript\" src=\"https://www.google.com/jsapi\"></script>\n" +
                    "<script type=\"text/javascript\">\n" +
                    "google.load(\"visualization\",\"1\", {packages:[\"corechart\"]});\n" +
                    "google.setOnLoadCallback(drawChart);\n" +
                    "function drawChart() {\n" +
                    "var data = google.visualization.arrayToDataTable([\n" +
                    "[\'Index\',\'Fahrenheit\',\'Celsius\'],\n" +
                    Data +                         // the data
                    "]);\n" +
                    "var options = { title: \'Record\',focusTarget:\'category\',pointSize:\'5\' };\n" +   // Set options and point size=5.
                    "var chart = new google.visualization.LineChart(document.getElementById(\'chart_div\'));\n" +
                    "chart.draw(data,options);" +
                    "}</script>\n" +
                         "</head><body><div id=\"chart_div\" style=\"width: 640px; height: 420px;\"></div>" +                                     //  Chart frame size
                    "</body></html>", "utf-8");
         } catch (Exception e){
              e.printStackTrace();
         }
         return chartHtml;
 }

  • Within the thread, use the runOnUiThread() to update the UI:

Use the android webkit to draw graph.

import android.webkit.WebView;
import android.webkit.WebSettings;

runOnUiThread(new Runnable() {
      public void run() {
             //stuff that updates ui   
             //web view load data.
             setContentView(R.layout.get_measurement_record_online);
             mWebView = (WebView)findViewById(R.id.chartWebView);
       WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
       webSettings.setSupportZoom(true);
             webSettings.setLoadWithOverviewMode(true);
             mWebView.setScrollBarStyle
                       (View.SCROLLBARS_OUTSIDE_OVERLAY);
             // the function call to display chart
             mWebView.loadDataWithBaseURL(null,chartHtml,"text/html","utf-8",null);
      }
});

2) Play mp4 Video

Here is a simple example of clicking a button and playing a video from sdcard. we cannot use it in a separate thread. The actual video playback takes place in runOnUiThread().

public class GatsbyDemoActivity extends Activity
{
....
  public void onCreate(Bundle savedInstanceState)
  {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    // save the context for use later
    context = this;
    btnVideo = (Button)findViewById(R.id.btnVideo);
    ...
    btnVideo.setOnClickListener(new View.OnClickListener()
    {                
          @Override
          public void onClick(View v)
          {
               vv = (VideoView) findViewById(R.id.videoView);
               // get the Activity context for use within button OnClickListener
               mc = new MediaController(context);
               //System.out.println("video="+"play video1");
               runOnUiThread(new Runnable() {
                 public void run() {
                   //stuff that updates ui
                  getWindow().setFormat(PixelFormat.TRANSLUCENT);  
                  setContentView(R.layout.get_video);
                   mVideobackBtn =(
                      Button)findViewById(R.id.videoBackBtn);
                   mVideobackBtn
                     .setOnClickListener(btnBackOnClkLis);
                                  
                   //System.out.println("video="+"play video3");
                   vv=(VideoView)findViewById(R.id.videoView);
    vv.setVideoPath("/sdcard/DCIM/Camera/GATSBY_MOVING_RUBBER.mp4");
                   mc.setMediaPlayer(vv);
                  vv.setMediaController(mc);
                  vv.requestFocus();
                  vv.start();                              
               } //run


               private Button.OnClickListener btnBackOnClkLis = new

                Button.OnClickListener(){
               @Override
               public void onClick(View arg0) {
// TODO Auto-generated method stub
// Back to the home menu
Intent intent = new Intent(vv.getContext(), GatsbyDemoActivity.class);
                startActivity(intent);
                   }
               }; //OnClickListener                             
               }); //runOnUiThread                                     
            } //onClick
       });
    }
}

After that, you can play mp4 video, and click on the back button to go back to previous screen.

3) Screen orientation

In AndroidManifest.xml file, in activity section, set
   android:screenOrientation="landscape"
to fix the display in landscape mode.

Wednesday 18 September 2013

Joomla

Joomla is an open source CMS, written in PHP and based on MySQL. A CMS is software that keeps track of every aspects of content on your website. CMS manages your content, so you are free to do other creative stuff.

To install Joomla, download the Joomla packages, put it in Apache DocumentRoot, then point your browser to <xxx.xxx.xxx.xxx>/Joomla, such as 127.0.0.1/Joomla. The installation of Joomla will run inside the browser.

To customise Joomla, go to site administrator, then login with admin username and password.

To add user login functionality, then, go to Extensions->Module Manager, click on new, and choose user login module. You can configure the user login module, such as the position, module assignment, etc.

To change template, go to Extensions->Template Manager, you can choose and select the default style for your site.

Monday 16 September 2013

[Android] Calling SOAP Web Service

Android App is able to call Web Service using SOAP.

1) create a new Android project as usual. Name the activity file as main.xml.

2) Download the ksoap2-android-assembly-2.6.0-jar-with-dependencies.jar library and copy it to the project libs folder

3) Right click on the project name, select Java Build Path->Libraries, click on "Add JARs...", and add the jar library

4) In the same dialog box, click on "Order and Export", and click the jar library and move it up. Make sure the jar is above Android Dependencies and Private Libraries.

5) Modify the main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Fahrenheit"
        android:textAppearance="?android:attr/textAppearanceLarge" />
    <EditText
        android:id="@+id/txtFar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
        <requestFocus />
    </EditText>
    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Celsius"
        android:textAppearance="?android:attr/textAppearanceLarge" />
    <EditText
        android:id="@+id/txtCel"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <LinearLayout
        android:id="@+id/linearLayout1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
        <Button
            android:id="@+id/btnFar"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="0.5"
            android:text="Convert To Celsius" />
        <Button
            android:id="@+id/btnCel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="0.5"
            android:text="Convert To Fahrenheit" />
    </LinearLayout>
    <Button
        android:id="@+id/btnClear"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Clear" />
</LinearLayout>

6) Make use and understand the ksoap2 class

  • SOAPObject
  • SoapSerializationEnvelope
  • HttpTransportSE
Initialise the SoapObject, the namespace and method name are gotten from wsdl file. Namespace is from <xs:schema targetNamespace="tns" elementFormDefault="qualified">
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);

Set the parameter, the parameter are also from wsdl file. The parameter is case-sensitive.
request.addProperty("Fahrenheit", txtFar.getText().toString());

The URL is from <soap:address location="http://mywebsite.com/service"/>
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);

Call the soap action, the Soap action is from <soap:operation soapAction="addMyData" style="document"/>
androidHttpTransport.call(SOAP_ACTION1, envelope);

7) Edit the WebServiceDemoActivity.java file.

If you try to access network in the main thread, in Android 4.0 and above, you will get the error of
NetworkOnMainThreadException:
The exception that is thrown when an application attempts to perform a networking operation on its main thread.

The solution is to create a thread, and access the network in the thread

                        Thread thread = new Thread()
                        {
                            @Override
                            public void run() {
                                try {
                                      //access the network
                                      ......
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }
                        };
                        thread.start();

Furthermore, if you try to update the GUI in the thread, you will get the error:
Only the original thread that created a view hierarchy can touch its views.

The solution is to use runOnUiThread() function to update the UI.

                                runOnUiThread(new Runnable() {
                                    public void run() {
                                        //stuff that updates ui
                                            ......
                                    }
                                });

8) The full source code of WebServiceDemoActivity.java will be published at the bottom.

9) Open your "WebServiceDemo -> android.manifest" file. Add the following line before the <application> tag:

<uses-permission android:name="android.permission.INTERNET" />

This will allow the application to use the internet.



10) Full source code of WebServiceDemoActivity.java:


package com.webservicedemo;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;

import com.webservicedemo.R;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class WebServiceDemoActivity extends Activity
{
    /** Called when the activity is first created. */
      private static String SOAP_ACTION1 = "http://tempuri.org/FahrenheitToCelsius";
      private static String NAMESPACE1 = "http://tempuri.org/";
      private static String METHOD_NAME1 = "FahrenheitToCelsius";
      private static String URL1 = "http://www.w3schools.com/webservices/tempconvert.asmx?WSDL";

      private static String SOAP_ACTION2 = "http://tempuri.org/CelsiusToFahrenheit";
      private static String NAMESPACE2 = "http://tempuri.org/";
      private static String METHOD_NAME2 = "CelsiusToFahrenheit";
      private static String URL2 = "http://www.w3schools.com/webservices/tempconvert.asmx?WSDL";

      Button btnFar,btnCel,btnClear;
      EditText txtFar,txtCel;
      
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
       
        btnFar = (Button)findViewById(R.id.btnFar);
        btnCel = (Button)findViewById(R.id.btnCel);
        btnClear = (Button)findViewById(R.id.btnClear);
        txtFar = (EditText)findViewById(R.id.txtFar);
        txtCel = (EditText)findViewById(R.id.txtCel);    
        
        btnFar.setOnClickListener(new View.OnClickListener()
        {
                  @Override
                  public void onClick(View v)
                  {           
                       
                        //this is the actual part that will call the webservice

                        Thread thread = new Thread()
                        {
                            @Override
                            public void run() {
                                try {
                                    SoapObject request = new SoapObject(NAMESPACE1, METHOD_NAME1);                                    
                                    //Use this to add parameters
                                    request.addProperty("Fahrenheit",txtFar.getText().toString());
                                    SoapSerializationEnvelope envelope = 
                                        new SoapSerializationEnvelope(SoapEnvelope.VER11);
                                    envelope.setOutputSoapObject(request);
                                    envelope.dotNet = true;
                                    HttpTransportSE androidHttpTransport = new HttpTransportSE(URL1);
                                    androidHttpTransport.call(SOAP_ACTION1, envelope);
                                    // Get the SoapResult from the envelope body.
                                    SoapObject result = (SoapObject)envelope.bodyIn;
                                    if(result != null)
                                    {
                                     final String result_str = result.getProperty(0).toString();
                                     runOnUiThread(new Runnable() {
                                          public void run() {
                                            //stuff that updates ui
                                            //Get the first property and change the label text                                             
                                                 txtCel.setText(result_str);
                                          }
                                     });
                                     ;
                                    }
                                    else
                                    {
                                      Toast.makeText(getApplicationContext(), "No Response",Toast.LENGTH_LONG).show();
                                    }                                    
                               
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }
                        };
                        thread.start();
                  }
         });
       
        btnCel.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {           
                 
                  //this is the actual part that will call the webservice

                  Thread thread = new Thread()
                  {
                      @Override
                      public void run() {
                                                     
                          try {
                              SoapObject request = new SoapObject(NAMESPACE2, METHOD_NAME2);                                    
                              //Use this to add parameters
                              request.addProperty("Celsius",txtCel.getText().toString());
                              SoapSerializationEnvelope envelope = 
                                  new SoapSerializationEnvelope(SoapEnvelope.VER11);
                              envelope.setOutputSoapObject(request);
                              envelope.dotNet = true;
                              HttpTransportSE androidHttpTransport = new HttpTransportSE(URL2);
                              androidHttpTransport.call(SOAP_ACTION2, envelope);
                              // Get the SoapResult from the envelope body.
                              SoapObject result = (SoapObject)envelope.bodyIn;
                              if(result != null)
                              {
                               final String result_str = result.getProperty(0).toString();
                               runOnUiThread(new Runnable() {
                                    public void run() {
                                      //stuff that updates ui
                                      //Get the first property and change the label text                                             
                                           txtFar.setText(result_str);
                                    }
                               });
                               ;
                              }
                              else
                              {
                                    Toast.makeText(getApplicationContext(), "No Response",Toast.LENGTH_LONG).show();
                              }                                    
                         
                          } catch (Exception e) {
                              e.printStackTrace();
                          }
                      }
                  };
                  thread.start();
            }
        });
       
        btnClear.setOnClickListener(new View.OnClickListener()
        {
                  @Override
                  public void onClick(View v)
                  {
                        txtCel.setText("");
                        txtFar.setText("");
                  }
        });
    }
}

Tuesday 10 September 2013

Ubuntu Linux

0) To change samba4 password

sudo samba-tool user  setpassword <username>

The system will prompt you for entering the password.

1) During configure command, sometimes we meet this error:

No package 'libusb-1.0' found

This is what we need to do to find out the actual packages to be installed.

LinuxBox:~$ apt-cache search libusb-1.0
libusb-1.0-0 - userspace USB programming library
libusb-1.0-0-dev - userspace USB programming library development files
libfprint-dev - async fingerprint library of fprint project, development headers
libfprint0 - async fingerprint library of fprint project, shared libraries
libpam-fprint - PAM module allowing authentication via fprint
libusb-ocaml - OCaml bindings to libusb-1.0 (runtime)
libusb-ocaml-dev - OCaml bindings to libusb-1.0

Then, install the missing packages.

LinuxBox:~$ apt-get install libusb-1.0-0

2) During make, sometimes we see this error:

cannot stat .deps/***.Tpo
No such file or directory

Then, run autoreconf to update the generated configuration files.

autoreconf
configure
make

3) Drop MySQL tables in databases matching some wildcard:

Using the shell command to do this:

mysql -u root -pkeyasic -D medical -e "show tables" -s | 
  egrep "^Whoever_" | 
  xargs -I "@@" echo mysql -u root -pkeyasic -D medical -e "DROP TABLE @@"

Explanation:

First part, output a list of your tables
mysql -u root -pkeyasic -D medical -e "show tables" -s 

Second part, searches for any lines that begins with the word "Whoever_"
egrep "^Whoever_"

Third part, will take each line from second part, and inserts it instead of the @@ in the DROP TABLE command.
xargs -I "@@" echo mysql -u root -pkeyasic -D medical -e "DROP TABLE @@"

To actually execute the command, remove the echo in the command.

4) Ask Make process to show full commands:

to execute and print the commands, run:
# make V=1

to print the full commands without executing them, run:
# make -n

5) Linux Apache MySQL PHP (LAMP) Server setup in Ubuntu

a) Install Apache Http Server

Download the source code, then build it.

When configuring it, you may need to get some APR libraries.
sudo apt-get install libapr1-dev
sudo apt-get install libaprutil1-dev

Then you build it.
./configure --prefix=/usr/local
make
sudo make install

Your apache binary is in /use/local/bin because of the prefix.

Your apache httpd.conf is in /usr/local/conf as well. Check the DocumentRoot setting, such as
/usr/local/htdocs

To restart Apache httpd:
sudo httpd -k restart

Alternatively, install the Apache Ubuntu binary:
sudo apt-get install apache2

Then, restart apache2:

 sudo service apache2 restart

The conf file is in /etc/apache2/apache2.conf.
The htdocs is in /var/www folder.

b) Install MySQL Server

sudo apt-get install mysql-server

After you make changes to /etc/mysql/my.cnf, you can restart MySQL
sudo service mysql restart

c) Install PHP5

Install the apache2 mod php5 library:
sudo apt-get install libapache2-mod-php5

Then, create a symbolic link /etc/apache2/mods-enabled/php5.xxx pointing to 


/etc/apache2/mods-availble/php5.xxx
sudo a2enmod php5

Then, install php5:
sudo apt-get install php5


d) Install MySQL and PHP binding


sudo apt-get install libapache2-mod-auth-mysql php5-mysql


Shortcut:




In Ubuntu 12.04, we can do the LAMP in a single step. Firstly, get the tasksel:
$ sudo apt-get install tasksel 



Then, install the lamp-server, which includes everything we need for LAMP.
sudo tasksel install lamp-server

Friday 6 September 2013

SOAP web service using NuSOAP

SOAP web service is based on SOAP request and SOAP response messages. NuSOAP is a SOAP library written in PHP language.

SOAP message:

SOAP message is in XML format. It can be generated and parsed in any programming languages. A barebone SOAP message looks like below:

<?xml version="1.0"?>
<soap:Envelope
 xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
 soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
 <soap:Header>
  ...
 </soap:Header>
 <soap:Body>
  ...
  <soap:Fault>
   ...
  </soap:Fault>
 </soap:Body>
</soap:Envelope>

So SOAP message is just XML message. It becomes SOAP message with the soap namespace. The soap:Envelope is mandatory, the soap:Header is not. The soap.Body contains the actual rpc message. The soap.Fault is optional.

The graph above shows the soap envelope.

Looking at SOAP request message below:

<?xml version="1.0" encoding="ISO-8859-1"?>
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="urn:test-soap-server">
<SOAP-ENV:Body><tns:getProd xmlns:tns="urn:test-soap-server"><category xsi:type="xsd:string">music</category></tns:getProd>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>


From above we can see, getProd is the name of the function that will be called for this request, category is the parameter passed to the function. The valus "tns" stand for this name space.

Looking at SOAP response message below:

<?xml version="1.0" encoding="ISO-8859-1"?>
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body><ns1:getProdResponse xmlns:ns1="urn:test-soap-server"><return xsi:type="xsd:string">The Music Collection, Victor Strauss: Writing music the creative way</return></ns1:getProdResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>


From above we can see, the getProdResponse is the response element, return is the return value.

WSDL file:

WSDL stands for web service description language. It is XML file that records SOAP service metadata. The metadata describes the functions that are provided by the web service application.

The elements that forms the WSDL file.

<definitions>
 <types>
  ........
 </types>
 <message>
  <part></part>
 </message>
 <portType>
  .......
 </portType>
 <binding>
  ....
 </binding>
 <service>
  ....
 </service>
</definitions>

SOAP server:

Soap server with WSDL output, named it "test-soap-server.php"::

<?php
require_once "nusoap-0.9.5/lib/nusoap.php";

function getProd($category) {
    if ($category == "books") {
        return join(",", array(
            "The Music Collection,
            "Victor Strauss:",
            "Writing music the creative way"));
    }
    else {
            return "No products listed under that category";
    }
}

$server = new soap_server();

$server->configureWSDL("test-soap-server", "urn:test-soap-server");

//$server->register("getProd");

$server->register("getProd",
    array("category" => "xsd:string"),
    array("return" => "xsd:string"),
//array("category" => "tns:string"),
    //array("return" => "tns:string"),
    "urn:test-soap-server",
    "urn:test-soap-server#getProd",
    "rpc",
    "encoded",
    "Get a listing of products by category");

// Use the request to (try to) invoke the service
$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '';
$server->service($HTTP_RAW_POST_DATA);

//$server->service($HTTP_RAW_POST_DATA);
//$server->service('php://input');

?>

The configureWSDL() asks the server to generate the WSDL file.

SOAP client:

SOAP client that uses the WSDL file, named it "test-soap-client.php":

<?php
require_once "nusoap-0.9.5/lib/nusoap.php";
//$client = new nusoap_client("http://127.0.0.1/test-soap-server.php");
$client = new nusoap_client("http://127.0.0.1/test-soap-server.php?wsdl", true);

$error = $client->getError();
if ($error) {
    echo "<h2>Constructor error</h2><pre>" . $error . "</pre>";
}

$result = $client->call("getProd", array("category" => "books"));

if ($client->fault) {
    echo "<h2>Fault</h2><pre>";
    print_r($result);
    echo "</pre>";
}
else {
    $error = $client->getError();
    if ($error) {
        echo "<h2>Error</h2><pre>" . $error . "</pre>";
    }
    else {
        echo "<h2>Books</h2><pre>";
        echo $result;
        echo "</pre>";
    }
}

echo "<h2>Request</h2>";
echo "<pre>" . htmlspecialchars($client->request, ENT_QUOTES) . "</pre>";
echo "<h2>Response</h2>";
echo "<pre>" . htmlspecialchars($client->response, ENT_QUOTES) . "</pre>";
echo '<h2>Debug</h2>';
echo '<pre>' . htmlspecialchars($client->debug_str, ENT_QUOTES) . '</pre>';

?>

The call() will call the method available in the web service.

Using SOAP:

Now if you run the soap client in the browser, you can see the screen below:


Thursday 5 September 2013

Django Framework and Django CMS

Django is a Python web framework, developed by a fast moving newsroom operation. Django CMS is the open source CMS based on the Django Framework.

Setup Django Framework and first Django App

If you are using Windows, start a command shell with administrator privileges. Then run the command in your Django folder. If it is Linux, just run the command:
"python setup.py install"
This will install Django in your Python installation’s site-packages directory.

open the Python shell, then run:
>>> import django
>>> print(django.get_version())
1.5

create a Django project:
python C:\pythonXY\Scripts\django-admin.py startproject mysite
python /usr/local/bin/django-admin.py startproject mysite

go to Django project folder, start Django lightweight web server, listening on port 8080:
python manage.py runserver 8080

create the tables in the database, If you’re using SQLite, you don’t need to create anything beforehand - the database file will be created automatically when it is needed.

edit the settings.py file, if using SQLite, add:
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'c:/Python33/victor-test/mysite/my.db',

the syncdb command create tables in database, based on INSTALLED_APPS setting:
python manage.py syncdb

After you setup the project, you can create your app. A project can contain multiple apps.

To create your app, make sure you’re in the same directory as your mysite manage.py and type this command:
python manage.py startapp polls

Then, edit polls/models.py, to add in Poll and Choice classes:
from django.db import models

class Poll(models.Model):
    question = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')

class Choice(models.Model):
    poll = models.ForeignKey(Poll)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)
edit settings.py, and add polls to INSTALLED_APPS:
INSTALLED_APPS = (.... 'polls',)
run this command to see the SQL commands:
python manage.py sql polls

run "python manage.py syncdb" to create the model tables.

To invoke the Python shell, use this command:
python manage.py shell

to check if you did everything correctly:
python manage.py cms check

Django admin sites are for your staff or clients to add, change and delete content. Django was written in a newsroom environment, with a very clear separation between “content publishers” and the “public” site. The admin is not intended to be used by site visitors. It’s for site managers.

Activate the admin site:

  • Uncomment "django.contrib.admin" in the INSTALLED_APPS setting
  • Run python manage.py syncdb. Since we have added a new application to INSTALLED_APPS, the database tables need to be updated
  • Edit your mysite/urls.py file and uncomment the lines that reference to the admin

Setup Django CMS

To setup Django CMS on Linux:
sudo apt-get install python python-setuptools python-imaging
sudo easy_install pip
pip install django-cms
pip install south

Then, you start your project and run your webserver, using the Django method.

After that, you need to configure Django CMS in the Django project.
1) edit <project>/settings.py, add Django CMS and South to INSTALLED_APPS, make sure to uncomment 'django.contrib.admin'
2) edit <project>/settings.py, add Django CMS to the MIDDLEWARE_CLASSES
3) edit <project>/settings.py, add Django CMS to TEMPLATE_CONTEXT_PROCESSORS
4)edit <project>/settings.py, modify STATIC_ROOT
5)edit <project>/settings.py, modify TEMPLATE_DIRS
6)edit <project>/settings.py, add CMS_TEMPLATE
7)edit <project>/settings.py, modify DATABASES
8)edit <project>/urls.py, modify urlpatterns
9) add template files to <project>/templates/ folder

Django uses South for database migration. Models used in South are not synced to DB with syncdb. After you install South, you have to run:
python manage.py syncdb --all
python manage.py migrate --fake
python manage.py syncdb 
python manage.py migrate

Django CMS use admin interface to add pages. Start the Django lightweight server:
python manage.py runserver 8000

Now, go to 127.0.0.1/admin/ and log in. You can use the admin interface to add pages and content.