Blog

All Blog Posts  |  Next Post  |  Previous Post

An API, an iPhone app, a Delphi plugin and ... your app ?

Monday, January 4, 2010

In December, we have released an iPhone application and a Delphi plugin that enables you to track our latest releases anytime and anywhere. From the Delphi IDE Plugin, you can get notifications of our latest components and see the release history details. The same is possible with the iPhone application.
iPhone application:
TMS Software Delphi  Components


Delphi plugin:
TMS Software Delphi  Components


Behind the iPhone application and the Delphi plugin is a simple API that is freely accessible. As such, you can use the API to build your own applications to inform you about the latest releases of our components. Two links return the required information via XML:
To get our latest releases, the URL

https://www.tmssoftware.com/site/productquery.asp?count=10
can be used. The parameter defines the number of latest releases that should be returned. The results are in order of the release date. The resulting XML has following structure for each release:
 <item>
  <title>TWebCopy : v2.2.0.0</title>
  <pubDate>Mon, 4 Jan 2010 00:00:00 +0100</pubDate>
  <productName>TWebCopy</productName>
  <version>2.2.0.0</version>
  <api>D5,D6,D7,D2005,D2006,D2007,D2009,D2010,C5,C6,C2006,C2007,C2009,C2010</api>
  <link>https://www.tmssoftware.com/site/webcopy.asp</link>
  <![CDATA[Component for automatic downloading/uploading single or multiple files via http, https, ftp or network based]]></description>
  <image></image>
  <id>webcopy</id>
</item>
As can be seen, it has the component name, component version, component web page, the list of supported Delphi and C++Builder versions, a description and an ID. The ID is used to query for the component the version history details with the URL:
https://www.tmssoftware.com/site/versionquery.asp?id=advgrid&version=5.0.0.0
This returns the version history in XML format with following structure:
<item>
  <title><![CDATA[New : Marquee style progressbar for HTTP servers unable to return file size]]></title>
  <updateType>1</updateType>
  <updateText><![CDATA[Marquee style progressbar for HTTP servers unable to return file size]]></updateText>
</item>
The updateType element has a value 1 for "New" features, 2 for "Improved" features and "3" for fixes. To demonstrate how this can be used in a real situation, a small basic Silverlight client is shown here that first shows a list of the 10 latest releases. This list shows the release date, the component name, the version and in the tooltip, it shows the description. When an item in this list is clicked, a list of version history for the component is shown in a second list:

Silverlight client:
To focus on the use of the API, the Silverlight client was intentionally kept simple. It consists of a stackpanel, a button, some labels and two listboxes:

<StackPanel Background="Beige" HorizontalAlignment="Left" VerticalAlignment ="Top" Height="400" Width="600">
      <Button x:Name="btnClick" Click="Button_Click" Content="Get latest releases" Margin="5" Width="150" HorizontalAlignment="Left"></Button>
      <dataInput:Label x:Name="lbl" Margin="5" Content="Status:"></dataInput:Label> 
      <dataInput:Label Margin="5" Content="Latest releases:"></dataInput:Label>
      <ListBox SelectionChanged="selchanged" x:Name="listb" Height="100" Margin="5"></ListBox>
      <dataInput:Label Margin="5" Content="Release details:"></dataInput:Label>
      <ListBox x:Name="versioninfolist" Height="100" Margin="5"></ListBox>
