Thursday, September 2, 2010

#1 2008-06-13 03:51:28 am

Martin Michel
Administrator
From: Berlin, Germany
Registered: 2008-03-03
Posts: 655
Website

subidoo - Enhanced subfolder creation for Mac OS X

If you also suffer from subfolder creation sickness, then I might have a cure for you smile

Overview
subidoo is an AppleScript that simplifies the creation of subfolders in Mac OS X. Especially in list view, subfolders are tedious to create. subidoo can create multiple subfolders in multiple locations at once, saves the names of the last 300 subfolders created and supports convenient folder sets, which can contain collections of frequently used subfolders.

You can download subidoo for free right here:



 - Click to enlarge


System Requirements
Mac OS X 10.5.1 or later
- subidoo may run on other systems as well,  but I did/could not test it
- subidoo was tested on Intel- and PowerPC-based Macs

Installation
Just drag the script into your Applications/Scripts folder (or wherever you like to put it).

Afterwards you »can«:
a) drag subidoo into the toolbar of a Finder window to use it as a Toolbar Script.
b) drag subidoo into the Dock to use it as a Dock Item.

I find both solutions very convenient for creating subfolders, but personally think, that subidoo works best when used from the toolbar.

Usage
• Options panel:
To invoke the options panel in order to manage and create folder sets, just start subidoo by double-clicking its icon without any items selected in the Finder (except subidoo itself).

 - Click to enlarge


• Toolbar Script/Dock Item:
Select folder items in the frontmost Finder window. Then start subidoo by clicking its icon in the dock or toolbar. After providing names for subfolders or choosing folder sets, they will be created within the selected folder items.
If you don't select any items in the Finder, the options panel for managing your folder sets will be displayed.

• Droplet:
subidoo also works extremely well as a droplet. Therefor you can simply drag & drop folder items onto it. After providing names for subfolders or choosing folder sets, they will be created within the folder items, which you dragged & dropped onto the script.

Folder Sets
subidoo now supports convenient folder sets, which can contain collections of frequently used folder names. This is very useful, when you need to create the same bunch of subfolders over and over again. System administrators will love this! For example, if you are often creating the same set of subfolders representing the 12 months of a year, e.g. '01 January', '02 February', '03 March', then just save them in a folder set named 'Months'! Now you can choose to create this folder set in chosen folders whenever you want by just a click!
To manage, create and edit your folder sets, just start subidoo without selecting any items in The Finder.

 - Click to enlarge


Tips
When you are asked to provide subfolder names, you can enter multiple entries separated by a colon. Nested subfolder structures can be entered by separating subfolder names by a slash.

If you want to manually edit the database file containing the folder sets, you can find it here:

/Users/yourname/Library/Application Support/subidoo/foldersets.db

After manipulating the database file, please always save it with UTF-8 text encoding.

Known Problems
If you select folder items in the Finder and then start subidoo out of a Finder window, it will not recognize the selected folders. This is because AppleScript seems to be unable to recognize selected items in 'background' Finder windows (when you start subidoo out of a Finder window, it is itself the frontmost selection). This does not happen if you are using subidoo as a Toolbar Script or Dock Item. So this is absolutely recommended.

Troubleshoot/Help
-/-

Version History
• Version 1.5b
- subidoo now finally supports folder sets! wohoo!
- (sub)folders are not anymore created with the Finder,
  but using «mkdir -p» on the command line
- subidoo now supports relative subfolder structures, so
  that you can create subfolders in subfolders in subfolders in...
• Version 1.0
- upon request of my wife, I removed the gave-up mode in the dialog, where the user can enter the subfoldernames. now the user has 'endless' time to enter the subfoldernames without the dialog suddenly disappearing after 50 seconds.
• Version 0.9b
- First public release! Yo!

Important: Opening and saving the below script code in Script Editor won't result in a usable AppleScript! That is because subidoo internally relies on a Python script, which is located inside its Application bundle. Therefor please download the complete script here.

Applescript:


-- created: 07.12.2005
-- modified: 18.02.2008
-- version: 1.5
-- tested with:
-- • Mac OS X 10.5.1
-- • Intel and PowerPC based Macs
-- history:
-- v1.5 (18.02.2008):
-- • finally subidoo supports folder sets! wohoo!
-- • subidoo now supports relative folder structures, so
-- you can also create subfolders in subfolders in subfolders...
-- • (sub)folders are now created using the «mkdir -p»-command
-- -->> type 'man mkdir' into a Terminal window
-- v1.0 (11.02.2006):
-- • upon request of my wife, I removed the gave-up mode in the dialog,
-- where the user enters the subfolder names. now the user has 'endless'
-- time to enter the subfoler names without the dialog window suddenly
-- disappearing after 50 seconds.
-- future:
-- • icon, icon, icon!

