libxml and serialization

BlitzMax Modules Forums/Brucey's Modules/libxml and serialization

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.

Try using this as the rss feed: http://www.nytimes.com/services/xml/rss/nyt/Technology.xml

Is there a way it can be a normal listbox (going down, instead of going on to the right)?

EDIT: wxHtmlWindow updated version, includes another problem, when displaying the description the image does not show, however in firefox (opening the "test.html" file) shows everything correctly.
SuperStrict

Framework wx.wxApp
Import wx.wxFrame
Import wx.wxListCtrl
Import wx.wxButton
Import wx.wxPanel
Import wx.wxTextCtrl
Import wx.wxHtmlWindow
Import wx.wxSystemSettings

Import brl.basic
Import brl.blitz
Import brl.retro
Import brl.system

Import BaH.libxml

Type rssChannel
  Global _list:TList = New TList
	
	'channel information
	Field Title:String			'title of channel
	Field Description:String	'description of channel
	Field Pubdate:String		'date channel was created?/updated?
	'channel links
	Field lk_Feed:String		'link to the channel's rss feed
	Field lk_Link:String		'link to main feed site
	
	Field chnItems:TList
		
		Method New() 
			chnItems = New TList
		   _list.AddLast(Self) 
			
		End Method
		
		Method SetTitle(_Title:String) 
			Title = _Title
			
		End Method
		
		Method SetDescription(_Desc:String) 
			Description = _Desc
		
		End Method
		
		'fix incoming date for appended timezone data (ex. Thu, 13 Mar 2008 19:26:44 >-0000<)
		Method SetPubdate(pubdateraw:String) 
			Pubdate = pubdateraw
			
		End Method
		
		Method SetLink(Link:String, which:Int) 
		 
			Select which
				Case 0
					lk_Feed = Link
					
				Case 1
					lk_Link = Link
					
			End Select
			
		End Method
		
		Method ReadChannel(root:TxmlNode) 
		  Local channel:TxmlNode = TxmlNode(root.GetFirstChild()) 
		
		   If chnItems.Count() > 0 Then Clear() 
		  
			For Local part:TxmlNode = EachIn channel.getChildren()
			
				Select Lower(part.GetName()) 
				
					Case "title"
						SetTitle(part.getContent()) 
						
					Case "description"
						SetDescription(part.getContent()) 
						
					Case "pubdate"
						SetPubdate(part.getContent()) 
						
					Case "link"
						SetLink(part.getContent(), 1) 
						
					Case "item"
						ReadItem(part) 
						
					Default
						DebugLog("rchn noparse: ~q" + part.getName() + "~q") 
						DebugLog("~t" + part.getName() + " :: " + part.getContent()) 
						
				End Select
			
			Next
		
		End Method
		
		Method ReadItem(parent:TxmlNode) 
		  Local ritem:rssItem = New rssItem
			
			For Local part:TxmlNode = EachIn parent.getChildren() 
			
				Select Lower(part.GetName()) 
				
					Case "title"
						ritem.SetTitle(part.getContent()) 
						
					Case "description"
						ritem.SetDescription(part.getContent()) 
						
					Case "pubdate"
						ritem.SetPubdate(part.getContent()) 
						
					Case "link"
						ritem.SetLink(part.getContent()) 
						
				End Select
			
			Next
			
		   chnItems.AddLast(ritem) 
		   
		End Method
		
		Method Clear() 
		  Local ritem:rssItem
		  
			For ritem = EachIn chnItems
				
				ritem.Clear(Self) 
				
			Next
			
			Title = Null ; Pubdate = Null
			Description = Null
			lk_Feed = Null ; lk_Link = Null
			
		End Method
		
End Type

