Getting Mac file paths from disk...

V

Vincent Angeloni

Hi,

As part of my "training" with Ruby, I decided to try and get a list
of files, then save based on size to a new folder for burning onto
CD. When I do this using "Find", I can get the files but if there
are any bundles or packages in the folder, those are being treated
like ordinary folders and Find is burrowing down into the package
contents. This behavior I do not want.

Here is the code I am using (borrowed from a book):

require "find" def findfiles(dir, name)
list = [] Find.find(dir) do |path|
Find.prune if [".",".."].include? path case name
when String
list << path if File.basename(path) == name
when Regexp
list << path if File.basename(path) =~ name
else
raise ArgumentError
end
end list
end

So when this finds a Numbers file, the result it gives is:

.../filesizeTest/401k allocation.numbers
.../filesizeTest/401k allocation.numbers/QuickLook
.../filesizeTest/401k allocation.numbers/QuickLook/Thumbnail.jpg
.../filesizeTest/401k allocation.numbers/index.xml.gz
.../filesizeTest/401k allocation.numbers/document-thumbnail.tiff
.../filesizeTest/401k allocation.numbers/Contents
.../filesizeTest/401k allocation.numbers/Contents/PkgInfo

I understand why this is happening (bundles and packages are folders
which the Mac OS treats like a file, but Ruby does not know about
this). The only "easy" solution that I can see to this is to use
rb-appscript and get the folder contents using Applescript (which
presumably *would* know to treat a package/bundle app as a file,
not a folder). I haven't tried this yet, and if anyone has, let
me know if it works!

Has anyone else dealt with this problem and, if so, what solution
did you use?

TIA

vince

ruby 1.86
mac OS X 10.5.2
 
7

7stud --

Vincent said:
Hi,

As part of my "training" with Ruby, I decided to try and get a list
of files, then save based on size to a new folder for burning onto
CD. When I do this using "Find", I can get the files but if there
are any bundles or packages in the folder, those are being treated
like ordinary folders and Find is burrowing down into the package
contents. This behavior I do not want.

Here is the code I am using (borrowed from a book):

require "find" def findfiles(dir, name)
list = [] Find.find(dir) do |path|
Find.prune if [".",".."].include? path case name
when String
list << path if File.basename(path) == name
when Regexp
list << path if File.basename(path) =~ name
else
raise ArgumentError
end
end list
end

Do you expect anyone to be able to read that code?

So when this finds a Numbers file, the result it gives is:

What's a Numbers file?
 
M

matt neuburg

Vincent Angeloni said:
So when this finds a Numbers file, the result it gives is:

../filesizeTest/401k allocation.numbers
../filesizeTest/401k allocation.numbers/QuickLook
../filesizeTest/401k allocation.numbers/QuickLook/Thumbnail.jpg
../filesizeTest/401k allocation.numbers/index.xml.gz
../filesizeTest/401k allocation.numbers/document-thumbnail.tiff
../filesizeTest/401k allocation.numbers/Contents
../filesizeTest/401k allocation.numbers/Contents/PkgInfo

I understand why this is happening (bundles and packages are folders
which the Mac OS treats like a file, but Ruby does not know about
this). The only "easy" solution that I can see to this is to use
rb-appscript and get the folder contents using Applescript (which
presumably *would* know to treat a package/bundle app as a file,
not a folder). I haven't tried this yet, and if anyone has, let
me know if it works!

Has anyone else dealt with this problem and, if so, what solution
did you use?

The Finder uses a number of different criteria to determine whether a
folder should be portrayed to the user as a file:
The directory has a known extension: .app, .bundle, .framework,
.plugin, .kext, and so on.
The directory has its bundle bit set.
The directory has a known structure type indicating it is a modern or
versioned bundle.

You wouldn't want to have to perform all those tests yourself, so the
simplest thing is to use an API that can perform them for you. Your
choice of rb-appscript and AppleScript is therefore a sensible one. Your
code will probably look something like this:

require 'rubygems'
require "osax"

sa = OSAX::ScriptingAddition.new("StandardAdditions")

