Programming and Scripting :: MyDSL info parser



Those requests are very reasonable.

There are two things I'll need help with:
1) As the file is bzipped, I assume that means reading the file will require bunzipping before being able to read it into lua. This could be done by unzipping the file directly and then reading the unzipped file. Is it possible to pipe the output of bunzip to lua in order to prevent having to create a new file?
2) While testing mydsl-install from the "install" button I noticed that it downloaded the extension to /home/dsl rather than to the directory in /opt/mydsl.dir. Do I need to specify the directory? I assumed mydsl.dir was used by mydsl-load when it downoaded.

I'm also having a really difficult time creating a single resizeable widget. According to the FLTK docs resizable can be very specific, but I can't figure out how to resize just one single widget. I'd like to be able to make the main output fields be resizable, but nothing else =op

1. change inputfile to:

inputfile = io.popen("bunzip2 -c "..listfile)

2. I will adjust that in mydsl-load. Was presently not enforced, but expected users to be in the mydsl folder. But much better to be enforced.

It's very possible that /opt/mydsl.dir points to a read-only directory. In that case should it fall back to $HOME?
I am talking about v4.x, it is not likely to be read-only.

However booting 4.x, without specifying the mydsl boot option, results in a default of /tmp/mydsl/ being used and becomes the content of /opt/.mydsl_dir. As 4.x boots is sets the perms for user/group on the mydsl dir so should be accessible.

Even with a custom mydsl.iso containing a mydsl dir, that is read-only, the mydsl dir becomes secondary to a specified mydsl boot option or /tmp/mydsl.



WARNING: This version is half-baked. I need to rework the update function and do a better job of determining whether or not the mydslinfo.bz2 file is usable. I'm still working out how to visually show the user the status of the wget download. Since the current version uses the exit status of wget, that wouldn't work if wget was running in aterm, so I'll probably need to check the file after the download completes as mydsl-load does. But I don't feel like working on it any more today, so I'll post what I have for feedback.

I'm mostly happy, though, because I finally understand how to use the resizable method to specify a nested object to resize (a widget inside a group inside a group).

Code Sample
#!/bin/murgaLua
-- mydsl info browser, 2008 mikshaw
--
-- Changelog (yyyy/mm/dd)
--   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
--
-- TODO: Fix the update function to not create empty file
--       Let the user know what's happening during update

mydsldirfile=io.open("/opt/.mydsl_dir")
if not mydsldirfile then
 print("can't open "..mydsldirfile)
 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()
inputfile = io.popen("bunzip2 -c "..listfile)
data=inputfile:read("*a")
inputfile:close()

info={}
info_count=0
-- breaks up each info file into a separate string
for s in string.gmatch(data,"(Location:.-\n)Location:") 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

b_loc:value(0)
b_loc:do_callback()
end

function updatedb(nofile)
 if not nofile then backup=os.rename(listfile,listfile..".bak") end
--  if backup then
   wget=os.execute("wget "..listurl.." -O "..listfile)
   if wget==0 then
     while b_loc:size()>1 do b_loc:remove(0) end
     load_list()
   -- This is terrible
   else if not nofile then os.rename(listfile..".bak",listfile) end
   end
--  end
end


ww=420; wh=360; bh=25; bw=ww/2-5
w=fltk:Fl_Window(ww,wh,"MyDSL Info Browser")

tabs=fltk:Fl_Tabs(0,0,ww,wh)

tab1=fltk:Fl_Group(0,0,ww,wh-bh,"browse")
b_loc=fltk:Fl_Choice(5,5,bw,bh)
b_loc:callback(
function()
 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_Choice(ww/2,5,bw,bh)
b_files:callback(
function()
 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)
     break
   end
 end
end
)

info_display=fltk:Fl_Text_Display(5,10+bh,ww-10,wh-(20+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()
 os.execute("mydsl-load "..b_files:text().." "..b_loc:text())
end
)

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

tab2=fltk:Fl_Group(0,0,ww,wh-bh,"search text")
search_b=fltk:Fl_Return_Button(5,5,80,bh,"search")
search_b:callback(
function()
 if search_text:value() ~= "" then
   results:clear()
   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.."\t\t"..info[i].location)
     end
   end
 end
end
)
search_text=fltk:Fl_Input(85,5,ww-90,bh)
results=fltk:Fl_Hold_Browser(5,10+bh,ww-10,wh-(20+bh*2))
results:textfont(fltk.FL_SCREEN)
results:textsize(12)
results:callback(
function()
-- show selected info file in the browse tab
if results:value() > 0 then
 get_loc=string.match(results:text(results:value()),"\t\t(.*)")
 get_fname=string.match(results:text(results:value()),"(.*)\t\t")
 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
)
fltk:Fl_End()

w:resizable(tabs)
tabs:resizable(tab1)
tabs:resizable(tab2)
tab1:resizable(info_display)
tab2:resizable(results)
w:show()
find_file=io.open(listfile)
if find_file then
find_file:close()
load_list()
else updatedb(1)
end
Fl:run()

Next Page...
original here.