Home | Reviews | GUIpedia | Forum | Fun500


pharoahIntroducing QGET, roll your own QML reader!
You may be able to add a simple QML reader to your GUI in just a few minutes of coding. I've noticed a lot of people here seem to be interested in adding QML reader functionality to their GUIs, but don't know where to start. My solution is QGET, a simple command line utility. You give it a URL and some optional parameters, and it pulls the file from the web, renders it, and spits out 3 output files. They are even easier to parse than QML. Text.dat contains the full text of the rendered page, wrapped and padded into 80 character long lines. Color.dat contains a line of 80 bytes for each line of the page. The high nibble of each byte is the background color for that character, and the low nibble is the foreground. Links.dat contains a simple line-by-line, tab separated page full of information about the location, URL, and name of various links, downloads, and form inputs on the page. For command line style readers, links can be numbered in the page. For point-and-click style, the info in links.dat allows the reader to determine the location of each link, input, and download. You can find the linux binary version of qget here: http://host.theguiblog.com/atlas/qget I haven't compiled for Windows yet, but I will in about a week when I get home. If you're willing to help us all out, you can compile the code below. All you need is Chaos's ChiSock FB library. Let me know how this works for you. I hope that it is useful and will help QML become more popular :). [code] 'Command Line Options ' d - Download ' i - Info (version and credits) ' h - Command help ' +n - Link numbering ' +p - Return play string ' -c - No color ' -f - No forms ' -s - No padding lines with spaces #include "chisock.bi" type colortype bg :4 as ubyte fg :4 as ubyte end type type linetype text as string colors(1 to 80) as colortype end type type linktype row as integer column as integer title as string url as string end type type inputtype row as integer column as integer title as string * 32 end type type formtype url as string appends as string elem as inputtype pointer elems as integer submit_row as integer submit_column as integer end type declare function getpage(url as string) as string declare function strip_tabs(s as string) as string declare sub render(page as string) declare sub add_text(text as string, clr as colortype) declare function process_commands() as string declare sub generate_files() declare sub pad() redim shared array(1 to 1) as linetype redim shared links(1 to 1) as linktype redim shared dlinks(1 to 1) as linktype redim shared forms(1 to 1) as formtype dim shared ref_url as string var shared ref_time = -1 dim shared play as string var shared useplay = 0 var shared usenums = 0 var shared usecolor = 1 var shared useforms = 1 var shared usepadding = 1 render getpage(process_commands) pad generate_files() function strip_tabs(s as string) as string if left(s, 1) = chr$(9) then return strip_tabs(mid(s, 2)) else return s end if end function function replace_tabs(s as string) as string dim i as integer for i = 1 to len(s) if mid(s, i, 1) = chr$(9) then s = left(s, i-1) + " " +mid(s, i+1) end if next return s end function sub add_text(text as string, clr as colortype) text = replace_tabs(text) dim i as integer for i = 1 to len(text) if len(array(ubound(array)).text) = 80 then redim preserve array(1 to ubound(array)+1) end if array(ubound(array)).text += mid(text, i, 1) array(ubound(array)).colors(len(array(ubound(array)).text)) = clr next end sub sub add_input(title as string) dim s as zstring * 32 s = title forms(ubound(forms)).elems +=1 dim p as inputtype ptr p = reallocate(forms(ubound(forms)).elem, forms(ubound(forms)).elems * sizeof(inputtype)) if p = 0 then end forms(ubound(forms)).elem = p dim dummy as inputtype dummy.title = s dummy.column = len(array(ubound(array)).text)+1 dummy.row = ubound(array) forms(ubound(forms)).elem[forms(ubound(forms)).elems-1] = dummy end sub sub render(page as string) dim lin as string dim clr as colortype dim std as colortype clr.fg = 7 : std.fg = 7 clr.bg = 0 : std.bg = 0 dim as integer n, n2 dim as string first, rest while page "" n = instr(page, chr$(13)+chr$(10)) n2 = instr(page, chr$(10)) if n2 = 0 then lin = page page = "" elseif n < n2 and n > 0 then lin = left(page, n-1) page = mid(page, n+2) else lin = left(page, n2-1) page = mid(page, n2+1) end if lin = strip_tabs(lin) first = left(lin, 1) rest = mid(lin, 2) select case first case "F" if trim(rest)"" then std.fg = valint(rest) end if case "B" if trim(rest)"" then std.bg = valint(rest) end if case "#" if trim(rest) = "" then clr.fg = std.fg else clr.fg = valint(rest) end if case ":" if trim(rest) = "" then clr.bg = std.bg else clr.bg = valint(rest) end if case "$" add_text(rest, clr) case "-" add_text(rest, clr) case "|" dim i as integer for i = 1 to len(rtrim(lin)) if len(array(ubound(array)).text) = 0 and usepadding = 1 then add_text(string(80, " "), clr) else redim preserve array(1 to ubound(array)+1) end if next case "*" if useplay = 1 then play = play + trim(rest) end if case "_" if instr(rest, ">") > 0 then var i = instr(rest, ">") links(ubound(links)).row = ubound(array) links(ubound(links)).column = len(array(ubound(array)).text)+1 links(ubound(links)).title = left(rest, i-1) links(ubound(links)).url = mid(rest, i+1) if usenums = 1 then links(ubound(links)).title += "("+str(ubound(links))+")" end if add_text(links(ubound(links)).title, clr) redim preserve links(1 to ubound(links)+1) end if case "^" if instr(rest, ">") > 0 then var i = instr(rest, ">") dlinks(ubound(dlinks)).row = ubound(array) dlinks(ubound(dlinks)).column = len(array(ubound(array)).text)+ 1 dlinks(ubound(dlinks)).title = left(rest, i-1) dlinks(ubound(dlinks)).url = mid(rest, i+1) if usenums = 1 then dlinks(ubound(dlinks)).title += "{"+str(ubound(dlinks))+"}" end if add_text(dlinks(ubound(dlinks)).title, clr) redim preserve dlinks(1 to ubound(dlinks)+1) end if case "=" if len(array(ubound(array)).text) = 0 and usepadding = 1 then add_text(string(80, " "), clr) else redim preserve array(1 to ubound(array)+1) end if if trim(rest) = "" then add_text(string(80, chr(205)), clr) else add_text(string(80, chr(val(rest))), clr) end if case "c" if trim(rest) "" then add_text(chr(val(rest)), clr) end if case """" if trim(rest) "" then add_text(getpage(rest),clr) end if case "+" if trim(rest) "" then page = getpage(rest) +chr(10)+ page end if case "~" if instr(rest, ">") > 0 then ref_time = val(trim(left(rest, instr(rest, ">")-1))) ref_url = trim(mid(rest, instr(rest, ">")+1)) elseif trim(rest) "" then ref_url = "" ref_time = val(rest) end if case "[" if useforms = 1 then rest = trim(mid(rest, instr(rest, ">")+1)) forms(ubound(forms)).url = rest end if case "?" if useforms = 1 then add_input(rest) var l = 78-len(array(ubound(array)).text) if l>20 then l = 20 if usenums = 1 then add_text "["+str(ubound(forms))+"-"+rest+"]", clr else add_text "[",clr add_text string(l, "_"), clr add_text "]",clr end if end if case "]" if useforms = 1 then forms(ubound(forms)).appends = rest forms(ubound(forms)).submit_row = ubound(array) forms(ubound(forms)).submit_column = len(array(ubound(array)).text)+1 if usenums = 1 then add_text "[Submit "+str(ubound(forms))+"]", clr else add_text "[Submit]",clr end if redim preserve forms(1 to ubound(forms)+1) end if end select wend end sub function getpage (url as string) as string url = trim(url) if left(url, 7) = "http://" then url = mid(url, 8) end if using chi dim as socket sock sock.client( url, socket.PORT.HTTP ) sock.put_HTTP_request( url ) var the_data = sock.get_until( "" ) getpage = mid( the_data, instr( the_data, chr(13, 10, 13, 10) ) + 4 ) end function sub pad() if usepadding = 1 then dim l as integer dim i as integer dim k as integer dim c as colortype for i = 1 to ubound(array) l = len(array(i).text) if l < 80 then c = array(i).colors(l) for k = l + 1 to 80 array(i).text += " " array(i).colors(k) = c next end if next end if end sub function process_commands() as string if command(1) = "" then print "No URL given":end if trim(command(1)) = "i" then print "QGET Version 1.0" print "Written by Pharoah using the ChiSock library by Chaos" end elseif trim(command(1)) = "h" then print "Command Summary:" print" i - Info and credits" print" h - Command help" print" (url) d - Download file" print" (url)... +n - Number links" print" (url)... +p - Return play string" print" (url)... -c - No color" print" (url)... -s - No padding of short lines" print" (url)... -f - No forms" end else var url = trim(command(1)) if trim(command(2)) = "d" then var y = kill("out.dat") open "out.dat" for binary as #1 put #1,,getpage(url) close 1 end else var i = 2 while command(i) "" select case trim(command(i)) case "+n" usenums = 1 case "+p" useplay = 1 case "-c" usecolor = 0 case "-f" useforms = 0 case "-s" usepadding = 0 case else print "Invalid parameter: "+command(i) end end select i += 1 wend return url end if end if end function sub generate_files() var crlf = chr$(13)+chr$(10) dim i as integer, x as integer i = kill("text.dat") open "text.dat" for output as #1 for i = 1 to ubound(array) - 1 print #1, array(i).text +crlf; next close 1 if usecolor = 1 then i = kill("color.dat") open "color.dat" for binary as #1 for i = 1 to ubound(array) - 1 for x = 1 to 80 put #1,, array(i).colors(x) next put #1,, crlf next close 1 end if i = kill("links.dat") open "links.dat" for output as #1 if ref_time >= 0 then print #1, "Refresh:";crlf; print #1, chr$(9);ref_time;crlf; print #1, chr$(9);ref_url;crlf; end if print #1, "Links:";crlf; if ubound(links)>1 then for i = 1 to ubound(links) - 1 print #1, chr$(9)+links(i).title+crlf; print #1, chr$(9)+chr$(9);links(i).row;crlf; print #1, chr$(9)+chr$(9);links(i).column;crlf; print #1, chr$(9)+chr$(9);links(i).url;crlf; next end if print #1, "Downloads:";crlf; if ubound(dlinks)>1 then for i = 1 to ubound(dlinks) - 1 print #1, chr$(9)+dlinks(i).title+crlf; print #1, chr$(9)+chr$(9);dlinks(i).row;crlf; print #1, chr$(9)+chr$(9);dlinks(i).column;crlf; print #1, chr$(9)+chr$(9);dlinks(i).url;crlf; next end if if useforms = 1 then print #1, "Forms:";crlf; for i = 1 to ubound(forms) - 1 print #1, chr(9)+forms(i).url+crlf; print #1, chr(9)+forms(i).appends+crlf; print #1, chr(9);forms(i).submit_row;crlf; print #1, chr(9);forms(i).submit_column;crlf; if forms(i).elems > 0 then for x = 0 to forms(i).elems - 1 print #1, chr(9)+chr(9)+forms(i).elem[x].title+crlf; print #1, chr(9)+chr(9)+chr(9);forms(i).elem[x].row;crlf; print #1, chr(9)+chr(9)+chr(9);forms(i).elem[x].column;crlf; next end if next end if end sub [/code]
2009-03-2412:38 AM

BrandonRe:Introducing QGET, roll your own QML reader!
We want a DOS VERSION!!! GUIs are for DOS!
2009-03-2412:00 PM

pharoahRe:Introducing QGET, roll your own QML reader!
Correction: your current GUI is for DOS. Anyway, I'd welcome a link to a FB TCP/IP lib. I'd really appreciate if someone could help me out by compiling under windows and posting the exe. I am throwing together a sample mouse-based QML reader.
2009-03-2512:45 AM

Blog


2021 Brandon Cornell