Rename Finder Items - applescript

I am looking to create a script and was wanting to know if this is something that is possible. I have a little knowledge of applescript. But this one is confusing me.
I have a list of loose files inside of one folder that reads as such.
1111111111 010
1111111111 011
1111111222 012
1111111222 013
1111111222 014
1111111243 020
1111111243 021
Its very random every time. But there is always a 10 digit number that is constant, but I would like to add a sequential number starting with one that resets every time the number changes. So that the file name would look like this.
1111111111_1
1111111111_2
1111111222_1
1111111222_2
1111111222_3
1111111243_1
1111111243_2
Any help is much appreciated. Thanks.

tell application "Finder"
set prev to missing value
repeat with f in (get files of (POSIX file "/Users/username/folder" as alias))
set w1 to word 1 of (get name of f)
if w1 is prev then
set n to n + 1
else
set n to 1
end if
set name of f to w1 & "_" & n
set prev to w1
end repeat
end tell
You could also run a command like this in Terminal:
cd ~/folder;for f in *;do w1=${f% *};[ $prev = $w1 ]&&let n++||n=1;mv "$f" $w1\_$n;prev=$w1;done

Related

Applescript to sort files into folder based on British financial year

I'm looking for way to move files based on UK financial year (runs from 6th April -5th April).
Files are named in pattern as
2014-08-26_Asda_lunch.pdf
2016-03-20_Tesco_sationary.pdf
The File needs to be moved to folders which are named, and so on
FY 2014-15
FY 2015-16
Just wondering if applescript/ shell script or automator action would help to achieve this. Also interface with hazel wud be even better
Thanks in advance
I have tried to modify the script
My first aim is get month right, then wud try dates;
the Output for Script
File 2019-07-26_Tesco_stationary -> FY 2020 ( expected FY 2019-20)
File 2019-03-15_Sainsbury -> FY 2019 ( expected FY 2018-19)
Please advise, also any pointers to add date in sorting wud be helpful
Thank you
set savedDelimiters to AppleScript's text item delimiters
set AppleScript's text item delimiters to {"-"}
tell application "Finder"
set filename to name of theFile
end tell
set expenseYear to (first text item of filename) as number
set expenseMonth to (second text item of filename) as number
set expenseDate to (third text item of filename) as number
-- Get the last two characters of the Year
set AppleScript's text item delimiters to savedDelimiters
set lastTwoCharactersOfYear to (characters 3 thru 4 of (expenseYear as text))
set RoundedExpYear to (lastTwoCharactersOfYear as text) as number
if expenseMonth ≥ 4 then
set LongString to expenseYear
set ShortString to RoundedExpYear + 1
else
set LongString to expenseYear - 1
set ShortString to RoundedExpYear
end if
set returnText to "FY" & " " & LongString & "-" & ShortString
There are many ways to parse dates but since your format is always the same (yyyy-mm-dd_xxxx) I used the easiest way. In script below the handler GetFY returns directly the format you're looking for "FY YYYY-YYYY" when you give parameter your file name:
set Fname to "2014-03-05_xxxx" -- value to test
set myfolder to GetFy(Fname)
log "myfolder=" & myfolder
on GetFy(Fname) -- return FY-(FY+1) based on Fname as YYYY-MM-DD_xxxxxx
set myear to (text 1 thru 4 of Fname) as integer
set mmonth to (text 6 thru 7 of Fname) as integer
set mday to (text 9 thru 10 of Fname) as integer
if mmonth < 4 then set Fy to myear - 1
if mmonth = 4 then set Fy to myear - ((mday ≤ 5) as integer)
if mmonth > 4 then set Fy to myear
return "FY " & Fy & "-" & (Fy + 1)
end GetFy

Get date added of Finder items in Applescript