f = "/Users/mattneub/Desktop/newXcodeNotes.tao1"
h = sa.info_for(MacTypes::FileURL.path(f))
puts h[:package_folder] #=> true

f2 = "/Users/mattneub/Desktop/gcsc backups"
h = sa.info_for(MacTypes::FileURL.path(f2))
puts h[:package_folder] #=> false

Hope this helps - Of course if there's an installed Unix tool that does
the same job, then you could use that, but I don't happen to know of
one... m.
 
M

matt neuburg

matt neuburg said:
Vincent Angeloni said:
So when this finds a Numbers file, the result it gives is:

../filesizeTest/401k allocation.numbers
../filesizeTest/401k allocation.numbers/QuickLook
../filesizeTest/401k allocation.numbers/QuickLook/Thumbnail.jpg
../filesizeTest/401k allocation.numbers/index.xml.gz
../filesizeTest/401k allocation.numbers/document-thumbnail.tiff
../filesizeTest/401k allocation.numbers/Contents
../filesizeTest/401k allocation.numbers/Contents/PkgInfo

I understand why this is happening (bundles and packages are folders
which the Mac OS treats like a file, but Ruby does not know about
this). The only "easy" solution that I can see to this is to use
rb-appscript and get the folder contents using Applescript (which
presumably *would* know to treat a package/bundle app as a file,
not a folder). I haven't tried this yet, and if anyone has, let
me know if it works!

Has anyone else dealt with this problem and, if so, what solution
did you use?

The Finder uses a number of different criteria to determine whether a
folder should be portrayed to the user as a file:
The directory has a known extension: .app, .bundle, .framework,
.plugin, .kext, and so on.
The directory has its bundle bit set.
The directory has a known structure type indicating it is a modern or
versioned bundle.

You wouldn't want to have to perform all those tests yourself, so the
simplest thing is to use an API that can perform them for you. Your
choice of rb-appscript and AppleScript is therefore a sensible one. Your
code will probably look something like this:

require 'rubygems'
require "osax"

sa = OSAX::ScriptingAddition.new("StandardAdditions")

f = "/Users/mattneub/Desktop/newXcodeNotes.tao1"
h = sa.info_for(MacTypes::FileURL.path(f))
puts h[:package_folder] #=> true

f2 = "/Users/mattneub/Desktop/gcsc backups"
h = sa.info_for(MacTypes::FileURL.path(f2))
puts h[:package_folder] #=> false

Hope this helps - Of course if there's an installed Unix tool that does
the same job, then you could use that, but I don't happen to know of
one... m.

Sorry - I should have added that the obvious implementation here would
be as part of something like the File class:

class File
require 'rubygems'
require "osax"
SA = OSAX::ScriptingAddition.new("StandardAdditions")

def self.bundle?(f)
return false unless directory?(f)
return SA.info_for(MacTypes::FileURL.path(f))[:package_folder]
end
end

The following all get the right answer OMM:

f = "/Users/mattneub/Desktop/newXcodeNotes.tao1" # like .numbers
puts File.bundle?(f)
f2 = "/Users/mattneub/Desktop/gcsc backups" # just a folder
puts File.bundle?(f2)
f3 = "/Users/mattneub/Desktop/ReMate.tgz" # just a folder
puts File.bundle?(f3)
f4 = "/Users/mattneub/Desktop/nonexistent" # just a mistake
puts File.bundle?(f4)

m.
 
V

Vincent Angeloni

Thanks Matt. That will work to test individual files. Since
I am looking to get a clean list of files from a folder, I
was thinking I would use the "list folder" scripting addition
which should give me just the file names, without digging
down into the bundle folder hierarchy.

I got rb-appscript installed and this works:

require 'rubygems'
require "osax"
sa = OSAX.osax
puts sa.list_folder("OS X:Users:vangelon:Desktop:filesizeTest")

BTW, your article on rb-appscript turned me on to Ruby.
Thanks again. : )

Vince
 
V

Vincent Angeloni

oops

it seems that Dir.entries will also return a list of items in a
folder without digging into a bundle.

Dir.entries(/path/to/folder)

Then just parse out the invis files and add the folder path to
the file name to get a complete path.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,073
Latest member
DarinCeden

Latest Threads

Top