• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: El Capitan Wrecks my Desktop Sweeper Script
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: El Capitan Wrecks my Desktop Sweeper Script


  • Subject: Re: El Capitan Wrecks my Desktop Sweeper Script
  • From: Shane Stanley <email@hidden>
  • Date: Fri, 02 Oct 2015 22:55:25 +1000

On 2 Oct 2015, at 5:40 PM, Christopher Stone <email@hidden> wrote:

I expect there's an ASObjC method of doing this that is quite fast.

Your "this" seems to be a moving target ;-)

OK, step one is to get a list of the files. There are two main options: a simpler one that takes a POSIX path, and a slightly more complex one that takes an NSURL. However, the latter returns URLS, whereas the former returns just names, and it lets you filter out invisible items. Moreover, if you're running 10.11, you can just pass an alias or file and it will be bridged to a URL. So:

use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set theDesktop to path to desktop
considering numeric strings
if AppleScript's version < "2.5" then set theDesktop to current application's class "NSURL"'s fileURLWithPath:(POSIX path of theDesktop)
end considering
set fileManager to current application's NSFileManager's defaultManager()
set theURLs to fileManager's contentsOfDirectoryAtURL:theDesktop includingPropertiesForKeys:{} options:(current application's NSDirectoryEnumerationSkipsHiddenFiles) |error|:(missing value)

That gives you all the files, and will run on 10.10 too (or 10.9 within a script library). Extracting the ones you want can be done a couple of ways, depending on how you're filtering them. If it's based on the name ot path, you can do it very quickly with a predicate, which is a sort of whose clause for arrays. So for example:

set theDesktop to path to desktop
considering numeric strings
if AppleScript's version < "2.5" then set theDesktop to current application's class "NSURL"'s fileURLWithPath:(POSIX path of theDesktop)
end considering
set fileManager to current application's NSFileManager's defaultManager()
set theURLs to fileManager's contentsOfDirectoryAtURL:theDesktop includingPropertiesForKeys:{} options:(current application's NSDirectoryEnumerationSkipsHiddenFiles) |error|:(missing value)
set extensionList to {"pdf", "txt", "scptd"}
set exclusionList to {"Access.txt"}
set thePredicate to current application's NSPredicate's predicateWithFormat:"(pathExtension IN [c]%@) AND (NOT lastPathComponent IN [c]%@)" argumentArray:{extensionList, exclusionList}
set theURLs to theURLs's filteredArrayUsingPredicate:thePredicate

The [c] means to ignore case, and pathExtension and lastPathComponent are NSURL methods.

If you want to filter further, such as by label index, you need to loop through. So let's say you want only those left whose label index is in {2, 6, 7}. You need to get the value for the key NSURLLabelNumberKey. This relies on something in Objective-C that doesn't translate directly to AppleScript, so the workaround is to pass the value reference  to the argument, which in turn tells AppleScript to return the result as a list, with the argument value included after the normal result. So:

set newArray to current application's NSMutableArray's array() -- to store URLs
set theCount to theURLs's |count|()
repeat with i from 1 to theCount
set oneURL to (theURLs's objectAtIndex:(i - 1)) -- zero-based indexes
set {theResult, theValue} to (oneURL's getResourceValue:(reference) forKey:(current application's NSURLLabelNumberKey) |error|:(missing value))
if theResult as boolean and {2, 6, 7} contains theValue then
(newArray's addObject:oneURL)
end if
end repeat

Back where you got the contents of the directory, it can be a little more efficient if includingPropertiesForKeys: contains any properties you will be using, so you might also insert current application's NSURLLabelNumberKey in that empty list (although in this case the difference will probably be un-noticable).

Now you have an array of URLs. If you coerce it to a list in 10.11, you will get a list of POSIX paths; that's why the looping above was done using the Cocoa objectAtIndex: method, rather than "item i of ".

To move them, you just need another repeat loop and a destination:

set theDestURL to current application's class "NSURL"'s fileURLWithPath:somePosixPath
set theCount to newArray's |count|()
repeat with i from 1 to theCount
set oneURL to (newArray's objectAtIndex:(i - 1)) -- zero-based indexes
set theName to oneURL's lastPathComponent()
(fileManager's moveItemAtURL:oneURL toURL:(theDestURL's URLByAppendingPathComponent:theName) |error|:(missing value))
end repeat

For your date string, you can use a date formatter. This is very simple under 10.11:

set theFormatter to current application's NSDateFormatter's new()
theFormatter's setDateFormat:"yyyy MM dd hh.mm"
set dateString to (theFormatter's stringFromDate:(current date)) as text

Under earlier versions, you need to convert the AS date to a Cocoa date, something like this:

on makeNSDateFrom:theASDate
set {theYear, theMonth, theDay, theSeconds} to theASDate's {year, month, day, time}
if theYear < 0 then set theYear to -theYear
set theCalendar to current application's NSCalendar's currentCalendar()
set newDate to theCalendar's dateWithEra:(theYear ≥ 0) |year|:theYear |month|:(theMonth as integer) |day|:theDay hour:0 minute:0 |second|:theSeconds nanosecond:0
return newDate
end makeNSDateFrom:

Put all that together along with file manager's createDirectoryAtURL:withIntermediateDirectories:attributes:error:, and you're well on your way. 

Or use the BridgePlus script library, and it's even easier...


-- 
Shane Stanley <email@hidden>
<www.macosxautomation.com/applescript/apps/>

 _______________________________________________
Do not post admin requests to the list. They will be ignored.
AppleScript-Users mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
Archives: http://lists.apple.com/archives/applescript-users

This email sent to email@hidden

References: 
 >El Capitan Wrecks my Desktop Sweeper Script (From: Christopher Stone <email@hidden>)

  • Prev by Date: Best Practices
  • Next by Date: Exit Repeat
  • Previous by thread: Re: El Capitan Wrecks my Desktop Sweeper Script
  • Next by thread: Best Practices
  • Index(es):
    • Date
    • Thread