-->

02/06/2012

Google Page Preview & Google API in MVC Razor


Look at this . . .


Isn't this different from Google home page. Yes it is. This is my custom MVC Razor search page, which i have created with full features of Asynchronous data retrieval, displaying Page Preview . As i cannot write such a powerful search algorithm, i am still using Google API here.

From the time, i saw that "Page Preview" getting displayed beside URL info, i thought of implementing such functionality. At-last today, i have done it. The biggest Win in this POC is Page Preview using c# code only. Lets see how to build our own search page using Google's search engine.



Step 1: Create a MVC web application. I named it as "MVCSearchEnginePreview".  Modify the Index.cshtml file to accommodate required infrastructure.
<h2>@ViewBag.Message</h2>
<p>
<form id="form1" runat="server">
<table width="100%">
    <tr>
        <td colspan="2">
        <input id="srchterm" type="text" style="width:500px"/>
        <button onclick="SearchWeb();return false;">Search</button>
        </td>
    </tr>
    <tr align="left">
        <td style="width:50%">
         <div class="demo-container"></div>         
        </td>
        <td align="center" style="width:50% !important;">
                <div id="divResultPreview" class="divresultpreview">
                
                </div>              
                 <div id="divLoading" style="margin: 0px; padding: 0px; position: fixed; right: 0px;
                    top: 0px; width: 100%; height: 100%; background-color: #333333; z-index: 30001;
                    opacity: .8; filter: alpha(opacity=70);display:none" >
                    <p style="position: absolute; top: 40%; left: 40%; color: White;font-size:medium">
                        <b>Loading, please wait...</b><br/><img src="http://www.stickergiant.com/custom_stickers/sites/all/themes/sg_custom/progressbar.gif">
                    </p>
                </div>     
        </td>
    </tr>
</table>
</form>
</p>
Step 2: Lets have a look at the Action method used to hit Google's API and fetch Websearch results for a given search term.
[HttpPost]
        public ActionResult GetResult(string term)
        {

            var searchTerm = term;
            var web = new WebClient();
            
                web.Headers.Add("Referrer", "http://pratapreddypilaka.blogspot.com/");
                var result = web.DownloadString(String.Format(
                       "http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q={0}",
                       searchTerm));

                web.Dispose();
            return Json(result);
        }

Step 3: If you see the html button control defined above is associated with a javascript function which will send the search term and will call Google API to get results to display.
<script type="text/javascript" language="javascript">
    function SearchWeb() {
        try {
            var url = '@Url.Action("GetResult", "Home")';
            var term = $("#srchterm").val();
            $.post(url, { term: term },
            function (data) {
            var obj = jQuery.parseJSON(data);
            var strHtml = "";
            if (obj.responseData.results.length > 0) {
            for (var i = 0; i < obj.responseData.results.length; i++) {
            strHtml = strHtml + "<table id=\"restable" + i + "\" style=\"border:0px\"><tr><td><fieldset style=\"border-style:none\" onmouseover=\"ShowArrow(" + i + ")\" onmouseout=\"HideArrow(" + i + ")\"><a href=\"" + obj.responseData.results[i].url + "\" style=\"font-size:medium;margin:2px;\">" + obj.responseData.results[i].title + "</a><br/>";
            strHtml = strHtml + "<label style=\"color:Green;style=\"font-size:x-small;margin:2px;\"><b>" + obj.responseData.results[i].url + "</b></label><br/>";
            strHtml = strHtml + "<label style=\"color:Blue;margin:2px;\">" + obj.responseData.results[i].content + "</label><br/>";
            strHtml = strHtml + "<label id=\"lblCacheUrl" + i + "\" style=\"display:none\">" + obj.responseData.results[i].cacheUrl + "</label>";
            strHtml = strHtml + "</fieldset></td><td>";
            strHtml = strHtml + "<img ID=\"showimg" + i + "\" src=\"http://cdn1.iconfinder.com/data/icons/30_Free_Black_ToolBar_Icons/40/Black_Circle-Arrow.png\" style=\"filter: alpha(opacity=0);\" onmouseover=\"HighlightAndPreview(" + i + ")\" onmouseout=\"RemoveHighlightAndPreview(" + i + ")\" onclick=\"ShowPreview(" + i + ")\"></td></tr></table>";
            }
                        $('div.demo-container').html(strHtml);
                    }                                                                                                           
                });
        } catch (err) { }
    }