I can get files by date modified using this bit of code:
get (files of entire contents of folder "Macintosh HD:General Music:05 Reggae:" whose modification date is less than ((current date)) - modDate * days)
but I can't seem to get their date added (nor is it listed in Applescript dictionary for Finder that I can see). This is weird, 'cause I can do a smart folder that uses this property.
Any idea on how to get files who were added within 15 days? Otherwise I'm doing loads of weird stuff with GUI at the moment and I'd like to automate it further.
Thanks
Tardy
You can search Spotlight's metadata with the mdfind command, use the kMDItemDateAdded key:
set _15daysAgo to -15 * days -- number of seconds
set tFolder to quoted form of POSIX path of "Macintosh HD:General Music:05 Reggae:"
-- find files, not folders
do shell script "mdfind -onlyin " & tFolder & " 'kMDItemDateAdded>$time.now(" & _15daysAgo & ") && ! kMDItemContentType == public.folder'"
set tFiles to paragraphs of the result
repeat with i in tFiles
tell i to set contents to i as POSIX file as alias
end repeat
tFiles -- list of files who were added within 15 days
Or, use the methods of the NSFileManager Class to get the NSURLAddedToDirectoryDateKey of the files (require Yosemite or El Capitan),
Here's the AppleScript:
set _15daysAgo to -15 * days -- number of seconds
set f to POSIX path of "Macintosh HD:General Music:05 Reggae:"
do shell script "/usr/bin/python -c 'import sys; from Foundation import NSFileManager, NSURL, NSDate, NSDirectoryEnumerationSkipsHiddenFiles
def procFolder(tDir):
p = dfM.contentsOfDirectoryAtURL_includingPropertiesForKeys_options_error_(tDir, myKeys, NSDirectoryEnumerationSkipsHiddenFiles, None)[0]
for f in p:
myDict, error=f.resourceValuesForKeys_error_(myKeys, None)
if error is None:
if (myDict.get(\"NSURLIsDirectoryKey\")): procFolder(f)
elif (myDict.get(\"NSURLAddedToDirectoryDateKey\").compare_(d) == 1):
print f.path().encode(\"utf8\")
fold=NSURL.fileURLWithPath_isDirectory_(sys.argv[1].decode(\"utf8\"), True)
dfM=NSFileManager.defaultManager()
d=NSDate.dateWithTimeIntervalSinceNow_(" & _15daysAgo & ")
myKeys=[\"NSURLIsDirectoryKey\", \"NSURLAddedToDirectoryDateKey\"]
procFolder(fold)' " & f
set tFiles to paragraphs of the result
repeat with i in tFiles
tell i to set contents to i as POSIX file as alias
end repeat
tFiles -- list of files who were added within 15 days

Mavericks AppleScript count every desktop always returns 1

I've got a script taken from GitHub that is supposed to set the wallpaper of every desktop to a certain image depending on the time of day. (I have modified it from the original code to include more time ranges, issue shows in both versions)
The script attempts to count the number of desktops in order to change more than just the current desktop. It does this by first telling System Events the following
set theDesktops to a reference to every desktop
And then, in order to loop through every desktop, it does the following:
if ((count theDesktops) > 1) then
repeat with x from 2 to (count theDesktops)
--some code removed, see full code below
end repeat
end if
The issues is that count theDesktops always returns a 1, no matter how many desktops there are, as seen in the following screenshot.
http://ss.kobitate.com/2013-12-28_0922_2.png
What can be done to fix this? Here is the full code
(*
Script by Philip Hutchison, April 2013
http://pipwerks.com
MIT license http://pipwerks.mit-license.org/
This script assumes:
1. You have a folder named "Wallpapers" in your Pictures folder
2. You have a subfolder named "Time of Day" in Wallpapers
3. You have six subfolders inside "Time of Day", with names that match the variables below.
* If you decide to use different folder names, you must change the variables to match the new folder names
4. You have images inside each folder
For example:
/Users/YOUR_USER_NAME/Pictures/Wallpapers/Time of Day/Afternoon Early/image.jpg
GeekTool can execute this script for you at specified intervals. Use this line in the command field:
osascript ~/Pictures/Wallpapers/Time\ of\ Day/wallpaper.scpt
*)
-- BEGIN USER CONFIGURATION
-- supply folder names
set morningEarly to "Morning Early"
set morningLate to "Morning Late"
set afternoonEarly to "Afternoon Early"
set afternoonLate to "Afternoon Late"
set eveningEarly to "Evening Early"
set eveningLate to "Evening Late"
set nightEarly to "Night Early"
set nightLate to "Night Late"
-- for multiple monitor support.
-- set to true to display the same image on all desktops, false to show unique images on each desktop
set useSamePictureAcrossDisplays to true
-- END USER CONFIGURATION
-- get current hour
set h to hours of (current date)
-- set default periodOfDay
set periodOfDay to nightLate
-- change value of periodOfDay based on current time
if (h > 6 and h < 8) then
set periodOfDay to morningEarly
else if (h ≥ 8 and h < 10) then
set periodOfDay to morningLate
else if (h ≥ 10 and h < 12) then
set periodOfDay to afternoonEarly
else if (h ≥ 12 and h < 16) then
set periodOfDay to afternoonLate
else if (h ≥ 16 and h < 18) then
set periodOfDay to eveningEarly
else if (h ≥ 18 and h < 20) then
set periodOfDay to eveningLate
else if (h ≥ 20 and h < 22) then
set periodOfDay to nightEarly
else if (h ≥ 22) then
set periodOfDay to nightLate
end if
-- helper function ("handler") for getting random image
on getImage(folderName)
tell application "Finder"
return some file of folder ("Pictures:Wallpapers:Time of Day:" & folderName) of home as text
end tell
end getImage
tell application "Finder"
-- wrapped in a try block for error suppression
try
-- determine which picture to use for main display
set mainDisplayPicture to my getImage(periodOfDay)
-- set the picture for additional monitors, if applicable
tell application "System Events"
-- get a reference to all desktops
set theDesktops to a reference to every desktop
-- handle additional desktops
if ((count theDesktops) > 1) then
-- loop through all desktops (beginning with the second desktop)
repeat with x from 2 to (count theDesktops)
-- determine which image to use
if (useSamePictureAcrossDisplays is false) then
set secondaryDisplayPicture to my getImage(periodOfDay)
else
set secondaryDisplayPicture to my mainDisplayPicture
end if
-- apply image to desktop
set picture of item x of the theDesktops to secondaryDisplayPicture
end repeat
end if
end tell
-- set the primary monitor's picture
-- due to a Finder quirk, this has to be done AFTER setting the other displays
set desktop picture to mainDisplayPicture
end try
end tell
Edit: Fixed an unrelated mistake I found in the code
This seems to be fixed now. I remember testing this when #KobiTate posted it.
I am now on 10.9.1 but not sure when it was fixed
tell application "System Events"
set theDesktops to count of (a reference to every desktop)
set theDesktops2 to count every desktop
end tell
log "count of (a reference to every desktop) = " & theDesktops
log "count every desktop = " & theDesktops2
Returns:
(count of (a reference to every desktop) = 2)
(count every desktop = 2)

Loop Over Video Files in Folder to get video length

I have the following which returns how many seconds a selected video file is.
However I was after a way to just give it the movie folder and for it to then loop through all subdirectories and find all video file types.
Once it has these I would like to list the video length in "1 hour 53 seconds" type format as "7990 seconds" isn't too helpful.
Thanks
set macPath to (choose file) as text
tell application "System Events"
set ts to time scale of movie file macPath
set dur to duration of movie file macPath
set movieTime to dur / ts
end tell
You have several sub-questions involved in your question.
1) How do I get all of the files in a folder, including the sub folders
2) how do I filter that list to only include video files
3) How do I loop through that list of video files and extract information from each and
4) How do I convert seconds into a useable string of words
Normally I would ask that you break it down into those individual questions because it's a large task for someone to write the whole thing for you. However, in this case you're lucky because I had done this before myself... so you can have my script. I put lots of comments in the code to help you learn how it works.
-- I found these extensions for video files here http://www.fileinfo.net/filetypes/video
-- we can check the file extensions of a file against this list to evaluate if it's a video file
set video_ext_list to {"3g2", "3gp", "3gp2", "3gpp", "3mm", "60d", "aep", "ajp", "amv", "asf", "asx", "avb", "avi", "avs", "bik", "bix", "box", "byu", "cvc", "dce", "dif", "dir", "divx", "dv", "dvr-ms", "dxr", "eye", "fcp", "flc", "fli", "flv", "flx", "gl", "grasp", "gvi", "gvp", "ifo", "imovieproject", "ivf", "ivs", "izz", "izzy", "lsf", "lsx", "m1v", "m2v", "m4e", "m4u", "m4v", "mjp", "mkv", "moov", "mov", "movie", "mp4", "mpe", "mpeg", "mpg", "mpv2", "msh", "mswmm", "mvb", "mvc", "nvc", "ogm", "omf", "prproj", "prx", "qt", "qtch", "rm", "rmvb", "rp", "rts", "sbk", "scm", "smil", "smv", "spl", "srt", "ssm", "svi", "swf", "swi", "tivo", "ts", "vdo", "vf", "vfw", "vid", "viewlet", "viv", "vivo", "vob", "vro", "wm", "wmd", "wmv", "wmx", "wvx", "yuv"}
-- get the folder to check
set f to choose folder
-- notice the use of "entire contents" to also go through subfolders of f
-- use a "whose" filter to find only the video files
tell application "Finder"
set vidFiles to (files of entire contents of f whose name extension is in video_ext_list) as alias list
end tell
-- use a repeat loop to loop over a list of something
set vidList to {} -- this is where we store the information as we loop over the files
repeat with aFile in vidFiles
-- get some information from aFile
tell application "System Events"
set vidFile to movie file (aFile as text)
set ts to time scale of vidFile
set dur to duration of vidFile
end tell
-- add the information to the "storage" list we made earlier
set end of vidList to {POSIX path of aFile, secs_to_hms(dur / ts)}
end repeat
return vidList
(*=================== SUBROUTINES ===================*)
-- convert seconds into a string of words
-- the use of "mod" and "div" here makes it easy
-- we also make sure that each value is at least 2 places long to make it look nicer
on secs_to_hms(the_secs)
set timeString to ""
set hr to the_secs div hours
if hr is not 0 then set timeString to timeString & (text -2 thru -1 of ("0" & (hr as text))) & " hours "
set min to the_secs mod hours div minutes
if min is not 0 then set timeString to timeString & (text -2 thru -1 of ("0" & (min as text))) & " minutes "
set sec to the_secs mod minutes div 1
if sec is not 0 then
set fraction to text 2 thru 3 of ((100 + the_secs mod 1 * 100) as text)
set timeString to timeString & (sec as text) & "." & fraction & " seconds"
end if
if timeString ends with space then set timeString to text 1 thru -2 of timeString
return timeString
end secs_to_hms
I came across this post because I wanted to have a log of video files in a folder; something I could import in a spreadsheet, also to calculate the total duration but not only.
The posted script didn't work for me so I ended up importing the folder in Final Cut Pro, doing Batch Export on the folder and than File > Export > Batch List, which resulted in a plain text file I could import in a spreadsheet as the start of a log and to calculate the total duration.
Perhaps this helps others.

Save and restore applications and layout

I'm looking for ways to reduce the wasted time spent to open all the applications needed, position windows, open urls/files/change directories/etc. before actual coding starts.
In the perfect world there would be 2 buttons marked 'SAVE STATE' and 'RESTORE STATE' per 'project'. The kind of feature you find in some games.
I'm on a mac and just spent afew hours banging my head with 'Automator' (which for some reason has problems to even open firefox from the dock) and then applescript (which gives me the feeling i'm in for a long ride).
Searching on the net led me to this script:
http://snipt.net/Fotinakis/applescript-to-save-and-restore-window-positions/
#!/usr/bin/osascript
-- Usage:
-- $ osacompile -o windowPositions.compiled.scpt windowPositions.scpt
-- $ osascript windowPositions.compiled.scpt --save
-- $ osascript windowPositions.compiled.scpt --restore
-- Change this to be the list of windows you want to save/restore
property affectedProcesses : {"Chrome", "Adium", "Eclipse", "Terminal"}
property windowRecord : {}
on run argv
if (count of argv) is equal to 0 then
log "Please specify one of --save or --restore."
return
end if
tell application "System Events"
if (item 1 of argv is equal to "--save") then
set windowRecord to {}
repeat with i from 1 to count affectedProcesses
set end of windowRecord to {0, {}, {}}
end repeat
repeat with p from 1 to count affectedProcesses
set processName to (item p of affectedProcesses)
if exists process processName then
log "Process '" & processName & "' exists"
tell process processName
set numWindows to count windows
set item 1 of item p of windowRecord to numWindows
repeat with i from 1 to numWindows
set end of item 2 of item p of windowRecord to position of window i
set end of item 3 of item p of windowRecord to size of window i
end repeat
end tell
end if
end repeat
else
repeat with p from 1 to count affectedProcesses
set processName to (item p of affectedProcesses)
if exists process processName then
log "Process '" & processName & "' exists"
tell process processName
set numWindows to item 1 of item p of windowRecord
repeat with i from 1 to numWindows
set position of window i to (item i of item 2 of item p of windowRecord)
set size of window i to (item i of item 3 of item p of windowRecord)
end repeat
end tell
end if
end repeat
end if
end tell
end run
It does half the job (resize and position current windows) but falls apart on a multi-monitor multi-desktops setup. There is no contact info for the original author to ask for help or feedback.
Can anyone shed some light on saving and restoring applications and layout? It feels like such a common task that ought to have some helper utilities. The best I have is the 'sleep mode' but it seems I have to to do a full restart every other day and I have different applications and layout for different projects.
This is a feature of Lion (Mac OS X 10.7) ... I wouldn't kill yourself over a feature Apple has seen the need for and has implemented rather seamlessly...

Resources