-- some basic properties
property mytitle : "subidoo"
property mydomain : "com.jos." & mytitle
property myversion : "1.5b"

-- handler called when Finder items are dropped onto the script icon
on open dropitems
   set mode to "on open"
   my main(mode, dropitems)
end open

-- handler called when the script is opened with a double-click onto its icon
on run
   set mode to "on run"
   set args to missing value
   my main(mode, args)
end run

-- I am the main function of the script and control the application flow
on main(mode, args)
   try
       -- creating application support folder & copying default database file if necessary
       my initialize()
       -- user dropped Finder items onto the script
       if mode is "on open" then
           -- process dropped Finder items
           my procselitems(mode, args)
           -- user opened the script with a double-click
       else if mode is "on run" then
           -- the user might have selected items in the Finder
           tell application "Finder"
               set selitems to selection as list
           end tell
           if selitems is {} then
               -- dock item?
               my guiloop()
           else
               -- is the script itself the selected item or are there no selected items at all?
               -- > in this case we display the options panel
               set myname to name of (info for (path to me))
               set selitemname to name of (info for ((item 1 of selitems) as alias))
               if length of selitems = 1 and myname = selitemname then
                   my guiloop()
               else
                   -- process selected Finder items
                   my procselitems(mode, selitems)
               end if
           end if
       end if
       -- catching unexpected errors, hopefully not too often
   on error errmsg number errnum
       my dsperrmsg(errmsg, errnum)
   end try
end main

-- I am initializing the script, taking precautions for a successful operation
on initialize()
   -- path to my own application support folder
   set myasfpath to (((path to application support folder from user domain) as Unicode text) & mytitle & ":")
   -- if the application support folder does not yet exist, we try to create it
   -- occuring errors (missing permissions?) will be catched by
   -- the try/on error-block of the main function
   try
       set myasfalias to myasfpath as alias
   on error
       do shell script "mkdir -p" & space & quoted form of (POSIX path of myasfpath)
       -- if the script's application support folder did not exist so far, then
       -- chances are good, that the user uses the script for the very first time,
       -- so we display an inviting welcome message
       my dspwelcomemsg()
   end try
   -- path to the user's database file inside the application support folder, which contains the folder sets
   set dbfilepath to myasfpath & "foldersets.db"
   -- path to the default database file inside the script's package folder
   set defdbfilepath to (((path to me) as Unicode text) & "Contents:Resources:foldersets.db")
   -- if the user's database file does not yet exist, we copy the default database file to the
   -- application support folder
   try
       set dbfilealias to dbfilepath as alias
   on error
       do shell script "cp" & space & quoted form of (POSIX path of defdbfilepath) & space & quoted form of (POSIX path of dbfilepath)
   end try
end initialize

-- I am processing the selected/dropped Finder items and create the chosen subfolders
-- therein if possible
on procselitems(mode, selitems)
   -- we are only interested in dropped/selected folder items
   set selfolders to {}
   repeat with selitem in selitems
       try
           set selinfo to (info for (selitem as alias))
           if folder of selinfo and name of selinfo does not end with ".app" then
               set selfolders to selfolders & (selitem as Unicode text)
           end if
       end try
   end repeat
   -- unfortunately the user only selected/dropped files
   if selfolders is {} then
       if mode is "on run" then
           set errmsg to "You did only select non-folder items in the Finder." & return & return & "Please try again by selecting folders only."
       else if mode is "on open" then
           set errmsg to "You did only drop non-folder items onto " & mytitle & "." & return & return & "Please try again by dropping folders only."
       end if
       my dsperrmsg(errmsg, "--")
       -- early finish
       return
       -- we found selected/dropped folders!
   else
       -- asking the user to provide (sub)folder names to be created inside
       -- the dropped or selected folders
       set countselfolders to length of selfolders
       set relfoldernames to my askforrelfoldernames(mode, countselfolders)
       if relfoldernames is not missing value then
           -- so now that we got (sub)folder names, we have to create a string
           -- of quoted folder paths to be used with the mkdir-command below
           repeat with selfolder in selfolders
               set stringfolders to ""
               set countrelfoldernames to length of relfoldernames
               repeat with i from 1 to countrelfoldernames
                   -- .e.g. 'Invoices/2008/01 January/'
                   set relfoldername to item i of relfoldernames
                   -- e.g. '/Users/martin/Documents/Customers/BigCompany/Invoices/2008/01 January/'
                   set newpath to quoted form of ((POSIX path of selfolder) & relfoldername)
                   if i is not equal to countrelfoldernames then
                       set stringfolders to stringfolders & newpath & space
                   else
                       set stringfolders to stringfolders & newpath
                   end if
               end repeat
               -- finally creating the subfolders using the mkdir-command with the p-option
               set command to "mkdir -p" & space & stringfolders
               set command to command as «class utf8»
               set shellresult to do shell script command
           end repeat
       end if
   end if