Type rssItem
	'item information
	Field Title:String			'title of item
	Field Description:String	'description of item
	Field Pubdate:String		'date event occured
	'item links
	Field lk_Link:String		'referring link to event
	
		Method SetTitle(_Title:String) 
			Title = _Title
			
		End Method
		
		Method SetDescription(_Desc:String) 
			Description = _Desc
		
		End Method
		
		'fix incoming date for appended timezone data (Thu, 13 Mar 2008 19:26:44 >-0000<)
		Method SetPubdate(pubdateraw:String) 
			Pubdate = pubdateraw
			
		End Method
		
		Method SetLink(Link:String) 
			lk_Link = Link
			
		End Method
		
		Method Clear(channel:rssChannel) 
			Title = Null
			Description = Null
			Pubdate = Null
			lk_link = Null
			
		  channel.chnItems.Remove(Self) 
		End Method
		
		
		Function Create:rssItem(Title:String, Desc:String, Pubdate:String, lk_Link:String) 
		  Local ritem:rssItem = New rssItem
			
			ritem.Title = Title
			ritem.Description = Desc
			ritem.SetPubdate(Pubdate) 
			ritem.lk_Link = lk_Link
			
		   Return ritem
		   
		End Function
		
End Type

Type Thttp
	Field sock:TSocket
	Field stream:TStream
	Field host:String
	Field agent:String = "BlitzHTTP/1.0"
	Field autoClose:Int
	
		Method Open:Int(host:String, autoClose:Int = False) 
		  Self.sock = CreateTCPSocket()
			 
			If ConnectSocket(Self.sock, HostIp(host), 80) 
				Self.host = host
				Self.stream = CreateSocketStream(Self.sock) 
				Self.autoClose = autoClose
			   Return True
				
			Else
			   Return False
				
			End If
			
		End Method
		
		Method Get:HTTPReturnData(get:String = "") 'def get = ""
		  Local HTRD:HTTPReturnData = New HTTPReturnData, buffer:String, rlnewline:String
			
		   'WriteLine(stream, "GET /" + get + " HTTP/1.0~nHost: " + Self.host + "~nUser-Agent: " + Self.agent + "~n~n") 
		   WriteLine stream, "GET /" + get + " HTTP/1.0" ' GET / gets Default page
		   WriteLine stream, "Host: " + Self.host
		   WriteLine stream, "User-Agent: " + Self.agent
		   WriteLine stream, "Accept: */*"
		   WriteLine stream, ""
		
		  Local cExtType:String, cExt:String, cLength:Int
		   ReadLine(stream)
			While Not Eof(stream)
			  rlnewline = ReadLine(stream)
			  Local spos:Int = Instr(rlnewline, ":")
			'Print "rln" + Lower(Left(rlnewline, spos - 1)) + "rln"
				Select Lower(Left(rlnewline, spos - 1))
					Case "content-type"
					  Local prtmp:String = Mid(rlnewline, spos + 2, Instr(rlnewline, ";") - spos - 2), slpos:Int = Instr(prtmp, "/")
					  cExtType = Left(prtmp, slpos - 1) cExt = Right(prtmp, prtmp.Length - slpos)
						
					Case "content-length"
						cLength = Int(Right(rlnewline, rlnewline.Length - spos - 1))
						
					Case ""
					   Exit
						
				End Select
				
			Wend
			
			While Not Eof(stream) 
			  rlnewline = ReadLine(stream)
				
				buffer:+ rlnewline + "~n"
				
			Wend
			
		  HTRD.Set(Left(buffer, buffer.Length - 1), cExtType, cExt, cLength)
			
		   If autoClose Close() 
		   
		   Return HTRD
		 
			
		End Method
		
		Method Post:String(page:String = "", keys:String[] , values:String[] ) 
		  Local buffer:String
		  Local data:String
		  Local i:Int
			
			For i = 0 To keys.Length - 1
				data:+ UrlEncode(keys[i] ) + "=" + UrlEncode(values[i] ) + "&"
				
			Next
			
		  data = Left(data, data.Length - 1) 
			WriteLine(stream, "POST /" + page + " HTTP/1.0~nHost: " + Self.host + "~nUser-Agent: " + Self.agent + "~nContent-Length: " + data.Length + "~nContent-Type: application/x-www-form-urlencoded~n~n" + data) 
			
			While Not Eof(stream) 
				buffer:+ReadLine(stream) + "~n"
				
			Wend
			
		 If autoClose Close() 
		
		   Return Left(buffer, buffer.Length - 1) 
			
		End Method
		
		Method Close() 
			If Self.stream CloseStream(Self.stream) 
			If Self.sock CloseSocket(Self.sock) 
			
		End Method
	
		Function UrlEncode:String(url:String) 
		  Local buffer:String
		  Local Char:Int
		  Local i:Int
			
			For i = 1 To url.Length
			  Char = Asc(Mid(url, i, 1)) 
				
				If(Char >= 48 And Char <= 57) Or (Char >= 65 And Char <= 90) Or (Char >= 97 And Char <= 122) Or Char = 43 Or Char = 45 Or Char = 46 Or Char = 95
					buffer = buffer + Chr(Char) 
					
				Else
					buffer = buffer + "%" + Right(Hex(Char), 2) 
					
				End If
				
			Next
			
		   Return buffer
		
		End Function
		
		Function UrlDecode:String(url:String) 
		  Local sHex:String = "0123456789ABCDEF"
		  Local buffer:String
		  Local i:Int
			
			For i = 1 To url.Length
				If Mid(url, i, 1) = "%"
					buffer = buffer + Chr(Instr(sHex, Mid(url, i + 1, 1)) Shl 4 + Instr(sHex, Mid(url, i + 2, 1)) - 17) 
				   i:+ 2
					
				Else
					buffer = buffer + Mid(url, i, 1)
					 
				End If
				
			Next
			
		   Return buffer
		
		End Function
	
