Quote |
I think your collapsable browser would be nicer than those two drop downs. |
Quote |
Xfree86-devel.unc is the only one that screws up. |
Quote (mikshaw @ Mar. 16 2008,05:06) | ||||
|
Quote |
This is that sort of thing that I have been "cleaing up" to try to get data to be INSERTable to an SQL table. |
Code Sample |
#!/home/dsl/bin/murgaLua-0.6.4 --[[ MyDSL info browser, 2008 mikshaw Changelog (yyyy/mm/dd) 2008/03/16: Interface tweaks 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" list_sep="@b@B50@u" function toggle(b) local count,state,one,two=1 -- selected line and its label local me,label=b:value(),b:text(b:value()) if string.find(label,"%+%s*") then state,one,two="expanded","%+ ","%- " else state,one,two="collapsed","%- ","%+ " end b:text(me,string.gsub(label,one,two)) -- swap + and - -- toggle all lines until reaching the next section or the browser end while b:text(me+count) and not string.match(b:text(me+count),list_sep) do if state=="collapsed" then b:hide(me+count) else b:show(me+count) end count=count+1 end end function fill_list() inputfile = io.popen("bunzip2 -c "..listfile) data=inputfile:read("*a") inputfile:close() if not string.find(data,"%w") then -- if there's nothing readable in it info_display_buffer:text("Cannot read database "..listfile.."\nPlease try updating again.") else filelist:clear() header={} info={} -- table containing all package data: info[index].{location,title,date} info_count=0 -- number of packages local current_loc="" -- location string local headers=0 -- nuber of locations -- breaks up info for each package 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"), date=string.match(s,"Current:%s*(.-%d)%s"), text=s } if current_loc ~= info[info_count].location then -- create a header when location changes current_loc=info[info_count].location filelist:add(list_sep.."- "..current_loc) headers=headers+1 header[headers]=filelist:size() end filelist:add(info[info_count].title) end for i,v in ipairs(header) do filelist:value(header[i]); toggle(filelist) end last_update:label("last update "..os.date("%d %b %Y",lfs.attributes(listfile).modification)) end filelist:value(1) tab_browse:setonly() 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) fill_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.."(.*)"..spacer) get_fname=string.match(results:text(results:value()),"(.-)"..spacer) -- select the package in filelist local myloc=1 while myloc<=filelist:size() do if not string.find(filelist:text(myloc)," "..get_loc,1,1) then myloc=myloc+1 else filelist:value(myloc) break end end -- open submenu if not open if string.find(filelist:text(myloc),list_sep.."+ ",1,1) then toggle(filelist) end while myloc<=filelist:size() do if filelist:text(myloc) ~= get_fname then myloc=myloc+1 else filelist:value(myloc) break end end for i=1,info_count do -- make sure you get the right info AND category if info[i].title == get_fname and info[i].location == get_loc then info_display_buffer:text(info[i].text) tab_browse:setonly() myfile=info[i] -- this is the file that will be downloaded break end end tabs:value(tab1) end end function list_cb() if filelist:value()>0 then -- clicking a blank space can be fatal without this check if Fl:event() == fltk.FL_RELEASE or Fl:event_key()==fltk.FL_Enter then -- on click or Enter if string.find(filelist:text(filelist:value()),list_sep) then toggle(filelist) -- if it's a separator else -- find out what submenu we're under local myloc=filelist:value() while myloc > 0 do myloc=myloc-1 if string.find(filelist:text(myloc),list_sep) then myloc=string.gsub(filelist:text(myloc),".-%s%s","") break end end for i=1,info_count do -- make sure you get the right info AND category if info[i].title == filelist:text(filelist:value()) and info[i].location == myloc then info_display_buffer:text(info[i].text) myfile=info[i] tab_browse:setonly() break end end end end 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") tiles=fltk:Fl_Tile(5,5+bh,ww-10,wh-(15+bh*2)) filelist=fltk:Fl_Hold_Browser(5,5+bh,ww/2-5,wh-(15+bh*2)) filelist:callback(list_cb) info_display=fltk:Fl_Text_Display(ww/2,5+bh,ww/2-5,wh-(15+bh*2)) info_display:textfont(fltk.FL_SCREEN) info_display:textsize(12) info_display_buffer=fltk:Fl_Text_Buffer() info_display:buffer(info_display_buffer) fltk:Fl_End() --end tiles -- offscreen button that allows the list to respond to Enter key enter=fltk:Fl_Return_Button(ww,wh,10,10) enter:callback(function() filelist:do_callback() end) install=fltk:Fl_Button(ww/2,5,bw,bh,"&Install Selected Package") install:callback( function() if myfile then mydslload=os.execute("mydsl-load "..myfile.title.." "..myfile.location) if mydslload~=0 then fltk.fl_alert(myfile.title..":\nDownload or Checksum error!") end end end ) b_updatedb=fltk:Fl_Button(5,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"..spacer.."@B49@b@uRelease Date") 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"..spacer.."RELEASE DATE") end for i=1,info_count do if string.find(string.lower(info[i].text),string.lower(search_text:value()),1,true) then if not info[i].date then info[i].date="" end results:add(info[i].title..spacer..info[i].location..spacer..info[i].date) end end end end ) results=fltk:Fl_Hold_Browser(5,5+bh,ww-10,wh-(15+bh*2)) -- column widths available in 0.6.4+ if Fl_Browser.column_widths then results:column_widths({results:w()/2,200,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_BORDER_BOX); tab_browse:selection_color(7) 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_BORDER_BOX); tab_search:selection_color(7) 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(tiles) 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() fill_list() else updatedb() end Fl:run() |
Code Sample |
#!/bin/murgaLua --[[ MyDSL Extension Browser, 2008 mikshaw - SQL and other GUI mods by Robert Shingledecker 2008/02/26: Added packed comments (probably needs sep table 2008/02/16: Added menu for Update database and Quit. 2008/02/14: Created QBE tab based on feedback not finished. 2008/02/08: Basic SQL queries working - take to Scale6x to show John. 2008/01/28: Dropped columns and switched to vertical VIEW layout. 2008/01/24: Created sqlite database mydsl.db with only simple cols. 2008/01/21: Gutted all flat file logic kept some GUI. 2008/01/13: Started from mikshaw's 2008 mydsl info browser. ]]-- function updatedb(nofile) if not nofile then backup=os.rename(database,database..".bak") end os.execute("aterm +tr -bg white -fg black -geometry 80x4 -title \"Database Update\" -e wget "..dburl.." -O "..database) end function doSQL() if inputSQL:value() ~= "" then results:clear() selected = {} field_names = {} stmt = db:prepare(inputSQL:value()) if stmt == nil then fltk.fl_alert(db:errmsg()) else field_names = stmt:get_names() for row in stmt:rows(inputSQL:value()) do results:add(row[1].."\t"..row[2]) selected[#selected+1] = row end stmt:finalize() end end end function showSQL() if results:value() > 0 then viewResults = "" for i = 1, #field_names do if field_names[i] == "comments" then selected[results:value()][i] = string.gsub(selected[results:value()][i],"%^","\n") end viewResults = viewResults .. field_names[i].."\t" viewResults = viewResults .. selected[results:value()][i].."\n" end info_display:value(viewResults) tabs:value(tab1) tab1:hide() tab3:show() end end ww=420; wh=360; bh=25 w=fltk:Fl_Window(ww,wh,"MyDSL Extension Browser") w:callback( function(w) db:close() os.exit(0) end) mb = fltk:Fl_Menu_Bar(0,0,ww,bh) mb:add("&File/&UpdateDB",0,updatedb) mb:add("&File/E&xit",0,quit) mb:callback(menu_items) tabs=fltk:Fl_Tabs(0,bh,ww,wh-bh) tab1=fltk:Fl_Pack(1,bh+1,ww,0,"SQL") inputSQL=fltk:Fl_Input(0,0,ww-10,bh) inputSQL:when(fltk.FL_WHEN_ENTER_KEY_ALWAYS) inputSQL:callback(doSQL) results=fltk:Fl_Select_Browser(0,0,ww-10,wh-(8+bh*3)) results:textfont(fltk.FL_SCREEN) results:textsize(12) results:when(fltk.FL_WHEN_CHANGED) results:callback(showSQL) fltk:Fl_End() tab2=fltk:Fl_Group(0,0,ww,wh-bh,"QBE") field_label = {"loc","title","desc","ver","author","site","policy","user","current","comments"} field_len = {120,180,325,240,320,290,325,285,110,335} field_in = {} for i = 1, #field_label do field_in[i] = fltk:Fl_Input(75,28+(28*(i-1)),field_len[i],bh,field_label[i]) end okBtn = fltk:Fl_Return_Button(340, 310, 70, 20, "OK"); okBtn:callback( function(okBtn) for i = 1, #field_label do if field_in[i]:value() ~= "" then print(field_label[i] .." ".. field_in[i]:value()) end end end) fltk:Fl_End() tab3=fltk:Fl_Group(0,0,ww,wh-bh,"View") info_display=fltk:Fl_Multiline_Output(4,bh+4,ww-10,wh-(30+bh*2)) info_display:textfont(fltk.FL_SCREEN) info_display:textsize(12) install=fltk:Fl_Return_Button(340,310,70,20,"Install") install:callback( function() os.execute("mydsl-load "..selected[results:value()][2].." "..selected[results:value()][1]) end ) w:resizable(tabs) tabs:resizable(tab1) tabs:resizable(tab2) tab1:resizable(info_display) tab2:resizable(results) w:show() 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() database = mydsl_dir.."/mydsl.db" dburl="ftp://ibiblio.org/pub/Linux/distributions/damnsmall/mydsl/mydsl.db" databaseCheck = io.open(database) if databaseCheck then databaseCheck:close() else updatedb(1) end selected = {} field_names = {} db = sqlite3.open(database) inputSQL:value("select * from mydsl order by loc;") Fl:run() |
Quote |
Oh, and this works with DSL 4.2.5 or DSL 3.4.11 no need to grab latest murgaLua |