end procselitems

-- I am displaying the options panel and trigger actions on the basis of
-- the chosen menu items
on guiloop()
   set chosenmenuitem to my dspoptionsmenu()
   if chosenmenuitem is missing value then
       return
   else
       if chosenmenuitem is "Add folder set" then
           my miaddfset()
       else if chosenmenuitem is "Delete folder set(s)" then
           my midelfsets()
       else if chosenmenuitem is "Rename folder set" then
           my mirenfset()
       else if chosenmenuitem is "Show folder sets" then
           my mishowfsets()
       else if chosenmenuitem is "Add folder name(s) to folder set" then
           my miaddfolderstofset()
       else if chosenmenuitem is "Delete folder name(s) from folder set" then
           my midelfoldersfromfset()
       else if chosenmenuitem is "Create folder set from recent folder names" then
           my micrtfsetfromsysfolders("Recent folder names")
       else if chosenmenuitem is "Add recent folder names to a folder set" then
           my miaddsysfolderstofset("Recent folder names")
       else if chosenmenuitem is "Create folder set from last folder names" then
           my micrtfsetfromsysfolders("Last folder names")
       else if chosenmenuitem is "Add last folder names to a folder set" then
           my miaddsysfolderstofset("Last folder names")
       else if chosenmenuitem is "Open database file" then
           my miopendbfile()
       end if
   end if
   my guiloop()
end guiloop

-- I am displaying the options menu and return the chosen menu items
on dspoptionsmenu()
   set spacer to "………………………………………………………"
   set menuitems to {"Add folder set", "Delete folder set(s)", "Rename folder set", "Show folder sets", spacer, "Add folder name(s) to folder set", "Delete folder name(s) from folder set", spacer, "Create folder set from recent folder names", "Add recent folder names to a folder set", spacer, "Create folder set from last folder names", "Add last folder names to a folder set", spacer, "Open database file"}
   choose from list menuitems with title mytitle with prompt "Please choose an option:" without multiple selections allowed and empty selection allowed
   set choice to result
   if choice is not false then
       set chosenmenuitem to item 1 of choice
       return chosenmenuitem
   else
       return missing value
   end if
end dspoptionsmenu

-- I am asking the user to choose a single folder set name from a list
-- of existing folder set names
on choosefoldersetname(showhidden)
   set foldersetnames to my getfoldersetnames(showhidden)
   if foldersetnames is missing value then
       return missing value
   else
       choose from list foldersetnames with title mytitle with prompt "Please choose a folder set:" without multiple selections allowed and empty selection allowed
       set choice to result
       if choice is not false then
           set chosenfoldersetname to item 1 of choice
           return chosenfoldersetname
       else
           return missing value
       end if
   end if
end choosefoldersetname

-- I am asking the user to choose one or more folder set names from a list
-- of existing folder set names
on choosefoldersetnames(showhidden)
   set foldersetnames to my getfoldersetnames(showhidden)
   if foldersetnames is missing value then
       return missing value
   else
       choose from list foldersetnames with title mytitle with prompt "Please choose one or more folder sets:" with multiple selections allowed without empty selection allowed
       set choice to result
       if choice is not false then
           set chosenfoldersetnames to (choice as list)
           return chosenfoldersetnames
       else
           return missing value
       end if
   end if
end choosefoldersetnames

-- I am adding a new folder set to the existing database of
-- folder sets
on miaddfset()
   set srcfolder to my choosesrcfolder()
   if srcfolder is not missing value then
       set relfolders to my searchrelfolders(srcfolder)
       if relfolders is not missing value then
           -- for enhanced convenience, we suggest the user to use
           -- the name of the above chosen source folder for the
           -- new folder set
           set srcfolderinfo to info for (srcfolder as alias)
           set srcfoldername to displayed name of srcfolderinfo
           set newfoldersetname to my getnewfoldersetname(srcfoldername)
           if newfoldersetname is not missing value then
               my addfolderset(newfoldersetname, relfolders)
           end if
       end if
   end if