</StackPanel>
To get the latest releases info, a WebClient class is used to get the XML and then the XmlReader class is used from the WebClient DownloadStringCompleted event to parse the XML. The listbox item text is set to the release date, component name and version. A class with the extra information such as ID is added via the Tag property and the tooltip is set to the description of the component. The code used is:
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            WebClient wc = new WebClient();
            wc.DownloadStringCompleted += new DownloadStringCompletedEventHandler(wc_DownloadProductsCompleted);
            wc.DownloadStringAsync(new Uri("https://www.tmssoftware.com/site/productquery.asp?count=10", UriKind.Absolute));
        }

        void wc_DownloadProductsCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            lbl.Content = "Status: downloaded latest releases";
            if (e.Error == null)
            {
                StringReader stream = new StringReader(e.Result);
                XmlReader xmlReader = XmlReader.Create(stream);

                bool firstitem = false;

                while (xmlReader.Read())
                {
                    if (xmlReader.NodeType == XmlNodeType.Element)
                    {
                        if (xmlReader.Name == "item")
                            firstitem = true;
                        if ((xmlReader.Name == "title") && (firstitem))
                        {
                            ListBoxItem li = new ListBoxItem();

                            ComponentInfo ci = new ComponentInfo();

                            // skip full title
                            xmlReader.ReadElementContentAsString();

                            xmlReader.Read();

                            ci.ReleaseDate = System.DateTime.Parse(xmlReader.ReadElementContentAsString());

                            xmlReader.Read();
                            ci.Title = xmlReader.ReadElementContentAsString();
                            xmlReader.Read(); 
                            ci.Version = xmlReader.ReadElementContentAsString();
                            xmlReader.Read(); 
                            ci.IDEs = xmlReader.ReadElementContentAsString();
                            xmlReader.Read(); 
                            ci.URL = xmlReader.ReadElementContentAsString();
                            xmlReader.Read(); 
                            ci.Description = xmlReader.ReadElementContentAsString();
                            xmlReader.Read(); 
                            xmlReader.ReadElementContentAsString();
                            xmlReader.Read(); 
                            ci.ID = xmlReader.ReadElementContentAsString();
                            xmlReader.Read();

                            li.Content = ci.ReleaseDate.ToShortDateString()+":"+ci.Title+":"+ci.Version;
                            ToolTipService.SetToolTip(li, ci.Description);
                           
                            listb.Items.Add(li);
                            li.Tag = ci;  
                      
                        }
                    }
                }
            }
            else
                lbl.Content = "Status:" + e.Error.ToString();
        }
In a second step, when an item is selected in the listbox of latest releases, a WebClient instance is used to retrieve the component specific version history. In the same way as above, the XML is parsed via the XmlReader from the DownloadStringCompleted event of the second WebClient:
        private void selchanged(object sender, SelectionChangedEventArgs e)
        {
            ListBoxItem li = (ListBoxItem)listb.Items[listb.SelectedIndex];
            ComponentInfo ci = (ComponentInfo)li.Tag;

            WebClient wc = new WebClient();
            wc.DownloadStringCompleted += new DownloadStringCompletedEventHandler(wc_DownloadVersionInfoCompleted);

            string query = "id=" + ci.ID + "&version=" + ci.Version;
            wc.DownloadStringAsync(new Uri("https://www.tmssoftware.com/site/versionquery.asp?" + query, UriKind.Absolute));
        }

        void wc_DownloadVersionInfoCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            lbl.Content = "Status: downloaded version info";

            if (e.Error == null)
            {
                versioninfolist.Items.Clear();
                StringReader stream = new StringReader(e.Result);
                XmlReader xmlReader = XmlReader.Create(stream);
                bool firstitem = false;
                while (xmlReader.Read())
                {
                    if (xmlReader.NodeType == XmlNodeType.Element)
                    {
                        if (xmlReader.Name == "item")
                            firstitem = true;

                        if ((xmlReader.Name == "title") && (firstitem))
                        {
                            ListBoxItem li = new ListBoxItem();                            

                            li.Content = xmlReader.ReadElementContentAsString();
                            versioninfolist.Items.Add(li);
                        }
                    }
                }
            }
            else
                lbl.Content = "Status:" + e.Error.ToString();      
        }
And this is basically all that is needed to build a small custom application that retrieves release information. We'll prepare a download here of the Silverlight client source code if you want to play with this. We wish you fun in building your own clients and if you have created something cool, don't hesitate to share it here.

Bruno Fierens




This blog post has received 1 comment.


1. Monday, January 4, 2010 at 6:25:43 PM

Where''s the love for D7?

Puett David




Add a new comment

You will receive a confirmation mail with a link to validate your comment, please use a valid email address.
All fields are required.



All Blog Posts  |  Next Post  |  Previous Post