Getting folder information

36 views
Skip to first unread message

Collection PhotoGraphex

unread,
Aug 7, 2019, 9:19:58 PM8/7/19
to SuperCard Discussion
Hello, 

That would be nice if the Dir() XFcn would also return the last modification date of a folder in its result. 

I haven't found in the Helper another way to get this information. 

For my particular case I wish to retrieve the last modification date of a folder in seconds. 

It can most certainly be done with a Unix command like Stat or with AppleScript!

Any suggestions!

Regards

André Tremblay
PhotoGraphex

codegreen

unread,
Aug 8, 2019, 1:49:06 AM8/8/19
to SuperCard Discussion

That would be nice if the Dir() XFcn would also return the last modification date of a folder in its result. 

Well, it does. Note that there's a wee bit of massaging required to convert such raw file system dates to local time.

Here's a simple example which displays them in human-readable format for easy comparison to Finder views:

on mouseUp

  local instr = dir(posixToHFS("~"),  false, false, cr tab, folders), outstr

  set the itemdel to tab

  repeat for each line aLine of instr

    put item 1 of aline & tab & localizeDate(item 3 of aLine) & cr after outstr

  end repeat

  ask list outstr

end mouseUp


function localizeDate inDate

  get inDate

  convert it to international time

  get last word of it

  add char 1 of it & char 2 to 3 of it * 3600 + char 4 to 5 of it * 60 to inDate

  convert inDate to abbr date and time

  return ltrim(item 2 to 999 of inDate)

end localizeDate


Just tweak the last couple of lines of the localizer function to return your desired format.

If you want to query a particular folder's mod date directly (rather than enumerating its contents) dir isn't really the right tool. You can do that easily enough using shell though:

on mouseUp

  answer folder "Select a folder:"

  if it is empty then exit script

  get shell(merge("GetFileInfo -m `[[hfsToPosix(it)]]`"))

  convert it to abbr date and time

  put ltrim(item 2 to 999 of it)

end mouseUp


HTH,
-Mark

codegreen

unread,
Aug 8, 2019, 6:02:52 AM8/8/19
to SuperCard Discussion
For posterity it should probably also be noted that using merge to wrap an arbitrary path in double quotes (while it makes for a nice simple example) is not a 'production code' solution, since any path containing double quotes will break it.

Fortunately 'escaping' strings so they don't need to be quoted in shell commands is trivial (if non-obvious) in SuperTalk:

on mouseUp

  answer folder "Select a folder:"

  if it "" then answer shell("GetFileInfo -m" && bash_escape(hfsToPosix(it)))

end mouseUp


function bash_escape instr

  return "'" & replace(instr, "'", "\'") & "'"

end bash_escape


In performance-critical code you'd skip the function call and embed the replace right in the client, but otherwise factoring out this bit of space voodoo is probably worth the extra overhead...

-Mark

André Tremblay

unread,
Aug 8, 2019, 11:11:53 AM8/8/19
to superca...@googlegroups.com
Hello Mark, 


Le 08-août-2019 à 01:49:06, 'codegreen' via SuperCard Discussion <superca...@googlegroups.com> a écrit :

If you want to query a particular folder's mod date directly (rather than enumerating its contents) dir isn't really the right tool. You can do that easily enough using shell though:

on mouseUp
  answer folder "Select a folder:"
  if it is empty then exit script
  get shell(merge("GetFileInfo -m `[[hfsToPosix(it)]]`"))
  convert it to abbr date and time
  put ltrim(item 2 to 999 of it)
end mouseUp

Well, that's exactly my intend, having a script doing the inventory of a very large number of very large folders and keeping logs of the procedure, after an initial pass that takes several days, subsequently on a next pass, I want to compare the modification date of a specific folder with the seconds of the previous pass that are recorded in the logs. Thus cutting the update process tremendously. 

Testing your example, first, I was asked by the OS to install the necessary Xcode command lines, which I did. 

The shell returns a date in this format: 01/24/2016 16:43:57

The convert command does return the same format: 01/24/2016 16:43:57 or M/D/Y H:M:S

My problem is my localisation is in the date format: D/M/Y H:M:S

Which generate an error when converting to the seconds.

Obviously, this local date format is part of the user's international localization. I wonder if there is a SuperTalk function to convert it?

Meanwhile, I've been tinkering with my initial lead using Unix stat and I produced this test script: 

function DossModSec CheminHFS
  -- DossModSec(CheminHFS) -- 20190807
  --> Returns the last modification date of a folder in seconds
  put HFStoPosix(CheminHFS) into CheminPosix
  put merge("stat -f `%m` -t `%s` `[[CheminPosix]]`") into UnixShell
  put unixTask(empty, "/bin/bash", "-c",UnixShell) into SecondesUnix
  return SecondesUnix+2082844800  -- Offset in seconds between Unix time and Mac HFS time
end DossModSec

Which seems to perform correctly while testing, though it seems the 2082844800 offset is not accurate!

I've also tested the same script with the shell(UnixShell) function, the result is presented in two lines, which render it an incompatible numerical. 