end miaddfset

-- I am deleting one or more chosen folder sets from the database file
on midelfsets()
   -- we don't want the user to delete the internally used folder set names
   -- ('Last folder names', 'Recent folder names'), so we set
   -- «showhidden» to false
   set showhidden to false
   set chosenfoldersetnames to my choosefoldersetnames(showhidden)
   if chosenfoldersetnames is not missing value then
       repeat with chosenfoldersetname in chosenfoldersetnames
           my delfolderset(chosenfoldersetname)
       end repeat
   end if
end midelfsets

-- I am renaming an existing folder set
on mirenfset()
   -- we don't want the user to rename the internally used folder set names
   -- ('Last folder names', 'Recent folder names'), so we set
   -- «showhidden» to false
   set showhidden to false
   set oldfoldersetname to my choosefoldersetname(showhidden)
   if oldfoldersetname is not missing value then
       set newfoldersetname to my getnewfoldersetname(oldfoldersetname)
       if newfoldersetname is not missing value then
           my renamefolderset(oldfoldersetname, newfoldersetname)
       end if
   end if
end mirenfset

-- I am displaying a list of available folder sets
on mishowfsets()
   -- let's hide the internally used folder sets from the user's eyes
   set showhidden to false
   set foldersetname to my choosefoldersetname(showhidden)
   if foldersetname is not missing value then
       set relfolders to my getfolderset(foldersetname)
       if relfolders is {} then
           set errmsg to "Sorry, the folder set '" & foldersetname & "' does not contain any folder names."
           my dsperrmsg(errmsg, "--")
       else
           choose from list relfolders with title mytitle with prompt "Folder names of folder set '" & foldersetname & "':" with empty selection allowed
       end if
   end if
end mishowfsets

-- I am adding new folder names to an already existing folder set
on miaddfolderstofset()
   -- let's hide the internally used folder sets from the user's eyes
   set showhidden to false
   set foldersetname to my choosefoldersetname(showhidden)
   if foldersetname is not missing value then
       tell me
           activate
           display dialog "Do you want to manually enter the additional folder names or do you want to choose a folder?" buttons {"Choose folder", "Enter manually"} default button 2 with title mytitle
           set dlgresult to result
       end tell
       if button returned of dlgresult is "Choose folder" then
           set srcfolder to my choosesrcfolder()
           if srcfolder is not missing value then
               set relfolders to my searchrelfolders(srcfolder)
           else
               set relfolders to missing value
           end if
       else if button returned of dlgresult is "Enter manually" then
           set relfolders to my askforfoldernames()
       end if
       if relfolders is not missing value then
           my addrelfolderstofolderset(foldersetname, relfolders)
       end if
   end if
end miaddfolderstofset

-- I am removing selected folder names from a folder set
on midelfoldersfromfset()
   -- let's hide the internally used folder sets from the user's eyes
   set showhidden to false
   set foldersetname to my choosefoldersetname(showhidden)
   if foldersetname is not missing value then
       set relfolders to my getfolderset(foldersetname)
       if relfolders is {} then
           set errmsg to "Sorry, the folder set '" & foldersetname & "' does not contain any folder names."
           my dsperrmsg(errmsg, "--")
       else
           choose from list relfolders with title mytitle with prompt "Please choose folder names to delete from the folder set '" & foldersetname & "':" cancel button name "Cancel" OK button name "Delete" with multiple selections allowed without empty selection allowed
           set choice to result
           if choice is not false then
               set relfolders to (choice as list)
               my delrelfoldersfromfolderset(foldersetname, relfolders)
           end if
       end if
   end if
end midelfoldersfromfset

-- I am creating a new folder set from selected recent or last folder names
on micrtfsetfromsysfolders(foldersetname)
   if not my foldersetnameexists(foldersetname) then
       set errmsg to "Sorry, the folder set '" & foldersetname & "' does not exist in the database."
       my dsperrmsg(errmsg, "--")
   else
       set relfolders to my getfolderset(foldersetname)
       if relfolders is {} then
           set errmsg to "Sorry, the folder set '" & foldersetname & "' does not contain any folder names."
           my dsperrmsg(errmsg, "--")
       else
           choose from list relfolders with title mytitle with prompt "Please choose folder names from the folder set '" & foldersetname & "' to create a new folder set:" with multiple selections allowed without empty selection allowed
           set choice to result
           if choice is not false then
               set relfolders to (choice as list)
               set newfoldersetname to my getnewfoldersetname("")
               if newfoldersetname is not missing value then
                   my addfolderset(newfoldersetname, relfolders)
               end if
           end if
       end if
   end if
