Home    | Software    | Articles    | Tips'n Tricks    | Contacts    | Support Us  
Home arrow Articles arrow First steps with Gambas (I)

First steps with Gambas (I)

A simple news feed aggregator Introduction
Gambas is, as its site states, "a free development environment based on a Basic interpreter with object extensions, like Visual Basic (but it is NOT a clone !)"
If you're curious about the whys and motivations of Gambas please read the official introduction.
This article focuses on introducing Gambas environment with a real, maybe useful program; a news feed aggregator. This will allow us to overview some components(HttpClient,Xml features and graphical widgets) to see how easy it is to assemble applications with this tool, even for relatively newbies programmers. Creating the project
First things first. After launching the IDE choose "New Project" and follow the wizard. We need to create a graphical project, choose a name and a title for it, select/create a directory to host it and we're done with it.

Some screenshots of the project wizard

On the left tree view right click on "Forms" and select "New" and then "Form". We can keep the default values, it will be automatically called "Form1" and will be the startup class.
Now we need to import the components we need. From the menu choose Project->Properties and from there the Components tab.Make sure the following components are selected:
  1. gb
  2. gb.net
  3. gb.net.curl
  4. gb.qt
  5. gb.qt.ext
  6. gb.xml


Now it's time to design the layout of the aggregator, using the widgets on the right palette. We need a ComboBox to choose feeds from with a Button for reloading, a listView for the list of items of a feed and a TextView for reading the actual news. Shouldn't be too complicated, the result could be something like this:



Good, let's write some code now.

The "Items" class
We'll call this "class" in the gambas sense, not the object oriented sense. What we need is a kind of object that stores news data when a feed is retrieved from the net, and that can be queried for link,description and title of news. So right click on "Classes" in the left tree view of the IDE, New->Class and name it Items. And here is the code to put inside it:

last_checked AS Date
titles AS NEW String[100]
descriptions AS NEW String[100]
links AS NEW String[100]
last_index AS Integer
current_index AS Integer
PUBLIC SUB Main()
current_index = 0
last_index = 0
last_checked = Now
END
Here we declare some arrays (descriptions,links and titles) that will store the news data. Their max size to 100 but this can be different.
last_checked stores the date/time the feed has been last retrieved, and last_index and current_index the number of news contained and the currently shown news item. The Main sub, kinda contructor, initializes some of those variables.
PUBLIC SUB addItem(title AS String, description AS String, item_link AS String)
last_index = last_index + 1

titles[last_index] = title
descriptions[last_index] = description
links[last_index] = item_link
END
PUBLIC SUB reset()
current_index = 0
END
PUBLIC SUB clear()
current_index = 0
last_index = 0
titles = NEW String[100]
links = NEW String[100]
descriptions = NEW String[100]
END
PUBLIC FUNCTION next() AS Boolean
IF last_index = current_index THEN
RETURN FALSE
ELSE
current_index = current_index + 1
RETURN TRUE
END IF
END
Some easy actions on the feed: reset sets the cursor to the first element,clear just does what it says and next moves the cursor to the next item in the feed if there are more.
PUBLIC FUNCTION getTitle() AS String
RETURN titles[current_index]
END
PUBLIC FUNCTION getDescription() AS String
RETURN descriptions[current_index]
END
PUBLIC FUNCTION getLink() AS String
RETURN links[current_index]
END
PUBLIC FUNCTION getCurrentIndex() AS Integer
RETURN current_index
END
These retrieve data of the currently selected news item.
PUBLIC FUNCTION seek(index AS Integer) AS Boolean
IF index <= last_index AND index >= 0 THEN
current_index = index
RETURN TRUE
ELSE
RETURN FALSE
END IF
END

and this moves the cursor to the given index, if it exists.
This is all our business logic to manage news feeds. Now let's see how to retrieve and parse them.

The Form code
At this point we can write the code to handle the GUI, retrieve feeds xml data, parse them and store/show data using the Items class.
The code that goes in our Form1 follows.

