class DirToXML
How dir-to-xml should work
if the dir.xml file doesn’t exist then
generate the dir.xml file
else
# the dir.xml file does exist # check for one of the following: # 1 or more new files # 1 or more removed files # 1 or more modified files
note: Ideally The index needs to be stored and retrieved the fastest way possible.
This is why it's saved as a .json file rather .xml
tested:
-
finding the latest file in the current directory
-
finding the latest file in a sub-directory (using recursive: true)
Attributes
deleted_files[R]
dx[R]
latest_file[R]
latest_files[R]
new_files[R]
Public Class Methods
new(obj= '.', index: 'dir.json', recursive: false, verbose: true, debug: false)
click to toggle source
# File lib/dir-to-xml.rb, line 38 def initialize(obj= '.', index: 'dir.json', recursive: false, verbose: true, debug: false) if verbose then puts puts 'DirToXML at your service!'.highlight puts puts end @index, @recursive, @verbose, @debug = index, recursive, verbose, debug if File.basename(obj) == index then #read the index file @path = File.dirname(obj) puts 'intialize() @path: ' + @path.inspect if @debug @dx = read(index) else @path = obj puts 'intialize() @path: ' + @path.inspect if @debug new_scan() end end
Public Instance Methods
activity()
click to toggle source
# File lib/dir-to-xml.rb, line 67 def activity() { new: @new_files, deleted: @deleted_files, modified: @latest_files } end
Also aliased as: changes
directories(recursive: false)
click to toggle source
Returns a list of directory names
note: if recursive is true then it will return a 1-dimensional Array
object containing all directory paths including nested directories
# File lib/dir-to-xml.rb, line 82 def directories(recursive: false) a = @dx.all puts 'inside directories() a: ' + a.inspect if @debug if recursive then directories.flat_map do |dir_name| #puts 'dir_name: ' + dir_name.inspect #puts 'path+dir: ' + File.join(@path, dir_name).inspect dtx = DirToXML.new(File.join(@path, dir_name), verbose: false, debug: false) list = dtx.directories(recursive: true) r = [File.join(@path, dir_name)] r.concat list if list.any? r end else a.select {|x| x.type == 'directory'}.map(&:name) end end
find_all_by_ext(s)
click to toggle source
# File lib/dir-to-xml.rb, line 107 def find_all_by_ext(s) @dx.find_all_by_ext(s) end
find_by_filename(s)
click to toggle source
# File lib/dir-to-xml.rb, line 111 def find_by_filename(s) @dx.find_by_filename(s) end
latest()
click to toggle source
# File lib/dir-to-xml.rb, line 115 def latest() if @latest_file then File.join(@latest_file[:path], @latest_file[:name]) end end
new_scan()
click to toggle source
# File lib/dir-to-xml.rb, line 123 def new_scan() t = Time.now puts '_new_scan() @path: ' + @path.inspect if @debug records = scan_dir @path puts '_new_scan() records: ' + records.inspect if @debug a = records.map {|x| x[:name]} if FileX.exist? File.join(@path, @index) then @dx = read() old_records = @dx.to_a a2 = old_records.map {|x| x[:name]} # delete any old files # @deleted_files = a2 - a if @deleted_files.any? then @deleted_files.each do |filename| record = @dx.find_by_name filename record.delete if record end end # Add any new files # @new_files = a - a2 if @new_files.any? then @dx.import @new_files.map {|filename| getfile_info(filename) } end if (@deleted_files + @new_files).any? then @dx.last_modified = Time.now.to_s @dx.save new_scan() else # check for newly modified files # compare the file date with index file last modified date # dtx_last_modified = Time.parse(@dx.last_modified) select_records = records.select do |file| file[:mtime] > dtx_last_modified or file[:type] == 'directory' end puts 'select_records: ' + select_records.inspect if @debug find_latest(select_records) if select_records.any? end else @dx = new_index(records) find_latest(records) if records.any? end t2 = Time.now - t puts ("directory scanned in %.2f seconds" % t2).info if @verbose end
read(index=@index)
click to toggle source
# File lib/dir-to-xml.rb, line 198 def read(index=@index) t = Time.now puts 'read path: ' + File.join(@path, index).inspect if @debug dx = DxLite.new(File.join(@path, index), autosave: false) t2 = Time.now - t puts ("%s read in %.2f seconds" % [@index, t2]).info if @verbose return dx end
Private Instance Methods
find_latest(files)
click to toggle source
# File lib/dir-to-xml.rb, line 214 def find_latest(files) @latest_files = files.sort_by {|file| file[:mtime]} puts '@latest_files: ' + @latest_files.inspect if @debug @latest_file = @latest_files[-1] @latest_file[:path] = @path puts ':@latest_file: ' + @latest_file.inspect if @debug return unless @recursive puts 'before directories()' if @debug dir_list = directories() puts 'dir_list: ' + dir_list.inspect if @debug if dir_list.any? then dir_latest = dir_list.map do |dir| puts 'dir: ' + dir.inspect if @debug dtx2 = DirToXML.new(File.join(@path, dir), index: @index, recursive: @recursive, verbose: false, debug: @debug) [dir, dtx2.latest_file] end.reject {|_,latest| latest.nil? }.sort_by {|_, x| x[:mtime]}.last puts 'dir_latest: ' + dir_latest.inspect if @debug @latest_file = if dir_latest and \ ((dir_latest.last[:mtime] > latest_file[:mtime]) \ or latest_file.nil? \ or latest_file[:type] == 'directory') then dir_latest.last[:path] = File.expand_path(File.join(@path, dir_latest.first)) dir_latest.last elsif latest_file and latest_file[:type] == 'file' latest_file[:path] = File.expand_path(@path) latest_file end else return end end
getfile_info(filename)
click to toggle source
# File lib/dir-to-xml.rb, line 263 def getfile_info(filename) x = File.join(@path, filename) puts '_x: ' + x.inspect if @debug begin { name: filename, type: FileX.ftype(x), ext: FileX.extname(x), mtime: FileX.mtime(x), description: '' } end end
new_index(records)
click to toggle source
# File lib/dir-to-xml.rb, line 279 def new_index(records) dx = DxLite.new('directory[title, file_path, ' + 'last_modified, description]/file(name, ' + 'type, ext, mtime, description)') puts 'before title' if @debug dx.title = 'Index of ' + @path dx.file_path = @path dx.last_modified = Time.now dx.import records.reverse if records.any? dx.save File.join(@path, @index) return dx end
scan_dir(path)
click to toggle source
# File lib/dir-to-xml.rb, line 296 def scan_dir(path) a = DirX.glob(File.join(path, "*")).map {|x| File.basename(x) } a.delete @index a.map {|filename| getfile_info(filename) } end