end micrtfsetfromsysfolders

-- I am adding selected recent or last folder names to an existing folder set
on miaddsysfolderstofset(foldersetname)
   if not my foldersetnameexists(foldersetname) then
       set errmsg to "Sorry, the folder set '" & foldersetname & "' does not exist in the database."
       my dsperrmsg(errmsg, "--")
   else
       set relfolders to my getfolderset(foldersetname)
       if relfolders is {} then
           set errmsg to "Sorry, the folder set '" & foldersetname & "' does not contain any folder names."
           my dsperrmsg(errmsg, "--")
       else
           choose from list relfolders with title mytitle with prompt "Please choose folder names from the folder set '" & foldersetname & "' to add them to an existing folder set:" with multiple selections allowed without empty selection allowed
           set choice to result
           if choice is not false then
               set relfolders to (choice as list)
               -- let's hide the internally used folder sets from the user's eyes
               set showhidden to false
               set foldersetname to my choosefoldersetname(showhidden)
               if foldersetname is not missing value then
                   my addrelfolderstofolderset(foldersetname, relfolders)
               end if
           end if
       end if
   end if
end miaddsysfolderstofset

-- I am opening the database file in the default application
on miopendbfile()
   -- path to my application support folder
   set myasfpath to (((path to application support folder from user domain) as Unicode text) & mytitle & ":")
   -- path to the database file located in my application support folder
   set dbfilepath to quoted form of (POSIX path of (myasfpath & "foldersets.db"))
   set command to "open" & space & dbfilepath
   set command to command as «class utf8»
   do shell script command
end miopendbfile

-- I am asking the user to provide a new folder set name
on getnewfoldersetname(suggestion)
   try
       tell me
           display dialog "Please choose a name for your new folder set:" default answer suggestion buttons {"Cancel", "Select"} default button 2 with title mytitle
           set dlgresult to result
       end tell
   on error errmsg number errnum
       if errnum is equal to -128 then
           return missing value
       else
           error errmsg number errnum
       end if
   end try
   set newfoldersetname to text returned of dlgresult
   if newfoldersetname is "" then
       my getnewfoldersetname(suggestion)
   else
       if my foldersetnameexists(newfoldersetname) then
           set errmsg to "The chosen folder set name '" & newfoldersetname & "' already exists in the database. " & return & return & newfoldersetname & return & return & "Please choose a different folder set name."
           my dsperrmsg(errmsg, "--")
           my getnewfoldersetname(suggestion)
       else
           return newfoldersetname
       end if
   end if
end getnewfoldersetname

-- I am asking the user to choose a source folder to search for contained (sub)folder names
on choosesrcfolder()
   try
       set srcfolder to choose folder with prompt "Please choose a source folder:" without multiple selections allowed
       return srcfolder
   on error errmsg number errnum
       if errnum is equal to -128 then
           return missing value
       end if
   end try
end choosesrcfolder

-- I am asking the user to choose a folder and return the relative folders contained therein
on searchrelfolders(srcfolder)
   set srcfolder to POSIX path of (srcfolder as Unicode text)
   tell me
       activate
       display dialog "Do you want to scan for subfolders beyond the first level?" buttons {"Yes", "No"} default button 2 with title mytitle
       set dlgresult to result
   end tell
   -- if the user choosed to scan subfolders, we set a warn level
   -- if we find more folders than set by the warn level (e.g. > 250),
   -- we display a dialog and ask the user if we should continue the scan process
   -- this is to avoid problems, that might occur, when the user accidently choosed
   -- the wrong source folder, e.g. the hard disk itself...
   if button returned of dlgresult is "Yes" then
       set subfolders to true
       set warnlevel to 250
   else if button returned of dlgresult is "No" then
       set subfolders to false
       set warnlevel to false
   end if
   set relfolders to my aspybridge("getrelfolders", {srcfolder, subfolders, warnlevel}, "lines")
   if relfolders is {} then
       set errmsg to "Sorry, your source folder did not contain any folders."
       my dsperrmsg(errmsg, "--")
       return missing value
   else if (item 1 of relfolders) begins with "<<Error>>" then
       set warnmsg to "Warning: " & return & return & ((characters 11 through -1 of (item 1 of relfolders)) as Unicode text) & return & return & "Do you want to continue anyway?"
       try
           tell me
               activate
               display dialog warnmsg buttons {"Cancel", "Continue"} default button 1 with title mytitle with icon caution
           end tell
       on error errmsg number errnum
           if errnum is equal to -128 then
               return missing value
           else
               error errmsg number errnum
           end if
       end try
       set warnlevel to false
       set relfolders to my aspybridge("getrelfolders", {srcfolder, subfolders, warnlevel}, "lines")
       return relfolders
   else
       return relfolders
   end if