PUBLIC P AS HttpClient
PUBLIC items AS NEW Items
PUBLIC feeds AS String[4]
PUBLIC SUB Form_Open()
items = NEW Items
P = NEW HttpClient AS "P"
feeds[0] = "http://rss.freshmeat.net/freshmeat/feeds/fm-releases-unix"
feeds[1] = "http://rss.slashdot.org/Slashdot/slashdot"
feeds[2] = "http://www.repubblica.it/rss/homepage/rss2.0.xml"
combobox1.Add("Freshmeat", 0)
combobox1.Add("Slashdot", 1)
combobox1.Add("La Repubblica", 2)
END
We first declare an HttpClient object to retrieve feeds from the net,an Items object to store data and a feeds[] array to store feeds url.
In the "Form_Open" method(the entry point for the Form) we fill the feeds url array and the combobox for choosing them. Note that we are doing this statically; obviously a more complete program would allow users to add/edit/delete feeds from the list, but let's keep it simple for now.
PUBLIC SUB P_finished()
DIM buffer AS String

IF Lof(P) THEN READ #P, buffer, Lof(P)
parseFeed(buffer)
fillList()

END
This method is event managed. When the HttpClient object finishes receiving data this event is generated and the method called.
We define a buffer, fill it with data retrieved by HttpClient, parse it and use parsed data to fill the news list. For an explaination of parseFeed and fillList, see below.
PUBLIC SUB ListView1_Select()
DIM key AS Integer
key = listview1.Current.Key
items.seek(key)
textview1.Text = items.getDescription() & "\n" & items.getLink()
END

PUBLIC SUB Button1_Click()
P.URL = feeds[combobox1.Index]
P.Get

END
These are event methods called when a selection is made on the listview or the button is clicked. In the first case we take the index of the selected item from the listview,this is also the index of the correspondent item in our Items object, so we can use it to seek the specific news item and show it in the textview. In case of a button click, we set the url of the httpclient object to that of the selected feed in the combobox, and retrieve it.
SUB parseFeed(data AS String)
DIM xml AS NEW XmlDocument
DIM node AS XmlNode
xml.FromString(data)
node = xml.Root
items.clear
parseNode(node)

END

SUB parseNode(node AS XmlNode)
DIM t, t1 AS Integer
DIM node1 AS XmlNode
DIM buf AS String
DIM title, description, item_link AS String
FOR t = 0 TO node.Children.Count - 1
node1 = node.Children[t]
IF node1.name = "item" THEN
FOR t1 = 0 TO node1.Children.Count - 1
buf = node1.Children[t1].name
IF buf = "title" THEN
title = node1.Children[t1].value
ELSE IF buf = "description" THEN
description = node1.Children[t1].value
ELSE IF buf = "link" THEN
item_link = node1.Children[t1].value
END IF
NEXT
items.addItem(title, description, item_link)
ELSE
IF node1.Children.Count > 0 THEN parseNode(node1)
END IF
NEXT
END
Now the xml parsing part. parseFeed takes the xml text as argument, create an xml document out of it, sets the root node as the current node and passes it to parseNode, which does the dirty job. is a recursive sub that takes description,link and title out of a node if this is an item node, otherwise recurses it, until it reaches the end of the xml document. Data taken from item nodes are put into our Items object.
When this method finishes, we have an Items object containing all the news of the selected feed.

SUB fillList()
listview1.Clear
items.reset
WHILE items.next()
listview1.Add(items.getCurrentIndex(), items.getTitle())
WEND

END


fillList just fills the listview with the titles of the retrieved news. You can now run/compile your program and test it.

Here is how the running program looks like:

feed aggregator running

What's next
The program is pretty basic and there are bugs to be fixed and enhancements to be made. In particular, referring to bugs, we're using a textView for showing news articles as it is capable of rendering html code, but as far as we're not handling mime types, images will be rendered as dark gray squares inside the textView. As for enhancements, interesting ones could be: menus, dynamic handling of feeds, auto refresh for feeds and so on.
I'll maybe write a further article focusing on these points, as an opportunity to introduce other gambas components.

Conclusions
We've seen here how easy it is to use Gambas. You have at your fingertips both an easy, comfortable and powerful RAD and lots of nice components.
This time we've used xml, http and graphical widgets, but available are: db, opengl, xsl,kde integration and all those "fancy" components you would like to have when working with a development platform.

Hasta la proxima.

 

 

 

 
< Prev   Next >

  Articles RSS feed

Latest Articles
Latest Software
   
designed by allmambo.com