Programming and Scripting :: MyDSL info parser



More minor changes. The Tabs were replaced by Fl_Wizard. This allows the previously offscreen buttons to be used onscreen so there is only one control for switching tabs. This also gave me a way to display the last update time in the bottom right instead of printing it every time a new info is loaded.

The date check now uses murgaLua builtins instead of running ls | awk in a separate process.

Removed the 5-pixel gap between the text fields and the top/bottom widgets.

Code Sample
#!/home/dsl/bin/murgaLua-0.6.4
--[[
    MyDSL info browser, 2008 mikshaw

    Changelog (yyyy/mm/dd)
      2008/03/15: Improved the update function
                  Database date check uses os.date/lfs instead of os.popen/ls/awk
                  Use wizard instead of tabs for better use of resources
      2008/03/14: Undid gmatch change due to improvements to the database file
                  Improved keyboard control
                  Use Fl_Menu_Button for menus to add to keyboard control
                  Fixed crash on search or install with an empty database
      2008/01/24: Fixed string.gmatch to break up files even if there is no newline between them
      2008/01/17: Added date of last update
                  Tweaked the update function (it's still sloppy)
                  Fixed ".mydsl_dir not found" error message
      2008/01/16: Fixed resizable behavior
                  Uses file in .mydsl_dir
                  Added auto update for first run
      2008/01/15: Added text search
      2008/01/14: Fixed display of incorrect duplicate info file
                  Check for trailing spaces in title string
                  Added "Update" function
                  Code and interface tweaks
      2008/01/13: start of project
   
--]]

mydsldirfile=io.open("/opt/.mydsl_dir")
if not mydsldirfile then
 print(arg[0]..": Can't open /opt/.mydsl_dir")
 os.exit(1)
end
mydsl_dir=mydsldirfile:read("*l")
mydsldirfile:close()

listfile=mydsl_dir.."/mydslinfo.bz2"
listurl="ftp://ibiblio.org/pub/Linux/distributions/damnsmall/mydsl/mydslinfo.bz2"

function load_list() -- load the database
while b_loc:size()>1 do b_loc:remove(0) end
inputfile = io.popen("bunzip2 -c "..listfile)
data=inputfile:read("*a")
inputfile:close()
if not string.find(data,"%w") then
 info_display_buffer:text("Cannot read database "..listfile.."\nPlease try updating again.")
else
info={}
info_count=0
-- breaks up each info file into a separate string
for s in string.gmatch(data,"(Location:.-)\nLocation:") do
 info_count=info_count+1
 info[info_count]={
 location=string.match(s,"Location:%s*(.-)%s*\n"),
 title=string.match(s,"Title:%s*(.-)%s*\n"),
 text=s
 }
 b_loc:add(info[info_count].location)
end
last_update:label("last update "..os.date("%d %b %Y",lfs.attributes(listfile).modification))
b_loc:value(0)
b_loc:do_callback()
end
end

function updatedb()
-- download to temp file, check file integrity, and only then replace the old file
 tempfile=os.tmpname()
 os.execute("aterm +tr -bg white -fg black -geometry 80x4 -title \"Database Update\" -e wget "..listurl.." -O "..tempfile)
 if os.execute("bzip2 -t "..tempfile) == 0 then
   os.rename(tempfile,listfile)
   load_list()
 else fltk.fl_alert("Database check failed.\nThis may be the result of an incomplete download\nor gremlins in your internets.")
 os.remove(tempfile)
 end
end

function pick_search_result()
if results:value() > 1 then
-- show selected info file in the browse tab
 get_loc=string.match(results:text(results:value()),spacer.."(.*)")
 get_fname=string.match(results:text(results:value()),"(.*)"..spacer)
 results:deselect()
 for i=0,b_loc:size() do
   if get_loc == b_loc:text(i) then
     b_loc:value(i)
     break
   end
 end
 b_loc:do_callback()
 for i=0,b_files:size() do
   if get_fname == b_files:text(i) then
     b_files:value(i)
     break
   end
 end
 b_files:do_callback()
tabs:value(tab1)
end
end

ww=500; wh=360; bh=30; bw=ww/2-5
win=fltk:Fl_Window(ww,wh,"MyDSL Info Browser")

tabs=fltk:Fl_Wizard(0,0,ww,wh-bh-5)

tab1=fltk:Fl_Group(0,0,ww,wh-bh-5,"browse")
b_loc=fltk:Fl_Menu_Button(5,5,bw,bh)
b_loc:align(20)
b_loc:callback(
function()
 b_loc:label("&Location:  "..b_loc:text())
 while b_files:size()>1 do b_files:remove(0) end
 b_files:redraw()
   for i=1,info_count do
     if info[i].location==b_loc:text() then
       b_files:add(info[i].title)
     end
   end
 b_files:value(0)
 b_files:do_callback()
end
)

b_files=fltk:Fl_Menu_Button(ww/2,5,bw,bh)
b_files:align(20)
b_files:callback(
function()
 b_files:label("&Filename:  "..b_files:text())
 for i=1,info_count do
   if info[i].title == b_files:text() and info[i].location == b_loc:text() then
     info_display_buffer:text(info[i].text)
     tab_browse:setonly()
     break
   end
 end
end
)

info_display=fltk:Fl_Text_Display(5,5+bh,ww-10,wh-(10+bh*3))
info_display:textfont(fltk.FL_SCREEN)
info_display:textsize(12)
info_display_buffer=fltk:Fl_Text_Buffer()
info_display:buffer(info_display_buffer)

install=fltk:Fl_Button(5,wh-bh*2-5,bw,bh,"&Install Selected Package")
install:callback(
function()
if b_files:text() and b_loc:text() then
 os.execute("mydsl-load "..b_files:text().." "..b_loc:text())
end
end
)

b_updatedb=fltk:Fl_Button(bw+5,wh-bh*2-5,bw,bh,"&Update Database")
b_updatedb:callback(updatedb)
fltk:Fl_End() --end tab1

tab2=fltk:Fl_Group(0,0,ww,wh-bh-5,"search text")
search_text=fltk:Fl_Input(85,5,ww-90,bh,"search text ")
search_text:when(fltk.FL_WHEN_ENTER_KEY)
search_text:callback(
function()
 if search_text:value() ~= "" and info_count and info_count>0 then
   results:clear()
   if Fl_Browser.column_widths then
     results:add("@B49@b@uPackage Name"..spacer.."@B49@b@uLocation")
   else
     -- default screen font does not have bold or underline
     -- and no columns means only one format string is used
     results:add("@B49PACKAGE NAME"..spacer.."LOCATION")
   end
   for i=1,info_count do
     if string.find(string.lower(info[i].text),string.lower(search_text:value()),1,true) then
       results:add(info[i].title..spacer..info[i].location)
     end
   end
 end
end
)

results=fltk:Fl_Hold_Browser(5,5+bh,ww-10,wh-(10+bh*2))
-- column widths available in 0.6.4+
if Fl_Browser.column_widths then
 results:column_widths({results:w()/2,0})
 spacer="\t"
else spacer="\t\t" -- force some extra space for older versions
results:textfont(fltk.FL_SCREEN) -- fixed-width makes it closer to columns
end
results:callback(
-- react to click only
function()
if results:value() > 1 and Fl:event()==fltk.FL_RELEASE then
 pick_search_result() end
end
)
-- offscreen results_callback button for Enter key
results_cb=fltk:Fl_Return_Button(ww,wh,bh,bh)
results_cb:callback(pick_search_result)
fltk:Fl_End() --end tab2
fltk:Fl_End() --end tabs group

-- using buttons instead of tabs gives better keyboard control
tabbuttons=fltk:Fl_Pack(5,wh-bh,200,bh-5)
tabbuttons:type(fltk.FL_HORIZONTAL)
tabbuttons:spacing(5)
tab_browse=fltk:Fl_Radio_Button(0,0,100,bh-5,"&browse")
tab_browse:when(fltk.FL_WHEN_CHANGED)
tab_browse:box(fltk.FL_THIN_UP_BOX)
tab_browse:callback(function() tabs:value(tab1) end)
tab_search=fltk:Fl_Radio_Button(0,0,100,bh-5,"text &search")
tab_search:when(fltk.FL_WHEN_CHANGED)
tab_search:box(fltk.FL_THIN_UP_BOX)
tab_search:callback(
function()
 tabs:value(tab2)
 Fl:focus(search_text)
end
)
fltk:Fl_End() --end tabs buttons
last_update=fltk:Fl_Box(bw+5,wh-bh-5,bw,bh+5)

win:resizable(tabs)
tabs:resizable(tab1)
tabs:resizable(tab2)
tab1:resizable(info_display)
tab2:resizable(results)
win:show()
find_file=io.open(listfile)
if find_file then data=find_file:read("*a") else data="" end
if string.find(data,"%w") then
 find_file:close()
 load_list()
else updatedb()
end
Fl:run()

I was messing around with extra colums in the results output, and when using the release date as a result, Xfree86-devel.unc is the only one that screws up. I can't figure out why this is.
Interestingly enough, as you may be aware,  I am working on an sql version of this.

One extension that I was using as a test case is testing/compile-3.3.5.uci.

When using your latest mydsl info parser text search, I type compile and no compile-3.3.5.uci shows up? Your code appears to be doing a full text search including title (text=s)

It is interesting the two approaches that we have taken. I showed John my sql version during Scale and it was received as "possibly too dificult to use". I prefer the fine grained searching capabilitities of sql. But I realize that many users may not be comfortable typing sql queries. So I am adding a QBE tab. Still the state of the info files are not very structured and I am not an advanced sql user. It has been a real challenge to break the info files into sql tables and fields.

Quote
I type compile and no compile-3.3.5.uci shows up
I did that exact thing a couple days ago, and thought maybe the extension disappeared. I also checked the repository and didn't find it, though.
However, I just tried "compile" again just now and compile-3.3.5.uci showed up. Odd.

I've been trying to do straight case-insensitive searches of the entire text, but I know there are still some issues to work out.

I know absolutely nothing about using sql, but I assume it's something that can be done entirely within murgaLua....at least if it's sqlite?

Yeah, I bunziped the mydslinfo.bz2 and did a grep compile and it was there. Strange.

I am doing  sql all in murgaLua. Still not sure if it will be a go or not.

Yours with a flat file is easier to use and offers full text search. Also since flat file is just text it can be bzipped to a smaller download than a sqlite database..

Once I get some progress on the QBE screen I will post mine and see what happens. Afterall, it is always about a sharing and leaning experience. The more I do, the more complex it is getting.

On yours, I think your collapsable browser would be nicer than those two drop downs. Just a suggestion.

Next Page...
original here.