end searchrelfolders

-- I am asking the user to provide (sub)folder names, either by entering
-- them manually or by choosing an existing folder set
-- Yes, I am ugly...
on askforrelfoldernames(mode, countselfolders)
   if countselfolders is equal to 1 then
       if mode is "on run" then
           set selfoldmsg to "» You have selected 1 folder in the Finder «"
       else if mode is "on open" then
           set selfoldmsg to "» You dropped 1 folder onto " & mytitle & " «"
       end if
   else
       if mode is "on run" then
           set selfoldmsg to "» You have selected " & countselfolders & " folders in the Finder «"
       else if mode is "on open" then
           set selfoldmsg to "» You dropped " & countselfolders & " folders onto " & mytitle & " «"
       end if
   end if
   -- if the folder set 'Last folder names' exists and contains
   -- folder names, we conveniently use them for the default answer
   set defanswer to ""
   set foldersetname to "Last folder names"
   if my foldersetnameexists(foldersetname) then
       set relfolders to my getfolderset(foldersetname)
       if relfolders is not {} then
           set countrelfolders to length of relfolders
           repeat with i from 1 to countrelfolders
               set relfolder to item i of relfolders
               if i is equal to countrelfolders then
                   set defanswer to defanswer & relfolder
               else
                   set defanswer to defanswer & relfolder & ":"
               end if
           end repeat
       end if
   end if
   -- if no folder sets exist so far, we do not show the «Folder sets»-button
   set showhidden to true
   set foldersetnames to my aspybridge("getfsetnames", {showhidden}, "lines")
   if foldersetnames is {} then
       set dlgbuttons to {"Cancel", "Enter"}
   else
       set dlgbuttons to {"Folder sets", "Cancel", "Enter"}
   end if
   -- the dialog
   try
       set msg to "Please enter your desired folder names manually or choose folder sets:" & return & return & "(Enter multiple folder names separated by a colon," & return & "enter subfolder names separated by a slash)" & return & return & selfoldmsg
       tell me
           activate
           display dialog msg default answer defanswer buttons {"Folder sets", "Cancel", "Enter"} default button 3 with title mytitle
           set dlgresult to result
       end tell
   on error errmsg number errnum
       if errnum is equal to -128 then
           return missing value
       else
           error errmsg number errnum
       end if
   end try
   if button returned of dlgresult is "Enter" then
       set usrinput to text returned of dlgresult
       if usrinput is "" then
           my askforrelfoldernames(mode, countselfolders)
       else
           set relfoldernames to my checkenteredfoldernames(usrinput)
           -- oops, no valid folder names
           if relfoldernames is {} then
               my askforrelfoldernames(mode, countselfolders)
           else
               -- saving entered folder names to the 'Last folder names'-folder set
               if my foldersetnameexists("Last folder names") then
                   my delfolderset("Last folder names")
               end if
               my addfolderset("Last folder names", relfoldernames)
               -- saving entered folder names to the 'Recent folder names'-folder set
               if my foldersetnameexists("Recent folder names") then
                   my addrelfolderstofolderset("Recent folder names", relfoldernames)
               else
                   my addfolderset("Recent folder names", relfoldernames)
               end if
               return relfoldernames
           end if
       end if
   else if button returned of dlgresult is "Folder sets" then
       -- we want the user to see the internally used folder sets, so that
       -- he can choose folder names from them
       set showhidden to true
       set foldersetnames to my choosefoldersetnames(showhidden)
       if foldersetnames is missing value then
           my askforrelfoldernames(mode, countselfolders)
       else
           set relfoldernames to {}
           repeat with foldersetname in foldersetnames
               set relfolders to my getfolderset(foldersetname)
               if relfolders is {} then
                   set errmsg to "Sorry, the folder set '" & foldersetname & "' does not contain any folder names."
                   my dsperrmsg(errmsg, "--")
               else
                   if foldersetname is in {"Last folder names", "Recent folder names"} then
                       choose from list relfolders with prompt "Please choose folder names from the folder set '" & foldersetname & "':" with title mytitle with multiple selections allowed without empty selection allowed
                       set choice to result
                       if choice is not false then
                           set relfolders to (choice as list)
                       else
                           set relfolders to {}
                       end if
                   end if
                   repeat with relfolder in relfolders
                       if relfolder is not in relfoldernames then
                           set relfoldernames to relfoldernames & relfolder
                       end if
                   end repeat
               end if
           end repeat
           if relfoldernames is {} then
               my askforrelfoldernames(mode, countselfolders)
           else
               return relfoldernames
           end if
       end if
   end if
