#!/usr/bin/ruby # dskexplorer.rb # # == Synopsis # A web-based DSK file explorer # # == Usage # dskexplorer.rb [switches] # # -h | --help display this message # -p | --port PORT_NUMBER port number to listen on (default is 6502) # -r | --root ROOT_DIR root directory to explore from (default is current directory) # -v | --version show version number # # Examples # dskexplorer.rb -r http://www.apple2.org.za/mirrors/ # dskexplorer.rb -r c:\downloads\apple2\ -p 8080 #make sure the relevant folder with our libraries is in the require path lib_path=File.expand_path(File.dirname(__FILE__)+"//..//lib") $:.unshift(lib_path) unless $:.include?(lib_path) require 'optparse' require 'rdoc_patch' #RDoc::usage patched to work under gem executables dskexplorer_VERSION="0.1.0" @listening_port=6502 @@root_directory="." opts=OptionParser.new opts.on("-h","--help") {RDoc::usage_from_file(__FILE__)} opts.on("-v","--version") do puts File.basename($0)+" "+dskexplorer_VERSION exit end opts.on("-p","--port PORT_NUMBER",Integer) {|val| @listening_port=val%0xFFFF} opts.on("-r","--root ROOT_DIR",String) {|val| @@root_directory=val} filename=opts.parse(ARGV)[0] rescue RDoc::usage_from_file(__FILE__,'Usage') @@root_directory=File.expand_path(@@root_directory) require 'webrick' require 'DSK' include WEBrick @@uri_cache={} @@dsk_cache={} def get_uri_from_cache(uri) if @@uri_cache[uri].nil? then @@uri_cache[uri]=open(uri).read end @@uri_cache[uri] end def get_dsk_from_cache(uri) if @@dsk_cache[uri].nil? then @@dsk_cache[uri]=DSK.read(uri) end @@dsk_cache[uri] end def common_header "
DSK Explorerthis is alpha software - please send feedback using the dsktool.rb forum
"
end
def root_dir_is_website?
require 'hpricot'
require 'open-uri'
@@root_directory=~/^http[s]?:/?true : false
end
def make_absolute_path(relative_path)
if root_dir_is_website? then
@@root_directory+uri_encode(relative_path)
else
@@root_directory+relative_path
end
end
def html_escape(s) s.gsub("&","&").gsub("<","<")end
def uri_encode(s)
#standard URI.escape appears to miss some important characters
require 'uri'
URI.escape(s).gsub("[","%5b").gsub("]","%5d")
end
def get_directories_and_files(relative_path)
directories=[]
dsk_files=[]
absolute_path=make_absolute_path(relative_path)
if root_dir_is_website? then
html=get_uri_from_cache(absolute_path)
doc=Hpricot(html)
doc.search("a[@href]").each do |a|
href=URI.unescape(a.attributes["href"])
if (href=~/\w\/$/)
if !(href=~/^\//) then #directories end with a /, but skip absolute paths
directories<<(href)
end
elsif DSK.is_dsk_file?(href) then
dsk_files<<(href)
end
end
else
if File.exist?(absolute_path) && (File.stat(absolute_path).directory?) then
dir=Dir.new(absolute_path)
dir.each do |f|
directories< "
begin
absolute_path=make_absolute_path(relative_path)
dsk=get_dsk_from_cache(absolute_path)
s<<" View Sectors"
rescue Exception => exception
s<<"ERROR:#{exception}"
end
s
end
def show_sector(relative_path,track,sector)
track="0" if track.nil?
sector="0" if sector.nil?
track=("0"+track).to_i
sector=("0"+sector).to_i
absolute_path=make_absolute_path(relative_path)
dsk=get_dsk_from_cache(absolute_path)
uri="/showsector/#{uri_encode(relative_path)}"
s=""
s<<" "
s<<""
#s<<"
"
s
end
def make_catalog(relative_path)
s="
file system: #{dsk.file_system}
sector order: #{dsk.sector_order}
tracks: #{dsk.track_count}
"
if (dsk.respond_to?(:files)) then
s<<"\n
"
else
s<<"not a recognised format"
end
s<<"TYPE SIZE (BYTES) NAME \n"
dsk.files.keys.sort.each do |full_path|
f=dsk.files[full_path]
display_url="/showfile/#{uri_encode(relative_path)+'?filename='+uri_encode(full_path)}"
if f.respond_to?(:file_type) then
s<<"#{f.file_type} "
else
s<<""
end
s<<" #{sprintf('%03d',f.contents.length)} "
s<<"#{full_path} "
s<<"hex dump "
if f.can_be_picture? then
s<<"picture "
elsif f.respond_to?(:disassembly)
s<<"disassembly "
else
s<<"text "
end
s<<"\n"
end
s<<"
"
s<<" "
s<<"TRACK "
0.upto(dsk.track_count-1) do |track_no|
if track_no==track then
s<<" "
end
end
s<<""
s<<"$#{sprintf('%02X',track)} "
else
s<<"$#{sprintf('%02X',track_no)} "
end
if track_no>0 && track_no%0x10==0 then
s<<"
"
s<<" "
s<<"SECTOR "
0.upto(0x0F) do |sector_no|
if sector_no==sector then
s<<" "
s<<"$#{sprintf('%02X',sector)} "
else
s<<"$#{sprintf('%02X',sector_no)} "
end
end
s<<"\n"
s<
\n"
s<
"
if display_mode=="hex" then
s<