Home    | Software    | Articoli    | Tips'n Tricks    | Contattaci    | Supportaci  
Home arrow Articoli arrow Primi passi in Gambas (I)

Primi passi in Gambas (I)

Un semplice aggregatore di news

 

Introduzione
Gambas è, descrive il suo sito, "un ambiente di sviluppo libero, basato su un interprete BASIC con estensioni ad oggetti, come Visual Basic(ma non ne è un clone !)"
Se siete curiosi sui perchè e le motivazioni di Gambas, consiglio di leggere l'introduzione ufficiale.
Questo articolo mira ad introdurre l'ambiente Gambas mediante lo sviluppo di un piccolo programma; un aggregatore di news. In questo modo potremo lavorare con alcuni componenti(HttpClient, Xml e oggetti grafici) per vedere quanto sia semplice assemblare applicativi con questo strumento, anche per programmatori non propriamente esperti. Introduzione
Gambas è, descrive il suo sito, "un ambiente di sviluppo libero, basato su un interprete BASIC con estensioni ad oggetti, come Visual Basic(ma non ne è un clone !)"
Se siete curiosi sui perchè e le motivazioni di Gambas, consiglio di leggere l'introduzione ufficiale.
Questo articolo mira ad introdurre l'ambiente Gambas mediante lo sviluppo di un piccolo programma; un aggregatore di news. In questo modo potremo lavorare con alcuni componenti(HttpClient, Xml e oggetti grafici) per vedere quanto sia semplice assemblare applicativi con questo strumento, anche per programmatori non propriamente esperti.

Creare un progetto
Dopo aver lanciato l'IDE, selezionare "New Project" e seguire il wizard. Abbiamo bisogno di creare un progetto grafico, scegliergli un nome e un titolo, selezionare/creare una cartella che lo contenga, e siamo a posto.

Alcune immagini del wizard

Sul treeView di sinistra, click destro su "Forms", selezionare "New" e poi "Form". Teniamo i valori di default, verrà chiamato automaticamente "Form1" e sarà la classe di partenza.
Ora abbiamo bisogno di importare alcuni componenti. Dal menu principale selezioniamo "Project->Properties" e da li il tab "Components". Assicuriamoci che siano selezionati i seguenti componenti:
  1. gb
  2. gb.net
  3. gb.net.curl
  4. gb.qt
  5. gb.qt.ext
  6. gb.xml


Ora è tempo di creare il layout dell'aggregatore, usando gli oggetti grafici nella Palette a destra. Abbiamo bisogno di una comboBox per la scelta del feed da scaricare, una listView per la lista degli articoli e un textView per leggere il testo degli articoli stessi. Non dovrebbero esserci troppi problemi, e il risultato potrebbe essere qualcosa del genere:



Bene, ora scriviamo un pò di codice.

 

La classe "Items"
La chiamiamo "classe" nell'accezione di Gambas, non in quella orientata agli oggetti. Ci serve una sorta di oggetto in cui memorizzare i dati degli articoli quando scarichiamo dalla rete un feed, che possa essere interrogato per ottenere link, descrizione e titolo degli articoli. Per cui click destro su "Classes" nella treeView di sinistra, "New->Class" e diamo nome "Items". Ecco il codice da metterci dentro:

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
Qui dichiariamo alcuni arrays(descriptions,links and titles) che memorizzeranno i dati. La dimensione massima è 100 ma possimao anche definire diversamente.
last_checked tiene data/ora dell'ultimo aggiornamento dalla rete del feed, e last_index e current_index il numero di articoli presenti nel feed e l'articolo correntemente selezionato. Il metodo Main, una sorta di costruttore, inizializza alcune di queste variabili.
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
Alcune semplici azioni sul feed: reset porta il cursore sul primo articolo, clear fa quello quello che dice e next muove il cursore al successivo articolo, se ce ne sono altri.
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
Questi metodi restituiscono i dati dell'articolo correntemente selezionato.
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

 