</script> 
There is a lot to discuss here. what exactly is happening here?
The Javascript function sending the search term to Ajax post call, which intern called a action method mentioned above. Once the results are fetched, the call back function highlighted here will do the task of formatting result and displaying it.

You might be interested to know what exactly Google fetch  when you search for any thing. Well let's have a look at it. Search for Maps and compare this with one of the result record.


Step 4: If you observe carefully, the call back function was adding a arrow image at end of each result. This will be used to display the "Page Preview" as Google did.
This image is associated with couple of Javascript functions which will change the opacity of the image. "Onclick" function will be hitting a action method fetching the page Preview.
[HttpPost]
        public ActionResult GetPreview(string Url)
        {           
            Bitmap bmp= ClassWSThumb.GetWebSiteThumbnail(Url, 1000 ,1500, 500, 750);
            string actPath = Server.MapPath(@"../");
            actPath = actPath + "\\Content\\themes\\base\\images\\previewInstantImage.png";
            string relpath = HttpContext.Request.Url.ToString();
            relpath = relpath.Replace("Home/GetPreview", "Content/themes/base/images/previewInstantImage.png");
            bmp.Save(actPath);
            return Json(relpath);         
        }     

Step 5: Before going further, lets dig the above action method a bit.
First Line:
Bitmap bmp= ClassWSThumb.GetWebSiteThumbnail(Url, 1000 ,1500, 500, 750);
This peice of code is responsible for taking the instant Image snapshot of the site, pertaining to Url passed as a paramater.
For this we have a  C# class file which can take the instant Image snapshot of the site without using any 3rd party tools/dlls.
Next: Now, as we got the image of Site in a bitmap format, i am saving it to server as per Physical Path and then send the relative path of the image as a JSON result.

I tried my best to send the JSon parsed object of Bitmap Image to client side, but unable to extract the image to display on client View. If any one have idea, please post the suggestions.
Step 6: We will get the relative path of image as JSON result to the Javascript method's Callback function.
Just look what we have done.
<script type="text/javascript" language="javascript">
    function ShowPreview(par) {
        var CacheUrl = $("#lblCacheUrl" + par)[0].innerHTML;
        var url = '@Url.Action("GetPreview", "Home")';
        $("#divLoading").show();
        var term = $("#srchterm").val();
        $.post(url, { Url: CacheUrl },
                function (data) {                    
                    $("#divResultPreview")[0].innerHTML="<img src=\""+data+"\" />";
                    $("#divLoading").hide();
                });
         }    
</script>
We just created an image tag inside a div and appended the JSON result as src.

The code for entire POC was attached below.

With respective this POC, i feeling very happy for developing this "Page Preview" concept.
Code sample:
Google Page Preview & Google API in MVC Razor
Note: As we are using Google API , you need to have internet connected to execute/test this code.

Is it helpful for you? Kindly let me know your comments / Questions.

3 comments:

  1. Re: Getting a bitmap from the server to a browser.

    Basically, the only way to get an image from the server is for the browser to request the image. In your case, what I would do is have a controller action that generates a bitmap based on a URL in the parameter. So, instead of the server returning a URL in response to a JSON request, you have the server generate the image in response to an http GET request.

    To do this, in the browser you set the image url to the controller action with the target url encoded as a parameter.

    Steve G.

    P.S. DDO - I'm Thelamir or Cearadon on Sarlonis. :-)

    ReplyDelete
    Replies
    1. Hi
      Thanks for suggestion. I did the same thing in the first place. what aim unable to to is, extract bitmap image from JSon object on client side and once it is extracted, how to make it display in callback function using Jquery.

      Delete
  2. send image as BASE64

    ReplyDelete