pharoah | Introducing 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-24 | 12:38 AM |