function DossModSec CheminHFS
  --  DossModSec(CheminHFS) -- 20190808
  --> Returns the last modification date of a folder in seconds
  put HFStoPosix(CheminHFS) into CheminPosix
  put merge("stat -f `%m` -t `%s` `[[CheminPosix]]`") into UnixShell
  put line 1 of shell(UnixShell) into SecondesUnix -- the result is presented in two lines
  return SecondesUnix+2082844800 -- Offset in seconds between Unix time and Mac HFS time
end DossModSec

Any suggestions or comments?

-------

Le 08-août-2019 à 06:02:52, 'codegreen' via SuperCard Discussion <superca...@googlegroups.com> a écrit :

For posterity it should probably also be noted that using merge to wrap an arbitrary path in double quotes (while it makes for a nice simple example) is not a 'production code' solution, since any path containing double quotes will break it.

Fortunately 'escaping' strings so they don't need to be quoted in shell commands is trivial (if non-obvious) in SuperTalk:

on mouseUp
  answer folder "Select a folder:"
  if it "" then answer shell("GetFileInfo -m" && bash_escape(hfsToPosix(it)))
end mouseUp

function bash_escape instr
  return "'" & replace(instr, "'", "\'") & "'"
end bash_escapeThank you for the information, I will test it and implement it in the project's scripts. 

My regards


André Tremblay
PhotoGraphex

codegreen

unread,
Aug 8, 2019, 1:46:17 PM8/8/19
to SuperCard Discussion
At this point there's no general built-in facility in SuperTalk for doing localization conversion on dates (just numbers and currency).

There might be better ways, but you can use shell to do this manually for your local format:

on mouseUp

  answer folder "Yo:"

  if it = "" then exit script

  get shell(merge("stat -f `%m` -t `%c`") && bash_escape(hfsToPosix(it)))

  answer shell(merge("date -jf `%s` `[[it]]` +`%d/%m/%Y %H:%M:%S`"))

end mouseUp


or:

on mouseUp

  answer folder "Yo:"

  if it = "" then exit script

  get shell("GetFileInfo -m" && bash_escape(hfsToPosix(it)))

  answer shell(merge("date -jf `%m/%d/%Y %H:%M:%S` `[[it]]` +`%d/%m/%Y %H:%M:%S`"))

end mouseUp


By creating a localized date string directly in bash you can sidestep all that icky raw file system timestamp voodoo (then convert back to Mac seconds as needed in SuperTalk).

HTH,
-Mark


Message has been deleted

codegreen

unread,
Aug 8, 2019, 7:32:47 PM8/8/19
to SuperCard Discussion
Just for the record, the bash portion of this should work equally well on both files and folders.

Also you don't need that merge wrapper around GetFileInfo -m.

-Mark
Message has been deleted

Collection PhotoGraphex

unread,
Aug 9, 2019, 9:49:08 PM8/9/19
to SuperCard Discussion
Le jeudi 8 août 2019 13:46:17 UTC-4, codegreen a écrit :

There might be better ways, but you can use shell to do this manually for your local format:

Hello Mark, again thanks a bunch for this most helpful suggestions. 

With the corrections to “merge wrapper around GetFileInfo -m”. 

Here is my wrap of your prototype with GetFileinfo, I've added a detailed version of the script for educational purpose:

on mouseUp

  answer folder "Which the folder to check for its last modification?"

  if it is not "Cancel" then 

     put FolderLastModSec(it) into Time01

    put FolderLastModSec_Detailed(it) into Time02

    answer "The last time this folder: " &RETURN&RETURN& it &RETURN&RETURN& ¬

      "was modified in Mac HFS seconds, was:" &RETURN&RETURN& Time01

  end if

end mouseUp


function FolderLastModSec HFSFolderPath

  -- FolderLastModSec(HFSFolderPath) by Mark Lukas 20190808

  --> Returns the time of the last modification to a folder in Mac HFS seconds format

  put shell("GetFileInfo -m" && bash_escape(HFStoPosix(HFSFolderPath))) into the_result

  put shell(merge("date -jf `%m/%d/%Y %H:%M:%S` `[[the_result]]` +`%d/%m/%Y %H:%M:%S`")) into the_result

  convert the_result to seconds

  return the_result

end FolderLastModSec


function bash_escape instr

  return "'" & replace(instr, "'", "\'") & "'"

end bash_escape

-------

function FolderLastModSec_Detailed HFSFolderPath

  -- FolderLastModSec_Detailed(HFSFolderPath) by Mark Lukas 20190808

  --> Returns the time of the last modification to a folder in Mac HFS seconds format

  -- Detailed script for educational purpose

  -- trace

  put HFStoPosix(HFSFolderPath) into POSIXFolderPath

  put shell("GetFileInfo -m" && bash_escape(POSIXFolderPath)) into the_result1

  put merge("date -jf `%m/%d/%Y %H:%M:%S` `[[the_result1]]` +`%d/%m/%Y %H:%M:%S`") into UnixShell2

  put shell(UnixShell2) into the_result2

  convert the_result2 to seconds

  return the_result2

end FolderLastModSec_Detailed


-------

My best regards

André Tremblay
PhotoGraphex

Reply all
Reply to author
Forward
0 new messages