end askforrelfoldernames

-- I am also asking the user to provide (sub)folder names, but am used
-- from within the options panel
on askforfoldernames()
   set msg to "Please enter your desired folder names:" & return & return & "(Enter multiple folder names separated by a colon," & return & "enter subfolders separated by a slash)"
   try
       tell me
           activate
           display dialog msg default answer "" buttons {"Cancel", "Enter"} default button 2 with title mytitle
           set dlgresult to result
       end tell
   on error errmsg number errnum
       if errnum is equal to -128 then
           return missing value
       else
           error errmsg number errnum
       end if
   end try
   set usrinput to text returned of dlgresult
   if usrinput is "" then
       my askforfoldernames()
   else
       set foldernames to my checkenteredfoldernames(usrinput)
       -- oops, no valid folder names
       if foldernames is {} then
           my askforfoldernames()
       else
           return foldernames
       end if
   end if
end askforfoldernames

-- I am validating the entered folder names
on checkenteredfoldernames(usrinput)
   considering case, diacriticals and punctuation
       set olddelims to AppleScript's text item delimiters
       set AppleScript's text item delimiters to ":"
       set inputfoldernames to text items of usrinput
       set AppleScript's text item delimiters to olddelims
   end considering
   -- sorting out 'empty' entries, deleting double entries, ignoring invalid entries
   set foldernames to {}
   repeat with inputfoldername in inputfoldernames
       set inputfoldername to inputfoldername as Unicode text
       if inputfoldername is not "" and inputfoldername is not in foldernames and inputfoldername does not start with "/" then
           set foldernames to foldernames & inputfoldername
       end if
   end repeat
   return foldernames
end checkenteredfoldernames

-- I am returning a list of available folder set names in the database file
-- If there are no folder set names available, I display an error message and
-- return «missing value»
on getfoldersetnames(showhidden)
   set foldersetnames to my aspybridge("getfsetnames", {showhidden}, "lines")
   if foldersetnames is {} then
       set errmsg to "Your database file does not contain any folder set names."
       my dsperrmsg(errmsg, "--")
       return missing value
   else
       return foldersetnames
   end if
end getfoldersetnames

-- I am adding a new folder set to the database file
on addfolderset(foldersetname, relfolders)
   my aspybridge("addfset", {foldersetname, relfolders}, missing value)
end addfolderset

-- I am deleting a folder set
on delfolderset(foldersetname)
   my aspybridge("delfset", {foldersetname}, missing value)
end delfolderset

-- I am renaming a folder set
on renamefolderset(oldfoldersetname, newfoldersetname)
   my aspybridge("renfset", {oldfoldersetname, newfoldersetname}, missing value)
end renamefolderset

-- I am returning the folder names saved in a given folder set (name)
on getfolderset(foldersetname)
   set relfolders to my aspybridge("getfset", {foldersetname}, "lines")
   return relfolders
end getfolderset

-- I am adding a list of folder names to a given folder set (name)
on addrelfolderstofolderset(foldersetname, relfolders)
   my aspybridge("addrelfolderstofset", {foldersetname, relfolders}, missing value)
end addrelfolderstofolderset

-- I am deleting a list of folder names from a given folder set (name)
on delrelfoldersfromfolderset(foldersetname, relfolders)
   my aspybridge("delrelfoldersfromfset", {foldersetname, relfolders}, missing value)
end delrelfoldersfromfolderset

on foldersetnameexists(foldersetname)
   return (my aspybridge("hasfsetname", {foldersetname}, "boolean"))
end foldersetnameexists

on getquotedstringfolders(relfolders)
   set countrelfolders to length of relfolders
   set quotedstringfolders to ""
   repeat with i from 1 to countrelfolders
       set relfolder to item i of relfolders
       if i is equal to countrelfolders then
           set quotedstringfolders to quotedstringfolders & quoted form of relfolder
       else
           set quotedstringfolders to quotedstringfolders & quoted form of relfolder & space
       end if
   end repeat
   return quotedstringfolders
end getquotedstringfolders