e questo muove il cursore all'indice dato, se esiste,
Questa è tutta la logica per manipolare i feed. Ora vediamo come scaricarli e parsarli.

 

Il codice della Form
A questo punto possiamo scrivere il codice per: gestire l'interfaccia grafica, scaricare i feed dalla rete, parsarli e mostrare i dati mediante la classe Items.
Il codice che va in Form è il seguente.

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
Per prima cosa dichiariamo un oggetto HttpClient per scaricare i feed, un oggetto Items per memorizzare i dati e un array feeds[] per memorizzare le url dei feed.
Mel metodo "Form_Open"(il punto d'ingresso della "Form") popoliamo l'array dei feed e la combobox per selezionarli. Da notare che lo facciamo staticamente; ovviamente un programma più completo permetterebbe di aggiungere/modificare/cancellare elementi dalla lista, ma per ora mantieniamo il tutto semplice.
PUBLIC SUB P_finished()
DIM buffer AS String

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

END
questo metodo è "guidato da eventi". Quando l'oggetto Httpclient finisce di ricevere dati un evento viene generato e viene chiamato questo metodo.
Definiamo un buffer, lo riempiamo con i dati ricevuti da HttpClient, parsiamo e popoliamo la lista di articoli. Per una spiegazione di parseFeed e fillList, vedere sotto.
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
Questi sono metodi chiamati da eventi, quando viene effettuata una selezione sulla listView o viene cliccato il pulsante. nel primo caso prendiamo l'indice dell'elemento selezionato dalla listView, che è anche l'indice del corrispondente articolo nell'oggetto "Items", così possiamo utilizzarlo per cercare l'articolo che ci interessa(metodo seek) e mostrarne il testo nella textView. La pressione del pulsante invece, fa puntare l'oggetto HttpClient all'url selezionata nella comboBox e ne lancia lo scaricamento da rete.
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
Ora la gestione dell'xml scaricato.parseFeed accetta del testo xml come argomento, crea un documento xml, pone il nodo radice del documento come nodo corrente e lo passa a parseNode, che fa il lavoro sporco.parseNode è una funzione ricorsiva che estrae descrizione,link e titolo da un nodo se questo è di tipo "item", altrimenti applica a questo la ricorsione, fino a che non raggiunga la fine del documento xml. I dati estratti dai nodi vengono salvati nell'oggetto "Items".
Quando il metodo termina, abbiamo un oggetto "Items" che contiene tutti gli articoli del feed selezionato.

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

END

fillList popola la listView con i titoli degli articoli estratti. Ora è possibile lanciare/compilare il programma e testarlo.

 

Ecco come appare il programma una volta lanciato:

feed aggregator running

Cosa manca
Il programma è molto semplice e ci sono bachi da risolvere e migliorie da apportare. Per i bachi in particolare, utilizziamo una textView per mostrare il testo degli articoli perchè questa è in grado di elaborare codice html, ma dato che non ci stiamo curando dei mime types, eventuali immagini verranno mostrate come rettangoli grigio-scuri. Per le migliorie, alcune interessanti potrebbero essere: menu,gestione dinamica della lista dei feed, auto aggiornamento dei feed, etc.
Magari scriverò un ulteriore articolo su questi punti, anche come opportunità per vedere nuovi componenti di gambas.

Conclusioni


Abbiamo visto quanto sia semplice usare Gambas. Si hanno a portata di mano sia un RAD facile,comodo e potente, sia tutta una serie di utili componenti.
Questa volta abbiamo utilizzato xml,http e alcuni oggetti grafici, ma abbiamo a disposizione: db, opengl, integrazione con kde e tutti quegli "stravaganti" componenti che tornano utili quando si lavora su una piattaforma di sviluppo.

Hasta la proxima.

 

 

 
< Prec.   Pros. >

  Articles RSS feed

Articoli pił recenti
Software pił recenti
   
designed by allmambo.com