Monday, March 7, 2011

Bing API - Using the Bing Translator with C#


This will be the first post of a series about creating a class library for Microsoft Bing APIs in C#. I had ignore Microsoft offering in the past because Google APIs have always done the work for me; however, I recently worked in my first WP7 application and found Bing services to be really mature and capable of delivering results just as good as Google’s. 

Let’s Begin

NOTE:  You need to register and create an AppID at http://www.bing.com/developers.

Create a new project called .NET 4.0 Class Library called DeveloperCaster.Bing; we will wrap all API calls within this class library.




I want to be able to expand this library beyond the translation API so I will leave room to extend it in future posts.
We will begin by adding the following objects:

The Bing Parameter Class - It is a simple value pair class that will be used to represent request parameters to the API.










Source code:
    public class BingParameter
    {
        public string Name
        {
            set;
            get;
        }

        public string Value
        {
            set;
            get;
        }
    }



The IBingRequest Interface – Will be our datatype for request to the Bing service (see BingService class).









Source code:
  public interface IBingRequest
  {
     List<BingParameter> List { get; }
  }


The BingService class – We are going to use this class to execute all our requests to the Bing API.  BingService provide one method to perform a request and I also added an extra method that will take a IBingRequest plus an anonymous method to process a request using the Request(IBingRequest) method to send its return value to the ResponseHandler parameter (not really needed for core functionality). Our class will embed the Bing API URL (“http://api.bing.net/xml.aspx”); however, you may choose not to do so and pass it as a parameter.


















Source Code:

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;

namespace DeveloperCaster.Bing
{
    public delegate void ResponseHandler(HttpWebResponse response);

    public class BingService
    {
        private string _api = "http://api.bing.net/xml.aspx";
        private string _appId = "";

        /// <summary>
        /// Default constructor
        /// </summary>
        public BingService()
            : this("")
        { }

        /// <summary>
        /// Contructor with ApiId
        /// </summary>
        /// <param name="appId">AppId</param>
        public BingService(string appId)
        {
            _appId = appId;
        }


        /// <summary>
        /// Request with response handler
        /// </summary>
        /// <param name="r"></param>
        /// <param name="response"></param>
        public void ProcessRequest(IBingRequest r, ResponseHandler response)
        {
            response(Request(r));
        }

        /// <summary>
        /// Request from Api
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        public HttpWebResponse Request(IBingRequest r)
        {
            StringBuilder req = new StringBuilder();
            req.Append(this.Api);

            foreach (BingParameter field in r.List)
            {
                req.Append("&" + field.Name + "=" + field.Value);
            }

            HttpWebRequest webRq = (HttpWebRequest)HttpWebRequest.Create(req.ToString());
            HttpWebResponse result = (HttpWebResponse)webRq.GetResponse();
            return result;

        }

        /// <summary>
        /// Get Api
        /// </summary>
        public string Api
        {
            get { return _api + "?AppId=" + _appId; }
        }

        /// <summary>
        /// Set/Get Api
        /// </summary>
        public string AppId
        {
            set { _appId = value; }
            get { return _appId; }
        }

    }

}




Translation Request Object
The translation request will be the first Bing request of our series so let’s being.  The Bing API allows us to request services based on SourceTypes. A SourceType is a source of information available by the API (see full documentation).
To work with the Bing Translation SourceType we will need the following two classes for our object:

The TranslationResponse Class – We will use this object to store our translation API results.











Source Code
using System;

namespace DeveloperCaster.Bing
{
    public class TranslationResponse
    {
        public string SearchedTerms
        {
            set;
            get;
        }

        public string TranslatedTerm
        {
            set;
            get;
        }
    }
}




The TranslationRequest Class – This is or main request object





















Note: Our request object must inherit from the IBingRequest Interface.

Source Code:
using System;
using System.Collections.Generic;
using System.Net;
using System.Xml;

namespace DeveloperCaster.Bing
{

    public class TranslationRequest : IBingRequest
    {

        private List<BingParameter> _items;
        private string _query;
        private string _sourceLanguage;
        private string _targetLanguage;
        private string _version;


        public static TranslationResponse ParseResponse(HttpWebResponse response)
        {
            TranslationResponse result = new TranslationResponse();

            XmlDocument doc = new XmlDocument();
            doc.Load(response.GetResponseStream());
            if (doc.HasChildNodes)
            {
                try
                {
                    if (doc.HasChildNodes)
                    {
                        if (doc["SearchResponse"] != null)
                        {
                            if (doc["SearchResponse"]["Query"]["SearchTerms"] != null)
                            {
                                result.SearchedTerms = doc["SearchResponse"]["Query"]["SearchTerms"].InnerText;
                            }

                            if (doc["SearchResponse"]["tra:Translation"] != null)
                            {
                                result.TranslatedTerm = doc["SearchResponse"]
                                    ["tra:Translation"]
                                    ["tra:Results"]
                                    ["tra:TranslationResult"]["tra:TranslatedTerm"].InnerText;
                            }
                        }

                    }
                }
                catch (NullReferenceException ex)
                {

                }
                catch (XmlException ex)
                {
                }

            }

            return result;
        }

        /// <summary>
        /// Default constructor
        /// </summary>
        public TranslationRequest()
            : this("", "", "", "") { }

        /// <summary>
        /// Second constructor
        /// </summary>
        /// <param name="query">query</param>
        /// <param name="sourceLanguage">source language</param>
        /// <param name="targetLanguage">target language</param>
        public TranslationRequest(string query, string sourceLanguage,
 string targetLanguage)
            : this(query, sourceLanguage, targetLanguage, "2.2") { }

       /// <summary>
       /// Third constructor
       /// </summary>
       /// <param name="query">query</param>
       /// <param name="sourceLanguage">source language</param>
       /// <param name="targetLanguage">target language</param>
       /// <param name="version">api version</param>
public TranslationRequest(string query, string sourceLanguage,
string targetLanguage, string version)
        {
            _items = new List<BingParameter>();
            _items.Add(new BingParameter
            {
                Name = "Sources",
                Value = "Translation"
            });

            if (!Exists("Query"))
            {
                _query = query;
            }
            if (!Exists("Translation.SourceLanguage"))
            {
                _sourceLanguage = sourceLanguage;
            }
            if (!Exists("Translation.TargetLanguage"))
            {
                _targetLanguage = targetLanguage;
            }
            if (!Exists("Version"))
            {
                _version = version;
            }
        }

        private void Add(string name, string val)
        {
            _items.Add(new BingParameter
            {
                Name = name,
                Value = val
            });
        }

        private bool Exists(string name)
        {
            bool result = false;
            foreach (BingParameter f in _items)
            {
                if (f.Name.ToLower() == name.ToLower())
                {
                    result = true;
                    break;
                }
            }

            return result;
        }

        public ResponseHandler Response;

        public string Query
        {
            set
            {
                if (!Exists("Query"))
                {
                    _query = value;
                    Add("Query", value);
                }
            }
            get { return _query; }
        }

        public string SourceLanguage
        {
            set
            {
                if (!Exists("Translation.SourceLanguage"))
                {
                    _sourceLanguage = value;
                    Add("Translation.SourceLanguage", value);
                }
            }

            get { return _sourceLanguage; }
        }

        public string TargetLanguage
        {
            set
            {
                if (!Exists("Translation.TargetLanguage"))
                {
                    _targetLanguage = value;
                    Add("Translation.TargetLanguage", value);
                }
            }

            get { return _targetLanguage; }
        }

        public string Version
        {
            set
            {
                if (!Exists("Version"))
                {
                    _version = value;
                    Add("Version", value);
                }
            }
            get { return _version; }
        }

        /// <summary>
        /// Set/Get Items
        /// </summary>
        public List<BingParameter> List
        {
            get
            {
                return _items;
            }
        }


    }


}




Usage
We will test our library by translating a phrase from English to Spanish. Create a console application, create a reference to our complied dll, and add the following code to test our library:


BingService bing = new BingService("ADD YOUR APPID HERE");

TranslationResponse response =TranslationRequest.ParseResponse(bing.Request(new            TranslationRequest{
                    Query = "Welcome to my blog",
                    SourceLanguage = "en",
                    TargetLanguage = "es"
                  })
);

Console.WriteLine("{0} = {1}", response.SearchedTerms, response.TranslatedTerm);

Console.ReadLine();


Output:
Welcome to my blog = Bienvenido a mi blog





Thursday, January 27, 2011

Extracting ID3v1 tags from mp3s in C#

In 1996 Eric Kemp had the idea to add a small chunk of data to audio files; such method is now known as ID3v1. ID3 tags quickly became standard for storing metadata in MP3s. Nowadays the standard has evolved to add greater flexibility on how tags are stored (ID3v2, v2.3, and v2.4); however, for illustration purposes I will create a set of classes to read the ID3v1 tag off mp3 files.

The ID3v1 tag consists of 128 bytes of data added at the end of the file. The ID3v1 tag begins with the string TAG then it allows 30 bytes each for the title, artist, album, and comment; also, 4 bytes for the year and a byte to identify the genre and the track number.

ID3v1 tag format:
Field
Length
Description
header
3
"TAG"
title
30
30 characters of the title
artist
30
30 characters of the artist name
album
30
30 characters of the album name
year
4
A four-digit year
comment
 30
The comment.
zero-byte
1
If a track number is stored, this byte contains a binary 0.
Track
1
The number of the track on the album, or 0. Invalid, if previous byte is not a binary 0.
Genre
1
Index in a list of genres, or 255


Now that we know the expected format  we need to create a class to hold this data:

ID3Tag class:

   public class ID3Tag
    {
        public string HeaderData;
        public string TrackName;
        public string ArtistName;
        public string AlbumName;
        public string Year;
        public string Comments;
        public int ZeroByte;
        public int TrackNumber;
        public int Genre;
    }

I will add the parsing function in a separate class so if we ever want to add support for ID3v2 the project will be organized.

TagReader class:

    public class TagReader
    {


        /// <summary>
        /// Read ID3 tag
        /// </summary>
        /// <remarks>
        /// TagHeader 0-2
        /// TrackName 3-32
        /// ArtistName 33-62
        /// AlbumName 63-92
        /// Year 93-96
        /// Comment 97-126
        /// ZeroByte 125
        /// TrackNumber 126
        /// Genres 127
        /// </remarks>
        /// <param name="file">filename</param>
        /// <returns>ID3Tag object</returns>
        public ID3Tag ReadTag(string file)
        {
            ID3Tag tag = new ID3Tag();

            byte[] f = ReadID3FromFile(file);
            string data = Encoding.UTF8.GetString(f);

            if (data.Length >= 128)
            {
                tag.HeaderData = data.Substring(0,3);
                tag.TrackName = data.Substring(3, 30);
                tag.ArtistName = data.Substring(33, 30);
                tag.AlbumName = data.Substring(63, 30);
                tag.Year = data.Substring(93, 4);
                tag.Comments = data.Substring(97, 30);
                int zb = 0;
                int.TryParse(data.Substring(125, 1), out zb);
                tag.ZeroByte = zb;
                int track = 0;
                int.TryParse(data.Substring(125, 1), out track);
                tag.TrackNumber = track;
                int gen = 0;
                int.TryParse(data.Substring(127, 1), out gen);
                tag.Genre = gen;
            }

            return tag;

          
        }

        /// <summary>
        /// Read  ID3 tag from a file (last 128 bytes)
        /// </summary>
        /// <param name="mediaFile">file</param>
        /// <returns>tag segment</returns>
        private byte[] ReadID3FromFile(string mediaFile)
        {
            byte[] result = null;
            FileStream fs = null;
            BinaryReader reader = null;

            try
            {
                fs = new FileStream(mediaFile, FileMode.Open, FileAccess.Read);
                reader = new BinaryReader(fs);
                reader.BaseStream.Position = fs.Length - 128;
                result = reader.ReadBytes((int)fs.Length);
            }
            finally
            {
                if (reader != null)
                {
                    reader.Close();

                }
                if (fs != null)
                {
                    fs.Close();
                    fs.Dispose();
                }
            }
            return result;
        }
        
    }

There are only two methods in this class. ReadTag method accepts the fullpath for the media file to be read while the ReadID3FromFile does strip the ID3 tag as a byte[] to be parsed.

USAGE:
TagReader reader = new TagReader();

ID3Tag tag = reader.ReadTag(@"C:\testing\mytrack.mp3");

Console.WriteLine(tag.TrackName);
Console.WriteLine(tag.ArtistName);
Console.WriteLine(tag.AlbumName);

Console.ReadLine();




Thursday, January 20, 2011

Basic JavaScript Animation Function

Note(s):
AddEvent source code can be found here.
$ function source code can be found here.

This function is really helpful to move or change states of a DOM object in a loop.

I will start by creating the DeveloperCaster namespace (using JSON).

var DeveloperCaster = {
        Animate: function (params) {

        }
}

The function will be called Animate and it will take the following set of parameters in JSON format:

Parameters:
Animation speed, start value, end value, and action function

Example:
    var params = {
        speed:0,
        start:0,
        end:0,
        func:function (i) {}
    };





Here is the function:

    var DeveloperCaster = {
        Animate: function (params) {
            var speed = Math.round(params.speed / 1000);
            var timer = 0;
            if (params.start > params.end) {
                for (var i = params.start; i >= params.end; i--) {
                 (function (i, _f, speed, timer) {
                   setTimeout(function () { _f(i); }, (timer * speed));
                 })(i, params.func, speed, timer);
                    timer++;
                }
            } else if (params.start < params.end) {
                for (var index = params.start; index <= params.end; index++) {
                 (function (i, _f, speed, timer) {
                   setTimeout(function () { _f(i); }, (timer * speed));
                 })(index, params.func, speed, timer);
                    timer++;
                }

            }
        }
    }

The idea here is to loop from the start value to the end value while executing and passing the step parameter to the anonymous function in every step of the loop.

Usage:

JavaScript:
window.onload = function () {
            DeveloperCaster.AddEvent("b", "click", function () {
            DeveloperCaster.Animate({
                speed: 2000,
                start: 0,
                end: 300,
                func: function (i) { $('i').style.height = i + "px"; }
            });
        });

…
Html :
<input name="b" type="button" value="Click" />
<p>&nbsp;</p>
<div id="i" style="border:1px solid #333333">
&nbsp;
</div>


Example:
  

Whats new in Silverlight 5

Whats new in Silverlight 5

Highlights
  • Debugging DataBinding
  • Expanded Media Support
  • True 3D Support
  • P/Invoke
  • Elevated rights in the browser
  • Vector printing
  • Multiple windows (out-of-Browser only)
  • Better DataBinding
  • Custom Markup Extensions
  • UI Testing


MS planning phone-console multiplayer | Games Industry | MCV

MS planning phone-console multiplayer | Games Industry | MCV

HTC Launching Three Android Tablets - PCWorld

HTC Launching Three Android Tablets - PCWorld