-- I am the connection to the Python script controlling and managing the
-- database file. Yes, I am ugly, but I am hard-working and busy as a bee.
on aspybridge(action, args, returntype)
   -- pyth to myself
   set mypath to ((path to me) as Unicode text)
   -- path to the Python script
   set pyscriptpath to quoted form of (POSIX path of (mypath & "Contents:Resources:Scripts:aspybridge.py"))
   -- path to my application support folder
   set myasfpath to (((path to application support folder from user domain) as Unicode text) & mytitle & ":")
   -- path to the database file located in my application support folder
   set dbfilepath to quoted form of (POSIX path of (myasfpath & "foldersets.db"))
   
   if action is "getfsetnames" then
       set showhidden to item 1 of args
       set command to "python" & space & pyscriptpath & space & action & space & showhidden & space & dbfilepath
       
   else if action is "addfset" then
       set foldersetname to item 1 of args
       set quotedstringfolders to my getquotedstringfolders(item 2 of args)
       set command to "python" & space & pyscriptpath & space & action & space & quoted form of foldersetname & space & quotedstringfolders & space & dbfilepath
       
   else if action is "delfset" then
       set foldersetname to item 1 of args
       set command to "python" & space & pyscriptpath & space & action & space & quoted form of foldersetname & space & dbfilepath
       
   else if action is "getrelfolders" then
       set srcfolder to item 1 of args
       set subfolders to (item 2 of args) as Unicode text
       set warnlevel to (item 3 of args) as Unicode text
       set command to "python" & space & pyscriptpath & space & action & space & quoted form of srcfolder & space & subfolders & space & warnlevel & space & dbfilepath
       
   else if action is "hasfsetname" then
       set foldersetname to item 1 of args
       set command to "python" & space & pyscriptpath & space & action & space & quoted form of foldersetname & space & dbfilepath
       
   else if action is "renfset" then
       set oldfoldersetname to item 1 of args
       set newfoldersetname to item 2 of args
       set command to "python" & space & pyscriptpath & space & action & space & quoted form of oldfoldersetname & space & quoted form of newfoldersetname & space & dbfilepath
       
   else if action is "addrelfolderstofset" then
       set foldersetname to item 1 of args
       set quotedstringfolders to my getquotedstringfolders(item 2 of args)
       set command to "python" & space & pyscriptpath & space & action & space & quoted form of foldersetname & space & quotedstringfolders & space & dbfilepath
       
   else if action is "delrelfoldersfromfset" then
       set foldersetname to item 1 of args
       set quotedstringfolders to my getquotedstringfolders(item 2 of args)
       set command to "python" & space & pyscriptpath & space & action & space & quoted form of foldersetname & space & quotedstringfolders & space & dbfilepath
       
   else if action is "getfset" then
       set foldersetname to item 1 of args
       set command to "python" & space & pyscriptpath & space & action & space & quoted form of foldersetname & space & dbfilepath
       
   end if
   
   set command to command as «class utf8»
   set shellresult to do shell script command
   
   if returntype is "lines" then
       return (paragraphs of shellresult)
   else if returntype is "boolean" then
       if shellresult is in {"True", "1"} then
           return true
       else if shellresult is in {"False", "0"} then
           return false
       end if
   else
       return shellresult
   end if
end aspybridge

-- I am displaying a welcome message to uses who start subidoo for the first time
on dspwelcomemsg()
   tell application "System Events"
       set usrname to (full name of current user) as Unicode text
   end tell
   set welcomemsg to "Hello " & usrname & ", and welcome to " & mytitle & "." & return & return & "It seems, that you are using this application for the first time." & return & return & "If you want to manage your folder sets, just start the application by double-clicking its icon without any items selected in the Finder." & return & return & "If you want to create subfolders, just drop folders onto " & mytitle & "'s icon or select folders in the Finder before starting " & mytitle & "." & return & return & "Have fun!"
   tell me
       activate
       display dialog welcomemsg with title mytitle buttons {"OK"} default button 1
   end tell
end dspwelcomemsg

-- I am displaying error messages
on dsperrmsg(errmsg, errnum)
   tell me
       activate
       display dialog "Sorry, an error occured:" & return & return & errmsg & " (" & errnum & ")" buttons {"Never mind"} default button 1 with icon stop with title mytitle
   end tell
end dsperrmsg


Sal Soghoian is my role model.

Offline

 

Board footer

Powered by FluxBB

[ Generated in 1.119 seconds, 8 queries executed ]

RSS (new topics) RSS (active topics)