End Type

Type HTTPReturnData
	Field Content:String
	Field ContLength:Int
	
	Field ExtensionType:String
	Field Extension:String		
		
		Method Set(Cont:String, ExtType:String, Ext:String, CLen:Int)
			Content = Cont
			ContLength = CLen
			Extension = Ext
			ExtensionType = ExtType
			
		End Method
		
		Method SaveContent(File:String, useExt:Int = False)
		 
		 If useExt File:+ "." + Extension
			
			SaveText(Content, File)
			
		End Method
		
		Method ToString:String()
			Return "Content-Type: " + ExtensionType + "/" + Extension + "~nContent-Length: " + ContLength
			
		End Method
		
End Type
	
New MyApp.Run() 

End

Type MyApp Extends wxApp
	Field testframe:MyFrame
	
		Method OnInit:Int() 
			testframe = MyFrame(New MyFrame.Create(Null, - 1, "rss Channel reader", - 1, - 1, 575, 390, wxMINIMIZE_BOX | wxCLOSE_BOX | wxSYSTEM_MENU | wxCAPTION | wxCLIP_CHILDREN)) 
				testframe.Show() 
				
		   Return True
		End Method
		
End Type

Type MyFrame Extends wxFrame
	Field ctrpanel:wxPanel
	
	Field TCtr_rssfeedurl:wxTextCtrl

	Field LCtr_ChannelItems:wxListCtrl
	'Field TCtr_rssItemInfo:wxTextCtrl
	Field Htw_rssItemInfo:wxHtmlWindow
	
	Field rchan:rssChannel
	
		Method OnInit() 
		   ctrpanel = New wxPanel.Create(Self) 
			rchan = New rssChannel
			
			TCtr_rssfeedurl = New wxTextCtrl.Create(ctrpanel, idTCtr_rssfeedurl, "www.hulu.com/feed/show/60/episodes", 5, 17, 400, 20, wxTE_PROCESS_ENTER) 
			New wxButton.Create(ctrpanel, idbtnrefresh, "Refresh", 410, 16, 64, 22) 
			
			LCtr_ChannelItems = wxListCtrl(New wxListCtrl.Create(ctrpanel, idLCtr_ChannelItems, 5, 55, 200, 300, wxLC_LIST | wxLC_SINGLE_SEL | wxSUNKEN_BORDER)) 
				'LCtr_ChannelItems.InsertColumn(0, "rss items") 
			'TCtr_rssItemInfo = New wxTextCtrl.Create(ctrpanel, idTCtr_rssItemInfo, "", 210, 55, 350, 300, wxTE_MULTILINE) 
			Htw_rssItemInfo = New wxHtmlWindow.Create(ctrpanel, idHtw_rssItemInfo, 210, 55, 350, 300) 
				
			RefreshChannel() 
			
			'connect events
			Connect(idbtnrefresh, wxEVT_COMMAND_BUTTON_CLICKED, OnRefreshChannel) 
			Connect(idTCtr_rssfeedurl, wxEVT_COMMAND_TEXT_ENTER, OnRefreshChannel) 
			
			Connect(idLCtr_ChannelItems, wxEVT_COMMAND_LIST_ITEM_SELECTED, OnSelected) 
			Connect(idHtw_rssItemInfo, wxEVT_COMMAND_HTML_LINK_CLICKED, OnrssLink) 
			
			'ConnectAny(wxEVT_CLOSE_WINDOW, OnQuit) 
			
		   Centre() 
		   
		End Method
		
		Method RefreshChannel() 
		  Local feedurl:String = TCtr_rssfeedurl.GetLineText(0) 
		   
		   If Left(feedurl, 7) = "http://" Then feedurl = Right(feedurl, feedurl.Length - 7) 
		   
		  Local firstsl:Int = Instr(feedurl, "/"), sitename:String = Left(feedurl, firstsl - 1), getfile:String = Right(feedurl, feedurl.Length - firstsl) 
		  Local httpg:Thttp = New Thttp, htrd:HTTPReturnData
			If httpg.Open(sitename) 
			  Local doc:TxmlDoc, root:TxmlNode
				rchan.Clear() 
				htrd = httpg.Get(getfile) 
				
				doc = TxmlDoc.parseDoc(htrd.Content) 
				root = doc.GetRootElement() 
				
				rchan.ReadChannel(root) 
					rchan.lk_Feed = "www.hulu.com/feed/show/60/episodes"
					
				LCtr_ChannelItems.ClearAll() 
				
			  Local ritem:rssItem
				For ritem = EachIn rchan.chnItems
				  Local wxl:wxListItem = New wxListItem.Create() 
					wxl.SetData(ritem) wxl.SetText(ritem.Title) 
					LCtr_ChannelItems.InsertItem(wxl) 
					print ritem.Description
				Next
				
			   rssLoadInfo(ritem) 
				
			Else
				wxMessageBox("error: can't obtain url, sitename: ~q" + sitename + "~q getfile: ~q" + getfile + "~q") 
				
			End If
			
		End Method
		
		Function OnRefreshChannel(evt:wxEvent) 
		  Local mfr:MyFrame = MyFrame(evt.parent) 
			mfr.RefreshChannel() 
			
		End Function
		
		Function OnSelected(evt:wxEvent) 
		  Local mfr:MyFrame = MyFrame(evt.parent) 
		  Local lst:wxListCtrl = mfr.LCtr_ChannelItems
		  
			 mfr.rssLoadInfo(rssItem(wxListEvent(evt).GetItem().GetData())) 
			
		End Function
		
		Method rssLoadInfo(item:rssItem)    'load rssitem info into a browser area | currently a textctrl
		   'tctr_rssItemInfo.Clear() 
			'tctr_rssItemInfo.AppendText(item.Title + " date: " + item.Pubdate + "~n") 
			'tctr_rssItemInfo.AppendText(item.lk_Link + "~n" + item.Description)
		  Local pageCont:String = "<html><body>~r~n" + ..
		  		"<a href=~q" + item.lk_Link + "~q>" + item.Title + "</a>~r~n" + ..
				item.Description + ..
				"~r~n</body></html>"
				
			Htw_rssItemInfo.SetPage(pageCont) 
			SaveText(pageCont, "test.html") 
		
		End Method
		
		Function OnrssLink(evt:wxEvent) 
			OpenURL(wxHtmlLinkEvent(evt).GetLinkInfo().GetHref()) 
			
		End Function
		
		'Function OnQuit(event:wxEvent) 
		'	wxWindow(event.parent).Close(True) 
		'	
		'End Function
	
End Type
'id's
Const idTCtr_rssfeedurl:Int = 101
Const idbtnrefresh:Int = 102
	
Const idLCtr_ChannelItems:Int = 103
Const idTCtr_rssItemInfo:Int = 104
Const idHtw_rssItemInfo:Int = 105